shroom 0.0.3 → 0.0.4

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/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.3'
10
+ s.version = '0.0.4'
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'
@@ -0,0 +1,20 @@
1
+ module Sh
2
+ class Album
3
+ attr_writer :artist
4
+ attr_accessor :title, :mbid, :image_path, :info, :date
5
+ attr_accessor :db_id
6
+
7
+ def initialize
8
+ @songs = []
9
+ end
10
+
11
+ def artist
12
+ #@artist = $db.artists(:id => @artist.db_id).first if @artist and @artist.db_id
13
+ return @artist
14
+ end
15
+
16
+ def to_s
17
+ return self.title
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Sh
2
+ class Artist
3
+ attr_accessor :name, :mbid, :image_path, :info
4
+ attr_accessor :db_id
5
+
6
+ def initialize
7
+ @albums = []
8
+ end
9
+
10
+ def to_s
11
+ return self.name
12
+ end
13
+ end
14
+ end
@@ -9,13 +9,14 @@ module Sh
9
9
  col_artist.set_cell_data_func(ren_artist) do |tvc, cell, model, iter|
10
10
  cell.text = ''
11
11
  data = iter[0]
12
- cell.text = data if data.is_a? String
13
12
  if data.is_a? Sh::Song
14
13
  if data.title
15
14
  cell.text = sprintf("%.2d\t%s", data.track_num, data.title)
16
15
  else
17
16
  cell.text = data.path.split('/').last
18
17
  end
18
+ else
19
+ cell.text = data.to_s
19
20
  end
20
21
  end
21
22
  @tree.append_column col_artist
@@ -104,8 +105,8 @@ module Sh
104
105
  def fill_model
105
106
  artist_node = album_node = track_node = nil
106
107
  $db.songs.sort_by {|a| a.to_s}.each do |song|
107
- artist = song.artist || '!Unknown Artist!'
108
- if not artist_node or artist_node[0] != artist
108
+ artist = song.artist
109
+ if not artist_node or artist_node[0].db_id != artist.db_id
109
110
  artist_node = @model.append nil
110
111
  artist_node[0] = artist
111
112
  # Required for proper handling of multiple artists with on album
@@ -113,9 +114,9 @@ module Sh
113
114
  end
114
115
  artist_node[1] ||= []
115
116
  artist_node[1] << song
116
-
117
- album = song.album || '!Unknown Album!'
118
- if not album_node or album_node[0] != album
117
+
118
+ album = song.album
119
+ if not album_node or album_node[0].db_id != album.db_id
119
120
  album_node = @model.append artist_node
120
121
  album_node[0] = album
121
122
  end
@@ -6,7 +6,7 @@ module Sh
6
6
  class CoverArt
7
7
  def CoverArt.get_cover song
8
8
  if $prefs[:cover_art]
9
- artist, album = song.artist, song.album
9
+ artist, album = song.artist.name, song.album.title
10
10
  path = "#{$cover_dir}/#{artist} - #{album}"
11
11
  return path if File.exists? path
12
12
  doc = lastfm("album.getInfo", {:artist => artist, :album => album})
@@ -1,59 +1,150 @@
1
1
  require 'rubygems'
2
2
  require 'sequel'
3
3
  require 'sh_song'
4
+ require 'sh_album'
5
+ require 'sh_artist'
4
6
 
5
7
  module Sh
6
8
  class Database
7
9
  def initialize
8
10
  @db = Sequel.sqlite("#{$config_dir}/songs.db")
9
11
 
12
+ @db.create_table :artists do
13
+ primary_key :id
14
+ String :mbid
15
+ String :name
16
+ String :image_path
17
+ String :info
18
+ end unless @db.table_exists? :artists
19
+
20
+ @db.create_table :albums do
21
+ primary_key :id
22
+ String :mbid
23
+ String :title
24
+ String :image_path
25
+ String :info
26
+ String :date
27
+ end unless @db.table_exists? :albums
28
+
10
29
  @db.create_table :songs do
11
30
  primary_key :id
31
+ String :mbid
12
32
  String :path
13
33
  String :title
14
34
  String :lyrics
15
- String :image
16
- String :year
17
- String :album
18
- String :artist
35
+ String :image_path
19
36
  String :track_num
37
+ foreign_key :album_id, :albums
38
+ foreign_key :artist_id, :artists
20
39
  end unless @db.table_exists? :songs
21
40
  end
22
41
 
23
42
  def save_song song
24
- hash = {
43
+ # Get artist info
44
+ artist = song.artist
45
+ artist_hash = {
46
+ :mbid => artist.mbid,
47
+ :name => artist.name,
48
+ :image_path => artist.image_path,
49
+ :info => artist.info
50
+ }
51
+
52
+ # Insert/update artist in database
53
+ artist_id = nil
54
+ row_artist = @db[:artists][:name => artist.name]
55
+ if row_artist
56
+ artist_hash.each do |k, v|
57
+ if artist_hash[k] != v
58
+ @db[:artists].filter(:name => artist.name).update(k => v)
59
+ end
60
+ end
61
+ artist_id = row_artist[:id]
62
+ else
63
+ artist_id = @db[:artists].insert(artist_hash)
64
+ end
65
+ artist.db_id = artist_id
66
+
67
+ # Get album info
68
+ album = song.album
69
+ album_hash = {
70
+ :mbid => album.mbid,
71
+ :title => album.title,
72
+ :image_path => album.image_path,
73
+ :date => album.date,
74
+ :info => album.info,
75
+ }
76
+
77
+ # Insert/update artist in database
78
+ album_id = nil
79
+ row_album = @db[:albums][:title => album.title]
80
+ if row_album
81
+ album_hash.each do |k, v|
82
+ if album_hash[k] != v
83
+ @db[:albums].filter(:title => album.title).update(k => v)
84
+ end
85
+ end
86
+ album_id = row_album[:id]
87
+ else
88
+ album_id = @db[:albums].insert(album_hash)
89
+ end
90
+ album.db_id = album_id
91
+
92
+ song_hash = {
25
93
  :path => song.path,
94
+ :mbid => song.mbid,
26
95
  :title => song.title,
27
96
  :lyrics => song.lyrics,
28
- :image => song.image,
29
- :year => song.year,
30
- :album => song.album,
31
- :artist => song.artist,
32
- :track_num => song.track_num
97
+ :track_num => song.track_num,
98
+ :album_id => album_id,
99
+ :artist_id => artist_id
33
100
  }
34
101
 
35
102
  song_id = nil
36
103
  row_song = @db[:songs][:path => song.path]
37
104
  if row_song
38
- hash.each do |k, v|
105
+ song_hash.each do |k, v|
39
106
  if row_song[k] != v
40
107
  @db[:songs].filter(:path => song.path).update(k => v)
41
108
  end
42
109
  end
43
110
  song_id = row_song[:id]
44
111
  else
45
- # Create row in db for song
46
- song_id = @db[:songs].insert(hash)
47
- # Retrieve row to return
112
+ song_id = @db[:songs].insert(song_hash)
48
113
  row_song = @db[:songs][:id => song_id]
49
114
  end
115
+ song.db_id = song_id
50
116
 
51
117
  return row_song
52
118
  end
53
119
 
54
- def songs
120
+ def artists(params={})
121
+ artists = []
122
+ params ||= {}
123
+ rows = @db[:artists]
124
+ rows = rows.filter(params) unless params == {}
125
+ rows.each do |hash|
126
+ artists << hash_to_artist(hash)
127
+ end
128
+ return artists
129
+ end
130
+
131
+ def albums(params={})
132
+ albums = []
133
+ params ||= {}
134
+ rows = @db[:albums]
135
+ rows = rows.filter(params) unless params == {}
136
+ rows.each do |hash|
137
+ albums << hash_to_album(hash)
138
+ end
139
+ return albums
140
+ end
141
+
142
+ def songs(params={})
55
143
  songs = []
56
- @db[:songs].each do |hash|
144
+ params ||= {}
145
+ rows = @db[:songs]
146
+ rows = rows.filter(params) unless params == {}
147
+ rows.each do |hash|
57
148
  songs << hash_to_song(hash)
58
149
  end
59
150
  return songs
@@ -80,7 +171,32 @@ module Sh
80
171
  assign = (k.to_s + '=').to_sym
81
172
  song.send assign, v if song.respond_to? assign
82
173
  end
174
+ song.db_id = hash[:id]
175
+ song.album = hash_to_album(@db[:albums][:id => hash[:album_id]])
176
+ song.artist = hash_to_artist(@db[:artists][:id => hash[:artist_id]])
83
177
  return song
84
178
  end
179
+
180
+ def hash_to_album hash
181
+ album = Sh::Album.new
182
+ return album unless hash
183
+ hash.each do |k, v|
184
+ assign = (k.to_s + '=').to_sym
185
+ album.send assign, v if album.respond_to? assign
186
+ end
187
+ album.db_id = hash[:id]
188
+ return album
189
+ end
190
+
191
+ def hash_to_artist hash
192
+ artist = Sh::Artist.new
193
+ return artist unless hash
194
+ hash.each do |k, v|
195
+ assign = (k.to_s + '=').to_sym
196
+ artist.send assign, v if artist.respond_to? assign
197
+ end
198
+ artist.db_id = hash[:id]
199
+ return artist
200
+ end
85
201
  end
86
202
  end
@@ -5,7 +5,7 @@ require 'cgi'
5
5
  module Sh
6
6
  class Lyrics
7
7
  def Lyrics.get_lyrics song
8
- artist, title = song.artist, song.title
8
+ artist, title = song.artist.name, song.title
9
9
  return "" unless artist and title
10
10
  LyricsWiki.get_lyrics(artist, title)
11
11
  end
@@ -90,9 +90,9 @@ module Sh
90
90
  @@scrobble_queue << Scrobbler::Scrobble.new(
91
91
  :session_id => auth.session_id,
92
92
  :submission_url => auth.submission_url,
93
- :artist => song.artist,
93
+ :artist => song.artist.name,
94
94
  :track => song.title,
95
- :album => song.album,
95
+ :album => song.album.title,
96
96
  :time => Time.new,
97
97
  :length => duration,
98
98
  :track_number => song.track_num)
@@ -0,0 +1,51 @@
1
+ module Sh
2
+ class Queue
3
+ def initialize view
4
+ @view = view
5
+ sw = ScrolledWindow.new(nil, nil)
6
+ @widget = sw
7
+ sw.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
8
+ @sto_tabs = ListStore.new(String, Song)
9
+ lst_tabs = TreeView.new @sto_tabs
10
+ renderer = CellRendererText.new
11
+ column = TreeViewColumn.new('Artist',
12
+ renderer,
13
+ 'text' => 0)
14
+ lst_tabs.append_column column
15
+ renderer = CellRendererText.new
16
+ column = TreeViewColumn.new('Songs', renderer)
17
+ column.set_cell_data_func(renderer) do |tvc, cell, model, iter|
18
+ cell.text = ''
19
+ data = iter[1]
20
+ if data.title
21
+ cell.text = sprintf("%.2d\t%s", data.track_num, data.title)
22
+ else
23
+ cell.text = data.path.split('/').last
24
+ end
25
+ end
26
+ lst_tabs.append_column column
27
+ sw.add lst_tabs
28
+
29
+ lst_tabs.signal_connect('row_activated') do |widget, path, col|
30
+ iter = lst_tabs.model.get_iter(path)
31
+ song = iter[1]
32
+ view.stop
33
+ view.queue_pos = path.indices.first
34
+ view.play
35
+ end
36
+ end
37
+
38
+ def update
39
+ @sto_tabs.clear
40
+ @view.queue.each do |song|
41
+ iter = @sto_tabs.append
42
+ iter[0] = song.artist.name
43
+ iter[1] = song
44
+ end if @view.queue
45
+ end
46
+
47
+ def widget
48
+ return @widget
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'sh_tagreader'
3
+ require 'sh_album'
4
+ require 'sh_artist'
3
5
  require 'earworm'
4
6
  require 'rbrainz'
5
7
  include MusicBrainz
@@ -7,17 +9,30 @@ include MusicBrainz
7
9
  module Sh
8
10
  class Song
9
11
  attr_reader :path, :mime, :matches
10
- attr_accessor :title, :artist, :album, :image, :lyrics, :track_num, :year
12
+ attr_writer :album, :artist
13
+ attr_accessor :title, :mbid, :lyrics, :track_num
14
+ attr_accessor :db_id
11
15
 
12
16
  def initialize path
13
17
  @path = File.expand_path path
18
+ self.artist = Sh::Artist.new
19
+ self.album = Sh::Album.new
20
+ end
21
+
22
+ def album
23
+ #@album = $db.albums(:id => @album.db_id).first if @album and @album.db_id
24
+ return @album
25
+ end
26
+
27
+ def artist
28
+ #@artist = $db.artists(:id => @artist.db_id).first if @artist and @artist.db_id
29
+ return @artist
14
30
  end
15
31
 
16
32
  def duration
17
33
  @duration ||= Sh::TagReader.read(path)[:duration]
18
34
  end
19
35
 
20
-
21
36
  def lookup!
22
37
  track = lookup_multiple.first
23
38
  if track
@@ -25,14 +40,14 @@ module Sh
25
40
  track.artist.disambiguation = false
26
41
  # Pull data from response
27
42
  self.title = track.title
28
- self.artist = track.artist.to_s
29
- artistid = track.artist.id.to_mbid.uuid
43
+ artist.name = track.artist.to_s
44
+ artist.mbid = track.artist.id.to_mbid.uuid
30
45
  rel = track.releases.to_a.first
31
- self.album = rel.title
32
- releaseid = rel.id.to_mbid.uuid
46
+ album.title = rel.title
47
+ album.mbid = rel.id.to_mbid.uuid
33
48
  # Determine track number
34
49
  query = Webservice::Query.new
35
- filter = Webservice::TrackFilter.new(:artistid => artistid, :releaseid => releaseid)
50
+ filter = Webservice::TrackFilter.new(:artistid => artist.mbid, :releaseid => album.mbid)
36
51
  tracks = query.get_tracks(filter).entities
37
52
  tracks.to_a.each_with_index do |t, i|
38
53
  self.track_num = i + 1 if t.title == track.title and t.duration == track.duration
@@ -52,12 +67,12 @@ module Sh
52
67
  end
53
68
  puids = info.puid_list
54
69
  self.title = info.title
55
- self.artist = info.artist_name
70
+ self.artist.name = info.artist_name
56
71
  # Return if no matches are found
57
- return if not title or not artist
72
+ return if not title or not artist.name
58
73
  # Get more information from MusicBrainz
59
74
  query = Webservice::Query.new
60
- filter = Webservice::TrackFilter.new(:artist => artist, :title => title, :puid => puids.first)
75
+ filter = Webservice::TrackFilter.new(:artist => artist.name, :title => title, :puid => puids.first)
61
76
  tracks = query.get_tracks(filter).entities
62
77
  @matches = tracks || []
63
78
  end
@@ -67,16 +82,16 @@ module Sh
67
82
  Sh::TagReader.read(path) do |data|
68
83
  if overwrite
69
84
  @title = data[:title]
70
- @artist = data[:artist]
71
- @album = data[:album]
72
- @year = data[:year]
85
+ artist.name = data[:artist]
86
+ album.title = data[:album]
87
+ album.date = data[:year]
73
88
  @track_num = data[:track_num]
74
89
  @duration = data[:duration]
75
90
  else
76
91
  @title ||= data[:title]
77
- @artist ||= data[:artist]
78
- @album ||= data[:album]
79
- @year ||= data[:year]
92
+ artist.name ||= data[:artist]
93
+ album.title ||= data[:album]
94
+ album.date ||= data[:year]
80
95
  @track_num ||= data[:track_num]
81
96
  @duration ||= data[:duration]
82
97
  end
@@ -92,10 +107,10 @@ module Sh
92
107
  t = title
93
108
  t = "Unknown" if not t or t.is_binary_data?
94
109
  t.gsub!("<", "&lt;")
95
- ar = artist
110
+ ar = artist.name
96
111
  ar = "Unknown" if not ar or ar.is_binary_data?
97
112
  ar.gsub!("<", "&lt;")
98
- al = album
113
+ al = album.title
99
114
  al = "Unknown" if not al or al.is_binary_data?
100
115
  al.gsub!("<", "&lt;")
101
116
  return "<b>#{t}</b> by <i>#{ar}</i> from <i>#{al}</i>".gsub("&", "&amp;")
@@ -37,7 +37,7 @@ module Kelp
37
37
  end
38
38
 
39
39
  def message=(msg)
40
- @lbl_message.set_markup(msg)
40
+ @lbl_message.text = msg
41
41
  end
42
42
 
43
43
  def message
@@ -1,4 +1,5 @@
1
1
  require 'sh_browse'
2
+ require 'sh_queue'
2
3
  require 'sh_lyrics'
3
4
  require 'sh_cover_art'
4
5
  require 'libglade2'
@@ -198,7 +199,7 @@ module Sh
198
199
  event_box = EventBox.new
199
200
  event_box.add @img_cover
200
201
  event_box.signal_connect("button-press-event") do |w, event|
201
- Kelp::ImageDialog.new(@pixbuf, @player.song.album).show if @pixbuf and @player
202
+ Kelp::ImageDialog.new(@pixbuf, @player.song.album.title).show if @pixbuf and @player
202
203
  end
203
204
  @img_cover.height_request = 150
204
205
  sidebar.pack_start event_box, false, false, 0
@@ -210,11 +211,13 @@ module Sh
210
211
  scr_lyrics.add @txt_lyrics
211
212
  # Browse area
212
213
  browse = Sh::Browse.new self
214
+ queue = Sh::Queue.new self
213
215
  lst_tabs.selection.signal_connect('changed') do |selection|
214
216
  frm_content.remove frm_content.child if frm_content.child
215
217
  case selection.selected.path.indices[0]
216
218
  when TAB_QUEUE
217
- frm_content.child = Label.new 'Queue'
219
+ frm_content.child = queue.widget
220
+ queue.update
218
221
  when TAB_BROWSE
219
222
  frm_content.child = browse.widget
220
223
  when TAB_LYRICS
@@ -337,25 +340,25 @@ module Sh
337
340
  @note = nil
338
341
  if @rnotify
339
342
  # Prepare notification
340
- msg = "by <i>#{song.artist}</i> from <i>#{song.album}</i>"
343
+ msg = "by <i>#{song.artist.name}</i> from <i>#{song.album.title}</i>"
341
344
  @note = Notify::Notification.new(song.title || 'Unknown track', msg, nil, @status_icon)
342
345
  end
343
346
  # Cover art
344
347
  if $prefs[:cover_art]
345
348
  @pixbuf = nil
346
- (@pixbuf = Gdk::Pixbuf.new(song.image)) rescue Exception
349
+ (@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
347
350
  if @pixbuf
348
351
  @note.pixbuf_icon = @pixbuf.scale(48, 48) if @rnotify
349
352
  @img_cover.pixbuf = @pixbuf.scale(132, 132)
350
353
  else
351
354
  @img_cover.pixbuf = nil
352
355
  Thread.new do
353
- song.image = Sh::CoverArt.get_cover(song)
356
+ song.album.image_path = Sh::CoverArt.get_cover(song)
354
357
  $db.save_song song
355
358
  # Show cover unless requests have been shuffled
356
359
  if song == @player.song
357
360
  @pixbuf = nil
358
- (@pixbuf = Gdk::Pixbuf.new(song.image)) rescue Exception
361
+ (@pixbuf = Gdk::Pixbuf.new(song.album.image_path)) rescue Exception
359
362
  if @pixbuf
360
363
  if @rnotify
361
364
  @note.close
@@ -391,6 +394,10 @@ module Sh
391
394
  end
392
395
 
393
396
  public
397
+ def queue
398
+ return @queue
399
+ end
400
+
394
401
  def queue=(queue)
395
402
  @queue_pos = 0
396
403
  @queue = 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.3
4
+ version: 0.0.4
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-07-23 00:00:00 +10:00
12
+ date: 2009-07-26 00:00:00 +10:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -129,7 +129,10 @@ files:
129
129
  - lib/sh_global.rb
130
130
  - lib/sh_browse.rb
131
131
  - lib/sh_main.rb
132
+ - lib/sh_queue.rb
133
+ - lib/sh_album.rb
132
134
  - lib/sh_song.rb
135
+ - lib/sh_artist.rb
133
136
  - lib/sh_cover_art.rb
134
137
  - lib/sh_tagreader.rb
135
138
  - lib/sh_lyrics.rb