CinemaPress/routes/episode.js

336 lines
10 KiB
JavaScript

'use strict';
/**
* Module dependencies.
*/
var CP_get = require('../lib/CP_get');
var CP_tv = require('../modules/CP_tv');
var CP_translit = require('../lib/CP_translit');
/**
* Configuration dependencies.
*/
var config = require('../config/production/config');
Object.keys(config).length === 0 &&
(config = require('../config/production/config.backup'));
var config_md5 = require('md5')(JSON.stringify(config));
var modules = require('../config/production/modules');
Object.keys(modules).length === 0 &&
(modules = require('../config/production/modules.backup'));
var modules_md5 = require('md5')(JSON.stringify(modules));
setInterval(function() {
if (
config_md5 &&
process.env['CP_CONFIG_MD5'] &&
config_md5 !== process.env['CP_CONFIG_MD5']
) {
config = require('../config/production/config');
Object.keys(config).length === 0 &&
(config = require('../config/production/config.backup'));
config_md5 = process.env['CP_CONFIG_MD5'];
}
if (
modules_md5 &&
process.env['CP_MODULES_MD5'] &&
modules_md5 !== process.env['CP_MODULES_MD5']
) {
modules = require('../config/production/modules');
Object.keys(modules).length === 0 &&
(modules = require('../config/production/modules.backup'));
modules_md5 = process.env['CP_MODULES_MD5'];
}
}, 3333);
/**
* Node dependencies.
*/
var op = require('object-path');
var adop = require('adop');
var LRU = require('lru-cache');
var cache = new LRU({
maxAge: 3600000,
max: 1000,
length: function(n, key) {
return (
(new TextEncoder().encode(JSON.stringify(n)).length + key.length) / 1024
);
}
});
var md5 = require('md5');
var async = require('async');
var request = require('request');
var express = require('express');
var router = express.Router();
/**
* Callback.
*
* @callback Callback
* @param {Object} err
* @param {Object} [render]
*/
/**
* List episodes.
*/
router.get('/?', function(req, res) {
res.setHeader('Content-Type', 'application/json');
if (!req.query.id) return res.status(404).json({ error: '404' });
if (!cache.has('CP_VER') || cache.get('CP_VER') !== process.env['CP_VER']) {
cache.reset();
cache.set('CP_VER', process.env['CP_VER']);
}
var kp_id = parseInt(req.query.id) ? [parseInt(req.query.id)] : [];
var tv = typeof req.query.tv !== 'undefined';
var host = req.get('host');
var port =
/:[0-9]{1,5}$/.test(host) && !/:80$/.test(host) && !/:443$/.test(host)
? ':' + host.split(':')[1]
: '';
var options = {};
options.protocol = (req.userinfo && req.userinfo.protocol) || config.protocol;
options.domain =
(req.userinfo && req.userinfo.domain) || config.subdomain + config.domain;
options.origin = options.protocol + options.domain;
options.port = port;
if (/^\/tv-version/i.test(req.originalUrl)) {
req.userinfo.domain =
(modules.tv.data.subdomain ? 'tv.' : config.subdomain) +
options.domain +
port +
(modules.tv.data.subdomain ? '' : '/tv-version');
} else if (/^\/mobile-version/i.test(req.originalUrl)) {
req.userinfo.domain =
(modules.mobile.data.subdomain ? 'm.' : config.subdomain) +
options.domain +
port +
(modules.mobile.data.subdomain ? '' : '/mobile-version');
} else {
req.userinfo.domain = options.domain + port;
}
var serials = {};
async.eachOfLimit(
modules.episode.data.custom,
1,
function(task, index, callback) {
CP_get.movies({ query_id: kp_id }, 1, '', 1, true, options, function(
err,
movies
) {
if (err || !movies || !movies.length) return callback();
var movie = movies[0];
var parse = task.replace(/\s*~\s*/g, '~').split('~');
if (task.charAt(0) === '#' || parse.length < 3) {
return callback();
}
var changes = (parse[0].split('<>')[1] || '').split(',');
var params = {
url: parse[0].split('<>')[0].trim(),
season: parse[1],
episode: parse[2]
};
if (parse[3]) {
params.translate = parse[3];
}
params.url = params.url
.replace(
/\[kp_id]/,
movie.kp_id && parseInt(movie.kp_id)
? '' + (parseInt(movie.kp_id) % 1000000000)
: ''
)
.replace(/\[imdb_id]/, movie.imdb_id ? movie.imdb_id : '')
.replace(/\[tmdb_id]/, movie.tmdb_id ? movie.tmdb_id : '')
.replace(/\[douban_id]/, movie.douban_id ? movie.douban_id : '')
.replace(/\[tvmaze_id]/, movie.tvmaze_id ? movie.tvmaze_id : '')
.replace(/\[wa_id]/, movie.wa_id ? movie.wa_id : '')
.replace(/\[movie_id]/, movie.movie_id ? movie.movie_id : '');
var hash = md5(
JSON.stringify(params) + options.origin + process.env['CP_VER']
);
if (cache.has(hash)) {
serials = cache.get(hash);
return callback();
}
var group = 'season.episode';
var obj = [
{
name: 'season',
path: parse[1],
type: 'number',
regex: /([0-9]{1,4})/
},
{
name: 'episode',
path: parse[2],
type: 'number',
regex: /([0-9]{1,4})/
}
];
if (parse[3]) {
group = 'translate.season.episode';
obj.push({
name: 'translate',
path: parse[3],
type: 'string'
});
}
request(
{
url: params.url,
method: 'GET',
timeout: 15000
},
function(error, response, body) {
if (error || response.statusCode !== 200 || !body) {
return callback();
}
var body_json = tryParseJSON(body);
if (typeof body_json !== 'object') {
return callback();
}
function zero(first_path, id, key_paths) {
var add_path = id && key_paths[id] ? key_paths[id] : '';
var next_id = key_paths[id + 1] ? id + 1 : 0;
var array_key_path = op.get(body_json, first_path);
if (typeof array_key_path !== 'object') return;
if (!Array.isArray(array_key_path)) {
var key_array = [];
Object.keys(array_key_path).forEach(function(key) {
key_array.push({
key: key,
value: array_key_path[key]
});
});
op.set(body_json, first_path, key_array);
} else {
array_key_path.forEach(function(akp, i) {
var curr_key_path = [first_path, i, add_path]
.filter(function(p) {
return p !== '';
})
.join('.');
var key_object = op.get(body_json, curr_key_path);
if (typeof key_object !== 'object') return;
zero(curr_key_path, next_id, key_paths);
});
}
}
if (changes && changes.length) {
changes.forEach(function(change) {
var key_path = change.trim();
if (!key_path) return;
var key_paths = key_path.split('0').map(function(p) {
return p.replace(/\.+/g, '.').replace(/(^\.*)|(\.*)$/g, '');
});
zero(key_paths[0], key_paths[1] ? 1 : 0, key_paths);
});
}
var get_serials = adop(body_json, obj, group);
if (group === 'season.episode') {
get_serials = {
'': get_serials
};
}
Object.keys(get_serials).forEach(function(translate) {
if (translate.indexOf("'") + 1 || translate.indexOf('"') + 1) {
get_serials[
translate.replace(/"/g, '&#34;').replace(/'/g, '&#39;')
] = get_serials[translate];
delete get_serials[translate];
translate = translate
.replace(/"/g, '&#34;')
.replace(/'/g, '&#39;');
}
Object.keys(get_serials[translate]).forEach(function(season) {
Object.keys(get_serials[translate][season]).forEach(function(
episode
) {
get_serials[translate][season][episode] = {
kp_id: movie.kp_id,
title: movie.title,
title_ru: movie.title_ru,
title_en: movie.title_en,
poster: movie.poster,
season: season + ' ' + modules.episode.data.season,
episode: episode + ' ' + modules.episode.data.episode,
translate: translate
? modules.episode.data.translate + ' ' + translate
: '',
pathname:
movie.pathname +
'/s' +
season +
'e' +
episode +
(translate
? '_' +
CP_translit.text(translate, undefined, 'translate')
: ''),
url:
movie.url +
'/s' +
season +
'e' +
episode +
(translate
? '_' +
CP_translit.text(translate, undefined, 'translate')
: '')
};
});
});
});
serials = Object.assign({}, get_serials, serials);
cache.set(hash, serials);
callback();
}
);
});
},
function() {
if (
serials &&
Object.keys(serials).length &&
(typeof serials[''] === 'undefined' || Object.keys(serials['']).length)
) {
return res.json(tv ? CP_tv.episode(serials, options) : serials);
} else {
return res.status(404).json({ error: 'NO EPISODES' });
}
}
);
/**
* Valid JSON.
*
* @param {String} jsonString
*/
function tryParseJSON(jsonString) {
try {
var o = JSON.parse(jsonString);
if (o && typeof o === 'object') {
return o;
}
} catch (e) {}
return {};
}
});
module.exports = router;