@xriss/weerss 0.0.3 → 0.0.5

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.js CHANGED
@@ -2,8 +2,9 @@
2
2
  const cmd={}
3
3
  export default cmd
4
4
 
5
+ import wtf from 'wtfnode'
5
6
 
6
- import minimist from "minimist"
7
+ import mri from "mri"
7
8
 
8
9
  import path from "path"
9
10
  import url from "url"
@@ -17,14 +18,16 @@ import items from "./items.js"
17
18
 
18
19
  import weerss from "./weerss.js"
19
20
 
20
- const args = minimist(process.argv.slice(2),{boolean:true})
21
+ const args = mri(process.argv.slice(2))
22
+ //console.log(args)
21
23
 
22
- args.config=args.config || process.env.WEERSS_CONFIG
24
+ args.config=args.config || process.env.WEERSS_CONFIG || process.env.HOME+"/.config/weerss/config.djon"
23
25
 
24
26
  await weerss.load_config(args)
25
27
 
26
28
  let arg1=args._[0] || "help"
27
29
  let arg2=args._[1]
30
+ let arg3=args._[3]
28
31
 
29
32
  if( arg1=="help" )
30
33
  {
@@ -42,30 +45,48 @@ options:
42
45
 
43
46
  export WEERSS_CONFIG=/home/dave/weerss.config
44
47
 
48
+ All options are loaded into this config structure with . used as an
49
+ object seperator and the value parsed as json.
50
+
51
+ EG To choose the number of items in your rss feed from the command line
52
+ and thus overide the config file setting.
53
+
54
+ --rss.length=100
55
+ or
56
+ --rss='{length:100}'
57
+
58
+ With the later removing any other values in the rss object while the
59
+ former just changes the legth value.
60
+
45
61
  commands:
46
62
 
47
- tvrss config
48
- Print current config.
63
+ weerss config
64
+ Create a default to config file if we do not already have one and
65
+ then print the current config. I recomend reading the default
66
+ config file for comments about how to configure weerss.
49
67
 
50
- tvrss config FILENAME
51
- Save current (default?) config to FILENAME.
68
+ weerss config --force
69
+ Force saving of default config over current config.
52
70
 
53
- tvrss fetch
71
+ weerss fetch
54
72
  Fetch all feeds and scan files with tvmaze.
55
73
 
56
- tvrss list
74
+ weerss list
57
75
  List torrents in db.
58
76
 
59
- tvrss rss
77
+ weerss rss
60
78
  Save torrents as rss.
61
79
 
62
- tvrss move
63
- Move downloaded chaotic files to an organised location.
80
+ weerss move
81
+ Move downloaded chaotic files to an organised jellyfin style
82
+ directory.
64
83
 
65
- tvrss dirs
66
- Create a script to cleanup TV dirs using tvmaze.
84
+ weerss dirs
85
+ Create a script to cleanup TV dirs using tvmaze. This does not do
86
+ any cleanup just prints bash commands that you may wish to run
87
+ later.
67
88
 
68
- tvrss help
89
+ weerss help
69
90
  Print this help message.
70
91
 
71
92
  `)
@@ -78,6 +99,7 @@ if( arg1=="config" )
78
99
  else
79
100
  if( arg1=="fetch" )
80
101
  {
102
+ args.wtf=true // torrents are a problem so force exit afterwards
81
103
  await weerss.fetch(args)
82
104
  }
83
105
  else
@@ -104,3 +126,10 @@ else
104
126
  {
105
127
  console.log(` Unknown weerss command "${arg1}" `)
106
128
  }
129
+
130
+ if(args.wtf)
131
+ {
132
+ console.log(` Forcing exit `)
133
+ wtf.dump()
134
+ process.exit(0)
135
+ }
package/db.js CHANGED
@@ -29,7 +29,7 @@ db.name="weerss"
29
29
  db.setup=async function()
30
30
  {
31
31
 
32
- db.handle = await AsyncDatabase.open( weerss.get_config_path("sqlite_filename") );
32
+ db.handle = await AsyncDatabase.open( weerss.get_config_path("sqlite") );
33
33
 
34
34
  // db.handle.inner.on("trace", (sql) => console.log("[TRACE]", sql));
35
35
 
package/hoard.js CHANGED
@@ -66,10 +66,13 @@ hoard.fetch_text=async function(url,refresh)
66
66
  it.date=new Date()
67
67
  try{
68
68
 
69
+ let timeout_id
69
70
  let res=await Promise.race([
70
71
  fetch(corsurl),
71
- new Promise((_, reject) => setTimeout(() => reject("timeout"), 2*1000)),
72
+ new Promise(function(_, reject){ timeout_id=setTimeout(function(){reject("timeout")}, 2*1000) } ),
72
73
  ])
74
+ if(timeout_id) { clearTimeout(timeout_id) }
75
+
73
76
  it.status=res.status
74
77
  it.text=await res.text()
75
78
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xriss/weerss",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "source": "weerss.js",
5
5
  "type": "module",
6
6
  "repository": {
@@ -17,8 +17,9 @@
17
17
  "dependencies": {
18
18
  "@xriss/djon": "^0.0.14",
19
19
  "express": "^4.19.2",
20
- "minimist": "^1.2.8",
20
+ "memory-chunk-store": "^1.3.5",
21
21
  "move-file": "^3.1.0",
22
+ "mri": "^1.2.0",
22
23
  "parse-torrent": "^11.0.17",
23
24
  "path-browserify": "^1.0.1",
24
25
  "promised-sqlite3": "^2.1.0",
@@ -27,7 +28,9 @@
27
28
  "sax": "^1.4.1",
28
29
  "sqlite3": "^5.1.7",
29
30
  "stream-browserify": "^3.0.0",
30
- "webpack": "^5.94.0"
31
+ "webpack": "^5.94.0",
32
+ "webtorrent": "^2.5.1",
33
+ "wtfnode": "^0.9.3"
31
34
  },
32
35
  "devDependencies": {
33
36
  "webpack-cli": "^5.1.4"
package/torrents.js CHANGED
@@ -4,9 +4,12 @@ let torrents={}
4
4
  export default torrents
5
5
 
6
6
 
7
- import db from "./db.js"
7
+ import db from "./db.js"
8
+ import hoard from "./hoard.js"
8
9
 
10
+ import WebTorrent from 'webtorrent'
9
11
  import { remote } from 'parse-torrent'
12
+ import memchunks from 'memory-chunk-store'
10
13
 
11
14
 
12
15
 
@@ -27,15 +30,90 @@ torrents.fetch=async function(url)
27
30
  let ret = await torrents.get(url)
28
31
  if( ret && ret.data) { return ret.data }
29
32
 
30
- let torrent_parse=function(torrent) {
33
+ let urlplus=url
34
+ if(urlplus.toLowerCase().startsWith("magnet:")) // auto add trackers
35
+ {
36
+ let trackers=(await hoard.fast_text("https://newtrackon.com/api/stable")).split("\n")
37
+ let count=0
38
+ for(let t of trackers)
39
+ {
40
+ t=t.trim()
41
+ if(t!="")
42
+ {
43
+ urlplus=urlplus+"&tr="+encodeURIComponent(t)
44
+ count=count+1
45
+ if(count>10){break}
46
+ }
47
+ }
48
+ }
49
+ // console.log(urlplus)
50
+
51
+ let torrent_parse=function(url) {
31
52
  return new Promise(function(resolve, reject) {
32
- remote(torrent, { timeout: 60 * 1000 }, function(err, parsedTorrent){
53
+ remote(url, { timeout: 60 * 1000 }, function(err, parsedTorrent){
33
54
  if (err) { reject(err) }
34
55
  resolve(parsedTorrent)
35
56
  })
36
57
  })
37
58
  }
38
- let data=await torrent_parse(url) // should work with magnets
59
+ let data=await torrent_parse(urlplus) // does not work with magnets?
60
+
61
+ let client
62
+ let torrent_magnet_add=async function(url) {
63
+ return new Promise(function(resolve, reject)
64
+ {
65
+ client = new WebTorrent()
66
+ client.on('error', function(err){ if(!client.destroyed){client.destroy()} ; reject(err) })
67
+ // download to memory using memchunks
68
+ let torrent=client.add(url, {store:memchunks} , function(torrent){
69
+ resolve(torrent)
70
+ })
71
+ torrent.on('error', function(err){ if(!client.destroyed){client.destroy()} ; reject(err) })
72
+ torrent.on('noPeers', function(err){ if(!client.destroyed){client.destroy()} ; reject(err) })
73
+ /*
74
+ for(let n of [
75
+ "infoHash" , "metadata" , "ready" , "warning" ,
76
+ "error" , "done" , "download" , "upload" ,
77
+ "wire" , "noPeers" , "verified"
78
+ ])
79
+ {
80
+ torrent.on(n, function(d){ console.log(n,d) })
81
+ }
82
+ */
83
+ })
84
+ }
85
+
86
+ if(!data.files) // need to magnet?
87
+ {
88
+ data.files=[]
89
+ // console.log(data)
90
+
91
+ let timeout_id
92
+ let torrent=await Promise.race([
93
+ torrent_magnet_add(urlplus),
94
+ new Promise(function(_, reject){ timeout_id=setTimeout(function(){reject("timeout")}, 10*1000) } ),
95
+ ])
96
+ if(timeout_id) { clearTimeout(timeout_id) }
97
+
98
+ if(torrent)
99
+ {
100
+ data.length=torrent.length
101
+ // console.log(data.files)
102
+ for( let ff of torrent.files )
103
+ {
104
+ let f={}
105
+ f.name=ff.name
106
+ f.length=ff.length
107
+ data.files.push(f)
108
+ }
109
+ torrent.destroy()
110
+ }
111
+ if(client)
112
+ {
113
+ if(!client.destroyed){client.destroy()}
114
+ client=undefined
115
+ }
116
+ }
39
117
 
40
118
  if(data)
41
119
  {
@@ -91,7 +169,7 @@ torrents.fill_torrent=async function(item)
91
169
  if( torrent ) // did we get something
92
170
  {
93
171
  item.torrent={fail:true}
94
-
172
+
95
173
  for(let file of torrent.files)
96
174
  {
97
175
  let pct=Math.floor(100*file.length/torrent.length)
package/weerss.js CHANGED
@@ -17,31 +17,36 @@ import shows from "./shows.js"
17
17
  import util from "util"
18
18
  import {moveFile} from 'move-file'
19
19
 
20
+ import { promises as pfs } from "fs"
20
21
  import fs from "fs"
21
22
  import path from "path"
22
23
 
23
24
  import sanitize from "sanitize-filename"
24
25
 
25
-
26
26
  import djon from "@xriss/djon"
27
27
 
28
28
 
29
29
 
30
30
  weerss.config_default=`
31
31
  {
32
+ // set to true for verbose rule checking
32
33
  debug = FALSE
34
+ // array of url to rss feeds of torrent files
33
35
  feeds = [
34
36
  "https://archive.org/services/collection-rss.php?collection=television_inbox"
35
37
  ]
36
38
  rss = {
39
+ // number of episodes to list in the rss files
37
40
  length = 100
38
41
  }
42
+ // decide which shows we like ( data from tvmaze )
39
43
  show = {
40
44
  rules = [
41
45
  [ TRUE ]
42
46
  [ "!english" FALSE ]
43
47
  ]
44
48
  }
49
+ // decide which episode we like tags come from filename
45
50
  episode = {
46
51
  best = "small"
47
52
  maxsize = 4000000000
@@ -51,9 +56,13 @@ weerss.config_default=`
51
56
  [ "480p" FALSE ]
52
57
  ]
53
58
  }
54
- sqlite_filename = "./weerss.sqlite"
55
- download_dirname = "./download"
56
- tv_dirname = "./TV"
59
+ // paths can be relative to this config files location
60
+ paths = {
61
+ rss = "./weerss.rss"
62
+ sqlite = "./weerss.sqlite"
63
+ download = "./download"
64
+ tv = "./TV"
65
+ }
57
66
  }
58
67
  `
59
68
 
@@ -86,29 +95,37 @@ weerss.load_config=async function(args)
86
95
  {
87
96
  if(n!="_")
88
97
  {
89
- weerss.config[n]=args[n]
98
+ let va=args[n]
99
+ try{ va=djon.load(va) }catch(e){} // if can parse
100
+ let ns=n.split(".")
101
+ let f=ns.pop()
102
+ let b=weerss.config
103
+ for( let v of ns ) { b=b[v] } // sub sets
104
+ b[f]=va
90
105
  }
91
106
  }
92
107
  }
93
108
 
94
109
  weerss.save_config=async function(args)
95
110
  {
96
- if( args._[1] )
111
+ if(args.config) // need a config location
97
112
  {
98
- let fname=args._[1]
99
- console.log(` Saving config to `+fname)
100
- if(args.config) // loading a config
113
+ if( (!args.force) && fs.existsSync(args.config) ) // must not already exist
101
114
  {
102
- djon.save_file(fname,weerss.config,"djon","strict")
115
+ console.log( "Config already exists : "+args.config )
116
+ console.log( djon.save(weerss.config,"djon","strict") )
103
117
  }
104
- else // save default
118
+ else // write defaukt config
105
119
  {
106
- fs.writeFileSync( fname , weerss.config_default )
120
+ console.log( "Writing config to : "+args.config )
121
+ try{ await pfs.mkdir( path.dirname(args.config) ) }catch(e){}
122
+ fs.writeFileSync( args.config , weerss.config_default )
107
123
  }
108
- return
109
124
  }
110
-
111
- console.log( djon.save(weerss.config,"djon","strict") )
125
+ else
126
+ {
127
+ console.log( "Must specify config file with --config=~/.weerss.config " )
128
+ }
112
129
  }
113
130
 
114
131
  weerss.get_config_path=function(name)
@@ -123,8 +140,8 @@ weerss.get_config_path=function(name)
123
140
  d=path.resolve( "." )
124
141
  }
125
142
 
126
- let f=weerss.config[name] || "."
127
- if( ! f.startsWith("/" ) )
143
+ let f=weerss.config.paths[name] || "."
144
+ if( ! path.isAbsolute(f) )
128
145
  {
129
146
  f=path.join( d , f )
130
147
  }
@@ -313,7 +330,7 @@ weerss.list=async function(args)
313
330
  {
314
331
  await db.setup()
315
332
 
316
- let list=(await weerss.getlist())
333
+ let list=(await weerss.getlist()).slice(0,weerss.config.rss.length)
317
334
  for(let item of list)
318
335
  {
319
336
  console.log( item_to_string(item))
@@ -367,16 +384,16 @@ weerss.save_rss=async function(args)
367
384
  rss_items.push(it)
368
385
  }
369
386
 
370
- let list=(await weerss.getlist(weerss.config.show.rules)).slice(0,100)
387
+ let list=(await weerss.getlist(weerss.config.show.rules)).slice(0,weerss.config.rss.length)
371
388
  for(let item of list)
372
389
  {
373
390
  push_item(item)
374
391
  }
375
392
 
376
393
 
377
- if( args._[1] )
394
+ let fname=weerss.get_config_path("rss")
395
+ if( fname )
378
396
  {
379
- let fname=args._[1]
380
397
  console.log(` Saving rss to `+fname)
381
398
 
382
399
  fs.writeFileSync( fname , jxml.build_xml(dat) )
@@ -393,8 +410,8 @@ weerss.save_rss=async function(args)
393
410
  weerss.move=async function(args)
394
411
  {
395
412
 
396
- let from=weerss.get_config_path("download_dirname") //args._[2] // optional dest dir
397
- let dest=weerss.get_config_path("tv_dirname") //args._[2] // optional dest dir
413
+ let from=weerss.get_config_path("download") //args._[2] // optional dest dir
414
+ let dest=weerss.get_config_path("tv") //args._[2] // optional dest dir
398
415
 
399
416
  dest=null // do not move
400
417
 
@@ -483,7 +500,7 @@ weerss.move=async function(args)
483
500
 
484
501
  weerss.dirs=async function(args)
485
502
  {
486
- let dest=weerss.get_config_path("tv_dirname")
503
+ let dest=weerss.get_config_path("tv")
487
504
 
488
505
 
489
506
  await db.setup()