cloudruby 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|