Skip to content

Instantly share code, notes, and snippets.

@xingoxu
Last active March 7, 2017 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xingoxu/9f682d4d002f87d18ff43b95fa4d2959 to your computer and use it in GitHub Desktop.
Save xingoxu/9f682d4d002f87d18ff43b95fa4d2959 to your computer and use it in GitHub Desktop.
Get bangumi activities with request & serve with express
/**
* Created by xingo on 2017/03/06.
*/
let httpClient = require('request');
let domEnv = require('jsdom').env,
jQInit = require('jquery');
function fetchTimeline(username, page) {
return new Promise((resolve, reject) => {
httpClient.get({
url: `https://bgm.tv/user/${username}/timeline?type=all&page=${page}&ajax=1`,
headers: {
'User-Agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36`,
'Upgrade-Insecure-Requests': 1,
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,ja;q=0.2,zh-TW;q=0.2',
'Referer': `https://bgm.tv/user/${username}/timeline`,
}
}, (err, response, body) => {
if (err)
return reject(err);
resolve(body)
})
});
}
function fetchWindow(username) {
return new Promise((resolve, reject) => {
httpClient.get({
url: `https://bgm.tv/user/${username}/timeline`,
headers: {
'User-Agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36`,
'Upgrade-Insecure-Requests': 1,
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,ja;q=0.2,zh-TW;q=0.2',
}
}, (err, response, body) => {
if (err)
return reject(err);
resolve(body)
})
}).then(body => {
return new Promise((resolve, reject) => {
domEnv(body, (errors, window) => {
if (errors)
return reject(errors);
let $ = jQInit(window);
resolve($);
})
})
})
}
let moment = require('moment');
function setDate($, body, dateObj) {
let timeline = $(body);
let shouldStop = false;
timeline.children('h4.Header').each(function (index) {
let date = $(this).text();
switch (date) {
case '今天':
date = moment().format('YYYY-MM-DD');
break;
case '昨天':
date = moment().subtract(1, 'days').format('YYYY-MM-DD');
break;
default:
date = moment(date, 'YYYY-M-D').format('YYYY-MM-DD');
break;
}
if (moment().diff(moment(date), 'days') > 371) {
shouldStop = true;
return false;
}
dateObj[date] = $(this).next().children('li').length;
});
return shouldStop;
}
function fetchTimelinePromise(username, page, jquery, dateObj) {
return fetchTimeline(username, page).then(body => {
if (setDate(jquery, body, dateObj)) {
return dateObj;
}
else {
return fetchTimelinePromise(username, page + 1, jquery, dateObj);
}
})
}
function getBangumiTimelineJSON(username) {
return fetchWindow(username).then(jquery => {
let page = 1;
let dateObj = {};
return fetchTimelinePromise(username, page, jquery, dateObj);
}).then(dateObj => {
let day = 0;
let json = {
max: 0,
data: [],
};
let momentObj = moment().subtract(day, 'days');
while (!(momentObj.day() == 6 && day >= 365)) {
let date = momentObj.format('YYYY-MM-DD');
let count = dateObj[date];
count = count ? count : 0;
json.data.unshift({
count: count ? count : 0,
date: date,
});
if (count > json.max)
json.max = count;
momentObj = moment().subtract(++day, 'days');
}
return json;
})
}
let cache = {};
function getBangumiTimeline(username) {
return getBangumiTimelineJSON(username)
.then(json => {
return cache[username] = json;
})
}
let router = require('express').Router();
let currentUser = 'xingo';
getBangumiTimeline(currentUser);
function clearCache() {
setTimeout(() => {
cache = {};
getBangumiTimeline(currentUser);
clearCache();
}, moment().endOf('day').toDate().valueOf() - Date.now());
}
clearCache();
router.get('/', function (req, res, next) {
res.append('Access-Control-Allow-Origin', '*');
if (cache[currentUser]) {
return res.json(cache[currentUser]);
}
else {
return getBangumiTimeline(currentUser)
.then(json => {
res.json(json);
})
.catch(err => {
return res.status(500).json({
code: 500,
message: 'something went wrong',
});
});
}
});
module.exports = router;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment