aniview 0.3.0 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f84d93b24636a62d6ce22d1f9849091921c181c
4
- data.tar.gz: a231335941b316bc5c11e1f65f92f2df6b413956
3
+ metadata.gz: c3997c84f2c7fe4c76932df56e2974b8e7fcdfdd
4
+ data.tar.gz: de56d18cced70e4feb91ad1f54bbf6975eaaa761
5
5
  SHA512:
6
- metadata.gz: 7781cf1761ba7187e1f890e4be9d810e23a9e4c55983ae19df2a27af93215c7862898adfbc3af1d2dcfa2bd1d44037318479b92b9a180ae0d0317b92004247cb
7
- data.tar.gz: a313caffe6a8a5c04d9501f91af855a194936f9af9a4699b904b223a4cf43c57585520d042485105592eb2f0c176751293567b118d5f22899c379b659138b5dc
6
+ metadata.gz: e59457afc95892f3a5002bc9fa01d3433a39a831ea32c5382628939245c3f23e1125c829634f1760b830fc1f2edec1645c58ed9d2d43a30113ceb79060ff7a49
7
+ data.tar.gz: c51ed7a61437b2ed9bc3c7a8ea02e4b7b52a04c788bcfedcaa5e8baa54af72025e4ed9d0e29459a2b54b47029650ae825ce07db620cbf0737473383f2ec71a3c
@@ -1,6 +1,5 @@
1
1
  require 'highline'
2
2
  require 'highline/import'
3
- require 'json'
4
3
  require 'thread'
5
4
  require 'io/console'
6
5
  require 'warning'
@@ -10,30 +9,54 @@ Warning.ignore([:fixnum, :bignum])
10
9
  require_relative 'aniview/view/aiomenu'
11
10
  require_relative 'aniview/view/delugemenu'
12
11
  require_relative 'aniview/view/prefmenu'
12
+ require_relative 'aniview/view/schedulemenu'
13
+ require_relative 'aniview/view/subscriptionmenu'
13
14
 
14
15
  require_relative 'aniview/interface/animeio/animeio'
15
16
  require_relative 'aniview/interface/deluge/delugec'
16
17
  require_relative 'aniview/interface/pref/pref'
17
- require_relative 'aniview/interface/rssfeed/rssfeed'
18
+ require_relative 'aniview/interface/subscription/subscription'
19
+ require_relative 'aniview/interface/subscription/subscriptiondaemon'
20
+ require_relative 'aniview/interface/schedule/schedule'
18
21
 
19
22
  require_relative 'aniview/util/alogger'
20
23
  require_relative 'aniview/util/command'
21
24
  require_relative 'aniview/util/term'
22
25
 
26
+ require_relative 'aniview/client/aniclient'
27
+
23
28
  $stdout.sync = true
24
29
 
25
30
  class AniView
26
31
  def initialize
27
32
 
28
- @term = Term.new
33
+ @term = Term.new
29
34
 
30
35
  @pref = Pref.new
31
36
 
32
- @aio = AnimeIO.new(@pref)
33
- @delugec = DelugeC.new(@pref)
34
- #@rssfeed = RssFeed.new(@pref)
35
- @l = ALogger.new(@pref.parseTilde(@pref.get "log_file"))
36
- @aiomenu = AioMenu.new(
37
+ $l = ALogger.new(@pref.parseDir(@pref.get "log_file"), false)
38
+
39
+ @aio = AnimeIO.new @pref
40
+
41
+ @schedule = Schedule.new @pref
42
+
43
+ @delugec = DelugeC.new(@pref)
44
+
45
+ @c = AniClient.new @pref
46
+
47
+ @subscription = Subscription.new(@pref, @schedule, @delugec, @c)
48
+
49
+ if not @c.server?
50
+ #puts "starting server"
51
+ process = fork do
52
+ require_relative 'aniviewd'
53
+ avd = AniViewd.new([])
54
+ avd.run
55
+ end
56
+ Process.detach(process)
57
+ end
58
+
59
+ @aiomenu = AioMenu.new(
37
60
  refresh_function: :getAll,
38
61
  interface: @aio,
39
62
  name: @pref.get("menu_titles")["library"],
@@ -59,6 +82,26 @@ class AniView
59
82
  term: @term,
60
83
  children: false
61
84
  )
85
+
86
+ @schedulemenu = ScheduleMenu.new(
87
+ refresh_function: :getAll,
88
+ interface: @schedule,
89
+ name: @pref.get("menu_titles")["schedlue"],
90
+ pref: @pref,
91
+ format: "format_schedule",
92
+ term: @term,
93
+ children: false
94
+ )
95
+
96
+ @subscriptionmenu = SubscriptionMenu.new(
97
+ refresh_function: :getAll,
98
+ interface: @subscription,
99
+ name: @pref.get("menu_titles")["subscriptions"],
100
+ pref: @pref,
101
+ format: "format_subscriptions",
102
+ term: @term,
103
+ children: false
104
+ )
62
105
 
63
106
  @term.save.hide_cursor.echo_off
64
107
 
@@ -130,12 +173,18 @@ class AniView
130
173
  elsif key == @pref.get("keybindings")["goto_torrents"]
131
174
  @view = @delugemenu
132
175
  @view.setName(@pref.get("menu_titles")["torrents"])
133
- @view.setRfunc(:getTorrents)
134
176
 
135
177
  elsif key == @pref.get("keybindings")["goto_preferences"]
136
178
  @view = @prefmenu
137
179
  @view.setName(@pref.get("menu_titles")["preferences"])
138
- @view.setRfunc(:getAll)
180
+
181
+ elsif key == @pref.get("keybindings")["goto_schedule"]
182
+ @view = @schedulemenu
183
+ @view.setName(@pref.get("menu_titles")["schedule"])
184
+
185
+ elsif key == @pref.get("keybindings")["goto_subscriptions"]
186
+ @view = @subscriptionmenu
187
+ @view.setName(@pref.get("menu_titles")["subscriptions"])
139
188
 
140
189
  elsif key == ":"
141
190
  cmd = Command.read(@term, ":")
@@ -0,0 +1,50 @@
1
+ require 'socket'
2
+
3
+ #require_relative '../interface/pref/pref'
4
+
5
+ class AniClient
6
+
7
+ def initialize(pref)
8
+ @pref = pref
9
+ # @pref = Pref.new if @pref == "no"
10
+ end
11
+
12
+ def connect
13
+ begin
14
+ TCPSocket.new 'localhost', @pref.get("daemon")["port"]
15
+ rescue Errno::ECONNREFUSED
16
+ return false
17
+ end
18
+ end
19
+
20
+ def sendMsg msg
21
+ begin
22
+ s = connect
23
+ return "" if s == false
24
+ s.puts msg
25
+ r = s.gets.chomp
26
+ s.close
27
+ return r
28
+ rescue Errno::ECONNRESET
29
+ return ""
30
+ end
31
+ end
32
+
33
+ def stopDaemon
34
+ sendMsg "quit"
35
+ end
36
+
37
+ def info
38
+ sendMsg "info"
39
+ end
40
+
41
+ def lastchecked
42
+ sendMsg "lastchecked"
43
+ end
44
+
45
+ def server?
46
+ return false unless sendMsg("up?") == "true"
47
+ return true
48
+ end
49
+
50
+ end
@@ -41,7 +41,7 @@ class AnimeIO
41
41
  ret = {}
42
42
  (@pref.get("anime_locations").split(":")).each { |dir|
43
43
 
44
- dir = @pref.parseTilde dir
44
+ dir = @pref.parseDir dir
45
45
 
46
46
  Dir.glob("#{dir}*/*.{mkv,avi,mp4}").each { |file|
47
47
  puts "indexing #{file}" if verbose
@@ -117,11 +117,6 @@ class AnimeIO
117
117
  subarray
118
118
  ) => subarray
119
119
  )
120
-
121
-
122
- #puts ret.inspect
123
- #exit
124
-
125
120
  return Hash[ret.sort_by{ |a| a[0].title}]
126
121
  end
127
122
 
@@ -157,7 +152,7 @@ class AnimeIO
157
152
  end
158
153
 
159
154
  def logWatched(file)
160
- open(@pref.parseTilde(@pref.get("watch_log")), 'a') do |f|
155
+ open(@pref.parseDir(@pref.get("watch_log")), 'a') do |f|
161
156
  f.puts %x(date).chomp + " ./" + File.basename(file) + " " + @watch_log_tag
162
157
  end
163
158
  end
@@ -3,54 +3,151 @@ require_relative 'torrentitem'
3
3
 
4
4
  class DelugeC
5
5
 
6
- def initialize pref
7
- @pref = pref
8
-
9
- host = @pref.get("deluge_config")["host"]
10
- login = @pref.get("deluge_config")["login"]
11
- password = @pref.get("deluge_config")["password"]
12
-
13
- if (login == "" and password == "") and (host == "127.0.0.1" or host == "localhost")
14
- la = localAuth
15
- login = la[0]
16
- password = la[1]
17
- @pref.set(["deluge_config", "login"], login)
18
- @pref.set(["deluge_config", "password"], password)
19
- end
20
-
21
- @client = Deluge::Rpc::Client.new(
22
- host: host,
23
- port: Integer(@pref.get("deluge_config")["port"]),
24
- login: @pref.get("deluge_config")["login"],
25
- password: @pref.get("deluge_config")["password"]
26
- )
27
-
28
- @client.connect
29
-
30
- end
31
-
32
- def localAuth
33
- authfile = Dir.home + "/.config/deluge/auth"
34
- ["", ""] if not File.exist? authfile
35
- File.open(Dir.home + "/.config/deluge/auth") { |f| f.read }.split(":")
36
- end
37
-
38
- def getTorrents
39
- return @client.core.get_torrents_status({}, ['name', 'progress', 'eta'])
40
- end
41
-
42
- def makeHash(arr)
43
- ret = {}
44
- arr.each{ |t|
45
- tinfo = t[1]
46
- torrent = TorrentItem.new(
47
- name: tinfo["name"],
48
- progress: tinfo["progress"],
49
- eta: tinfo["eta"],
50
- )
51
- ret.merge!(torrent => torrent)
52
- }
53
- return ret
54
- end
6
+ def initialize pref
7
+ @pref = pref
8
+
9
+ host = @pref.get("deluge_config")["host"]
10
+ login = @pref.get("deluge_config")["login"]
11
+ password = @pref.get("deluge_config")["password"]
12
+
13
+ if (login == "" and password == "") and (host == "127.0.0.1" or host == "localhost")
14
+ la = localAuth
15
+ login = la[0]
16
+ password = la[1]
17
+ @pref.set(["deluge_config", "login"], login)
18
+ @pref.set(["deluge_config", "password"], password)
19
+ end
20
+
21
+ @client = Deluge::Rpc::Client.new(
22
+ host: host,
23
+ port: Integer(@pref.get("deluge_config")["port"]),
24
+ login: @pref.get("deluge_config")["login"],
25
+ password: @pref.get("deluge_config")["password"]
26
+ )
27
+
28
+ @status = "not connected"
29
+ @connected = false
30
+ connect
31
+
32
+ end
33
+
34
+ def getStatus
35
+ @status
36
+ end
37
+
38
+ def connect
39
+ begin
40
+ @status = "connected"
41
+ @client.connect
42
+ @connected = true
43
+ rescue Deluge::Rpc::Connection::RPCError
44
+ @status = "error connecting"
45
+ @connected = false
46
+ rescue RuntimeError
47
+ @status = "error connecting"
48
+ @client.close
49
+ @connected = false
50
+ end
51
+
52
+ @client.close unless @connected
53
+ end
54
+
55
+ def localAuth
56
+ authfile = Dir.home + "/.config/deluge/auth"
57
+ ["", ""] if not File.exist? authfile
58
+ File.open(Dir.home + "/.config/deluge/auth") { |f| f.read }.split(":")
59
+ end
60
+
61
+ def getTorrents
62
+ connect unless @connected
63
+ return {} unless @connected
64
+
65
+ tkeys = [
66
+ "name",
67
+ "progress",
68
+ "eta",
69
+ "paused",
70
+ "state",
71
+ "hash",
72
+ #"active_time",
73
+ #"is_finished",
74
+ #"max_connections",
75
+ #"max_download_speed",
76
+ #"max_upload_slots",
77
+ #"max_upload_speed",
78
+ #"message",
79
+ #"next_announce",
80
+ #"num_peers",
81
+ #"num_seeds",
82
+ #"remove_at_ratio",
83
+ #"save_path",
84
+ #"seeding_time",
85
+ #"seeds_peers_ratio",
86
+ #"seed_rank",
87
+ #"stop_at_ratio",
88
+ #"stop_ratio",
89
+ #"time_added",
90
+ #"upload_payload_rate",
91
+ #"comment",
92
+ #"file_priorities",
93
+ #"file_progress",
94
+ #"files",
95
+ #"is_seed",
96
+ #"num_files",
97
+ #"num_pieces",
98
+ #"peers",
99
+ #"piece_length",
100
+ #"private",
101
+ #"queue",
102
+ #"ratio",
103
+ #"total_size",
104
+ #"tracker_host"
105
+ ]
106
+
107
+ return @client.core.get_torrents_status({}, tkeys)
108
+ end
109
+
110
+ def toggleTorrent torrentItem
111
+ id = torrentItem.attributes["h"]
112
+ if torrentItem.attributes["u"]
113
+ @client.core.resume_torrent([id])
114
+ else
115
+ @client.core.pause_torrent([id])
116
+ end
117
+ end
118
+
119
+ def removeTorrent torrentItem, withData
120
+ id = torrentItem.attributes["h"]
121
+ @client.core.remove_torrent(id, withData)
122
+ end
123
+
124
+ def addTorrent mag, loc
125
+ connect unless @connected
126
+ return false unless @connected
127
+ begin
128
+ tid = @client.core.add_torrent_magnet(mag, {"download_location": loc})
129
+ rescue Deluge::Rpc::Connection::InvokeTimeoutError
130
+ tid = nil
131
+ end
132
+ return true if tid.class == String and tid.length > 1
133
+ return false
134
+ end
135
+
136
+ def makeHash(arr)
137
+ ret = {}
138
+ arr.each{ |t|
139
+ tinfo = t[1]
140
+ torrent = TorrentItem.new(
141
+ name: tinfo["name"],
142
+ progress: tinfo["progress"],
143
+ eta: tinfo["eta"],
144
+ paused: tinfo["paused"],
145
+ state: tinfo["state"],
146
+ id: tinfo["hash"]
147
+ )
148
+ ret.merge!(torrent => torrent)
149
+ }
150
+ return ret
151
+ end
55
152
 
56
153
  end
@@ -2,11 +2,14 @@ require_relative '../../util/format'
2
2
  require_relative '../item'
3
3
 
4
4
  class TorrentItem < Item
5
- def initialize(name:, progress:, eta:)
5
+ def initialize(name:, progress:, eta:, paused:, state:, id:)
6
6
  @attr = {
7
7
  "n" => name,
8
8
  "p" => Format.format_progress(progress),
9
9
  "e" => Format.format_duration(eta),
10
+ "u" => paused,
11
+ "s" => state,
12
+ "h" => id
10
13
  }
11
14
  end
12
15
 
@@ -1,68 +1,97 @@
1
1
  {
2
- "keybindings" :
3
- {
4
- "goto_preferences" : "0",
5
- "goto_unwatched" : "1",
6
- "goto_library" : "2",
7
- "goto_torrents" : "3",
8
- "anime_set_watched" : "Z",
9
- "anime_set_unwatched" : "u",
10
- "anime_undo_set_watched" : "z",
11
- "menu_nav_up" : "up",
12
- "menu_nav_down" : "down",
13
- "menu_nav_expand" : "space"
14
- },
15
- "anime_locations" : "~/anime/",
16
- "clr" :
17
- {
18
- "main" : "blue",
19
- "primary" : "white",
20
- "secondary" : "cyan",
21
- "selected" : "red"
22
- },
23
- "menu_titles" :
24
- {
25
- "unwatched" : "unwatched",
26
- "library" : "anime library",
27
- "torrents" : "torrents",
28
- "preferences" : "preferences"
29
- },
30
- "format_library" :
31
- {
32
- "title" : " %t @ %D %S ",
33
- "parent" : " %t - %c@ %D %S ",
34
- "child" : " %t@ %D %S "
35
- },
36
- "format_library_unwatched" :
37
- {
38
- "title" : " %t @ $q@ %D %S ",
39
- "parent" : " %t - %c@ %D %S ",
40
- "child" : " %t@ %D %S %r "
41
- },
42
- "format_torrents" :
43
- {
44
- "title" : " %t",
45
- "parent" : " %n@ %p "
46
- },
47
- "format_preferences" :
48
- {
49
- "title" : " %t",
50
- "parent" : " %t@ %v "
51
- },
52
- "deluge_config" :
53
- {
54
- "host" : "localhost",
55
- "port" : "58846",
56
- "login" : "",
57
- "password" : ""
58
- },
59
- "rss_feed" :
60
- {
61
- "url" : "https://www.nyaa.se/?page=rss&cats=1_37&filter=1&term=",
62
- "refresh_interval" : "150"
63
- },
64
- "log_file" : "~/.aw/aw.log",
65
- "watch_log" : "~/.aw/watchlog",
66
- "watch_command" : "mpv -alang jpn -slang eng -msg-level=all=fatal -ass",
67
- "local_anime" : null
2
+ "keybindings" :
3
+ {
4
+ "goto_preferences" : "0",
5
+ "goto_unwatched" : "1",
6
+ "goto_library" : "2",
7
+ "goto_torrents" : "3",
8
+ "goto_schedule" : "4",
9
+ "goto_subscriptions" : "5",
10
+ "anime_set_watched" : "Z",
11
+ "anime_set_unwatched" : "u",
12
+ "anime_undo_set_watched" : "z",
13
+ "torrents_pause" : "space",
14
+ "torrents_remove" : "-",
15
+ "torrents_remove_data" : "_",
16
+ "schedule_add_item" : "+",
17
+ "schedule_delete_item" : "-",
18
+ "schedule_edit_item" : "enter",
19
+ "subscriptions_edit" : "enter",
20
+ "menu_nav_up" : "up",
21
+ "menu_nav_down" : "down",
22
+ "menu_nav_expand" : "space"
23
+ },
24
+ "anime_locations" : "~/anime/:$airing_dir",
25
+ "airing_dir" : "~/anime/airing/",
26
+ "clr" :
27
+ {
28
+ "main" : "blue",
29
+ "primary" : "white",
30
+ "secondary" : "cyan",
31
+ "selected" : "red"
32
+ },
33
+ "menu_titles" :
34
+ {
35
+ "unwatched" : "unwatched",
36
+ "library" : "anime library",
37
+ "torrents" : "torrents",
38
+ "preferences" : "preferences",
39
+ "schedule" : "schedule",
40
+ "subscriptions" : "subscriptions"
41
+ },
42
+ "format_library" :
43
+ {
44
+ "title" : " %t @ %D %S ",
45
+ "parent" : " %t - %c@ %D %S ",
46
+ "child" : " %t@ %D %S "
47
+ },
48
+ "format_library_unwatched" :
49
+ {
50
+ "title" : " %t @ $q@ %D %S ",
51
+ "parent" : " %t - %c@ %D %S ",
52
+ "child" : " %t@ %D %S %r "
53
+ },
54
+ "format_torrents" :
55
+ {
56
+ "title" : " %t - %s",
57
+ "parent" : " %n@ %p "
58
+ },
59
+ "format_schedule" :
60
+ {
61
+ "title" : " %t",
62
+ "parent" : " %t@ %p "
63
+ },
64
+ "format_subscriptions" :
65
+ {
66
+ "title" : " %t - %d@ last checked: %l ",
67
+ "parent" : " %f - /%r/@ %m "
68
+ },
69
+ "format_preferences" :
70
+ {
71
+ "title" : " %t",
72
+ "parent" : " %t@ %v "
73
+ },
74
+ "deluge_config" :
75
+ {
76
+ "host" : "localhost",
77
+ "port" : "58846",
78
+ "login" : "",
79
+ "password" : ""
80
+ },
81
+ "rss_feed" :
82
+ {
83
+ "url" : "https://nyaa.pantsu.cat/feed?c=3_5&s=1&max=100&userID=0&q=",
84
+ "refresh_interval" : "150"
85
+ },
86
+ "daemon" :
87
+ {
88
+ "port" : "21312"
89
+ },
90
+ "log_file" : "$conf_dir/aw.log",
91
+ "daemon_log_file" : "$conf_dir/server.log",
92
+ "watch_log" : "$conf_dir/watchlog",
93
+ "conf_dir" : "~/.config/aniview",
94
+ "watch_command" : "mpv -alang jpn -slang eng -msg-level=all=fatal -ass",
95
+ "local_anime" : null,
96
+ "schedule" : []
68
97
  }