Files
kiss-translator/src/libs/sync.js

220 lines
4.6 KiB
JavaScript
Raw Normal View History

2023-07-31 15:08:51 +08:00
import {
2023-09-18 17:36:10 +08:00
APP_LCNAME,
2023-07-31 15:08:51 +08:00
KV_SETTING_KEY,
KV_RULES_KEY,
2023-11-13 18:03:38 +08:00
KV_WFRULES_KEY,
2023-10-26 17:32:55 +08:00
KV_WORDS_KEY,
2023-08-20 23:30:08 +08:00
KV_RULES_SHARE_KEY,
KV_SALT_SHARE,
2023-09-18 15:45:32 +08:00
OPT_SYNCTYPE_WEBDAV,
2023-07-31 15:08:51 +08:00
} from "../config";
2023-08-31 00:18:57 +08:00
import {
getSyncWithDefault,
updateSync,
getSettingWithDefault,
getRulesWithDefault,
2023-10-26 17:32:55 +08:00
getWordsWithDefault,
2023-11-13 18:03:38 +08:00
getWebfixRulesWithDefault,
2023-08-31 00:18:57 +08:00
setSetting,
setRules,
2023-11-13 18:03:38 +08:00
setWebfixRules,
2023-10-26 17:32:55 +08:00
setWords,
2023-08-31 00:18:57 +08:00
} from "./storage";
2023-07-31 15:08:51 +08:00
import { apiSyncData } from "../apis";
2023-09-21 16:13:00 +08:00
import { sha256, removeEndchar } from "./utils";
2023-09-19 11:56:19 +08:00
import { createClient, getPatcher } from "webdav";
import { fetchApi } from "./fetch";
getPatcher().patch("request", (opts) => {
return fetchApi({
input: opts.url,
init: { method: opts.method, headers: opts.headers, body: opts.data },
});
});
2023-09-18 17:36:10 +08:00
2023-09-20 17:47:23 +08:00
const syncByWebdav = async (data, { syncUrl, syncUser, syncKey }) => {
2023-09-18 17:36:10 +08:00
const client = createClient(syncUrl, {
username: syncUser,
password: syncKey,
});
const pathname = `/${APP_LCNAME}`;
2023-09-20 17:47:23 +08:00
const filename = `/${APP_LCNAME}/${data.key}`;
2023-09-18 17:36:10 +08:00
if ((await client.exists(pathname)) === false) {
await client.createDirectory(pathname);
}
const isExist = await client.exists(filename);
2023-09-20 17:47:23 +08:00
if (isExist) {
const cont = await client.getFileContents(filename, { format: "text" });
const webData = JSON.parse(cont);
if (webData.updateAt >= data.updateAt) {
return webData;
2023-09-18 17:36:10 +08:00
}
}
2023-09-21 11:47:22 +08:00
await client.putFileContents(filename, JSON.stringify(data, null, 2));
2023-09-20 17:47:23 +08:00
return data;
2023-09-18 17:36:10 +08:00
};
2023-07-31 15:08:51 +08:00
2023-09-20 17:47:23 +08:00
const syncByWorker = async (data, { syncUrl, syncKey }) => {
2023-09-21 16:13:00 +08:00
syncUrl = removeEndchar(syncUrl, "/");
2023-09-20 17:47:23 +08:00
return await apiSyncData(`${syncUrl}/sync`, syncKey, data);
2023-09-18 15:45:32 +08:00
};
2023-09-20 17:47:23 +08:00
const syncData = async (key, valueFn) => {
2023-09-18 15:45:32 +08:00
const {
syncType,
2023-09-11 11:33:28 +08:00
syncUrl,
2023-09-18 15:45:32 +08:00
syncUser,
2023-09-11 11:33:28 +08:00
syncKey,
2023-09-20 17:47:23 +08:00
syncMeta = {},
2023-09-11 11:33:28 +08:00
} = await getSyncWithDefault();
2023-09-18 15:45:32 +08:00
if (!syncUrl || !syncKey || (syncType === OPT_SYNCTYPE_WEBDAV && !syncUser)) {
2023-09-20 22:15:09 +08:00
return;
2023-08-26 14:31:13 +08:00
}
2023-07-31 15:08:51 +08:00
2023-09-20 17:47:23 +08:00
let { updateAt = 0, syncAt = 0 } = syncMeta[key] || {};
syncAt === 0 && (updateAt = 0);
const value = await valueFn();
const data = {
key,
value: JSON.stringify(value),
updateAt,
};
2023-09-18 17:36:10 +08:00
const args = {
2023-09-18 15:45:32 +08:00
syncUrl,
2023-09-18 17:36:10 +08:00
syncUser,
2023-08-26 14:31:13 +08:00
syncKey,
2023-09-18 17:36:10 +08:00
};
2023-09-20 17:47:23 +08:00
2023-09-18 17:36:10 +08:00
const res =
syncType === OPT_SYNCTYPE_WEBDAV
2023-09-20 17:47:23 +08:00
? await syncByWebdav(data, args)
: await syncByWorker(data, args);
2023-08-17 13:27:22 +08:00
2023-09-20 17:47:23 +08:00
syncMeta[key] = {
updateAt: res.updateAt,
syncAt: Date.now(),
};
await updateSync({ syncMeta });
2023-09-20 22:15:09 +08:00
return { value: JSON.parse(res.value), isNew: res.updateAt > updateAt };
2023-09-20 17:47:23 +08:00
};
2023-09-09 19:26:22 +08:00
2023-09-20 17:47:23 +08:00
/**
* 同步设置
* @returns
*/
const syncSetting = async () => {
2023-09-20 22:15:09 +08:00
const res = await syncData(KV_SETTING_KEY, getSettingWithDefault);
if (res?.isNew) {
await setSetting(res.value);
2023-09-20 17:47:23 +08:00
}
2023-08-26 14:31:13 +08:00
};
2023-09-20 17:47:23 +08:00
export const trySyncSetting = async () => {
2023-08-26 14:31:13 +08:00
try {
2023-09-20 17:47:23 +08:00
await syncSetting();
2023-08-17 13:27:22 +08:00
} catch (err) {
console.log("[sync setting]", err);
2023-07-31 15:08:51 +08:00
}
};
/**
* 同步规则
* @returns
*/
2023-09-20 17:47:23 +08:00
const syncRules = async () => {
2023-09-20 22:15:09 +08:00
const res = await syncData(KV_RULES_KEY, getRulesWithDefault);
if (res?.isNew) {
await setRules(res.value);
2023-08-26 14:31:13 +08:00
}
};
2023-08-17 13:27:22 +08:00
2023-09-20 17:47:23 +08:00
export const trySyncRules = async () => {
2023-08-26 14:31:13 +08:00
try {
2023-09-20 17:47:23 +08:00
await syncRules();
2023-08-17 13:27:22 +08:00
} catch (err) {
2023-08-21 21:31:20 +08:00
console.log("[sync user rules]", err);
2023-07-31 15:08:51 +08:00
}
};
2023-11-13 18:03:38 +08:00
/**
* 同步修复规则
* @returns
*/
const syncWebfixRules = async () => {
const res = await syncData(KV_WFRULES_KEY, getWebfixRulesWithDefault);
if (res?.isNew) {
await setWebfixRules(res.value);
}
};
export const trySyncWebfixRules = async () => {
try {
await syncWebfixRules();
} catch (err) {
console.log("[sync user webfix rules]", err);
}
};
2023-10-26 17:32:55 +08:00
/**
* 同步词汇
* @returns
*/
const syncWords = async () => {
const res = await syncData(KV_WORDS_KEY, getWordsWithDefault);
if (res?.isNew) {
await setWords(res.value);
}
};
export const trySyncWords = async () => {
try {
await syncWords();
} catch (err) {
console.log("[sync fav words]", err);
}
};
/**
* 同步分享规则
* @param {*} param0
* @returns
*/
2023-08-20 23:30:08 +08:00
export const syncShareRules = async ({ rules, syncUrl, syncKey }) => {
2023-09-20 22:15:09 +08:00
const data = {
2023-08-20 23:30:08 +08:00
key: KV_RULES_SHARE_KEY,
2023-09-21 11:47:22 +08:00
value: JSON.stringify(rules, null, 2),
2023-09-20 22:15:09 +08:00
updateAt: Date.now(),
};
const args = {
2023-09-18 15:45:32 +08:00
syncUrl,
syncKey,
2023-09-18 17:36:10 +08:00
};
2023-09-20 22:15:09 +08:00
await syncByWorker(data, args);
2023-08-20 23:30:08 +08:00
const psk = await sha256(syncKey, KV_SALT_SHARE);
2023-09-18 13:28:36 +08:00
const shareUrl = `${syncUrl}/rules?psk=${psk}`;
2023-08-20 23:30:08 +08:00
return shareUrl;
};
/**
* 同步个人设置和规则
* @returns
*/
2023-09-20 17:47:23 +08:00
export const syncSettingAndRules = async () => {
await syncSetting();
await syncRules();
2023-11-13 18:03:38 +08:00
await syncWebfixRules();
2023-10-26 17:32:55 +08:00
await syncWords();
2023-07-31 15:08:51 +08:00
};
2023-08-26 14:31:13 +08:00
2023-09-20 17:47:23 +08:00
export const trySyncSettingAndRules = async () => {
await trySyncSetting();
await trySyncRules();
2023-11-13 18:03:38 +08:00
await trySyncWebfixRules();
2023-10-26 17:32:55 +08:00
await trySyncWords();
2023-08-26 14:31:13 +08:00
};