-
-
Notifications
You must be signed in to change notification settings - Fork 174
/
Copy pathrutor.js
152 lines (130 loc) · 3.28 KB
/
rutor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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')
const mkdirp = require('mkdirp')
module.exports = class Rutor
{
constructor(props)
{
this.p2p = props.p2p
this.dataDirectory = props.dataDirectory
let t = setTimeout(() => this.recheck(), 30000)
t.unref()
}
get 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
logT('rutor', 'add records to', Object.keys(this.rutorMap).length)
}
else if(!this.rutorMap)
this.rutorMap = {}
if(page > 10)
{
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
});
await mkdirp(`${this.dataDirectory}/rutor`)
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()
html = html.replace(/textarea/g, 'div')
const $ = cheerio.load(html)
const topicTitle = $('h1').text()
if(!topicTitle)
return
let contentCategory
$('#details tr').each(function(i, elem) {
const row = $(this)
const field = row.find('td.header').text()
if(field == 'Категория')
{
contentCategory = row.find('td').next().text().trim()
}
});
return {
name: topicTitle,
poster: $('#details tbody img').attr('src'),
description: $('#details tbody').first().text(),
rutorThreadId: parseInt(id),
contentCategory
}
}
}