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.
@@ -13,11 +13,10 @@ class Object
13
13
  end
14
14
 
15
15
  def find_in_load_path(file)
16
- $:.each do |path|
17
- abs_file = "#{path}/#{file}"
18
- return abs_file if File.exists? abs_file
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
+ "&quot;" => "\"",
70
+ "&apos;" => "'",
71
+ "&amp;" => "&",
72
+ "&lt;" => "<",
73
+ "&gt;" => ">",
74
+ "&nbsp;" => " "
75
+ }
76
+
77
+ return CGI.unescapeHTML(self.gsub(/&\w*;/) {|e| entities[e] || e})
78
+ end
66
79
  end
67
80
 
68
81
  module Kelp
@@ -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 'sh_cover_art'
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
- Dir[Global.prefs[:library_dir]+'/**/*'].each do |path|
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 += inc
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...', '<StockItem>', nil, Stock::DISCONNECT, lambda {show_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 = '0.0.0'
472
+ version = Gem::Version.new('')
446
473
  Gem::SourceIndex.from_installed_gems.each do |n, spec|
447
- version = spec.version.to_s if spec.name == 'shroom'
448
- end
449
- dlg_about = Gnome::About.new('Shroom', version,
450
- "Copyright (C) 2009 Aiden Nibali",
451
- "Shroom - A music player and organizer in Ruby",
452
- ["Aiden Nibali"], ["Aiden Nibali"], nil)
453
- dlg_about.logo = Gdk::Pixbuf.new(Global.locate('icon_128x128.png'))
454
- dlg_about.show
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
- image_path = song.album.image_path
537
- # Use image path in database if valid
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
- unless @pixbuf
581
+ if @pixbuf.nil?
543
582
  @img_cover.pixbuf = Gdk::Pixbuf.new(Global.locate("cover_unavailable.png")).scale(132, 132)
544
- image_path = Sh::CoverArt.get_cover(song)
545
- if image_path
546
- begin
547
- @pixbuf = Gdk::Pixbuf.new(image_path)
548
- song.album.image_path = image_path
549
- song.album.save
550
- rescue
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 * (65535 / 255)}
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
- Sh::Log.info "Plasma generation failed", $!
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=(queue)
606
- @queue_pos = 0
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 queue_pos=(pos)
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.11
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-10-06 00:00:00 +11:00
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-ogginfo
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.3.2
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/shroom-res
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
- - libgnome2-ruby
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.1
179
+ rubygems_version: 1.3.5
177
180
  signing_key:
178
- specification_version: 2
181
+ specification_version: 3
179
182
  summary: Shroom is a music player and organizer
180
183
  test_files: []
181
184
 
@@ -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