shroom 0.0.10 → 0.0.11
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/LICENSE +626 -629
- data/README +25 -32
- data/Rakefile +2 -4
- data/lib/sh_actions.rb +25 -19
- data/lib/sh_browse.rb +84 -54
- data/lib/sh_cover_art.rb +3 -6
- data/lib/sh_cover_browse.rb +10 -6
- data/lib/sh_database.rb +149 -160
- data/lib/sh_fingerprint.rb +64 -0
- data/lib/sh_main.rb +13 -11
- data/lib/sh_playlist.rb +15 -11
- data/lib/sh_util.rb +0 -17
- data/lib/sh_view.rb +45 -33
- data/lib/shroom-res/cover_unavailable.png +0 -0
- data/lib/shroom-res/icon_128x128.png +0 -0
- data/lib/shroom-res/plugins/lastfm_scrobbler.rb +32 -30
- data/lib/shroom-res/shroom.glade +13 -1
- metadata +4 -19
- data/lib/sh_album.rb +0 -14
- data/lib/sh_artist.rb +0 -14
- data/lib/sh_song.rb +0 -135
- data/lib/shroom-res/cover_unavailable.svg +0 -152
- data/lib/shroom-res/icon.svg +0 -206
data/lib/sh_playlist.rb
CHANGED
@@ -8,19 +8,23 @@ module Sh
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.parse(path)
|
11
|
-
list = Playlist.new
|
11
|
+
list = Playlist.new File.basename(path)
|
12
12
|
open(path) do |f|
|
13
13
|
while line = f.gets
|
14
14
|
line.strip!
|
15
15
|
unless line[0] == ?# or line.empty?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
if
|
20
|
-
|
16
|
+
begin
|
17
|
+
# TODO: make cross-platform
|
18
|
+
ref = File.expand_path(line.gsub('\\', '/'), File.dirname(path))
|
19
|
+
if File.exists? ref
|
20
|
+
if Global::SUPPORTED_EXTENSIONS.include? File.extname(ref)
|
21
|
+
list << (Song.first(:path => ref) || Database.add_song(ref))
|
22
|
+
end
|
23
|
+
else
|
24
|
+
Log.info "File at #{ref} not found"
|
21
25
|
end
|
22
|
-
|
23
|
-
|
26
|
+
rescue Exception
|
27
|
+
Log.info "Couldn't parse line in playlist: #{line}", $!
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -37,7 +41,7 @@ module Sh
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def save!
|
40
|
-
path =
|
44
|
+
path = Global::PATHS[:playlists_file]
|
41
45
|
playlists = []
|
42
46
|
if File.exists? path
|
43
47
|
playlists = YAML.load_file path
|
@@ -83,8 +87,8 @@ module Sh
|
|
83
87
|
playlist = Playlist.new name
|
84
88
|
paths.each do |path|
|
85
89
|
if File.exists? path
|
86
|
-
if
|
87
|
-
song = (
|
90
|
+
if Global::SUPPORTED_EXTENSIONS.include? File.extname(path)
|
91
|
+
song = (Song.first(:path => path) || Database.add_song(path))
|
88
92
|
playlist << song
|
89
93
|
end
|
90
94
|
else
|
data/lib/sh_util.rb
CHANGED
@@ -65,23 +65,6 @@ class String
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
require 'thread'
|
69
|
-
require 'gtkhtml2'
|
70
|
-
module Gtk
|
71
|
-
class HtmlView
|
72
|
-
def set_html content=nil
|
73
|
-
@doc_mutex ||= Mutex.new
|
74
|
-
doc = self.document ||= HtmlDocument.new
|
75
|
-
@doc_mutex.synchronize do
|
76
|
-
doc.open_stream 'text/html'
|
77
|
-
content ||= (yield || '')
|
78
|
-
doc.write_stream content
|
79
|
-
doc.close_stream
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
68
|
module Kelp
|
86
69
|
class ProgressDialog < Gtk::Dialog
|
87
70
|
def initialize(title)
|
data/lib/sh_view.rb
CHANGED
@@ -7,7 +7,6 @@ require 'sh_cover_art'
|
|
7
7
|
require 'sh_mmkeys'
|
8
8
|
require 'sh_actions'
|
9
9
|
require 'gtk2'
|
10
|
-
require 'gtkhtml2'
|
11
10
|
include Gtk
|
12
11
|
|
13
12
|
module Sh
|
@@ -24,7 +23,7 @@ module Sh
|
|
24
23
|
@@instance = nil
|
25
24
|
|
26
25
|
def initialize
|
27
|
-
|
26
|
+
Log.warning 'Instance of View already created!' if @@instance
|
28
27
|
@@instance = self
|
29
28
|
|
30
29
|
# Initialize GTK
|
@@ -38,38 +37,40 @@ module Sh
|
|
38
37
|
|
39
38
|
# Search for songs in library directory if it exists
|
40
39
|
if File.exists? Global.prefs[:library_dir]
|
41
|
-
cancelled = false
|
42
40
|
# Prepare progress dialog
|
43
41
|
dialog = Kelp::ProgressDialog.new("Updating database...")
|
42
|
+
cancelled = false
|
44
43
|
dialog.signal_connect('response') { cancelled = true}
|
44
|
+
|
45
45
|
# Scan for new songs which are not in the database
|
46
46
|
new_songs = []
|
47
47
|
Dir[Global.prefs[:library_dir]+'/**/*'].each do |path|
|
48
48
|
ext = File.extname path
|
49
|
-
if
|
50
|
-
new_songs << Song.
|
49
|
+
if Global::SUPPORTED_EXTENSIONS.include? ext
|
50
|
+
new_songs << path if Song.first(:path => path).nil?
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
53
54
|
# Show progress dialog if there are new songs to process
|
54
55
|
if new_songs.length > 0
|
55
56
|
dialog.show_all
|
56
57
|
Kelp.process_events
|
57
58
|
end
|
59
|
+
|
58
60
|
# inc = the fraction to increment the progress bar by for each song
|
59
61
|
inc = 1 / new_songs.length.to_f
|
62
|
+
|
60
63
|
# Enter new songs in database
|
61
|
-
new_songs.each do |
|
64
|
+
new_songs.each do |path|
|
62
65
|
# Show path to song in the dialog
|
63
|
-
dialog.message =
|
66
|
+
dialog.message = path
|
64
67
|
|
65
68
|
begin
|
66
|
-
# Read metadata from song tags
|
67
|
-
song.read_tags!
|
68
69
|
# Save song to the database
|
69
|
-
|
70
|
-
|
70
|
+
Database.add_song path
|
71
|
+
Log.debug "Added #{path} to database"
|
71
72
|
rescue
|
72
|
-
|
73
|
+
Log.info "Failed to add ${path} to database", $!
|
73
74
|
end
|
74
75
|
# Increment progress bar
|
75
76
|
dialog.fraction += inc
|
@@ -82,7 +83,10 @@ module Sh
|
|
82
83
|
# Remove old entries from database
|
83
84
|
dialog.message = "Cleaning out old entries..."
|
84
85
|
dialog.pulse
|
85
|
-
|
86
|
+
|
87
|
+
Song.clean_missing_songs
|
88
|
+
Album.clean_empty_albums
|
89
|
+
Artist.clean_empty_artists
|
86
90
|
|
87
91
|
# Destroy progress dialog
|
88
92
|
dialog.destroy
|
@@ -91,7 +95,7 @@ module Sh
|
|
91
95
|
new_songs = dialog = nil
|
92
96
|
end
|
93
97
|
|
94
|
-
|
98
|
+
Log.debug 'Synchronized library dir with database'
|
95
99
|
|
96
100
|
# Load small 16x16 pixel Shroom logo
|
97
101
|
icon = Gdk::Pixbuf.new Global.locate('icon_16x16.png')
|
@@ -226,10 +230,15 @@ module Sh
|
|
226
230
|
bx.pack_start event_box, false, false, 16
|
227
231
|
sidebar.pack_start bx, false, false, 16
|
228
232
|
# Lyrics text view
|
229
|
-
@
|
233
|
+
@txt_lyrics = TextView.new
|
234
|
+
@txt_lyrics.editable = false
|
235
|
+
@txt_lyrics.cursor_visible = false
|
236
|
+
@txt_lyrics.left_margin = @txt_lyrics.right_margin = 8
|
230
237
|
scr_lyrics = ScrolledWindow.new(nil, nil)
|
231
238
|
scr_lyrics.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
232
|
-
scr_lyrics.add @
|
239
|
+
scr_lyrics.add @txt_lyrics
|
240
|
+
@buf_lyrics = @txt_lyrics.buffer
|
241
|
+
@buf_lyrics.create_tag 'title', 'font' => 'Sans 18'
|
233
242
|
box_lyrics = VBox.new false, 0
|
234
243
|
box_lyrics.add scr_lyrics
|
235
244
|
@btn_refresh_lyrics = Button.new Stock::REFRESH
|
@@ -462,7 +471,7 @@ module Sh
|
|
462
471
|
def on_song_changed
|
463
472
|
if @player
|
464
473
|
song = @player.song
|
465
|
-
|
474
|
+
Log.debug "Playback started for \"#{song.title}\""
|
466
475
|
@note.close if @note
|
467
476
|
@note = nil
|
468
477
|
if @rnotify
|
@@ -475,11 +484,11 @@ module Sh
|
|
475
484
|
Thread.new {update_image song} if Global.prefs[:cover_art]
|
476
485
|
# Lyrics
|
477
486
|
if Global.prefs[:lyrics]
|
478
|
-
@
|
487
|
+
@buf_lyrics.text = 'Loading...'
|
479
488
|
Thread.new do
|
480
489
|
if not song.lyrics
|
481
|
-
song.lyrics =
|
482
|
-
|
490
|
+
song.lyrics = Lyrics.get_lyrics(song)
|
491
|
+
song.save
|
483
492
|
end
|
484
493
|
# Show lyrics unless requests have been shuffled
|
485
494
|
if @player.song == song
|
@@ -501,20 +510,23 @@ module Sh
|
|
501
510
|
lyrics = song.lyrics || "[Lyrics not found]"
|
502
511
|
# Stupid character encoding stuff
|
503
512
|
lyrics = lyrics.unpack('U*').pack('C*')
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
513
|
+
|
514
|
+
@buf_lyrics.text = ""
|
515
|
+
last = @buf_lyrics.get_iter_at_offset(0)
|
516
|
+
@buf_lyrics.insert last, song.title
|
517
|
+
start = last.clone
|
518
|
+
start.backward_chars(song.title.length)
|
519
|
+
@buf_lyrics.apply_tag('title', start, last)
|
520
|
+
@buf_lyrics.insert last, "\n\n#{lyrics}"
|
521
|
+
|
522
|
+
if @lyric_signal_id and @btn_refresh_lyrics.signal_handler_is_connected?(@lyric_signal_id)
|
523
|
+
@btn_refresh_lyrics.signal_handler_disconnect(@lyric_signal_id)
|
512
524
|
end
|
513
|
-
@
|
514
|
-
@
|
525
|
+
@lyric_signal_id = @btn_refresh_lyrics.signal_connect('pressed') do |*args|
|
526
|
+
@buf_lyrics.text = 'Loading...'
|
515
527
|
Thread.new do
|
516
528
|
song.lyrics = Sh::Lyrics.get_lyrics(song)
|
517
|
-
|
529
|
+
song.save
|
518
530
|
show_lyrics song if @player and @player.song == song
|
519
531
|
end
|
520
532
|
end
|
@@ -534,7 +546,7 @@ module Sh
|
|
534
546
|
begin
|
535
547
|
@pixbuf = Gdk::Pixbuf.new(image_path)
|
536
548
|
song.album.image_path = image_path
|
537
|
-
|
549
|
+
song.album.save
|
538
550
|
rescue
|
539
551
|
end
|
540
552
|
end
|
@@ -661,7 +673,7 @@ module Sh
|
|
661
673
|
end
|
662
674
|
|
663
675
|
def show
|
664
|
-
|
676
|
+
Log.debug 'Starting GTK main loop'
|
665
677
|
Gtk.main
|
666
678
|
end
|
667
679
|
|
Binary file
|
Binary file
|
@@ -68,47 +68,49 @@ Sh::Plugin.define "lastfm_scrobbler" do
|
|
68
68
|
:track_number => song.track_num
|
69
69
|
}
|
70
70
|
|
71
|
-
# Scrobble
|
72
|
-
submit_scrobbles!
|
71
|
+
# Scrobble
|
72
|
+
submit_scrobbles!
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
def submit_scrobbles!
|
77
77
|
(@mutex ||= Mutex.new).synchronize do
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
details = {:user => @user, :password => @password}
|
82
|
-
auth = @scrobble_auth = Scrobbler::SimpleAuth.new(details)
|
83
|
-
auth.handshake!
|
84
|
-
Sh::Log.debug "Last.fm authentication status is \"#{auth.status}\""
|
85
|
-
rescue
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# No point attempting to scrobble without authentication
|
90
|
-
if auth.status and auth.status.strip.upcase == 'OK'
|
91
|
-
failed_scrobbles = []
|
92
|
-
until @scrobble_queue.empty?
|
93
|
-
hash = @scrobble_queue.pop
|
94
|
-
hash[:session_id] = auth.session_id
|
95
|
-
hash[:submission_url] = auth.submission_url
|
96
|
-
scrobble = nil
|
78
|
+
if Ping.pingecho("post.audioscrobbler.com", 5)
|
79
|
+
auth = @scrobble_auth
|
80
|
+
if not auth or auth.status.strip.upcase != 'OK'
|
97
81
|
begin
|
98
|
-
|
99
|
-
|
82
|
+
details = {:user => @user, :password => @password}
|
83
|
+
auth = @scrobble_auth = Scrobbler::SimpleAuth.new(details)
|
84
|
+
auth.handshake!
|
85
|
+
Sh::Log.debug "Last.fm authentication status is \"#{auth.status}\""
|
100
86
|
rescue
|
101
|
-
scrobble = nil
|
102
87
|
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# No point attempting to scrobble without authentication
|
91
|
+
if auth.status and auth.status.strip.upcase == 'OK'
|
92
|
+
failed_scrobbles = []
|
93
|
+
until @scrobble_queue.empty?
|
94
|
+
hash = @scrobble_queue.pop
|
95
|
+
hash[:session_id] = auth.session_id
|
96
|
+
hash[:submission_url] = auth.submission_url
|
97
|
+
scrobble = nil
|
98
|
+
begin
|
99
|
+
scrobble = Scrobbler::Scrobble.new(hash)
|
100
|
+
scrobble.submit!
|
101
|
+
rescue
|
102
|
+
scrobble = nil
|
103
|
+
end
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
if scrobble and scrobble.status.strip.upcase == 'OK'
|
106
|
+
Sh::Log.debug "Scrobble for \"#{scrobble.track}\" succeeded"
|
107
|
+
else
|
108
|
+
Sh::Log.info "Failed to scrobble for \"#{scrobble.track}\""
|
109
|
+
failed_scrobbles.insert 0, hash
|
110
|
+
end
|
109
111
|
end
|
112
|
+
@scrobble_queue.push *failed_scrobbles
|
110
113
|
end
|
111
|
-
@scrobble_queue.push *failed_scrobbles
|
112
114
|
end
|
113
115
|
end
|
114
116
|
end
|
data/lib/shroom-res/shroom.glade
CHANGED
@@ -131,7 +131,7 @@
|
|
131
131
|
</widget>
|
132
132
|
<packing>
|
133
133
|
<property name="left_attach">1</property>
|
134
|
-
<property name="right_attach">
|
134
|
+
<property name="right_attach">2</property>
|
135
135
|
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
136
136
|
<property name="y_options"></property>
|
137
137
|
</packing>
|
@@ -285,6 +285,18 @@
|
|
285
285
|
<property name="bottom_attach">4</property>
|
286
286
|
</packing>
|
287
287
|
</child>
|
288
|
+
<child>
|
289
|
+
<widget class="GtkSpinButton" id="spn_track_num">
|
290
|
+
<property name="visible">True</property>
|
291
|
+
<property name="can_focus">True</property>
|
292
|
+
<property name="invisible_char">●</property>
|
293
|
+
<property name="adjustment">1 1 99 1 5 5</property>
|
294
|
+
</widget>
|
295
|
+
<packing>
|
296
|
+
<property name="left_attach">2</property>
|
297
|
+
<property name="right_attach">3</property>
|
298
|
+
</packing>
|
299
|
+
</child>
|
288
300
|
<child>
|
289
301
|
<placeholder/>
|
290
302
|
</child>
|
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.11
|
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-10-
|
12
|
+
date: 2009-10-06 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -102,16 +102,6 @@ dependencies:
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 0.2.3
|
104
104
|
version:
|
105
|
-
- !ruby/object:Gem::Dependency
|
106
|
-
name: shared-mime-info
|
107
|
-
type: :runtime
|
108
|
-
version_requirement:
|
109
|
-
version_requirements: !ruby/object:Gem::Requirement
|
110
|
-
requirements:
|
111
|
-
- - ">="
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
version: "0.1"
|
114
|
-
version:
|
115
105
|
description: Shroom is a music player and organizer
|
116
106
|
email: dismal.denizen@gmail.com
|
117
107
|
executables:
|
@@ -130,11 +120,8 @@ files:
|
|
130
120
|
- lib/sh_browse.rb
|
131
121
|
- lib/sh_main.rb
|
132
122
|
- lib/sh_queue.rb
|
133
|
-
- lib/sh_album.rb
|
134
123
|
- lib/sh_playlist.rb
|
135
124
|
- lib/sh_cover_browse.rb
|
136
|
-
- lib/sh_song.rb
|
137
|
-
- lib/sh_artist.rb
|
138
125
|
- lib/sh_actions.rb
|
139
126
|
- lib/sh_plugin.rb
|
140
127
|
- lib/sh_log.rb
|
@@ -145,15 +132,14 @@ files:
|
|
145
132
|
- lib/sh_database.rb
|
146
133
|
- lib/sh_util.rb
|
147
134
|
- lib/sh_mmkeys.rb
|
135
|
+
- lib/sh_fingerprint.rb
|
148
136
|
- lib/shroom-res
|
149
137
|
- lib/shroom-res/cover_unavailable.png
|
150
138
|
- lib/shroom-res/icon_16x16.png
|
151
139
|
- lib/shroom-res/plugins
|
152
140
|
- lib/shroom-res/plugins/lastfm_scrobbler.rb
|
153
|
-
- lib/shroom-res/icon.svg
|
154
141
|
- lib/shroom-res/icon_128x128.png
|
155
142
|
- lib/shroom-res/shroom.glade
|
156
|
-
- lib/shroom-res/cover_unavailable.svg
|
157
143
|
- lib/sh_player.rb
|
158
144
|
- lib/sh_view.rb
|
159
145
|
has_rdoc: true
|
@@ -180,10 +166,9 @@ requirements:
|
|
180
166
|
- libwxgtk2.8-0
|
181
167
|
- libgnome2-ruby
|
182
168
|
- libglade2-ruby
|
183
|
-
- libgtkhtml2-ruby
|
184
169
|
- libsqlite3-ruby
|
185
|
-
- ruby-dev
|
186
170
|
- libopenssl-ruby
|
171
|
+
- ruby-dev
|
187
172
|
- libmp3lame-dev
|
188
173
|
- libvorbis-dev
|
189
174
|
- build-essential
|