Skip to content

Commit

Permalink
♻️ 重构脚本订阅
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Nov 8, 2022
1 parent 88a6d4a commit 8b1a73c
Show file tree
Hide file tree
Showing 26 changed files with 1,011 additions and 203 deletions.
8 changes: 8 additions & 0 deletions example/usersubscribe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// ==UserSubscribe==
// @name 订阅脚本
// @description 可以通过指定脚本url订阅一系列的脚本
// @version 1.0.0
// @author You
// @connect www.baidu.com
// @scriptUrl https://scriptcat.org/scripts/code/22/test.user.js
// ==/UserSubscribe==
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scriptcat",
"version": "0.10.0-alpha.1",
"version": "0.10.0-beta",
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
"author": "CodFrm",
"license": "GPLv3",
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloudscript/cloudscript.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import IoC from "@App/app/ioc";
import { Script } from "@App/app/repo/scripts";
import { Value, ValueDAO } from "@App/app/repo/value";
import { Value } from "@App/app/repo/value";
import ValueManager from "@App/app/service/value/manager";

export type ExportCookies = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/const.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const ExtVersion = "0.10.0-alpha.1";
export const ExtVersion = "0.10.0-beta";

export const Server = "https://sc.icodef.com/";

Expand Down
1 change: 0 additions & 1 deletion src/app/repo/subscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export interface Subscribe {
scripts: { [key: string]: SubscribeScript };
metadata: Metadata;
status: SUBSCRIBE_STATUS;
error?: string;
createtime: number;
updatetime?: number;
checktime: number;
Expand Down
2 changes: 1 addition & 1 deletion src/app/service/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import LoggerCore from "../logger/core";
import Logger from "../logger/logger";
import { MessageHander, MessageSender } from "../message/message";

export type Handler = (data: any, sender: MessageSender) => void | Promise<any>;
export type Handler = (data: any, sender: any) => void | Promise<any>;

export default abstract class Manager {
message: MessageHander;
Expand Down
7 changes: 5 additions & 2 deletions src/app/service/script/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,18 @@ export default class ScriptEventListener {

// 安装或者更新脚本,将数据保存到数据库
@ListenEventDecorator("upsert")
public upsertHandler(script: Script, upsertBy: "user" | "sync" = "user") {
public upsertHandler(
script: Script,
upsertBy: "user" | "system" | "sync" = "user"
) {
return new Promise((resolve, reject) => {
const logger = this.logger.with({
scriptId: script.id,
name: script.name,
uuid: script.uuid,
version: script.metadata.version[0],
upsertBy,
});

this.dao.save(script).then(
() => {
logger.info("script upsert success");
Expand Down
86 changes: 27 additions & 59 deletions src/app/service/script/manager.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
import {
fetchScriptInfo,
parseMetadata,
prepareScriptByCode,
} from "@App/pkg/utils/script";
import { fetchScriptInfo, prepareScriptByCode } from "@App/pkg/utils/script";
import Cache from "@App/app/cache";
import semver from "semver";
import CacheKey from "@App/pkg/utils/cache_key";
import { MessageHander } from "@App/app/message/message";
import IoC from "@App/app/ioc";
import axios from "axios";
import LoggerCore from "@App/app/logger/core";
import Logger from "@App/app/logger/logger";
import { SystemConfig } from "@App/pkg/config/config";
import { checkSilenceUpdate, ltever } from "@App/pkg/utils/utils";
import Manager from "../manager";
import {
Metadata,
Script,
SCRIPT_STATUS_DISABLE,
ScriptDAO,
} from "../../repo/scripts";
import { Script, SCRIPT_STATUS_DISABLE, ScriptDAO } from "../../repo/scripts";
import ScriptEventListener from "./event";
import Hook from "../hook";

export type InstallSource = "user" | "system" | "sync" | "subscribe";

// 脚本管理器,负责脚本实际的安装、卸载、更新等操作
@IoC.Singleton(MessageHander, SystemConfig)
export class ScriptManager extends Manager {
Expand Down Expand Up @@ -76,10 +68,6 @@ export class ScriptManager extends Manager {
return;
}
this.checkUpdate(script.id, "system");
// 更新检查时间
this.scriptDAO.update(script.id, {
checktime: new Date().getTime(),
});
});
});
}, 600 * 1000);
Expand Down Expand Up @@ -121,7 +109,7 @@ export class ScriptManager extends Manager {
Cache.getInstance().del(CacheKey.scriptInfo(info.uuid));
}, 60 * 1000);
chrome.tabs.create({
url: `src/install.html?uuid=${info.uuid}`,
url: `/src/install.html?uuid=${info.uuid}`,
});
})
.catch(() => {
Expand All @@ -137,26 +125,17 @@ export class ScriptManager extends Manager {
if (!script) {
return Promise.resolve(false);
}
this.scriptDAO.update(id, { checktime: new Date().getTime() });
if (!script.checkUpdateUrl) {
return Promise.resolve(false);
}
const logger = LoggerCore.getLogger({
scriptId: id,
name: script.name,
});
this.scriptDAO.update(id, { checktime: new Date().getTime() });
try {
const resp = await axios.get(script.checkUpdateUrl, {
responseType: "text",
headers: {
"Cache-Control": "no-cache",
},
});
if (resp.status !== 200) {
logger.error("check update failed", { status: resp.status });
return Promise.resolve(false);
}
const metadata = parseMetadata(resp.data);
const info = await fetchScriptInfo(script.checkUpdateUrl, source, false);
const { metadata } = info;
if (!metadata) {
logger.error("parse metadata failed");
return Promise.resolve(false);
Expand All @@ -171,7 +150,7 @@ export class ScriptManager extends Manager {
oldVersion = "0.0.0";
}
// 对比版本大小
if (semver.lte(newVersion, oldVersion)) {
if (ltever(newVersion, oldVersion, logger)) {
return Promise.resolve(false);
}
// 进行更新
Expand Down Expand Up @@ -202,51 +181,40 @@ export class ScriptManager extends Manager {
script.uuid
);
if (
this.checkUpdateRule(
checkSilenceUpdate(
newScript.oldScript!.metadata,
newScript.metadata
)
) {
logger.info("silence update script");
this.event.upsertHandler(newScript);
return;
}
} catch (e) {
logger.error("prepare script failed", Logger.E(e));
}
} else {
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
chrome.tabs.create({
url: `src/install.html?uuid=${info.uuid}`,
});
}
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
chrome.tabs.create({
url: `src/install.html?uuid=${info.uuid}`,
});
})
.catch((e) => {
logger.error("fetch script info failed", Logger.E(e));
});
}

// 检查订阅规则是否改变,是否能够静默更新
public checkUpdateRule(oldMeta: Metadata, newMeta: Metadata): boolean {
// 判断connect是否改变
const oldConnect = new Map();
const newConnect = new Map();
oldMeta.connect &&
oldMeta.connect.forEach((val) => {
oldConnect.set(val, 1);
});
newMeta.connect &&
newMeta.connect.forEach((val) => {
newConnect.set(val, 1);
});
// 老的里面没有新的就需要用户确认了
const keys = Object.keys(newConnect);
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i];
if (!oldConnect.has(key)) {
return false;
}
}
return true;
// 直接通过url静默安装脚本
async installByUrl(
url: string,
source: InstallSource,
subscribeUrl?: string
) {
const info = await fetchScriptInfo(url, "system", false);
const script = await prepareScriptByCode(info.code, url, info.uuid);
script.subscribeUrl = subscribeUrl;
await this.event.upsertHandler(script, "system");
return Promise.resolve(script);
}
}

Expand Down
43 changes: 43 additions & 0 deletions src/app/service/subscribe/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import IoC from "@App/app/ioc";
import MessageInternal from "@App/app/message/internal";
import {
Subscribe,
SUBSCRIBE_STATUS_DISABLE,
SUBSCRIBE_STATUS_ENABLE,
SubscribeDAO,
} from "@App/app/repo/subscribe";
import Controller from "../controller";

@IoC.Singleton(MessageInternal)
export default class SubscribeController extends Controller {
subscribeDAO = new SubscribeDAO();

constructor(internal: MessageInternal) {
super(internal, "subscribe");
}

upsert(subscribe: Subscribe) {
return this.dispatchEvent("upsert", subscribe);
}

enable(id: number) {
// 订阅脚本开启和关闭没有副作用,直接修改数据库
return this.subscribeDAO.update(id, {
status: SUBSCRIBE_STATUS_ENABLE,
});
}

disable(id: number) {
return this.subscribeDAO.update(id, {
status: SUBSCRIBE_STATUS_DISABLE,
});
}

checkUpdate(id: number) {
return this.dispatchEvent("checkUpdate", id);
}

delete(id: number) {
return this.dispatchEvent("delete", id);
}
}
Loading

0 comments on commit 8b1a73c

Please sign in to comment.