mirror of
https://github.com/lyz05/danmaku.git
synced 2026-02-02 17:59:53 +08:00
fix: 提升代码质量,增加测试用例
This commit is contained in:
20
app.js
20
app.js
@@ -1,19 +1,19 @@
|
||||
var createError = require('http-errors');
|
||||
var express = require('express');
|
||||
var path = require('path');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var 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();
|
||||
|
||||
// 引入一个个路由模块
|
||||
var danmakuRouter = require('./routes/danmaku');
|
||||
var usersRouter = require('./routes/users');
|
||||
var ipinfoRouter = require('./routes/ipinfo');
|
||||
var airportsubRouter = require('./routes/airportsub');
|
||||
const danmakuRouter = require('./routes/danmaku');
|
||||
const usersRouter = require('./routes/users');
|
||||
const ipinfoRouter = require('./routes/ipinfo');
|
||||
const airportsubRouter = require('./routes/airportsub');
|
||||
|
||||
var app = express();
|
||||
const app = express();
|
||||
|
||||
// view engine setup
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
35
bin/www
35
bin/www
@@ -3,23 +3,20 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var app = require('../app');
|
||||
var debug = require('debug')('danmaku:server');
|
||||
var http = require('http');
|
||||
const app = require('../app');
|
||||
const debug = require('debug')('danmaku:server');
|
||||
const http = require('http');
|
||||
|
||||
/**
|
||||
* Get port from environment and store in Express.
|
||||
*/
|
||||
|
||||
var port = normalizePort(process.env.PORT || '3000');
|
||||
const port = normalizePort(process.env.PORT || '3000');
|
||||
app.set('port', port);
|
||||
|
||||
/**
|
||||
* Create HTTP server.
|
||||
*/
|
||||
|
||||
var server = http.createServer(app);
|
||||
const server = http.createServer(app);
|
||||
|
||||
/**
|
||||
* Listen on provided port, on all network interfaces.
|
||||
@@ -34,9 +31,9 @@ server.on('listening', onListening);
|
||||
*/
|
||||
|
||||
function normalizePort(val) {
|
||||
var port = parseInt(val, 10);
|
||||
const port = parseInt(val, 10);
|
||||
|
||||
if (isNaN(port)) {
|
||||
if (isNaN(port)) {
|
||||
// named pipe
|
||||
return val;
|
||||
}
|
||||
@@ -58,11 +55,11 @@ function onError(error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var bind = typeof port === 'string'
|
||||
? 'Pipe ' + port
|
||||
: 'Port ' + port;
|
||||
const bind = typeof port === 'string'
|
||||
? 'Pipe ' + port
|
||||
: 'Port ' + port;
|
||||
|
||||
// handle specific listen errors with friendly messages
|
||||
// handle specific listen errors with friendly messages
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
console.error(bind + ' requires elevated privileges');
|
||||
@@ -82,9 +79,9 @@ function onError(error) {
|
||||
*/
|
||||
|
||||
function onListening() {
|
||||
var addr = server.address();
|
||||
var bind = typeof addr === 'string'
|
||||
? 'pipe ' + addr
|
||||
: 'port ' + addr.port;
|
||||
debug('Listening on ' + bind);
|
||||
const addr = server.address();
|
||||
const bind = typeof addr === 'string'
|
||||
? 'pipe ' + addr
|
||||
: 'port ' + addr.port;
|
||||
debug('Listening on ' + bind);
|
||||
}
|
||||
|
||||
31
package-lock.json
generated
31
package-lock.json
generated
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"ali-oss": "^6.17.1",
|
||||
"axios": "^1.1.3",
|
||||
"cookie": "^0.5.0",
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
"dotenv": "^16.0.3",
|
||||
@@ -25,7 +26,8 @@
|
||||
"morgan": "~1.9.1",
|
||||
"pako": "^1.0.11",
|
||||
"whacko": "^0.19.1",
|
||||
"xml-js": "^1.6.11"
|
||||
"xml-js": "^1.6.11",
|
||||
"xml2js": "^0.4.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.3.6",
|
||||
@@ -1602,9 +1604,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -1621,6 +1623,14 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser/node_modules/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
@@ -7260,9 +7270,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.4.6",
|
||||
@@ -7271,6 +7281,13 @@
|
||||
"requires": {
|
||||
"cookie": "0.4.1",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"ali-oss": "^6.17.1",
|
||||
"axios": "^1.1.3",
|
||||
"cookie": "^0.5.0",
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
"dotenv": "^16.0.3",
|
||||
@@ -26,7 +27,8 @@
|
||||
"morgan": "~1.9.1",
|
||||
"pako": "^1.0.11",
|
||||
"whacko": "^0.19.1",
|
||||
"xml-js": "^1.6.11"
|
||||
"xml-js": "^1.6.11",
|
||||
"xml2js": "^0.4.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.3.6",
|
||||
|
||||
@@ -18,7 +18,7 @@ function getuserinfo(headers) {
|
||||
if (str === undefined) {
|
||||
return undefined
|
||||
}
|
||||
var dic = cookie.parse(str);
|
||||
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)
|
||||
@@ -87,6 +87,7 @@ router.get('/', async function (req, res, next) {
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: 定时任务
|
||||
router.get('/cache', async function (req, res, next) {
|
||||
const database = await updateDatabase();
|
||||
let messages = [];
|
||||
@@ -107,7 +108,7 @@ router.get('/cache', async function (req, res, next) {
|
||||
const userinfo = res.headers['subscription-userinfo']
|
||||
const base64userinfo = Buffer.from(userinfo).toString('base64')
|
||||
// 设置强制下载并设置文件名
|
||||
headers = {
|
||||
const headers = {
|
||||
'Content-type': 'text/plain; charset=utf-8',
|
||||
'content-disposition': `attachment; filename=${key}`,
|
||||
'x-oss-persistent-headers': "Subscription-Userinfo:" + base64userinfo
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// noinspection EqualityComparisonWithCoercionJS
|
||||
|
||||
const urlmodule = require('url');
|
||||
const axios = require('axios');
|
||||
const got = require('got');
|
||||
@@ -17,14 +19,14 @@ function Bilibili() {
|
||||
// 相关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"
|
||||
var q = urlmodule.parse(url, true);
|
||||
var path = q.pathname.split('/');
|
||||
const q = urlmodule.parse(url, true);
|
||||
const path = q.pathname.split('/');
|
||||
// 普通投稿视频
|
||||
if (url.indexOf('video/') !== -1) {
|
||||
// 获取视频分P信息
|
||||
const p = q.query.p || 1;
|
||||
// 判断是否为旧版av号
|
||||
var params;
|
||||
let params;
|
||||
if (url.indexOf('BV') !== -1) {
|
||||
params = {'bvid': path.slice(-1)[0]};
|
||||
} else {
|
||||
@@ -49,7 +51,7 @@ function Bilibili() {
|
||||
this.error_msg = '获取番剧视频信息失败!'
|
||||
return
|
||||
}
|
||||
for (var i = 0; i < response.data.result.episodes.length; i++) {
|
||||
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;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const axios = require('axios');
|
||||
const pako = require('pako');
|
||||
var xml2js = require('xml2js');
|
||||
const xml2js = require('xml2js');
|
||||
const {time_to_second, make_response, content_template} = require('./utils');
|
||||
const memory = require('../../utils/memory')
|
||||
|
||||
@@ -35,7 +35,7 @@ function Iqiyi() {
|
||||
console.log('tvid', tvid)
|
||||
let promises = []
|
||||
for (let i = 0; i < page; i++) {
|
||||
const api_url = `http://cmts.iqiyi.com/bullet/${tvid.slice(-4, -2)}/${tvid.slice(-2)}/${tvid}_300_${i + 1}.z`
|
||||
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',
|
||||
@@ -67,7 +67,7 @@ function Iqiyi() {
|
||||
continue
|
||||
for (const bulletInfo of entry.list[0].bulletInfo){
|
||||
// console.log(bulletInfo)
|
||||
var content = JSON.parse(JSON.stringify(content_template));
|
||||
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
|
||||
|
||||
@@ -38,7 +38,7 @@ function Mgtv() {
|
||||
if (data.data.items === null)
|
||||
continue;
|
||||
for (const item of data.data.items) {
|
||||
var content = JSON.parse(JSON.stringify(content_template));
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = item.time / 1000;
|
||||
content.content = item.content;
|
||||
content.uid = item.uid;
|
||||
|
||||
@@ -45,7 +45,7 @@ function Tencentvideo() {
|
||||
|
||||
for (const data of datas) {
|
||||
for (const item of data.barrage_list) {
|
||||
var content = JSON.parse(JSON.stringify(content_template));
|
||||
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)
|
||||
|
||||
@@ -11,9 +11,9 @@ const content_template = {
|
||||
};
|
||||
|
||||
function time_to_second(time) {
|
||||
var t = time.split(':');
|
||||
var s = 0;
|
||||
var m = 1;
|
||||
const t = time.split(':');
|
||||
let s = 0;
|
||||
let m = 1;
|
||||
while (t.length > 0) {
|
||||
s += m * parseInt(t.pop(), 10);
|
||||
m *= 60;
|
||||
|
||||
@@ -35,13 +35,13 @@ function Youku() {
|
||||
}
|
||||
|
||||
const yk_msg_sign = (msg) => {
|
||||
var md5 = crypto.createHash('md5');
|
||||
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('&');
|
||||
var md5 = crypto.createHash('md5');
|
||||
const md5 = crypto.createHash('md5');
|
||||
return md5.update(text).digest('hex')
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ function Youku() {
|
||||
msg['sign'] = yk_msg_sign(msg_b64encode)
|
||||
const data = JSON.stringify(msg)
|
||||
const t = Date.now()
|
||||
params = {
|
||||
const params = {
|
||||
"jsv": "2.5.6",
|
||||
"appKey": "24679788",
|
||||
"t": t,
|
||||
@@ -130,7 +130,7 @@ function Youku() {
|
||||
// 接口请求情况
|
||||
// console.log(i, res.ret[0])
|
||||
for (danmu of danmus) {
|
||||
var content = JSON.parse(JSON.stringify(content_template));
|
||||
const content = JSON.parse(JSON.stringify(content_template));
|
||||
content.timepoint = danmu["playat"] / 1000
|
||||
if (danmu.propertis.color) {
|
||||
content.color = JSON.parse(danmu.propertis).color
|
||||
|
||||
@@ -24,8 +24,8 @@ async function build_response(url,req) {
|
||||
console.log(e)
|
||||
return {msg: '传入的链接非法!请检查链接是否能在浏览器正常打开'}
|
||||
}
|
||||
var fc = undefined
|
||||
for (var item of list) {
|
||||
let fc = undefined;
|
||||
for (let item of list) {
|
||||
if (url.indexOf(item.domain) !== -1) {
|
||||
fc = item
|
||||
}
|
||||
@@ -49,13 +49,13 @@ router.get('/', async function (req, res, next) {
|
||||
leancloud.danmakuAccessAdd({ip: getClientIp(req), url: req.query.url, ua: req.headers['user-agent']})
|
||||
//检查是否包含URL参数
|
||||
if (!req.query.url) {
|
||||
var urls = [mgtv.example_urls[0], bilibili.example_urls[0], tencentvideo.example_urls[0], youku.example_urls[0], iqiyi.example_urls[0]];
|
||||
const urls = [mgtv.example_urls[0], bilibili.example_urls[0], tencentvideo.example_urls[0], youku.example_urls[0], iqiyi.example_urls[0]];
|
||||
const path = getscheme(req) + '://' + req.headers.host + req.originalUrl;
|
||||
res.render('danmaku', {path, urls});
|
||||
} else {
|
||||
url = req.query.url;
|
||||
download = (req.query.download === 'on');
|
||||
ret = await build_response(url,req)
|
||||
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)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
var libqqwry = require('lib-qqwry');
|
||||
var dns = require('dns');
|
||||
var qqwry = libqqwry() //初始化IP库解析器
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const libqqwry = require('lib-qqwry');
|
||||
const dns = require('dns');
|
||||
const qqwry = libqqwry(); //初始化IP库解析器
|
||||
|
||||
function getClientIp(req) {
|
||||
return req.headers['x-forwarded-for'] ||
|
||||
@@ -13,14 +13,15 @@ function getClientIp(req) {
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function (req, res, next) {
|
||||
var ip = req.query.name || getClientIp(req);
|
||||
let ip = req.query.name || getClientIp(req);
|
||||
dns.lookup(ip, (err, address, family) => {
|
||||
let ipL;
|
||||
if (err) {
|
||||
ipL = { 'ip': ip, 'msg': '域名解析IP失败' };
|
||||
} else {
|
||||
ip = address
|
||||
try {
|
||||
var ipL = qqwry.searchIP(ip); //查询IP信息
|
||||
ipL = qqwry.searchIP(ip); //查询IP信息
|
||||
} catch (e) {
|
||||
ipL = { 'ip': ip, 'msg': e };
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
/* GET users listing. */
|
||||
router.get('/', function(req, res, next) {
|
||||
|
||||
26
test.js
26
test.js
@@ -1,26 +0,0 @@
|
||||
|
||||
function main() {
|
||||
const p1 = new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve('p1');
|
||||
}, 500);
|
||||
});
|
||||
const p2 = new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve('p2');
|
||||
}, 300);
|
||||
});
|
||||
const Promises = [p1,p2];
|
||||
let count = 0;
|
||||
p1.then((value) => {
|
||||
count ++;
|
||||
console.log(value)
|
||||
})
|
||||
p2.then((value) => {
|
||||
count ++;
|
||||
console.log(value)
|
||||
})
|
||||
while (count<2) ;
|
||||
console.log('All promise done');
|
||||
}
|
||||
main()
|
||||
@@ -7,6 +7,7 @@ const list = [bilibili, mgtv, tencentvideo, youku, iqiyi];
|
||||
let should = chai.should();
|
||||
chai.use(chaiHttp);
|
||||
|
||||
//TODO: add more test cases
|
||||
describe('App', () => {
|
||||
|
||||
describe('弹幕解析模块测试', function () {
|
||||
@@ -19,7 +20,30 @@ describe('App', () => {
|
||||
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;
|
||||
@@ -119,6 +143,32 @@ describe('App', () => {
|
||||
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')
|
||||
|
||||
@@ -9,15 +9,6 @@ AV.init({
|
||||
serverURL: "https://dbvunek8.lc-cn-e1-shared.com"
|
||||
});
|
||||
|
||||
function test() {
|
||||
const TestObject = AV.Object.extend('TestObject');
|
||||
const testObject = new TestObject();
|
||||
testObject.set('words', 'Hello world!');
|
||||
testObject.set('number', 123);
|
||||
testObject.save().then((testObject) => {
|
||||
console.log('保存成功。')
|
||||
})
|
||||
}
|
||||
|
||||
function danmakuAccessAdd(obj) {
|
||||
const {ip, url, ua} = obj;
|
||||
@@ -44,9 +35,9 @@ function lastDay() {
|
||||
}
|
||||
|
||||
function currentMonth() {
|
||||
var date = new Date(), y = date.getFullYear(), m = date.getMonth();
|
||||
var firstDay = new Date(y, m, 1);
|
||||
var lastDay = new Date(y, m + 1, 0);
|
||||
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]
|
||||
}
|
||||
|
||||
@@ -65,6 +56,7 @@ function danmakuErrorAdd(obj) {
|
||||
const record = new DanmakuErrorObject();
|
||||
record.set('remoteIP', ip);
|
||||
record.set('url', url);
|
||||
//TODO: 转换成object
|
||||
record.set('error', JSON.stringify(error));
|
||||
record.save().then()
|
||||
}
|
||||
|
||||
@@ -11,18 +11,19 @@
|
||||
<div class="container">
|
||||
<h3>温馨提示:</h3>
|
||||
<p>
|
||||
带filter的是过滤无效节点并精选的结果(建议优先使用)。强烈建议使用clash作为客户端,具有自动测试节点的功能和完善的规则。</p>
|
||||
带filter的是过滤无效节点并精选的结果(建议优先使用)。强烈建议使用clash作为客户端,具有自动测试节点的功能和完善的规则。
|
||||
</p>
|
||||
<p>
|
||||
相关软件<a href="/sub/download">下载链接</a><br>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
<p class="card-heading">Telegram 代理</p>
|
||||
<p>
|
||||
<a href="tg://proxy?server=vipserv.ccloud.live&port=443&secret=dddd561961fea026e517764b084bd64072">域名</a>
|
||||
<a href="tg://proxy?server=167.235.77.32&port=443&secret=dddd561961fea026e517764b084bd64072">IPV4</a>
|
||||
<a href="tg://proxy?server=2a01:4f8:1c1e:eeb6::1&port=443&secret=dddd561961fea026e517764b084bd64072">IPV6</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<h3>Your Subscribe:</h3>
|
||||
<p>
|
||||
当前账户过期时间:<%= expire %><br>
|
||||
@@ -32,13 +33,14 @@
|
||||
<%= path %>&ctype=<%= index %>
|
||||
</a>
|
||||
|
||||
<br>
|
||||
<% if (ret[index]) { %>
|
||||
过去已用:<%= ret[index].total_use %> 总量:<%= ret[index].total %> 过期时间:<%= ret[index].expire %> 用量比:<%= ret[index].use_percent %>%
|
||||
日期比:<%= ret[index].date_percent %>%<br>
|
||||
<% } %>
|
||||
<br>
|
||||
<% if (ret[index]) { %>
|
||||
过去已用:<%= ret[index].total_use %> 总量:<%= ret[index].total %> 过期时间:<%= ret[index].expire %>
|
||||
用量比:<%= ret[index].use_percent %>%
|
||||
日期比:<%= ret[index].date_percent %>%<br>
|
||||
<% } %>
|
||||
|
||||
<% }; %>
|
||||
<% } %>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label">视频网址</label>
|
||||
<div class="col-sm-5">
|
||||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<input type="text" class="form-control" placeholder="URL" name="url">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<title><%= error.status %> <%= message %></title>
|
||||
|
||||
Reference in New Issue
Block a user