shroom 0.0.11 → 0.0.12
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/README +5 -5
- data/Rakefile +5 -5
- data/bin/shroom +1 -0
- data/lib/{shroom-res → res}/cover_unavailable.png +0 -0
- data/lib/{shroom-res → res}/icon_128x128.png +0 -0
- data/lib/{shroom-res → res}/icon_16x16.png +0 -0
- data/lib/res/license.txt +674 -0
- data/lib/res/plugin.png +0 -0
- data/lib/{shroom-res → res}/plugins/lastfm_scrobbler.rb +0 -0
- data/lib/{shroom-res → res}/shroom.glade +1 -1
- data/lib/res/shroom_resources_signpost +2 -0
- data/lib/sh_actions.rb +14 -16
- data/lib/sh_browse.rb +29 -17
- data/lib/sh_cover_browse.rb +1 -1
- data/lib/sh_database.rb +12 -2
- data/lib/sh_fingerprint.rb +2 -15
- data/lib/sh_global.rb +4 -2
- data/lib/sh_lastfm.rb +64 -0
- data/lib/sh_log.rb +13 -11
- data/lib/sh_main.rb +2 -2
- data/lib/sh_playlist.rb +8 -2
- data/lib/sh_queue.rb +1 -1
- data/lib/sh_tagreader.rb +65 -33
- data/lib/sh_util.rb +17 -4
- data/lib/sh_view.rb +103 -34
- metadata +19 -16
- data/lib/sh_cover_art.rb +0 -26
data/lib/sh_util.rb
CHANGED
@@ -13,11 +13,10 @@ class Object
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def find_in_load_path(file)
|
16
|
-
$:.each do |path|
|
17
|
-
|
18
|
-
return
|
16
|
+
$:.reverse.each do |path|
|
17
|
+
joined = File.join(path, file)
|
18
|
+
return joined if File.exists?(joined)
|
19
19
|
end
|
20
|
-
return nil
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
@@ -50,6 +49,7 @@ module Rest
|
|
50
49
|
end
|
51
50
|
|
52
51
|
require 'digest/md5'
|
52
|
+
require 'cgi'
|
53
53
|
class String
|
54
54
|
def to_md5
|
55
55
|
return (Digest::MD5.new << self).to_s
|
@@ -63,6 +63,19 @@ class String
|
|
63
63
|
return utf8 ? utf8.to_s : unpack('C*').pack('U*')
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
def unescape_html
|
68
|
+
entities = {
|
69
|
+
""" => "\"",
|
70
|
+
"'" => "'",
|
71
|
+
"&" => "&",
|
72
|
+
"<" => "<",
|
73
|
+
">" => ">",
|
74
|
+
" " => " "
|
75
|
+
}
|
76
|
+
|
77
|
+
return CGI.unescapeHTML(self.gsub(/&\w*;/) {|e| entities[e] || e})
|
78
|
+
end
|
66
79
|
end
|
67
80
|
|
68
81
|
module Kelp
|
data/lib/sh_view.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
1
3
|
require 'sh_browse'
|
2
4
|
require 'sh_cover_browse'
|
3
5
|
require 'sh_queue'
|
4
6
|
require 'sh_playlist'
|
5
7
|
require 'sh_lyrics'
|
6
|
-
require '
|
8
|
+
require 'sh_lastfm'
|
7
9
|
require 'sh_mmkeys'
|
8
10
|
require 'sh_actions'
|
9
11
|
require 'gtk2'
|
@@ -25,6 +27,8 @@ module Sh
|
|
25
27
|
def initialize
|
26
28
|
Log.warning 'Instance of View already created!' if @@instance
|
27
29
|
@@instance = self
|
30
|
+
|
31
|
+
GLib.application_name = "Shroom"
|
28
32
|
|
29
33
|
# Initialize GTK
|
30
34
|
Gtk.init
|
@@ -40,11 +44,11 @@ module Sh
|
|
40
44
|
# Prepare progress dialog
|
41
45
|
dialog = Kelp::ProgressDialog.new("Updating database...")
|
42
46
|
cancelled = false
|
43
|
-
dialog.signal_connect('response') { cancelled = true}
|
47
|
+
dialog.signal_connect('response') { cancelled = true }
|
44
48
|
|
45
49
|
# Scan for new songs which are not in the database
|
46
50
|
new_songs = []
|
47
|
-
|
51
|
+
Find.find(Global.prefs[:library_dir]) do |path|
|
48
52
|
ext = File.extname path
|
49
53
|
if Global::SUPPORTED_EXTENSIONS.include? ext
|
50
54
|
new_songs << path if Song.first(:path => path).nil?
|
@@ -73,7 +77,8 @@ module Sh
|
|
73
77
|
Log.info "Failed to add ${path} to database", $!
|
74
78
|
end
|
75
79
|
# Increment progress bar
|
76
|
-
dialog.fraction
|
80
|
+
frac = dialog.fraction + inc
|
81
|
+
dialog.fraction = frac > 1 ? 1 : frac
|
77
82
|
# Make sure that the GUI is updated
|
78
83
|
Kelp.process_events
|
79
84
|
# Stop adding songs if process is cancelled by the user
|
@@ -153,6 +158,7 @@ module Sh
|
|
153
158
|
btn_next.add Image.new Stock::MEDIA_NEXT, IconSize::SMALL_TOOLBAR
|
154
159
|
box_controls.pack_start btn_next, false, true, 0
|
155
160
|
|
161
|
+
# Allow user to seek using the slider
|
156
162
|
seeker.signal_connect('change_value') do |range, scroll, value|
|
157
163
|
if @player
|
158
164
|
seeker.value = value if value < 0.999
|
@@ -162,19 +168,24 @@ module Sh
|
|
162
168
|
seeker.value = 0
|
163
169
|
end
|
164
170
|
end
|
171
|
+
|
165
172
|
GLib::Timeout.add(100) do
|
166
173
|
if @player
|
174
|
+
# Update slider and time label according to position in song
|
167
175
|
pos = @player.position.to_f
|
168
176
|
seeker.value = pos / @player.duration
|
169
177
|
lbl_time.text = format_seconds(pos) + "/" + format_seconds(@player.duration)
|
178
|
+
# Ensure label shows title of currently playing song
|
170
179
|
lbl_song.set_markup @player.song.to_html
|
171
180
|
else
|
181
|
+
# No song is playing or paused, reflect this on display
|
172
182
|
seeker.value = 0
|
173
183
|
lbl_time.text = format_seconds(0) + "/" + format_seconds(0)
|
174
184
|
lbl_song.set_markup "<b>Not playing</b>"
|
175
185
|
end
|
176
186
|
true
|
177
187
|
end
|
188
|
+
|
178
189
|
@btn_play.signal_connect('clicked') do |toggle|
|
179
190
|
if toggle.active?
|
180
191
|
@player.play
|
@@ -224,6 +235,22 @@ module Sh
|
|
224
235
|
event_box.signal_connect('button-press-event') do |w, event|
|
225
236
|
Kelp::ImageDialog.new(@pixbuf, @player.song.album.title).show if @pixbuf and @player
|
226
237
|
end
|
238
|
+
#FIXME
|
239
|
+
Drag.dest_set(event_box, 0, [], 0)
|
240
|
+
event_box.signal_connect('drag-data-received') do |w, dc, x, y, data, info, time|
|
241
|
+
p data
|
242
|
+
dc.drop_finish(true, time)
|
243
|
+
true
|
244
|
+
end
|
245
|
+
event_box.signal_connect('drag-motion') do |w, dc, x, y, time|
|
246
|
+
dc.drag_status(Gdk::DragContext::ACTION_COPY, time)
|
247
|
+
true
|
248
|
+
end
|
249
|
+
event_box.signal_connect('drag-drop') do |w, dc, x, y, time|
|
250
|
+
Drag.get_data(w, dc, dc.targets.last, time)
|
251
|
+
true
|
252
|
+
end
|
253
|
+
# END FIXME
|
227
254
|
@img_cover.height_request = 128
|
228
255
|
@img_cover.width_request = 128
|
229
256
|
bx = HBox.new false, 0
|
@@ -244,7 +271,7 @@ module Sh
|
|
244
271
|
@btn_refresh_lyrics = Button.new Stock::REFRESH
|
245
272
|
box_lyrics.pack_start @btn_refresh_lyrics, false, false
|
246
273
|
queue = Sh::Queue.new self
|
247
|
-
browse = Sh::Browse.new self
|
274
|
+
@browse = Sh::Browse.new self
|
248
275
|
cover_browse = Sh::CoverBrowse.new self
|
249
276
|
playlists = Sh::Playlists.new self
|
250
277
|
lst_tabs.selection.signal_connect('changed') do |selection|
|
@@ -254,7 +281,7 @@ module Sh
|
|
254
281
|
frm_content.child = queue.widget
|
255
282
|
queue.update
|
256
283
|
when TAB_BROWSE
|
257
|
-
frm_content.child = browse.widget
|
284
|
+
frm_content.child = @browse.widget
|
258
285
|
when TAB_LYRICS
|
259
286
|
frm_content.child = box_lyrics
|
260
287
|
when TAB_COVER_BROWSE
|
@@ -309,7 +336,7 @@ module Sh
|
|
309
336
|
['/File/sep1', '<Separator>', nil, nil, lambda {}],
|
310
337
|
['/File/Quit', '<StockItem>', '<control>Q', Stock::QUIT, lambda {Gtk.main_quit}],
|
311
338
|
['/_Edit'],
|
312
|
-
['/Edit/Plugins...', '<
|
339
|
+
['/Edit/Plugins...', '<ImageItem>', nil, Gdk::Pixbuf.new(Global.locate('plugin.png')), lambda {show_plugins}],
|
313
340
|
['/Edit/Preferences...', '<StockItem>', nil, Stock::PREFERENCES, lambda {show_preferences}],
|
314
341
|
['/_Help'],
|
315
342
|
['/Help/About', '<StockItem>', nil, Stock::ABOUT, lambda {show_about}]
|
@@ -442,16 +469,18 @@ module Sh
|
|
442
469
|
end
|
443
470
|
|
444
471
|
def show_about
|
445
|
-
version =
|
472
|
+
version = Gem::Version.new('')
|
446
473
|
Gem::SourceIndex.from_installed_gems.each do |n, spec|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
474
|
+
ver = spec.version
|
475
|
+
version = ver if spec.name == 'shroom' and ver > version
|
476
|
+
end
|
477
|
+
AboutDialog.show(@window, {
|
478
|
+
:version => version.to_s,
|
479
|
+
:logo => Gdk::Pixbuf.new(Global.locate('icon_128x128.png')),
|
480
|
+
:license => open(Global.locate('license.txt')).read,
|
481
|
+
:copyright => "Copyright (C) 2009 Aiden Nibali",
|
482
|
+
:authors => ["Aiden Nibali"]
|
483
|
+
})
|
455
484
|
end
|
456
485
|
|
457
486
|
def prepare_song
|
@@ -508,8 +537,6 @@ module Sh
|
|
508
537
|
|
509
538
|
def show_lyrics song
|
510
539
|
lyrics = song.lyrics || "[Lyrics not found]"
|
511
|
-
# Stupid character encoding stuff
|
512
|
-
lyrics = lyrics.unpack('U*').pack('C*')
|
513
540
|
|
514
541
|
@buf_lyrics.text = ""
|
515
542
|
last = @buf_lyrics.get_iter_at_offset(0)
|
@@ -533,21 +560,54 @@ module Sh
|
|
533
560
|
end
|
534
561
|
|
535
562
|
def update_image song
|
536
|
-
|
537
|
-
|
563
|
+
@img_cover.width_request = 128
|
564
|
+
@img_cover.height_request = 128
|
565
|
+
|
566
|
+
image_path = song.image_path
|
567
|
+
# Use image path for song if valid
|
538
568
|
if image_path and File.size? image_path
|
539
569
|
(@pixbuf = Gdk::Pixbuf.new(image_path)) rescue Exception
|
540
570
|
end
|
571
|
+
|
572
|
+
if @pixbuf.nil?
|
573
|
+
image_path = song.album.image_path
|
574
|
+
# Use image path for album if valid
|
575
|
+
if image_path and File.size? image_path
|
576
|
+
(@pixbuf = Gdk::Pixbuf.new(image_path)) rescue Exception
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
541
580
|
# Lookup cover art on Internet if necessary
|
542
|
-
|
581
|
+
if @pixbuf.nil?
|
543
582
|
@img_cover.pixbuf = Gdk::Pixbuf.new(Global.locate("cover_unavailable.png")).scale(132, 132)
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
583
|
+
# Get album cover art from Last.fm
|
584
|
+
LastFM.get_album_info song.album
|
585
|
+
|
586
|
+
if song.album.image_path
|
587
|
+
(@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
|
588
|
+
end
|
589
|
+
|
590
|
+
unless @pixbuf
|
591
|
+
unless song.artist.image_path
|
592
|
+
LastFM.get_artist_info song.artist
|
593
|
+
end
|
594
|
+
|
595
|
+
if song.artist.image_path
|
596
|
+
begin
|
597
|
+
pixbuf = Gdk::Pixbuf.new(song.artist.image_path)
|
598
|
+
r = pixbuf.width.to_f / pixbuf.height
|
599
|
+
if r > 1
|
600
|
+
pixbuf = pixbuf.scale(132, 132 / r)
|
601
|
+
@img_cover.width_request = 128
|
602
|
+
@img_cover.height_request = 128 / r
|
603
|
+
else
|
604
|
+
pixbuf = pixbuf.scale(132 * r, 132)
|
605
|
+
@img_cover.width_request = 128 * r
|
606
|
+
@img_cover.height_request = 128
|
607
|
+
end
|
608
|
+
@img_cover.pixbuf = pixbuf
|
609
|
+
rescue Exception
|
610
|
+
end
|
551
611
|
end
|
552
612
|
end
|
553
613
|
end
|
@@ -579,8 +639,10 @@ module Sh
|
|
579
639
|
# Get color by shrinking image to 1px and extracting RGB values
|
580
640
|
color = pixbuf.scale(1, 1, Gdk::Pixbuf::INTERP_NEAREST).pixels.unpack("CCC")
|
581
641
|
# Convert colour from values between 0 and 255 to values between
|
582
|
-
# 0 and 65535.
|
583
|
-
color.map! {|n| n *
|
642
|
+
# 0 and 65535 (257 = 65535 / 255).
|
643
|
+
color.map! {|n| n * 257}
|
644
|
+
# Ensure that the colour isn't too dark
|
645
|
+
color.map! {|n| n < 20 ? n + 20 : n}
|
584
646
|
|
585
647
|
# If the color has changed, regenerate plasma background
|
586
648
|
if color != @plasma_color
|
@@ -593,22 +655,29 @@ module Sh
|
|
593
655
|
end
|
594
656
|
end
|
595
657
|
rescue
|
596
|
-
|
658
|
+
Log.info "Plasma generation failed", $!
|
597
659
|
end
|
598
660
|
end
|
599
661
|
|
600
662
|
public
|
663
|
+
def update_song song
|
664
|
+
@browse.update_song(song) do |s|
|
665
|
+
new_song = yield s
|
666
|
+
song = new_song if new_song.is_a? Song
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
601
670
|
def queue
|
602
671
|
return @queue
|
603
672
|
end
|
604
673
|
|
605
|
-
def queue=
|
606
|
-
@queue_pos =
|
674
|
+
def set_queue queue, pos=0
|
675
|
+
@queue_pos = pos
|
607
676
|
@queue = queue
|
608
677
|
prepare_song
|
609
678
|
end
|
610
679
|
|
611
|
-
def
|
680
|
+
def set_queue_pos pos
|
612
681
|
@queue_pos = pos
|
613
682
|
prepare_song
|
614
683
|
end
|
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.12
|
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-
|
12
|
+
date: 2009-11-24 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -33,14 +33,14 @@ dependencies:
|
|
33
33
|
version: 0.3.3
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name: ruby-
|
36
|
+
name: ruby-ogg
|
37
37
|
type: :runtime
|
38
38
|
version_requirement:
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.0.1
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: flacinfo-rb
|
@@ -125,25 +125,28 @@ files:
|
|
125
125
|
- lib/sh_actions.rb
|
126
126
|
- lib/sh_plugin.rb
|
127
127
|
- lib/sh_log.rb
|
128
|
-
- lib/sh_cover_art.rb
|
129
128
|
- lib/sh_tagreader.rb
|
130
129
|
- lib/sh_plasma.rb
|
131
130
|
- lib/sh_lyrics.rb
|
132
131
|
- lib/sh_database.rb
|
133
132
|
- lib/sh_util.rb
|
134
133
|
- lib/sh_mmkeys.rb
|
134
|
+
- lib/res/shroom_resources_signpost
|
135
|
+
- lib/res/cover_unavailable.png
|
136
|
+
- lib/res/license.txt
|
137
|
+
- lib/res/icon_16x16.png
|
138
|
+
- lib/res/plugins/lastfm_scrobbler.rb
|
139
|
+
- lib/res/icon_128x128.png
|
140
|
+
- lib/res/shroom.glade
|
141
|
+
- lib/res/plugin.png
|
135
142
|
- lib/sh_fingerprint.rb
|
136
|
-
- lib/
|
137
|
-
- lib/shroom-res/cover_unavailable.png
|
138
|
-
- lib/shroom-res/icon_16x16.png
|
139
|
-
- lib/shroom-res/plugins
|
140
|
-
- lib/shroom-res/plugins/lastfm_scrobbler.rb
|
141
|
-
- lib/shroom-res/icon_128x128.png
|
142
|
-
- lib/shroom-res/shroom.glade
|
143
|
+
- lib/sh_lastfm.rb
|
143
144
|
- lib/sh_player.rb
|
144
145
|
- lib/sh_view.rb
|
145
146
|
has_rdoc: true
|
146
147
|
homepage: http://shroom.rubyforge.org
|
148
|
+
licenses: []
|
149
|
+
|
147
150
|
post_install_message:
|
148
151
|
rdoc_options: []
|
149
152
|
|
@@ -162,20 +165,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
165
|
version: "0"
|
163
166
|
version:
|
164
167
|
requirements:
|
165
|
-
- rake
|
166
168
|
- libwxgtk2.8-0
|
167
|
-
-
|
169
|
+
- libgtk2-ruby
|
168
170
|
- libglade2-ruby
|
169
171
|
- libsqlite3-ruby
|
170
172
|
- libopenssl-ruby
|
173
|
+
- libofa0
|
171
174
|
- ruby-dev
|
172
175
|
- libmp3lame-dev
|
173
176
|
- libvorbis-dev
|
174
177
|
- build-essential
|
175
178
|
rubyforge_project: shroom
|
176
|
-
rubygems_version: 1.3.
|
179
|
+
rubygems_version: 1.3.5
|
177
180
|
signing_key:
|
178
|
-
specification_version:
|
181
|
+
specification_version: 3
|
179
182
|
summary: Shroom is a music player and organizer
|
180
183
|
test_files: []
|
181
184
|
|
data/lib/sh_cover_art.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'rexml/document'
|
2
|
-
|
3
|
-
module Sh
|
4
|
-
class CoverArt
|
5
|
-
def self.get_cover song
|
6
|
-
artist, album = song.artist.name, song.album.title
|
7
|
-
if artist and album
|
8
|
-
@lastfm_rest ||= Rest::Get.new("http://ws.audioscrobbler.com/2.0",
|
9
|
-
:api_key => Sh::KEYS[:lastfm], :method => "album.getInfo")
|
10
|
-
path = "#{Global::PATHS[:cover_dir]}/#{artist.to_md5}_#{album.to_md5}"
|
11
|
-
if File.exists? path and File.size?(path) > 0
|
12
|
-
return path
|
13
|
-
else
|
14
|
-
doc = REXML::Document.new(@lastfm_rest[:artist => artist, :album => album])
|
15
|
-
img_url = REXML::XPath.first(doc, '//image[@size="extralarge"]').text
|
16
|
-
if img_url
|
17
|
-
open(path, 'w') do |output|
|
18
|
-
output << open(img_url).read
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
return path if File.exists? path
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|