groove-dl 0.2.0 → 0.3.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/.gitignore +1 -0
- data/MANIFEST +4 -8
- data/bin/groove-dl +4 -9
- data/glade/groove-dl.glade +539 -0
- data/groove-dl.gemspec +4 -4
- data/lib/groove-dl/app.rb +16 -43
- data/lib/groove-dl/cli/search.rb +1 -7
- data/lib/groove-dl/displayer.rb +9 -9
- data/lib/groove-dl/downloader.rb +10 -10
- data/lib/groove-dl/version.rb +1 -1
- data/lib/groove-dl/widgets/download.rb +231 -0
- data/lib/groove-dl/widgets/events.rb +23 -0
- data/lib/groove-dl/widgets/search.rb +77 -0
- data/spec/groove-dl/displayer_spec.rb +6 -5
- data/spec/groove-dl/downloader_spec.rb +9 -9
- metadata +10 -14
- data/lib/groove-dl/widgets/download/bar.rb +0 -96
- data/lib/groove-dl/widgets/download/book.rb +0 -77
- data/lib/groove-dl/widgets/download/list/failed.rb +0 -75
- data/lib/groove-dl/widgets/download/list/queue.rb +0 -171
- data/lib/groove-dl/widgets/download/list/success.rb +0 -83
- data/lib/groove-dl/widgets/menu/success.rb +0 -32
- data/lib/groove-dl/widgets/search/bar.rb +0 -74
- data/lib/groove-dl/widgets/search/list.rb +0 -151
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module GrooveDl
|
3
|
+
# Widgets components
|
4
|
+
module Widgets
|
5
|
+
# Search section
|
6
|
+
class Search < Events
|
7
|
+
attr_accessor :data, :store
|
8
|
+
|
9
|
+
TYPE_PLAYLISTS,
|
10
|
+
TYPE_SONGS,
|
11
|
+
TYPE_PLAYLIST_ID = *(0..2).to_a
|
12
|
+
|
13
|
+
COLUMN_CHECKBOX,
|
14
|
+
COLUMN_ID,
|
15
|
+
COLUMN_NAME,
|
16
|
+
COLUMN_AUTHOR,
|
17
|
+
COLUMN_SONG = *(0..4).to_a
|
18
|
+
|
19
|
+
def on_search_entry_activate
|
20
|
+
@app.get_object('search_button').signal_emit('clicked')
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_search_button_clicked
|
24
|
+
type = @app.get_object('search_type').active_id.to_i
|
25
|
+
query = @app.get_object('search_entry').text
|
26
|
+
return if query.empty?
|
27
|
+
|
28
|
+
case type
|
29
|
+
when TYPE_PLAYLISTS
|
30
|
+
results = @client.search('Playlists', query)
|
31
|
+
when TYPE_SONGS
|
32
|
+
results = @client.search('Songs', query)
|
33
|
+
when TYPE_PLAYLIST_ID
|
34
|
+
playlist = Grooveshark::Playlist.new(@client, 'playlist_id' => query)
|
35
|
+
results = playlist.load_songs
|
36
|
+
end
|
37
|
+
|
38
|
+
@data = {}
|
39
|
+
@store = @app.get_object('search_list_store')
|
40
|
+
@store.clear
|
41
|
+
results.each do |element|
|
42
|
+
iter = @store.append
|
43
|
+
iter[COLUMN_CHECKBOX] = false
|
44
|
+
if element.is_a?(Grooveshark::Song)
|
45
|
+
@data[element.id.to_i] = element
|
46
|
+
iter[COLUMN_ID] = element.id.to_i
|
47
|
+
iter[COLUMN_NAME] = element.name
|
48
|
+
iter[COLUMN_AUTHOR] = element.artist
|
49
|
+
iter[COLUMN_SONG] = element.album
|
50
|
+
else
|
51
|
+
@data[element.id.to_i] = element
|
52
|
+
iter[COLUMN_ID] = element.id.to_i.to_i
|
53
|
+
iter[COLUMN_NAME] = element.name
|
54
|
+
iter[COLUMN_AUTHOR] = element.username
|
55
|
+
iter[COLUMN_SONG] = element.num_songs.to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def on_search_list_toggle_toggled(_cell, path_str)
|
61
|
+
path = Gtk::TreePath.new(path_str)
|
62
|
+
iter = @store.get_iter(path)
|
63
|
+
fixed = iter[COLUMN_CHECKBOX]
|
64
|
+
fixed ^= 1
|
65
|
+
iter[COLUMN_CHECKBOX] = fixed
|
66
|
+
end
|
67
|
+
|
68
|
+
def on_search_list_selected_clicked
|
69
|
+
@store.each do |_model, _path, iter|
|
70
|
+
fixed = iter[COLUMN_CHECKBOX]
|
71
|
+
fixed ^= 1
|
72
|
+
iter[COLUMN_CHECKBOX] = fixed
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -42,16 +42,17 @@ module GrooveDl
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'should render songs' do
|
45
|
-
playlist =
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
playlist = Grooveshark::Playlist.new(double,
|
46
|
+
'playlist_id' => 1,
|
47
|
+
'name' => 'Someting',
|
48
|
+
'f_name' => 'GoT',
|
49
|
+
'num_songs' => 1)
|
49
50
|
displayer = Displayer.new([playlist], 'Playlists')
|
50
51
|
|
51
52
|
str = '+----+----------+--------+----------+
|
52
53
|
| Playlists |
|
53
54
|
+----+----------+--------+----------+
|
54
|
-
| Id |
|
55
|
+
| Id | Name | Author | NumSongs |
|
55
56
|
+----+----------+--------+----------+
|
56
57
|
| 1 | Someting | GoT | 1 |
|
57
58
|
+----+----------+--------+----------+'
|
@@ -104,9 +104,9 @@ module GrooveDl
|
|
104
104
|
|
105
105
|
it 'should process response in gui mode' do
|
106
106
|
Dir.mkdir('/tmp')
|
107
|
-
stub_const('Widgets::Download::
|
108
|
-
stub_const('Widgets::Download::
|
109
|
-
stub_const('Widgets::Download::
|
107
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PATH', 0)
|
108
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_VALUE', 1)
|
109
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_TEXT', 2)
|
110
110
|
iter = []
|
111
111
|
iter[0] = '/tmp/got-test.mp3'
|
112
112
|
response = double
|
@@ -128,9 +128,9 @@ module GrooveDl
|
|
128
128
|
|
129
129
|
it 'should process response in gui mode and does not download twice' do
|
130
130
|
Dir.mkdir('/tmp')
|
131
|
-
stub_const('Widgets::Download::
|
132
|
-
stub_const('Widgets::Download::
|
133
|
-
stub_const('Widgets::Download::
|
131
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PATH', 0)
|
132
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_VALUE', 1)
|
133
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_TEXT', 2)
|
134
134
|
iter = []
|
135
135
|
iter[0] = '/tmp/got-test.mp3'
|
136
136
|
response = double
|
@@ -159,9 +159,9 @@ module GrooveDl
|
|
159
159
|
it 'should download in gui mode' do
|
160
160
|
@downloader.type = 'gui'
|
161
161
|
Dir.mkdir('/tmp')
|
162
|
-
stub_const('Widgets::Download::
|
163
|
-
stub_const('Widgets::Download::
|
164
|
-
stub_const('Widgets::Download::
|
162
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PATH', 0)
|
163
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_VALUE', 1)
|
164
|
+
stub_const('Widgets::Download::QUEUE_COLUMN_PGBAR_TEXT', 2)
|
165
165
|
iter = []
|
166
166
|
iter[0] = '/tmp/got-test.mp3'
|
167
167
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groove-dl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pierre Rambaud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|
@@ -164,7 +164,8 @@ dependencies:
|
|
164
164
|
- - ~>
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0.25'
|
167
|
-
description: Grooveshark downloader allow you to
|
167
|
+
description: Grooveshark downloader allow you to search, choose playlists and songs
|
168
|
+
and download them.
|
168
169
|
email: pierre.rambaud86@gmail.com
|
169
170
|
executables:
|
170
171
|
- groove-dl
|
@@ -182,6 +183,7 @@ files:
|
|
182
183
|
- Rakefile
|
183
184
|
- bin/groove-dl
|
184
185
|
- bin/groove-dl-cli
|
186
|
+
- glade/groove-dl.glade
|
185
187
|
- groove-dl.gemspec
|
186
188
|
- lib/groove-dl.rb
|
187
189
|
- lib/groove-dl/app.rb
|
@@ -192,14 +194,9 @@ files:
|
|
192
194
|
- lib/groove-dl/downloader.rb
|
193
195
|
- lib/groove-dl/errors.rb
|
194
196
|
- lib/groove-dl/version.rb
|
195
|
-
- lib/groove-dl/widgets/download
|
196
|
-
- lib/groove-dl/widgets/
|
197
|
-
- lib/groove-dl/widgets/
|
198
|
-
- lib/groove-dl/widgets/download/list/queue.rb
|
199
|
-
- lib/groove-dl/widgets/download/list/success.rb
|
200
|
-
- lib/groove-dl/widgets/menu/success.rb
|
201
|
-
- lib/groove-dl/widgets/search/bar.rb
|
202
|
-
- lib/groove-dl/widgets/search/list.rb
|
197
|
+
- lib/groove-dl/widgets/download.rb
|
198
|
+
- lib/groove-dl/widgets/events.rb
|
199
|
+
- lib/groove-dl/widgets/search.rb
|
203
200
|
- spec/groove-dl/cli_spec.rb
|
204
201
|
- spec/groove-dl/displayer_spec.rb
|
205
202
|
- spec/groove-dl/downloader_spec.rb
|
@@ -219,7 +216,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
219
216
|
requirements:
|
220
217
|
- - '>='
|
221
218
|
- !ruby/object:Gem::Version
|
222
|
-
version: 1.9.
|
219
|
+
version: 1.9.3
|
223
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
221
|
requirements:
|
225
222
|
- - '>='
|
@@ -230,6 +227,5 @@ rubyforge_project:
|
|
230
227
|
rubygems_version: 2.0.14
|
231
228
|
signing_key:
|
232
229
|
specification_version: 4
|
233
|
-
summary:
|
230
|
+
summary: Grooveshark songs downloader.
|
234
231
|
test_files: []
|
235
|
-
has_rdoc:
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module GrooveDl
|
3
|
-
# Widgets components
|
4
|
-
module Widgets
|
5
|
-
# Download section
|
6
|
-
module Download
|
7
|
-
# Download 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
|
-
set_name('download_bar')
|
19
|
-
|
20
|
-
download_box = Gtk::Box.new(:horizontal, 6)
|
21
|
-
|
22
|
-
add_button = Gtk::Button.new(stock_id: Gtk::Stock::ADD)
|
23
|
-
|
24
|
-
add_button.signal_connect('released') do
|
25
|
-
l = window.find_by_name('download_list')
|
26
|
-
l.store.clear
|
27
|
-
search_list = window.find_by_name('search_list')
|
28
|
-
selected = {}
|
29
|
-
column_id = GrooveDl::Widgets::Search::List::COLUMN_ID
|
30
|
-
column_checkbox = GrooveDl::Widgets::Search::List::COLUMN_CHECKBOX
|
31
|
-
search_list.store.each do |_model, _path, iter|
|
32
|
-
next unless iter[column_checkbox]
|
33
|
-
selected[iter[column_id]] = search_list.data[iter[column_id]]
|
34
|
-
end
|
35
|
-
|
36
|
-
l.create_model(selected)
|
37
|
-
end
|
38
|
-
|
39
|
-
download_box.pack_start(add_button,
|
40
|
-
expand: false,
|
41
|
-
fill: true,
|
42
|
-
padding: 5)
|
43
|
-
|
44
|
-
directory_chooser =
|
45
|
-
Gtk::FileChooserButton.new('Select directory',
|
46
|
-
Gtk::FileChooser::Action::SELECT_FOLDER)
|
47
|
-
directory_chooser.filename = Dir.tmpdir
|
48
|
-
directory_chooser.set_name('directory_chooser')
|
49
|
-
download_box.pack_start(directory_chooser,
|
50
|
-
expand: true,
|
51
|
-
fill: true,
|
52
|
-
padding: 5)
|
53
|
-
|
54
|
-
concurrency_entry = Gtk::Entry.new
|
55
|
-
concurrency_entry.set_name('concurrency_entry')
|
56
|
-
concurrency_entry.text = '5'
|
57
|
-
|
58
|
-
concurrency_label = Gtk::Label.new('Concurrency', true)
|
59
|
-
concurrency_label.mnemonic_widget = concurrency_entry
|
60
|
-
|
61
|
-
download_box.pack_start(concurrency_label,
|
62
|
-
expand: false,
|
63
|
-
fill: false,
|
64
|
-
padding: 5)
|
65
|
-
download_box.pack_start(concurrency_entry,
|
66
|
-
expand: false,
|
67
|
-
fill: false,
|
68
|
-
padding: 5)
|
69
|
-
|
70
|
-
concurrency_entry.signal_connect('changed') do
|
71
|
-
value = concurrency_entry.text.to_i
|
72
|
-
concurrency_entry.text = value.to_s unless value == 0
|
73
|
-
end
|
74
|
-
|
75
|
-
download_button = Gtk::Button.new(stock_id: Gtk::Stock::SAVE)
|
76
|
-
|
77
|
-
download_button.signal_connect('released') do
|
78
|
-
download_list = window.find_by_name('download_list')
|
79
|
-
next if download_list.queue.zero?
|
80
|
-
download_button.sensitive = false
|
81
|
-
download_list.download
|
82
|
-
end
|
83
|
-
|
84
|
-
download_box.pack_start(download_button,
|
85
|
-
expand: false,
|
86
|
-
fill: true,
|
87
|
-
padding: 5)
|
88
|
-
|
89
|
-
pack_start(download_box,
|
90
|
-
expand: false,
|
91
|
-
padding: 10)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module GrooveDl
|
3
|
-
# Widgets components
|
4
|
-
module Widgets
|
5
|
-
# Download section
|
6
|
-
module Download
|
7
|
-
# Download book
|
8
|
-
class Book < Gtk::Notebook
|
9
|
-
attr_reader :window
|
10
|
-
|
11
|
-
QUEUE = 'Queue (%d)'
|
12
|
-
SUCCESS = 'Success (%d)'
|
13
|
-
FAILED = 'Failed (%d)'
|
14
|
-
|
15
|
-
##
|
16
|
-
# Initialize widgets
|
17
|
-
#
|
18
|
-
# @param [Grooveshark::Client] client Grooveshark client
|
19
|
-
# @param [Gtk::Window] window Gtk app
|
20
|
-
#
|
21
|
-
def load(client, window)
|
22
|
-
@window = window
|
23
|
-
set_name('download_book')
|
24
|
-
set_tab_pos(Gtk::PositionType::TOP)
|
25
|
-
|
26
|
-
# Download list
|
27
|
-
download_list = Widgets::Download::List::Queue.new(:vertical, 6)
|
28
|
-
download_list.set_name('download_list')
|
29
|
-
download_list.load(client, window)
|
30
|
-
|
31
|
-
@download_label = Gtk::Label.new(QUEUE % 0)
|
32
|
-
@download_label.set_name('download_label')
|
33
|
-
append_page(download_list, @download_label)
|
34
|
-
|
35
|
-
# Success menu
|
36
|
-
menu_success = Widgets::Menu::Success.new
|
37
|
-
menu_success.load(client, window)
|
38
|
-
|
39
|
-
# Success list
|
40
|
-
download_success_list =
|
41
|
-
Widgets::Download::List::Success.new(:vertical, 6)
|
42
|
-
download_success_list.set_name('download_success_list')
|
43
|
-
download_success_list.load(client, window, menu_success)
|
44
|
-
|
45
|
-
@download_success_label = Gtk::Label.new(SUCCESS % 0)
|
46
|
-
@download_success_label.set_name('download_success_label')
|
47
|
-
append_page(download_success_list, @download_success_label)
|
48
|
-
|
49
|
-
# Failed list
|
50
|
-
download_failed_list =
|
51
|
-
Widgets::Download::List::Failed.new(:vertical, 6)
|
52
|
-
download_failed_list.set_name('download_failed_list')
|
53
|
-
download_failed_list.load(client, window)
|
54
|
-
|
55
|
-
@download_failed_label = Gtk::Label.new(FAILED % 0)
|
56
|
-
@download_failed_label.set_name('download_failed_label')
|
57
|
-
append_page(download_failed_list, @download_failed_label)
|
58
|
-
end
|
59
|
-
|
60
|
-
##
|
61
|
-
# Set label for page in notebook element
|
62
|
-
#
|
63
|
-
# @param [String] type Page type
|
64
|
-
# @param [Integer] nb Number of element in this page
|
65
|
-
#
|
66
|
-
def set_label(type, nb)
|
67
|
-
element = @download_label if type == 'QUEUE'
|
68
|
-
element = @download_success_label if type == 'SUCCESS'
|
69
|
-
element = @download_failed_label if type == 'FAILED'
|
70
|
-
|
71
|
-
return if element.nil?
|
72
|
-
element.set_text(Book.const_get(type.upcase) % nb)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
module GrooveDl
|
3
|
-
# Widgets components
|
4
|
-
module Widgets
|
5
|
-
# Download section
|
6
|
-
module Download
|
7
|
-
# List page
|
8
|
-
module List
|
9
|
-
# Failed tree
|
10
|
-
class Failed < Gtk::Box
|
11
|
-
attr_reader :store, :data
|
12
|
-
|
13
|
-
COLUMN_PATH,
|
14
|
-
COLUMN_REASON = *(0..1).to_a
|
15
|
-
|
16
|
-
##
|
17
|
-
# Initialize widgets
|
18
|
-
#
|
19
|
-
# @param [Grooveshark::Client] client Grooveshark client
|
20
|
-
# @param [Gtk::Window] window Gtk app
|
21
|
-
#
|
22
|
-
def load(_client, _window)
|
23
|
-
@data = {}
|
24
|
-
sw = Gtk::ScrolledWindow.new
|
25
|
-
sw.shadow_type = Gtk::ShadowType::ETCHED_IN
|
26
|
-
sw.set_policy(Gtk::PolicyType::AUTOMATIC,
|
27
|
-
Gtk::PolicyType::AUTOMATIC)
|
28
|
-
pack_start(sw, expand: true, fill: true, padding: 0)
|
29
|
-
|
30
|
-
@store = Gtk::ListStore.new(String, String)
|
31
|
-
treeview = Gtk::TreeView.new(@store)
|
32
|
-
treeview.rules_hint = true
|
33
|
-
|
34
|
-
sw.add(treeview)
|
35
|
-
|
36
|
-
add_columns(treeview)
|
37
|
-
end
|
38
|
-
|
39
|
-
##
|
40
|
-
# Append row in list store
|
41
|
-
#
|
42
|
-
# @param [Gtk::TreeIter] i Iterable element
|
43
|
-
# @param [String] reason Why this download have failed
|
44
|
-
#
|
45
|
-
def create_model(i, reason)
|
46
|
-
iter = @store.append
|
47
|
-
path = i[COLUMN_PATH]
|
48
|
-
iter[COLUMN_PATH] = path
|
49
|
-
iter[COLUMN_REASON] = reason
|
50
|
-
end
|
51
|
-
|
52
|
-
##
|
53
|
-
# Add columns on the treeview element
|
54
|
-
#
|
55
|
-
# @param [Gtk::Treeview] treeview Treeview
|
56
|
-
#
|
57
|
-
def add_columns(treeview)
|
58
|
-
renderer = Gtk::CellRendererText.new
|
59
|
-
column = Gtk::TreeViewColumn.new('Path',
|
60
|
-
renderer,
|
61
|
-
'text' => COLUMN_PATH)
|
62
|
-
column.fixed_width = 650
|
63
|
-
treeview.append_column(column)
|
64
|
-
|
65
|
-
renderer = Gtk::CellRendererText.new
|
66
|
-
column = Gtk::TreeViewColumn.new('Reason',
|
67
|
-
renderer,
|
68
|
-
'text' => COLUMN_REASON)
|
69
|
-
treeview.append_column(column)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|