groove-dl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +674 -0
- data/MANIFEST +34 -0
- data/README.md +87 -0
- data/Rakefile +10 -0
- data/bin/groove-dl +18 -0
- data/bin/groove-dl-cli +15 -0
- data/groove-dl.gemspec +32 -0
- data/lib/groove-dl.rb +13 -0
- data/lib/groove-dl/app.rb +54 -0
- data/lib/groove-dl/cli.rb +58 -0
- data/lib/groove-dl/cli/search.rb +30 -0
- data/lib/groove-dl/configuration.rb +14 -0
- data/lib/groove-dl/displayer.rb +56 -0
- data/lib/groove-dl/downloader.rb +178 -0
- data/lib/groove-dl/errors.rb +8 -0
- data/lib/groove-dl/version.rb +5 -0
- data/lib/groove-dl/widgets/download/bar.rb +87 -0
- data/lib/groove-dl/widgets/download/book.rb +73 -0
- data/lib/groove-dl/widgets/download/list/failed.rb +75 -0
- data/lib/groove-dl/widgets/download/list/queue.rb +171 -0
- data/lib/groove-dl/widgets/download/list/success.rb +76 -0
- data/lib/groove-dl/widgets/search/bar.rb +67 -0
- data/lib/groove-dl/widgets/search/list.rb +146 -0
- data/spec/groove-dl/cli_spec.rb +49 -0
- data/spec/groove-dl/displayer_spec.rb +63 -0
- data/spec/groove-dl/downloader_spec.rb +188 -0
- data/spec/spec_helper.rb +8 -0
- data/task/manifest.rake +9 -0
- data/task/rubocop.rake +5 -0
- data/task/spec.rake +6 -0
- metadata +233 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module GrooveDl
|
3
|
+
# Widgets components
|
4
|
+
module Widgets
|
5
|
+
# Search section
|
6
|
+
module Search
|
7
|
+
# Search bar
|
8
|
+
class Bar < Gtk::Box
|
9
|
+
attr_reader :type, :query
|
10
|
+
|
11
|
+
##
|
12
|
+
# Initialize widgets
|
13
|
+
#
|
14
|
+
# @param [Grooveshark::Client] client Grooveshark client
|
15
|
+
# @param [Gtk::Window] window Gtk app
|
16
|
+
#
|
17
|
+
def load(client, window)
|
18
|
+
search_box = Gtk::Box.new(:horizontal, 6)
|
19
|
+
|
20
|
+
search_bar = Gtk::Entry.new
|
21
|
+
search_bar.set_name('search_bar')
|
22
|
+
search_bar.text = 'CruciAGoT'
|
23
|
+
search_box.pack_start(search_bar,
|
24
|
+
expand: true,
|
25
|
+
fill: true,
|
26
|
+
padding: 10)
|
27
|
+
|
28
|
+
search_type = Gtk::ComboBoxText.new
|
29
|
+
search_type.set_name('search_type')
|
30
|
+
search_type.append_text 'Playlists'
|
31
|
+
search_type.append_text 'Songs'
|
32
|
+
search_type.active = 0
|
33
|
+
|
34
|
+
search_box.pack_start(search_type,
|
35
|
+
expand: false,
|
36
|
+
fill: true,
|
37
|
+
padding: 5)
|
38
|
+
|
39
|
+
button = Gtk::Button.new(label: 'Search', stock_id: Gtk::Stock::FIND)
|
40
|
+
button.signal_connect('released') do
|
41
|
+
@type = search_type.active_text
|
42
|
+
@query = search_bar.text
|
43
|
+
next if @type.empty? || @query.empty?
|
44
|
+
search = client.request('getResultsFromSearch',
|
45
|
+
type: @type,
|
46
|
+
query: @query)
|
47
|
+
results = search['result'].map do |data|
|
48
|
+
next Grooveshark::Song.new data if type == 'Songs'
|
49
|
+
data
|
50
|
+
end if search.key?('result')
|
51
|
+
|
52
|
+
window.find_by_name('search_list').create_model(results)
|
53
|
+
end
|
54
|
+
|
55
|
+
search_box.pack_start(button,
|
56
|
+
expand: false,
|
57
|
+
fill: false,
|
58
|
+
padding: 10)
|
59
|
+
|
60
|
+
pack_start(search_box,
|
61
|
+
expand: false,
|
62
|
+
padding: 10)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module GrooveDl
|
3
|
+
# Widgets components
|
4
|
+
module Widgets
|
5
|
+
# Search section
|
6
|
+
module Search
|
7
|
+
# Search list tree
|
8
|
+
class List < Gtk::Box
|
9
|
+
attr_reader :data
|
10
|
+
attr_reader :store
|
11
|
+
attr_reader :selection
|
12
|
+
|
13
|
+
COLUMN_FIXED,
|
14
|
+
COLUMN_ID,
|
15
|
+
COLUMN_NAME,
|
16
|
+
COLUMN_AUTHOR,
|
17
|
+
COLUMN_SONG = *(0..5).to_a
|
18
|
+
|
19
|
+
##
|
20
|
+
# Initialize widgets
|
21
|
+
#
|
22
|
+
# @param [Grooveshark::Client] client Grooveshark client
|
23
|
+
# @param [Gtk::Window] window Gtk app
|
24
|
+
#
|
25
|
+
def load(_client, _window)
|
26
|
+
set_name('search_list')
|
27
|
+
|
28
|
+
@selection = {}
|
29
|
+
sw = Gtk::ScrolledWindow.new
|
30
|
+
sw.shadow_type = Gtk::ShadowType::ETCHED_IN
|
31
|
+
sw.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC)
|
32
|
+
pack_start(sw, expand: true, fill: true, padding: 0)
|
33
|
+
|
34
|
+
@store = Gtk::ListStore.new(TrueClass,
|
35
|
+
Integer,
|
36
|
+
String,
|
37
|
+
String,
|
38
|
+
String)
|
39
|
+
create_model
|
40
|
+
treeview = Gtk::TreeView.new(@store)
|
41
|
+
treeview.rules_hint = true
|
42
|
+
treeview.search_column = COLUMN_SONG
|
43
|
+
|
44
|
+
sw.add(treeview)
|
45
|
+
|
46
|
+
add_columns(treeview)
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Create line in the list store
|
51
|
+
#
|
52
|
+
# @param [Array] data Data stored
|
53
|
+
#
|
54
|
+
def create_model(data = [])
|
55
|
+
@store.clear
|
56
|
+
@data = {}
|
57
|
+
data.each do |element|
|
58
|
+
iter = @store.append
|
59
|
+
iter[COLUMN_FIXED] = false
|
60
|
+
if element.is_a?(Grooveshark::Song)
|
61
|
+
@data[element.id.to_i] = element
|
62
|
+
iter[COLUMN_ID] = element.id.to_i
|
63
|
+
iter[COLUMN_NAME] = element.name
|
64
|
+
iter[COLUMN_AUTHOR] = element.artist
|
65
|
+
iter[COLUMN_SONG] = element.album
|
66
|
+
else
|
67
|
+
@data[element['playlist_id'].to_i] = element
|
68
|
+
iter[COLUMN_ID] = element['playlist_id'].to_i
|
69
|
+
iter[COLUMN_NAME] = element['name']
|
70
|
+
iter[COLUMN_AUTHOR] = element['f_name']
|
71
|
+
iter[COLUMN_SONG] = element['num_songs']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Add columns on the treeview element
|
78
|
+
#
|
79
|
+
# @param [Gtk::Treeview] treeview Treeview
|
80
|
+
#
|
81
|
+
def add_columns(treeview)
|
82
|
+
renderer = Gtk::CellRendererToggle.new
|
83
|
+
renderer.signal_connect('toggled') do |_cell, path|
|
84
|
+
fixed_toggled(treeview.model, path)
|
85
|
+
end
|
86
|
+
|
87
|
+
column = Gtk::TreeViewColumn.new('X',
|
88
|
+
renderer,
|
89
|
+
'active' => COLUMN_FIXED)
|
90
|
+
column.sizing = Gtk::TreeViewColumn::Sizing::FIXED
|
91
|
+
column.fixed_width = 30
|
92
|
+
treeview.append_column(column)
|
93
|
+
|
94
|
+
renderer = Gtk::CellRendererText.new
|
95
|
+
column = Gtk::TreeViewColumn.new('Id',
|
96
|
+
renderer,
|
97
|
+
'text' => COLUMN_ID)
|
98
|
+
column.set_sort_column_id(COLUMN_ID)
|
99
|
+
column.sizing = Gtk::TreeViewColumn::Sizing::FIXED
|
100
|
+
column.fixed_width = 70
|
101
|
+
treeview.append_column(column)
|
102
|
+
|
103
|
+
renderer = Gtk::CellRendererText.new
|
104
|
+
column = Gtk::TreeViewColumn.new('Name',
|
105
|
+
renderer,
|
106
|
+
'text' => COLUMN_NAME)
|
107
|
+
column.set_sort_column_id(COLUMN_NAME)
|
108
|
+
column.fixed_width = 400
|
109
|
+
treeview.append_column(column)
|
110
|
+
|
111
|
+
renderer = Gtk::CellRendererText.new
|
112
|
+
column = Gtk::TreeViewColumn.new('Author',
|
113
|
+
renderer,
|
114
|
+
'text' => COLUMN_AUTHOR)
|
115
|
+
column.set_sort_column_id(COLUMN_AUTHOR)
|
116
|
+
column.fixed_width = 200
|
117
|
+
treeview.append_column(column)
|
118
|
+
|
119
|
+
renderer = Gtk::CellRendererText.new
|
120
|
+
column = Gtk::TreeViewColumn.new('Other data',
|
121
|
+
renderer,
|
122
|
+
'text' => COLUMN_SONG)
|
123
|
+
column.set_sort_column_id(COLUMN_SONG)
|
124
|
+
column.fixed_width = 100
|
125
|
+
treeview.append_column(column)
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# Fixed toggle button
|
130
|
+
#
|
131
|
+
# @param [Gtk::ListStore] model List store
|
132
|
+
# @param [String] path_str Path to row
|
133
|
+
#
|
134
|
+
def fixed_toggled(model, path_str)
|
135
|
+
path = Gtk::TreePath.new(path_str)
|
136
|
+
iter = model.get_iter(path)
|
137
|
+
fixed = iter[COLUMN_FIXED]
|
138
|
+
fixed ^= 1
|
139
|
+
iter[COLUMN_FIXED] = fixed
|
140
|
+
@selection[iter[COLUMN_ID]] = @data[iter[COLUMN_ID]] if fixed
|
141
|
+
@selection.delete(iter[COLUMN_ID]) unless fixed
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'groove-dl/cli'
|
4
|
+
require 'slop'
|
5
|
+
|
6
|
+
# Groove Dl tests
|
7
|
+
module GrooveDl
|
8
|
+
# CLI tests
|
9
|
+
module CLI
|
10
|
+
describe 'CLI' do
|
11
|
+
it 'should return options' do
|
12
|
+
options = CLI.options
|
13
|
+
expect(options).to be_a(::Slop)
|
14
|
+
expect(options.config[:strict]).to be_truthy
|
15
|
+
expect(options.config[:banner])
|
16
|
+
.to eq('Usage: groove-dl [COMMAND] [OPTIONS]')
|
17
|
+
expect(options.to_s)
|
18
|
+
.to match(/-v, --version(\s+)Shows the current version/)
|
19
|
+
expect(options.to_s)
|
20
|
+
.to match(/-h, --help(\s+)Display this help message./)
|
21
|
+
|
22
|
+
version = options.fetch_option(:v)
|
23
|
+
expect(version.short).to eq('v')
|
24
|
+
expect(version.long).to eq('version')
|
25
|
+
expect { version.call }.to output(/Groove-dl v.* on ruby/).to_stdout
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should retrieve version information' do
|
29
|
+
expect(CLI.version_information).to eq(
|
30
|
+
"Groove-dl v#{VERSION} on #{RUBY_DESCRIPTION}"
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should download playlist' do
|
35
|
+
allow(Grooveshark::Client).to receive(:new).and_return(true)
|
36
|
+
downloader = double
|
37
|
+
allow(downloader).to receive(:playlist).with(1).and_return(true)
|
38
|
+
allow(Downloader).to receive(:new).and_return(downloader)
|
39
|
+
expect(CLI.options.parse %w( -p 1)).to eq(['-p', '1'])
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should do nothing if v option is passed' do
|
43
|
+
expect(CLI.options).to receive(:puts).with(/Groove-dl v.* on ruby/)
|
44
|
+
.and_return(nil)
|
45
|
+
expect(CLI.options.parse %w( -v)).to eq(['-v'])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'grooveshark'
|
4
|
+
require 'terminal-table'
|
5
|
+
require 'fakefs/spec_helpers'
|
6
|
+
require 'groove-dl/displayer'
|
7
|
+
|
8
|
+
# Groove Dl tests
|
9
|
+
module GrooveDl
|
10
|
+
# Downloader test
|
11
|
+
describe 'Displayer' do
|
12
|
+
include FakeFS::SpecHelpers
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should initialize' do
|
18
|
+
song = Grooveshark::Song.new('song_id' => 1,
|
19
|
+
'name' => 'test',
|
20
|
+
'artist_name' => 'got')
|
21
|
+
displayer = Displayer.new([song], 'Songs')
|
22
|
+
expect(displayer.type).to eq('Songs')
|
23
|
+
expect(displayer.result.first).to be_a(Grooveshark::Song)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should render songs' do
|
27
|
+
song = Grooveshark::Song.new('song_id' => 1,
|
28
|
+
'name' => 'test',
|
29
|
+
'artist_name' => 'got')
|
30
|
+
displayer = Displayer.new([song], 'Songs')
|
31
|
+
|
32
|
+
str = '+----+-------+--------+------+
|
33
|
+
| Songs |
|
34
|
+
+----+-------+--------+------+
|
35
|
+
| Id | Album | Artist | Song |
|
36
|
+
+----+-------+--------+------+
|
37
|
+
| 1 | | got | test |
|
38
|
+
+----+-------+--------+------+'
|
39
|
+
allow(displayer).to receive(:puts)
|
40
|
+
.with(str).and_return(nil)
|
41
|
+
expect(displayer.render).to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should render songs' do
|
45
|
+
playlist = { 'playlist_id' => 1,
|
46
|
+
'name' => 'Someting',
|
47
|
+
'f_name' => 'GoT',
|
48
|
+
'num_songs' => 1 }
|
49
|
+
displayer = Displayer.new([playlist], 'Playlists')
|
50
|
+
|
51
|
+
str = '+----+----------+--------+----------+
|
52
|
+
| Playlists |
|
53
|
+
+----+----------+--------+----------+
|
54
|
+
| Id | Nam | Author | NumSongs |
|
55
|
+
+----+----------+--------+----------+
|
56
|
+
| 1 | Someting | GoT | 1 |
|
57
|
+
+----+----------+--------+----------+'
|
58
|
+
allow(displayer).to receive(:puts)
|
59
|
+
.with(str).and_return(nil)
|
60
|
+
expect(displayer.render).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'grooveshark'
|
4
|
+
require 'ruby-progressbar'
|
5
|
+
require 'fakefs/spec_helpers'
|
6
|
+
require 'groove-dl/downloader'
|
7
|
+
require 'groove-dl/errors'
|
8
|
+
require 'slop'
|
9
|
+
|
10
|
+
# Groove Dl tests
|
11
|
+
module GrooveDl
|
12
|
+
# Downloader test
|
13
|
+
describe 'Downloader' do
|
14
|
+
include FakeFS::SpecHelpers
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@client = double
|
18
|
+
@downloader = Downloader.new(@client, {})
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should do nothing if playlist not found' do
|
22
|
+
allow(@client).to receive(:request).and_return({})
|
23
|
+
expect(@downloader.playlist(1)).to be_falsy
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should do nothing if queue is empty' do
|
27
|
+
expect(@downloader.download_queue).to be_falsy
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should download playlist' do
|
31
|
+
allow(@client).to receive(:request)
|
32
|
+
.and_return('songs' => [{ 'song_id' => 1,
|
33
|
+
'name' => 'test',
|
34
|
+
'artist_name' => 'got',
|
35
|
+
'album_name' => 'ruby' }])
|
36
|
+
allow(@client).to receive(:get_stream_auth_by_songid)
|
37
|
+
.with(1).and_return({})
|
38
|
+
allow(@client).to receive(:get_song_url_by_id)
|
39
|
+
.with(1).and_return('http://test/stream?key=something')
|
40
|
+
|
41
|
+
allow(RestClient::Request).to receive(:execute)
|
42
|
+
.and_return(true)
|
43
|
+
|
44
|
+
expect(@downloader.playlist('1'))
|
45
|
+
.to eq(skipped: 0, downloaded: 0)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should download song' do
|
49
|
+
allow(@client).to receive(:get_stream_auth_by_songid)
|
50
|
+
.with(1).and_return({})
|
51
|
+
allow(@client).to receive(:get_song_url_by_id)
|
52
|
+
.with(1).and_return('http://test/stream?key=something')
|
53
|
+
|
54
|
+
allow(RestClient::Request).to receive(:execute)
|
55
|
+
.and_return(true)
|
56
|
+
|
57
|
+
expect(@downloader.song(1))
|
58
|
+
.to eq(skipped: 0, downloaded: 0)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should process response in cli mode' do
|
62
|
+
Dir.mkdir('/tmp')
|
63
|
+
pbar = double
|
64
|
+
allow(pbar).to receive(:progress).and_return(pbar)
|
65
|
+
allow(pbar).to receive(:+).and_return(0)
|
66
|
+
allow(pbar).to receive(:progress=).and_return(0)
|
67
|
+
allow(pbar).to receive(:finish).and_return(true)
|
68
|
+
allow(ProgressBar).to receive(:create)
|
69
|
+
.with(title: 'got-test.mp3', format: '%a |%b>>%i| %p%% %t', total: 1)
|
70
|
+
.and_return(pbar)
|
71
|
+
response = double
|
72
|
+
allow(response).to receive(:[])
|
73
|
+
.with('content-length').and_return('1')
|
74
|
+
allow(response).to receive(:read_body)
|
75
|
+
.and_yield('something')
|
76
|
+
.and_yield('nested')
|
77
|
+
|
78
|
+
expect(@downloader.process_cli_response('/tmp/got-test.mp3')
|
79
|
+
.call(response))
|
80
|
+
.to eq(1)
|
81
|
+
|
82
|
+
expect(File.read('/tmp/got-test.mp3')).to eq('somethingnested')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should process response in cli mode and does not download twice' do
|
86
|
+
Dir.mkdir('/tmp')
|
87
|
+
response = double
|
88
|
+
allow(response).to receive(:[])
|
89
|
+
.with('content-length').and_return('15')
|
90
|
+
allow(response).to receive(:read_body)
|
91
|
+
.and_yield('something')
|
92
|
+
.and_yield('nested')
|
93
|
+
|
94
|
+
File.open('/tmp/got-test.mp3', 'w') do |f|
|
95
|
+
f.write('somethingnested')
|
96
|
+
end
|
97
|
+
|
98
|
+
expect do
|
99
|
+
@downloader.process_cli_response('/tmp/got-test.mp3')
|
100
|
+
.call(response)
|
101
|
+
end.to raise_error(Errors::AlreadyDownloaded,
|
102
|
+
'/tmp/got-test.mp3 already downloaded')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should process response in gui mode' do
|
106
|
+
Dir.mkdir('/tmp')
|
107
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PATH', 0)
|
108
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_VALUE', 1)
|
109
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_TEXT', 2)
|
110
|
+
iter = []
|
111
|
+
iter[0] = '/tmp/got-test.mp3'
|
112
|
+
response = double
|
113
|
+
allow(response).to receive(:[])
|
114
|
+
.with('content-length').and_return('15')
|
115
|
+
allow(response).to receive(:read_body)
|
116
|
+
.and_yield('something')
|
117
|
+
.and_yield('nested')
|
118
|
+
|
119
|
+
expect(@downloader.process_gui_response(iter)
|
120
|
+
.call(response))
|
121
|
+
.to eq('Complete')
|
122
|
+
|
123
|
+
expect(iter[1]).to eq(100)
|
124
|
+
expect(iter[2]).to eq('Complete')
|
125
|
+
|
126
|
+
expect(File.read('/tmp/got-test.mp3')).to eq('somethingnested')
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should process response in gui mode and does not download twice' do
|
130
|
+
Dir.mkdir('/tmp')
|
131
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PATH', 0)
|
132
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_VALUE', 1)
|
133
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_TEXT', 2)
|
134
|
+
iter = []
|
135
|
+
iter[0] = '/tmp/got-test.mp3'
|
136
|
+
response = double
|
137
|
+
allow(response).to receive(:[])
|
138
|
+
.with('content-length').and_return('15')
|
139
|
+
allow(response).to receive(:read_body)
|
140
|
+
.and_yield('something')
|
141
|
+
.and_yield('nested')
|
142
|
+
|
143
|
+
File.open('/tmp/got-test.mp3', 'w') do |f|
|
144
|
+
f.write('somethingnested')
|
145
|
+
end
|
146
|
+
|
147
|
+
expect do
|
148
|
+
@downloader.process_gui_response(iter)
|
149
|
+
.call(response)
|
150
|
+
end.to raise_error(Errors::AlreadyDownloaded,
|
151
|
+
'/tmp/got-test.mp3 already downloaded')
|
152
|
+
|
153
|
+
expect(iter[1]).to eq(100)
|
154
|
+
expect(iter[2]).to eq('Complete')
|
155
|
+
|
156
|
+
expect(File.read('/tmp/got-test.mp3')).to eq('somethingnested')
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should download in gui mode' do
|
160
|
+
@downloader.type = 'gui'
|
161
|
+
Dir.mkdir('/tmp')
|
162
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PATH', 0)
|
163
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_VALUE', 1)
|
164
|
+
stub_const('Widgets::Download::List::Queue::COLUMN_PGBAR_TEXT', 2)
|
165
|
+
iter = []
|
166
|
+
iter[0] = '/tmp/got-test.mp3'
|
167
|
+
|
168
|
+
allow(@client).to receive(:get_stream_auth_by_songid)
|
169
|
+
.with(1).and_return({})
|
170
|
+
allow(@client).to receive(:get_song_url_by_id)
|
171
|
+
.with(1).and_return('http://test/stream?key=something')
|
172
|
+
|
173
|
+
head_return = double
|
174
|
+
allow(head_return).to receive(:headers)
|
175
|
+
.and_return(content_length: nil)
|
176
|
+
|
177
|
+
allow(RestClient).to receive(:head)
|
178
|
+
.and_return(head_return)
|
179
|
+
|
180
|
+
allow(RestClient::Request).to receive(:execute)
|
181
|
+
.and_return(true)
|
182
|
+
|
183
|
+
song = Grooveshark::Song.new('song_id' => 1)
|
184
|
+
expect(@downloader.download(song, iter))
|
185
|
+
.to eq(true)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|