ektoplayer 0.1.19 → 0.1.20

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: 9900059a06f9aa74a7cb9ba1ea0ae4454c277a5f
4
- data.tar.gz: ed88fdc3dab3eedffd42de732596ca6ff4bbfab6
3
+ metadata.gz: 25039a3262bb6332eef51524e8f210e95f9d5bca
4
+ data.tar.gz: bf810de03fbbeb0b6b78aec743fe22c1b02a79c3
5
5
  SHA512:
6
- metadata.gz: 6c53f882d896c43c7d51ecdea80e407e3211d248726dd08189fbda66ac3e6a74d285a50034f9f3bef945980b120a3fdd6f3c1db58efc66405980606059352064
7
- data.tar.gz: ad2b475b718c3b7aa5e6c6945178000ccffce51680218f0dabbbd1b006068a2878e32bc69966b24b790e77de6f3529496faea563a573d5864cdc1e414d212495
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.19'.freeze
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
@@ -127,10 +127,6 @@ module Ektoplayer
127
127
 
128
128
  @albums << album
129
129
  end
130
-
131
- Application.log(self, "#{src} #{@albums.size} albums found")
132
- rescue
133
- Application.log(self, src, $!)
134
130
  end
135
131
  end
136
132
  end
@@ -1,4 +1,4 @@
1
- unless Array.respond_to? :sum
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.respond_to? :clamp
9
+ unless Integer.public_method_defined? :clamp
10
10
  class Integer
11
11
  def clamp(min, max)
12
12
  return min if self < min
@@ -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 donwload threads during database update',
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  unless ARGV[0]
4
- %w(curses ncurses ncursesw ffi_curses).each do |i|
4
+ %w(curses ncurses ncursesw ffi-curses).each do |i|
5
5
  puts i
6
6
  fail i unless system($0, i)
7
7
  end
@@ -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) end
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
- source.size
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
- 0
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; self.selected=(@search.next(@selected, @list)) end
99
- def search_prev; self.selected=(@search.prev(@selected, @list)) end
100
- def search_up; self.search_start(:up) end
101
- def search_down; self.search_start(:down) end
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, 'render todo') unless @list[index]
160
+ return Ektoplayer::Application.log(self, index, caller) unless @list[index]
136
161
 
137
- opts[:selection] = (@selection.started? and (
138
- opts[:selected] or index.between?(
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.scroll_up(size.height) end
156
- def page_down; self.scroll_down(size.height) end
157
- def up(n=1) self.selected=(selected - n) end
158
- def down(n=1) self.selected=(selected + n) end
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 selected=(new_index)
174
- fail ArgumentError unless new_index
175
- old_index_bottom = index_bottom
176
- old_index_top = index_top
177
- old_selected, @selected = @selected, new_index.clamp(0, index_last)
178
- return if old_selected == @selected or @list.empty?
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
- old_cursor, new_cursor = @cursor, @cursor + (@selected - old_selected)
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
- if new_cursor.between?(0, @size.height - 1)
185
- # new selected item resides in current screen,
186
- # just want_redraw the old line and the newly selected one
187
- @cursor = new_cursor
221
+ if @selection.started?
222
+ want_redraw
223
+ else
224
+ write_at(@cursor); render(@selected)
188
225
 
189
- # redraw whole screen in selection mode!
190
- return want_redraw if @selection.started?
226
+ (index_bottom + 1).upto(new_selected - 1).each do |index|
227
+ @win.append_bottom; render(index)
228
+ end
191
229
 
192
- write_at(old_cursor); render(old_selected)
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
- (old_index_top - 1).downto(@selected + 1).each do |index|
204
- @win.insert_top; render(index)
232
+ want_refresh
205
233
  end
234
+ end
235
+ end
206
236
 
207
- @win.insert_top; render(@selected, selected: true)
208
- @cursor = 0
209
- #_check
210
- else
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
- (old_index_bottom + 1).upto(@selected - 1).each do |index|
216
- @win.append_bottom; render(index)
217
- end
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
- @win.append_bottom; render(@selected, selected: true)
220
- @cursor = cursor_max
221
- #_check
222
- end
249
+ self.lock
223
250
 
224
- want_refresh
225
- else
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
- self.lock
259
- if @selected <= cursor_max
260
- @cursor = @selected
261
- elsif (diff = (index_last - @selected)) < cursor_max
262
- @cursor = @size.height - diff - 1 #cursor_max.clamp(0, index_last - @selected)
263
- else
264
- @cursor = new_cursor.clamp(0, cursor_max)
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 scroll_up(n=1)
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 # TODO: move up?
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 scroll_down(n=1)
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
- @selected = @selected.clamp(0, index_last)
345
- #_check
401
+ #@selected = @selected.clamp(0, index_last)
346
402
 
347
403
  @cursor.times do |i|
348
- unless row = @list[@selected - (@cursor - i)]
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 row = @list[@selected + i + 1]
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; [@size.height, @list.size].min - 1 end
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
@@ -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
- results << BrowsePage.new(url)
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 while not queue.empty?
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.19
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-10-02 00:00:00.000000000 Z
11
+ date: 2017-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3