mirror of
https://github.com/lyz05/danmaku.git
synced 2026-04-13 18:10:16 +08:00
docs: 使用eslint进行代码检查
This commit is contained in:
32
.eslintrc.js
Normal file
32
.eslintrc.js
Normal file
@@ -0,0 +1,32 @@
|
||||
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"
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,10 @@
|
||||
FROM node:14.21.0-alpine3.16
|
||||
ENV TZ Asia/Shanghai
|
||||
|
||||
RUN apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
|
||||
&& echo ${TZ} > /etc/timezone \
|
||||
&& apk del tzdata
|
||||
|
||||
|
||||
LABEL fly_launch_runtime="nodejs"
|
||||
COPY . /app
|
||||
|
||||
62
app.js
62
app.js
@@ -1,57 +1,57 @@
|
||||
const createError = require('http-errors');
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const logger = require('morgan');
|
||||
const createError = require("http-errors");
|
||||
const express = require("express");
|
||||
const path = require("path");
|
||||
const cookieParser = require("cookie-parser");
|
||||
const logger = require("morgan");
|
||||
|
||||
// 引入环境变量
|
||||
require('dotenv').config();
|
||||
require("dotenv").config();
|
||||
|
||||
// 引入一个个路由模块
|
||||
const danmakuRouter = require('./routes/danmaku');
|
||||
const ipinfoRouter = require('./routes/ipinfo');
|
||||
const airportsubRouter = require('./routes/airportsub');
|
||||
const danmakuRouter = require("./routes/danmaku");
|
||||
const ipinfoRouter = require("./routes/ipinfo");
|
||||
const airportsubRouter = require("./routes/airportsub");
|
||||
const DEBUG = process.env.DEBUG==="true" || false;
|
||||
if (!DEBUG) {
|
||||
console.log("PRODUCTION MODE!该模式下TG机器人与定时任务正常运行");
|
||||
// 引入定时任务模块
|
||||
const schedule = require('./schedule/schedule');
|
||||
// 引入TG机器人
|
||||
const tgbot = require('./tgbot/bot');
|
||||
console.log("PRODUCTION MODE!该模式下TG机器人与定时任务正常运行");
|
||||
// 引入定时任务模块
|
||||
require("./schedule/schedule");
|
||||
// 引入TG机器人
|
||||
require("./tgbot/bot");
|
||||
} else
|
||||
console.log("DEBUG MODE!该模式下将关闭TG机器人和定时任务");
|
||||
console.log("DEBUG MODE!该模式下将关闭TG机器人和定时任务");
|
||||
|
||||
const app = express();
|
||||
|
||||
// view engine setup
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('trust proxy', true)
|
||||
app.set("views", path.join(__dirname, "views"));
|
||||
app.set("view engine", "ejs");
|
||||
app.set("trust proxy", true);
|
||||
|
||||
app.use(logger('dev'));
|
||||
app.use(logger("dev"));
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({extended: false}));
|
||||
app.use(cookieParser());
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
app.use(express.static(path.join(__dirname, "public")));
|
||||
|
||||
app.use('/', danmakuRouter);
|
||||
app.use('/ipinfo', ipinfoRouter);
|
||||
app.use('/sub', airportsubRouter);
|
||||
app.use("/", danmakuRouter);
|
||||
app.use("/ipinfo", ipinfoRouter);
|
||||
app.use("/sub", airportsubRouter);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(function (req, res, next) {
|
||||
next(createError(404));
|
||||
next(createError(404));
|
||||
});
|
||||
|
||||
// error handler
|
||||
app.use(function (err, req, res, next) {
|
||||
// set locals, only providing error in development
|
||||
res.locals.message = err.message;
|
||||
res.locals.error = req.app.get('env') === 'development' ? err : {};
|
||||
app.use(function (err, req, res) {
|
||||
// set locals, only providing error in development
|
||||
res.locals.message = err.message;
|
||||
res.locals.error = req.app.get("env") === "development" ? err : {};
|
||||
|
||||
// render the error page
|
||||
res.status(err.status || 500);
|
||||
res.render('error');
|
||||
// render the error page
|
||||
res.status(err.status || 500);
|
||||
res.render("error");
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
|
||||
1909
package-lock.json
generated
1909
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,8 @@
|
||||
"xml2js": "^0.4.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"mocha": "^10.1.0",
|
||||
"nodemon": "^2.0.20",
|
||||
"nyc": "^15.1.0"
|
||||
|
||||
@@ -1,164 +1,162 @@
|
||||
const express = require('express');
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const oss = require('../utils/oss');
|
||||
const yaml = require('js-yaml');
|
||||
const cookie = require('cookie');
|
||||
const {filesize} = require('filesize');
|
||||
const moment = require('moment');
|
||||
const axios = require('axios');
|
||||
const leancloud = require('../utils/leancloud')
|
||||
|
||||
const oss = require("../utils/oss");
|
||||
const yaml = require("js-yaml");
|
||||
const cookie = require("cookie");
|
||||
const {filesize} = require("filesize");
|
||||
const moment = require("moment");
|
||||
const axios = require("axios");
|
||||
const leancloud = require("../utils/leancloud");
|
||||
|
||||
// TODO 迁移到leancloud
|
||||
function getuserinfo(headers) {
|
||||
if (!headers)
|
||||
return undefined
|
||||
const str = headers["subscription-userinfo"]
|
||||
if (str === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const dic = cookie.parse(str);
|
||||
dic['total_use'] = 1 * dic.upload + 1 * dic.download
|
||||
dic['use_percent'] = (100.0 * dic.total_use / dic.total).toFixed(2)
|
||||
const now_time = Math.floor(Date.now() / 1000)
|
||||
const end_time = dic.expire
|
||||
dic['date_percent'] = (100.0 * (now_time - end_time + 3600 * 24 * 365.0) / (3600 * 24 * 365.0)).toFixed(2)
|
||||
if (!headers)
|
||||
return undefined;
|
||||
const str = headers["subscription-userinfo"];
|
||||
if (str === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const dic = cookie.parse(str);
|
||||
dic["total_use"] = 1 * dic.upload + 1 * dic.download;
|
||||
dic["use_percent"] = (100.0 * dic.total_use / dic.total).toFixed(2);
|
||||
const now_time = Math.floor(Date.now() / 1000);
|
||||
const end_time = dic.expire;
|
||||
dic["date_percent"] = (100.0 * (now_time - end_time + 3600 * 24 * 365.0) / (3600 * 24 * 365.0)).toFixed(2);
|
||||
|
||||
dic['total_use'] = filesize(dic['total_use'], {base: 2, standard: "jedec"})
|
||||
dic.total = filesize(dic.total, {base: 2, standard: "jedec"})
|
||||
dic.expire = moment(dic.expire * 1000).format('YYYY-MM-DD')
|
||||
return dic
|
||||
dic["total_use"] = filesize(dic["total_use"], {base: 2, standard: "jedec"});
|
||||
dic.total = filesize(dic.total, {base: 2, standard: "jedec"});
|
||||
dic.expire = moment(dic.expire * 1000).format("YYYY-MM-DD");
|
||||
return dic;
|
||||
}
|
||||
|
||||
async function updateDatabase() {
|
||||
const database = await oss.get('SUB/database.yaml');
|
||||
try {
|
||||
const doc = yaml.load(database);
|
||||
return doc
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
const database = await oss.get("SUB/database.yaml");
|
||||
try {
|
||||
return yaml.load(database);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* GET users listing. */
|
||||
router.get('/', async function (req, res, next) {
|
||||
const database = await updateDatabase();
|
||||
leancloud.add('SubAccess', {
|
||||
ip: req.ip,
|
||||
ua: req.headers['user-agent'],
|
||||
user: req.query.user,
|
||||
ctype: req.query.ctype
|
||||
})
|
||||
if (req.query.user) {
|
||||
const userinfo = database.user[req.query.user]
|
||||
if (userinfo) {
|
||||
const expireDate = new Date(userinfo.expire);
|
||||
const now = new Date();
|
||||
if (now < expireDate) {
|
||||
if (req.query.ctype) {
|
||||
const subinfo = database.suburl[req.query.ctype]
|
||||
//返回指定订阅信息
|
||||
if (subinfo) {
|
||||
const ua = req.headers['user-agent'];
|
||||
if (ua.indexOf('Mozilla') === -1) {
|
||||
const url = await oss.signurl('SUB/' + req.query.ctype, true)
|
||||
res.redirect(url)
|
||||
} else {
|
||||
const ret = await oss.get('SUB/' + req.query.ctype)
|
||||
res.type('text/plain').end(ret);
|
||||
}
|
||||
} else {
|
||||
res.status(404).send('Not Found 找不到这种订阅类型');
|
||||
}
|
||||
} else {
|
||||
const path = req.protocol + '://' + req.headers.host + req.originalUrl;
|
||||
const tgproxys = database.telegram;
|
||||
const ctypes = Object.keys(database.suburl)
|
||||
let ret = {}
|
||||
for (key of ctypes) {
|
||||
const headers = await oss.head('SUB/' + key)
|
||||
ret[key] = getuserinfo(headers)
|
||||
// ret[key] = getuserinfotxt(getuserinfo(headers))
|
||||
}
|
||||
res.render('airportsub', {ret, path, tgproxys, expire: userinfo.expire});
|
||||
}
|
||||
} else {
|
||||
res.send('您的订阅已过期,请联系管理员');
|
||||
}
|
||||
} else {
|
||||
res.status(404).send('Not Found 找不到这个用户');
|
||||
}
|
||||
} else {
|
||||
res.status(400).send('Bad Request 缺少参数');
|
||||
}
|
||||
router.get("/", async function (req, res) {
|
||||
const database = await updateDatabase();
|
||||
leancloud.add("SubAccess", {
|
||||
ip: req.ip,
|
||||
ua: req.headers["user-agent"],
|
||||
user: req.query.user,
|
||||
ctype: req.query.ctype
|
||||
});
|
||||
if (req.query.user) {
|
||||
const userinfo = database.user[req.query.user];
|
||||
if (userinfo) {
|
||||
const expireDate = new Date(userinfo.expire);
|
||||
const now = new Date();
|
||||
if (now < expireDate) {
|
||||
if (req.query.ctype) {
|
||||
const subinfo = database.suburl[req.query.ctype];
|
||||
//返回指定订阅信息
|
||||
if (subinfo) {
|
||||
const ua = req.headers["user-agent"];
|
||||
if (ua.indexOf("Mozilla") === -1) {
|
||||
const url = await oss.signurl("SUB/" + req.query.ctype, true);
|
||||
res.redirect(url);
|
||||
} else {
|
||||
const ret = await oss.get("SUB/" + req.query.ctype);
|
||||
res.type("text/plain").end(ret);
|
||||
}
|
||||
} else {
|
||||
res.status(404).send("Not Found 找不到这种订阅类型");
|
||||
}
|
||||
} else {
|
||||
const path = req.protocol + "://" + req.headers.host + req.originalUrl;
|
||||
const tgproxys = database.telegram;
|
||||
const ctypes = Object.keys(database.suburl);
|
||||
let ret = {};
|
||||
for (const key of ctypes) {
|
||||
const headers = await oss.head("SUB/" + key);
|
||||
ret[key] = getuserinfo(headers);
|
||||
// ret[key] = getuserinfotxt(getuserinfo(headers))
|
||||
}
|
||||
res.render("airportsub", {ret, path, tgproxys, expire: userinfo.expire});
|
||||
}
|
||||
} else {
|
||||
res.send("您的订阅已过期,请联系管理员");
|
||||
}
|
||||
} else {
|
||||
res.status(404).send("Not Found 找不到这个用户");
|
||||
}
|
||||
} else {
|
||||
res.status(400).send("Bad Request 缺少参数");
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/cache', async function (req, res, next) {
|
||||
const database = await updateDatabase();
|
||||
let messages = [];
|
||||
// 缓存所有的协程
|
||||
let promises = [];
|
||||
for (let key in database.suburl) {
|
||||
const url = database.suburl[key].url
|
||||
const params = database.suburl[key].params
|
||||
if (!url) continue
|
||||
promises.push(axios.get(url, {params}));
|
||||
}
|
||||
Promise.all(promises).then(values => {
|
||||
promises = [];
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const res = values[i];
|
||||
const key = Object.keys(database.suburl)[i]
|
||||
messages.push({title: 'Download', key, status: res.status})
|
||||
const userinfo = res.headers['subscription-userinfo']
|
||||
const base64userinfo = Buffer.from(userinfo).toString('base64')
|
||||
// 设置强制下载并设置文件名
|
||||
const headers = {
|
||||
'Content-type': 'text/plain; charset=utf-8',
|
||||
'content-disposition': `attachment; filename=${key}`,
|
||||
'x-oss-persistent-headers': "Subscription-Userinfo:" + base64userinfo
|
||||
}
|
||||
promises.push(oss.put('SUB/' + key, res.data, headers))
|
||||
}
|
||||
Promise.all(promises).then(values => {
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const res = values[i];
|
||||
const key = Object.keys(database.suburl)[i]
|
||||
messages.push({title: 'Upload', key, status: res.res.status})
|
||||
}
|
||||
res.json(messages);
|
||||
})
|
||||
});
|
||||
router.get("/cache", async function (req, res) {
|
||||
const database = await updateDatabase();
|
||||
let messages = [];
|
||||
// 缓存所有的协程
|
||||
let promises = [];
|
||||
for (let key in database.suburl) {
|
||||
const url = database.suburl[key].url;
|
||||
const params = database.suburl[key].params;
|
||||
if (!url) continue;
|
||||
promises.push(axios.get(url, {params}));
|
||||
}
|
||||
Promise.all(promises).then(values => {
|
||||
promises = [];
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const res = values[i];
|
||||
const key = Object.keys(database.suburl)[i];
|
||||
messages.push({title: "Download", key, status: res.status});
|
||||
const userinfo = res.headers["subscription-userinfo"];
|
||||
const base64userinfo = Buffer.from(userinfo).toString("base64");
|
||||
// 设置强制下载并设置文件名
|
||||
const headers = {
|
||||
"Content-type": "text/plain; charset=utf-8",
|
||||
"content-disposition": `attachment; filename=${key}`,
|
||||
"x-oss-persistent-headers": "Subscription-Userinfo:" + base64userinfo
|
||||
};
|
||||
promises.push(oss.put("SUB/" + key, res.data, headers));
|
||||
}
|
||||
Promise.all(promises).then(values => {
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const res = values[i];
|
||||
const key = Object.keys(database.suburl)[i];
|
||||
messages.push({title: "Upload", key, status: res.res.status});
|
||||
}
|
||||
res.json(messages);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/download', async function (req, res, next) {
|
||||
const repos = ['Dreamacro/clash', 'Fndroid/clash_for_windows_pkg', 'Kr328/ClashForAndroid',
|
||||
'shadowsocks/shadowsocks-android', 'XTLS/Xray-core', '2dust/v2rayN', 'NetchX/Netch', '2dust/v2rayNG',
|
||||
'yichengchen/clashX', 'shadowsocks/shadowsocks-windows',
|
||||
'shadowsocksrr/shadowsocksr-csharp', 'FelisCatus/SwitchyOmega']
|
||||
const auth = {
|
||||
'username': process.env.GITHUB_USERNAME,
|
||||
'password': process.env.GITHUB_TOKEN
|
||||
}
|
||||
const api = 'https://api.github.com/repos/{}/releases/latest'
|
||||
const promises = repos.map(repo => axios.get(api.replace('{}', repo), {auth}))
|
||||
Promise.all(promises).then(values => {
|
||||
let datas = values.map(value => value.data)
|
||||
for (let i = 0; i < datas.length; i++) {
|
||||
datas[i].repo = repos[i]
|
||||
for (asset of datas[i].assets) {
|
||||
asset.size = filesize(asset.size, {base: 2, standard: "jedec"})
|
||||
asset['fastgit_url'] = asset['browser_download_url'].replace('github.com', 'download.fastgit.org')
|
||||
asset['ghproxy_url'] = 'https://mirror.ghproxy.com?q=' + asset['browser_download_url']
|
||||
}
|
||||
}
|
||||
res.render('airportdownload', {datas});
|
||||
});
|
||||
router.get("/download", async function (req, res) {
|
||||
const repos = ["Dreamacro/clash", "Fndroid/clash_for_windows_pkg", "Kr328/ClashForAndroid",
|
||||
"shadowsocks/shadowsocks-android", "XTLS/Xray-core", "2dust/v2rayN", "NetchX/Netch", "2dust/v2rayNG",
|
||||
"yichengchen/clashX", "shadowsocks/shadowsocks-windows",
|
||||
"shadowsocksrr/shadowsocksr-csharp", "FelisCatus/SwitchyOmega"];
|
||||
const auth = {
|
||||
"username": process.env.GITHUB_USERNAME,
|
||||
"password": process.env.GITHUB_TOKEN
|
||||
};
|
||||
const api = "https://api.github.com/repos/{}/releases/latest";
|
||||
const promises = repos.map(repo => axios.get(api.replace("{}", repo), {auth}));
|
||||
Promise.all(promises).then(values => {
|
||||
let datas = values.map(value => value.data);
|
||||
for (let i = 0; i < datas.length; i++) {
|
||||
datas[i].repo = repos[i];
|
||||
for (const asset of datas[i].assets) {
|
||||
asset.size = filesize(asset.size, {base: 2, standard: "jedec"});
|
||||
asset["fastgit_url"] = asset["browser_download_url"].replace("github.com", "download.fastgit.org");
|
||||
asset["ghproxy_url"] = "https://mirror.ghproxy.com?q=" + asset["browser_download_url"];
|
||||
}
|
||||
}
|
||||
res.render("airportdownload", {datas});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
if (!module.parent) {
|
||||
updateDatabase();
|
||||
}
|
||||
updateDatabase();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//引入API组件
|
||||
const Bilibili = require('./bilibili');
|
||||
const Mgtv = require('./mgtv');
|
||||
const Tencentvideo = require('./tencentvideo');
|
||||
const Youku = require('./youku');
|
||||
const Iqiyi = require('./iqiyi');
|
||||
const Bilibili = require("./bilibili");
|
||||
const Mgtv = require("./mgtv");
|
||||
const Tencentvideo = require("./tencentvideo");
|
||||
const Youku = require("./youku");
|
||||
const Iqiyi = require("./iqiyi");
|
||||
// 实例化API组件
|
||||
const bilibili = new Bilibili();
|
||||
const mgtv = new Mgtv();
|
||||
@@ -12,4 +12,4 @@ const youku = new Youku();
|
||||
const iqiyi = new Iqiyi();
|
||||
|
||||
//TODO 优化代码
|
||||
module.exports = { bilibili, mgtv, tencentvideo, youku, iqiyi };
|
||||
module.exports = { bilibili, mgtv, tencentvideo, youku, iqiyi };
|
||||
|
||||
@@ -1,99 +1,97 @@
|
||||
// noinspection EqualityComparisonWithCoercionJS
|
||||
|
||||
const urlmodule = require('url');
|
||||
const axios = require('axios');
|
||||
const got = require('got');
|
||||
const {inflateRawSync} = require('zlib');
|
||||
const urlmodule = require("url");
|
||||
const axios = require("axios");
|
||||
const got = require("got");
|
||||
const {inflateRawSync} = require("zlib");
|
||||
|
||||
function Bilibili() {
|
||||
this.name = 'B站';
|
||||
this.domain = 'bilibili.com';
|
||||
this.example_urls = [
|
||||
'https://www.bilibili.com/video/av170001',
|
||||
'https://www.bilibili.com/video/av170001?p=2',
|
||||
'https://www.bilibili.com/video/BV17x411w7KC?p=3',
|
||||
'https://www.bilibili.com/bangumi/play/ep691614'
|
||||
];
|
||||
this.name = "B站";
|
||||
this.domain = "bilibili.com";
|
||||
this.example_urls = [
|
||||
"https://www.bilibili.com/video/av170001",
|
||||
"https://www.bilibili.com/video/av170001?p=2",
|
||||
"https://www.bilibili.com/video/BV17x411w7KC?p=3",
|
||||
"https://www.bilibili.com/bangumi/play/ep691614"
|
||||
];
|
||||
|
||||
this.resolve = async (url) => {
|
||||
// 相关API
|
||||
const api_video_info = "https://api.bilibili.com/x/web-interface/view"
|
||||
const api_epid_cid = "https://api.bilibili.com/pgc/view/web/season"
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split('/');
|
||||
// 普通投稿视频
|
||||
if (url.indexOf('video/') !== -1) {
|
||||
// 获取视频分P信息
|
||||
const p = q.query.p || 1;
|
||||
// 判断是否为旧版av号
|
||||
let params;
|
||||
if (url.indexOf('BV') !== -1) {
|
||||
params = {'bvid': path.slice(-1)[0]};
|
||||
} else {
|
||||
params = {'aid': path.slice(-1)[0].substring(2)};
|
||||
}
|
||||
const response = await axios.get(api_video_info, {params})
|
||||
if (response.data.code !== 0) {
|
||||
this.error_msg = '获取普通投稿视频信息失败!'
|
||||
return
|
||||
}
|
||||
this.title = response.data.data.title;
|
||||
const subtitle = response.data.data.pages[p - 1].part;
|
||||
this.title = this.title + '-' + subtitle;
|
||||
const cid = response.data.data.pages[p - 1].cid;
|
||||
return [`https://comment.bilibili.com/${cid}.xml`];
|
||||
} // 番剧
|
||||
else if (url.indexOf('bangumi/') !== -1) {
|
||||
const epid = path.slice(-1)[0];
|
||||
const params = {'ep_id': epid.slice(2)};
|
||||
const response = await axios.get(api_epid_cid, {params})
|
||||
if (response.data.code !== 0) {
|
||||
this.error_msg = '获取番剧视频信息失败!'
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < response.data.result.episodes.length; i++) {
|
||||
if (response.data.result.episodes[i].id == params.ep_id) {
|
||||
this.title = response.data.result.episodes[i].share_copy;
|
||||
const cid = response.data.result.episodes[i].cid;
|
||||
return [`https://comment.bilibili.com/${cid}.xml`];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.error_msg = '不支持的B站视频网址,仅支持普通视频(av,bv)、剧集视频(ep)';
|
||||
}
|
||||
this.resolve = async (url) => {
|
||||
// 相关API
|
||||
const api_video_info = "https://api.bilibili.com/x/web-interface/view";
|
||||
const api_epid_cid = "https://api.bilibili.com/pgc/view/web/season";
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split("/");
|
||||
// 普通投稿视频
|
||||
if (url.indexOf("video/") !== -1) {
|
||||
// 获取视频分P信息
|
||||
const p = q.query.p || 1;
|
||||
// 判断是否为旧版av号
|
||||
let params;
|
||||
if (url.indexOf("BV") !== -1) {
|
||||
params = {"bvid": path.slice(-1)[0]};
|
||||
} else {
|
||||
params = {"aid": path.slice(-1)[0].substring(2)};
|
||||
}
|
||||
const response = await axios.get(api_video_info, {params});
|
||||
if (response.data.code !== 0) {
|
||||
this.error_msg = "获取普通投稿视频信息失败!";
|
||||
return;
|
||||
}
|
||||
this.title = response.data.data.title;
|
||||
const subtitle = response.data.data.pages[p - 1].part;
|
||||
this.title = this.title + "-" + subtitle;
|
||||
const cid = response.data.data.pages[p - 1].cid;
|
||||
return [`https://comment.bilibili.com/${cid}.xml`];
|
||||
} // 番剧
|
||||
else if (url.indexOf("bangumi/") !== -1) {
|
||||
const epid = path.slice(-1)[0];
|
||||
const params = {"ep_id": epid.slice(2)};
|
||||
const response = await axios.get(api_epid_cid, {params});
|
||||
if (response.data.code !== 0) {
|
||||
this.error_msg = "获取番剧视频信息失败!";
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < response.data.result.episodes.length; i++) {
|
||||
if (response.data.result.episodes[i].id == params.ep_id) {
|
||||
this.title = response.data.result.episodes[i].share_copy;
|
||||
const cid = response.data.result.episodes[i].cid;
|
||||
return [`https://comment.bilibili.com/${cid}.xml`];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.error_msg = "不支持的B站视频网址,仅支持普通视频(av,bv)、剧集视频(ep)";
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.parse = async (urls) => {
|
||||
// B站使用特殊的压缩方法,需要使用got模块
|
||||
const bufferData = await got(urls[0], {
|
||||
decompress: false
|
||||
}).buffer();
|
||||
const content = inflateRawSync(bufferData).toString();
|
||||
return content
|
||||
}
|
||||
this.parse = async (urls) => {
|
||||
// B站使用特殊的压缩方法,需要使用got模块
|
||||
const bufferData = await got(urls[0], {
|
||||
decompress: false
|
||||
}).buffer();
|
||||
const content = inflateRawSync(bufferData).toString();
|
||||
return content;
|
||||
};
|
||||
|
||||
this.work = async (url) => {
|
||||
const urls = await this.resolve(url);
|
||||
console.log(this.name,'api lens:',urls.length);
|
||||
if (!this.error_msg)
|
||||
this.content = await this.parse(urls);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: this.error_msg? this.error_msg: 'ok'
|
||||
}
|
||||
}
|
||||
this.work = async (url) => {
|
||||
const urls = await this.resolve(url);
|
||||
console.log(this.name,"api lens:",urls.length);
|
||||
if (!this.error_msg)
|
||||
this.content = await this.parse(urls);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: this.error_msg? this.error_msg: "ok"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = Bilibili
|
||||
module.exports = Bilibili;
|
||||
|
||||
if(!module.parent) {
|
||||
const b = new Bilibili();
|
||||
b.work(b.example_urls[0]).then(() => {
|
||||
console.log(b.content);
|
||||
console.log(b.title);
|
||||
});
|
||||
const b = new Bilibili();
|
||||
b.work(b.example_urls[0]).then(() => {
|
||||
console.log(b.content);
|
||||
console.log(b.title);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,106 +1,106 @@
|
||||
const axios = require('axios');
|
||||
const pako = require('pako');
|
||||
const xml2js = require('xml2js');
|
||||
const {time_to_second, make_response, content_template} = require('./utils');
|
||||
const memory = require('../../utils/memory')
|
||||
const axios = require("axios");
|
||||
const pako = require("pako");
|
||||
const xml2js = require("xml2js");
|
||||
const {time_to_second, make_response, content_template} = require("./utils");
|
||||
const memory = require("../../utils/memory");
|
||||
|
||||
//资源消耗大 256M内存扛不住
|
||||
function Iqiyi() {
|
||||
this.name = '爱奇艺'
|
||||
this.domain = 'iqiyi.com'
|
||||
this.example_urls = [
|
||||
'https://www.iqiyi.com/v_19rr1lm35o.html', //api lens 11
|
||||
'https://www.iqiyi.com/v_1wozsa91cfs.html', //api lens 9
|
||||
'https://www.iqiyi.com/v_1zzwhiozqww.html', //api lens 10
|
||||
'http://www.iqiyi.com/v_2ga8zts86ys.html'
|
||||
];
|
||||
this.name = "爱奇艺";
|
||||
this.domain = "iqiyi.com";
|
||||
this.example_urls = [
|
||||
"https://www.iqiyi.com/v_19rr1lm35o.html", //api lens 11
|
||||
"https://www.iqiyi.com/v_1wozsa91cfs.html", //api lens 9
|
||||
"https://www.iqiyi.com/v_1zzwhiozqww.html", //api lens 10
|
||||
"http://www.iqiyi.com/v_2ga8zts86ys.html"
|
||||
];
|
||||
|
||||
this.resolve = async (url) => {
|
||||
const res = await axios({
|
||||
method: 'get',
|
||||
url: "https://proxy-fc-python-fdssfsqzaa.cn-shenzhen.fcapp.run/",
|
||||
params: {url},
|
||||
auth: {username: 'proxy', password: 'proxy'}
|
||||
});
|
||||
const data = res.data
|
||||
const result = data.match(/window.Q.PageInfo.playPageInfo=(.*);/)
|
||||
const page_info = JSON.parse(result[1])
|
||||
// console.log('page_info:', page_info)
|
||||
this.resolve = async (url) => {
|
||||
const res = await axios({
|
||||
method: "get",
|
||||
url: "https://proxy-fc-python-fdssfsqzaa.cn-shenzhen.fcapp.run/",
|
||||
params: {url},
|
||||
auth: {username: "proxy", password: "proxy"}
|
||||
});
|
||||
const data = res.data;
|
||||
const result = data.match(/window.Q.PageInfo.playPageInfo=(.*);/);
|
||||
const page_info = JSON.parse(result[1]);
|
||||
// console.log('page_info:', page_info)
|
||||
|
||||
const duration = time_to_second(page_info.duration)
|
||||
this.title = page_info.tvName ? page_info.tvName : page_info.name
|
||||
const albumid = page_info.albumId
|
||||
const tvid = page_info.tvId.toString()
|
||||
const categoryid = page_info.cid
|
||||
const page = Math.round(duration / (60 * 5))
|
||||
console.log('tvid', tvid)
|
||||
let promises = []
|
||||
for (let i = 0; i < page; i++) {
|
||||
const api_url = `https://cmts.iqiyi.com/bullet/${tvid.slice(-4, -2)}/${tvid.slice(-2)}/${tvid}_300_${i + 1}.z`
|
||||
const params = {
|
||||
rn: '0.0123456789123456',
|
||||
business: 'danmu',
|
||||
is_iqiyi: 'true',
|
||||
is_video_page: 'true',
|
||||
tvid: tvid,
|
||||
albumid: albumid,
|
||||
categoryid: categoryid,
|
||||
qypid: '01010021010000000000'
|
||||
}
|
||||
promises.push(axios({method: 'get', url: api_url, params: params, responseType: 'arraybuffer'}))
|
||||
}
|
||||
return promises
|
||||
}
|
||||
const duration = time_to_second(page_info.duration);
|
||||
this.title = page_info.tvName ? page_info.tvName : page_info.name;
|
||||
const albumid = page_info.albumId;
|
||||
const tvid = page_info.tvId.toString();
|
||||
const categoryid = page_info.cid;
|
||||
const page = Math.round(duration / (60 * 5));
|
||||
console.log("tvid", tvid);
|
||||
let promises = [];
|
||||
for (let i = 0; i < page; i++) {
|
||||
const api_url = `https://cmts.iqiyi.com/bullet/${tvid.slice(-4, -2)}/${tvid.slice(-2)}/${tvid}_300_${i + 1}.z`;
|
||||
const params = {
|
||||
rn: "0.0123456789123456",
|
||||
business: "danmu",
|
||||
is_iqiyi: "true",
|
||||
is_video_page: "true",
|
||||
tvid: tvid,
|
||||
albumid: albumid,
|
||||
categoryid: categoryid,
|
||||
qypid: "01010021010000000000"
|
||||
};
|
||||
promises.push(axios({method: "get", url: api_url, params: params, responseType: "arraybuffer"}));
|
||||
}
|
||||
return promises;
|
||||
};
|
||||
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises)
|
||||
const datas = values
|
||||
.map(value => value.data)
|
||||
.map(value => pako.inflate(value, {to: 'string'}));
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises);
|
||||
const datas = values
|
||||
.map(value => value.data)
|
||||
.map(value => pako.inflate(value, {to: "string"}));
|
||||
|
||||
for (const xml of datas) {
|
||||
const json = await xml2js.parseStringPromise(xml)
|
||||
// console.log(json)
|
||||
global.gc()
|
||||
for (const entry of json.danmu.data[0].entry??[]) {
|
||||
for (const bulletInfo of entry.list[0].bulletInfo??[]){
|
||||
// console.log(bulletInfo)
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = bulletInfo['showTime'][0]//showTime
|
||||
content.color = parseInt(bulletInfo['color'][0], 16)//color
|
||||
content.content = bulletInfo['content'][0] //content
|
||||
content.size = bulletInfo['font'][0]//font
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
memory()
|
||||
}
|
||||
contents = make_response(contents)
|
||||
return contents
|
||||
}
|
||||
for (const xml of datas) {
|
||||
const json = await xml2js.parseStringPromise(xml);
|
||||
// console.log(json)
|
||||
global.gc();
|
||||
for (const entry of json.danmu.data[0].entry??[]) {
|
||||
for (const bulletInfo of entry.list[0].bulletInfo??[]){
|
||||
// console.log(bulletInfo)
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = bulletInfo["showTime"][0];//showTime
|
||||
content.color = parseInt(bulletInfo["color"][0], 16);//color
|
||||
content.content = bulletInfo["content"][0]; //content
|
||||
content.size = bulletInfo["font"][0];//font
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
memory();
|
||||
}
|
||||
contents = make_response(contents);
|
||||
return contents;
|
||||
};
|
||||
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name, 'api lens:', promises.length)
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: 'ok'
|
||||
}
|
||||
}
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name, "api lens:", promises.length);
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: "ok"
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = Iqiyi
|
||||
module.exports = Iqiyi;
|
||||
|
||||
if (!module.parent) {
|
||||
const m = new Iqiyi();
|
||||
const m = new Iqiyi();
|
||||
|
||||
m.work(m.example_urls[2]).then(() => {
|
||||
// console.log(m.content);
|
||||
console.log(m.title);
|
||||
memory();
|
||||
});
|
||||
}
|
||||
m.work(m.example_urls[2]).then(() => {
|
||||
// console.log(m.content);
|
||||
console.log(m.title);
|
||||
memory();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
const urlmodule = require('url');
|
||||
const axios = require('axios');
|
||||
const {time_to_second, make_response, content_template} = require('./utils');
|
||||
const urlmodule = require("url");
|
||||
const axios = require("axios");
|
||||
const {time_to_second, make_response, content_template} = require("./utils");
|
||||
|
||||
function Mgtv() {
|
||||
this.name = '芒果TV'
|
||||
this.domain = 'mgtv.com'
|
||||
this.example_urls = [
|
||||
'https://www.mgtv.com/b/336727/8087768.html',
|
||||
'https://www.mgtv.com/b/459529/17730031.html' //api lens 90
|
||||
];
|
||||
this.name = "芒果TV";
|
||||
this.domain = "mgtv.com";
|
||||
this.example_urls = [
|
||||
"https://www.mgtv.com/b/336727/8087768.html",
|
||||
"https://www.mgtv.com/b/459529/17730031.html" //api lens 90
|
||||
];
|
||||
|
||||
this.resolve = async (url) => {
|
||||
const api_video_info = "https://pcweb.api.mgtv.com/video/info"
|
||||
const api_danmaku = 'https://galaxy.bz.mgtv.com/rdbarrage'
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split('/');
|
||||
const cid = path.slice(-2)[0];
|
||||
const vid = path.slice(-1)[0].split('.')[0];
|
||||
const res = await axios.get(api_video_info, {params: {cid, vid}});
|
||||
this.title = res.data.data.info.videoName;
|
||||
const time = res.data.data.info.time;
|
||||
this.resolve = async (url) => {
|
||||
const api_video_info = "https://pcweb.api.mgtv.com/video/info";
|
||||
const api_danmaku = "https://galaxy.bz.mgtv.com/rdbarrage";
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split("/");
|
||||
const cid = path.slice(-2)[0];
|
||||
const vid = path.slice(-1)[0].split(".")[0];
|
||||
const res = await axios.get(api_video_info, {params: {cid, vid}});
|
||||
this.title = res.data.data.info.videoName;
|
||||
const time = res.data.data.info.time;
|
||||
|
||||
const step = 60 * 1000;
|
||||
const end_time = time_to_second(time) * 1000;
|
||||
let promises = [];
|
||||
for (let i = 0; i < end_time; i += step) {
|
||||
promises.push(axios({method: 'get', url: api_danmaku, params: {vid, cid, time: i}}));
|
||||
}
|
||||
return promises
|
||||
}
|
||||
const step = 60 * 1000;
|
||||
const end_time = time_to_second(time) * 1000;
|
||||
let promises = [];
|
||||
for (let i = 0; i < end_time; i += step) {
|
||||
promises.push(axios({method: "get", url: api_danmaku, params: {vid, cid, time: i}}));
|
||||
}
|
||||
return promises;
|
||||
};
|
||||
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises)
|
||||
let datas = values.map(value => value.data)
|
||||
for (const data of datas) {
|
||||
if (data.data.items === null)
|
||||
continue;
|
||||
for (const item of data.data.items) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = item.time / 1000;
|
||||
content.content = item.content;
|
||||
content.uid = item.uid;
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
contents = make_response(contents)
|
||||
return contents
|
||||
}
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises);
|
||||
let datas = values.map(value => value.data);
|
||||
for (const data of datas) {
|
||||
if (data.data.items === null)
|
||||
continue;
|
||||
for (const item of data.data.items) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = item.time / 1000;
|
||||
content.content = item.content;
|
||||
content.uid = item.uid;
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
contents = make_response(contents);
|
||||
return contents;
|
||||
};
|
||||
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name,'api lens:', promises.length)
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: 'ok'
|
||||
}
|
||||
}
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name,"api lens:", promises.length);
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: "ok"
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = Mgtv
|
||||
module.exports = Mgtv;
|
||||
|
||||
if (!module.parent) {
|
||||
const m = new Mgtv();
|
||||
const m = new Mgtv();
|
||||
|
||||
m.work(m.example_urls[0]).then(() => {
|
||||
console.log(m.content);
|
||||
console.log(m.title);
|
||||
});
|
||||
m.work(m.example_urls[0]).then(() => {
|
||||
console.log(m.content);
|
||||
console.log(m.title);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,93 +1,92 @@
|
||||
const urlmodule = require('url');
|
||||
const axios = require('axios');
|
||||
const urlmodule = require("url");
|
||||
const axios = require("axios");
|
||||
const whacko = require("whacko");
|
||||
const {make_response, content_template} = require('./utils');
|
||||
|
||||
const {make_response, content_template} = require("./utils");
|
||||
|
||||
function Tencentvideo() {
|
||||
this.name = '腾讯视频'
|
||||
this.domain = 'v.qq.com'
|
||||
this.example_urls = [
|
||||
'https://v.qq.com/x/cover/mzc002003pn34qk/u3319i5s3jt.html',
|
||||
'https://v.qq.com/x/cover/53q0eh78q97e4d1/x00174aq5no.html',//api lens 50
|
||||
'https://v.qq.com/x/cover/mzc00200fph94nw/l00448ijvve.html',//api lens 91
|
||||
];
|
||||
this.name = "腾讯视频";
|
||||
this.domain = "v.qq.com";
|
||||
this.example_urls = [
|
||||
"https://v.qq.com/x/cover/mzc002003pn34qk/u3319i5s3jt.html",
|
||||
"https://v.qq.com/x/cover/53q0eh78q97e4d1/x00174aq5no.html",//api lens 50
|
||||
"https://v.qq.com/x/cover/mzc00200fph94nw/l00448ijvve.html",//api lens 91
|
||||
];
|
||||
|
||||
this.resolve = async (url) => {
|
||||
const api_danmaku_base = "https://dm.video.qq.com/barrage/base/"
|
||||
const api_danmaku_segment = "https://dm.video.qq.com/barrage/segment/"
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split('/');
|
||||
let vid;
|
||||
if (q.query.vid) {
|
||||
vid = q.query.vid
|
||||
} else {
|
||||
vid = path.slice(-1)[0].split('.')[0];
|
||||
}
|
||||
let res = await axios.get(url);
|
||||
const $ = whacko.load(res.data, null, false);
|
||||
this.title = $("title")[0].children[0].data.split('_')[0];
|
||||
console.log('vid:', vid,'title:', this.title)
|
||||
try {
|
||||
res = await axios.get(api_danmaku_base + vid);
|
||||
} catch (e) {
|
||||
if (e.response.status === 404) {
|
||||
this.error_msg = '好像没有弹幕哦'
|
||||
return
|
||||
} else throw e
|
||||
}
|
||||
this.resolve = async (url) => {
|
||||
const api_danmaku_base = "https://dm.video.qq.com/barrage/base/";
|
||||
const api_danmaku_segment = "https://dm.video.qq.com/barrage/segment/";
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split("/");
|
||||
let vid;
|
||||
if (q.query.vid) {
|
||||
vid = q.query.vid;
|
||||
} else {
|
||||
vid = path.slice(-1)[0].split(".")[0];
|
||||
}
|
||||
let res = await axios.get(url);
|
||||
const $ = whacko.load(res.data, null, false);
|
||||
this.title = $("title")[0].children[0].data.split("_")[0];
|
||||
console.log("vid:", vid,"title:", this.title);
|
||||
try {
|
||||
res = await axios.get(api_danmaku_base + vid);
|
||||
} catch (e) {
|
||||
if (e.response.status === 404) {
|
||||
this.error_msg = "好像没有弹幕哦";
|
||||
return;
|
||||
} else throw e;
|
||||
}
|
||||
|
||||
let promises = []
|
||||
let list = Object.values(res.data.segment_index)
|
||||
for (item of list) {
|
||||
promises.push(axios.get(`${api_danmaku_segment}${vid}/${item.segment_name}`))
|
||||
}
|
||||
return promises
|
||||
}
|
||||
let promises = [];
|
||||
let list = Object.values(res.data.segment_index);
|
||||
for (const item of list) {
|
||||
promises.push(axios.get(`${api_danmaku_segment}${vid}/${item.segment_name}`));
|
||||
}
|
||||
return promises;
|
||||
};
|
||||
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises)
|
||||
let datas = values.map(value => value.data)
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises);
|
||||
let datas = values.map(value => value.data);
|
||||
|
||||
for (const data of datas) {
|
||||
for (const item of data.barrage_list) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = item.time_offset / 1000;
|
||||
if (item.content_style.color) {
|
||||
const content_style = JSON.stringify(item.content_style.color)
|
||||
console.log("有颜色", content_style);
|
||||
}
|
||||
content.content = item.content;
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
contents = make_response(contents)
|
||||
return contents
|
||||
}
|
||||
for (const data of datas) {
|
||||
for (const item of data.barrage_list) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = item.time_offset / 1000;
|
||||
if (item.content_style.color) {
|
||||
const content_style = JSON.stringify(item.content_style.color);
|
||||
console.log("有颜色", content_style);
|
||||
}
|
||||
content.content = item.content;
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
contents = make_response(contents);
|
||||
return contents;
|
||||
};
|
||||
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
if (!this.error_msg) {
|
||||
console.log(this.name, 'api lens:', promises.length)
|
||||
this.content = await this.parse(promises)
|
||||
}
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: this.error_msg ? this.error_msg : 'ok'
|
||||
}
|
||||
}
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
if (!this.error_msg) {
|
||||
console.log(this.name, "api lens:", promises.length);
|
||||
this.content = await this.parse(promises);
|
||||
}
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: this.error_msg ? this.error_msg : "ok"
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = Tencentvideo
|
||||
module.exports = Tencentvideo;
|
||||
|
||||
if (!module.parent) {
|
||||
console.log('main')
|
||||
const t = new Tencentvideo()
|
||||
t.work(t.example_urls[0]).then(() => {
|
||||
console.log(t.content)
|
||||
console.log(t.title)
|
||||
});
|
||||
}
|
||||
console.log("main");
|
||||
const t = new Tencentvideo();
|
||||
t.work(t.example_urls[0]).then(() => {
|
||||
console.log(t.content);
|
||||
console.log(t.title);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
const convert = require("xml-js");
|
||||
|
||||
const content_template = {
|
||||
timepoint: 0,
|
||||
content: '',
|
||||
ct: 1,
|
||||
size: 20,
|
||||
color: 16777215,
|
||||
unixtime: Math.floor(Date.now() / 1000),
|
||||
uid: 0,
|
||||
timepoint: 0,
|
||||
content: "",
|
||||
ct: 1,
|
||||
size: 20,
|
||||
color: 16777215,
|
||||
unixtime: Math.floor(Date.now() / 1000),
|
||||
uid: 0,
|
||||
};
|
||||
|
||||
function time_to_second(time) {
|
||||
const t = time.split(':');
|
||||
let s = 0;
|
||||
let m = 1;
|
||||
while (t.length > 0) {
|
||||
s += m * parseInt(t.pop(), 10);
|
||||
m *= 60;
|
||||
}
|
||||
return s;
|
||||
const t = time.split(":");
|
||||
let s = 0;
|
||||
let m = 1;
|
||||
while (t.length > 0) {
|
||||
s += m * parseInt(t.pop(), 10);
|
||||
m *= 60;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function make_response(contents) {
|
||||
let xml = {
|
||||
_declaration: {
|
||||
_attributes: {
|
||||
version: '1.0',
|
||||
encoding: 'utf-8'
|
||||
}
|
||||
},
|
||||
i: {
|
||||
d: []
|
||||
}
|
||||
}
|
||||
for (let content of contents) {
|
||||
xml.i.d.push({
|
||||
_attributes: {
|
||||
p: `${content.timepoint},${content.ct},${content.size},${content.color},${content.unixtime},${content.uid},26732601000067074`
|
||||
},
|
||||
_text: content.content
|
||||
});
|
||||
}
|
||||
let xml = {
|
||||
_declaration: {
|
||||
_attributes: {
|
||||
version: "1.0",
|
||||
encoding: "utf-8"
|
||||
}
|
||||
},
|
||||
i: {
|
||||
d: []
|
||||
}
|
||||
};
|
||||
for (let content of contents) {
|
||||
xml.i.d.push({
|
||||
_attributes: {
|
||||
p: `${content.timepoint},${content.ct},${content.size},${content.color},${content.unixtime},${content.uid},26732601000067074`
|
||||
},
|
||||
_text: content.content
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const res = convert.js2xml(xml, {compact: true, spaces: 4})
|
||||
return res
|
||||
const res = convert.js2xml(xml, {compact: true, spaces: 4});
|
||||
return res;
|
||||
}
|
||||
|
||||
module.exports = {time_to_second, make_response, content_template};
|
||||
module.exports = {time_to_second, make_response, content_template};
|
||||
|
||||
@@ -1,166 +1,173 @@
|
||||
const urlmodule = require('url');
|
||||
const axios = require('axios');
|
||||
const cookie = require('cookie');
|
||||
const crypto = require('crypto');
|
||||
const {make_response, content_template} = require('./utils');
|
||||
const urlmodule = require("url");
|
||||
const axios = require("axios");
|
||||
const cookie = require("cookie");
|
||||
const crypto = require("crypto");
|
||||
const {
|
||||
make_response,
|
||||
content_template
|
||||
} = require("./utils");
|
||||
|
||||
function Youku() {
|
||||
this.name = '优酷'
|
||||
this.domain = 'v.youku.com'
|
||||
this.example_urls = [
|
||||
'https://v.youku.com/v_show/id_XNTE5NjUxNjUyOA==.html',
|
||||
'https://v.youku.com/v_show/id_XMTc1OTE4ODI5Ng==.html',
|
||||
'https://v.youku.com/v_show/id_XNTkxNDY2Nzg2MA==.html'
|
||||
];
|
||||
this.name = "优酷";
|
||||
this.domain = "v.youku.com";
|
||||
this.example_urls = [
|
||||
"https://v.youku.com/v_show/id_XNTE5NjUxNjUyOA==.html",
|
||||
"https://v.youku.com/v_show/id_XMTc1OTE4ODI5Ng==.html",
|
||||
"https://v.youku.com/v_show/id_XNTkxNDY2Nzg2MA==.html"
|
||||
];
|
||||
|
||||
this.get_tk_enc = async () => {
|
||||
const api_url = "https://acs.youku.com/h5/mtop.com.youku.aplatform.weakget/1.0/?jsv=2.5.1&appKey=24679788"
|
||||
const res = await axios.get(api_url);
|
||||
const cookies = res.headers['set-cookie']
|
||||
let targetCookie = {};
|
||||
for (let cookieStr of cookies) {
|
||||
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
|
||||
}
|
||||
return targetCookie
|
||||
}
|
||||
this.get_cna = async () => {
|
||||
const api_url = "https://log.mmstat.com/eg.js"
|
||||
const res = await axios.get(api_url);
|
||||
const cookies = res.headers['set-cookie']
|
||||
let targetCookie = {};
|
||||
for (let cookieStr of cookies) {
|
||||
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
|
||||
}
|
||||
return targetCookie['cna']
|
||||
}
|
||||
this.get_tk_enc = async () => {
|
||||
const api_url = "https://acs.youku.com/h5/mtop.com.youku.aplatform.weakget/1.0/?jsv=2.5.1&appKey=24679788";
|
||||
const res = await axios.get(api_url);
|
||||
const cookies = res.headers["set-cookie"];
|
||||
let targetCookie = {};
|
||||
for (let cookieStr of cookies) {
|
||||
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
|
||||
}
|
||||
return targetCookie;
|
||||
};
|
||||
this.get_cna = async () => {
|
||||
const api_url = "https://log.mmstat.com/eg.js";
|
||||
const res = await axios.get(api_url);
|
||||
const cookies = res.headers["set-cookie"];
|
||||
let targetCookie = {};
|
||||
for (let cookieStr of cookies) {
|
||||
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
|
||||
}
|
||||
return targetCookie["cna"];
|
||||
};
|
||||
|
||||
const yk_msg_sign = (msg) => {
|
||||
const md5 = crypto.createHash('md5');
|
||||
return md5.update(msg + "MkmC9SoIw6xCkSKHhJ7b5D2r51kBiREr").digest('hex');
|
||||
}
|
||||
const yk_msg_sign = (msg) => {
|
||||
const md5 = crypto.createHash("md5");
|
||||
return md5.update(msg + "MkmC9SoIw6xCkSKHhJ7b5D2r51kBiREr")
|
||||
.digest("hex");
|
||||
};
|
||||
|
||||
const yk_t_sign = (token, t, appkey, data) => {
|
||||
const text = [token, t, appkey, data].join('&');
|
||||
const md5 = crypto.createHash('md5');
|
||||
return md5.update(text).digest('hex')
|
||||
}
|
||||
const yk_t_sign = (token, t, appkey, data) => {
|
||||
const text = [token, t, appkey, data].join("&");
|
||||
const md5 = crypto.createHash("md5");
|
||||
return md5.update(text)
|
||||
.digest("hex");
|
||||
};
|
||||
|
||||
const get_vinfos_by_video_id = async (url) => {
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split('/');
|
||||
const video_id = path.slice(-1)[0].split('.')[0].slice(3);
|
||||
if (video_id) {
|
||||
// "?client_id=53e6cc67237fc59a&package=com.huawei.hwvplayer.youku&ext=show&video_id={}"
|
||||
const api_url = "https://openapi.youku.com/v2/videos/show.json"
|
||||
const params = {
|
||||
client_id: "53e6cc67237fc59a",
|
||||
video_id: video_id,
|
||||
package: "com.huawei.hwvplayer.youku",
|
||||
ext: "show"
|
||||
}
|
||||
const res = await axios.get(api_url, {params: params})
|
||||
const duration = res.data.duration
|
||||
this.title = res.data.title
|
||||
console.log("video_id:", video_id, 'duration:', duration, 'title:', this.title)
|
||||
return [video_id, duration]
|
||||
}
|
||||
}
|
||||
const get_vinfos_by_video_id = async (url) => {
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split("/");
|
||||
const video_id = path.slice(-1)[0].split(".")[0].slice(3);
|
||||
if (video_id) {
|
||||
// "?client_id=53e6cc67237fc59a&package=com.huawei.hwvplayer.youku&ext=show&video_id={}"
|
||||
const api_url = "https://openapi.youku.com/v2/videos/show.json";
|
||||
const params = {
|
||||
client_id: "53e6cc67237fc59a",
|
||||
video_id: video_id,
|
||||
package: "com.huawei.hwvplayer.youku",
|
||||
ext: "show"
|
||||
};
|
||||
const res = await axios.get(api_url, { params: params });
|
||||
const duration = res.data.duration;
|
||||
this.title = res.data.title;
|
||||
console.log("video_id:", video_id, "duration:", duration, "title:", this.title);
|
||||
return [video_id, duration];
|
||||
}
|
||||
};
|
||||
|
||||
this.resolve = async (url) => {
|
||||
const cna = await this.get_cna()
|
||||
const tk_enc = await this.get_tk_enc()
|
||||
const headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Cookie": '_m_h5_tk=' + tk_enc['_m_h5_tk'] + ';_m_h5_tk_enc=' + tk_enc['_m_h5_tk_enc'] + ';',
|
||||
"Referer": "https://v.youku.com",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
|
||||
}
|
||||
const [vid, duration] = await get_vinfos_by_video_id(url)
|
||||
this.resolve = async (url) => {
|
||||
const cna = await this.get_cna();
|
||||
const tk_enc = await this.get_tk_enc();
|
||||
const headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Cookie": "_m_h5_tk=" + tk_enc["_m_h5_tk"] + ";_m_h5_tk_enc=" + tk_enc["_m_h5_tk_enc"] + ";",
|
||||
"Referer": "https://v.youku.com",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
|
||||
};
|
||||
const [vid, duration] = await get_vinfos_by_video_id(url);
|
||||
|
||||
const max_mat = Math.floor(duration / 60) + 1
|
||||
let promises = []
|
||||
for (let mat = 0; mat < max_mat; mat++) {
|
||||
const api_url = "https://acs.youku.com/h5/mopen.youku.danmu.list/1.0/"
|
||||
const msg = {
|
||||
"ctime": Date.now(),
|
||||
"ctype": 10004,
|
||||
"cver": "v1.0",
|
||||
"guid": cna,
|
||||
"mat": mat,
|
||||
"mcount": 1,
|
||||
"pid": 0,
|
||||
"sver": "3.1.0",
|
||||
"type": 1,
|
||||
"vid": vid
|
||||
}
|
||||
// plain-text string
|
||||
const str = JSON.stringify(msg);
|
||||
const buff = Buffer.from(str, 'utf-8');
|
||||
const msg_b64encode = buff.toString('base64');
|
||||
msg['msg'] = msg_b64encode
|
||||
msg['sign'] = yk_msg_sign(msg_b64encode)
|
||||
const data = JSON.stringify(msg)
|
||||
const t = Date.now()
|
||||
const params = {
|
||||
"jsv": "2.5.6",
|
||||
"appKey": "24679788",
|
||||
"t": t,
|
||||
"sign": yk_t_sign(tk_enc["_m_h5_tk"].slice(0, 32), t, "24679788", data),
|
||||
"api": "mopen.youku.danmu.list",
|
||||
"v": "1.0",
|
||||
"type": "originaljson",
|
||||
"dataType": "jsonp",
|
||||
"timeout": "20000",
|
||||
"jsonpIncPrefix": "utility"
|
||||
}
|
||||
promises.push(axios.post(api_url, {data}, {headers: headers, params: params}))
|
||||
}
|
||||
return promises
|
||||
}
|
||||
const max_mat = Math.floor(duration / 60) + 1;
|
||||
let promises = [];
|
||||
for (let mat = 0; mat < max_mat; mat++) {
|
||||
const api_url = "https://acs.youku.com/h5/mopen.youku.danmu.list/1.0/";
|
||||
const msg = {
|
||||
"ctime": Date.now(),
|
||||
"ctype": 10004,
|
||||
"cver": "v1.0",
|
||||
"guid": cna,
|
||||
"mat": mat,
|
||||
"mcount": 1,
|
||||
"pid": 0,
|
||||
"sver": "3.1.0",
|
||||
"type": 1,
|
||||
"vid": vid
|
||||
};
|
||||
// plain-text string
|
||||
const str = JSON.stringify(msg);
|
||||
const buff = Buffer.from(str, "utf-8");
|
||||
const msg_b64encode = buff.toString("base64");
|
||||
msg["msg"] = msg_b64encode;
|
||||
msg["sign"] = yk_msg_sign(msg_b64encode);
|
||||
const data = JSON.stringify(msg);
|
||||
const t = Date.now();
|
||||
const params = {
|
||||
"jsv": "2.5.6",
|
||||
"appKey": "24679788",
|
||||
"t": t,
|
||||
"sign": yk_t_sign(tk_enc["_m_h5_tk"].slice(0, 32), t, "24679788", data),
|
||||
"api": "mopen.youku.danmu.list",
|
||||
"v": "1.0",
|
||||
"type": "originaljson",
|
||||
"dataType": "jsonp",
|
||||
"timeout": "20000",
|
||||
"jsonpIncPrefix": "utility"
|
||||
};
|
||||
promises.push(axios.post(api_url, { data }, {
|
||||
headers: headers,
|
||||
params: params
|
||||
}));
|
||||
}
|
||||
return promises;
|
||||
};
|
||||
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises)
|
||||
let datas = values.map(value => value.data)
|
||||
this.parse = async (promises) => {
|
||||
let contents = [];
|
||||
const values = await Promise.all(promises);
|
||||
let datas = values.map(value => value.data);
|
||||
|
||||
let i = 0;
|
||||
for (const res of datas) {
|
||||
i ++;
|
||||
const danmus = JSON.parse(res.data.result).data.result
|
||||
// 接口请求情况
|
||||
// console.log(i, res.ret[0])
|
||||
for (danmu of danmus) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = danmu["playat"] / 1000
|
||||
if (danmu.propertis.color) {
|
||||
content.color = JSON.parse(danmu.propertis).color
|
||||
}
|
||||
content.content = danmu.content
|
||||
contents.push(content)
|
||||
}
|
||||
}
|
||||
contents = make_response(contents)
|
||||
return contents
|
||||
}
|
||||
for (const res of datas) {
|
||||
const danmus = JSON.parse(res.data.result).data.result;
|
||||
// 接口请求情况
|
||||
// console.log(i, res.ret[0])
|
||||
for (const danmu of danmus) {
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = danmu["playat"] / 1000;
|
||||
if (danmu.propertis.color) {
|
||||
content.color = JSON.parse(danmu.propertis).color;
|
||||
}
|
||||
content.content = danmu.content;
|
||||
contents.push(content);
|
||||
}
|
||||
}
|
||||
contents = make_response(contents);
|
||||
return contents;
|
||||
};
|
||||
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name, 'api lens:', promises.length)
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: 'ok'
|
||||
}
|
||||
}
|
||||
this.work = async (url) => {
|
||||
const promises = await this.resolve(url);
|
||||
console.log(this.name, "api lens:", promises.length);
|
||||
this.content = await this.parse(promises);
|
||||
return {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
msg: "ok"
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Youku
|
||||
module.exports = Youku;
|
||||
|
||||
if (!module.parent) {
|
||||
const b = new Youku();
|
||||
b.work(b.example_urls[0]).then(() => {
|
||||
console.log(b.content);
|
||||
console.log(b.title);
|
||||
});
|
||||
const b = new Youku();
|
||||
b.work(b.example_urls[0])
|
||||
.then(() => {
|
||||
console.log(b.content);
|
||||
console.log(b.title);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
const express = require('express');
|
||||
const axios = require('axios');
|
||||
const express = require("express");
|
||||
const axios = require("axios");
|
||||
const router = express.Router();
|
||||
const {bilibili, mgtv, tencentvideo, youku, iqiyi} = require('./api/base');
|
||||
const {bilibili, mgtv, tencentvideo, youku, iqiyi} = require("./api/base");
|
||||
const list = [bilibili, mgtv, tencentvideo, youku, iqiyi];
|
||||
const memory = require('../utils/memory')
|
||||
const leancloud = require('../utils/leancloud')
|
||||
const memory = require("../utils/memory");
|
||||
const leancloud = require("../utils/leancloud");
|
||||
|
||||
async function build_response(url, req) {
|
||||
try {
|
||||
await axios.get(url)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return {msg: '传入的链接非法!请检查链接是否能在浏览器正常打开'}
|
||||
}
|
||||
let fc = undefined;
|
||||
for (let item of list) {
|
||||
if (url.indexOf(item.domain) !== -1) {
|
||||
fc = item
|
||||
}
|
||||
}
|
||||
if (fc === undefined) {
|
||||
return {'msg': '不支持的视频网址'}
|
||||
}
|
||||
let ret;
|
||||
try {
|
||||
ret = await fc.work(url)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
let err = JSON.stringify(e, Object.getOwnPropertyNames(e))
|
||||
err = JSON.parse(err)
|
||||
leancloud.add('DanmakuError', {ip: req.ip, url, err})
|
||||
return {msg: '弹幕解析过程中程序报错退出,请等待管理员修复!或者换条链接试试!'}
|
||||
}
|
||||
return ret
|
||||
try {
|
||||
await axios.get(url);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return {msg: "传入的链接非法!请检查链接是否能在浏览器正常打开"};
|
||||
}
|
||||
let fc = undefined;
|
||||
for (let item of list) {
|
||||
if (url.indexOf(item.domain) !== -1) {
|
||||
fc = item;
|
||||
}
|
||||
}
|
||||
if (fc === undefined) {
|
||||
return {"msg": "不支持的视频网址"};
|
||||
}
|
||||
let ret;
|
||||
try {
|
||||
ret = await fc.work(url);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
let err = JSON.stringify(e, Object.getOwnPropertyNames(e));
|
||||
err = JSON.parse(err);
|
||||
leancloud.add("DanmakuError", {ip: req.ip, url, err});
|
||||
return {msg: "弹幕解析过程中程序报错退出,请等待管理员修复!或者换条链接试试!"};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', async function (req, res, next) {
|
||||
leancloud.add('DanmakuAccess', {remoteIP: req.ip, url: req.query.url, UA: req.headers['user-agent']})
|
||||
//检查是否包含URL参数
|
||||
if (!req.query.url) {
|
||||
const urls = [mgtv.example_urls[0], bilibili.example_urls[0], tencentvideo.example_urls[0], youku.example_urls[0], iqiyi.example_urls[0]];
|
||||
const path = req.protocol + '://' + req.headers.host + req.originalUrl;
|
||||
res.render('danmaku', {path, urls});
|
||||
} else {
|
||||
const url = req.query.url;
|
||||
const download = (req.query.download === 'on');
|
||||
const ret = await build_response(url, req)
|
||||
memory() //显示内存使用量
|
||||
if (ret.msg !== 'ok') {
|
||||
res.status(403).send(ret.msg)
|
||||
} else if (download) {
|
||||
res.attachment(ret.title + '.xml');
|
||||
res.end(ret.content);
|
||||
} else {
|
||||
res.type('application/xml');
|
||||
res.end(ret.content);
|
||||
}
|
||||
}
|
||||
router.get("/", async function (req, res) {
|
||||
leancloud.add("DanmakuAccess", {remoteIP: req.ip, url: req.query.url, UA: req.headers["user-agent"]});
|
||||
//检查是否包含URL参数
|
||||
if (!req.query.url) {
|
||||
const urls = [mgtv.example_urls[0], bilibili.example_urls[0], tencentvideo.example_urls[0], youku.example_urls[0], iqiyi.example_urls[0]];
|
||||
const path = req.protocol + "://" + req.headers.host + req.originalUrl;
|
||||
res.render("danmaku", {path, urls});
|
||||
} else {
|
||||
const url = req.query.url;
|
||||
const download = (req.query.download === "on");
|
||||
const ret = await build_response(url, req);
|
||||
memory(); //显示内存使用量
|
||||
if (ret.msg !== "ok") {
|
||||
res.status(403).send(ret.msg);
|
||||
} else if (download) {
|
||||
res.attachment(ret.title + ".xml");
|
||||
res.end(ret.content);
|
||||
} else {
|
||||
res.type("application/xml");
|
||||
res.end(ret.content);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/pageinfo', async function (req, res, next) {
|
||||
const promises = [
|
||||
leancloud.danmakuQuery(leancloud.currentDay()),
|
||||
leancloud.danmakuQuery(leancloud.lastDay()),
|
||||
leancloud.danmakuQuery(leancloud.currentMonth())
|
||||
]
|
||||
const [today_visited, lastday_visited, month_visited] = await Promise.all(promises)
|
||||
res.json({today_visited, lastday_visited, month_visited})
|
||||
router.get("/pageinfo", async function (req, res) {
|
||||
const promises = [
|
||||
leancloud.danmakuQuery(leancloud.currentDay()),
|
||||
leancloud.danmakuQuery(leancloud.lastDay()),
|
||||
leancloud.danmakuQuery(leancloud.currentMonth())
|
||||
];
|
||||
const [today_visited, lastday_visited, month_visited] = await Promise.all(promises);
|
||||
res.json({today_visited, lastday_visited, month_visited});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
const express = require('express');
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const libqqwry = require('lib-qqwry');
|
||||
const dns = require('dns');
|
||||
const libqqwry = require("lib-qqwry");
|
||||
const dns = require("dns");
|
||||
const qqwry = libqqwry(); //初始化IP库解析器
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function (req, res, next) {
|
||||
let ip = req.query.name || req.ip;
|
||||
dns.lookup(ip, (err, address, family) => {
|
||||
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("/", 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);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -4,23 +4,22 @@ const chai = require("chai");
|
||||
const chaiHttp = require("chai-http");
|
||||
const app = require("../app");
|
||||
|
||||
|
||||
function subcache() {
|
||||
console.log("Running Cron Job:subcache");
|
||||
chai.use(chaiHttp);
|
||||
chai.request(app)
|
||||
.get('/sub/cache')
|
||||
.end((err, res) => {
|
||||
leancloud.add('Schedule', {name: 'subcache', result: res.text});
|
||||
console.log(res.text);
|
||||
});
|
||||
console.log("Running Cron Job:subcache");
|
||||
chai.use(chaiHttp);
|
||||
chai.request(app)
|
||||
.get("/sub/cache")
|
||||
.end((err, res) => {
|
||||
leancloud.add("Schedule", {name: "subcache", result: res.text});
|
||||
console.log(res.text);
|
||||
});
|
||||
}
|
||||
|
||||
cron.schedule('0 12/3 * * *', () => {
|
||||
subcache();
|
||||
cron.schedule("0 * * * *", () => {
|
||||
subcache();
|
||||
});
|
||||
//TODO 添加自动删除一个月前的日志
|
||||
console.log('schedule.js loaded');
|
||||
if (!module.parent) {
|
||||
subcache();
|
||||
}
|
||||
console.log("schedule.js loaded");
|
||||
// if (!module.parent) {
|
||||
// subcache();
|
||||
// }
|
||||
|
||||
347
test/App.test.js
347
test/App.test.js
@@ -1,180 +1,179 @@
|
||||
let chai = require('chai');
|
||||
let chaiHttp = require('chai-http');
|
||||
let app = require('../app');
|
||||
const { bilibili, mgtv, tencentvideo, youku, iqiyi } = require('../routes/api/base');
|
||||
let chai = require("chai");
|
||||
let chaiHttp = require("chai-http");
|
||||
let app = require("../app");
|
||||
const { bilibili, mgtv, tencentvideo, youku, iqiyi } = require("../routes/api/base");
|
||||
const list = [bilibili, mgtv, tencentvideo, youku, iqiyi];
|
||||
|
||||
let should = chai.should();
|
||||
chai.should();
|
||||
chai.use(chaiHttp);
|
||||
|
||||
//TODO: add more test cases
|
||||
describe('App', () => {
|
||||
describe("App", () => {
|
||||
|
||||
describe('弹幕解析模块测试', function () {
|
||||
this.timeout(1000*10);
|
||||
it('主页测试', (done) => {
|
||||
chai.request(app)
|
||||
.get('/')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('页面统计计数测试', (done) => {
|
||||
chai.request(app)
|
||||
.get('/pageinfo')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('传入无法打开的url测试', (done) => {
|
||||
chai.request(app)
|
||||
.get('/?url=ababa')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('传入不支持的网址', (done) => {
|
||||
chai.request(app)
|
||||
.get('/?url=https://tv.sohu.com/v/MjAyMDA2MjYvbjYwMDg3NDcwOS5zaHRtbA==.html')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
for (const item of list) {
|
||||
const name = item.name;
|
||||
const example_urls = item.example_urls;
|
||||
for (const i in example_urls) {
|
||||
const url = example_urls[i];
|
||||
it(name+'视频测试#'+i, (done) => {
|
||||
chai.request(app)
|
||||
.get('/')
|
||||
.query({url})
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
res.header['content-type'].should.equal('application/xml');
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
describe("弹幕解析模块测试", function () {
|
||||
this.timeout(1000*10);
|
||||
it("主页测试", (done) => {
|
||||
chai.request(app)
|
||||
.get("/")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("页面统计计数测试", (done) => {
|
||||
chai.request(app)
|
||||
.get("/pageinfo")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("传入无法打开的url测试", (done) => {
|
||||
chai.request(app)
|
||||
.get("/?url=ababa")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("传入不支持的网址", (done) => {
|
||||
chai.request(app)
|
||||
.get("/?url=https://tv.sohu.com/v/MjAyMDA2MjYvbjYwMDg3NDcwOS5zaHRtbA==.html")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
for (const item of list) {
|
||||
const name = item.name;
|
||||
const example_urls = item.example_urls;
|
||||
for (const i in example_urls) {
|
||||
const url = example_urls[i];
|
||||
it(name+"视频测试#"+i, (done) => {
|
||||
chai.request(app)
|
||||
.get("/")
|
||||
.query({url})
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
res.header["content-type"].should.equal("application/xml");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
it('should respond status 404', (done) => {
|
||||
chai.request(app)
|
||||
.get('/wrongUrl')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
describe('ipinfo modules', () => {
|
||||
it('GET the ipinfo response', (done) => {
|
||||
chai.request(app)
|
||||
.get('/ipinfo')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('GET the ipinfo with name', (done) => {
|
||||
chai.request(app)
|
||||
.get('/ipinfo?name=home999.cc')
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('机场订阅模块',function (){
|
||||
this.timeout(1000*5);
|
||||
it('接口不带参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口错误参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?abc=123')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口带user参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=congcong')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口错误user参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=123')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口带user与ctype参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=congcong&ctype=v2ray')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口带user与错误ctype参数测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=congcong&ctype=abaaba')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口带user与ctype参数测试,带Mozilla UA', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=congcong&ctype=v2ray')
|
||||
.set('User-Agent','Mozilla/5.0 ')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('接口带user,订阅过期测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub?user=test&ctype=v2ray')
|
||||
.set('User-Agent','Mozilla/5.0 ')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('缓存测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub/cache')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('软件下载测试', (done) =>{
|
||||
chai.request(app)
|
||||
.get('/sub/download')
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
res.text.should.have.string('clash');
|
||||
res.text.should.have.string('v2ray');
|
||||
res.text.should.have.string('shadowsocks');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it("should respond status 404", (done) => {
|
||||
chai.request(app)
|
||||
.get("/wrongUrl")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
describe("ipinfo modules", () => {
|
||||
it("GET the ipinfo response", (done) => {
|
||||
chai.request(app)
|
||||
.get("/ipinfo")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("GET the ipinfo with name", (done) => {
|
||||
chai.request(app)
|
||||
.get("/ipinfo?name=home999.cc")
|
||||
.end((err, res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("机场订阅模块",function (){
|
||||
this.timeout(1000*5);
|
||||
it("接口不带参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口错误参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?abc=123")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(400);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口带user参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=congcong")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口错误user参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=123")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口带user与ctype参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=congcong&ctype=v2ray")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口带user与错误ctype参数测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=congcong&ctype=abaaba")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口带user与ctype参数测试,带Mozilla UA", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=congcong&ctype=v2ray")
|
||||
.set("User-Agent","Mozilla/5.0 ")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("接口带user,订阅过期测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub?user=test&ctype=v2ray")
|
||||
.set("User-Agent","Mozilla/5.0 ")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("缓存测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub/cache")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("软件下载测试", (done) =>{
|
||||
chai.request(app)
|
||||
.get("/sub/download")
|
||||
.end((err,res) => {
|
||||
res.should.have.status(200);
|
||||
res.text.should.have.string("clash");
|
||||
res.text.should.have.string("v2ray");
|
||||
res.text.should.have.string("shadowsocks");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
33
tgbot/bot.js
33
tgbot/bot.js
@@ -1,19 +1,20 @@
|
||||
require('dotenv').config({path: '../.env'});
|
||||
const memory = require('../utils/memory');
|
||||
const hkaliyun = require('./bot/hkaliyun.js');
|
||||
const airportsub = require('./bot/airportsub.js');
|
||||
require("dotenv").config({path: "../.env"});
|
||||
const memory = require("../utils/memory");
|
||||
const hkaliyun = require("./bot/hkaliyun.js");
|
||||
const airportsub = require("./bot/airportsub.js");
|
||||
|
||||
bots = [
|
||||
hkaliyun(process.env.TELEGRAM_TOKEN_HKALIYUN),
|
||||
airportsub(process.env.TELEGRAM_TOKEN_AIRPORTSUB),
|
||||
const bots = [
|
||||
hkaliyun(process.env.TELEGRAM_TOKEN_HKALIYUN),
|
||||
airportsub(process.env.TELEGRAM_TOKEN_AIRPORTSUB),
|
||||
];
|
||||
console.log('bot.js loaded');
|
||||
memory()
|
||||
console.log("bot.js loaded");
|
||||
memory();
|
||||
for (const bot of bots) {
|
||||
bot.getMe().then((botInfo) => {
|
||||
console.log('Bot info:', botInfo);
|
||||
});
|
||||
// bot.getWebHookInfo().then((webhookInfo) => {
|
||||
// console.log('Webhook info:', webhookInfo);
|
||||
// });
|
||||
}
|
||||
bot.getMe().then((botInfo) => {
|
||||
console.log("Bot info:", botInfo);
|
||||
});
|
||||
bot.deleteWebHook();
|
||||
// bot.getWebHookInfo().then((webhookInfo) => {
|
||||
// console.log('Webhook info:', webhookInfo);
|
||||
// });
|
||||
}
|
||||
|
||||
@@ -1,215 +1,223 @@
|
||||
// Import modules
|
||||
const whacko = require('whacko');
|
||||
const yaml = require('js-yaml');
|
||||
const TelegramBot = require('node-telegram-bot-api');
|
||||
const goindex = require('./goindex');
|
||||
const axios = require('axios');
|
||||
const OSS = require('ali-oss');
|
||||
const whacko = require("whacko");
|
||||
const yaml = require("js-yaml");
|
||||
const TelegramBot = require("node-telegram-bot-api");
|
||||
const axios = require("axios");
|
||||
const OSS = require("ali-oss");
|
||||
const goindex = require("./goindex");
|
||||
|
||||
// Environment variables
|
||||
const OSS_OPTIONS = {
|
||||
region: 'oss-cn-hongkong',
|
||||
accessKeyId: process.env.OSS_ACCESS_KEY,
|
||||
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
|
||||
bucket: 'hkosslog'
|
||||
region: "oss-cn-hongkong",
|
||||
accessKeyId: process.env.OSS_ACCESS_KEY,
|
||||
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
|
||||
bucket: "hkosslog",
|
||||
};
|
||||
|
||||
// function sleep(ms) {
|
||||
// return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
// }
|
||||
|
||||
module.exports = (TOKEN) => {
|
||||
let game = {};
|
||||
const bot = new TelegramBot(TOKEN, {polling: true});
|
||||
const client = new OSS(OSS_OPTIONS);
|
||||
const game = {};
|
||||
let setu = {};
|
||||
const bot = new TelegramBot(TOKEN, { polling: true });
|
||||
const client = new OSS(OSS_OPTIONS);
|
||||
|
||||
function sendSetu(chatId, i) {
|
||||
const href = setu[i];
|
||||
const prev = { text: "上一张", callback_data: i - 1 };
|
||||
const next = { text: "下一张", callback_data: i + 1 };
|
||||
let replyMarkup = { inline_keyboard: [[prev, next]] };
|
||||
if (i === 0) {
|
||||
replyMarkup = { inline_keyboard: [[next]] };
|
||||
} else if (i+1 === setu.length) {
|
||||
replyMarkup = { inline_keyboard: [[prev]] };
|
||||
}
|
||||
bot.sendMessage(chatId, href, { reply_markup: replyMarkup });
|
||||
}
|
||||
|
||||
// Just to ping!
|
||||
bot.on('message', msg => {
|
||||
if (!msg.text) {
|
||||
bot.sendMessage(msg.chat.id, 'I can only understand text messages!');
|
||||
}
|
||||
});
|
||||
// Just to ping!
|
||||
bot.on("message", (msg) => {
|
||||
if (!msg.text) {
|
||||
bot.sendMessage(msg.chat.id, "I can only understand text messages!");
|
||||
}
|
||||
});
|
||||
|
||||
// 智能聊天机器人
|
||||
bot.on('text', msg => {
|
||||
if (msg.text.indexOf('/') === -1) {
|
||||
bot.sendMessage(msg.chat.id, 'you said: ' + msg.text);
|
||||
axios.get('https://api.qingyunke.com/api.php?key=free&appid=0&msg=' + encodeURI(msg.text)).then(res => {
|
||||
console.log(res.data);
|
||||
bot.sendMessage(msg.chat.id, res.data.content);
|
||||
});
|
||||
}
|
||||
});
|
||||
// 智能聊天机器人
|
||||
bot.on("text", (msg) => {
|
||||
if (msg.text.indexOf("/") === -1) {
|
||||
bot.sendMessage(msg.chat.id, `you said: ${msg.text}`);
|
||||
axios.get(`https://api.qingyunke.com/api.php?key=free&appid=0&msg=${encodeURI(msg.text)}`).then((res) => {
|
||||
console.log(res.data);
|
||||
bot.sendMessage(msg.chat.id, res.data.content);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 欢迎页面
|
||||
bot.onText(/\/start/, (msg) => {
|
||||
let name = [msg.from.first_name];
|
||||
if (msg.from.last_name) {
|
||||
name.push(msg.from.last_name);
|
||||
}
|
||||
name = name.join(" ");
|
||||
bot.sendMessage(msg.chat.id, `Welcome, ${name}!`);
|
||||
bot.sendMessage(msg.chat.id, `You can send me any message and I will repeat it back to you.`);
|
||||
bot.sendMessage(msg.chat.id, `You can also send me commands like /start, /help.`);
|
||||
});
|
||||
// 欢迎页面
|
||||
bot.onText(/\/start/, (msg) => {
|
||||
let name = [msg.from.first_name];
|
||||
if (msg.from.last_name) {
|
||||
name.push(msg.from.last_name);
|
||||
}
|
||||
name = name.join(" ");
|
||||
bot.sendMessage(msg.chat.id, `Welcome, ${name}!`);
|
||||
bot.sendMessage(msg.chat.id, "你可以给我发送消息,我会回复你.");
|
||||
bot.sendMessage(msg.chat.id, "你可以发送类似这样的指令 /start, /help.");
|
||||
});
|
||||
|
||||
// 发送用户头像
|
||||
bot.onText(/\/sendpic/, (msg) => {
|
||||
bot.getUserProfilePhotos(msg.chat.id).then(photos => {
|
||||
const photo = photos.photos[0][0];
|
||||
bot.sendPhoto(msg.chat.id, photo.file_id, {
|
||||
caption: "This is a picture of You!"
|
||||
});
|
||||
});
|
||||
// bot.sendPhoto(msg.chat.id, "https://blog.home999.cc/images/avatar.jpg");
|
||||
});
|
||||
// 发送用户头像
|
||||
bot.onText(/\/sendpic/, (msg) => {
|
||||
bot.getUserProfilePhotos(msg.chat.id).then((photos) => {
|
||||
const photo = photos.photos[0][0];
|
||||
bot.sendPhoto(msg.chat.id, photo.file_id, {
|
||||
caption: "This is a picture of You!",
|
||||
});
|
||||
});
|
||||
// bot.sendPhoto(msg.chat.id, "https://blog.home999.cc/images/avatar.jpg");
|
||||
});
|
||||
|
||||
bot.onText(/\/register/, (msg) => {
|
||||
bot.sendMessage(msg.chat.id, `Chat id: ${msg.chat.id}\n请把该id告诉管理员用于注册。`);
|
||||
});
|
||||
bot.onText(/\/register/, (msg) => {
|
||||
bot.sendMessage(msg.chat.id, `Chat id: ${msg.chat.id}\n请把该id告诉管理员用于注册。`);
|
||||
});
|
||||
|
||||
bot.onText(/\/sub/, async (msg) => {
|
||||
const database = await (await client.get("SUB/database.yaml")).content.toString();
|
||||
const data = yaml.load(database);
|
||||
const users = data.user;
|
||||
for (let user in users) {
|
||||
if (users[user].chatID == msg.chat.id) {
|
||||
bot.sendMessage(msg.chat.id, `您已经注册过了,请勿重复注册。`);
|
||||
bot.sendMessage(msg.chat.id, `你好,${user}。`);
|
||||
const url = `https://fc.home999.cc/sub?user=${user}`;
|
||||
bot.sendMessage(msg.chat.id, `您的订阅链接为:${url}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bot.sendMessage(msg.chat.id, `您已经成功注册,请等待管理员审核`);
|
||||
});
|
||||
bot.onText(/\/sub/, async (msg) => {
|
||||
const database = await (await client.get("SUB/database.yaml")).content.toString();
|
||||
const data = yaml.load(database);
|
||||
const users = data.user;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const user in users) {
|
||||
if (users[user].chatID === msg.chat.id) {
|
||||
bot.sendMessage(msg.chat.id, "您已经注册过了,请勿重复注册。");
|
||||
bot.sendMessage(msg.chat.id, `你好,${user}。`);
|
||||
const url = `https://fc.home999.cc/sub?user=${user}`;
|
||||
bot.sendMessage(msg.chat.id, `您的订阅链接为:${url}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bot.sendMessage(msg.chat.id, "您已经成功注册,请等待管理员审核");
|
||||
});
|
||||
|
||||
//猜数游戏
|
||||
bot.onText(/\/game/, (msg) => {
|
||||
const chatID = msg.chat.id;
|
||||
const guess = parseInt(msg.text.replace("/game", ""));
|
||||
if (game[chatID] == undefined) {
|
||||
game[chatID] = {
|
||||
num: Math.floor(Math.random() * 100),
|
||||
limit: 10,
|
||||
}
|
||||
bot.sendMessage(chatID, `我们来玩猜数游戏吧!`);
|
||||
bot.sendMessage(chatID, `猜一个数字,你有10次机会。范围:[0, 100)`);
|
||||
bot.sendMessage(chatID, `请输入你的猜测:(例:/game 50)`);
|
||||
return;
|
||||
}
|
||||
let {num, limit} = game[chatID];
|
||||
if (limit <= 0) {
|
||||
bot.sendMessage(chatID, `游戏结束!未猜出正确答案,正确答案为:${num}`);
|
||||
game[chatID] = undefined;
|
||||
return;
|
||||
}
|
||||
game[chatID].limit--;
|
||||
if (guess == num) {
|
||||
bot.sendMessage(chatID, `恭喜你猜对了!`);
|
||||
game[chatID] = undefined;
|
||||
} else if (guess > num) {
|
||||
bot.sendMessage(chatID, `你猜的数字太大了!`);
|
||||
} else {
|
||||
bot.sendMessage(chatID, `你猜的数字太小了!`);
|
||||
}
|
||||
});
|
||||
// 猜数游戏
|
||||
bot.onText(/\/game/, async (msg) => {
|
||||
const chatID = msg.chat.id;
|
||||
const guess = parseInt(msg.text.replace("/game", ""), 10);
|
||||
if (game[chatID] === undefined) {
|
||||
game[chatID] = {
|
||||
num: Math.floor(Math.random() * 100),
|
||||
limit: 10,
|
||||
};
|
||||
await bot.sendMessage(chatID, "我们来玩猜数游戏吧!");
|
||||
await bot.sendMessage(chatID, "猜一个数字,你有10次机会。范围:[0, 100)");
|
||||
await bot.sendMessage(chatID, "请输入你的猜测:(例:/game 50)");
|
||||
return;
|
||||
}
|
||||
const { num, limit } = game[chatID];
|
||||
if (limit <= 0) {
|
||||
bot.sendMessage(chatID, `游戏结束!未猜出正确答案,正确答案为:${num}`);
|
||||
game[chatID] = undefined;
|
||||
return;
|
||||
}
|
||||
game[chatID].limit -= 1;
|
||||
if (guess === num) {
|
||||
bot.sendMessage(chatID, "恭喜你猜对了!");
|
||||
game[chatID] = undefined;
|
||||
} else if (guess > num) {
|
||||
bot.sendMessage(chatID, "你猜的数字太大了!");
|
||||
} else {
|
||||
bot.sendMessage(chatID, "你猜的数字太小了!");
|
||||
}
|
||||
});
|
||||
|
||||
bot.onText(/\/help/, (msg) => {
|
||||
const helpMsg = [
|
||||
{command: 'start', description: '欢迎界面'},
|
||||
{command: 'game', description: '猜数游戏'},
|
||||
{command: 'sub', description: '订阅链接'},
|
||||
{command: 'register', description: '注册'},
|
||||
{command: 'sendpic', description: '发送你的头像'},
|
||||
{command: 'setu', description: '随机色图,可加编号'},
|
||||
{command: 'goindex', description: '查询GoIndex上的文件'},
|
||||
{command: 'help', description: '帮助'},
|
||||
];
|
||||
const helpMsgText = helpMsg.map(item => {
|
||||
return `/${item.command} - ${item.description}`;
|
||||
}).join("\n");
|
||||
bot.sendMessage(msg.chat.id, helpMsgText, {parse_mode: "HTML"});
|
||||
bot.setMyCommands(helpMsg);
|
||||
});
|
||||
bot.onText(/\/help/, (msg) => {
|
||||
const helpMsg = [
|
||||
{ command: "start", description: "欢迎界面" },
|
||||
{ command: "game", description: "猜数游戏" },
|
||||
{ command: "sub", description: "订阅链接" },
|
||||
{ command: "register", description: "注册" },
|
||||
{ command: "sendpic", description: "发送你的头像" },
|
||||
{ command: "setu", description: "随机色图,可加编号" },
|
||||
{ command: "goindex", description: "查询GoIndex上的文件" },
|
||||
{ command: "help", description: "帮助" },
|
||||
];
|
||||
const helpMsgText = helpMsg.map((item) => `/${item.command} - ${item.description}`).join("\n");
|
||||
bot.sendMessage(msg.chat.id, helpMsgText, { parse_mode: "HTML" });
|
||||
bot.setMyCommands(helpMsg);
|
||||
});
|
||||
|
||||
bot.onText(/\/setu/, (msg) => {
|
||||
const index = parseInt(msg.text.replace("/setu", ""));
|
||||
bot.sendMessage(msg.chat.id, `色图模式`);
|
||||
axios.get('https://asiantolick.com/ajax/buscar_posts.php', {params: {index}})
|
||||
.then(res => {
|
||||
const $ = whacko.load(res.data);
|
||||
$('.miniatura').each((i, e) => {
|
||||
const href = $(e).attr('href');
|
||||
setTimeout(() => {
|
||||
bot.sendMessage(msg.chat.id, href, {
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
[{text: '带我去看图', url: href}],
|
||||
]
|
||||
}
|
||||
});
|
||||
}, i * 250);
|
||||
});
|
||||
});
|
||||
});
|
||||
bot.onText(/\/setu/, async (msg) => {
|
||||
const index = parseInt(msg.text.replace("/setu", ""), 10);
|
||||
bot.sendMessage(msg.chat.id, "色图模式");
|
||||
const res = await axios.get("https://asiantolick.com/ajax/buscar_posts.php", { params: { index } });
|
||||
const $ = whacko.load(res.data);
|
||||
setu = Object.values($(".miniatura")).map((item) => $(item).attr("href"));
|
||||
sendSetu(msg.chat.id, 0);
|
||||
});
|
||||
|
||||
bot.onText(/\/goindex/, (msg) => {
|
||||
const q = msg.text.replace("/goindex ", "")
|
||||
bot.sendMessage(msg.chat.id, `正在搜寻“${q}”...`);
|
||||
goindex.query(q).then(res => {
|
||||
//筛选符合条件的文件
|
||||
videos = res.filter(e => e.mimeType === "video/mp4").filter(e => e.size < 50 * 1024 * 1024);
|
||||
images = res.filter(e => e.mimeType === "image/jpeg");
|
||||
audios = res.filter(e => e.mimeType === "audio/mp3").filter(e => e.size < 50 * 1024 * 1024);
|
||||
folders = res.filter(e => e.mimeType === "application/vnd.google-apps.folder");
|
||||
bot.on("callback_query", async (query) => {
|
||||
const i = parseInt(query.data, 10);
|
||||
const queryId = query.id;
|
||||
sendSetu(query.message.chat.id, i);
|
||||
bot.answerCallbackQuery(queryId);
|
||||
});
|
||||
|
||||
bot.sendMessage(msg.chat.id, `共有${images.length}个图片结果,${videos.length}个视频,${audios.length}个音乐,${folders.length}个目录,搜索结果:`);
|
||||
bot.sendChatAction(msg.chat.id, "upload_photo");
|
||||
images = goindex.group(images, 10);
|
||||
images.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
bot.sendMediaGroup(msg.chat.id, e.map(e => {
|
||||
return {
|
||||
type: "photo",
|
||||
media: e.thumbnailLink.replace('=s220', '=s0'),
|
||||
caption: e.name,
|
||||
}
|
||||
}));
|
||||
}, i * 2000);
|
||||
});
|
||||
bot.sendChatAction(msg.chat.id, 'upload_video');
|
||||
videos.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
goindex.id2path(e.id).then(path => {
|
||||
console.log(path);
|
||||
bot.sendVideo(msg.chat.id, encodeURI(path), {
|
||||
caption: `${e.name}`,
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
[{text: '带我去看片', url: encodeURI(path)}],
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
}, i * 2000);
|
||||
});
|
||||
bot.sendChatAction(msg.chat.id, 'upload_voice');
|
||||
audios.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
goindex.id2path(e.id).then(path => {
|
||||
console.log(path);
|
||||
bot.sendAudio(msg.chat.id, path, {caption: `${e.name}`});
|
||||
});
|
||||
}, i * 2000);
|
||||
});
|
||||
})
|
||||
});
|
||||
bot.onText(/\/goindex/, (msg) => {
|
||||
const q = msg.text.replace("/goindex ", "");
|
||||
bot.sendMessage(msg.chat.id, `正在搜寻“${q}”...`);
|
||||
goindex.query(q).then((res) => {
|
||||
// 筛选符合条件的文件
|
||||
const videos = res.filter((e) => e.mimeType === "video/mp4").filter((e) => e.size < 50 * 1024 * 1024);
|
||||
let images = res.filter((e) => e.mimeType === "image/jpeg");
|
||||
const audios = res.filter((e) => e.mimeType === "audio/mp3").filter((e) => e.size < 50 * 1024 * 1024);
|
||||
const folders = res.filter((e) => e.mimeType === "application/vnd.google-apps.folder");
|
||||
|
||||
bot.onText(/\/senddice/, (msg) => {
|
||||
bot.sendDice(msg.chat.id, {emoji: "🎲"});
|
||||
});
|
||||
bot.sendMessage(msg.chat.id, `共有${images.length}个图片结果,${videos.length}个视频,${audios.length}个音乐,${folders.length}个目录,搜索结果:`);
|
||||
bot.sendChatAction(msg.chat.id, "upload_photo");
|
||||
images = goindex.group(images, 10);
|
||||
images.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
bot.sendMediaGroup(msg.chat.id, e.map((el) => ({
|
||||
type: "photo",
|
||||
media: el.thumbnailLink.replace("=s220", "=s0"),
|
||||
caption: el.name,
|
||||
})));
|
||||
}, i * 2000);
|
||||
});
|
||||
bot.sendChatAction(msg.chat.id, "upload_video");
|
||||
videos.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
goindex.id2path(e.id).then((path) => {
|
||||
console.log(path);
|
||||
bot.sendVideo(msg.chat.id, encodeURI(path), {
|
||||
caption: `${e.name}`,
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
[{ text: "带我去看片", url: encodeURI(path) }],
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
}, i * 2000);
|
||||
});
|
||||
bot.sendChatAction(msg.chat.id, "upload_voice");
|
||||
audios.forEach((e, i) => {
|
||||
setTimeout(() => {
|
||||
goindex.id2path(e.id).then((path) => {
|
||||
console.log(path);
|
||||
bot.sendAudio(msg.chat.id, path, { caption: `${e.name}` });
|
||||
});
|
||||
}, i * 2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
bot.on('polling_error', (error) => {
|
||||
console.log(error.code); // => 'EFATAL'
|
||||
})
|
||||
return bot;
|
||||
}
|
||||
bot.onText(/\/senddice/, (msg) => {
|
||||
bot.sendDice(msg.chat.id, { emoji: "🎲" });
|
||||
});
|
||||
|
||||
bot.on("polling_error", (error) => {
|
||||
console.log(error.message); // => 'EFATAL'
|
||||
});
|
||||
return bot;
|
||||
};
|
||||
|
||||
@@ -1,83 +1,85 @@
|
||||
const axios = require("axios")
|
||||
const BASE_URL = 'https://gd.lyz05.workers.dev'
|
||||
const axios = require("axios");
|
||||
|
||||
module.exports = {
|
||||
query,
|
||||
id2path,
|
||||
group,
|
||||
}
|
||||
const BASE_URL = "https://gd.lyz05.workers.dev";
|
||||
|
||||
function group(array, subGroupLength) {
|
||||
var index = 0;
|
||||
var newArray = [];
|
||||
let index = 0;
|
||||
const newArray = [];
|
||||
|
||||
while(index < array.length) {
|
||||
newArray.push(array.slice(index, index += subGroupLength));
|
||||
}
|
||||
while (index < array.length) {
|
||||
newArray.push(array.slice(index, index += subGroupLength));
|
||||
}
|
||||
|
||||
return newArray;
|
||||
return newArray;
|
||||
}
|
||||
|
||||
async function id2path(id) {
|
||||
url = BASE_URL+'/0:id2path'
|
||||
const ret = await axios.post(url, { id: id })
|
||||
return BASE_URL+'/0:'+ret.data;
|
||||
const url = `${BASE_URL}/0:id2path`;
|
||||
const ret = await axios.post(url, { id });
|
||||
return `${BASE_URL}/0:${ret.data}`;
|
||||
}
|
||||
|
||||
async function query(q) {
|
||||
url = BASE_URL+'/0:search'
|
||||
files = [];
|
||||
let page_token = null;
|
||||
while (true) {
|
||||
data = {
|
||||
'q': q,
|
||||
'page_index': 1,
|
||||
'page_token': page_token,
|
||||
}
|
||||
const ret = await axios.post(url, data)
|
||||
files = files.concat(ret.data.data.files);
|
||||
// console.log(ret.data.data.files)
|
||||
page_token = ret.data.nextPageToken
|
||||
if (page_token === null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// console.log('files:',files);
|
||||
return files;
|
||||
const url = `${BASE_URL}/0:search`;
|
||||
let files = [];
|
||||
let page_token = null;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const data = {
|
||||
q,
|
||||
page_index: 1,
|
||||
page_token,
|
||||
};
|
||||
const ret = await axios.post(url, data);
|
||||
files = files.concat(ret.data.data.files);
|
||||
// console.log(ret.data.data.files)
|
||||
page_token = ret.data.nextPageToken;
|
||||
if (page_token === null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// console.log('files:',files);
|
||||
return files;
|
||||
}
|
||||
|
||||
async function queryData(path = '') {
|
||||
url = BASE_URL+'/0:/Inbox/seer/%E5%86%99%E7%9C%9F/Miho%20Kaneko%20Complete%20Photo%20Collection/' + path
|
||||
data = {
|
||||
'q': '',
|
||||
'page_index': 0,
|
||||
'page_token': null,
|
||||
'password': null,
|
||||
}
|
||||
const response = await axios.post(url, data)
|
||||
return response.data
|
||||
}
|
||||
// async function queryData(path = "") {
|
||||
// const url = `${BASE_URL}/0:/Inbox/seer/%E5%86%99%E7%9C%9F/Miho%20Kaneko%20Complete%20Photo%20Collection/${path}`;
|
||||
// const data = {
|
||||
// q: "",
|
||||
// page_index: 0,
|
||||
// page_token: null,
|
||||
// password: null,
|
||||
// };
|
||||
// const response = await axios.post(url, data);
|
||||
// return response.data;
|
||||
// }
|
||||
|
||||
async function dfs(path) {
|
||||
let l = [];
|
||||
const res = await queryData(path);
|
||||
for (const item of res.data.files) {
|
||||
if (item.mimeType === 'application/vnd.google-apps.folder') {
|
||||
l = l.concat(await dfs(path + item.name + '/'));
|
||||
} else {
|
||||
l.push(item.name)
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
// async function dfs(path) {
|
||||
// let l = [];
|
||||
// const res = await queryData(path);
|
||||
// for (const item of res.data.files) {
|
||||
// if (item.mimeType === "application/vnd.google-apps.folder") {
|
||||
// l = l.concat(await dfs(`${path + item.name}/`));
|
||||
// } else {
|
||||
// l.push(item.name);
|
||||
// }
|
||||
// }
|
||||
// return l;
|
||||
// }
|
||||
|
||||
async function main(num) {
|
||||
// const res = await dfs('');
|
||||
// console.log(res);
|
||||
const files = await query();
|
||||
link = files[num].thumbnailLink;
|
||||
console.log(link)
|
||||
}
|
||||
// async function main(num) {
|
||||
// // const res = await dfs('');
|
||||
// // console.log(res);
|
||||
// const files = await query();
|
||||
// const link = files[num].thumbnailLink;
|
||||
// console.log(link);
|
||||
// }
|
||||
|
||||
module.exports = {
|
||||
query,
|
||||
id2path,
|
||||
group,
|
||||
};
|
||||
// main(12);
|
||||
|
||||
// console.log(response.data.data.files)
|
||||
// console.log(response.data.data.files)
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
const TelegramBot = require('node-telegram-bot-api');
|
||||
const TelegramBot = require("node-telegram-bot-api");
|
||||
|
||||
module.exports = (TOKEN) => {
|
||||
const bot = new TelegramBot(TOKEN, {polling: true});
|
||||
const bot = new TelegramBot(TOKEN, {polling: true});
|
||||
|
||||
// Just to ping!
|
||||
bot.on('message', msg => {
|
||||
if (msg.text) {
|
||||
bot.sendMessage(msg.chat.id, msg.text);
|
||||
} else {
|
||||
bot.sendMessage(msg.chat.id, 'I can only understand text messages!');
|
||||
}
|
||||
});
|
||||
bot.on('video', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive video message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.video));
|
||||
});
|
||||
bot.on('photo', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive photo message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.photo));
|
||||
});
|
||||
bot.on('audio', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive audio message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.audio));
|
||||
});
|
||||
bot.on('document', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive document message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.document));
|
||||
});
|
||||
bot.on('sticker', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive sticker message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.sticker));
|
||||
});
|
||||
bot.on('location', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive location message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.location));
|
||||
});
|
||||
bot.on('contact', msg => {
|
||||
bot.sendMessage(msg.chat.id, 'I reveive contact message!');
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.contact));
|
||||
});
|
||||
bot.on('polling_error', (error) => {
|
||||
console.log(error.code); // => 'EFATAL'
|
||||
})
|
||||
return bot;
|
||||
}
|
||||
// Just to ping!
|
||||
bot.on("message", msg => {
|
||||
if (msg.text) {
|
||||
bot.sendMessage(msg.chat.id, msg.text);
|
||||
} else {
|
||||
bot.sendMessage(msg.chat.id, "I can only understand text messages!");
|
||||
}
|
||||
});
|
||||
bot.on("video", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive video message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.video));
|
||||
});
|
||||
bot.on("photo", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive photo message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.photo));
|
||||
});
|
||||
bot.on("audio", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive audio message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.audio));
|
||||
});
|
||||
bot.on("document", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive document message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.document));
|
||||
});
|
||||
bot.on("sticker", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive sticker message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.sticker));
|
||||
});
|
||||
bot.on("location", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive location message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.location));
|
||||
});
|
||||
bot.on("contact", msg => {
|
||||
bot.sendMessage(msg.chat.id, "I reveive contact message!");
|
||||
bot.sendMessage(msg.chat.id, JSON.stringify(msg.contact));
|
||||
});
|
||||
bot.on("polling_error", (error) => {
|
||||
console.log(error.code); // => 'EFATAL'
|
||||
});
|
||||
return bot;
|
||||
};
|
||||
|
||||
@@ -1,54 +1,53 @@
|
||||
const AV = require('leancloud-storage');
|
||||
const {Query, User} = AV;
|
||||
const AV = require("leancloud-storage");
|
||||
// 引入环境变量
|
||||
require('dotenv').config({path: '../.env'});
|
||||
require("dotenv").config({path: "../.env"});
|
||||
|
||||
AV.init({
|
||||
appId: process.env.LEANCLOUD_APP_ID,
|
||||
appKey: process.env.LEANCLOUD_APP_KEY,
|
||||
serverURL: "https://dbvunek8.lc-cn-e1-shared.com"
|
||||
appId: process.env.LEANCLOUD_APP_ID,
|
||||
appKey: process.env.LEANCLOUD_APP_KEY,
|
||||
serverURL: "https://dbvunek8.lc-cn-e1-shared.com"
|
||||
});
|
||||
|
||||
function currentDay() {
|
||||
const date = new Date();
|
||||
const start = new Date(date.setHours(0, 0, 0, 0))
|
||||
const end = new Date(date.setHours(23, 59, 59, 999))
|
||||
return [start, end]
|
||||
const date = new Date();
|
||||
const start = new Date(date.setHours(0, 0, 0, 0));
|
||||
const end = new Date(date.setHours(23, 59, 59, 999));
|
||||
return [start, end];
|
||||
}
|
||||
|
||||
function lastDay() {
|
||||
const currentday = currentDay();
|
||||
currentday[0].setDate(currentday[0].getDate() - 1);
|
||||
currentday[1].setDate(currentday[1].getDate() - 1);
|
||||
return currentday
|
||||
const currentday = currentDay();
|
||||
currentday[0].setDate(currentday[0].getDate() - 1);
|
||||
currentday[1].setDate(currentday[1].getDate() - 1);
|
||||
return currentday;
|
||||
}
|
||||
|
||||
function currentMonth() {
|
||||
const date = new Date(), y = date.getFullYear(), m = date.getMonth();
|
||||
const firstDay = new Date(y, m, 1);
|
||||
const lastDay = new Date(y, m + 1, 0);
|
||||
return [firstDay, lastDay]
|
||||
const date = new Date(), y = date.getFullYear(), m = date.getMonth();
|
||||
const firstDay = new Date(y, m, 1);
|
||||
const lastDay = new Date(y, m + 1, 0);
|
||||
return [firstDay, lastDay];
|
||||
}
|
||||
|
||||
async function danmakuQuery(date) {
|
||||
const query = new AV.Query('DanmakuAccess');
|
||||
query.greaterThanOrEqualTo('createdAt', date[0]);
|
||||
query.lessThan('createdAt', date[1]);
|
||||
const query = new AV.Query("DanmakuAccess");
|
||||
query.greaterThanOrEqualTo("createdAt", date[0]);
|
||||
query.lessThan("createdAt", date[1]);
|
||||
|
||||
query.exists('url');
|
||||
return await query.count()
|
||||
query.exists("url");
|
||||
return await query.count();
|
||||
}
|
||||
|
||||
function add(className,obj) {
|
||||
const classInstance = AV.Object.extend(className);
|
||||
const record = new classInstance();
|
||||
for (const key of Object.keys(obj)){
|
||||
record.set(key, obj[key]);
|
||||
}
|
||||
record.save().then((obj) => {
|
||||
// 成功保存之后,执行其他逻辑
|
||||
console.log(`${className}添加一条记录。objectId:${obj.id}`);
|
||||
});
|
||||
const classInstance = AV.Object.extend(className);
|
||||
const record = new classInstance();
|
||||
for (const key of Object.keys(obj)){
|
||||
record.set(key, obj[key]);
|
||||
}
|
||||
record.save().then((obj) => {
|
||||
// 成功保存之后,执行其他逻辑
|
||||
console.log(`${className}添加一条记录。objectId:${obj.id}`);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {danmakuQuery, currentDay, currentMonth, lastDay, add};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
const {filesize} = require('filesize')
|
||||
const {filesize} = require("filesize");
|
||||
|
||||
const print = function () {
|
||||
const memoryUsage = process.memoryUsage();
|
||||
const memoryUsage = process.memoryUsage();
|
||||
|
||||
console.log(JSON.stringify({
|
||||
rss: filesize(memoryUsage.rss),//RAM 中保存的进程占用的内存部分,包括代码本身、栈、堆。
|
||||
heapTotal: filesize(memoryUsage.heapTotal),//堆中总共申请到的内存量。
|
||||
heapUsed: filesize(memoryUsage.heapUsed),//堆中目前用到的内存量,判断内存泄漏我们主要以这个字段为准。
|
||||
external: filesize(memoryUsage.external),// V8 引擎内部的 C++ 对象占用的内存。
|
||||
}));
|
||||
}
|
||||
console.log(JSON.stringify({
|
||||
rss: filesize(memoryUsage.rss),//RAM 中保存的进程占用的内存部分,包括代码本身、栈、堆。
|
||||
heapTotal: filesize(memoryUsage.heapTotal),//堆中总共申请到的内存量。
|
||||
heapUsed: filesize(memoryUsage.heapUsed),//堆中目前用到的内存量,判断内存泄漏我们主要以这个字段为准。
|
||||
external: filesize(memoryUsage.external),// V8 引擎内部的 C++ 对象占用的内存。
|
||||
}));
|
||||
};
|
||||
|
||||
module.exports = print
|
||||
module.exports = print;
|
||||
|
||||
80
utils/oss.js
80
utils/oss.js
@@ -1,61 +1,61 @@
|
||||
const OSS = require('ali-oss');
|
||||
const normalendpoint = 'oss-cn-hongkong.aliyuncs.com';
|
||||
const fastendpoint = 'oss-accelerate.aliyuncs.com';
|
||||
const OSS = require("ali-oss");
|
||||
const normalendpoint = "oss-cn-hongkong.aliyuncs.com";
|
||||
const fastendpoint = "oss-accelerate.aliyuncs.com";
|
||||
|
||||
// 引入环境变量
|
||||
require('dotenv').config({path: '../.env'});
|
||||
require("dotenv").config({path: "../.env"});
|
||||
|
||||
let client = new OSS({
|
||||
region: process.env.OSS_REGION,
|
||||
accessKeyId: process.env.OSS_ACCESS_KEY,
|
||||
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
|
||||
bucket: process.env.OSS_BUCKET,
|
||||
region: process.env.OSS_REGION,
|
||||
accessKeyId: process.env.OSS_ACCESS_KEY,
|
||||
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
|
||||
bucket: process.env.OSS_BUCKET,
|
||||
});
|
||||
|
||||
async function get(objname) {
|
||||
try {
|
||||
const result = await client.get(objname);
|
||||
return result.content.toString()
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
try {
|
||||
const result = await client.get(objname);
|
||||
return result.content.toString();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function put(objname, content, headers) {
|
||||
try {
|
||||
const result = await client.put(objname, new Buffer.from(content), {headers});
|
||||
return result
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
try {
|
||||
const result = await client.put(objname, new Buffer.from(content), {headers});
|
||||
return result;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function head(objname) {
|
||||
try {
|
||||
const result = await client.head(objname);
|
||||
return result.res.headers
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
try {
|
||||
const result = await client.head(objname);
|
||||
return result.res.headers;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function signurl(objname, isFast) {
|
||||
try {
|
||||
let result = await client.signatureUrl(objname);
|
||||
if (isFast) {
|
||||
result = result.replace("http://","//").replace(normalendpoint, fastendpoint)
|
||||
}
|
||||
return result
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
try {
|
||||
let result = await client.signatureUrl(objname);
|
||||
if (isFast) {
|
||||
result = result.replace("http://","//").replace(normalendpoint, fastendpoint);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {get, put, head, signurl};
|
||||
|
||||
if (!module.parent) {
|
||||
get('SUB/database.yaml');
|
||||
put('SUB/test.txt', '中文');
|
||||
head('SUB/database.yaml');
|
||||
signurl('SUB/database.yaml',true);
|
||||
}
|
||||
get("SUB/database.yaml");
|
||||
put("SUB/test.txt", "中文");
|
||||
head("SUB/database.yaml");
|
||||
signurl("SUB/database.yaml",true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user