shroom 0.0.11 → 0.0.12

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