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