From 73fd69802097e33524a3af13e8d88db614469aa6 Mon Sep 17 00:00:00 2001 From: Alexey Kasyanchuk Date: Sun, 2 Sep 2018 03:41:54 +0300 Subject: [PATCH] feat(rutor): rutor strategie --- src/background/spider.js | 16 ++-- src/background/strategies/rutor.js | 135 +++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 src/background/strategies/rutor.js diff --git a/src/background/spider.js b/src/background/spider.js index 9b4b463..171adfb 100644 --- a/src/background/spider.js +++ b/src/background/spider.js @@ -42,6 +42,7 @@ const mime = require('mime'); const Rutracker = require('./strategies/rutracker') const Nyaa = require('./strategies/nyaa') +const Rutor = require('./strategies/rutor') module.exports = function (send, recive, dataDirectory, version, env) @@ -105,9 +106,9 @@ module.exports = function (send, recive, dataDirectory, version, env) class RemoteTrackers { - constructor(sphinx) + constructor(args) { - this.sphinx = sphinx + this.sphinx = args.sphinx if(!config.trackers) { logT('tracker', 'trackers disabled') @@ -116,8 +117,9 @@ module.exports = function (send, recive, dataDirectory, version, env) } this.trackers = [ - new Rutracker, - new Nyaa + new Rutracker(args), + new Nyaa(args), + new Rutor(args) ] } @@ -167,7 +169,11 @@ module.exports = function (send, recive, dataDirectory, version, env) }) } } - const remoteTrackers = new RemoteTrackers(sphinxSingle) + const remoteTrackers = new RemoteTrackers({ + sphinx: sphinxSingle, + p2p, + dataDirectory + }) // start function baseRowData(row) diff --git a/src/background/strategies/rutor.js b/src/background/strategies/rutor.js new file mode 100644 index 0000000..a45c315 --- /dev/null +++ b/src/background/strategies/rutor.js @@ -0,0 +1,135 @@ + +const fetch = require('node-fetch') +const cheerio = require('cheerio') +const {promisify} = require('util'); +const fs = require('fs') +const fileRead = promisify(fs.readFile) +const exist = promisify(fs.exists) +const magnetParse = require('../magnetParse') + +module.exports = class Rutor +{ + constructor(props) + { + this.p2p = props.p2p + this.dataDirectory = props.dataDirectory + setTimeout(() => this.recheck(), 30000) + } + + name() { return 'rutor' } + + async findHash(hash) + { + if(!this.dataDirectory) + return + + let id; + const checkInDatabase = async (file, noCheck) => { + const fileName = this.dataDirectory + `/${file}` + if(this.p2p && !noCheck && !(await exist(fileName))) + { + logT('rutor', 'download hash database', file) + await this.p2p.file('rutor') + logT('rutor', 'downloaded hash database', file) + } + + if(id) + return + + let idMapFile = await fileRead(fileName) + idMapFile = JSON.parse(idMapFile).hashes + id = idMapFile[hash] + } + + try + { + await checkInDatabase(`rutor/rutor.${hash[0]}.json`) + await checkInDatabase(`rutor/rutor.x.json`, true) + if(id) + return this.parse(id) + } catch(error) + { + return + } + } + + async recheck(page = 0) { + if(!this.dataDirectory) + return + + if(!this.rutorMap && fs.existsSync(this.dataDirectory + '/rutor/rutor.x.json')) + { + let data = JSON.parse(fs.readFileSync(this.dataDirectory + '/rutor/rutor.x.json')) + this.rutorMap = data.hashes + } + else + this.rutorMap = {} + + if(page > 11) + { + delete this.rutorMap + return + } + + let html + try { + html = await fetch(`http://rutor.is/browse/${page}/0/0/0`) + } catch(err) { + return + } + if(!html) + return + html = await html.textConverted() + const $ = cheerio.load(html) + + const rutorMap = this.rutorMap + $('#index tr').each(function(i, elem) { + const row = $(this) + const nameField = row.find('td').next() + if(!nameField) + return + let id = nameField.find('a').attr('href') + if(!id) + return + id = id.match(/download\/([0-9]+)/)[1] + id = parseInt(id) + const hash = magnetParse(nameField.find('a').next().attr('href')) + + rutorMap[hash] = id + }); + + fs.writeFileSync(`${this.dataDirectory}/rutor/rutor.x.json`, JSON.stringify({ + date: Date.now(), + hashes: this.rutorMap + }, null, 4), 'utf8'); + + logT('rutor', 'parse new links page', page) + setTimeout(() => this.recheck(page + 1), 30) + } + + async parse(id) + { + let html; + try { + html = await fetch(`http://www.rutor.is/torrent/${id}`) + } catch(err) { + return + } + if(!html) + return + html = await html.textConverted() + const $ = cheerio.load(html) + const topicTitle = $('h1').text() + if(!topicTitle) + return + + return { + name: topicTitle, + poster: $('#details tbody img').attr('src'), + description: $('#details tbody').first().text(), + rutorThreadId: parseInt(id) + } + + } + +} \ No newline at end of file