Skip to content

Commit 8b1a73c

Browse files
committed
♻️ 重构脚本订阅
1 parent 88a6d4a commit 8b1a73c

26 files changed

Lines changed: 1011 additions & 203 deletions

File tree

‎example/usersubscribe.js‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// ==UserSubscribe==
2+
// @name 订阅脚本
3+
// @description 可以通过指定脚本url订阅一系列的脚本
4+
// @version 1.0.0
5+
// @author You
6+
// @connect www.baidu.com
7+
// @scriptUrl https://scriptcat.org/scripts/code/22/test.user.js
8+
// ==/UserSubscribe==

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scriptcat",
3-
"version": "0.10.0-alpha.1",
3+
"version": "0.10.0-beta",
44
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
55
"author": "CodFrm",
66
"license": "GPLv3",

‎pkg/cloudscript/cloudscript.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import IoC from "@App/app/ioc";
22
import { Script } from "@App/app/repo/scripts";
3-
import { Value, ValueDAO } from "@App/app/repo/value";
3+
import { Value } from "@App/app/repo/value";
44
import ValueManager from "@App/app/service/value/manager";
55

66
export type ExportCookies = {

‎src/app/const.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const ExtVersion = "0.10.0-alpha.1";
1+
export const ExtVersion = "0.10.0-beta";
22

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

‎src/app/repo/subscribe.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export interface Subscribe {
2020
scripts: { [key: string]: SubscribeScript };
2121
metadata: Metadata;
2222
status: SUBSCRIBE_STATUS;
23-
error?: string;
2423
createtime: number;
2524
updatetime?: number;
2625
checktime: number;

‎src/app/service/manager.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import LoggerCore from "../logger/core";
22
import Logger from "../logger/logger";
33
import { MessageHander, MessageSender } from "../message/message";
44

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

77
export default abstract class Manager {
88
message: MessageHander;

‎src/app/service/script/event.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ export default class ScriptEventListener {
4848

4949
// 安装或者更新脚本,将数据保存到数据库
5050
@ListenEventDecorator("upsert")
51-
public upsertHandler(script: Script, upsertBy: "user" | "sync" = "user") {
51+
public upsertHandler(
52+
script: Script,
53+
upsertBy: "user" | "system" | "sync" = "user"
54+
) {
5255
return new Promise((resolve, reject) => {
5356
const logger = this.logger.with({
5457
scriptId: script.id,
5558
name: script.name,
5659
uuid: script.uuid,
5760
version: script.metadata.version[0],
61+
upsertBy,
5862
});
59-
6063
this.dao.save(script).then(
6164
() => {
6265
logger.info("script upsert success");

‎src/app/service/script/manager.ts‎

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,19 @@
1-
import {
2-
fetchScriptInfo,
3-
parseMetadata,
4-
prepareScriptByCode,
5-
} from "@App/pkg/utils/script";
1+
import { fetchScriptInfo, prepareScriptByCode } from "@App/pkg/utils/script";
62
import Cache from "@App/app/cache";
7-
import semver from "semver";
83
import CacheKey from "@App/pkg/utils/cache_key";
94
import { MessageHander } from "@App/app/message/message";
105
import IoC from "@App/app/ioc";
11-
import axios from "axios";
126
import LoggerCore from "@App/app/logger/core";
137
import Logger from "@App/app/logger/logger";
148
import { SystemConfig } from "@App/pkg/config/config";
9+
import { checkSilenceUpdate, ltever } from "@App/pkg/utils/utils";
1510
import Manager from "../manager";
16-
import {
17-
Metadata,
18-
Script,
19-
SCRIPT_STATUS_DISABLE,
20-
ScriptDAO,
21-
} from "../../repo/scripts";
11+
import { Script, SCRIPT_STATUS_DISABLE, ScriptDAO } from "../../repo/scripts";
2212
import ScriptEventListener from "./event";
2313
import Hook from "../hook";
2414

15+
export type InstallSource = "user" | "system" | "sync" | "subscribe";
16+
2517
// 脚本管理器,负责脚本实际的安装、卸载、更新等操作
2618
@IoC.Singleton(MessageHander, SystemConfig)
2719
export class ScriptManager extends Manager {
@@ -76,10 +68,6 @@ export class ScriptManager extends Manager {
7668
return;
7769
}
7870
this.checkUpdate(script.id, "system");
79-
// 更新检查时间
80-
this.scriptDAO.update(script.id, {
81-
checktime: new Date().getTime(),
82-
});
8371
});
8472
});
8573
}, 600 * 1000);
@@ -121,7 +109,7 @@ export class ScriptManager extends Manager {
121109
Cache.getInstance().del(CacheKey.scriptInfo(info.uuid));
122110
}, 60 * 1000);
123111
chrome.tabs.create({
124-
url: `src/install.html?uuid=${info.uuid}`,
112+
url: `/src/install.html?uuid=${info.uuid}`,
125113
});
126114
})
127115
.catch(() => {
@@ -137,26 +125,17 @@ export class ScriptManager extends Manager {
137125
if (!script) {
138126
return Promise.resolve(false);
139127
}
128+
this.scriptDAO.update(id, { checktime: new Date().getTime() });
140129
if (!script.checkUpdateUrl) {
141130
return Promise.resolve(false);
142131
}
143132
const logger = LoggerCore.getLogger({
144133
scriptId: id,
145134
name: script.name,
146135
});
147-
this.scriptDAO.update(id, { checktime: new Date().getTime() });
148136
try {
149-
const resp = await axios.get(script.checkUpdateUrl, {
150-
responseType: "text",
151-
headers: {
152-
"Cache-Control": "no-cache",
153-
},
154-
});
155-
if (resp.status !== 200) {
156-
logger.error("check update failed", { status: resp.status });
157-
return Promise.resolve(false);
158-
}
159-
const metadata = parseMetadata(resp.data);
137+
const info = await fetchScriptInfo(script.checkUpdateUrl, source, false);
138+
const { metadata } = info;
160139
if (!metadata) {
161140
logger.error("parse metadata failed");
162141
return Promise.resolve(false);
@@ -171,7 +150,7 @@ export class ScriptManager extends Manager {
171150
oldVersion = "0.0.0";
172151
}
173152
// 对比版本大小
174-
if (semver.lte(newVersion, oldVersion)) {
153+
if (ltever(newVersion, oldVersion, logger)) {
175154
return Promise.resolve(false);
176155
}
177156
// 进行更新
@@ -202,51 +181,40 @@ export class ScriptManager extends Manager {
202181
script.uuid
203182
);
204183
if (
205-
this.checkUpdateRule(
184+
checkSilenceUpdate(
206185
newScript.oldScript!.metadata,
207186
newScript.metadata
208187
)
209188
) {
210189
logger.info("silence update script");
211190
this.event.upsertHandler(newScript);
191+
return;
212192
}
213193
} catch (e) {
214194
logger.error("prepare script failed", Logger.E(e));
215195
}
216-
} else {
217-
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
218-
chrome.tabs.create({
219-
url: `src/install.html?uuid=${info.uuid}`,
220-
});
221196
}
197+
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
198+
chrome.tabs.create({
199+
url: `src/install.html?uuid=${info.uuid}`,
200+
});
222201
})
223202
.catch((e) => {
224203
logger.error("fetch script info failed", Logger.E(e));
225204
});
226205
}
227206

228-
// 检查订阅规则是否改变,是否能够静默更新
229-
public checkUpdateRule(oldMeta: Metadata, newMeta: Metadata): boolean {
230-
// 判断connect是否改变
231-
const oldConnect = new Map();
232-
const newConnect = new Map();
233-
oldMeta.connect &&
234-
oldMeta.connect.forEach((val) => {
235-
oldConnect.set(val, 1);
236-
});
237-
newMeta.connect &&
238-
newMeta.connect.forEach((val) => {
239-
newConnect.set(val, 1);
240-
});
241-
// 老的里面没有新的就需要用户确认了
242-
const keys = Object.keys(newConnect);
243-
for (let i = 0; i < keys.length; i += 1) {
244-
const key = keys[i];
245-
if (!oldConnect.has(key)) {
246-
return false;
247-
}
248-
}
249-
return true;
207+
// 直接通过url静默安装脚本
208+
async installByUrl(
209+
url: string,
210+
source: InstallSource,
211+
subscribeUrl?: string
212+
) {
213+
const info = await fetchScriptInfo(url, "system", false);
214+
const script = await prepareScriptByCode(info.code, url, info.uuid);
215+
script.subscribeUrl = subscribeUrl;
216+
await this.event.upsertHandler(script, "system");
217+
return Promise.resolve(script);
250218
}
251219
}
252220

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import IoC from "@App/app/ioc";
2+
import MessageInternal from "@App/app/message/internal";
3+
import {
4+
Subscribe,
5+
SUBSCRIBE_STATUS_DISABLE,
6+
SUBSCRIBE_STATUS_ENABLE,
7+
SubscribeDAO,
8+
} from "@App/app/repo/subscribe";
9+
import Controller from "../controller";
10+
11+
@IoC.Singleton(MessageInternal)
12+
export default class SubscribeController extends Controller {
13+
subscribeDAO = new SubscribeDAO();
14+
15+
constructor(internal: MessageInternal) {
16+
super(internal, "subscribe");
17+
}
18+
19+
upsert(subscribe: Subscribe) {
20+
return this.dispatchEvent("upsert", subscribe);
21+
}
22+
23+
enable(id: number) {
24+
// 订阅脚本开启和关闭没有副作用,直接修改数据库
25+
return this.subscribeDAO.update(id, {
26+
status: SUBSCRIBE_STATUS_ENABLE,
27+
});
28+
}
29+
30+
disable(id: number) {
31+
return this.subscribeDAO.update(id, {
32+
status: SUBSCRIBE_STATUS_DISABLE,
33+
});
34+
}
35+
36+
checkUpdate(id: number) {
37+
return this.dispatchEvent("checkUpdate", id);
38+
}
39+
40+
delete(id: number) {
41+
return this.dispatchEvent("delete", id);
42+
}
43+
}

0 commit comments

Comments
 (0)