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,28 +0,0 @@
1
- require_relative 'menu'
2
- require_relative '../util/util'
3
-
4
- module Aniview
5
- module View
6
- class ScheduleMenu < Menu
7
- include Aniview::Util
8
-
9
- def customControl(key, sel)
10
-
11
- item = @items.values[sel["out"]].attributes["t"]
12
-
13
- if key == @pref.get("keybindings")["schedule_add_item"]
14
- newval = Util.readline(@term, "new item:")
15
- @interface.addItem newval
16
-
17
- elsif key == @pref.get("keybindings")["schedule_delete_item"]
18
- @interface.removeItem sel["out"]
19
-
20
- elsif key == @pref.get("keybindings")["schedule_edit_item"]
21
- newval = Util.readline(@term, "edit item:", item)
22
- @interface.editItem sel["out"], newval
23
-
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,60 +0,0 @@
1
- require_relative '../util/util'
2
- require_relative 'color'
3
-
4
- module Aniview
5
- module View
6
- class StatusLine
7
-
8
- include Aniview::Util
9
- include Observable
10
-
11
- def initialize pref, term, mpvbridge
12
- @term = term
13
- @pref = pref
14
- @mpvbridge = mpvbridge
15
-
16
- @mpvbridge.add_observer(self, :draw)
17
-
18
- @clr = Aniview::View::Color.public_send(@pref.get("clr")["main"])
19
- reset_message
20
- end
21
-
22
- def message msg, display_for: 1, color: "red"
23
- @message = {
24
- "text" => msg,
25
- "linger" => display_for,
26
- "color" => color
27
- }
28
- changed
29
- notify_observers
30
- end
31
-
32
- def reset_message
33
- @message = {
34
- "text" => nil,
35
- "linger" => 0,
36
- "color" => "red"
37
- }
38
- changed
39
- notify_observers
40
- end
41
-
42
- def print_row line
43
- print "\e[#{@term.rows - 1};1H" + @clr + line + "\e[K\nq\e[2K"
44
- end
45
-
46
- def draw
47
- if @message["text"] == nil
48
- line = Util.parse_format @pref.get("format_status"), @mpvbridge.attributes, @term.cols
49
- print_row line
50
- else
51
- line = Color.public_send(@message["color"]) + @message["text"]
52
- print_row line
53
- sleep Integer(@message["linger"])
54
- reset_message
55
- end
56
- end
57
-
58
- end
59
- end
60
- end
@@ -1,37 +0,0 @@
1
- require_relative 'menu'
2
- require_relative '../util/util'
3
-
4
- module Aniview
5
- module View
6
- class SubscriptionMenu < Menu
7
-
8
- include Aniview::Util
9
-
10
- #if Time.now.to_i < @last_checked + 10
11
- # @last_checked = Time.now.to_i
12
- #end
13
-
14
- def refresh_attributes
15
- @attributes["l"] = @interface.getLastChecked
16
- @attributes["d"] = @interface.checkDaemon
17
- @attributes["n"] = @interface.getNextCheck
18
- @interface.syncMatches
19
- end
20
-
21
- def customControl(key, sel)
22
-
23
- item = @items.values[sel["out"]].attributes["r"]
24
-
25
- if key == @pref.get("keybindings")["subscriptions_edit"]
26
- newval = Util.readline(@term, "regexp:", item)
27
- @interface.editItem(sel["out"], newval)
28
-
29
- elsif key == "m"
30
- @interface.forceMatch
31
-
32
- end
33
- end
34
-
35
- end
36
- end
37
- end
@@ -1,306 +0,0 @@
1
- require 'highline'
2
- require 'highline/import'
3
- require 'thread'
4
- require 'io/console'
5
- require 'warning'
6
- require 'observer'
7
- require 'benchmark'
8
-
9
- require 'logger'
10
-
11
- Warning.ignore([:fixnum, :bignum])
12
-
13
- require_relative 'aniview/view/aiomenu'
14
- require_relative 'aniview/view/delugemenu'
15
- require_relative 'aniview/view/prefmenu'
16
- require_relative 'aniview/view/schedulemenu'
17
- require_relative 'aniview/view/subscriptionmenu'
18
- require_relative 'aniview/view/statusline'
19
-
20
- require_relative 'aniview/interface/animeio/animeio'
21
- require_relative 'aniview/interface/mpv/mpvbridge'
22
- require_relative 'aniview/interface/deluge/delugec'
23
- require_relative 'aniview/interface/pref/pref'
24
- require_relative 'aniview/interface/subscription/subscription'
25
- require_relative 'aniview/interface/schedule/schedule'
26
-
27
- require_relative 'aniview/util/util'
28
- require_relative 'aniview/util/term'
29
-
30
- require_relative 'aniview/client/aniclient'
31
-
32
- $stdout.sync = true
33
- module Aniview
34
- # Main class for the aniview application
35
- class Application
36
-
37
- include Util
38
-
39
- # initializes a new Aniview application
40
- #
41
- # @return nil
42
- #
43
- def initialize
44
-
45
- @term = Util::Term.new
46
-
47
- @pref = Interface::Pref.new
48
-
49
- @logger = Logger.new(@pref.parseDir(@pref.get("log_file")))
50
- @logger.level = Logger::DEBUG
51
- @pref.logger = @logger
52
-
53
- @mpvbridge = Interface::MPVBridge.new @pref
54
-
55
- @aio = Interface::AnimeIO.new @pref, @mpvbridge
56
-
57
- @schedule = Interface::Schedule.new @pref
58
-
59
- @delugec = Interface::DelugeC.new @pref
60
-
61
- @c = Client::AniClient.new @pref
62
-
63
- @statusline = View::StatusLine.new @pref, @term, @mpvbridge
64
-
65
- @subscription = Interface::Subscription.new @pref, @schedule, @delugec, @c
66
-
67
- if not @c.server?
68
- process = fork do
69
- require_relative 'daemon'
70
- avd = Daemon.new([])
71
- avd.run
72
- end
73
- Process.detach(process)
74
- end
75
-
76
- @aiomenu = View::AioMenu.new(
77
- interface: @aio,
78
- name: @pref.get("menu_titles")["library"],
79
- pref: @pref,
80
- format: "format_library",
81
- term: @term,
82
- logger: @logger
83
- )
84
- @prefmenu = View::PrefMenu.new(
85
- interface: @pref,
86
- name: @pref.get("menu_titles")["preferences"],
87
- pref: @pref,
88
- format: "format_preferences",
89
- term: @term,
90
- children: false,
91
- logger: @logger
92
- )
93
- @delugemenu = View::DelugeMenu.new(
94
- interface: @delugec,
95
- name: @pref.get("menu_titles")["torrents"],
96
- pref: @pref,
97
- format: "format_torrents",
98
- term: @term,
99
- children: false,
100
- logger: @logger
101
- )
102
- @schedulemenu = View::ScheduleMenu.new(
103
- interface: @schedule,
104
- name: @pref.get("menu_titles")["schedule"],
105
- pref: @pref,
106
- format: "format_schedule",
107
- term: @term,
108
- children: false,
109
- logger: @logger
110
- )
111
- @subscriptionmenu = View::SubscriptionMenu.new(
112
- interface: @subscription,
113
- name: @pref.get("menu_titles")["subscriptions"],
114
- pref: @pref,
115
- format: "format_subscriptions",
116
- term: @term,
117
- children: false,
118
- logger: @logger
119
- )
120
- @term.save.hide_cursor.echo_off
121
-
122
- end
123
-
124
- # Cleans up Aniview, restoring terminal settings and safely exiting all
125
- # loops
126
- #
127
- # @return nil
128
- #
129
- def cleanup
130
- @view.pause
131
- @statusthread.exit if @statusthread
132
- @mthread.exit if @mthread != nil
133
- @statusthread.exit if @statusthread != nil
134
- @term.reset
135
- @mpvbridge.quit!
136
- @aio.cleanup
137
- exit
138
- end
139
-
140
- # Executes an Aniview command
141
- #
142
- # @param cmds The command to execute
143
- #
144
- # @return nil
145
- #
146
- def runCommand(cmds)
147
- cmd_s = cmds.split
148
- cmd = cmd_s[0]
149
- if cmd == "quit"
150
- self.cleanup
151
- elsif cmd == "sync"
152
- #alist = Anilist.new
153
- #alist.sync
154
- elsif cmd == "pref"
155
- @pref.set cmd_s[1], cmd_s[2]
156
- elsif cmd == "index"
157
- @aio.index_anime :force => true, :verbose => true
158
- @aiomenu.refresh
159
- elsif cmd == "help"
160
- print "\e[1;1H" + Aniview::View::Color.white
161
- puts "Help"
162
- puts ""
163
- else
164
- @statusline.message "unknown command"
165
- end
166
- end
167
-
168
- # Changes the current view in the app
169
- #
170
- # @param newView the view to change to, must inherit Aniview::View::Menu
171
- #
172
- # @return nil
173
- #
174
- def change_view(view:, rfunc: :items, format:nil, name:nil)
175
- @view.delete_observers
176
- @view.pause
177
- view.attributes["t"] = name if name
178
- view.format = format if format
179
- view.rfunc = rfunc
180
- view.add_observer(self, :drawview)
181
- view.change_screen_size redraw: false
182
- view.expand -1
183
- view.unpause
184
- @view = view
185
- end
186
-
187
- def drawview
188
- @view.draw
189
- #@statusline.draw
190
- @rcount ||= 0
191
- #puts "refreshed view #{@rcount+=1}"
192
- end
193
-
194
- def togglestatusline
195
- @logger.debug "toggling status line"
196
- return unless @mpvbridge.what_changed.key? :playing_status
197
- unless @statusthread
198
- @statusthread = Thread.new do
199
- while true
200
- @statusline.draw
201
- sleep 0.07
202
- end
203
- end
204
- else
205
- @statusthread.exit
206
- @statusthread = nil
207
- end
208
- end
209
-
210
- def drawmessage
211
- unless @statusthread
212
- @view.draw
213
- Thread.new do
214
- @statusline.draw
215
- @statusline.draw
216
- end
217
- end
218
- end
219
-
220
- # Runs the aniview application, this method starts all of the threads
221
- #
222
- # @return nil
223
- #
224
- def run
225
- @logger.debug "yo"
226
- nm = @pref.get("menu_titles")
227
- views = {
228
- :unwatched => {view: @aiomenu, name: nm["unwatched"], format: "format_library_unwatched", rfunc: :unwatched},
229
- :library => {view: @aiomenu, name: nm["library"], format: "format_library"},
230
- :torrents => {view: @delugemenu},
231
- :preferences => {view: @prefmenu},
232
- :schedule => {view: @schedulemenu},
233
- :subscription => {view: @subscriptionmenu}
234
- }
235
-
236
- current_view = 0
237
- @view = @aiomenu
238
-
239
- @view.add_observer(self, :drawview)
240
- @mpvbridge.add_observer(self, :togglestatusline)
241
- @statusline.add_observer(self, :drawmessage)
242
- @statusline.draw
243
-
244
- mutex = Mutex.new
245
- Signal.trap('SIGWINCH', proc {
246
- Thread.new { mutex.synchronize {
247
- @view.change_screen_size
248
- @statusline.draw
249
- } }
250
- } )
251
-
252
- key = ""
253
- @view.refresh
254
-
255
- while true
256
- @shoulddraw = true
257
- key = @term.getKey
258
- @shoulddraw = false
259
-
260
- kb = @pref.get("keybindings")
261
-
262
- case key
263
- when kb["goto_unwatched"]
264
- change_view(views[:unwatched])
265
- current_view = 0
266
- when kb["goto_library"]
267
- change_view(views[:library])
268
- current_view = 1
269
- when kb["goto_torrents"]
270
- change_view(views[:torrents])
271
- current_view = 2
272
- when kb["goto_preferences"]
273
- change_view(views[:preferences ])
274
- current_view = 5
275
- when kb["goto_schedule"]
276
- change_view(views[:schedule])
277
- current_view = 3
278
- when kb["goto_subscriptions"]
279
- change_view(views[:subscription])
280
- current_view = 4
281
- when "right"
282
- current_view += 1
283
- current_view = views.length - 1 if current_view >= views.length
284
- change_view(views.values[current_view])
285
- when "left"
286
- current_view -= 1
287
- current_view = 0 if current_view < 0
288
- change_view(views.values[current_view])
289
- when ":"
290
- @view.pause
291
- if @statusthread
292
- togglestatusline
293
- toggled = true
294
- end
295
- runCommand Util.readline(@term, ":")
296
- togglestatusline if toggled
297
- @view.unpause
298
- when "q"
299
- cleanup
300
- end
301
- @view.control(key)
302
- end
303
-
304
- end
305
- end
306
- end
@@ -1,188 +0,0 @@
1
- require 'thread'
2
- require 'socket'
3
- require 'warning'
4
-
5
- Warning.ignore([:fixnum, :bignum])
6
-
7
- require_relative 'aniview/interface/deluge/delugec'
8
- require_relative 'aniview/interface/pref/pref'
9
- require_relative 'aniview/interface/schedule/schedule'
10
- require_relative 'aniview/interface/subscription/subscription'
11
- require_relative 'aniview/client/aniclient'
12
- require_relative 'aniview/util/util'
13
-
14
- module Aniview
15
- class Daemon
16
-
17
- def initialize(args)
18
-
19
- @pref = Interface::Pref.new
20
- @c = Client::AniClient.new @pref
21
-
22
- args << "start" if args.length < 1
23
- parseArgs args
24
-
25
- @schedule = Interface::Schedule.new @pref
26
- @delugec = Interface::DelugeC.new(@pref)
27
- @subscription = Interface::Subscription.new(@pref, @schedule, @delugec, @c)
28
-
29
- begin
30
- @s = TCPServer.new @pref.get("daemon")["port"]
31
- rescue Errno::EADDRINUSE
32
- puts "error, something is already listening on #{@pref.get("daemon")["port"]}, maybe the \nserver is already running?"
33
- quit
34
- end
35
- @looped = 0
36
- @matches = 0
37
- @lastchecked = "never"
38
- @nextcheck = 0
39
-
40
- $stdout.reopen(@pref.parseDir(@pref.get("daemon_log_file")), "w")
41
- $stderr.reopen(@pref.parseDir(@pref.get("daemon_log_file")), "w")
42
- $stdout.sync = true
43
- $stderr.sync = true
44
-
45
- end
46
-
47
- def parseArgs args
48
- args.each { |a|
49
- case a
50
- when "help"
51
- help
52
- quit
53
- when "start"
54
- if @c.server?
55
- puts "already running"
56
- quit
57
- end
58
- when "stop"
59
- if @c.server?
60
- puts "quitting"
61
- @c.stopDaemon
62
- quit
63
- else
64
- puts "server isn't running"
65
- quit
66
- end
67
- when "restart"
68
- if @c.server?
69
- @c.stopDaemon
70
- else
71
- puts "server not running, just starting it"
72
- end
73
- when "info"
74
- if @c.server?
75
- puts @c.info
76
- quit
77
- else
78
- puts "server isn't running"
79
- quit
80
- end
81
- when "up?"
82
- puts @c.server?
83
- quit
84
- when "nani"
85
- puts @c.sendMsg("what?")
86
- quit
87
- when "items"
88
- p @c.getItems
89
- quit
90
- when "log"
91
- puts @pref.parseDir(@pref.get("daemon_log_file"))
92
- quit
93
- else
94
- puts "unknown command, dude!"
95
- quit
96
- end
97
- }
98
- end
99
-
100
- def help
101
- cmds = ["help", "start", "stop", "info", "up?", "nani"]
102
- puts "commands:"
103
- puts cmds.sort
104
- end
105
-
106
- def checkFeeds
107
- Thread.abort_on_exception = true
108
- Thread.new do
109
- while true
110
- @subscription.updateFeed
111
-
112
- if @subscription.feed == nil
113
- @lastchecked = "offline"
114
- else
115
- @lastchecked = Time.now.to_s
116
- @schedule.load
117
- @matches += @subscription.matchAll(verbose: true)
118
- end
119
- @looped += 1
120
- r_interval = Integer(@pref.get("rss_feed")["refresh_interval"])
121
- (0..r_interval).each { |i|
122
- @nextcheck = r_interval - i
123
- sleep 1
124
- }
125
- end
126
- end
127
- end
128
-
129
- def quit
130
- @checkThread.exit unless @checkThread == nil
131
- exit
132
- end
133
-
134
- def uptime
135
- Util.format_duration(Time.now - @started)
136
- end
137
-
138
- def run
139
- puts "--------"
140
- puts "server started"
141
- puts "server listening on port " + @pref.get("daemon")["port"]
142
-
143
- trap(:QUIT) do
144
- quit
145
- end
146
-
147
- @checkThread = checkFeeds
148
- @started = Time.now
149
- loop do
150
- lastloop = false
151
- client = @s.accept
152
-
153
- message = client.gets.chomp.split(" ")
154
- #puts "got msg #{message} from client"
155
- response = "okay."
156
-
157
- message.each_with_index { |m, i|
158
- case m
159
- when "up?"
160
- response = "true"
161
- when "quit"
162
- lastloop = true
163
- response = "quitting"
164
- when "info"
165
- response = "uptime: #{uptime}, loops: #{@looped}, matches, #{@matches}"
166
- when "lastchecked"
167
- response = @lastchecked
168
- when "items"
169
- response = Util.encode_object(@schedule.schedule)
170
- when "itemshash"
171
- response = @schedule.getAllCereal
172
- when "nextcheck"
173
- response = "#{@nextcheck}"
174
- else
175
- response = "what?"
176
- end
177
- }
178
-
179
- response += "\n"
180
-
181
- #puts "responding with #{response}"
182
- client.puts response
183
- client.close
184
- quit if lastloop
185
- end
186
- end
187
- end
188
- end