ektoplayer 0.1.19 → 0.1.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ektoplayer/application.rb +26 -24
- data/lib/ektoplayer/browsepage.rb +0 -4
- data/lib/ektoplayer/compat.rb +2 -2
- data/lib/ektoplayer/config.rb +13 -13
- data/lib/ektoplayer/icurses/test.rb +1 -1
- data/lib/ektoplayer/theme.rb +0 -6
- data/lib/ektoplayer/ui/widgets/listwidget.rb +143 -98
- data/lib/ektoplayer/updater.rb +25 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25039a3262bb6332eef51524e8f210e95f9d5bca
|
4
|
+
data.tar.gz: bf810de03fbbeb0b6b78aec743fe22c1b02a79c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ee4ff0aae66122c362b6b9ec918e098296b2814a33ef35dd4c6201b53863b37bac6ddf0c49dfd8f397a2f3b92866590730b8248587312fb957348082b8be20e
|
7
|
+
data.tar.gz: 58e915a5993a2f93e359d30fbfc6ce300b8dd9dd1c7b198b8bc45f46e00f5e42f5a5fe59b73a4c1870382f4d85f51093ce22d88cdfc49871ce3948eaa90fd0fd
|
@@ -10,7 +10,7 @@ require 'date'
|
|
10
10
|
|
11
11
|
module Ektoplayer
|
12
12
|
class Application
|
13
|
-
VERSION = '0.1.
|
13
|
+
VERSION = '0.1.20'.freeze
|
14
14
|
GITHUB_URL = 'https://github.com/braph/ektoplayer'.freeze
|
15
15
|
EKTOPLAZM_URL = 'http://www.ektoplazm.com'.freeze
|
16
16
|
|
@@ -61,6 +61,7 @@ module Ektoplayer
|
|
61
61
|
|
62
62
|
def run
|
63
63
|
puts "\033]0;ektoplayer\007"
|
64
|
+
Process.setproctitle('ektoplayer')
|
64
65
|
Thread.report_on_exception=(true) if Thread.respond_to? :report_on_exception
|
65
66
|
|
66
67
|
# make each configuration object globally accessible as a singleton
|
@@ -151,6 +152,30 @@ module Ektoplayer
|
|
151
152
|
operations.send(:'playlist.play_next') if reason == :track_completed
|
152
153
|
end
|
153
154
|
|
155
|
+
# ... bindings ...
|
156
|
+
Bindings.bind_view(:global, main_w, view_ops, operations)
|
157
|
+
%w(splash playlist browser info help).each do |w|
|
158
|
+
Bindings.bind_view(w, main_w.send(w), view_ops, operations)
|
159
|
+
end
|
160
|
+
|
161
|
+
player.stop
|
162
|
+
|
163
|
+
# Preload playlist
|
164
|
+
if (n = Config[:playlist_load_newest]) > 0
|
165
|
+
r = client.database.select(
|
166
|
+
order_by: 'date DESC,album,number',
|
167
|
+
limit: n
|
168
|
+
)
|
169
|
+
playlist.add(*r)
|
170
|
+
end
|
171
|
+
|
172
|
+
# If database is empty, start an initial update
|
173
|
+
if browser.tracks(0).size < 1
|
174
|
+
operations.send(:update)
|
175
|
+
elsif (c = Config[:small_update_pages]) > 0
|
176
|
+
operations.send(:update, pages: c)
|
177
|
+
end
|
178
|
+
|
154
179
|
if Config[:prefetch]
|
155
180
|
Thread.new do
|
156
181
|
current_download_track = nil
|
@@ -170,29 +195,6 @@ module Ektoplayer
|
|
170
195
|
end
|
171
196
|
end
|
172
197
|
|
173
|
-
# ... bindings ...
|
174
|
-
Bindings.bind_view(:global, main_w, view_ops, operations)
|
175
|
-
%w(splash playlist browser info help).each do |w|
|
176
|
-
Bindings.bind_view(w, main_w.send(w), view_ops, operations)
|
177
|
-
end
|
178
|
-
|
179
|
-
player.stop
|
180
|
-
|
181
|
-
# If database is empty, start an initial update
|
182
|
-
if browser.tracks(0).size < 1
|
183
|
-
operations.send(:update)
|
184
|
-
elsif (c = Config[:small_update_pages]) > 0
|
185
|
-
operations.send(:update, pages: c)
|
186
|
-
end
|
187
|
-
|
188
|
-
if (n = Config[:playlist_load_newest]) > 0
|
189
|
-
r = client.database.select(
|
190
|
-
order_by: 'date DESC,album,number',
|
191
|
-
limit: n
|
192
|
-
)
|
193
|
-
playlist.add(*r)
|
194
|
-
end
|
195
|
-
|
196
198
|
rescue
|
197
199
|
Application.log(self, $!)
|
198
200
|
end
|
data/lib/ektoplayer/compat.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
unless Array.
|
1
|
+
unless Array.public_method_defined? :sum
|
2
2
|
class Array
|
3
3
|
def sum
|
4
4
|
reduce(:+)
|
@@ -6,7 +6,7 @@ unless Array.respond_to? :sum
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
unless Integer.
|
9
|
+
unless Integer.public_method_defined? :clamp
|
10
10
|
class Integer
|
11
11
|
def clamp(min, max)
|
12
12
|
return min if self < min
|
data/lib/ektoplayer/config.rb
CHANGED
@@ -52,12 +52,12 @@ module Ektoplayer
|
|
52
52
|
CONFIG_DIR = File.join(Dir.home, '.config', 'ektoplayer').freeze
|
53
53
|
CONFIG_FILE = File.join(CONFIG_DIR, 'ektoplayer.rc').freeze
|
54
54
|
|
55
|
-
DEFAULT_PLAYLIST_FORMAT = %{
|
56
|
-
<number size="3" fg="magenta"
|
57
|
-
<artist rel="25" fg="blue"
|
58
|
-
<album rel="30" fg="red"
|
59
|
-
<title rel="33" fg="yellow"
|
60
|
-
<styles rel="20" fg="cyan"
|
55
|
+
DEFAULT_PLAYLIST_FORMAT = %{\
|
56
|
+
<number size="3" fg="magenta" />\
|
57
|
+
<artist rel="25" fg="blue" />\
|
58
|
+
<album rel="30" fg="red" />\
|
59
|
+
<title rel="33" fg="yellow" />\
|
60
|
+
<styles rel="20" fg="cyan" />\
|
61
61
|
<bpm size="3" fg="green" justify="right" />}.squeeze(' ').freeze
|
62
62
|
|
63
63
|
DEFAULT_PLAYINGINFO_FORMAT_TOP =
|
@@ -66,12 +66,12 @@ module Ektoplayer
|
|
66
66
|
DEFAULT_PLAYINGINFO_FORMAT_BOTTOM =
|
67
67
|
'<artist bold="on" fg="blue" /><text> - </text><album bold="on" fg="red" /><text> (</text><year fg="cyan" /><text>)</text>'.freeze
|
68
68
|
|
69
|
-
DEFAULT_PLAYLIST_FORMAT_256 = %{
|
70
|
-
<number size="3" fg="97"
|
71
|
-
<artist rel="25" fg="24"
|
72
|
-
<album rel="30" fg="160"
|
73
|
-
<title rel="33" fg="178"
|
74
|
-
<styles rel="20" fg="37"
|
69
|
+
DEFAULT_PLAYLIST_FORMAT_256 = %{\
|
70
|
+
<number size="3" fg="97" />\
|
71
|
+
<artist rel="25" fg="24" />\
|
72
|
+
<album rel="30" fg="160" />\
|
73
|
+
<title rel="33" fg="178" />\
|
74
|
+
<styles rel="20" fg="37" />\
|
75
75
|
<bpm size="3" fg="28" justify="right" />}.squeeze(' ').freeze
|
76
76
|
|
77
77
|
DEFAULT_PLAYINGINFO_FORMAT_TOP_256 =
|
@@ -156,7 +156,7 @@ module Ektoplayer
|
|
156
156
|
}
|
157
157
|
|
158
158
|
reg :threads,
|
159
|
-
'Number of
|
159
|
+
'Number of download threads during database update',
|
160
160
|
20, lambda { |v| fail if Integer(v) < 1; Integer(v) }
|
161
161
|
|
162
162
|
# - Playlist
|
data/lib/ektoplayer/theme.rb
CHANGED
@@ -101,12 +101,6 @@ module Ektoplayer
|
|
101
101
|
defs ||= @theme[8][name] if @current >= 8
|
102
102
|
defs ||= @theme[0][name]
|
103
103
|
|
104
|
-
#unless defs
|
105
|
-
# defs ||= @theme[256][:default] if @current == 256
|
106
|
-
# defs ||= @theme[8][:default] if @current >= 8
|
107
|
-
# defs ||= @theme[0][:default]
|
108
|
-
#end
|
109
|
-
|
110
104
|
UI::Colors.set(name, *defs)
|
111
105
|
end
|
112
106
|
end
|
@@ -58,27 +58,39 @@ module UI
|
|
58
58
|
false
|
59
59
|
end
|
60
60
|
|
61
|
-
def next(*a) @direction == :up ? search_up(*a): search_down(*a)
|
61
|
+
def next(*a) @direction == :up ? search_up(*a) : search_down(*a) end
|
62
62
|
def prev(*a) @direction == :up ? search_down(*a) : search_up(*a) end
|
63
63
|
|
64
64
|
def search_up(current_pos, source)
|
65
65
|
start_pos = (current_pos - 1).clamp(0, source.size)
|
66
66
|
|
67
|
+
# search up from current pos to 0
|
67
68
|
start_pos.downto(0).each do |i|
|
68
69
|
return i if comp(source[i])
|
69
70
|
end
|
70
71
|
|
71
|
-
|
72
|
+
# restart search from bottom to start_pos
|
73
|
+
(source.size - 1).downto(start_pos).each do |i|
|
74
|
+
return i if comp(source[i])
|
75
|
+
end
|
76
|
+
|
77
|
+
nil # not found
|
72
78
|
end
|
73
79
|
|
74
80
|
def search_down(current_pos, source)
|
75
81
|
start_pos = (current_pos + 1).clamp(0, source.size)
|
76
82
|
|
83
|
+
# search down from current pos
|
77
84
|
start_pos.upto(source.size).each do |i|
|
78
85
|
return i if comp(source[i])
|
79
86
|
end
|
80
87
|
|
81
|
-
|
88
|
+
# restart search from top to start_pos
|
89
|
+
0.upto(start_pos).each do |i|
|
90
|
+
return i if comp(source[i])
|
91
|
+
end
|
92
|
+
|
93
|
+
nil # not found
|
82
94
|
end
|
83
95
|
end
|
84
96
|
|
@@ -95,10 +107,23 @@ module UI
|
|
95
107
|
@selection = ListSelector.new
|
96
108
|
end
|
97
109
|
|
98
|
-
def search_next
|
99
|
-
|
100
|
-
|
101
|
-
|
110
|
+
def search_next
|
111
|
+
if pos = @search.next(@selected, @list)
|
112
|
+
self.selected=(pos)
|
113
|
+
self.center
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def search_prev
|
118
|
+
if pos = @search.prev(@selected, @list)
|
119
|
+
self.selected=(pos)
|
120
|
+
self.center
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def search_up; self.search_start(:up) end
|
125
|
+
def search_down; self.search_start(:down) end
|
126
|
+
|
102
127
|
def search_start(direction)
|
103
128
|
UI::Input.readline(@pos, @size.update(height: 1), prompt: '> ', add_hist: true) do |result|
|
104
129
|
if result
|
@@ -132,14 +157,13 @@ module UI
|
|
132
157
|
|
133
158
|
def render(index, **opts)
|
134
159
|
return unless @item_renderer
|
135
|
-
return Ektoplayer::Application.log(self,
|
160
|
+
return Ektoplayer::Application.log(self, index, caller) unless @list[index]
|
136
161
|
|
137
|
-
opts[:selection] = (@selection.started? and
|
138
|
-
|
162
|
+
opts[:selection] = (@selection.started? and
|
163
|
+
index.between?(
|
139
164
|
[@selection.start_pos, @selected].min,
|
140
165
|
[@selection.start_pos, @selected].max
|
141
166
|
)
|
142
|
-
)
|
143
167
|
)
|
144
168
|
|
145
169
|
@item_renderer.render(@win, @list[index], index, **opts)
|
@@ -152,97 +176,135 @@ module UI
|
|
152
176
|
|
153
177
|
def top; self.selected=(0) end
|
154
178
|
def bottom; self.selected=(index_last) end
|
155
|
-
def page_up; self.
|
156
|
-
def page_down; self.
|
157
|
-
def up(n=1) self.
|
158
|
-
def down(n=1) self.
|
179
|
+
def page_up; self.scroll_list_up(@size.height) end
|
180
|
+
def page_down; self.scroll_list_down(@size.height) end
|
181
|
+
def up(n=1) self.scroll_cursor_up(1) end
|
182
|
+
def down(n=1) self.scroll_cursor_down(1) end
|
159
183
|
def center; self.force_cursorpos(@size.height / 2) end
|
160
184
|
|
161
185
|
def list=(list)
|
162
186
|
with_lock do
|
163
187
|
@list = list
|
164
|
-
|
165
188
|
@cursor = @selected = 0
|
166
189
|
self.selected=(0)
|
167
190
|
self.force_cursorpos(0)
|
168
|
-
|
169
191
|
want_redraw
|
170
192
|
end
|
171
193
|
end
|
172
194
|
|
173
|
-
def
|
174
|
-
fail ArgumentError unless
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
195
|
+
def scroll_cursor_down(n)
|
196
|
+
fail ArgumentError unless n
|
197
|
+
fail ArgumentError if n.negative?
|
198
|
+
n = n.clamp(0, items_after_cursor)
|
199
|
+
return if n == 0
|
200
|
+
new_cursor, new_selected = @cursor + n, @selected + n
|
179
201
|
|
180
202
|
self.lock
|
181
203
|
|
182
|
-
|
204
|
+
# it's faster to redraw the whole screen
|
205
|
+
if n >= @size.height
|
206
|
+
new_cursor = cursor_max
|
207
|
+
want_redraw
|
208
|
+
else
|
209
|
+
# new cursor resides in current screen
|
210
|
+
if new_cursor <= cursor_max
|
211
|
+
if @selection.started?
|
212
|
+
want_redraw
|
213
|
+
else
|
214
|
+
write_at(@cursor); render(@selected)
|
215
|
+
write_at(new_cursor); render(new_selected, selected: true)
|
216
|
+
want_refresh
|
217
|
+
end
|
218
|
+
else
|
219
|
+
new_cursor = cursor_max
|
183
220
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
221
|
+
if @selection.started?
|
222
|
+
want_redraw
|
223
|
+
else
|
224
|
+
write_at(@cursor); render(@selected)
|
188
225
|
|
189
|
-
|
190
|
-
|
226
|
+
(index_bottom + 1).upto(new_selected - 1).each do |index|
|
227
|
+
@win.append_bottom; render(index)
|
228
|
+
end
|
191
229
|
|
192
|
-
|
193
|
-
write_at(new_cursor); render(@selected, selected: true)
|
194
|
-
#_check
|
195
|
-
want_refresh
|
196
|
-
elsif (new_cursor.between?(-(@size.height - 1), (2 * @size.height - 1)))
|
197
|
-
# new selected item is max a half screen size away
|
198
|
-
if @selected < old_selected
|
199
|
-
if lines_after_cursor > (old_selected - @selected)
|
200
|
-
write_at(old_cursor); render(old_selected)
|
201
|
-
end
|
230
|
+
@win.append_bottom; render(new_selected, selected: true)
|
202
231
|
|
203
|
-
|
204
|
-
@win.insert_top; render(index)
|
232
|
+
want_refresh
|
205
233
|
end
|
234
|
+
end
|
235
|
+
end
|
206
236
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
if lines_before_cursor > (@selected - old_selected)
|
212
|
-
write_at(old_cursor); render(old_selected)
|
213
|
-
end
|
237
|
+
@cursor, @selected = new_cursor, new_selected
|
238
|
+
ensure
|
239
|
+
self.unlock
|
240
|
+
end
|
214
241
|
|
215
|
-
|
216
|
-
|
217
|
-
|
242
|
+
def scroll_cursor_up(n)
|
243
|
+
fail ArgumentError unless n
|
244
|
+
fail ArgumentError if n.negative?
|
245
|
+
n = n.clamp(0, items_before_cursor)
|
246
|
+
return if n == 0
|
247
|
+
new_cursor, new_selected = @cursor - n, @selected - n
|
218
248
|
|
219
|
-
|
220
|
-
@cursor = cursor_max
|
221
|
-
#_check
|
222
|
-
end
|
249
|
+
self.lock
|
223
250
|
|
224
|
-
|
225
|
-
|
226
|
-
#@selected = new_index
|
227
|
-
@cursor = new_index.clamp(0, cursor_max) # todo new_index<>new_cursor? ne muess scho pasn
|
228
|
-
#_check
|
251
|
+
if n >= @size.height
|
252
|
+
new_cursor = 0
|
229
253
|
want_redraw
|
254
|
+
else
|
255
|
+
# new cursor resides in current screen
|
256
|
+
if new_cursor >= 0
|
257
|
+
if @selection.started?
|
258
|
+
want_redraw
|
259
|
+
else
|
260
|
+
write_at(@cursor); render(@selected)
|
261
|
+
write_at(new_cursor); render(new_selected, selected: true)
|
262
|
+
want_refresh
|
263
|
+
end
|
264
|
+
else
|
265
|
+
new_cursor = 0
|
266
|
+
|
267
|
+
if @selection.started?
|
268
|
+
want_redraw
|
269
|
+
else
|
270
|
+
write_at(@cursor); render(@selected)
|
271
|
+
|
272
|
+
(index_top - 1).downto(new_selected + 1).each do |index|
|
273
|
+
@win.insert_top; render(index)
|
274
|
+
end
|
275
|
+
|
276
|
+
@win.insert_top; render(new_selected, selected: true)
|
277
|
+
|
278
|
+
want_refresh
|
279
|
+
end
|
280
|
+
end
|
230
281
|
end
|
231
282
|
|
283
|
+
@cursor, @selected = new_cursor, new_selected
|
232
284
|
ensure
|
233
285
|
self.unlock
|
234
286
|
end
|
235
287
|
|
288
|
+
def selected=(new_index)
|
289
|
+
fail ArgumentError unless new_index
|
290
|
+
fail ArgumentError.new('negative index') if new_index.negative?
|
291
|
+
new_index = new_index.clamp(0, index_last)
|
292
|
+
|
293
|
+
with_lock do
|
294
|
+
@selected = new_index
|
295
|
+
self.force_cursorpos(@cursor)
|
296
|
+
want_redraw
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
236
300
|
# select an item by its current cursor pos
|
237
301
|
def select_from_cursorpos(new_cursor)
|
238
302
|
fail unless new_cursor.between?(0, cursor_max)
|
239
|
-
# FIXME: clamp with @list.size ????
|
240
303
|
return if (new_cursor == @cursor) or @list.empty?
|
241
304
|
|
242
305
|
with_lock do
|
243
306
|
old_cursor, @cursor = @cursor, new_cursor
|
244
307
|
old_selected, @selected = @selected, (@selected - (old_cursor - @cursor)).clamp(0, index_last)
|
245
|
-
#_check
|
246
308
|
|
247
309
|
if @selection.started?
|
248
310
|
want_redraw
|
@@ -255,19 +317,20 @@ module UI
|
|
255
317
|
end
|
256
318
|
|
257
319
|
def force_cursorpos(new_cursor)
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
320
|
+
with_lock do
|
321
|
+
if @selected <= cursor_max / 2
|
322
|
+
@cursor = @selected
|
323
|
+
elsif (diff = (index_last - @selected)) < cursor_max / 2
|
324
|
+
@cursor = @size.height - diff - 1
|
325
|
+
else
|
326
|
+
@cursor = new_cursor.clamp(cursor_max / 2, cursor_max)
|
327
|
+
end
|
328
|
+
|
329
|
+
want_redraw
|
265
330
|
end
|
266
|
-
want_redraw
|
267
|
-
self.unlock
|
268
331
|
end
|
269
332
|
|
270
|
-
def
|
333
|
+
def scroll_list_up(n=1)
|
271
334
|
fail ArgumentError unless n
|
272
335
|
n = n.clamp(0, items_before_cursor)
|
273
336
|
return if n == 0 or @list.empty?
|
@@ -290,19 +353,17 @@ module UI
|
|
290
353
|
|
291
354
|
write_at(@cursor); render(@selected, selected: true)
|
292
355
|
|
293
|
-
#_check
|
294
356
|
want_refresh
|
295
357
|
else
|
296
|
-
@selected -= n
|
358
|
+
@selected -= n
|
297
359
|
force_cursorpos(@cursor)
|
298
|
-
#_check # todo: move up
|
299
360
|
want_redraw
|
300
361
|
end
|
301
362
|
|
302
363
|
self.unlock
|
303
364
|
end
|
304
365
|
|
305
|
-
def
|
366
|
+
def scroll_list_down(n=1)
|
306
367
|
fail ArgumentError unless n
|
307
368
|
n = n.clamp(0, items_after_cursor)
|
308
369
|
return if n == 0 or @list.empty?
|
@@ -310,7 +371,6 @@ module UI
|
|
310
371
|
|
311
372
|
if index_bottom == index_last
|
312
373
|
select_from_cursorpos((@cursor + n).clamp(0, cursor_max))
|
313
|
-
#_check
|
314
374
|
elsif n < @size.height
|
315
375
|
old_index_bottom = index_bottom
|
316
376
|
old_selected, @selected = @selected, @selected + n
|
@@ -325,27 +385,23 @@ module UI
|
|
325
385
|
|
326
386
|
write_at(@cursor); render(@selected, selected: true)
|
327
387
|
|
328
|
-
#_check
|
329
388
|
want_refresh
|
330
389
|
else
|
331
390
|
@selected += n
|
332
391
|
force_cursorpos(@cursor)
|
333
|
-
#_check
|
334
392
|
want_redraw
|
335
393
|
end
|
336
394
|
|
337
395
|
self.unlock
|
338
|
-
#_check
|
339
396
|
end
|
340
397
|
|
341
398
|
def draw
|
342
399
|
@win.erase
|
343
400
|
return if @list.empty?
|
344
|
-
|
345
|
-
#_check
|
401
|
+
#@selected = @selected.clamp(0, index_last)
|
346
402
|
|
347
403
|
@cursor.times do |i|
|
348
|
-
unless
|
404
|
+
unless @list[@selected - (@cursor - i)]
|
349
405
|
@cursor = i
|
350
406
|
break
|
351
407
|
end
|
@@ -353,15 +409,12 @@ module UI
|
|
353
409
|
write_at(i); render(@selected - (@cursor - i))
|
354
410
|
end
|
355
411
|
|
356
|
-
#_check
|
357
412
|
write_at(@cursor); render(@selected, selected: true)
|
358
413
|
|
359
414
|
(@cursor + 1).upto(@size.height - 1).each_with_index do |c, i|
|
360
|
-
break unless
|
415
|
+
break unless @list[@selected + i + 1]
|
361
416
|
write_at(c); render(@selected + i + 1)
|
362
417
|
end
|
363
|
-
|
364
|
-
#_check
|
365
418
|
end
|
366
419
|
|
367
420
|
def on_mouse_click(mevent, mevent_transformed)
|
@@ -387,16 +440,8 @@ module UI
|
|
387
440
|
def items_before_cursor; @selected; end
|
388
441
|
def items_after_cursor; @list.size - @selected - 1 end
|
389
442
|
def cursor_min; 0 end
|
390
|
-
def cursor_max
|
391
|
-
|
392
|
-
private def _check # debug method
|
393
|
-
return
|
394
|
-
fail "@selected = nil" unless @selected
|
395
|
-
fail "@selected = #{@selected}" unless @selected >= 0
|
396
|
-
fail "@selected > @list.size" if @selected >= @list.size
|
397
|
-
fail "@cursor = nil" unless @cursor
|
398
|
-
fail "@cursor = #{@cursor}" unless @cursor >= 0
|
399
|
-
fail "@cursor > max" if @cursor > @win.maxy
|
443
|
+
def cursor_max
|
444
|
+
@list.empty? ? 0 : [@list.size, @size.height].min - 1
|
400
445
|
end
|
401
446
|
end
|
402
447
|
end
|
data/lib/ektoplayer/updater.rb
CHANGED
@@ -20,8 +20,18 @@ module Ektoplayer
|
|
20
20
|
|
21
21
|
def update(start_url: FREE_MUSIC_URL, pages: 0, parallel: 10)
|
22
22
|
queue = parallel > 0 ? SizedQueue.new(parallel) : Queue.new
|
23
|
-
insert_browserpage(bp = BrowsePage.new(start_url))
|
24
23
|
results = Queue.new
|
24
|
+
bp = BrowsePage.new(start_url)
|
25
|
+
results << bp
|
26
|
+
|
27
|
+
insert_thread = Thread.new do
|
28
|
+
loop do
|
29
|
+
result = results.pop
|
30
|
+
@db.transaction
|
31
|
+
insert_browserpage(result)
|
32
|
+
@db.commit
|
33
|
+
end
|
34
|
+
end
|
25
35
|
|
26
36
|
if pages > 0
|
27
37
|
bp.page_urls[(bp.current_page_index + 1)..(bp.current_page_index + pages + 1)]
|
@@ -30,24 +40,24 @@ module Ektoplayer
|
|
30
40
|
end.
|
31
41
|
each do |url|
|
32
42
|
queue << Thread.new do
|
33
|
-
|
43
|
+
|
44
|
+
3.times do |try|
|
45
|
+
begin
|
46
|
+
bp = BrowsePage.new(url)
|
47
|
+
Application.log(self, url, bp.albums.size, "albums found")
|
48
|
+
results << bp
|
49
|
+
break
|
50
|
+
rescue
|
51
|
+
Application.log(self, url, $!, "(retry ##{try})")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
34
55
|
queue.pop # unregister our thread
|
35
56
|
end.priority
|
36
|
-
|
37
|
-
if results.size > 40
|
38
|
-
@db.transaction
|
39
|
-
40.times { insert_browserpage(results.pop(true)) }
|
40
|
-
@db.commit
|
41
|
-
end
|
42
57
|
end
|
43
58
|
|
44
|
-
sleep 1
|
45
|
-
|
46
|
-
@db.transaction
|
47
|
-
while (result = queue.pop(true) rescue nil)
|
48
|
-
insert_browserpage(result)
|
49
|
-
end
|
50
|
-
@db.commit
|
59
|
+
sleep 1 until queue.empty?
|
60
|
+
insert_thread.kill
|
51
61
|
rescue
|
52
62
|
Application.log(self, $!)
|
53
63
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ektoplayer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Abendroth
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|