cloudruby 1.1.0 → 1.2.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 +4 -4
- data/bin/cloudruby +15 -2
- data/lib/cloudruby.rb +6 -2
- data/lib/gstplayer.rb +32 -10
- data/lib/mpg123player.rb +2 -0
- data/lib/ncurses_ui.rb +138 -45
- data/lib/soundcloud.rb +21 -12
- 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: f8d5679ca3d885cee4beedaa63a78115a1c1d6b0
|
4
|
+
data.tar.gz: f49c26dcd1a7626dfbbfdef0786425013a40f401
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb15c734a3a25d8285bcbc1fa968c19d31ad942603170b3f78e415bdf0bc8c6172861cb358b41deb877a9a44eb0ff1dce5f4d62de10f3bf81d1eee35b8c7c7be
|
7
|
+
data.tar.gz: a8e322c14749ed65694e1c2adbfb1367337d51afdf3a863aeae5c31182481503e85bb7068b387ff28c582b25a536f5d9c8e954e4721dae96d40902e786658853
|
data/bin/cloudruby
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'json/pure'
|
4
|
-
|
5
|
-
|
4
|
+
begin
|
5
|
+
require_relative '../lib/cloudruby' # from source dir
|
6
|
+
rescue LoadError
|
7
|
+
begin
|
8
|
+
require_relative '../lib/cloudruby/lib/cloudruby' # from /usr/bin/
|
9
|
+
rescue LoadError
|
10
|
+
begin
|
11
|
+
require 'cloudruby' # binary installed as gem
|
12
|
+
rescue LoadError
|
13
|
+
puts "Cannot load cloudruby library. Exiting."
|
14
|
+
exit false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
6
19
|
|
7
20
|
@config = {}
|
8
21
|
@query = []
|
data/lib/cloudruby.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
require 'pp'
|
2
1
|
require 'observer'
|
3
2
|
require 'logger'
|
4
|
-
|
3
|
+
begin
|
4
|
+
require 'json/pure'
|
5
|
+
rescue LoadError
|
6
|
+
require 'json'
|
7
|
+
end
|
8
|
+
|
5
9
|
require_relative 'soundcloud.rb'
|
6
10
|
require_relative 'mpg123player.rb'
|
7
11
|
require_relative 'gstplayer.rb'
|
data/lib/gstplayer.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'gst'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
2
5
|
|
3
6
|
class GstPlayer
|
4
7
|
include Observable
|
@@ -15,7 +18,12 @@ class GstPlayer
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def initialize params = {}
|
21
|
+
@curvature = 4
|
18
22
|
params.each { |key, value| send "#{key}=", value }
|
23
|
+
unless defined? Gst
|
24
|
+
puts "Gstream backend requires gstream gem"
|
25
|
+
exit false
|
26
|
+
end
|
19
27
|
|
20
28
|
@logger.info version
|
21
29
|
@inqueue = []
|
@@ -34,6 +42,10 @@ class GstPlayer
|
|
34
42
|
@pipeline.set_property "audio-sink", sink unless sink.nil?
|
35
43
|
when :"buffer-duration", :"buffer-size", :"mute", :"volume"
|
36
44
|
@pipeline.set_property key, value
|
45
|
+
when :volume
|
46
|
+
@pipeline.set_property key, logscale(value)
|
47
|
+
when :"volume-curvature"
|
48
|
+
@curvature = value.to_f
|
37
49
|
end
|
38
50
|
end
|
39
51
|
end
|
@@ -86,14 +98,23 @@ class GstPlayer
|
|
86
98
|
notify_observers :state => :error, :error => err
|
87
99
|
end
|
88
100
|
|
101
|
+
#approximation to a logarithmic scale
|
102
|
+
def logscale val, inverse = false
|
103
|
+
val = val.to_f
|
104
|
+
if inverse
|
105
|
+
100 * (val ** (1.0/@curvature))
|
106
|
+
else
|
107
|
+
(val/100)**@curvature
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
89
111
|
def volume= (val)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
@volume =
|
94
|
-
@pipeline.volume = @volume/100.0
|
112
|
+
vol = volume
|
113
|
+
vol += val
|
114
|
+
vol = [0, [vol, 100].min].max
|
115
|
+
@pipeline.volume = logscale(vol)
|
95
116
|
changed
|
96
|
-
notify_observers :state => :status, :type => "Volume", :value => "#{
|
117
|
+
notify_observers :state => :status, :type => "Volume", :value => "#{vol.to_i}%"
|
97
118
|
rescue => err
|
98
119
|
@error = err
|
99
120
|
changed
|
@@ -101,13 +122,14 @@ class GstPlayer
|
|
101
122
|
end
|
102
123
|
|
103
124
|
def volume
|
104
|
-
|
125
|
+
logval = @pipeline.get_property("volume").to_f
|
126
|
+
logscale logval, true
|
105
127
|
end
|
106
128
|
|
107
129
|
def mute
|
108
130
|
@pipeline.set_property "mute", !@pipeline.get_property("mute")
|
109
131
|
changed
|
110
|
-
notify_observers :state => :status, :type => "Volume", :value => "#{muted? ? 0 :
|
132
|
+
notify_observers :state => :status, :type => "Volume", :value => "#{muted? ? 0 : volume}%"
|
111
133
|
rescue => err
|
112
134
|
@error = err
|
113
135
|
changed
|
@@ -178,7 +200,7 @@ class GstPlayer
|
|
178
200
|
when Gst::MessageType::BUFFERING
|
179
201
|
percent = message.parse_buffering
|
180
202
|
changed
|
181
|
-
notify_observers :state => :
|
203
|
+
notify_observers :state => :buffer, :value => percent
|
182
204
|
when Gst::MessageType::STATE_CHANGED
|
183
205
|
error, state = message.parse_state_changed
|
184
206
|
case state
|
data/lib/mpg123player.rb
CHANGED
data/lib/ncurses_ui.rb
CHANGED
@@ -27,10 +27,12 @@ class NCursesUI
|
|
27
27
|
:playlist_active => [:white, :blue],
|
28
28
|
:progress => [:cyan, :blue],
|
29
29
|
:progress_bar => [:blue, :cyan],
|
30
|
+
:buffer_bar => [:blue, :magenta],
|
30
31
|
:title => [:cyan, :black],
|
31
32
|
:artist => [:cyan, :black],
|
32
33
|
:status => [:magenta, :black]
|
33
|
-
}
|
34
|
+
},
|
35
|
+
:palette => {}
|
34
36
|
}.freeze
|
35
37
|
|
36
38
|
@options = defaults.deep_merge(options || {})
|
@@ -48,14 +50,14 @@ class NCursesUI
|
|
48
50
|
begin
|
49
51
|
stdscr = Curses.init_screen
|
50
52
|
Curses.start_color
|
51
|
-
Colors.init @options[:colors]
|
53
|
+
Colors.init @options[:colors], @options[:palette]
|
52
54
|
stdscr.keypad true
|
53
55
|
Curses.nonl
|
54
56
|
Curses.cbreak
|
55
57
|
Curses.noecho
|
56
58
|
Curses.curs_set 0
|
57
59
|
Curses.timeout = 5
|
58
|
-
@p = NProgress.new stdscr, 0, 0, :progress, :progress_bar
|
60
|
+
@p = NProgress.new stdscr, 0, 0, :progress, :progress_bar, :buffer_bar
|
59
61
|
@l = NPlaylist.new stdscr, 4, 0, :playlist, :playlist_active, 0, 0, @playlist
|
60
62
|
@i = NInfobox.new self, stdscr, 4, 0, :playlist, 0, 9
|
61
63
|
@d = NDownloadBox.new stdscr, Curses.lines-1, 0, :default, 0, 1
|
@@ -95,15 +97,14 @@ class NCursesUI
|
|
95
97
|
@cloud.pause
|
96
98
|
end
|
97
99
|
|
98
|
-
statusLine = @status || @error
|
100
|
+
statusLine = @status || @error || ""
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
Curses.refresh
|
103
|
-
end
|
102
|
+
Nutils.print stdscr, 3, 0, "#{statusLine}", :status
|
103
|
+
Curses.refresh
|
104
104
|
tr = " %s " % [Nutils.timestr(@timetotal)]
|
105
105
|
t = " %-#{Curses.cols-tr.size-1}s%s" % [Nutils.timestr(@time), tr]
|
106
106
|
@p.value = @frac
|
107
|
+
@p.subvalue = (@bufferPercentage || 0)/100.0
|
107
108
|
@p.text = t
|
108
109
|
@p.refresh
|
109
110
|
Nutils.print stdscr, 1, 0, "#{@op} #{@title}", :title
|
@@ -117,7 +118,7 @@ class NCursesUI
|
|
117
118
|
ensure
|
118
119
|
@l.close if @l
|
119
120
|
@p.close if @p
|
120
|
-
stdscr.close
|
121
|
+
stdscr.close if stdscr
|
121
122
|
Curses.echo
|
122
123
|
Curses.nocbreak
|
123
124
|
Curses.nl
|
@@ -130,6 +131,8 @@ class NCursesUI
|
|
130
131
|
|
131
132
|
def cloud_update(arg)
|
132
133
|
case arg[:state]
|
134
|
+
when :error
|
135
|
+
@error = "Error: #{arg[:error]}"
|
133
136
|
when :load
|
134
137
|
@playlist |= arg[:tracks]
|
135
138
|
@l.list = @playlist if @l
|
@@ -156,6 +159,10 @@ class NCursesUI
|
|
156
159
|
@d.title = ""
|
157
160
|
end
|
158
161
|
end
|
162
|
+
when :status
|
163
|
+
if arg[:type]
|
164
|
+
status("#{arg[:type]}: #{arg[:value]}")
|
165
|
+
end
|
159
166
|
end
|
160
167
|
end
|
161
168
|
|
@@ -186,17 +193,11 @@ class NCursesUI
|
|
186
193
|
@op = "\u25FC"
|
187
194
|
when :error
|
188
195
|
@error = "Error: #{arg[:error]}"
|
196
|
+
when :buffer
|
197
|
+
@bufferPercentage = arg[:value].to_i || 0
|
189
198
|
when :status
|
190
199
|
if arg[:type]
|
191
|
-
|
192
|
-
if @statusTimeout
|
193
|
-
@statusTimeout.exit
|
194
|
-
end
|
195
|
-
@statusTimeout = Thread.new do
|
196
|
-
sleep 5
|
197
|
-
@status = nil
|
198
|
-
@statusTimeout = nil
|
199
|
-
end
|
200
|
+
status("#{arg[:type]}: #{arg[:value]}")
|
200
201
|
end
|
201
202
|
end
|
202
203
|
end
|
@@ -204,16 +205,28 @@ class NCursesUI
|
|
204
205
|
def close
|
205
206
|
@state = :close
|
206
207
|
end
|
208
|
+
|
209
|
+
def status msg
|
210
|
+
@status = msg
|
211
|
+
if @statusTimeout
|
212
|
+
@statusTimeout.exit
|
213
|
+
end
|
214
|
+
@statusTimeout = Thread.new do
|
215
|
+
sleep 5
|
216
|
+
@status = nil
|
217
|
+
@statusTimeout = nil
|
218
|
+
end
|
219
|
+
end
|
207
220
|
end
|
208
221
|
|
209
222
|
class Nutils
|
210
223
|
def self.print(scr, row, col, text, color, width = (Curses.cols))
|
211
224
|
width = [Curses.cols, col+width].min - col
|
212
225
|
t = "%-#{width}s" % [scroll(text, width)]
|
213
|
-
scr.attron(Colors.
|
226
|
+
scr.attron(Colors.pairMap(color)) if color
|
214
227
|
scr.setpos row, col
|
215
228
|
scr.addstr t
|
216
|
-
scr.attroff(Colors.
|
229
|
+
scr.attroff(Colors.pairMap(color)) if color
|
217
230
|
end
|
218
231
|
|
219
232
|
def self.scroll(text, width, offset=0)
|
@@ -234,47 +247,110 @@ class Nutils
|
|
234
247
|
end
|
235
248
|
|
236
249
|
class Colors
|
237
|
-
$
|
238
|
-
$
|
239
|
-
|
240
|
-
|
241
|
-
|
250
|
+
$pairMap = {}
|
251
|
+
$colorMap = {}
|
252
|
+
$attrMap = {}
|
253
|
+
$pairCounter = 0
|
254
|
+
$colorCounter = 0
|
255
|
+
def self.init colormap = {}, palette = {}
|
256
|
+
Curses.use_default_colors
|
257
|
+
$pairCounter += 1
|
258
|
+
|
259
|
+
Curses::constants.grep(/COLOR_/).each do |c|
|
260
|
+
color = c.to_s.split("_")[1]
|
261
|
+
$colorMap[color.downcase.to_sym] = Curses.const_get "#{c}"
|
262
|
+
$colorCounter += 1;
|
242
263
|
end
|
243
|
-
end
|
244
264
|
|
245
|
-
|
246
|
-
|
265
|
+
if Curses.can_change_color?
|
266
|
+
palette.each do |name, definition|
|
267
|
+
if $colorCounter >= Curses.colors || name.length == 0
|
268
|
+
$colorMap[name] = $colorMap[:white]
|
269
|
+
elsif $colorMap[name]
|
270
|
+
if definition.is_a? Integer
|
271
|
+
$colorMap[name] = definition
|
272
|
+
elsif definition.is_a?(Array) and definition.length == 3
|
273
|
+
Curses.init_color $colorMap[name], definition[0], definition[1], definition[2]
|
274
|
+
end
|
275
|
+
else
|
276
|
+
if definition.is_a? Integer
|
277
|
+
$colorMap[name] = definition
|
278
|
+
elsif definition.is_a?(Array) and definition.length == 3
|
279
|
+
$colorMap[name] = $colorCounter;
|
280
|
+
Curses.init_color $colorCounter, definition[0], definition[1], definition[2]
|
281
|
+
$colorCounter += 1;
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
colormap.each do |key, colors|
|
288
|
+
self.add(key, colors[0], colors[1], colors[2..-1])
|
289
|
+
end
|
247
290
|
end
|
248
291
|
|
249
|
-
def self.
|
250
|
-
|
251
|
-
|
252
|
-
|
292
|
+
def self.pairMap(key)
|
293
|
+
($pairMap[key] || $pairMap[:default] ) | ($attrMap[key] || 0)
|
294
|
+
end
|
295
|
+
|
296
|
+
def self.add(key, fg, bg, attrs=[])
|
297
|
+
Curses.init_pair $pairCounter, ncg(fg), ncg(bg)
|
298
|
+
$pairMap[key] = Curses.color_pair $pairCounter
|
299
|
+
$attrMap[key] = attrs.map do |a|
|
300
|
+
case a.to_sym
|
301
|
+
when :bold
|
302
|
+
Curses::A_BOLD
|
303
|
+
when :underline
|
304
|
+
Curses::A_UNDERLINE
|
305
|
+
when :blink
|
306
|
+
Curses::A_BLINK
|
307
|
+
when :dim
|
308
|
+
Curses::A_DIM
|
309
|
+
when :normal
|
310
|
+
Curses::A_NORMAL
|
311
|
+
when :standout
|
312
|
+
Curses::A_STANDOUT
|
313
|
+
when :reverse
|
314
|
+
Curses::A_REVERSE
|
315
|
+
end
|
316
|
+
end.compact.reduce :|
|
317
|
+
$pairCounter += 1
|
253
318
|
end
|
254
319
|
|
255
320
|
def self.debug
|
256
321
|
puts "colors supported: #{Curses.colors}"
|
257
|
-
puts "
|
322
|
+
puts "pairMap: #{$pairMap}"
|
323
|
+
puts "attributes: #{$attrMap}"
|
324
|
+
puts "colorPalette: #{$colorMap}"
|
258
325
|
end
|
326
|
+
|
259
327
|
# get ncurses color constant
|
260
328
|
def self.ncg(color)
|
261
|
-
color
|
262
|
-
|
329
|
+
if color.is_a? Integer
|
330
|
+
color
|
331
|
+
else
|
332
|
+
color = -1 unless color
|
333
|
+
color = color.to_sym
|
334
|
+
$colorMap[color] || -1
|
335
|
+
end
|
263
336
|
end
|
264
337
|
end
|
265
338
|
|
266
339
|
class NProgress
|
267
|
-
attr_reader :value
|
340
|
+
attr_reader :value, :subvalue
|
268
341
|
attr_accessor :text
|
269
|
-
def initialize scr, row, col, color, bar_color, width=0, value = 0, text = ""
|
342
|
+
def initialize scr, row, col, color, bar_color, subbar_color, width=0, value = 0, subvalue = 0, text = ""
|
270
343
|
@width = width
|
271
344
|
@color = color
|
272
345
|
@bar_color = bar_color
|
346
|
+
@subbar_color = subbar_color
|
273
347
|
@row = row
|
274
348
|
@col = col
|
275
349
|
@winfg = Curses::Window.new 1, 1, @row, @col
|
350
|
+
@winsfg = Curses::Window.new 1, 1, @row, @col
|
276
351
|
@winbg = Curses::Window.new 1, self.width, @row, @col
|
277
352
|
@value = value
|
353
|
+
@subvalue = subvalue
|
278
354
|
@text = text
|
279
355
|
refresh
|
280
356
|
end
|
@@ -288,11 +364,19 @@ class NProgress
|
|
288
364
|
@winfg.resize(1, fgw) if fgw > 0
|
289
365
|
end
|
290
366
|
|
367
|
+
def subvalue=(val)
|
368
|
+
@subvalue = val
|
369
|
+
@winsfg.resize(1, sfgw) if sfgw > 0
|
370
|
+
end
|
371
|
+
|
291
372
|
def refresh
|
292
|
-
|
293
|
-
|
373
|
+
bgOffset = [fgw, sfgw].max
|
374
|
+
sbOffset = fgw
|
375
|
+
Nutils.print @winbg, 0, bgOffset, @text[bgOffset..-1], @color
|
376
|
+
Nutils.print @winsfg, 0, sbOffset, @text[sbOffset..-1], @subbar_color if sfgw > 0
|
294
377
|
Nutils.print @winfg, 0, 0, @text, @bar_color if fgw > 0
|
295
378
|
@winbg.refresh
|
379
|
+
@winsfg.refresh if sfgw > 0
|
296
380
|
@winfg.refresh if fgw > 0
|
297
381
|
end
|
298
382
|
|
@@ -301,6 +385,7 @@ class NProgress
|
|
301
385
|
|
302
386
|
def close
|
303
387
|
@winbg.close
|
388
|
+
@winsfg.close
|
304
389
|
@winfg.close
|
305
390
|
end
|
306
391
|
|
@@ -309,6 +394,10 @@ class NProgress
|
|
309
394
|
w = width() == 0 ? Curses.cols - @col : width()
|
310
395
|
(w * @value).floor
|
311
396
|
end
|
397
|
+
def sfgw
|
398
|
+
w = width() == 0 ? Curses.cols - @col : width()
|
399
|
+
(w * @subvalue).floor
|
400
|
+
end
|
312
401
|
end
|
313
402
|
|
314
403
|
class NPlaylist
|
@@ -399,9 +488,13 @@ class NPlaylist
|
|
399
488
|
end
|
400
489
|
end
|
401
490
|
end
|
402
|
-
|
491
|
+
while r < height
|
492
|
+
Nutils.print @win, r, 0, "", @color
|
493
|
+
r += 1
|
494
|
+
end
|
495
|
+
@win.attron(Colors.pairMap(@color)) if @color
|
403
496
|
@win.box 0, 0
|
404
|
-
@win.attroff(Colors.
|
497
|
+
@win.attroff(Colors.pairMap(@color)) if @color
|
405
498
|
@win.refresh
|
406
499
|
@dirty = false
|
407
500
|
end
|
@@ -450,16 +543,16 @@ class NInfobox
|
|
450
543
|
|
451
544
|
def refresh
|
452
545
|
return unless @visible
|
453
|
-
Nutils.print @win, 1, 2, "Cloudruby v1.
|
454
|
-
Nutils.print @win, 2, 4, "UI Toolkit: #{(Curses.const_defined?"VERSION")?Curses::VERSION : "N/A"}", :default
|
546
|
+
Nutils.print @win, 1, 2, "Cloudruby v1.2", :default
|
547
|
+
Nutils.print @win, 2, 4, "UI Toolkit: #{(Curses.const_defined?"VERSION")?"#{Curses::VERSION}, #colors: #{Curses::colors}" : "N/A"}", :default
|
455
548
|
Nutils.print @win, 3, 4, "#{@parent.audio_backend.version}", :default
|
456
549
|
Nutils.print @win, 4, 4, "Ruby version: #{RUBY_VERSION}", :default
|
457
550
|
Nutils.print @win, 5, 4, "Author: kulpae <my.shando@gmail.com>", :artist
|
458
551
|
Nutils.print @win, 6, 4, "Website: uraniumlane.net", :title
|
459
552
|
Nutils.print @win, 7, 4, "License: MIT", :default
|
460
|
-
@win.attron(Colors.
|
553
|
+
@win.attron(Colors.pairMap(@color)) if @color
|
461
554
|
@win.box 0, 0
|
462
|
-
@win.attroff(Colors.
|
555
|
+
@win.attroff(Colors.pairMap(@color)) if @color
|
463
556
|
@win.refresh
|
464
557
|
end
|
465
558
|
|
data/lib/soundcloud.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'open-uri'
|
3
|
-
require '
|
3
|
+
require 'httpclient'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'json/pure'
|
7
|
+
rescue LoadError
|
8
|
+
require 'json'
|
9
|
+
end
|
4
10
|
|
5
11
|
class SoundCloud
|
6
12
|
include Observable
|
@@ -13,6 +19,7 @@ class SoundCloud
|
|
13
19
|
@playlist_pos = -1
|
14
20
|
@download_queue = []
|
15
21
|
@dthread = Thread.new do downloader end
|
22
|
+
@dthread.run
|
16
23
|
end
|
17
24
|
|
18
25
|
def load_playlist(search = nil, offset = 0)
|
@@ -91,46 +98,48 @@ class SoundCloud
|
|
91
98
|
filename = "#{t["permalink"]}.#{t["original_format"]}"
|
92
99
|
path = File.join(target_dir, filename)
|
93
100
|
pair = [path, t['download']]
|
101
|
+
@logger.debug {"download queued: #{pair}"}
|
94
102
|
@download_queue << pair unless @download_queue.include? pair
|
95
|
-
@dthread.run
|
96
103
|
|
97
104
|
changed
|
98
105
|
notify_observers :state => :download, :count => @download_queue.size
|
99
106
|
else
|
100
107
|
changed
|
101
|
-
notify_observers :state => :
|
108
|
+
notify_observers :state => :status, :type => "Download", :value => "Not granted by content owner"
|
102
109
|
end
|
103
110
|
end
|
104
111
|
|
105
112
|
# download thread
|
106
113
|
def downloader
|
107
114
|
loop do
|
108
|
-
size = @download_queue.size
|
109
115
|
while d = @download_queue.shift
|
110
116
|
path = d[0]
|
111
117
|
uri = d[1]
|
118
|
+
size = @download_queue.size
|
112
119
|
changed
|
113
120
|
notify_observers :state => :download, :name => path, :count => size
|
114
|
-
size = @download_queue.size
|
115
121
|
begin
|
116
122
|
path = File.expand_path path
|
117
|
-
file = File.new(path, "wb")
|
118
123
|
File.open(path, "wb") do |file|
|
119
|
-
|
124
|
+
cl = HTTPClient.new
|
125
|
+
cl.redirect_uri_callback = ->(uri, res) {
|
126
|
+
res.header['location'][0]
|
127
|
+
}
|
128
|
+
cl.get_content(uri) do |chunk|
|
129
|
+
file.write(chunk)
|
130
|
+
end
|
120
131
|
end
|
121
|
-
|
122
|
-
|
123
|
-
rescue OpenURI::HTTPError => e
|
132
|
+
rescue Exception => e
|
133
|
+
@logger.error {"Download error: #{e}"}
|
124
134
|
changed
|
125
135
|
notify_observers :state => :error, :error => e
|
126
|
-
ensure
|
127
|
-
file.close
|
128
136
|
end
|
129
137
|
end
|
130
138
|
sleep 5
|
131
139
|
end
|
132
140
|
rescue => e
|
133
141
|
changed
|
142
|
+
@logger.error {"Downloader thread: #{e}"}
|
134
143
|
notify_observers :state => "error", :error => e
|
135
144
|
end
|
136
145
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|