aniview 3.2.1 → 5.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -9
  3. data/bin/aniview +17 -9
  4. data/config/view.yml +3 -0
  5. data/lib/aniview.rb +1 -60
  6. data/modules/animeio/README.md +2 -0
  7. data/modules/animeio/config/daemon.yml +4 -0
  8. data/modules/animeio/config/view.yml +22 -0
  9. data/modules/animeio/lib/animeio.rb +24 -0
  10. data/modules/animeio/lib/animeio/anime_indexer.rb +99 -0
  11. data/modules/animeio/lib/animeio/animefile.rb +91 -0
  12. data/modules/animeio/lib/animeio/animeio.rb +175 -0
  13. data/modules/animeio/lib/animeio/animeio_view.rb +41 -0
  14. data/modules/animeio/lib/animeio/animeseries.rb +61 -0
  15. data/modules/mpv/README.md +2 -0
  16. data/modules/mpv/config/daemon.yml +2 -0
  17. data/modules/mpv/lib/mpv.rb +27 -0
  18. data/modules/mpv/lib/mpv/filename_widget.rb +16 -0
  19. data/modules/mpv/lib/mpv/mpv_controller.rb +85 -0
  20. data/modules/mpv/lib/mpv/time_widget.rb +29 -0
  21. metadata +33 -107
  22. data/lib/aniview/client/aniclient.rb +0 -118
  23. data/lib/aniview/interface/animeio/animefile.rb +0 -93
  24. data/lib/aniview/interface/animeio/animeio.rb +0 -321
  25. data/lib/aniview/interface/animeio/animeseries.rb +0 -60
  26. data/lib/aniview/interface/bridge.rb +0 -11
  27. data/lib/aniview/interface/deluge/delugec.rb +0 -172
  28. data/lib/aniview/interface/deluge/torrentitem.rb +0 -24
  29. data/lib/aniview/interface/item.rb +0 -24
  30. data/lib/aniview/interface/mpv/mpvbridge.rb +0 -149
  31. data/lib/aniview/interface/pref/defaults.json +0 -105
  32. data/lib/aniview/interface/pref/pref.rb +0 -209
  33. data/lib/aniview/interface/pref/prefitem.rb +0 -19
  34. data/lib/aniview/interface/pref/validate.json +0 -105
  35. data/lib/aniview/interface/schedule/schedule.rb +0 -99
  36. data/lib/aniview/interface/schedule/scheduleitem.rb +0 -59
  37. data/lib/aniview/interface/subscription/subscription.rb +0 -123
  38. data/lib/aniview/util/error.rb +0 -9
  39. data/lib/aniview/util/folder_listen.rb +0 -53
  40. data/lib/aniview/util/term.rb +0 -44
  41. data/lib/aniview/util/util.rb +0 -167
  42. data/lib/aniview/view/aiomenu.rb +0 -69
  43. data/lib/aniview/view/color.rb +0 -69
  44. data/lib/aniview/view/delugemenu.rb +0 -38
  45. data/lib/aniview/view/menu.rb +0 -325
  46. data/lib/aniview/view/prefmenu.rb +0 -26
  47. data/lib/aniview/view/schedulemenu.rb +0 -28
  48. data/lib/aniview/view/statusline.rb +0 -60
  49. data/lib/aniview/view/subscriptionmenu.rb +0 -37
  50. data/lib/application.rb +0 -306
  51. data/lib/daemon.rb +0 -188
@@ -1,60 +0,0 @@
1
- require 'date'
2
-
3
- require_relative '../../util/util'
4
- require_relative '../item'
5
-
6
- module Aniview
7
- module Interface
8
- class AnimeSeries < Item
9
- include Aniview::Util
10
-
11
- def initialize(path, children = [])
12
- @path = path
13
-
14
- @attr = {
15
- "t" => String(@path),
16
- "c" => 0,
17
- "d" => 0,
18
- "s" => 0,
19
- "p" => 0,
20
- "w" => 0,
21
- "W" => 0
22
- }
23
-
24
- @children = children
25
- @children.each { |c| self + c }
26
- end
27
-
28
- def + af
29
- @attr["d"] += af.attr["d"]
30
- @attr["D"] = Util.format_duration(@attr["d"])
31
- @attr["s"] += af.attr["s"]
32
- @attr["S"] = Util.format_size(@attr["s"])
33
- @attr["c"] += 1
34
- @attr["w"] += 1 if af.seen?
35
- @attr["W"] += af.attr["d"] if af.seen?
36
- end
37
-
38
- def << af
39
- @children << af
40
- self + af
41
- average
42
- end
43
-
44
- def average
45
- @attr["p"] = @attr["w"] * 100.0 / @attr["c"]
46
- @attr["q"] = @attr["d"] > 0 ? @attr["W"] * 100.0 / @attr["d"] : 0
47
- @attr["Q"] = Util.format_progress @attr["q"]
48
- @attr["P"] = Util.format_progress @attr["p"]
49
- end
50
-
51
- def title
52
- return @path
53
- end
54
-
55
- def attributes
56
- return @attr
57
- end
58
- end
59
- end
60
- end
@@ -1,11 +0,0 @@
1
- class Bridge
2
-
3
- def make_hash
4
-
5
- end
6
-
7
- def items
8
-
9
- end
10
-
11
- end
@@ -1,172 +0,0 @@
1
- require 'deluge'
2
- require_relative 'torrentitem'
3
-
4
- module Aniview
5
- module Interface
6
-
7
- class DelugeC < Bridge
8
-
9
- def initialize pref
10
- @pref = pref
11
- host = @pref.get("deluge_config")["host"]
12
- login = @pref.get("deluge_config")["login"]
13
- password = @pref.get("deluge_config")["password"]
14
-
15
- if (login == "" and password == "") and (host == "127.0.0.1" or host == "localhost")
16
- la = localAuth
17
- login = la[0]
18
- password = la[1]
19
- @pref.set(["deluge_config", "login"], login)
20
- @pref.set(["deluge_config", "password"], password)
21
- end
22
-
23
- @client = Deluge::Rpc::Client.new(
24
- host: host,
25
- port: Integer(@pref.get("deluge_config")["port"]),
26
- login: @pref.get("deluge_config")["login"],
27
- password: @pref.get("deluge_config")["password"]
28
- )
29
-
30
- @status = "not connected"
31
- @connected = false
32
- connect
33
-
34
- end
35
-
36
- def getStatus
37
- @status
38
- end
39
-
40
- def connect
41
- @connected = false
42
- @status = "error connecting"
43
- begin
44
- @client.connect
45
- rescue Deluge::Rpc::Connection::RPCError
46
- @client.close
47
- rescue RuntimeError
48
- @client.close
49
- rescue Errno::ECONNREFUSED
50
- @client.close
51
- else
52
- @status = "connected"
53
- @connected = true
54
- end
55
-
56
- @client.close unless @connected
57
- end
58
-
59
- def localAuth
60
- authfile = Dir.home + "/.config/deluge/auth"
61
- return ["", ""] if not File.exist? authfile
62
- File.open(Dir.home + "/.config/deluge/auth") { |f| f.read }.split(":")
63
- end
64
-
65
- def items
66
- connect unless @connected
67
- return {} unless @connected
68
-
69
- tkeys = [
70
- "name",
71
- "progress",
72
- "eta",
73
- "paused",
74
- "state",
75
- "hash",
76
- #"active_time",
77
- #"is_finished",
78
- #"max_connections",
79
- #"max_download_speed",
80
- #"max_upload_slots",
81
- #"max_upload_speed",
82
- #"message",
83
- #"next_announce",
84
- #"num_peers",
85
- #"num_seeds",
86
- #"remove_at_ratio",
87
- #"save_path",
88
- #"seeding_time",
89
- #"seeds_peers_ratio",
90
- #"seed_rank",
91
- #"stop_at_ratio",
92
- #"stop_ratio",
93
- #"time_added",
94
- #"upload_payload_rate",
95
- #"comment",
96
- #"file_priorities",
97
- #"file_progress",
98
- #"files",
99
- #"is_seed",
100
- #"num_files",
101
- #"num_pieces",
102
- #"peers",
103
- #"piece_length",
104
- #"private",
105
- #"queue",
106
- #"ratio",
107
- #"total_size",
108
- #"tracker_host"
109
- ]
110
-
111
- makeHash @client.core.get_torrents_status({}, tkeys)
112
- end
113
-
114
- def toggleTorrent torrentItem
115
- id = torrentItem.attributes["h"]
116
- if torrentItem.attributes["u"]
117
- @client.core.resume_torrent([id])
118
- else
119
- @client.core.pause_torrent([id])
120
- end
121
- end
122
-
123
- def removeTorrent torrentItem, withData
124
- id = torrentItem.attributes["h"]
125
- @client.core.remove_torrent(id, withData)
126
- end
127
-
128
- def addTorrent mag, loc, verbose: false
129
- connect unless @connected
130
- return false unless @connected
131
- puts "[delugec] connected!" if verbose
132
- begin
133
- tid = @client.core.add_torrent_magnet(mag, {"download_location": loc})
134
- rescue Deluge::Rpc::Connection::InvokeTimeoutError
135
- #puts "[delugec] Error: timeout error" if verbose
136
- tid = nil
137
- rescue Errno::EPIPE
138
- #puts "[delugec] Error: Errno::EPIPE" if verbose
139
- tid = nil
140
- end
141
- return true if tid.class == String and tid.length > 1
142
- addTorrentCli mag, loc
143
- return false
144
- end
145
-
146
- def addTorrentCli mag, loc
147
- cli_tool = @pref.get("deluge_config")["cli_executable"]
148
- command = "add #{mag} -p #{Shellwords.escape loc}"
149
- result = %x(#{cli_tool} '#{command}')
150
- end
151
-
152
- def makeHash(arr)
153
- ret = {}
154
- arr.each{ |t|
155
- tinfo = t[1]
156
- torrent = TorrentItem.new(
157
- name: tinfo["name"],
158
- progress: tinfo["progress"],
159
- eta: tinfo["eta"],
160
- paused: tinfo["paused"],
161
- state: tinfo["state"],
162
- id: tinfo["hash"]
163
- )
164
- ret.merge!(torrent => torrent)
165
- }
166
- ret
167
- end
168
-
169
- end
170
- end
171
- end
172
-
@@ -1,24 +0,0 @@
1
- require_relative '../../util/util'
2
- require_relative '../item'
3
-
4
- module Aniview
5
- module Interface
6
- class TorrentItem < Item
7
- include Aniview::Util
8
- def initialize(name:, progress:, eta:, paused:, state:, id:)
9
- @attr = {
10
- "n" => name,
11
- "p" => Util.format_progress(progress),
12
- "e" => Util.format_duration(eta),
13
- "u" => paused,
14
- "s" => state,
15
- "h" => id
16
- }
17
- end
18
-
19
- def attributes
20
- return @attr
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- module Aniview
2
- module Interface
3
- class Item
4
-
5
- attr_accessor :attr
6
-
7
- def initialize()
8
- @attr = {}
9
- end
10
-
11
- def attributes
12
- return @attr
13
- end
14
-
15
- def cereal
16
- contents = ""
17
- @attr.each{ |a|
18
- contents += String(a[1])
19
- }
20
- return "cereal-"+contents
21
- end
22
- end
23
- end
24
- end
@@ -1,149 +0,0 @@
1
- require 'mpv'
2
- require_relative '../../util/util'
3
- require 'logger'
4
-
5
- module Aniview
6
- module Interface
7
- class MPVBridge
8
-
9
- include Aniview::Util
10
-
11
- include Observable
12
-
13
- attr_accessor :playing
14
- attr_accessor :playing_file
15
- attr_accessor :what_changed
16
-
17
- def initialize pref
18
- @pref = pref
19
- @mpv_enabled = true
20
- @logger = Logger.new(@pref.parseDir('$conf_dir/mpv.log'))
21
- @logger.level = Logger::DEBUG
22
- connect
23
- @what_changed = ""
24
- @playing = false
25
- end
26
-
27
- def event_handler event
28
- case event["event"]
29
- #file-loaded
30
- when "start-file"
31
- @logger.debug "start file"
32
- @playing = true
33
- @what_changed = {:playing_status => :start}
34
- changed
35
- notify_observers
36
- when "end-file"
37
- @logger.debug "end file"
38
- @playing = false
39
- @what_changed = {:playing_status => :end}
40
- changed
41
- notify_observers
42
- when "property-change"
43
- case event["name"]
44
- when "path"
45
- @playing_file = @playing_files[event["data"]]
46
- end
47
- else
48
- end
49
- end
50
-
51
- def quit!
52
- @mpv.quit! unless @mpv == nil
53
- end
54
-
55
- def connect
56
- return unless @mpv_enabled
57
- return unless @mpv == nil or @mpv.client.get_property("idle-active") == nil
58
- @mpv = nil
59
- @mpv_enabled = false
60
- begin
61
- @mpv = MPV::Session.new(user_args: @pref.get("mpv_args").split(" "))
62
- @mpv.callbacks << method(:event_handler)
63
- @mpv.client.command("observe_property_string", 1, "path")
64
- #@mpv.client.command("observe_property_string", 1, "playback-abort")
65
- rescue MPV::MPVNotAvailableError
66
- rescue MPV::MPVUnsupportedFlagError
67
- else
68
- @mpv_enabled = true
69
- end
70
- end
71
-
72
- def play file
73
- @logger.debug "playing file"
74
- return unless @mpv_enabled
75
- connect
76
- @playing_files = {file.path => file}
77
- @mpv.client.command "loadfile", file.path
78
- @playing = true
79
- end
80
-
81
- def playlist playlist, files
82
- return unless @mpv_enabled
83
- connect
84
- @playing_files = files
85
- #@playing_file = @playing_files[0]
86
- @mpv.client.command "loadlist", playlist
87
- @playing = true
88
- end
89
-
90
- def playing?
91
- @playing
92
- end
93
-
94
- def checkSetWatched percentage
95
- if @playing_file != nil
96
- swp = Integer(@pref.get "set_watched_percentage")
97
- pct = Float(percentage)
98
- if pct >= swp and not @playing_file.seen?
99
- @playing_file.watch
100
- @what_changed = {:local_anime => :watched}
101
- changed
102
- notify_observers
103
- end
104
- end
105
- end
106
-
107
- def attributes
108
- if playing?
109
- r = {}
110
- props = [
111
- "time-pos",
112
- "percent-pos",
113
- "duration"
114
- ]
115
- props.each { |prop|
116
- prop_val = @mpv.client.get_property(prop)
117
- prop_val = 0 if prop_val == nil
118
- r.merge!(
119
- prop[0] => prop_val
120
- )
121
- }
122
-
123
- if @playing_file != nil
124
- r.merge!("n" => @playing_file.attributes["t"])
125
- else
126
- r.merge!("n" => "loading")
127
- end
128
-
129
- checkSetWatched r["p"]
130
-
131
- {
132
- "t" => Util.format_duration(r["t"]),
133
- "p" => Util.format_progress(r["p"]),
134
- "d" => Util.format_duration(r["d"]),
135
- "n" => r["n"],
136
- }
137
- else
138
- {
139
- "t" => "-",
140
- "p" => "0",
141
- "d" => "0:00",
142
- "n" => ".",
143
- }
144
- end
145
- end
146
-
147
- end
148
- end
149
- end
@@ -1,105 +0,0 @@
1
- {
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" : "$airing_dir",
25
- "airing_dir" : "",
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@ ##%w/##%c #####%Q ########%D #######%S ",
45
- "parent" : " %t@ ##%w/##%c #####%Q ########%D #######%S ",
46
- "child" : " %w %t@ ########%D #######%S "
47
- },
48
- "format_library_unwatched" :
49
- {
50
- "title" : " %t@ ##%w/##%c ########%D #######%S ",
51
- "parent" : " %t@ ##%w/##%c ########%D #######%S ",
52
- "child" : " %t@ %D %S %r "
53
- },
54
- "format_torrents" :
55
- {
56
- "title" : " %t - %s",
57
- "parent" : " %n - %s@ %e %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
- "format_status" : " %n - %t/%d@ %p\\% ",
75
- "deluge_config" :
76
- {
77
- "host" : "localhost",
78
- "port" : "58846",
79
- "login" : "",
80
- "password" : "",
81
- "cli_executable" : "/Applications/Deluge.app/Contents/MacOS/deluge-console"
82
- },
83
- "rss_feed" :
84
- {
85
- "url" : "https://www.tokyotosho.info/rss.php?filter=1&minMB=100&maxMB=500&reversepolarity=1&entries=300",
86
- "refresh_interval" : "300"
87
- },
88
- "daemon" :
89
- {
90
- "port" : "21312"
91
- },
92
- "avs_files":
93
- {
94
- "create?": true,
95
- "only_on_mounted_fs?": false
96
- },
97
- "set_watched_percentage" : "80",
98
- "log_file" : "$conf_dir/aw.log",
99
- "daemon_log_file" : "$conf_dir/server.log",
100
- "watch_log" : "$conf_dir/watchlog",
101
- "conf_dir" : "~/.config/aniview",
102
- "mpv_args" : "--alang=jpn --slang=eng",
103
- "local_anime" : null,
104
- "schedule" : []
105
- }