xmoj-script 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/Prerelease.yml +10 -2
- package/.github/workflows/Release.yml +10 -2
- package/README.md +4 -5
- package/SECURITY.md +3 -2
- package/Update/GetVersion.js +4 -2
- package/Update/UpdateToRelease.js +11 -6
- package/Update/UpdateVersion.js +14 -9
- package/Update.json +11 -1
- package/XMOJ.user.js +6 -1
- package/package.json +1 -1
- package/backend/.github/.config.yml +0 -21
- package/backend/.github/ISSUE_TEMPLATE/bug.yml +0 -30
- package/backend/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/backend/.github/ISSUE_TEMPLATE/feature.yml +0 -25
- package/backend/.github/dependabot.yml +0 -12
- package/backend/.github/labeler.yml +0 -14
- package/backend/LICENSE +0 -661
- package/backend/README.md +0 -3
- package/backend/Source/BBSSpider.js +0 -50
- package/backend/Source/Database.ts +0 -188
- package/backend/Source/Initial.sql +0 -95
- package/backend/Source/Output.ts +0 -14
- package/backend/Source/Process.ts +0 -1227
- package/backend/Source/Result.ts +0 -24
- package/backend/Source/XMOJ-bbs.code-workspace +0 -11
- package/backend/Source/index.ts +0 -31
- package/backend/bun.lockb +0 -0
- package/backend/package.json +0 -19
- package/backend/wrangler.toml +0 -17
@@ -1,50 +0,0 @@
|
|
1
|
-
let Data = {
|
2
|
-
bbs_post: [],
|
3
|
-
bbs_reply: []
|
4
|
-
};
|
5
|
-
const PostCount = 207;
|
6
|
-
const GetPost = async (i) => {
|
7
|
-
if (i > PostCount) {
|
8
|
-
console.log(Data);
|
9
|
-
let DataBlob = new Blob([JSON.stringify(Data)], { type: "text/plain" });
|
10
|
-
let DownloadLink = document.createElement("a");
|
11
|
-
DownloadLink.download = "BBSSpider.json";
|
12
|
-
DownloadLink.href = URL.createObjectURL(DataBlob);
|
13
|
-
DownloadLink.click();
|
14
|
-
return;
|
15
|
-
}
|
16
|
-
console.log(i + " / " + PostCount + " " + ((i - 1) / PostCount * 100).toFixed(2) + "%");
|
17
|
-
await fetch("http://www.xmoj.tech/discuss3/thread.php?tid=" + i)
|
18
|
-
.then((Response) => {
|
19
|
-
return Response.text();
|
20
|
-
})
|
21
|
-
.then((Response) => {
|
22
|
-
let Document = new DOMParser().parseFromString(Response, "text/html");
|
23
|
-
if (Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div:nth-child(2) > a") == null)
|
24
|
-
return;
|
25
|
-
Data.bbs_post.push({
|
26
|
-
post_id: Number(i),
|
27
|
-
user_id: String(Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div:nth-child(2) > a").innerHTML.trim()),
|
28
|
-
problem_id: Number(Document.querySelector("body > div > div > center > div > table > tbody > tr.toprow > td > a").innerHTML.trim().substring(8)),
|
29
|
-
title: String(Document.querySelector("body > div > div > center > div > table > tbody > tr.toprow > td").childNodes[2].data.substring(4)),
|
30
|
-
post_time: new Date(Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div:nth-child(2)").childNodes[1].data.substring(3)).getTime() - 8 * 60 * 60 * 1000
|
31
|
-
});
|
32
|
-
Data.bbs_reply.push({
|
33
|
-
post_id: Number(i),
|
34
|
-
user_id: String(Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div:nth-child(2) > a").innerHTML.trim()),
|
35
|
-
content: String(Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div.content").innerText.trim()),
|
36
|
-
reply_time: new Date(Document.querySelector("body > div > div > center > div > table > tbody > tr.evenrow > td > div:nth-child(2)").childNodes[1].data.substring(3)).getTime() - 8 * 60 * 60 * 1000
|
37
|
-
});
|
38
|
-
let ReplyElement = Document.querySelector("body > div > div > center > div > table > tbody").children;
|
39
|
-
for (let j = 2; j < ReplyElement.length; j++) {
|
40
|
-
Data.bbs_reply.push({
|
41
|
-
post_id: Number(i),
|
42
|
-
user_id: String(ReplyElement[j].querySelector("td > div:nth-child(2) > a").innerHTML.trim()),
|
43
|
-
content: String(ReplyElement[j].querySelector("td > div.content").innerText.trim()),
|
44
|
-
reply_time: new Date(ReplyElement[j].querySelector("td > div:nth-child(2)").childNodes[1].data.substring(3)).getTime() - 8 * 60 * 60 * 1000
|
45
|
-
});
|
46
|
-
}
|
47
|
-
});
|
48
|
-
await GetPost(i + 1);
|
49
|
-
};
|
50
|
-
GetPost(1);
|
@@ -1,188 +0,0 @@
|
|
1
|
-
import { Result, ThrowErrorIfFailed } from "./Result";
|
2
|
-
import { Output } from "./Output";
|
3
|
-
import { D1Database } from "@cloudflare/workers-types";
|
4
|
-
|
5
|
-
export class Database {
|
6
|
-
private RawDatabase: D1Database;
|
7
|
-
constructor(RawDatabase: D1Database) {
|
8
|
-
this.RawDatabase = RawDatabase;
|
9
|
-
}
|
10
|
-
private async Query(QueryString: string, BindData: string[]): Promise<Result> {
|
11
|
-
Output.Debug("Executing SQL query: \n" +
|
12
|
-
" Query : \"" + QueryString + "\"\n" +
|
13
|
-
" Arguments: " + JSON.stringify(BindData) + "\n");
|
14
|
-
try {
|
15
|
-
let SQLResult = await this.RawDatabase.prepare(QueryString).bind(...BindData).all()
|
16
|
-
Output.Debug("SQL query returned with result: \n" +
|
17
|
-
" Result: \"" + JSON.stringify(SQLResult) + "\"\n");
|
18
|
-
return new Result(true, "数据库查询成功", SQLResult);
|
19
|
-
} catch (ErrorDetail) {
|
20
|
-
Output.Warn("Error while executing SQL query: \n" +
|
21
|
-
" Query : \"" + QueryString + "\"\n" +
|
22
|
-
" Arguments: " + JSON.stringify(BindData) + "\n" +
|
23
|
-
" Error : \"" + ErrorDetail) + "\"\n";
|
24
|
-
return new Result(false, "数据库查询失败:" + String(ErrorDetail));
|
25
|
-
}
|
26
|
-
}
|
27
|
-
public async Insert(Table: string, Data: object): Promise<Result> {
|
28
|
-
let QueryString = "INSERT INTO `" + Table + "` (";
|
29
|
-
for (let i in Data) {
|
30
|
-
QueryString += "`" + i + "`, ";
|
31
|
-
}
|
32
|
-
QueryString = QueryString.substring(0, QueryString.length - 2);
|
33
|
-
QueryString += ") VALUES (";
|
34
|
-
for (let i in Data) {
|
35
|
-
QueryString += "?, ";
|
36
|
-
}
|
37
|
-
QueryString = QueryString.substring(0, QueryString.length - 2);
|
38
|
-
QueryString += ");";
|
39
|
-
let BindData = Array();
|
40
|
-
for (let i in Data) {
|
41
|
-
BindData.push(Data[i]);
|
42
|
-
}
|
43
|
-
return new Result(true, "数据库插入成功", {
|
44
|
-
"InsertID": ThrowErrorIfFailed(await this.Query(QueryString, BindData))["meta"]["last_row_id"]
|
45
|
-
});
|
46
|
-
}
|
47
|
-
public async Select(Table: string, Data: string[], Condition?: object, Other?: object, Distinct?: boolean): Promise<Result> {
|
48
|
-
let QueryString = "SELECT ";
|
49
|
-
if (Distinct !== undefined && Distinct) {
|
50
|
-
QueryString += "DISTINCT ";
|
51
|
-
}
|
52
|
-
if (Data.length == 0) {
|
53
|
-
QueryString += "*";
|
54
|
-
}
|
55
|
-
else {
|
56
|
-
for (let i in Data) {
|
57
|
-
QueryString += "`" + Data[i] + "`, ";
|
58
|
-
}
|
59
|
-
QueryString = QueryString.substring(0, QueryString.length - 2);
|
60
|
-
}
|
61
|
-
QueryString += " FROM `" + Table + "`";
|
62
|
-
if (Condition !== undefined) {
|
63
|
-
QueryString += " WHERE ";
|
64
|
-
for (let i in Condition) {
|
65
|
-
if (typeof Condition[i] != "object") {
|
66
|
-
QueryString += "`" + i + "` = ? AND ";
|
67
|
-
}
|
68
|
-
else {
|
69
|
-
QueryString += "`" + i + "` " + Condition[i]["Operator"] + " ? AND ";
|
70
|
-
}
|
71
|
-
}
|
72
|
-
QueryString = QueryString.substring(0, QueryString.length - 5);
|
73
|
-
}
|
74
|
-
if (Other !== undefined) {
|
75
|
-
if ((Other["Order"] !== undefined && Other["OrderIncreasing"] === undefined) ||
|
76
|
-
(Other["Order"] === undefined && Other["OrderIncreasing"] !== undefined)) {
|
77
|
-
return new Result(false, "排序关键字和排序顺序必须同时定义或非定义");
|
78
|
-
}
|
79
|
-
if (Other["Order"] !== undefined && Other["OrderIncreasing"] !== undefined) {
|
80
|
-
QueryString += " ORDER BY `" + Other["Order"] + "` " + (Other["OrderIncreasing"] ? "ASC" : "DESC");
|
81
|
-
}
|
82
|
-
if (Other["Limit"] !== undefined) {
|
83
|
-
QueryString += " LIMIT " + Other["Limit"];
|
84
|
-
}
|
85
|
-
if (Other["Offset"] !== undefined) {
|
86
|
-
QueryString += " OFFSET " + Other["Offset"];
|
87
|
-
}
|
88
|
-
}
|
89
|
-
QueryString += ";";
|
90
|
-
let BindData = Array();
|
91
|
-
for (let i in Condition) {
|
92
|
-
if (typeof Condition[i] != "object") {
|
93
|
-
BindData.push(Condition[i]);
|
94
|
-
}
|
95
|
-
else {
|
96
|
-
BindData.push(Condition[i]["Value"]);
|
97
|
-
}
|
98
|
-
}
|
99
|
-
return new Result(true, "数据库查找成功", ThrowErrorIfFailed(await this.Query(QueryString, BindData))["results"]);
|
100
|
-
}
|
101
|
-
public async Update(Table: string, Data: object, Condition?: object): Promise<Result> {
|
102
|
-
let QueryString = "UPDATE `" + Table + "` SET ";
|
103
|
-
for (let i in Data) {
|
104
|
-
QueryString += "`" + i + "` = ?, ";
|
105
|
-
}
|
106
|
-
QueryString = QueryString.substring(0, QueryString.length - 2);
|
107
|
-
if (Condition !== undefined) {
|
108
|
-
QueryString += " WHERE ";
|
109
|
-
for (let i in Condition) {
|
110
|
-
if (typeof Condition[i] != "object") {
|
111
|
-
QueryString += "`" + i + "` = ? AND ";
|
112
|
-
}
|
113
|
-
else {
|
114
|
-
QueryString += "`" + i + "` " + Condition[i]["Operator"] + " ? AND ";
|
115
|
-
}
|
116
|
-
}
|
117
|
-
QueryString = QueryString.substring(0, QueryString.length - 5);
|
118
|
-
}
|
119
|
-
QueryString += ";";
|
120
|
-
let BindData = Array();
|
121
|
-
for (let i in Data) {
|
122
|
-
BindData.push(Data[i]);
|
123
|
-
}
|
124
|
-
for (let i in Condition) {
|
125
|
-
if (typeof Condition[i] != "object") {
|
126
|
-
BindData.push(Condition[i]);
|
127
|
-
}
|
128
|
-
else {
|
129
|
-
BindData.push(Condition[i]["Value"]);
|
130
|
-
}
|
131
|
-
}
|
132
|
-
return new Result(true, "数据库更新成功", ThrowErrorIfFailed(await this.Query(QueryString, BindData))["results"]);
|
133
|
-
}
|
134
|
-
public async GetTableSize(Table: string, Condition?: object): Promise<Result> {
|
135
|
-
let QueryString = "SELECT COUNT(*) FROM `" + Table + "`";
|
136
|
-
if (Condition !== undefined) {
|
137
|
-
QueryString += " WHERE ";
|
138
|
-
for (let i in Condition) {
|
139
|
-
if (typeof Condition[i] != "object") {
|
140
|
-
QueryString += "`" + i + "` = ? AND ";
|
141
|
-
}
|
142
|
-
else {
|
143
|
-
QueryString += "`" + i + "` " + Condition[i]["Operator"] + " ? AND ";
|
144
|
-
}
|
145
|
-
}
|
146
|
-
QueryString = QueryString.substring(0, QueryString.length - 5);
|
147
|
-
}
|
148
|
-
QueryString += ";";
|
149
|
-
let BindData = Array();
|
150
|
-
for (let i in Condition) {
|
151
|
-
if (typeof Condition[i] != "object") {
|
152
|
-
BindData.push(Condition[i]);
|
153
|
-
}
|
154
|
-
else {
|
155
|
-
BindData.push(Condition[i]["Value"]);
|
156
|
-
}
|
157
|
-
}
|
158
|
-
return new Result(true, "数据库获得大小成功", {
|
159
|
-
"TableSize": ThrowErrorIfFailed(await this.Query(QueryString, BindData))["results"][0]["COUNT(*)"]
|
160
|
-
});
|
161
|
-
}
|
162
|
-
public async Delete(Table: string, Condition?: object): Promise<Result> {
|
163
|
-
let QueryString = "DELETE FROM `" + Table + "`";
|
164
|
-
if (Condition !== undefined) {
|
165
|
-
QueryString += " WHERE ";
|
166
|
-
for (let i in Condition) {
|
167
|
-
if (typeof Condition[i] != "object") {
|
168
|
-
QueryString += "`" + i + "` = ? AND ";
|
169
|
-
}
|
170
|
-
else {
|
171
|
-
QueryString += "`" + i + "` " + Condition[i]["Operator"] + " ? AND ";
|
172
|
-
}
|
173
|
-
}
|
174
|
-
QueryString = QueryString.substring(0, QueryString.length - 4);
|
175
|
-
}
|
176
|
-
QueryString += ";";
|
177
|
-
let BindData = Array();
|
178
|
-
for (let i in Condition) {
|
179
|
-
if (typeof Condition[i] != "object") {
|
180
|
-
BindData.push(Condition[i]);
|
181
|
-
}
|
182
|
-
else {
|
183
|
-
BindData.push(Condition[i]["Value"]);
|
184
|
-
}
|
185
|
-
}
|
186
|
-
return new Result(true, "数据库删除成功", ThrowErrorIfFailed(await this.Query(QueryString, BindData))["results"]);
|
187
|
-
}
|
188
|
-
}
|
@@ -1,95 +0,0 @@
|
|
1
|
-
DROP TABLE IF EXISTS badge;
|
2
|
-
|
3
|
-
CREATE TABLE badge (
|
4
|
-
user_id TEXT PRIMARY KEY NOT NULL,
|
5
|
-
background_color TEXT NOT NULL DEFAULT "#000000",
|
6
|
-
color TEXT NOT NULL DEFAULT "#ffffff",
|
7
|
-
content TEXT NOT NULL DEFAULT "VIP"
|
8
|
-
);
|
9
|
-
|
10
|
-
DROP TABLE IF EXISTS bbs_lock;
|
11
|
-
|
12
|
-
CREATE TABLE bbs_lock (
|
13
|
-
post_id INTEGER PRIMARY KEY NOT NULL,
|
14
|
-
lock_person TEXT NOT NULL,
|
15
|
-
lock_time INTEGER NOT NULL
|
16
|
-
);
|
17
|
-
|
18
|
-
DROP TABLE IF EXISTS bbs_mention;
|
19
|
-
|
20
|
-
CREATE TABLE bbs_mention (
|
21
|
-
bbs_mention_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
22
|
-
to_user_id TEXT NOT NULL,
|
23
|
-
post_id INTEGER NOT NULL,
|
24
|
-
bbs_mention_time TIMESTAMP NOT NULL
|
25
|
-
);
|
26
|
-
|
27
|
-
DROP TABLE IF EXISTS bbs_post;
|
28
|
-
|
29
|
-
CREATE TABLE bbs_post (
|
30
|
-
post_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
31
|
-
user_id TEXT NOT NULL,
|
32
|
-
problem_id INT NOT NULL,
|
33
|
-
title TEXT NOT NULL,
|
34
|
-
post_time INTEGER NOT NULL,
|
35
|
-
board_id INTEGER NOT NULL
|
36
|
-
);
|
37
|
-
|
38
|
-
DROP TABLE IF EXISTS bbs_reply;
|
39
|
-
|
40
|
-
CREATE TABLE bbs_reply (
|
41
|
-
reply_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
42
|
-
post_id INTEGER NOT NULL,
|
43
|
-
user_id TEXT NOT NULL,
|
44
|
-
content TEXT NOT NULL,
|
45
|
-
reply_time INTEGER NOT NULL,
|
46
|
-
edit_time INTEGER,
|
47
|
-
edit_person TEXT
|
48
|
-
);
|
49
|
-
|
50
|
-
DROP TABLE IF EXISTS bbs_board;
|
51
|
-
|
52
|
-
CREATE TABLE bbs_board (
|
53
|
-
board_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
54
|
-
board_name TEXT NOT NULL
|
55
|
-
);
|
56
|
-
INSERT INTO bbs_board (board_name) VALUES ('站务版');
|
57
|
-
INSERT INTO bbs_board (board_name) VALUES ('学术版');
|
58
|
-
INSERT INTO bbs_board (board_name) VALUES ('灌水区');
|
59
|
-
INSERT INTO bbs_board (board_name) VALUES ('反馈区');
|
60
|
-
INSERT INTO bbs_board (board_name) VALUES ('题目总版');
|
61
|
-
|
62
|
-
DROP TABLE IF EXISTS phpsessid;
|
63
|
-
|
64
|
-
CREATE TABLE phpsessid (
|
65
|
-
token TEXT PRIMARY KEY NOT NULL,
|
66
|
-
user_id TEXT NOT NULL,
|
67
|
-
create_time INTEGER NOT NULL
|
68
|
-
);
|
69
|
-
|
70
|
-
DROP TABLE IF EXISTS short_message;
|
71
|
-
|
72
|
-
CREATE TABLE short_message (
|
73
|
-
message_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
74
|
-
message_from TEXT NOT NULL,
|
75
|
-
message_to TEXT NOT NULL,
|
76
|
-
content TEXT NOT NULL,
|
77
|
-
is_read INTEGER NOT NULL DEFAULT 0,
|
78
|
-
send_time INTEGER NOT NULL
|
79
|
-
);
|
80
|
-
|
81
|
-
DROP TABLE IF EXISTS short_message_mention;
|
82
|
-
|
83
|
-
CREATE TABLE short_message_mention (
|
84
|
-
mail_mention_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
85
|
-
from_user_id TEXT NOT NULL,
|
86
|
-
to_user_id TEXT NOT NULL,
|
87
|
-
mail_mention_time TIMESTAMP NOT NULL
|
88
|
-
);
|
89
|
-
|
90
|
-
DROP TABLE IF EXISTS std_answer;
|
91
|
-
|
92
|
-
CREATE TABLE std_answer (
|
93
|
-
problem_id INTEGER PRIMARY KEY NOT NULL,
|
94
|
-
std_code TEXT
|
95
|
-
);
|
package/backend/Source/Output.ts
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
export class Output {
|
2
|
-
public static Debug(Message: any): void {
|
3
|
-
// console.debug("\x1b[36m%s\x1b[0m", Message);
|
4
|
-
}
|
5
|
-
public static Log(Message: any): void {
|
6
|
-
console.log("\x1b[32m%s\x1b[0m", Message);
|
7
|
-
}
|
8
|
-
public static Warn(Message: any): void {
|
9
|
-
console.warn("\x1b[33m%s\x1b[0m", Message);
|
10
|
-
}
|
11
|
-
public static Error(Message: any): void {
|
12
|
-
console.error("\x1b[31m%s\x1b[0m", Message);
|
13
|
-
}
|
14
|
-
}
|