Skip to content

Commit 6863135

Browse files
committed
first commit
0 parents  commit 6863135

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+5983
-0
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Node.js
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '20'
23+
24+
- name: Install dependencies
25+
run: npm install
26+
27+
- name: Use environment variables
28+
run: |
29+
echo "Username: ${{ secrets.USERNAME }}"
30+
echo "Password: ${{ secrets.PASSWORD }}"
31+
echo "Xiaolin: ${{ secrets.XIAOLIN }}"
32+
echo "Admin: ${{ secrets.ADMIN }}"
33+
34+
- name: Run tests
35+
run: npm test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.npmignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
.git/
3+
docs/
4+
tests/
5+
src/
6+
.github/
7+
.gitignore

dist/api/axiosInstance.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"use strict";
2+
// @ts-nocheck
3+
const axios = require("axios");
4+
const configManager = require("./config");
5+
const util = require("util");
6+
let plrequest = axios.create({
7+
baseURL: configManager.getConfig().baseURL,
8+
timeout: configManager.getConfig().timeout,
9+
headers: {
10+
"Content-Type": "application/json",
11+
Accept: "application/json",
12+
"Accept-Language": "zh-CN",
13+
"x-API-Version": "2411",
14+
},
15+
});
16+
plrequest.interceptors.request.use(function (config) {
17+
const { baseURL, timeout } = configManager.getConfig();
18+
config.baseURL = baseURL;
19+
config.timeout = timeout;
20+
return config;
21+
});
22+
plrequest.interceptors.response.use(function (response) {
23+
let config = configManager.getConfig();
24+
if (response.data.Status !== 200) {
25+
if (config.consoleError) {
26+
const detail = {
27+
header: response.config.headers.toJSON
28+
? response.config.headers.toJSON()
29+
: response.config.headers,
30+
url: configManager.getConfig().baseURL + response.config.url,
31+
body: JSON.parse(response.config.data),
32+
};
33+
console.log("\x1b[36m%s\x1b[0m", "--------physics-lab-web-api----------");
34+
console.log(util.inspect(detail, { colors: true, depth: null }));
35+
console.log("\x1b[31m%s\x1b[0m", response.data);
36+
console.log("\x1b[36m%s\x1b[0m", "--------physics-lab-web-api----------");
37+
}
38+
return response;
39+
}
40+
else {
41+
if (config.consolelog) {
42+
console.log("\x1b[32m%s\x1b[0m", response.config.url);
43+
}
44+
if (config.consoleResponse) {
45+
console.log(response.data.Data);
46+
}
47+
return response;
48+
}
49+
});
50+
module.exports = plrequest;

dist/api/config.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"use strict";
2+
let config = {
3+
baseURL: "https://physics-api-cn.turtlesim.com",
4+
timeout: 8000,
5+
consolelog: true,
6+
consoleResponse: false,
7+
consoleError: true,
8+
checkHttpsAgent: false,
9+
};
10+
// @ts-ignore
11+
function setConfig(newConfig) {
12+
config = { ...config, ...newConfig };
13+
}
14+
function getConfig() {
15+
return config;
16+
}
17+
module.exports = {
18+
setConfig,
19+
getConfig,
20+
};

dist/api/experiment/conver.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"use strict";
2+
const axios = require("axios");
3+
const FormData = require("form-data");
4+
const fs = require("fs");
5+
const plrequest = require("../axiosInstance");
6+
const getSummary = require("../projects/getSummary");
7+
/**
8+
*
9+
* @param {String} filePath
10+
* @param {*} t
11+
* @returns
12+
*/
13+
async function uploadFile(filePath, t) {
14+
const formData = new FormData();
15+
const f = fs.createReadStream(filePath);
16+
formData.append("authorization", t.Authorization);
17+
formData.append("policy", t.Policy);
18+
formData.append("file", f, { filename: "temp.jpg" });
19+
try {
20+
// @ts-ignore
21+
const response = await axios.post("https://v0.api.upyun.com/qphysics", formData, {
22+
headers: formData.getHeaders(),
23+
});
24+
return response.data;
25+
}
26+
catch (error) {
27+
console.error("上传文件失败:", error);
28+
}
29+
}
30+
/**
31+
* 更新作品封面
32+
* @param {string} filename - 需要上传的图片路径(本地)
33+
* @param {string} c - 作品分区
34+
* @param {number} i - 作品ID
35+
* @returns {Promise<void>} - 无返回值
36+
*/
37+
async function cover(filename, c, i) {
38+
this._getSummary = getSummary.bind(this);
39+
const getSummaryResponse = await this._getSummary(i, c);
40+
// @ts-ignore
41+
const imageIdex = getSummaryResponse.Data.Image + 1;
42+
try {
43+
const confirmExperimentResponse = await plrequest.post("/Contents/ConfirmExperiment", {
44+
Category: c,
45+
SummaryID: i,
46+
Image: imageIdex,
47+
Extension: ".png",
48+
}, {
49+
headers: {
50+
"Content-Type": "application/json",
51+
Accept: "application/json",
52+
"Accept-Language": "zh-CN",
53+
// @ts-ignore
54+
"x-API-Token": this.token,
55+
// @ts-ignore
56+
"x-API-AuthCode": this.authCode,
57+
},
58+
});
59+
// @ts-ignore
60+
const summaryData = getSummaryResponse.Data;
61+
const submitExperimentResponse = await plrequest.post("/Contents/SubmitExperiment", {
62+
Request: {
63+
FileSize: 0 - Math.abs(fs.statSync(filename).size),
64+
Extension: ".jpg",
65+
},
66+
Summary: summaryData,
67+
}, {
68+
headers: {
69+
"Content-Type": "application/json",
70+
Accept: "application/json",
71+
"Accept-Language": "zh-CN",
72+
// @ts-ignore
73+
"x-API-Token": this.token,
74+
// @ts-ignore
75+
"x-API-AuthCode": this.authCode,
76+
},
77+
});
78+
await uploadFile(filename, submitExperimentResponse.data.Data.Token);
79+
await plrequest.post("/Contents/ConfirmExperiment", {
80+
Category: c,
81+
SummaryID: i,
82+
Image: imageIdex,
83+
Extension: ".png",
84+
}, {
85+
headers: {
86+
"Content-Type": "application/json",
87+
Accept: "application/json",
88+
"Accept-Language": "zh-CN",
89+
// @ts-ignore
90+
"x-API-Token": this.token,
91+
// @ts-ignore
92+
"x-API-AuthCode": this.authCode,
93+
},
94+
});
95+
Promise.resolve();
96+
}
97+
catch (error) {
98+
throw error;
99+
}
100+
}
101+
module.exports = cover;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"use strict";
2+
const getSummary = require("../projects/getSummary");
3+
const plrequest = require("../axiosInstance");
4+
/**
5+
* 获取实验存档
6+
*
7+
* @param {String} id - 作品序列号
8+
* @param {String} type - Discussion 或 Experiment
9+
* @returns {Promise<Object>}
10+
*/
11+
module.exports = async function getExperiment(id, type) {
12+
this._getSummary = getSummary.bind(this);
13+
const Summary = await this._getSummary(id, type);
14+
// @ts-ignore
15+
const ContentID = Summary.Data.ContentID;
16+
const response = await plrequest.post("/Contents/GetExperiment", {
17+
ContentID,
18+
}, {
19+
headers: {
20+
"Content-Type": "application/json",
21+
Accept: "application/json",
22+
"Accept-Language": "zh-CN",
23+
// @ts-ignore
24+
"x-API-Token": this.token,
25+
// @ts-ignore
26+
"x-API-AuthCode": this.authCode,
27+
},
28+
});
29+
return response.data;
30+
};

dist/api/experiment/update.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use strict";
2+
const plrequest = require("../axiosInstance");
3+
/**
4+
* 更新作品
5+
*
6+
* @param {Object} s - 更新后的summary,可使用getSummary获取
7+
* @param {Object} w - workSpace
8+
* @returns {Promise<Object>}
9+
*/
10+
module.exports = async function update(s, w) {
11+
const response = await plrequest.post("/Contents/SubmitExperiment", {
12+
Summary: s,
13+
Workspace: w,
14+
}, {
15+
headers: {
16+
"Content-Type": "application/json",
17+
Accept: "application/json",
18+
"Accept-Language": "zh-CN",
19+
// @ts-ignore
20+
"x-API-Token": this.token,
21+
// @ts-ignore
22+
"x-API-AuthCode": this.authCode,
23+
},
24+
});
25+
return response.data;
26+
};

dist/api/index.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"use strict";
2+
const cover = require("./experiment/conver");
3+
const getExperiment = require("./experiment/getExperiment");
4+
const updateExperiment = require("./experiment/update");
5+
const getMessage = require("./messages/get");
6+
const sendMessages = require("./messages/send");
7+
const getDerivatives = require("./projects/getDerivatives");
8+
const getSummary = require("./projects/getSummary");
9+
const getSupporters = require("./projects/getSupporters");
10+
const query = require("./projects/query");
11+
const star = require("./projects/star");
12+
const getUser = require("./user/getUser");
13+
const getUserByComments = require("./user/getUserByCmmentID");
14+
const login = require("./user/login");
15+
/**
16+
* User 类用于创建用户实例,管理用户名、密码及相关操作。
17+
*
18+
* 构造函数接受用户名和密码作为参数,支持从环境变量中获取默认值。
19+
* 提供多个功能模块,包括消息处理、用户操作、项目管理及实验相关操作。
20+
*
21+
* @class User
22+
* @constructor
23+
* @param {string|null} username - 用户名,若为null则初始化为null,若未提供则尝试从环境变量获取。
24+
* @param {string|null} password - 密码,若为null则初始化为null,若未提供则尝试从环境变量获取。
25+
*
26+
* @property {Object} messages - 消息相关操作,包括获取用户评论、发送消息及获取消息。
27+
* @property {Object} user - 用户相关操作,包括登录及获取用户信息。
28+
* @property {Object} projects - 项目管理操作,包括查询、获取总结、获取详细信息、收藏项目及获取支持者。
29+
* @property {Object} experiment - 实验管理操作,包括更新实验、获取封面及获取实验。
30+
*/
31+
class User {
32+
/**
33+
* 创建一个物实用户实例
34+
* @param {String} username
35+
* @param {String} password
36+
* @memberof User
37+
*/
38+
constructor(username, password) {
39+
if (username === null) {
40+
this.username = null;
41+
this.password = null;
42+
}
43+
else {
44+
this.username = username || process?.env?.USERNAME || null;
45+
this.password = password || process?.env?.PASSWORD || null;
46+
}
47+
this.messages = {
48+
get: getMessage.bind(this),
49+
comment: sendMessages.bind(this),
50+
};
51+
this.user = {
52+
login: login.bind(this),
53+
getUser: getUser.bind(this),
54+
getUserByComments: getUserByComments.bind(this),
55+
};
56+
this.projects = {
57+
query: query.bind(this),
58+
getSummary: getSummary.bind(this),
59+
getDerivatives: getDerivatives.bind(this),
60+
star: star.bind(this),
61+
getSupporters: getSupporters.bind(this),
62+
};
63+
this.experiment = {
64+
update: updateExperiment.bind(this),
65+
cover: cover.bind(this),
66+
get: getExperiment.bind(this),
67+
};
68+
}
69+
}
70+
module.exports = User;

dist/api/messages/get.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use strict";
2+
const plrequest = require("../axiosInstance");
3+
/**
4+
* 获取留言/评论信息,部分作品需要非匿名登录(传入用户名和密码)
5+
*
6+
* @param {*} ID - 获取的相关type的序列号,例如667c0e11d46f35b9aaddb8dd
7+
* @param {string} [type="Discussion"] - 所获取的对象的类型。Discussion、Experiment、User
8+
* @param {number} [take=20] - 获取的留言/评论数量
9+
* @param {*} [from=null] - 从某个commentID开始跳过skip条
10+
* @param {number} [skip=0] - 跳过的数量
11+
* @returns {Promise<Object>}
12+
*/
13+
module.exports = async function getMessages(ID, type = "Discussion", take = 20, from = null, skip = 0) {
14+
if (take > 100)
15+
throw new Error("消息获取数量一次最多为100条");
16+
take = -take;
17+
const response = await plrequest.post("Messages/GetComments", {
18+
TargetID: ID,
19+
TargetType: type,
20+
CommentID: from,
21+
Take: take,
22+
Skip: skip,
23+
}, {
24+
headers: {
25+
"Content-Type": "application/json",
26+
Accept: "application/json",
27+
"Accept-Language": "zh-CN",
28+
// @ts-ignore
29+
"x-API-Token": this.token,
30+
// @ts-ignore
31+
"x-API-AuthCode": this.authCode,
32+
},
33+
});
34+
return response.data;
35+
};

0 commit comments

Comments
 (0)