Better api: log; blacklist; bug fixing

This commit is contained in:
DIYgod 2016-05-18 02:23:44 +08:00
parent 2a873bc91a
commit f1a9b8664f
No known key found for this signature in database
GPG Key ID: F8797DD1088C6506
10 changed files with 1144 additions and 987 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
node_modules node_modules
demo2 demo2
npm-debug.log npm-debug.log
DPlayer.log

View File

@ -7,7 +7,7 @@
[![Travis](https://img.shields.io/travis/DIYgod/DPlayer.svg?style=flat-square)](https://travis-ci.org/DIYgod/DPlayer) [![Travis](https://img.shields.io/travis/DIYgod/DPlayer.svg?style=flat-square)](https://travis-ci.org/DIYgod/DPlayer)
[![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://www.anotherhome.net/) [![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://www.anotherhome.net/)
Wow, such a lovely HTML5 danmaku video player > Wow, such a lovely HTML5 danmaku video player
## Introduction ## Introduction
@ -43,8 +43,6 @@ $ npm run build
- [ ] 快捷键: 空格暂停,双击全屏, 方向键控制进度 - [ ] 快捷键: 空格暂停,双击全屏, 方向键控制进度
- [ ] 弹幕相关
- [ ] icon 动画 - [ ] icon 动画
- [ ] 右键 - [ ] 右键

View File

@ -66,7 +66,8 @@
}, },
danmaku: { danmaku: {
id: '9E2E3368B56CDBB4', id: '9E2E3368B56CDBB4',
api: 'http://dplayer.daoapp.io/' api: 'https://dplayer.daoapp.io/',
token: 'tokendemo'
} }
}); });
dp.init(); dp.init();

4
dist/DPlayer.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3
nodejs/blacklist Normal file
View File

@ -0,0 +1,3 @@
Can be username and IP
username
0.0.0.0

View File

@ -1,9 +1,39 @@
var url = require('url'); var url = require('url');
var fs = require('fs');
var mongoose = require('mongoose'); var mongoose = require('mongoose');
var mongodbUrl = 'mongodb://' + process.env.MONGODB_USERNAME + ':' + process.env.MONGODB_PASSWORD + '@' + process.env.MONGODB_PORT_27017_TCP_ADDR + ':' + process.env.MONGODB_PORT_27017_TCP_PORT + '/' + process.env.MONGODB_INSTANCE_NAME;
var express = require('express'); var express = require('express');
var app = express(); var app = express();
var log4js = require('log4js');
log4js.configure({
appenders: [
{
type: "file",
filename: 'DPlayer.log',
maxLogSize: 20480,
backups: 3,
category: [ 'DPlayer','console' ]
},
{
type: "console"
}
],
replaceConsole: true
});
var logger = log4js.getLogger('DPlayer');
logger.setLevel('INFO');
logger.info(`🍻 DPlayer start! Cheers!`);
var postIP = [];
var mongodbUrl;
if (process.env.MONGODB_USERNAME && process.env.MONGODB_PASSWORD && process.env.MONGODB_PORT_27017_TCP_ADDR && process.env.MONGODB_PORT_27017_TCP_PORT && process.env.MONGODB_INSTANCE_NAME) {
mongodbUrl = 'mongodb://' + process.env.MONGODB_USERNAME + ':' + process.env.MONGODB_PASSWORD + '@' + process.env.MONGODB_PORT_27017_TCP_ADDR + ':' + process.env.MONGODB_PORT_27017_TCP_PORT + '/' + process.env.MONGODB_INSTANCE_NAME;
}
else {
mongodbUrl = 'mongodb://localhost:27017/danmaku';
}
var danmakuSchema = new mongoose.Schema({ var danmakuSchema = new mongoose.Schema({
player: String, player: String,
author: String, author: String,
@ -27,16 +57,23 @@ app.all('*', function(req, res, next) {
} }
}); });
app.get('/', function(req, res) { app.get('/', function (req, res) {
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
logger.info(`GET form IP: ${ip}`);
mongoose.connect(mongodbUrl); mongoose.connect(mongodbUrl);
var db = mongoose.connection; var db = mongoose.connection;
db.on('error',console.error); db.on('error', errorListener);
var id = url.parse(req.url,true).query.id; var id = url.parse(req.url,true).query.id;
db.once('open', function() { db.once('open', function() {
cleanListener();
danmaku.find({player: id}, function (err, data) { danmaku.find({player: id}, function (err, data) {
if (err) { if (err) {
console.error(err); logger.error(err);
} }
var json = `{"code": 1,"danmaku":[`; var json = `{"code": 1,"danmaku":[`;
@ -47,32 +84,138 @@ app.get('/', function(req, res) {
} }
} }
json += `]}`; json += `]}`;
res.write(json); res.send(json);
res.end();
db.close(); db.close();
}) })
}); });
function errorListener (err) {
cleanListener();
logger.error(err);
res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
}
function cleanListener () {
db.removeListener('error', errorListener);
}
}); });
app.post('/', function (req, res) { app.post('/', function (req, res) {
var body = '', jsonStr; var body = '';
req.on('data', function (chunk) { var jsonStr;
var db;
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
// check black ip
var blanklist = fs.readFileSync('blacklist').toString().split('\n');
if (blanklist.indexOf(ip) !== -1) {
logger.info(`Reject POST form ${ip} for black ip.`);
res.send(`{"code": -1, "msg": "Rejected for black ip."}`);
return;
}
// frequency limitation
if (postIP.indexOf(ip) !== -1) {
logger.info(`Reject POST form ${ip} for frequent operation.`);
res.send(`{"code": -2, "msg": "Rejected for frequent operation."}`);
return;
}
else {
postIP.push(ip);
setTimeout(function () {
postIP.splice(0, 1);
}, 1000);
}
req.on('data', dataListener);
req.on('end', endListener);
function dataListener (chunk) {
body += chunk; body += chunk;
}); }
req.on('end', function () { function endListener () {
cleanListener();
try { try {
jsonStr = JSON.parse(body); jsonStr = JSON.parse(body);
} catch (err) { } catch (err) {
jsonStr = null; jsonStr = null;
} }
var dan = new danmaku({player: jsonStr.player, author: jsonStr.author, time: jsonStr.time, text: jsonStr.text, color: jsonStr.color, type: jsonStr.type}); // check data
console.log(jsonStr.player, jsonStr.author, jsonStr.time, jsonStr.text, jsonStr.color, jsonStr.type);
if (jsonStr.player === undefined
|| jsonStr.author === undefined
|| jsonStr.time === undefined
|| jsonStr.text === undefined
|| jsonStr.color === undefined
|| jsonStr.type === undefined) {
logger.info(`Reject POST form ${ip} for illegal data: ${JSON.stringify(jsonStr)}`);
res.send(`{"code": -3, "msg": "Rejected for illegal data"}`);
return;
}
// check token: set it yourself
function checkToken (token) {
return true;
}
if (!checkToken(jsonStr.token)) {
logger.info(`Rejected POST form ${ip} for illegal token: ${jsonStr.token}`);
res.send(`{"code": -4, "msg": "Rejected for illegal token: ${jsonStr.token}"}`);
return;
}
// check black username
if (blanklist.indexOf(jsonStr.author) !== -1) {
logger.info(`Reject POST form ${jsonStr.author} for black user.`);
res.send(`{"code": -5, "msg": "Rejected for black user."}`);
return;
}
logger.info(`POST form ${ip}, data: ${JSON.stringify(jsonStr)}`);
mongoose.connect(mongodbUrl);
db = mongoose.connection;
db.on('error', errorListener);
db.once('open', function() {
cleandbListener();
var dan = new danmaku({
player: jsonStr.player,
author: jsonStr.author,
time: jsonStr.time,
text: jsonStr.text,
color: jsonStr.color,
type: jsonStr.type
});
dan.save(function (err, d) { dan.save(function (err, d) {
if (err){ if (err){
console.error(err); logger.error(err);
res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
} }
else {
res.send(`{"code": 1, "data": ${JSON.stringify(d)}}`);
}
db.close();
}); });
}); });
}
function errorListener (err) {
cleandbListener();
logger.error(err);
res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
}
function cleandbListener () {
db.removeListener('error', errorListener);
}
function cleanListener () {
req.removeListener('data', dataListener);
req.removeListener('end', endListener);
}
}); });
app.listen(1207); app.listen(1207);

View File

@ -8,6 +8,7 @@
"devDependencies": {}, "devDependencies": {},
"dependencies": { "dependencies": {
"express": "^4.13.4", "express": "^4.13.4",
"log4js": "^0.6.36",
"mongoose": "^4.1.9" "mongoose": "^4.1.9"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "dplayer", "name": "dplayer",
"version": "0.0.1", "version": "0.0.2",
"description": "Wow, such a lovely HTML5 danmaku video player", "description": "Wow, such a lovely HTML5 danmaku video player",
"main": "dist/DPlayer.min.js", "main": "dist/DPlayer.min.js",
"scripts": { "scripts": {

View File

@ -804,6 +804,41 @@
const commentSettingBox = this.element.getElementsByClassName('dplayer-comment-setting-box')[0]; const commentSettingBox = this.element.getElementsByClassName('dplayer-comment-setting-box')[0];
const commentSendIcon = this.element.getElementsByClassName('dplayer-send-icon')[0]; const commentSendIcon = this.element.getElementsByClassName('dplayer-send-icon')[0];
const sendComment = () => {
// text can't be empty
if (!commentInput.value.replace(/^\s+|\s+$/g, '')) {
alert('要输入弹幕内容啊喂!');
return;
}
const danmakuData = {
token: this.option.danmaku.token,
player: this.option.danmaku.id,
author: 'DIYgod',
time: this.audio.currentTime,
text: commentInput.value,
color: this.element.querySelector('input[name="dplayer-danmaku-color"]:checked').value,
type: this.element.querySelector('input[name="dplayer-danmaku-type"]:checked').value
};
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(JSON.parse(xhr.responseText));
}
else {
console.log('Request was unsuccessful: ' + xhr.status);
}
}
};
xhr.open('post', this.option.danmaku.api, true);
xhr.send(JSON.stringify(danmakuData));
commentInput.value = '';
closeComment();
this.danmakuIn(danmakuData.text, danmakuData.color, danmakuData.type);
};
const closeCommentSetting = () => { const closeCommentSetting = () => {
if (commentSettingBox.classList.contains('dplayer-comment-setting-open')) { if (commentSettingBox.classList.contains('dplayer-comment-setting-open')) {
commentSettingBox.classList.remove('dplayer-comment-setting-open'); commentSettingBox.classList.remove('dplayer-comment-setting-open');
@ -861,40 +896,15 @@
commentInput.addEventListener('click', () => { commentInput.addEventListener('click', () => {
closeCommentSetting(); closeCommentSetting();
}); });
commentInput.addEventListener('keydown', (e) => {
commentSendIcon.addEventListener('click', () => { const event = e || window.event;
// text can't be empty if (event.keyCode === 13) {
if (!commentInput.value.replace(/^\s+|\s+$/g, '')) { sendComment();
alert('要输入弹幕内容啊喂!');
return;
} }
const danmakuData = {
player: this.option.danmaku.id,
time: this.audio.currentTime,
text: commentInput.value,
color: this.element.querySelector('input[name="dplayer-danmaku-color"]:checked').value,
type: this.element.querySelector('input[name="dplayer-danmaku-type"]:checked').value
};
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(JSON.parse(xhr.responseText));
}
else {
console.log('Request was unsuccessful: ' + xhr.status);
}
}
};
xhr.open('post', this.option.danmaku.api, true);
xhr.send(JSON.stringify(danmakuData));
commentInput.value = '';
closeComment();
this.danmakuIn(danmakuData.text, danmakuData.color, danmakuData.type);
}); });
commentSendIcon.addEventListener('click', sendComment);
/** /**
* full screen * full screen
@ -982,12 +992,12 @@
this.event[name].push(func); this.event[name].push(func);
} }
} }
} }
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = DPlayer module.exports = DPlayer;
} }
else { else {
window.DPlayer = DPlayer; window.DPlayer = DPlayer;
} }
})(); })();