Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #583 from langningchen/langningchen/issue432
Browse files Browse the repository at this point in the history
自制图床,讨论区 Ctrl+V 上传图片
  • Loading branch information
Chen LangNing authored Oct 2, 2023
2 parents ef4d828 + c45bc1f commit 33d92ba
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 22 deletions.
82 changes: 79 additions & 3 deletions Server/Source/Process.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Result, ThrowErrorIfFailed } from "./Result";
import { Database } from "./Database";
import { Output } from "./Output";
import { CaptchaSecretKey } from "./Secret";
import { CaptchaSecretKey, GithubImagePAT } from "./Secret";
import { CheerioAPI, load } from "cheerio";
import CryptoJS from "crypto-js";
import md5 from "crypto-js/md5";

export class Process {
private AdminUserList: Array<string> = ["chenlangning", "zhuchenrui2", "shanwenxiao"];
Expand Down Expand Up @@ -1017,21 +1018,92 @@ export class Process {
return new Result(true, "获得板块列表成功", {
"Boards": Boards
});
},
UploadImage: async (Data: object): Promise<Result> => {
const GithubImageRepo = "langningchen/XMOJ-Script-Pictures";
ThrowErrorIfFailed(this.CheckParams(Data, {
"Image": "string"
}));
let Image: String = Data["Image"];
let ImageID: String = "";
for (let i = 0; i < 32; i++) {
ImageID += String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
let ImageData = Image.replace(/^data:image\/\w+;base64,/, "");
await fetch(new URL("https://api.github.com/repos/" + GithubImageRepo + "/contents/" + ImageID), {
method: "PUT",
headers: {
"Authorization": "Bearer " + GithubImagePAT,
"Content-Type": "application/json",
"User-Agent": "XMOJ-Script-Server"
},
body: JSON.stringify({
message: `${this.Username} ${new Date().getFullYear()}/${new Date().getMonth() + 1}/${new Date().getDate()} ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()}`,
content: ImageData
})
}).then((Response) => {
return Response.json();
}).then((Response) => {
if (Response["content"]["name"] !== ImageID) {
Output.Error("Upload image failed\n" +
"Username: \"" + this.Username + "\"\n" +
"ImageID : \"" + ImageID + "\"\n" +
"Response: \"" + JSON.stringify(Response) + "\"\n");
ThrowErrorIfFailed(new Result(false, "上传图片失败"));
}
}).catch((Error) => {
Output.Error("Upload image failed: " + Error + "\n" +
"Username: \"" + this.Username + "\"\n" +
"ImageID : \"" + ImageID + "\"\n");
ThrowErrorIfFailed(new Result(false, "上传图片失败"));
});
return new Result(true, "上传图片成功", {
ImageID: ImageID
});
},
GetImage: async (Data: object): Promise<Blob> => {
const GithubImageRepo = "langningchen/XMOJ-Script-Pictures";
ThrowErrorIfFailed(this.CheckParams(Data, {
"ImageID": "string"
}));
return await fetch(new URL("https://api.github.com/repos/" + GithubImageRepo + "/contents/" + Data["ImageID"] + "?1=1"), {
method: "GET",
headers: {
"Authorization": "Bearer " + GithubImagePAT,
"Accept": "application/vnd.github.v3.raw",
"User-Agent": "XMOJ-Script-Server"
}
}).then((Response) => {
return Response.blob();
}).catch((Error) => {
Output.Error("Get image failed: " + Error + "\n" +
"ImageID : \"" + Data["ImageID"] + "\"\n");
return new Blob();
});
}
};
constructor(RequestData: Request, Environment) {
this.XMOJDatabase = new Database(Environment.DB);
this.RequestData = RequestData;
this.RemoteIP = RequestData.headers.get("CF-Connecting-IP") || "";
}
public async Process(): Promise<Result> {
public async Process(): Promise<Response> {
try {
let PathName = new URL(this.RequestData.url).pathname;
PathName = PathName === "/" ? "/index" : PathName;
PathName = PathName.substring(1);
if (this.ProcessFunctions[PathName] === undefined) {
throw new Result(false, "访问的页面不存在");
}
if (this.RequestData.method === "GET" && PathName === "GetImage") {
return new Response(await this.ProcessFunctions[PathName]({
ImageID: new URL(this.RequestData.url).searchParams.get("ImageID")
}), {
headers: {
"content-type": "image/png"
}
});
}
if (this.RequestData.method !== "POST") {
throw new Result(false, "不允许此请求方式");
}
Expand Down Expand Up @@ -1067,7 +1139,11 @@ export class Process {
Output.Error(ResponseData);
ResponseData = new Result(false, "服务器运行错误:" + String(ResponseData).split("\n")[0]);
}
return ResponseData;
return new Response(JSON.stringify(ResponseData), {
headers: {
"content-type": "application/json;charset=UTF-8"
}
});
}
}
}
6 changes: 1 addition & 5 deletions Server/Source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { Database } from "./Database";
export default {
async fetch(RequestData: Request, Environment, Context) {
let Processor = new Process(RequestData, Environment);
return new Response(JSON.stringify(await Processor.Process()), {
headers: {
"content-type": "application/json;charset=UTF-8"
}
});
return await Processor.Process();
},
async scheduled(Event, Environment, Context) {
let XMOJDatabase = new Database(Environment.DB);
Expand Down
10 changes: 10 additions & 0 deletions Update.json
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,16 @@
"Description": "修复关闭时左上角仍显示为高老师的OJ"
}
]
},
"0.3.192": {
"UpdateDate": 1696222135180,
"Prerelease": true,
"UpdateContents": [
{
"PR": 583,
"Description": "自制图床,讨论区 Ctrl+V 上传图片"
}
]
}
}
}
94 changes: 80 additions & 14 deletions XMOJ.user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name XMOJ
// @version 0.3.191
// @version 0.3.192
// @description XMOJ增强脚本
// @author @langningchen
// @namespace https://github/langningchen
Expand Down Expand Up @@ -47,17 +47,22 @@ let GetRelativeTime = (Input) => {
else { RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 365) + "年前"; }
return "<span title=\"" + Input.toLocaleString() + "\">" + RelativeName + "</span>";
};
let RenderMathJax = () => {
var ScriptElement = document.createElement("script");
ScriptElement.id = "MathJax-script";
ScriptElement.type = "text/javascript";
ScriptElement.src = "https://cdn.bootcdn.net/ajax/libs/mathjax/3.0.5/es5/tex-chtml.js";
document.body.appendChild(ScriptElement);
ScriptElement.onload = () => {
MathJax.startup.input[0].findTeX.options.inlineMath.push(["$", "$"]);
MathJax.startup.input[0].findTeX.getPatterns();
MathJax.typeset();
};
let RenderMathJax = async () => {
if (document.getElementById("MathJax-script") === null) {
var ScriptElement = document.createElement("script");
ScriptElement.id = "MathJax-script";
ScriptElement.type = "text/javascript";
ScriptElement.src = "https://cdn.bootcdn.net/ajax/libs/mathjax/3.0.5/es5/tex-chtml.js";
document.body.appendChild(ScriptElement);
await new Promise((Resolve) => {
ScriptElement.onload = () => {
Resolve();
};
});
}
MathJax.startup.input[0].findTeX.options.inlineMath.push(["$", "$"]);
MathJax.startup.input[0].findTeX.getPatterns();
MathJax.typeset();
};
let GetUserInfo = async (Username) => {
if (localStorage.getItem("UserScript-User-" + Username + "-UserRating") != null &&
Expand Down Expand Up @@ -3697,14 +3702,33 @@ int main()
}
});
ContentElement.addEventListener("input", () => {
ContentElement.classList.remove("is-invalid");
PreviewTab.innerHTML = DOMPurify.sanitize(marked.parse(ContentElement.value));
RenderMathJax();
});
TitleElement.addEventListener("input", () => {
TitleElement.classList.remove("is-invalid");
});
ContentElement.addEventListener("input", () => {
ContentElement.classList.remove("is-invalid");
ContentElement.addEventListener("paste", (Event) => {
let Items = Event.clipboardData.items;
if (Items.length !== 0) {
for (let i = 0; i < Items.length; i++) {
if (Items[i].type.indexOf("image") != -1) {
let Reader = new FileReader();
Reader.readAsDataURL(Items[i].getAsFile());
Reader.onload = () => {
RequestAPI("UploadImage", {
"Image": Reader.result
}, (ResponseData) => {
if (ResponseData.Success) {
ContentElement.value += `![](https://api.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})`;
ContentElement.dispatchEvent(new Event("input"));
}
});
};
}
}
}
});
SubmitElement.addEventListener("click", async () => {
ErrorElement.style.display = "none";
Expand Down Expand Up @@ -3853,6 +3877,27 @@ int main()
PreviewTab.innerHTML = DOMPurify.sanitize(marked.parse(ContentElement.value));
RenderMathJax();
});
ContentElement.addEventListener("paste", (Event) => {
let Items = Event.clipboardData.items;
if (Items.length !== 0) {
for (let i = 0; i < Items.length; i++) {
if (Items[i].type.indexOf("image") != -1) {
let Reader = new FileReader();
Reader.readAsDataURL(Items[i].getAsFile());
Reader.onload = () => {
RequestAPI("UploadImage", {
"Image": Reader.result
}, (ResponseData) => {
if (ResponseData.Success) {
ContentElement.value += `![](https://api.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})`;
ContentElement.dispatchEvent(new Event("input"));
}
});
};
}
}
}
});
let RefreshReply = (Silent = true) => {
if (!Silent) {
PostTitle.innerHTML = `<span class="placeholder col-${Math.ceil(Math.random() * 6)}"></span>`;
Expand Down Expand Up @@ -4057,6 +4102,27 @@ int main()
PreviewTab.innerHTML = DOMPurify.sanitize(marked.parse(ContentEditor.value));
RenderMathJax();
});
ContentEditor.addEventListener("paste", (Event) => {
let Items = Event.clipboardData.items;
if (Items.length !== 0) {
for (let i = 0; i < Items.length; i++) {
if (Items[i].type.indexOf("image") != -1) {
let Reader = new FileReader();
Reader.readAsDataURL(Items[i].getAsFile());
Reader.onload = () => {
RequestAPI("UploadImage", {
"Image": Reader.result
}, (ResponseData) => {
if (ResponseData.Success) {
ContentEditor.value += `![](https://api.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})`;
ContentEditor.dispatchEvent(new Event("input"));
}
});
};
}
}
}
});
}

let UsernameElements = document.getElementsByClassName("Usernames");
Expand Down

0 comments on commit 33d92ba

Please sign in to comment.