@xriss/weerss 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd.import.js +2 -0
- package/cmd.js +106 -0
- package/db.js +245 -0
- package/feeds.js +321 -0
- package/hoard.js +85 -0
- package/items.js +188 -0
- package/jxml.js +262 -0
- package/npm-publish +11 -0
- package/package.json +35 -0
- package/register-hooks.js +35 -0
- package/register.js +3 -0
- package/serv.js +21 -0
- package/shows.js +249 -0
- package/torrents.js +116 -0
- package/webpack.config.cjs +61 -0
- package/weerss.js +565 -0
package/shows.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
let shows={}
|
|
4
|
+
export default shows
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import hoard from "./hoard.js"
|
|
8
|
+
import db from "./db.js"
|
|
9
|
+
import jxml from "./jxml.js"
|
|
10
|
+
|
|
11
|
+
import { configure } from 'safe-stable-stringify'
|
|
12
|
+
const stringify = configure({})
|
|
13
|
+
|
|
14
|
+
import weerss from "./weerss.js"
|
|
15
|
+
|
|
16
|
+
// cleanup a file name as best we can to be used in search
|
|
17
|
+
shows.clean_name=function(name)
|
|
18
|
+
{
|
|
19
|
+
return name.replace(/'|’/g,"").replace(/[^a-zA-Z0-9]/g," ").replace(/\s+/g," ").trim().toLowerCase()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
shows.get=async function(url) // always slow
|
|
24
|
+
{
|
|
25
|
+
return await db.get("shows",url)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
shows.set=async function(show)
|
|
29
|
+
{
|
|
30
|
+
await db.set("shows",show.url,show)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
shows.fetch=async function(url,force)
|
|
35
|
+
{
|
|
36
|
+
if(!force)
|
|
37
|
+
{
|
|
38
|
+
let ret = await shows.get(url)
|
|
39
|
+
if( ret && ret.data) { return ret.data }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let data = await fetch(url).then(res => res.json())
|
|
43
|
+
if(data)
|
|
44
|
+
{
|
|
45
|
+
await shows.set({url:url,data:data})
|
|
46
|
+
}
|
|
47
|
+
return data
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
shows.prepare=function(show)
|
|
52
|
+
{
|
|
53
|
+
return show
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
// lookup show on tvmaze
|
|
58
|
+
shows.get_tvmaze=async function(show,force)
|
|
59
|
+
{
|
|
60
|
+
try{ // on network errors, just return non tvmaze info
|
|
61
|
+
|
|
62
|
+
let show_year
|
|
63
|
+
let show_country
|
|
64
|
+
let show_name=show.name
|
|
65
|
+
let qurl="https://api.tvmaze.com/singlesearch/shows?q="+show_name.replaceAll(" ","+")
|
|
66
|
+
let tvmaze=await shows.fetch(qurl,force)
|
|
67
|
+
|
|
68
|
+
if(!tvmaze) // maybe try again
|
|
69
|
+
{
|
|
70
|
+
if( show_name.match(/\s\d\d\d\d$/i) ) // maybe a four digit year
|
|
71
|
+
{
|
|
72
|
+
show_year=show_name.substring(show_name.length-4)
|
|
73
|
+
show_name=show_name.substring(0,show_name.length-5)
|
|
74
|
+
qurl="https://api.tvmaze.com/singlesearch/shows?q="+show_name.replaceAll(" ","+")
|
|
75
|
+
tvmaze=await shows.fetch(qurl,force)
|
|
76
|
+
if(tvmaze)
|
|
77
|
+
{
|
|
78
|
+
show.year=show_year // remember the year we removed
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if(!tvmaze) // maybe try again
|
|
84
|
+
{
|
|
85
|
+
if( show_name.match(/\s\w\w$/i) ) // maybe a two letter country code
|
|
86
|
+
{
|
|
87
|
+
show_country=show_name.substring(show_name.length-2)
|
|
88
|
+
show_name=show_name.substring(0,show_name.length-3)
|
|
89
|
+
qurl="https://api.tvmaze.com/singlesearch/shows?q="+show_name.replaceAll(" ","+")
|
|
90
|
+
tvmaze=await shows.fetch(qurl,force)
|
|
91
|
+
if(tvmaze)
|
|
92
|
+
{
|
|
93
|
+
show.country=show_country // remember the country we removed
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if(tvmaze && tvmaze.name=="Too Many Requests") // ERROR
|
|
99
|
+
{
|
|
100
|
+
tvmaze=undefined
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
show.tvmaze=tvmaze
|
|
104
|
+
show.id=tvmaze && tvmaze.id
|
|
105
|
+
|
|
106
|
+
}catch(e){console.log(e)}
|
|
107
|
+
|
|
108
|
+
return show.tvmaze
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// guess the show and series/episode or movie from an item
|
|
112
|
+
shows.get_show=async function(filename)
|
|
113
|
+
{
|
|
114
|
+
let item_tags
|
|
115
|
+
let item_name
|
|
116
|
+
let item_season
|
|
117
|
+
let item_episode
|
|
118
|
+
|
|
119
|
+
let name=filename
|
|
120
|
+
if(!name){return} // give up
|
|
121
|
+
|
|
122
|
+
if(!item_name)
|
|
123
|
+
{
|
|
124
|
+
let aa=name.match(/(.*)S(\d\d+)E(\d\d+)(.*)/i)
|
|
125
|
+
if(aa) // found a season
|
|
126
|
+
{
|
|
127
|
+
item_name=shows.clean_name(aa[1])
|
|
128
|
+
item_season=Number(aa[2])
|
|
129
|
+
item_episode=Number(aa[3])
|
|
130
|
+
item_tags=shows.clean_name(aa[4]).split(" ")
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// try and match a date if we did not find an episode ?
|
|
135
|
+
if(!item_name)
|
|
136
|
+
{
|
|
137
|
+
let aa=name.match(/(.*)(\d\d\d\d)\D(\d\d)\D(\d\d)(.*)/i)
|
|
138
|
+
if(aa) // found a data
|
|
139
|
+
{
|
|
140
|
+
item_name=aa[1].replace(/[^a-zA-Z0-9]/g," ").replace(/\s+/g," ").trim().toLowerCase()
|
|
141
|
+
item_season=Number(aa[2]) // season is the year
|
|
142
|
+
item_episode=Number(aa[3]+aa[4]) // join month and day to make a 4 digit episode number
|
|
143
|
+
item_tags=aa[5].replace(/[^a-zA-Z0-9]/g," ").replace(/\s+/g," ").trim().toLowerCase().split(" ")
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if(!item_name){return} // give up
|
|
148
|
+
|
|
149
|
+
let show={
|
|
150
|
+
name:item_name,
|
|
151
|
+
tags:item_tags,
|
|
152
|
+
season:item_season,
|
|
153
|
+
episode:item_episode,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await shows.get_tvmaze(show)
|
|
157
|
+
|
|
158
|
+
return show
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// guess the show and series/episode or movie from an item
|
|
162
|
+
shows.fill_show=async function(item)
|
|
163
|
+
{
|
|
164
|
+
|
|
165
|
+
item.show=await shows.get_show(item.torrent.file_name)
|
|
166
|
+
|
|
167
|
+
item.show=item.show||{fail:true}
|
|
168
|
+
|
|
169
|
+
return item
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
let check_flags=function(flags,rules)
|
|
174
|
+
{
|
|
175
|
+
let good=false
|
|
176
|
+
|
|
177
|
+
if(weerss.config.debug)
|
|
178
|
+
{
|
|
179
|
+
console.log("checking rules",flags)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for( let rule of rules )
|
|
183
|
+
{
|
|
184
|
+
for( let s of rule )
|
|
185
|
+
{
|
|
186
|
+
if( "string" == typeof s ) // all these must be true
|
|
187
|
+
{
|
|
188
|
+
if( s.startsWith("!") )
|
|
189
|
+
{
|
|
190
|
+
s=s.substring(1)
|
|
191
|
+
if( flags[s] ) { break }
|
|
192
|
+
}
|
|
193
|
+
else
|
|
194
|
+
{
|
|
195
|
+
if( !flags[s] ) { break }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else
|
|
199
|
+
if( "boolean" == typeof s ) // to set this flag
|
|
200
|
+
{
|
|
201
|
+
if(weerss.config.debug)
|
|
202
|
+
{
|
|
203
|
+
console.log("rule matched",rule)
|
|
204
|
+
}
|
|
205
|
+
good=s
|
|
206
|
+
break
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
if(weerss.config.debug)
|
|
212
|
+
{
|
|
213
|
+
console.log("result",good,"\n")
|
|
214
|
+
}
|
|
215
|
+
return good
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// is this show good?
|
|
219
|
+
shows.good_show=function(show,rules)
|
|
220
|
+
{
|
|
221
|
+
if( !rules ) { return true }
|
|
222
|
+
|
|
223
|
+
let tvmaze=show.tvmaze||{}
|
|
224
|
+
|
|
225
|
+
let flags={}
|
|
226
|
+
if( tvmaze.language ) { flags[ tvmaze.language.trim().toLowerCase() ]=true }
|
|
227
|
+
if( tvmaze.type ) { flags[ tvmaze.type.trim().toLowerCase() ]=true }
|
|
228
|
+
if( tvmaze.genres )
|
|
229
|
+
for( let genre of tvmaze.genres || [] )
|
|
230
|
+
{
|
|
231
|
+
flags[ genre.trim().toLowerCase() ]=true
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return check_flags(flags,rules)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// is this episode good?
|
|
238
|
+
shows.good_episode=function(show,rules)
|
|
239
|
+
{
|
|
240
|
+
if( !rules ) { return true }
|
|
241
|
+
|
|
242
|
+
let flags={}
|
|
243
|
+
for( let tag of show.tags || [] )
|
|
244
|
+
{
|
|
245
|
+
flags[ tag.trim().toLowerCase() ]=true
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return check_flags(flags,rules)
|
|
249
|
+
}
|
package/torrents.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
let torrents={}
|
|
4
|
+
export default torrents
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import db from "./db.js"
|
|
8
|
+
|
|
9
|
+
import { remote } from 'parse-torrent'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
torrents.get=async function(url) // always slow
|
|
15
|
+
{
|
|
16
|
+
return await db.get("torrents",url)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
torrents.set=async function(torrent)
|
|
20
|
+
{
|
|
21
|
+
await db.set("torrents",torrent.url,torrent)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
torrents.fetch=async function(url)
|
|
26
|
+
{
|
|
27
|
+
let ret = await torrents.get(url)
|
|
28
|
+
if( ret && ret.data) { return ret.data }
|
|
29
|
+
|
|
30
|
+
let torrent_parse=function(torrent) {
|
|
31
|
+
return new Promise(function(resolve, reject) {
|
|
32
|
+
remote(torrent, { timeout: 60 * 1000 }, function(err, parsedTorrent){
|
|
33
|
+
if (err) { reject(err) }
|
|
34
|
+
resolve(parsedTorrent)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
let data=await torrent_parse(url) // should work with magnets
|
|
39
|
+
|
|
40
|
+
if(data)
|
|
41
|
+
{
|
|
42
|
+
await torrents.set({url:url,data:data})
|
|
43
|
+
}
|
|
44
|
+
return data
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
torrents.prepare=function(torrent)
|
|
49
|
+
{
|
|
50
|
+
return torrent
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// fill in the torrent part of an item
|
|
54
|
+
torrents.fill_torrent=async function(item)
|
|
55
|
+
{
|
|
56
|
+
let torrent_name
|
|
57
|
+
|
|
58
|
+
if(!torrent_name){
|
|
59
|
+
try{
|
|
60
|
+
torrent_name=item.rss["/enclosure"][0]["@url"]
|
|
61
|
+
}catch(e){}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if(!torrent_name){
|
|
65
|
+
try{
|
|
66
|
+
torrent_name=item.rss["/link"]
|
|
67
|
+
}catch(e){}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// hax archive.org to torrents
|
|
71
|
+
if(torrent_name)
|
|
72
|
+
{
|
|
73
|
+
let aa=torrent_name.split("https://archive.org/download/")
|
|
74
|
+
if(aa[1])
|
|
75
|
+
{
|
|
76
|
+
let name=aa[1].split("/")[0]
|
|
77
|
+
if(name)
|
|
78
|
+
{
|
|
79
|
+
torrent_name="https://archive.org/download/"+name+"/"+name+"_archive.torrent"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
try{
|
|
87
|
+
|
|
88
|
+
item.torrent={fail:true}
|
|
89
|
+
let torrent=await torrents.fetch(torrent_name) // should work with magnets
|
|
90
|
+
|
|
91
|
+
if( torrent ) // did we get something
|
|
92
|
+
{
|
|
93
|
+
item.torrent={fail:true}
|
|
94
|
+
|
|
95
|
+
for(let file of torrent.files)
|
|
96
|
+
{
|
|
97
|
+
let pct=Math.floor(100*file.length/torrent.length)
|
|
98
|
+
if(pct>75) // torrent must be mostly this one file
|
|
99
|
+
{
|
|
100
|
+
item.torrent={
|
|
101
|
+
torrent_name:torrent_name,
|
|
102
|
+
torrent_length:torrent.length,
|
|
103
|
+
file_name:file.name,
|
|
104
|
+
file_length:file.length
|
|
105
|
+
}
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
}catch(e){console.log(e)}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
return item
|
|
115
|
+
}
|
|
116
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
const webpack = require('webpack');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
let dd=new Date()
|
|
7
|
+
let da=new Date(dd.getFullYear(), 0, 0)
|
|
8
|
+
let db=new Date(dd.getFullYear()+1, 0, 0)
|
|
9
|
+
let dd_yy=(dd.getFullYear()-2000)
|
|
10
|
+
let dd_dd=Math.floor( 100000 * (dd-da) / (db-da) )
|
|
11
|
+
let dd_version=dd_yy+"."+( ("0000"+dd_dd).slice(-5) )
|
|
12
|
+
|
|
13
|
+
console.log("VERSION == "+dd_version)
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
module: {
|
|
17
|
+
rules: [
|
|
18
|
+
{
|
|
19
|
+
test: /\.(txt|md|html|css|csv)$/i,
|
|
20
|
+
use: 'raw-loader',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
plugins: [
|
|
25
|
+
new webpack.DefinePlugin({
|
|
26
|
+
__THIS_IS_WEBPACK__:true,
|
|
27
|
+
__VERSION__: JSON.stringify(dd_version)
|
|
28
|
+
}),
|
|
29
|
+
new webpack.ProvidePlugin({
|
|
30
|
+
process: 'process/browser',
|
|
31
|
+
}),
|
|
32
|
+
new webpack.ProvidePlugin({
|
|
33
|
+
Buffer: ['buffer', 'Buffer'],
|
|
34
|
+
}),
|
|
35
|
+
],
|
|
36
|
+
entry: './weerss.js',
|
|
37
|
+
resolve: {
|
|
38
|
+
fallback : {
|
|
39
|
+
fs: false,
|
|
40
|
+
url: false,
|
|
41
|
+
path: require.resolve("path-browserify"),
|
|
42
|
+
"stream": require.resolve("stream-browserify"),
|
|
43
|
+
"buffer": require.resolve("buffer/"),
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
performance: {
|
|
47
|
+
hints: false,
|
|
48
|
+
maxEntrypointSize: 555555,
|
|
49
|
+
maxAssetSize: 555555,
|
|
50
|
+
},
|
|
51
|
+
output: {
|
|
52
|
+
path: path.resolve(__dirname, '../docs/js/'),
|
|
53
|
+
filename: 'weerss.js',
|
|
54
|
+
globalObject: 'this',
|
|
55
|
+
library: {
|
|
56
|
+
name: 'weerss',
|
|
57
|
+
type: 'umd',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|