feat: 删除冗余代码,支持本地部署

This commit is contained in:
lyz05
2024-01-01 19:41:23 +08:00
parent 59daa35412
commit 89b85a233c
13 changed files with 41 additions and 4937 deletions

View File

@@ -1,32 +0,0 @@
module.exports = {
"env": {
"node": true,
"commonjs": true,
"es2021": true,
"jest": true
},
"extends": "eslint:recommended",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
]
}
};

15
app.js
View File

@@ -10,12 +10,8 @@ require("dotenv")
// 引入一个个路由模块
const danmakuRouter = require("./routes/danmaku");
// const ipinfoRouter = require("./routes/ipinfo");
const airportsubRouter = require("./routes/airportsub");
const imgRouter = require("./routes/img");
// const schedule = require("./schedule/schedule");
const DEBUG = process.env.DEBUG === "true" || false;
const DEBUG = !(process.env.DEBUG === "false");
const app = express();
// view engine setup
@@ -38,9 +34,7 @@ app.use("/upload", express.static(__dirname + "/upload"));
// 加载路由
app.use("/", danmakuRouter);
// app.use("/ipinfo", ipinfoRouter);
app.use("/sub", airportsubRouter);
app.use("/img", imgRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
@@ -59,14 +53,11 @@ app.use(function (err, req, res) {
});
if (!DEBUG) {
console.log("PRODUCTION MODE!该模式下TG机器人正常运行");
console.log("PRODUCTION MODE!该模式下TG机器人和日志记录正常运行");
// 引入TG机器人
require("./tgbot/tgbot");
// 引入定时任务模块
// const schedule = require("./schedule/schedule");
// schedule(app);
} else {
console.log("DEBUG MODE!该模式下将关闭TG机器人");
console.log("DEBUG MODE!该模式下将关闭TG机器人与日志记录功能");
}
module.exports = app;

4444
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,6 @@
const express = require("express");
const router = express.Router();
const yaml = require("js-yaml");
const axios = require("axios");
const leancloud = require("../utils/leancloud");
const libqqwry = require("lib-qqwry");
const dns = require("dns");
const qqwry = libqqwry(); //初始化IP库解析器
/* GET users listing. */
router.get("/", async function (req, res) {
@@ -26,47 +21,4 @@ router.get("/", async function (req, res) {
}
});
// 域名解析函数
function resolveDomain(domain) {
return new Promise((resolve, reject) => {
dns.lookup(domain, (error, address) => {
if (error) {
reject(error);
} else {
resolve(address);
}
});
});
}
async function proc(url) {
try {
const response = await axios.get(url);
const info = yaml.load(response.data, { schema: yaml.FullSchema });
for (const line of info.proxies) {
// 过滤解析结果相同的 IP
try {
const ipaddr = await resolveDomain(line.server);
const ipLoc = qqwry.searchIP(ipaddr); //查询IP信息
line.server = ipaddr;
console.log(line.name, line.server, ipLoc.Country, ipLoc.Area);
} catch {
console.log(line.name, line.server);
continue;
}
}
const updatedInfo = yaml.dump(info, { skipInvalid: true });
return updatedInfo;
} catch (error) {
console.error(error);
return yamldata;
}
}
module.exports = router;
if (!module.parent) {
updateDatabase();
}
module.exports = router;

View File

@@ -15,11 +15,11 @@ const leancloud = require("../utils/leancloud");
const rateLimit = require('express-rate-limit');
// 访问频率限制
const MAX_count_today = 2000;
const MAX_count_today = 1000;
const allowlist = ['::1', '::ffff:127.0.0.1'];
const apiLimiter = rateLimit({
windowMs: 2 * 60 * 1000, // 2 minutes
max: 8, // limit each IP to 8 requests per windowMs
windowMs: 5 * 60 * 1000, // 5 minutes
max: 20, // limit each IP to 20 requests per windowMs
message: 'Too many requests from this IP, please try again later',
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
skipFailedRequests: true, // Don't count failed requests (status >= 400)
@@ -107,7 +107,7 @@ router.get("/", apiLimiter, async function (req, res) {
url: req.query.url,
UA: req.headers["user-agent"]
});
// 查询该IP今日访问次数
// 查询该IP今日访问次数,异步查询
leancloud.danmakuQuery(leancloud.currentDay(), req.ip).then((count) => {
console.log("访问次数:", req.ip, count);
if (count > MAX_count_today) {

View File

@@ -1,63 +0,0 @@
const express = require("express");
const router = express.Router();
const fs = require("fs");
const oss = require("../utils/oss");
//设置跨域访问
router.all("*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", " 3.2.1");
next();
});
router.get("/", function (req, res) {
res.render("imgupload");
});
//图片上传
var multer = require("multer");
var upload = multer({
dest: "upload/",
fileFilter(req, file, callback) {
// 解决中文名乱码的问题
file.originalname = Buffer.from(file.originalname, "latin1")
.toString(
"utf8"
);
callback(null, true);
}
});
router.post("/upload", upload.single("file"), async function (req, res, next) {
// 文件路径
var fileName = req.file.filename;
// 构建图片名
var originalName = req.file.originalname;
const localfilename = "upload/" + fileName;
const key = "upload/" + originalName;
const ret = await oss.putfile(key, localfilename);
oss.putACL(key);
res.json(ret);
// res.json({
// status: "100",
// msg: "上传成功",
// key: key,
// imgName: originalName
// });
});
router.get("/search", async function (req, res, next) {
const objects = (await oss.list("upload/")).objects.map(
obj => {
let {lastModified,name,size,url} = obj;
name = name.replace("upload/","");
return {lastModified,name,size,url};
}
);
objects.sort((a,b) => {return b.lastModified>a.lastModified?1:-1;});
res.json(objects);
});
module.exports = router;

View File

@@ -1,67 +0,0 @@
const express = require("express");
const router = express.Router();
const libqqwry = require("lib-qqwry");
const dns = require("dns");
const qqwry = libqqwry(); //初始化IP库解析器
const dnspod = require("../utils/dnspod");
/* GET home page. */
router.get("/", function (req, res) {
let ip = req.query.name || req.ip;
dns.lookup(ip, (err, address) => {
let ipL;
if (err) {
ipL = {
"ip": ip,
"msg": "域名解析IP失败"
};
} else {
ip = address;
try {
ipL = qqwry.searchIP(ip); //查询IP信息
} catch (e) {
ipL = {
"ip": ip,
"msg": e
};
}
}
res.json(ipL);
});
});
router.get("/ddns", async function (req, res) {
let ip = req.query.ip ? req.query.ip : req.ip,
subdomain = req.query.subdomain;
if (ip.substr(0, 7) === "::ffff:") {
ip = ip.substr(7);
}
if (!subdomain || subdomain === "") {
res.json({ msg: "请提供subdomain参数" });
return;
}
const record_type = (ip.indexOf(":") !== -1)? "AAAA": "A";
const records = await dnspod.get_record("home999.cc", subdomain, record_type);
if (!records || records.length !== 1) {
res.json({ msg: "获取不到相关记录或者记录条数不是1。" });
return;
}
const record = records[0];
if (record.value === ip) {
res.json({ msg: "不需要更新IP" });
} else {
record.value = ip;
const status = await dnspod.update_record("home999.cc",record);
if (status.code==="1") {
res.json({msg: "更新成功" ,ip});
} else {
res.json({
msg: "更新失败",
status
});
}
}
});
module.exports = router;

9
test/tmp.js Normal file
View File

@@ -0,0 +1,9 @@
const leancloud = require('../utils/leancloud');
async function main(ms) {
const count = await leancloud.danmakuQuery(leancloud.currentDay(),"1217")
console.log(count);
};
main().then(console.log("OK"));

View File

@@ -1,75 +0,0 @@
const axios = require("axios");
const token = process.env.DNSPOD_TOKEN;
const querystring = require("querystring");
// 创建实例时配置默认值
const instance = axios.create({
baseURL: "https://dnsapi.cn"
});
async function get_record(domain, subdomain, recordtype) {
const api = "/Record.List";
const data = querystring.stringify({
"domain": domain,
"sub_domain": subdomain,
"login_token": token,
"record_type": recordtype,
"format": "json"
});
const res = await instance.post(api, data);
return res.data.records;
}
async function update_record(domain, record) {
const {id, line, type, name, value} = record;
const api = "/Record.Modify";
const data = querystring.stringify({
domain,
record_id: id,
value,
record_line: line,
record_type: type,
sub_domain: name,
"login_token": token,
"format": "json",
});
const res = await instance.post(api, data);
return res.data.status;
}
async function add_record(domain, record) {
const {line, type, name, value} = record;
const api = "/Record.Create";
const data = querystring.stringify({
domain,
value,
record_line: line,
record_type: type,
sub_domain: name,
"login_token": token,
"format": "json",
});
const res = await instance.post(api, data);
return res.data;
}
async function del_record(domain, record) {
const {id} = record;
const api = "/Record.Remove";
const data = querystring.stringify({
domain,
record_id: id,
"login_token": token,
"format": "json",
});
const res = await instance.post(api, data);
return res.data;
}
module.exports = {get_record, update_record, add_record, del_record};
if (!module.parent) {
get_record("home999.cc", "n1","AAAA").then(res => {
console.log(res);
});
}

View File

@@ -1,15 +1,19 @@
const { query } = require("express");
const AV = require("leancloud-storage");
const libqqwry = require("lib-qqwry");
const qqwry = libqqwry();
let AV;
// 引入环境变量
require("dotenv").config({path: "../.env"});
require("dotenv").config({ path: "../.env" });
const DEBUG = !(process.env.DEBUG === "false");
AV.init({
appId: process.env.LEANCLOUD_DANMAKU_APP_ID,
appKey: process.env.LEANCLOUD_DANMAKU_APP_KEY,
serverURL: "https://dbvunek8.lc-cn-n1-shared.com"
});
if (!DEBUG) {
AV = require("leancloud-storage");
AV.init({
appId: process.env.LEANCLOUD_DANMAKU_APP_ID,
appKey: process.env.LEANCLOUD_DANMAKU_APP_KEY,
serverURL: "https://dbvunek8.lc-cn-n1-shared.com"
});
};
function currentDay() {
const date = new Date();
@@ -33,6 +37,7 @@ function currentMonth() {
}
async function danmakuQuery(date, ip) {
if (!AV) return 0;
const query = new AV.Query("DanmakuAccess");
query.greaterThanOrEqualTo("createdAt", date[0]);
query.lessThan("createdAt", date[1]);
@@ -42,12 +47,13 @@ async function danmakuQuery(date, ip) {
return await query.count();
}
function add(className,obj) {
if (obj.ip || obj.remoteIP)
obj.ipCountry = getipCountry(obj.ip || obj.remoteIP);
function add(className, obj) {
if (!AV) return;
if (obj.ip || obj.remoteIP)
obj.ipCountry = getipCountry(obj.ip || obj.remoteIP);
const classInstance = AV.Object.extend(className);
const record = new classInstance();
for (const key of Object.keys(obj)){
for (const key of Object.keys(obj)) {
record.set(key, obj[key]);
}
record.save().then((obj) => {
@@ -57,15 +63,15 @@ function add(className,obj) {
}
function getipCountry(ip) {
try {
const info = qqwry.searchIP(ip);
return info.Country+" "+info.Area;
} catch (e) {
return null;
}
try {
const info = qqwry.searchIP(ip);
return info.Country + " " + info.Area;
} catch (e) {
return null;
}
}
module.exports = {danmakuQuery, currentDay, currentMonth, lastDay, add};
module.exports = { danmakuQuery, currentDay, currentMonth, lastDay, add };
if (!module.parent) {
}

View File

@@ -1,75 +0,0 @@
<% var title="代理软件下载"%>
<%- include('utils/header', {title}); %>
<body>
<div class="container">
<div class="row">
<h1>代理软件下载加速链接:</h1>
<p>
以下是各个代理软件(含浏览器扩展)的Github最新版本:
</p>
<ul>
<% for (item of datas) { %>
<li>
<a href="#<%= item.repo; %>"><%= item.repo; %></a>
</li>
<% } %>
</ul>
</div>
<% for (item of datas) { %>
<div class="row">
<div class="page-header">
<h2 id="<%= item.repo %>"><%= item.repo %>
<small><%= item.tag_name %></small>
</h2>
</div>
<div class="panel">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>文件名</th>
<th>文件大小</th>
<th>下载次数</th>
<th>修改时间</th>
<th>链接</th>
</tr>
</thead>
<tbody>
<% for(asset of item.assets){ %>
<tr>
<td>
<a href="<%= asset.fastgit_url %>">
<span><%= asset.name %></span>
</a>
</td>
<td>
<%= asset.size %>
</td>
<td>
<%= asset.download_count %>
</td>
<td>
<%= asset.updated_at %>
</td>
<td>
<div class="btn-group btn-group-sm">
<a class="btn btn-default" href="<%= asset.browser_download_url %>">
<span>原始链接</span>
</a>
<a class="btn btn-default" href="<%= asset.fastgit_url %>">
<span>fastgit</span>
</a>
<a class="btn btn-default" href="<%= asset.ghproxy_url %>">
<span>ghproxy</span>
</a>
</div>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
<% } %>
</div>
</body>
</html>

View File

@@ -1,41 +0,0 @@
<% var title="订阅信息"%>
<%- include('utils/header', {title}); %>
<body>
<div class="container">
<h3>温馨提示:</h3>
<p>
带filter的是过滤无效节点并精选的结果建议优先使用。强烈建议使用clash作为客户端具有自动测试节点的功能和完善的规则。
</p>
<p>
相关软件<a href="/sub/download">下载链接</a><br>
<a href="/sub/cache">立即更新</a>订阅缓存
</p>
<h3 class="card-heading">Telegram 代理:</h3>
<p>
<% for (const tgproxy of tgproxys) { %>
<a href="<%= tgproxy.url %>"><%= tgproxy.name %></a>
<% } %>
</p>
<h3>Your Subscribe:</h3>
<p>
当前账户过期时间:<%= expire %><br>
<% for (const index in ret) { %>
<%= index %>:
<a href="<%= path %>&ctype=<%= index %>">
<%= path %>&ctype=<%= index %>
</a>
<br>
<% if (ret[index]) { %>
过去已用:<%= ret[index].total_use %> 总量:<%= ret[index].total %> 过期时间:<%= ret[index].expire %>
用量比:<%= ret[index].use_percent %>%
日期比:<%= ret[index].date_percent %>%<br>
<% } %>
<% } %>
</p>
</div>
</body>
</html>

View File

@@ -1,57 +0,0 @@
<% var title="图片上传"%>
<%- include('utils/header', {title}); %>
<body>
<div class="container">
<form id="formId" action="/img/upload" method="post" enctype="multipart/form-data">
<h2>单图上传</h2>
<input type="file" name="file" accept=".jpg, .jpeg, .png, .hdr, .exr">
<input id="submit" type="button" value="提交">
</form>
<a id="search" class="btn btn-default">查询</a>
<p>
<h2>查询结果</h2>
<br>
原始名称:<span id="name"></span>
<br>
上传时间:<span id="lastModified"></span>
<br>
文件大小:<span id="size"></span>
<br>
图片地址:<a id="url" href=""></a>
</p>
</div>
</body>
<script>
$('#search').click(function () {
$.ajax({
url: '/img/search',
type: 'get',
success: function (data) {
const {name, lastModified, size, url} = data[0];
$('#name').text(name);
$('#lastModified').text(lastModified);
$('#size').text(size);
$('#url').text(url).attr('href', url);
}
});
});
$("#submit").click(function () {
$.ajax({
url: '/img/upload',
type: 'post',
data: new FormData($('#formId')[0]),
processData: false,
contentType: false,
success: function (data) {
if (data.res.status === 200) {
alert("上传成功");
} else {
alert("上传失败");
}
console.log(data);
}
});
return false; // 必须返回false否则表单会自己再做一次提交操作并且页面跳转
});
</script>
</html>