shroom 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -4
- data/lib/sh_browse.rb +12 -0
- data/lib/sh_cover_art.rb +10 -7
- data/lib/sh_database.rb +73 -68
- data/lib/sh_global.rb +0 -13
- data/lib/sh_lyrics.rb +1 -1
- data/lib/sh_plasma.rb +100 -0
- data/lib/sh_queue.rb +1 -1
- data/lib/sh_song.rb +1 -1
- data/lib/sh_tagreader.rb +15 -15
- data/lib/sh_util.rb +13 -3
- data/lib/sh_view.rb +70 -25
- metadata +7 -5
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ require 'rake/testtask'
|
|
7
7
|
|
8
8
|
spec = Gem::Specification.new do |s|
|
9
9
|
s.name = 'shroom'
|
10
|
-
s.version = '0.0.
|
10
|
+
s.version = '0.0.8'
|
11
11
|
s.has_rdoc = true
|
12
12
|
s.extra_rdoc_files = ['README', 'LICENSE']
|
13
13
|
s.summary = 'Shroom is a music player and organizer'
|
@@ -27,16 +27,17 @@ spec = Gem::Specification.new do |s|
|
|
27
27
|
s.add_dependency('scrobbler', '>= 0.2.3')
|
28
28
|
s.add_dependency('shared-mime-info', '>= 0.1')
|
29
29
|
s.requirements << 'rake'
|
30
|
+
s.requirements << 'libwxgtk2.8-0'
|
30
31
|
s.requirements << 'libgnome2-ruby'
|
31
|
-
s.requirements << 'libgtk-mozembed-ruby'
|
32
|
-
s.requirements << 'libsqlite3-ruby'
|
33
32
|
s.requirements << 'libglade2-ruby'
|
33
|
+
s.requirements << 'libgtkhtml2-ruby'
|
34
|
+
s.requirements << 'libsqlite3-ruby'
|
34
35
|
# Requirements for icanhasaudio
|
35
36
|
s.requirements << 'ruby-dev'
|
36
37
|
s.requirements << 'libopenssl-ruby'
|
37
38
|
s.requirements << 'libmp3lame-dev'
|
38
39
|
s.requirements << 'libvorbis-dev'
|
39
|
-
s.requirements << '
|
40
|
+
s.requirements << 'build-essential'
|
40
41
|
s.executables = ['shroom']
|
41
42
|
s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
|
42
43
|
s.require_path = "lib"
|
data/lib/sh_browse.rb
CHANGED
@@ -55,6 +55,18 @@ module Sh
|
|
55
55
|
song = data
|
56
56
|
menu = Menu.new
|
57
57
|
|
58
|
+
pbtn_add_to_queue = ImageMenuItem.new Stock::ADD
|
59
|
+
menu.append pbtn_add_to_queue
|
60
|
+
pbtn_add_to_queue.signal_connect('activate') do |widget|
|
61
|
+
queue = view.queue
|
62
|
+
if queue
|
63
|
+
queue << song
|
64
|
+
else
|
65
|
+
view.queue = [song]
|
66
|
+
view.queue_pos = 0
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
58
70
|
pbtn_lookup = MenuItem.new 'Lookup metadata automatically'
|
59
71
|
menu.append pbtn_lookup
|
60
72
|
pbtn_lookup.signal_connect('activate') do |widget|
|
data/lib/sh_cover_art.rb
CHANGED
@@ -5,29 +5,32 @@ require 'cgi'
|
|
5
5
|
module Sh
|
6
6
|
class CoverArt
|
7
7
|
def CoverArt.get_cover song
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
return path if File.exists? path
|
8
|
+
artist, album = song.artist.name, song.album.title
|
9
|
+
path = "#{$cover_dir}/#{artist.to_md5}_#{album.to_md5}"
|
10
|
+
if Ping.pingecho("audioscrobbler.com", 5) and not File.exists?(path)
|
12
11
|
doc = lastfm("album.getInfo", {:artist => artist, :album => album})
|
13
12
|
img_url = REXML::XPath.first(doc, '//image[@size="extralarge"]').text
|
13
|
+
puts doc
|
14
14
|
if img_url
|
15
15
|
open(path, 'w') do |output|
|
16
16
|
open(img_url) do |input|
|
17
17
|
output << input.read
|
18
18
|
end
|
19
19
|
end
|
20
|
-
return path
|
21
20
|
end
|
22
21
|
end
|
23
|
-
|
22
|
+
if File.exists? path
|
23
|
+
return path
|
24
|
+
else
|
25
|
+
return nil
|
26
|
+
end
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
27
30
|
def CoverArt.lastfm(method, arg_map = {}.freeze)
|
28
31
|
args = arg_map.collect { |k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}"}.join('&')
|
29
32
|
url = "http://ws.audioscrobbler.com/2.0/?method=#{method}&api_key=#{Sh::KEYS[:lastfm]}&#{args}"
|
30
|
-
|
33
|
+
return REXML::Document.new(open(url).read)
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
data/lib/sh_database.rb
CHANGED
@@ -40,81 +40,86 @@ module Sh
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def save_song song
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
43
|
+
begin
|
44
|
+
# Get artist info
|
45
|
+
artist = song.artist
|
46
|
+
artist_hash = {
|
47
|
+
:mbid => artist.mbid,
|
48
|
+
:name => artist.name,
|
49
|
+
:image_path => artist.image_path,
|
50
|
+
:info => artist.info
|
51
|
+
}
|
52
|
+
|
53
|
+
# Insert/update artist in database
|
54
|
+
artist_id = nil
|
55
|
+
row_artist = @db[:artists][:name => artist.name]
|
56
|
+
if row_artist
|
57
|
+
artist_hash.each do |k, v|
|
58
|
+
if row_artist[k] != v
|
59
|
+
@db[:artists].filter(:name => artist.name).update(k => v)
|
60
|
+
end
|
59
61
|
end
|
62
|
+
artist_id = row_artist[:id]
|
63
|
+
else
|
64
|
+
artist_id = @db[:artists].insert(artist_hash)
|
60
65
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
album_hash.each do |k, v|
|
82
|
-
if album_hash[k] != v
|
83
|
-
@db[:albums].filter(:title => album.title).update(k => v)
|
66
|
+
artist.db_id = artist_id
|
67
|
+
|
68
|
+
# Get album info
|
69
|
+
album = song.album
|
70
|
+
album_hash = {
|
71
|
+
:mbid => album.mbid,
|
72
|
+
:title => album.title,
|
73
|
+
:image_path => album.image_path,
|
74
|
+
:date => album.date,
|
75
|
+
:info => album.info,
|
76
|
+
}
|
77
|
+
|
78
|
+
# Insert/update artist in database
|
79
|
+
album_id = nil
|
80
|
+
row_album = @db[:albums][:title => album.title]
|
81
|
+
if row_album
|
82
|
+
album_hash.each do |k, v|
|
83
|
+
if row_album[k] != v
|
84
|
+
@db[:albums].filter(:title => album.title).update(k => v)
|
85
|
+
end
|
84
86
|
end
|
87
|
+
album_id = row_album[:id]
|
88
|
+
else
|
89
|
+
album_id = @db[:albums].insert(album_hash)
|
85
90
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
:
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
song_hash.each do |k, v|
|
106
|
-
if row_song[k] != v
|
107
|
-
@db[:songs].filter(:path => song.path).update(k => v)
|
91
|
+
album.db_id = album_id
|
92
|
+
|
93
|
+
song_hash = {
|
94
|
+
:path => song.path,
|
95
|
+
:mbid => song.mbid,
|
96
|
+
:title => song.title,
|
97
|
+
:lyrics => song.lyrics,
|
98
|
+
:track_num => song.track_num,
|
99
|
+
:album_id => album_id,
|
100
|
+
:artist_id => artist_id
|
101
|
+
}
|
102
|
+
|
103
|
+
song_id = nil
|
104
|
+
row_song = @db[:songs][:path => song.path]
|
105
|
+
if row_song
|
106
|
+
song_hash.each do |k, v|
|
107
|
+
if row_song[k] != v
|
108
|
+
@db[:songs].filter(:path => song.path).update(k => v)
|
109
|
+
end
|
108
110
|
end
|
111
|
+
song_id = row_song[:id]
|
112
|
+
else
|
113
|
+
song_id = @db[:songs].insert(song_hash)
|
114
|
+
row_song = @db[:songs][:id => song_id]
|
109
115
|
end
|
110
|
-
|
111
|
-
else
|
112
|
-
song_id = @db[:songs].insert(song_hash)
|
113
|
-
row_song = @db[:songs][:id => song_id]
|
114
|
-
end
|
115
|
-
song.db_id = song_id
|
116
|
+
song.db_id = song_id
|
116
117
|
|
117
|
-
|
118
|
+
return row_song
|
119
|
+
rescue
|
120
|
+
puts "Couldn's save song in database: " + song.path
|
121
|
+
return
|
122
|
+
end
|
118
123
|
end
|
119
124
|
|
120
125
|
def artists(params={})
|
data/lib/sh_global.rb
CHANGED
@@ -15,10 +15,6 @@ module Sh
|
|
15
15
|
GLADE = {}
|
16
16
|
|
17
17
|
def self.init
|
18
|
-
Thread.new do
|
19
|
-
recheck_internet
|
20
|
-
end
|
21
|
-
|
22
18
|
# Won't work on Windows
|
23
19
|
$home = ENV['HOME']
|
24
20
|
$config_dir = "#{$home}/.shroom"
|
@@ -45,15 +41,6 @@ module Sh
|
|
45
41
|
load_plugins
|
46
42
|
end
|
47
43
|
|
48
|
-
def self.recheck_internet(timeout=5)
|
49
|
-
# Ping Google
|
50
|
-
@@internet = Ping.pingecho("64.233.187.99", timeout, 80)
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.internet?
|
54
|
-
return @@internet
|
55
|
-
end
|
56
|
-
|
57
44
|
def self.locate(file)
|
58
45
|
find_in_load_path("shroom-res/#{file}") || "shroom-res/#{file}"
|
59
46
|
end
|
data/lib/sh_lyrics.rb
CHANGED
@@ -20,7 +20,7 @@ module Sh
|
|
20
20
|
"&song=#{CGI.escape(title)}"
|
21
21
|
doc = Hpricot(open(url))
|
22
22
|
page_url = (doc/'url').inner_text
|
23
|
-
page_name = page_url.match(
|
23
|
+
page_name = (page_url.match(/:([^:]*)$/) || ":").to_s[1..-1]
|
24
24
|
page_name = CGI.unescape(page_name)
|
25
25
|
page_name.freeze
|
26
26
|
unless page_url.end_with? ';action=edit'
|
data/lib/sh_plasma.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
module Sh
|
2
|
+
class Plasma
|
3
|
+
attr_reader :width, :height, :grid_size
|
4
|
+
|
5
|
+
def initialize width, height, grid_size = 5
|
6
|
+
@width, @height = width.to_f, height.to_f
|
7
|
+
@grid_size = grid_size.to_f
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate_map
|
11
|
+
map = [[rand, rand, nil],[rand, rand, nil], nil]
|
12
|
+
w = @width / 2
|
13
|
+
h = @height / 2
|
14
|
+
|
15
|
+
while w > @grid_size or h > @grid_size
|
16
|
+
w /= 2
|
17
|
+
h /= 2
|
18
|
+
|
19
|
+
new_map = []
|
20
|
+
map.each_cons(2) do |row, next_row|
|
21
|
+
next_row ||= map.first
|
22
|
+
|
23
|
+
r = []
|
24
|
+
row.each_cons(2) do |v, nv|
|
25
|
+
nv ||= row.first
|
26
|
+
r << v
|
27
|
+
r << (v + nv) / 2
|
28
|
+
end
|
29
|
+
r << nil
|
30
|
+
new_map << r
|
31
|
+
|
32
|
+
r = []
|
33
|
+
(row.size - 1).times do |x|
|
34
|
+
r << (row[x] + next_row[x]) / 2
|
35
|
+
midpoint = nil
|
36
|
+
if row[x+1]
|
37
|
+
midpoint = (row[x] + next_row[x] + row[x+1] + next_row[x+1]) / 4
|
38
|
+
else
|
39
|
+
midpoint = (row[x] + next_row[x] + row.first + next_row.first) / 4
|
40
|
+
end
|
41
|
+
midpoint += displace(w + h)
|
42
|
+
midpoint = midpoint > 1 ? 1 : midpoint < 0 ? 0 : midpoint
|
43
|
+
r << midpoint
|
44
|
+
end
|
45
|
+
r << nil
|
46
|
+
new_map << r
|
47
|
+
end
|
48
|
+
|
49
|
+
map = new_map << nil
|
50
|
+
end
|
51
|
+
# Get rid of all the nil values introduced as part of the processing
|
52
|
+
map = map[0..-2].collect {|r| r[0..-2]}
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_pixmap color1=[0, 0, 0], color2=[65535, 65535, 65535]
|
56
|
+
if try_require 'gtk2'
|
57
|
+
depth = 24
|
58
|
+
begin
|
59
|
+
depth = Gdk::Window.default_root_window.geometry.last
|
60
|
+
rescue
|
61
|
+
depth = 24
|
62
|
+
end
|
63
|
+
pixmap = Gdk::Pixmap.new(nil, @width, @height, depth)
|
64
|
+
gc = Gdk::GC.new(pixmap)
|
65
|
+
map = generate_map
|
66
|
+
h = @height / map.size
|
67
|
+
w = @width / map.first.size
|
68
|
+
x = y = 0
|
69
|
+
map.each do |row|
|
70
|
+
row.each do |v|
|
71
|
+
r1, g1, b1 = *color1
|
72
|
+
r2, g2, b2 = *color2
|
73
|
+
# Simulate alpha transparency overlay of one colour over the other
|
74
|
+
red = v*r1+(1-v)*r2
|
75
|
+
green = v*g1+(1-v)*g2
|
76
|
+
blue = v*b1+(1-v)*b2
|
77
|
+
# Draw rectangle in pixmap
|
78
|
+
color = Gdk::Color.new red, green, blue
|
79
|
+
gc.rgb_fg_color = color
|
80
|
+
pixmap.draw_rectangle(gc, true, x, y, @grid_size, @grid_size)
|
81
|
+
# Increment horizontal position
|
82
|
+
x += w
|
83
|
+
end
|
84
|
+
x = 0
|
85
|
+
y += h
|
86
|
+
end
|
87
|
+
return pixmap
|
88
|
+
else
|
89
|
+
raise "GTK is required to create a pixmap!"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
# Create random displacement value
|
95
|
+
def displace num
|
96
|
+
max = num / (@width + @height) * 3
|
97
|
+
return (rand - 0.5) * max
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/sh_queue.rb
CHANGED
@@ -13,7 +13,7 @@ module Sh
|
|
13
13
|
'text' => 0)
|
14
14
|
lst_tabs.append_column column
|
15
15
|
renderer = CellRendererText.new
|
16
|
-
column = TreeViewColumn.new('
|
16
|
+
column = TreeViewColumn.new('Song', renderer)
|
17
17
|
column.set_cell_data_func(renderer) do |tvc, cell, model, iter|
|
18
18
|
cell.text = ''
|
19
19
|
data = iter[1]
|
data/lib/sh_song.rb
CHANGED
data/lib/sh_tagreader.rb
CHANGED
@@ -45,9 +45,9 @@ module Sh
|
|
45
45
|
if try_require 'mp3info'
|
46
46
|
Mp3Info.open path do |mp3|
|
47
47
|
t = mp3.tag
|
48
|
-
metadata[:title] = t.title.
|
49
|
-
metadata[:artist] = t.artist.
|
50
|
-
metadata[:album] = t.album.
|
48
|
+
metadata[:title] = t.title.to_u if t.title
|
49
|
+
metadata[:artist] = t.artist.to_u if t.artist
|
50
|
+
metadata[:album] = t.album.to_u if t.album
|
51
51
|
metadata[:year] = t.year.to_i
|
52
52
|
metadata[:track_num] = t.tracknum.to_i
|
53
53
|
metadata[:duration] = mp3.length
|
@@ -63,9 +63,9 @@ module Sh
|
|
63
63
|
metadata = {}
|
64
64
|
if try_require 'mp4info'
|
65
65
|
mp4 = MP4Info.open path
|
66
|
-
metadata[:title] = mp4.NAM.
|
67
|
-
metadata[:artist] = mp4.ART.
|
68
|
-
metadata[:album] = mp4.ALB.
|
66
|
+
metadata[:title] = mp4.NAM.to_u if mp4.NAM
|
67
|
+
metadata[:artist] = mp4.ART.to_u if mp4.ART
|
68
|
+
metadata[:album] = mp4.ALB.to_u if mp4.ALB
|
69
69
|
metadata[:year] = mp4.DAY.to_i
|
70
70
|
metadata[:track_num] = mp4.TRKN.first.to_i
|
71
71
|
metadata[:duration] = mp4.SECS
|
@@ -81,9 +81,9 @@ module Sh
|
|
81
81
|
if try_require 'ogginfo'
|
82
82
|
OggInfo.open path do |ogg|
|
83
83
|
t = ogg.tag
|
84
|
-
metadata[:title] = t.title.
|
85
|
-
metadata[:artist] = t.artist.
|
86
|
-
metadata[:album] = t.album.
|
84
|
+
metadata[:title] = t.title.to_u if t.title
|
85
|
+
metadata[:artist] = t.artist.to_u if t.artist
|
86
|
+
metadata[:album] = t.album.to_u if t.album
|
87
87
|
metadata[:year] = t.date.to_i
|
88
88
|
metadata[:track_num] = t.tracknumber.to_i
|
89
89
|
metadata[:duration] = ogg.length
|
@@ -106,11 +106,11 @@ module Sh
|
|
106
106
|
value = nil if value == '' or value.is_binary_data?
|
107
107
|
case key
|
108
108
|
when 'title'
|
109
|
-
metadata[:title] = value.
|
109
|
+
metadata[:title] = value.to_u if value
|
110
110
|
when 'artist'
|
111
|
-
metadata[:artist] = value.
|
111
|
+
metadata[:artist] = value.to_u if value
|
112
112
|
when 'album'
|
113
|
-
metadata[:album] = value.
|
113
|
+
metadata[:album] = value.to_u if value
|
114
114
|
when 'year'
|
115
115
|
metadata[:year] = value.to_i
|
116
116
|
when 'tracknumber'
|
@@ -133,11 +133,11 @@ module Sh
|
|
133
133
|
value = nil if value == '' or value.is_binary_data?
|
134
134
|
case key
|
135
135
|
when 'title'
|
136
|
-
metadata[:title] = value.
|
136
|
+
metadata[:title] = value.to_u if value
|
137
137
|
when 'author'
|
138
|
-
metadata[:artist] = value.
|
138
|
+
metadata[:artist] = value.to_u if value
|
139
139
|
when 'albumtitle'
|
140
|
-
metadata[:album] = value.
|
140
|
+
metadata[:album] = value.to_u if value
|
141
141
|
when 'year'
|
142
142
|
metadata[:year] = value.to_i
|
143
143
|
when 'tracknumber'
|
data/lib/sh_util.rb
CHANGED
@@ -27,9 +27,16 @@ class String
|
|
27
27
|
return (Digest::MD5.new << self).to_s
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def to_u
|
31
31
|
begin
|
32
|
-
|
32
|
+
raise "Binary data!" if is_binary_data?
|
33
|
+
utf8 = isutf8
|
34
|
+
if utf8
|
35
|
+
utf8 = utf8.to_s
|
36
|
+
else
|
37
|
+
utf8 = unpack('C*').pack('U*')
|
38
|
+
end
|
39
|
+
return utf8
|
33
40
|
rescue Exception
|
34
41
|
return nil
|
35
42
|
end
|
@@ -67,7 +74,9 @@ class StringMatcher
|
|
67
74
|
end
|
68
75
|
|
69
76
|
def compare_ignore_case
|
70
|
-
|
77
|
+
@str1 = @str1.upcase
|
78
|
+
@str2 = @str2.upcase
|
79
|
+
return compare
|
71
80
|
end
|
72
81
|
|
73
82
|
private
|
@@ -115,6 +124,7 @@ module Kelp
|
|
115
124
|
Dialog::MODAL,
|
116
125
|
[Stock::CANCEL, Dialog::RESPONSE_NONE])
|
117
126
|
@lbl_message = Label.new("Please wait")
|
127
|
+
@lbl_message.ellipsize = Pango::Layout::ELLIPSIZE_START
|
118
128
|
vbox.pack_start @lbl_message, false, false, 8
|
119
129
|
@progress = ProgressBar.new
|
120
130
|
vbox.pack_start @progress, false, false, 8
|
data/lib/sh_view.rb
CHANGED
@@ -50,14 +50,18 @@ module Sh
|
|
50
50
|
inc = 1 / new_songs.length.to_f
|
51
51
|
# Enter new songs in database
|
52
52
|
new_songs.each do |song|
|
53
|
-
# Show
|
54
|
-
dialog.message =
|
53
|
+
# Show path to song in the dialog
|
54
|
+
dialog.message = song.path
|
55
55
|
puts "Adding: #{song.path}"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
begin
|
57
|
+
# Read metadata from song tags
|
58
|
+
song.read_tags!
|
59
|
+
# Save song to the database
|
60
|
+
$db.save_song song
|
61
|
+
# Increment progress bar
|
62
|
+
rescue
|
63
|
+
puts "Couldn't add song. Reason: #{$!}"
|
64
|
+
end
|
61
65
|
dialog.fraction += inc
|
62
66
|
# Make sure that the GUI is updated
|
63
67
|
Kelp.process_events
|
@@ -113,6 +117,7 @@ module Sh
|
|
113
117
|
vpaned.pack_start vbox, false, true, 8
|
114
118
|
hbox = HBox.new
|
115
119
|
lbl_song = Label.new
|
120
|
+
lbl_song.ellipsize = Pango::Layout::ELLIPSIZE_END
|
116
121
|
hbox.add lbl_song
|
117
122
|
lbl_time = Label.new(format_seconds(0) + "/" + format_seconds(0))
|
118
123
|
hbox.pack_start lbl_time, false, false, 8
|
@@ -177,12 +182,12 @@ module Sh
|
|
177
182
|
hpaned.add2 frm_content
|
178
183
|
|
179
184
|
# === Sidebar ===
|
185
|
+
sidebar = VBox.new(false, 0)
|
186
|
+
hpaned.add1 sidebar
|
180
187
|
sw = ScrolledWindow.new(nil, nil)
|
181
|
-
hpaned.add1 sw
|
182
188
|
sw.set_policy(POLICY_AUTOMATIC, POLICY_NEVER)
|
183
189
|
sw.width_request = 150
|
184
|
-
sidebar
|
185
|
-
sw.add_with_viewport sidebar
|
190
|
+
sidebar.add sw
|
186
191
|
sto_tabs = ListStore.new(String)
|
187
192
|
NUM_TABS.times do |tab|
|
188
193
|
iter = sto_tabs.append
|
@@ -195,7 +200,7 @@ module Sh
|
|
195
200
|
renderer,
|
196
201
|
'text' => 0)
|
197
202
|
lst_tabs.append_column column
|
198
|
-
|
203
|
+
sw.add lst_tabs
|
199
204
|
# Cover image widget
|
200
205
|
@img_cover = Image.new
|
201
206
|
event_box = EventBox.new
|
@@ -203,8 +208,11 @@ module Sh
|
|
203
208
|
event_box.signal_connect('button-press-event') do |w, event|
|
204
209
|
Kelp::ImageDialog.new(@pixbuf, @player.song.album.title).show if @pixbuf and @player
|
205
210
|
end
|
206
|
-
@img_cover.height_request =
|
207
|
-
|
211
|
+
@img_cover.height_request = 128
|
212
|
+
@img_cover.width_request = 128
|
213
|
+
bx = HBox.new false, 0
|
214
|
+
bx.pack_start event_box, false, false, 16
|
215
|
+
sidebar.pack_start bx, false, false, 16
|
208
216
|
# Lyrics text view
|
209
217
|
@html_lyrics = HtmlView.new
|
210
218
|
scr_lyrics = ScrolledWindow.new(nil, nil)
|
@@ -436,25 +444,29 @@ module Sh
|
|
436
444
|
rescue
|
437
445
|
@pixbuf = nil
|
438
446
|
end
|
447
|
+
|
439
448
|
if @pixbuf
|
440
449
|
@note.pixbuf_icon = @pixbuf.scale(48, 48) if @rnotify
|
441
|
-
@img_cover.pixbuf = @pixbuf.scale(
|
450
|
+
@img_cover.pixbuf = @pixbuf.scale(128, 128)
|
442
451
|
else
|
443
452
|
@img_cover.pixbuf = Gdk::Pixbuf.new(Global.locate("cover_unavailable.png")).scale(132, 132)
|
444
453
|
Thread.new do
|
445
454
|
song.album.image_path = Sh::CoverArt.get_cover(song)
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
if @
|
453
|
-
@
|
454
|
-
|
455
|
-
|
455
|
+
if song.album.image_path
|
456
|
+
$db.save_song song
|
457
|
+
# Show cover unless requests have been shuffled
|
458
|
+
if song == @player.song
|
459
|
+
@pixbuf = nil
|
460
|
+
(@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
|
461
|
+
if @pixbuf
|
462
|
+
if @rnotify
|
463
|
+
@note.close
|
464
|
+
@note.pixbuf_icon = @pixbuf.scale(48, 48)
|
465
|
+
@note.show
|
466
|
+
end
|
467
|
+
@img_cover.pixbuf = @pixbuf.scale(128, 128)
|
468
|
+
plasmarize_background @pixbuf
|
456
469
|
end
|
457
|
-
@img_cover.pixbuf = @pixbuf.scale(132, 132)
|
458
470
|
end
|
459
471
|
end
|
460
472
|
end
|
@@ -507,6 +519,39 @@ module Sh
|
|
507
519
|
end
|
508
520
|
end
|
509
521
|
|
522
|
+
def plasmarize_background image_path
|
523
|
+
begin
|
524
|
+
pixbuf = nil
|
525
|
+
if image_path.is_a? Gdk::Pixbuf
|
526
|
+
pixbuf = image_path
|
527
|
+
elsif image_path.respond_to? :to_str
|
528
|
+
pixbuf = Gdk::Pixbuf.new image_path.to_str
|
529
|
+
else
|
530
|
+
raise ArgumentError
|
531
|
+
end
|
532
|
+
|
533
|
+
if pixbuf
|
534
|
+
# Get color by shrinking image to 1px and extracting RGB values
|
535
|
+
color = pixbuf.scale(1, 1, Gdk::Pixbuf::INTERP_NEAREST).pixels.unpack("CCC")
|
536
|
+
# Convert colour from values between 0 and 255 to values between
|
537
|
+
# 0 and 65535.
|
538
|
+
color.map! {|n| n * (65535 / 255)}
|
539
|
+
|
540
|
+
# If the color has changed, regenerate plasma background
|
541
|
+
if color != @plasma_color
|
542
|
+
@plasma_color = color.dup
|
543
|
+
require 'sh_plasma'
|
544
|
+
pixmap = Plasma.new(600, 600, 3).generate_pixmap(color)
|
545
|
+
style = @window.style.copy
|
546
|
+
style.set_bg_pixmap(Gtk::STATE_NORMAL, pixmap)
|
547
|
+
@window.set_style style
|
548
|
+
end
|
549
|
+
end
|
550
|
+
rescue
|
551
|
+
puts "Plasma fail: #{$!}"
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
510
555
|
public
|
511
556
|
def queue
|
512
557
|
return @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.8
|
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-08-
|
12
|
+
date: 2009-08-29 00:00:00 +10:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- lib/sh_plugin.rb
|
138
138
|
- lib/sh_cover_art.rb
|
139
139
|
- lib/sh_tagreader.rb
|
140
|
+
- lib/sh_plasma.rb
|
140
141
|
- lib/sh_lyrics.rb
|
141
142
|
- lib/sh_database.rb
|
142
143
|
- lib/sh_util.rb
|
@@ -173,15 +174,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
174
|
version:
|
174
175
|
requirements:
|
175
176
|
- rake
|
177
|
+
- libwxgtk2.8-0
|
176
178
|
- libgnome2-ruby
|
177
|
-
- libgtk-mozembed-ruby
|
178
|
-
- libsqlite3-ruby
|
179
179
|
- libglade2-ruby
|
180
|
+
- libgtkhtml2-ruby
|
181
|
+
- libsqlite3-ruby
|
180
182
|
- ruby-dev
|
181
183
|
- libopenssl-ruby
|
182
184
|
- libmp3lame-dev
|
183
185
|
- libvorbis-dev
|
184
|
-
-
|
186
|
+
- build-essential
|
185
187
|
rubyforge_project: shroom
|
186
188
|
rubygems_version: 1.3.1
|
187
189
|
signing_key:
|