shroom 0.0.3 → 0.0.4
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.
- data/Rakefile +1 -1
- data/lib/sh_album.rb +20 -0
- data/lib/sh_artist.rb +14 -0
- data/lib/sh_browse.rb +7 -6
- data/lib/sh_cover_art.rb +1 -1
- data/lib/sh_database.rb +132 -16
- data/lib/sh_lyrics.rb +1 -1
- data/lib/sh_player.rb +2 -2
- data/lib/sh_queue.rb +51 -0
- data/lib/sh_song.rb +33 -18
- data/lib/sh_util.rb +1 -1
- data/lib/sh_view.rb +13 -6
- metadata +5 -2
data/Rakefile
CHANGED
data/lib/sh_album.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sh
|
2
|
+
class Album
|
3
|
+
attr_writer :artist
|
4
|
+
attr_accessor :title, :mbid, :image_path, :info, :date
|
5
|
+
attr_accessor :db_id
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@songs = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def artist
|
12
|
+
#@artist = $db.artists(:id => @artist.db_id).first if @artist and @artist.db_id
|
13
|
+
return @artist
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
return self.title
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/sh_artist.rb
ADDED
data/lib/sh_browse.rb
CHANGED
@@ -9,13 +9,14 @@ module Sh
|
|
9
9
|
col_artist.set_cell_data_func(ren_artist) do |tvc, cell, model, iter|
|
10
10
|
cell.text = ''
|
11
11
|
data = iter[0]
|
12
|
-
cell.text = data if data.is_a? String
|
13
12
|
if data.is_a? Sh::Song
|
14
13
|
if data.title
|
15
14
|
cell.text = sprintf("%.2d\t%s", data.track_num, data.title)
|
16
15
|
else
|
17
16
|
cell.text = data.path.split('/').last
|
18
17
|
end
|
18
|
+
else
|
19
|
+
cell.text = data.to_s
|
19
20
|
end
|
20
21
|
end
|
21
22
|
@tree.append_column col_artist
|
@@ -104,8 +105,8 @@ module Sh
|
|
104
105
|
def fill_model
|
105
106
|
artist_node = album_node = track_node = nil
|
106
107
|
$db.songs.sort_by {|a| a.to_s}.each do |song|
|
107
|
-
artist = song.artist
|
108
|
-
if not artist_node or artist_node[0] != artist
|
108
|
+
artist = song.artist
|
109
|
+
if not artist_node or artist_node[0].db_id != artist.db_id
|
109
110
|
artist_node = @model.append nil
|
110
111
|
artist_node[0] = artist
|
111
112
|
# Required for proper handling of multiple artists with on album
|
@@ -113,9 +114,9 @@ module Sh
|
|
113
114
|
end
|
114
115
|
artist_node[1] ||= []
|
115
116
|
artist_node[1] << song
|
116
|
-
|
117
|
-
album = song.album
|
118
|
-
if not album_node or album_node[0] != album
|
117
|
+
|
118
|
+
album = song.album
|
119
|
+
if not album_node or album_node[0].db_id != album.db_id
|
119
120
|
album_node = @model.append artist_node
|
120
121
|
album_node[0] = album
|
121
122
|
end
|
data/lib/sh_cover_art.rb
CHANGED
@@ -6,7 +6,7 @@ module Sh
|
|
6
6
|
class CoverArt
|
7
7
|
def CoverArt.get_cover song
|
8
8
|
if $prefs[:cover_art]
|
9
|
-
artist, album = song.artist, song.album
|
9
|
+
artist, album = song.artist.name, song.album.title
|
10
10
|
path = "#{$cover_dir}/#{artist} - #{album}"
|
11
11
|
return path if File.exists? path
|
12
12
|
doc = lastfm("album.getInfo", {:artist => artist, :album => album})
|
data/lib/sh_database.rb
CHANGED
@@ -1,59 +1,150 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'sequel'
|
3
3
|
require 'sh_song'
|
4
|
+
require 'sh_album'
|
5
|
+
require 'sh_artist'
|
4
6
|
|
5
7
|
module Sh
|
6
8
|
class Database
|
7
9
|
def initialize
|
8
10
|
@db = Sequel.sqlite("#{$config_dir}/songs.db")
|
9
11
|
|
12
|
+
@db.create_table :artists do
|
13
|
+
primary_key :id
|
14
|
+
String :mbid
|
15
|
+
String :name
|
16
|
+
String :image_path
|
17
|
+
String :info
|
18
|
+
end unless @db.table_exists? :artists
|
19
|
+
|
20
|
+
@db.create_table :albums do
|
21
|
+
primary_key :id
|
22
|
+
String :mbid
|
23
|
+
String :title
|
24
|
+
String :image_path
|
25
|
+
String :info
|
26
|
+
String :date
|
27
|
+
end unless @db.table_exists? :albums
|
28
|
+
|
10
29
|
@db.create_table :songs do
|
11
30
|
primary_key :id
|
31
|
+
String :mbid
|
12
32
|
String :path
|
13
33
|
String :title
|
14
34
|
String :lyrics
|
15
|
-
String :
|
16
|
-
String :year
|
17
|
-
String :album
|
18
|
-
String :artist
|
35
|
+
String :image_path
|
19
36
|
String :track_num
|
37
|
+
foreign_key :album_id, :albums
|
38
|
+
foreign_key :artist_id, :artists
|
20
39
|
end unless @db.table_exists? :songs
|
21
40
|
end
|
22
41
|
|
23
42
|
def save_song song
|
24
|
-
|
43
|
+
# Get artist info
|
44
|
+
artist = song.artist
|
45
|
+
artist_hash = {
|
46
|
+
:mbid => artist.mbid,
|
47
|
+
:name => artist.name,
|
48
|
+
:image_path => artist.image_path,
|
49
|
+
:info => artist.info
|
50
|
+
}
|
51
|
+
|
52
|
+
# Insert/update artist in database
|
53
|
+
artist_id = nil
|
54
|
+
row_artist = @db[:artists][:name => artist.name]
|
55
|
+
if row_artist
|
56
|
+
artist_hash.each do |k, v|
|
57
|
+
if artist_hash[k] != v
|
58
|
+
@db[:artists].filter(:name => artist.name).update(k => v)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
artist_id = row_artist[:id]
|
62
|
+
else
|
63
|
+
artist_id = @db[:artists].insert(artist_hash)
|
64
|
+
end
|
65
|
+
artist.db_id = artist_id
|
66
|
+
|
67
|
+
# Get album info
|
68
|
+
album = song.album
|
69
|
+
album_hash = {
|
70
|
+
:mbid => album.mbid,
|
71
|
+
:title => album.title,
|
72
|
+
:image_path => album.image_path,
|
73
|
+
:date => album.date,
|
74
|
+
:info => album.info,
|
75
|
+
}
|
76
|
+
|
77
|
+
# Insert/update artist in database
|
78
|
+
album_id = nil
|
79
|
+
row_album = @db[:albums][:title => album.title]
|
80
|
+
if row_album
|
81
|
+
album_hash.each do |k, v|
|
82
|
+
if album_hash[k] != v
|
83
|
+
@db[:albums].filter(:title => album.title).update(k => v)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
album_id = row_album[:id]
|
87
|
+
else
|
88
|
+
album_id = @db[:albums].insert(album_hash)
|
89
|
+
end
|
90
|
+
album.db_id = album_id
|
91
|
+
|
92
|
+
song_hash = {
|
25
93
|
:path => song.path,
|
94
|
+
:mbid => song.mbid,
|
26
95
|
:title => song.title,
|
27
96
|
:lyrics => song.lyrics,
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:artist => song.artist,
|
32
|
-
:track_num => song.track_num
|
97
|
+
:track_num => song.track_num,
|
98
|
+
:album_id => album_id,
|
99
|
+
:artist_id => artist_id
|
33
100
|
}
|
34
101
|
|
35
102
|
song_id = nil
|
36
103
|
row_song = @db[:songs][:path => song.path]
|
37
104
|
if row_song
|
38
|
-
|
105
|
+
song_hash.each do |k, v|
|
39
106
|
if row_song[k] != v
|
40
107
|
@db[:songs].filter(:path => song.path).update(k => v)
|
41
108
|
end
|
42
109
|
end
|
43
110
|
song_id = row_song[:id]
|
44
111
|
else
|
45
|
-
|
46
|
-
song_id = @db[:songs].insert(hash)
|
47
|
-
# Retrieve row to return
|
112
|
+
song_id = @db[:songs].insert(song_hash)
|
48
113
|
row_song = @db[:songs][:id => song_id]
|
49
114
|
end
|
115
|
+
song.db_id = song_id
|
50
116
|
|
51
117
|
return row_song
|
52
118
|
end
|
53
119
|
|
54
|
-
def
|
120
|
+
def artists(params={})
|
121
|
+
artists = []
|
122
|
+
params ||= {}
|
123
|
+
rows = @db[:artists]
|
124
|
+
rows = rows.filter(params) unless params == {}
|
125
|
+
rows.each do |hash|
|
126
|
+
artists << hash_to_artist(hash)
|
127
|
+
end
|
128
|
+
return artists
|
129
|
+
end
|
130
|
+
|
131
|
+
def albums(params={})
|
132
|
+
albums = []
|
133
|
+
params ||= {}
|
134
|
+
rows = @db[:albums]
|
135
|
+
rows = rows.filter(params) unless params == {}
|
136
|
+
rows.each do |hash|
|
137
|
+
albums << hash_to_album(hash)
|
138
|
+
end
|
139
|
+
return albums
|
140
|
+
end
|
141
|
+
|
142
|
+
def songs(params={})
|
55
143
|
songs = []
|
56
|
-
|
144
|
+
params ||= {}
|
145
|
+
rows = @db[:songs]
|
146
|
+
rows = rows.filter(params) unless params == {}
|
147
|
+
rows.each do |hash|
|
57
148
|
songs << hash_to_song(hash)
|
58
149
|
end
|
59
150
|
return songs
|
@@ -80,7 +171,32 @@ module Sh
|
|
80
171
|
assign = (k.to_s + '=').to_sym
|
81
172
|
song.send assign, v if song.respond_to? assign
|
82
173
|
end
|
174
|
+
song.db_id = hash[:id]
|
175
|
+
song.album = hash_to_album(@db[:albums][:id => hash[:album_id]])
|
176
|
+
song.artist = hash_to_artist(@db[:artists][:id => hash[:artist_id]])
|
83
177
|
return song
|
84
178
|
end
|
179
|
+
|
180
|
+
def hash_to_album hash
|
181
|
+
album = Sh::Album.new
|
182
|
+
return album unless hash
|
183
|
+
hash.each do |k, v|
|
184
|
+
assign = (k.to_s + '=').to_sym
|
185
|
+
album.send assign, v if album.respond_to? assign
|
186
|
+
end
|
187
|
+
album.db_id = hash[:id]
|
188
|
+
return album
|
189
|
+
end
|
190
|
+
|
191
|
+
def hash_to_artist hash
|
192
|
+
artist = Sh::Artist.new
|
193
|
+
return artist unless hash
|
194
|
+
hash.each do |k, v|
|
195
|
+
assign = (k.to_s + '=').to_sym
|
196
|
+
artist.send assign, v if artist.respond_to? assign
|
197
|
+
end
|
198
|
+
artist.db_id = hash[:id]
|
199
|
+
return artist
|
200
|
+
end
|
85
201
|
end
|
86
202
|
end
|
data/lib/sh_lyrics.rb
CHANGED
data/lib/sh_player.rb
CHANGED
@@ -90,9 +90,9 @@ module Sh
|
|
90
90
|
@@scrobble_queue << Scrobbler::Scrobble.new(
|
91
91
|
:session_id => auth.session_id,
|
92
92
|
:submission_url => auth.submission_url,
|
93
|
-
:artist => song.artist,
|
93
|
+
:artist => song.artist.name,
|
94
94
|
:track => song.title,
|
95
|
-
:album => song.album,
|
95
|
+
:album => song.album.title,
|
96
96
|
:time => Time.new,
|
97
97
|
:length => duration,
|
98
98
|
:track_number => song.track_num)
|
data/lib/sh_queue.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Sh
|
2
|
+
class Queue
|
3
|
+
def initialize view
|
4
|
+
@view = view
|
5
|
+
sw = ScrolledWindow.new(nil, nil)
|
6
|
+
@widget = sw
|
7
|
+
sw.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
8
|
+
@sto_tabs = ListStore.new(String, Song)
|
9
|
+
lst_tabs = TreeView.new @sto_tabs
|
10
|
+
renderer = CellRendererText.new
|
11
|
+
column = TreeViewColumn.new('Artist',
|
12
|
+
renderer,
|
13
|
+
'text' => 0)
|
14
|
+
lst_tabs.append_column column
|
15
|
+
renderer = CellRendererText.new
|
16
|
+
column = TreeViewColumn.new('Songs', renderer)
|
17
|
+
column.set_cell_data_func(renderer) do |tvc, cell, model, iter|
|
18
|
+
cell.text = ''
|
19
|
+
data = iter[1]
|
20
|
+
if data.title
|
21
|
+
cell.text = sprintf("%.2d\t%s", data.track_num, data.title)
|
22
|
+
else
|
23
|
+
cell.text = data.path.split('/').last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
lst_tabs.append_column column
|
27
|
+
sw.add lst_tabs
|
28
|
+
|
29
|
+
lst_tabs.signal_connect('row_activated') do |widget, path, col|
|
30
|
+
iter = lst_tabs.model.get_iter(path)
|
31
|
+
song = iter[1]
|
32
|
+
view.stop
|
33
|
+
view.queue_pos = path.indices.first
|
34
|
+
view.play
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def update
|
39
|
+
@sto_tabs.clear
|
40
|
+
@view.queue.each do |song|
|
41
|
+
iter = @sto_tabs.append
|
42
|
+
iter[0] = song.artist.name
|
43
|
+
iter[1] = song
|
44
|
+
end if @view.queue
|
45
|
+
end
|
46
|
+
|
47
|
+
def widget
|
48
|
+
return @widget
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/sh_song.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'sh_tagreader'
|
3
|
+
require 'sh_album'
|
4
|
+
require 'sh_artist'
|
3
5
|
require 'earworm'
|
4
6
|
require 'rbrainz'
|
5
7
|
include MusicBrainz
|
@@ -7,17 +9,30 @@ include MusicBrainz
|
|
7
9
|
module Sh
|
8
10
|
class Song
|
9
11
|
attr_reader :path, :mime, :matches
|
10
|
-
|
12
|
+
attr_writer :album, :artist
|
13
|
+
attr_accessor :title, :mbid, :lyrics, :track_num
|
14
|
+
attr_accessor :db_id
|
11
15
|
|
12
16
|
def initialize path
|
13
17
|
@path = File.expand_path path
|
18
|
+
self.artist = Sh::Artist.new
|
19
|
+
self.album = Sh::Album.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def album
|
23
|
+
#@album = $db.albums(:id => @album.db_id).first if @album and @album.db_id
|
24
|
+
return @album
|
25
|
+
end
|
26
|
+
|
27
|
+
def artist
|
28
|
+
#@artist = $db.artists(:id => @artist.db_id).first if @artist and @artist.db_id
|
29
|
+
return @artist
|
14
30
|
end
|
15
31
|
|
16
32
|
def duration
|
17
33
|
@duration ||= Sh::TagReader.read(path)[:duration]
|
18
34
|
end
|
19
35
|
|
20
|
-
|
21
36
|
def lookup!
|
22
37
|
track = lookup_multiple.first
|
23
38
|
if track
|
@@ -25,14 +40,14 @@ module Sh
|
|
25
40
|
track.artist.disambiguation = false
|
26
41
|
# Pull data from response
|
27
42
|
self.title = track.title
|
28
|
-
|
29
|
-
|
43
|
+
artist.name = track.artist.to_s
|
44
|
+
artist.mbid = track.artist.id.to_mbid.uuid
|
30
45
|
rel = track.releases.to_a.first
|
31
|
-
|
32
|
-
|
46
|
+
album.title = rel.title
|
47
|
+
album.mbid = rel.id.to_mbid.uuid
|
33
48
|
# Determine track number
|
34
49
|
query = Webservice::Query.new
|
35
|
-
filter = Webservice::TrackFilter.new(:artistid =>
|
50
|
+
filter = Webservice::TrackFilter.new(:artistid => artist.mbid, :releaseid => album.mbid)
|
36
51
|
tracks = query.get_tracks(filter).entities
|
37
52
|
tracks.to_a.each_with_index do |t, i|
|
38
53
|
self.track_num = i + 1 if t.title == track.title and t.duration == track.duration
|
@@ -52,12 +67,12 @@ module Sh
|
|
52
67
|
end
|
53
68
|
puids = info.puid_list
|
54
69
|
self.title = info.title
|
55
|
-
self.artist = info.artist_name
|
70
|
+
self.artist.name = info.artist_name
|
56
71
|
# Return if no matches are found
|
57
|
-
return if not title or not artist
|
72
|
+
return if not title or not artist.name
|
58
73
|
# Get more information from MusicBrainz
|
59
74
|
query = Webservice::Query.new
|
60
|
-
filter = Webservice::TrackFilter.new(:artist => artist, :title => title, :puid => puids.first)
|
75
|
+
filter = Webservice::TrackFilter.new(:artist => artist.name, :title => title, :puid => puids.first)
|
61
76
|
tracks = query.get_tracks(filter).entities
|
62
77
|
@matches = tracks || []
|
63
78
|
end
|
@@ -67,16 +82,16 @@ module Sh
|
|
67
82
|
Sh::TagReader.read(path) do |data|
|
68
83
|
if overwrite
|
69
84
|
@title = data[:title]
|
70
|
-
|
71
|
-
|
72
|
-
|
85
|
+
artist.name = data[:artist]
|
86
|
+
album.title = data[:album]
|
87
|
+
album.date = data[:year]
|
73
88
|
@track_num = data[:track_num]
|
74
89
|
@duration = data[:duration]
|
75
90
|
else
|
76
91
|
@title ||= data[:title]
|
77
|
-
|
78
|
-
|
79
|
-
|
92
|
+
artist.name ||= data[:artist]
|
93
|
+
album.title ||= data[:album]
|
94
|
+
album.date ||= data[:year]
|
80
95
|
@track_num ||= data[:track_num]
|
81
96
|
@duration ||= data[:duration]
|
82
97
|
end
|
@@ -92,10 +107,10 @@ module Sh
|
|
92
107
|
t = title
|
93
108
|
t = "Unknown" if not t or t.is_binary_data?
|
94
109
|
t.gsub!("<", "<")
|
95
|
-
ar = artist
|
110
|
+
ar = artist.name
|
96
111
|
ar = "Unknown" if not ar or ar.is_binary_data?
|
97
112
|
ar.gsub!("<", "<")
|
98
|
-
al = album
|
113
|
+
al = album.title
|
99
114
|
al = "Unknown" if not al or al.is_binary_data?
|
100
115
|
al.gsub!("<", "<")
|
101
116
|
return "<b>#{t}</b> by <i>#{ar}</i> from <i>#{al}</i>".gsub("&", "&")
|
data/lib/sh_util.rb
CHANGED
data/lib/sh_view.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'sh_browse'
|
2
|
+
require 'sh_queue'
|
2
3
|
require 'sh_lyrics'
|
3
4
|
require 'sh_cover_art'
|
4
5
|
require 'libglade2'
|
@@ -198,7 +199,7 @@ module Sh
|
|
198
199
|
event_box = EventBox.new
|
199
200
|
event_box.add @img_cover
|
200
201
|
event_box.signal_connect("button-press-event") do |w, event|
|
201
|
-
Kelp::ImageDialog.new(@pixbuf, @player.song.album).show if @pixbuf and @player
|
202
|
+
Kelp::ImageDialog.new(@pixbuf, @player.song.album.title).show if @pixbuf and @player
|
202
203
|
end
|
203
204
|
@img_cover.height_request = 150
|
204
205
|
sidebar.pack_start event_box, false, false, 0
|
@@ -210,11 +211,13 @@ module Sh
|
|
210
211
|
scr_lyrics.add @txt_lyrics
|
211
212
|
# Browse area
|
212
213
|
browse = Sh::Browse.new self
|
214
|
+
queue = Sh::Queue.new self
|
213
215
|
lst_tabs.selection.signal_connect('changed') do |selection|
|
214
216
|
frm_content.remove frm_content.child if frm_content.child
|
215
217
|
case selection.selected.path.indices[0]
|
216
218
|
when TAB_QUEUE
|
217
|
-
frm_content.child =
|
219
|
+
frm_content.child = queue.widget
|
220
|
+
queue.update
|
218
221
|
when TAB_BROWSE
|
219
222
|
frm_content.child = browse.widget
|
220
223
|
when TAB_LYRICS
|
@@ -337,25 +340,25 @@ module Sh
|
|
337
340
|
@note = nil
|
338
341
|
if @rnotify
|
339
342
|
# Prepare notification
|
340
|
-
msg = "by <i>#{song.artist}</i> from <i>#{song.album}</i>"
|
343
|
+
msg = "by <i>#{song.artist.name}</i> from <i>#{song.album.title}</i>"
|
341
344
|
@note = Notify::Notification.new(song.title || 'Unknown track', msg, nil, @status_icon)
|
342
345
|
end
|
343
346
|
# Cover art
|
344
347
|
if $prefs[:cover_art]
|
345
348
|
@pixbuf = nil
|
346
|
-
(@pixbuf = Gdk::Pixbuf.new(song.
|
349
|
+
(@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
|
347
350
|
if @pixbuf
|
348
351
|
@note.pixbuf_icon = @pixbuf.scale(48, 48) if @rnotify
|
349
352
|
@img_cover.pixbuf = @pixbuf.scale(132, 132)
|
350
353
|
else
|
351
354
|
@img_cover.pixbuf = nil
|
352
355
|
Thread.new do
|
353
|
-
song.
|
356
|
+
song.album.image_path = Sh::CoverArt.get_cover(song)
|
354
357
|
$db.save_song song
|
355
358
|
# Show cover unless requests have been shuffled
|
356
359
|
if song == @player.song
|
357
360
|
@pixbuf = nil
|
358
|
-
(@pixbuf = Gdk::Pixbuf.new(song.
|
361
|
+
(@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
|
359
362
|
if @pixbuf
|
360
363
|
if @rnotify
|
361
364
|
@note.close
|
@@ -391,6 +394,10 @@ module Sh
|
|
391
394
|
end
|
392
395
|
|
393
396
|
public
|
397
|
+
def queue
|
398
|
+
return @queue
|
399
|
+
end
|
400
|
+
|
394
401
|
def queue=(queue)
|
395
402
|
@queue_pos = 0
|
396
403
|
@queue = queue
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shroom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aiden Nibali
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-26 00:00:00 +10:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -129,7 +129,10 @@ files:
|
|
129
129
|
- lib/sh_global.rb
|
130
130
|
- lib/sh_browse.rb
|
131
131
|
- lib/sh_main.rb
|
132
|
+
- lib/sh_queue.rb
|
133
|
+
- lib/sh_album.rb
|
132
134
|
- lib/sh_song.rb
|
135
|
+
- lib/sh_artist.rb
|
133
136
|
- lib/sh_cover_art.rb
|
134
137
|
- lib/sh_tagreader.rb
|
135
138
|
- lib/sh_lyrics.rb
|