Skip to content

Commit

Permalink
feat: support memos v1 api
Browse files Browse the repository at this point in the history
Signed-off-by: EINDEX <snowstarlbk@gmail.com>
  • Loading branch information
EINDEX committed Jul 18, 2023
1 parent 4abd5b1 commit 1bb33e4
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 99 deletions.
48 changes: 38 additions & 10 deletions src/memos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import "@logseq/libs";
import { BlockEntity, PageEntity } from "@logseq/libs/dist/LSPlugin";
import { format } from "date-fns";
import { BATCH_SIZE } from "./constants";
import MemosClient from "./memos/client";
import MemosGeneralClient, { MemosClient } from "./memos/client";
import { Memo } from "./memos/type";
import {
formatContentWhenPush,
Expand Down Expand Up @@ -41,13 +41,22 @@ class MemosSync {
* syncMemos
*/
public async syncMemos(mode = "Manual") {
const { host, openId }: any = logseq.settings;
if (!host || !openId) {
logseq.UI.showMsg("Memos Setting up needed.");
logseq.showSettingsUI();
}
await this.choosingClient();
if (this.memosClient === undefined || this.memosClient === null) {
logseq.UI.showMsg("Memos Sync Setup issue", "error");
}
try {
await this.sync();
if (mode !== "Background") {
logseq.UI.showMsg("Memos Sync Success", "success");
}
} catch (e) {
console.error("memos-sync: ",e);
console.error("memos-sync: ", e);
if (mode !== "Background") {
logseq.UI.showMsg(String(e), "error");
}
Expand All @@ -71,16 +80,16 @@ class MemosSync {

private async sync() {
await this.beforeSync();

let maxMemoId = await this.lastSyncId();
let newMaxMemoId = maxMemoId;
let end = false;
let cousor = 0;
while (!end) {
const memos = await this.memosClient!.getMemos(
this.includeArchive!,
BATCH_SIZE,
cousor
cousor,
this.includeArchive!
);
for (const memo of this.memosFitler(memos)) {
if (memo.id <= maxMemoId) {
Expand Down Expand Up @@ -128,10 +137,16 @@ class MemosSync {
}
}

private async choosingClient() {
const { host, openId }: any = logseq.settings;
const client = new MemosGeneralClient(host, openId);
this.memosClient = await client.getClient();
}

public parseSetting() {
this.configMigrate();
try {
const {
openAPI,
mode,
customPage,
includeArchive,
Expand All @@ -142,7 +157,7 @@ class MemosSync {
tagFilter,
flat,
}: any = logseq.settings;
this.memosClient = new MemosClient(openAPI);
this.choosingClient();
this.mode = mode;
this.autoSync = autoSync;
this.customPage = customPage || "Memos";
Expand All @@ -155,7 +170,7 @@ class MemosSync {

this.backgroundConfigChange();
} catch (e) {
console.error("memos-sync: ",e);
console.error("memos-sync: ", e);
logseq.UI.showMsg("Memos OpenAPI is not a URL", "error");
}
}
Expand Down Expand Up @@ -188,7 +203,7 @@ class MemosSync {
await logseq.UI.showMsg("Post memo success");
}
} catch (error) {
console.error("memos-sync: ",error);
console.error("memos-sync: ", error);
await logseq.UI.showMsg(String(error), "error");
}
}
Expand Down Expand Up @@ -297,7 +312,7 @@ class MemosSync {
if (!parentBlock) {
throw "Not able to create parent Block";
}
console.debug('memos-sync: parentBlock', parentBlock)
console.debug("memos-sync: parentBlock", parentBlock);
await logseq.Editor.insertBatchBlock(
parentBlock.uuid,
memoContentGenerate(
Expand Down Expand Up @@ -337,6 +352,19 @@ class MemosSync {
};
return await this.memosClient!.updateMemo(memoId, payload);
}

private configMigrate() {
// memos v0 -> v1
const { openAPI, host, openId }: any = logseq.settings;
if (openAPI && !host && !openId) {
const memosUrl = new URL(openAPI);
logseq.updateSettings({
host: memosUrl.origin,
openId: memosUrl.searchParams.get("openId"),
openAPI: null,
});
}
}
}

export default MemosSync;
102 changes: 25 additions & 77 deletions src/memos/client.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,38 @@
import axios, { AxiosResponse } from "axios";
import { ListMemo, Memo } from "./type";

type MemosAPIResponse<T> = {
data:T;
message: string;
};
import MemosClientV1 from "./impls/clientV1";
import MemosClientV0 from "./impls/clientV0";
import { Memo } from "./type";

export interface MemosClient {
getMemos(
limit: number,
offset: number,
includeArchive: boolean,
): Promise<Memo[]>;
updateMemo(memoId: number, payload: Record<string, any>): Promise<Memo>;
createMemo(content: string, visibility: string): Promise<Memo>;
}

export default class MemosClient {
private openId: string;
private host: string;
export default class MemosGeneralClient {
private v1: MemosClientV1;
private v0: MemosClientV0;

constructor(openAPI: string) {
const openAPIURL = new URL(openAPI);
this.host = openAPIURL.origin;
const openId = openAPIURL.searchParams.get("openId");
constructor(host: string, openId: string) {
if (!openId) {
throw "OpenId not exist";
}
this.openId = openId;
}


private async request<T>(url: string, method: string, payload: any): Promise<T> {
try {
const resp: AxiosResponse<MemosAPIResponse<T>> = await axios({
method: method,
url: url,
data: payload,
});
if (resp.status !== 200) {
throw "Something wrong!";
} else if (resp.status >= 400 && resp.status < 500) {
throw resp.data?.message || "Error occurred";
}
const data = resp.data.data;
return data;
} catch ( error) {
throw "Cannot connect to memos server";
}

}

public async getMemos(
includeArchive: boolean,
limit: number,
offset: number
): Promise<Memo[]> {
const url = new URL(`${this.host}/api/memo`);
url.searchParams.append("openId", String(this.openId));
if (!includeArchive) {
url.searchParams.append("rowStatus", "NORMAL");
}
url.searchParams.append("limit", limit.toString());
url.searchParams.append("offset", offset.toString());
try {
return await this.request<Memo[]>(url.toString(), "GET", {});
} catch (error) {
throw new Error(`Failed to get memos, ${error}`);
}
this.v1 = new MemosClientV1(host, openId);
this.v0 = new MemosClientV0(host, openId);
}

public async updateMemo(
memoId: number,
payload: Record<string, any>
): Promise<Memo> {
const url = new URL(`${this.host}/api/memo/${memoId}`);
url.searchParams.append("openId", String(this.openId));
public async getClient(): Promise<MemosClient> {
try {
return await this.request<Memo>(url.toString(), "PATCH", payload);
await this.v1.me();
return this.v1;
} catch (error) {
throw new Error(`Failed to update memo, ${error}.`);
}
}

public async createMemo(content: string, visibility: string): Promise<Memo> {
const payload = {
content: content,
visibility: visibility,
};
const url = new URL(`${this.host}/api/memo`);
url.searchParams.append("openId", String(this.openId));
try {
return await this.request<Memo>(url.toString(), "POST", payload);
} catch (error) {
throw new Error(`Failed to create memo, ${error}.`);
if (error instanceof Error && error.message.includes("Not Found")) {
return this.v0;
}
throw error;
}
}
}
87 changes: 87 additions & 0 deletions src/memos/impls/clientV0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import axios, { AxiosResponse, Method } from "axios";
import { Memo } from "../type";
import { MemosClient } from "../client";

type MemosAPIResponse<T> = {
data: T;
message: string;
};

export default class MemosClientV0 implements MemosClient {
private openId: string;
private host: string;

constructor(host:string, openId: string) {
this.host = host;
this.openId = openId;
}

private async request<T>(
url: string,
method: Method,
payload: any
): Promise<T> {
try {
const resp: AxiosResponse<MemosAPIResponse<T>> = await axios({
method: method,
url: url,
data: payload,
});
if (resp.status !== 200) {
throw "Something wrong!";
} else if (resp.status >= 400 && resp.status < 500) {
throw resp.data?.message || "Error occurred";
}
const data = resp.data.data;
return data;
} catch (error) {
throw "Cannot connect to memos server";
}
}

public async getMemos(
limit: number,
offset: number,
includeArchive: boolean,
): Promise<Memo[]> {
const url = new URL(`${this.host}/api/memo`);
url.searchParams.append("openId", String(this.openId));
if (!includeArchive) {
url.searchParams.append("rowStatus", "NORMAL");
}
url.searchParams.append("limit", limit.toString());
url.searchParams.append("offset", offset.toString());
try {
return await this.request<Memo[]>(url.toString(), "GET", {});
} catch (error) {
throw new Error(`Failed to get memos, ${error}`);
}
}

public async updateMemo(
memoId: number,
payload: Record<string, any>
): Promise<Memo> {
const url = new URL(`${this.host}/api/memo/${memoId}`);
url.searchParams.append("openId", String(this.openId));
try {
return await this.request<Memo>(url.toString(), "PATCH", payload);
} catch (error) {
throw new Error(`Failed to update memo, ${error}.`);
}
}

public async createMemo(content: string, visibility: string): Promise<Memo> {
const payload = {
content: content,
visibility: visibility,
};
const url = new URL(`${this.host}/api/memo`);
url.searchParams.append("openId", String(this.openId));
try {
return await this.request<Memo>(url.toString(), "POST", payload);
} catch (error) {
throw new Error(`Failed to create memo, ${error}.`);
}
}
}
Loading

0 comments on commit 1bb33e4

Please sign in to comment.