shroom 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README +5 -5
- data/Rakefile +5 -5
- data/bin/shroom +1 -0
- data/lib/{shroom-res → res}/cover_unavailable.png +0 -0
- data/lib/{shroom-res → res}/icon_128x128.png +0 -0
- data/lib/{shroom-res → res}/icon_16x16.png +0 -0
- data/lib/res/license.txt +674 -0
- data/lib/res/plugin.png +0 -0
- data/lib/{shroom-res → res}/plugins/lastfm_scrobbler.rb +0 -0
- data/lib/{shroom-res → res}/shroom.glade +1 -1
- data/lib/res/shroom_resources_signpost +2 -0
- data/lib/sh_actions.rb +14 -16
- data/lib/sh_browse.rb +29 -17
- data/lib/sh_cover_browse.rb +1 -1
- data/lib/sh_database.rb +12 -2
- data/lib/sh_fingerprint.rb +2 -15
- data/lib/sh_global.rb +4 -2
- data/lib/sh_lastfm.rb +64 -0
- data/lib/sh_log.rb +13 -11
- data/lib/sh_main.rb +2 -2
- data/lib/sh_playlist.rb +8 -2
- data/lib/sh_queue.rb +1 -1
- data/lib/sh_tagreader.rb +65 -33
- data/lib/sh_util.rb +17 -4
- data/lib/sh_view.rb +103 -34
- metadata +19 -16
- data/lib/sh_cover_art.rb +0 -26
data/lib/res/plugin.png
ADDED
Binary file
|
File without changes
|
@@ -290,7 +290,7 @@
|
|
290
290
|
<property name="visible">True</property>
|
291
291
|
<property name="can_focus">True</property>
|
292
292
|
<property name="invisible_char">●</property>
|
293
|
-
<property name="adjustment">1
|
293
|
+
<property name="adjustment">1 0 99 1 5 5</property>
|
294
294
|
</widget>
|
295
295
|
<packing>
|
296
296
|
<property name="left_attach">2</property>
|
data/lib/sh_actions.rb
CHANGED
@@ -45,30 +45,29 @@ module Sh
|
|
45
45
|
if queue
|
46
46
|
queue << song
|
47
47
|
else
|
48
|
-
view.
|
49
|
-
view.queue_pos = 0
|
48
|
+
view.set_queue([song])
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
53
52
|
action[:stock_image] = Stock::ADD
|
54
53
|
|
55
54
|
action = Actions.new 'Reread tags', :song do |song|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
view = Sh::View.instance
|
56
|
+
proc = Proc.new do |s|
|
57
|
+
path = s.path
|
58
|
+
s.delete
|
59
|
+
Database.add_song path
|
60
|
+
end
|
61
|
+
view ? view.update_song(song, &proc) : proc.call(song)
|
62
62
|
end
|
63
63
|
action[:stock_image] = Stock::HARDDISK
|
64
64
|
|
65
65
|
if try_require 'earworm' and try_require 'rbrainz'
|
66
66
|
action = Actions.new 'Lookup metadata automatically', :song do |song|
|
67
67
|
if song.lookup!
|
68
|
-
|
69
|
-
|
70
|
-
song.
|
71
|
-
browse.insert_song song if browse
|
68
|
+
view = Sh::View.instance
|
69
|
+
proc = Proc.new {|s| s.save}
|
70
|
+
view ? view.update_song(song, &proc) : proc.call(song)
|
72
71
|
end
|
73
72
|
end
|
74
73
|
action[:stock_image] = Stock::FIND
|
@@ -130,14 +129,13 @@ module Sh
|
|
130
129
|
end
|
131
130
|
btn_ok = glade['btn_ok']
|
132
131
|
ok_handle = btn_ok.signal_connect('clicked') do
|
133
|
-
browse = Browse.instance
|
134
132
|
song.title = txt_title.text
|
135
133
|
song.track_num = spn_track_num.value
|
136
134
|
song.artist = cmb_artist.active_iter[1]
|
137
135
|
song.album = cmb_album.active_iter[1]
|
138
|
-
|
139
|
-
|
140
|
-
|
136
|
+
view = Sh::View.instance
|
137
|
+
proc = Proc.new {|s| s.save}
|
138
|
+
view ? view.update_song(song, &proc) : proc.call(song)
|
141
139
|
dlg_song.hide
|
142
140
|
end
|
143
141
|
btn_cancel = glade['btn_cancel']
|
data/lib/sh_browse.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
module Sh
|
2
2
|
class Browse
|
3
|
-
@@instance = nil
|
4
|
-
|
5
3
|
def initialize view
|
6
|
-
Sh::Log.warning 'Instance of Browse already created!' if @@instance
|
7
|
-
@@instance = self
|
8
4
|
@tree = TreeView.new
|
9
5
|
@tree.selection.mode = Gtk::SELECTION_MULTIPLE
|
10
6
|
|
@@ -13,7 +9,7 @@ module Sh
|
|
13
9
|
col_artist.set_cell_data_func(ren_artist) do |tvc, cell, model, iter|
|
14
10
|
cell.text = ''
|
15
11
|
data = iter[0]
|
16
|
-
if data.is_a?
|
12
|
+
if data.is_a? Song
|
17
13
|
if data.title
|
18
14
|
cell.text = "%.2d\t%s" % [data.track_num, data.title]
|
19
15
|
else
|
@@ -26,9 +22,19 @@ module Sh
|
|
26
22
|
@tree.append_column col_artist
|
27
23
|
|
28
24
|
@model = TreeStore.new(Object, Array)
|
29
|
-
@model.set_default_sort_func do |
|
30
|
-
|
31
|
-
|
25
|
+
@model.set_default_sort_func do |oa, ob|
|
26
|
+
a1, b1 = oa[0].to_s, ob[0].to_s
|
27
|
+
a2, b2 = a1.gsub(/[^\w ]/, ""), b1.gsub(/[^\w ]/, "")
|
28
|
+
cmp = 0
|
29
|
+
|
30
|
+
unless a2.empty? or b2.empty?
|
31
|
+
cmp = a2.casecmp b2 if cmp == 0
|
32
|
+
cmp = a2 <=> b2 if cmp == 0
|
33
|
+
end
|
34
|
+
|
35
|
+
cmp = a1.casecmp b1 if cmp == 0
|
36
|
+
cmp = a1 <=> b1 if cmp == 0
|
37
|
+
cmp
|
32
38
|
end
|
33
39
|
@model.set_sort_column_id(TreeSortable::DEFAULT_SORT_COLUMN_ID,
|
34
40
|
Gtk::SORT_ASCENDING)
|
@@ -113,12 +119,11 @@ module Sh
|
|
113
119
|
iter.next!
|
114
120
|
end
|
115
121
|
queue.insert 0, *prev
|
116
|
-
view.queue
|
117
|
-
view.queue_pos = prev.size
|
122
|
+
view.set_queue queue, prev.size
|
118
123
|
view.play
|
119
124
|
elsif not iter[1].empty?
|
120
125
|
view.stop
|
121
|
-
view.
|
126
|
+
view.set_queue iter[1].dup
|
122
127
|
view.play
|
123
128
|
end
|
124
129
|
end
|
@@ -127,16 +132,21 @@ module Sh
|
|
127
132
|
@scroll.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
128
133
|
@scroll.add @tree
|
129
134
|
end
|
130
|
-
|
131
|
-
def self.instance
|
132
|
-
return @@instance
|
133
|
-
end
|
134
135
|
|
135
136
|
def widget
|
136
137
|
return @scroll
|
137
138
|
end
|
138
139
|
|
140
|
+
def update_song song
|
141
|
+
# TODO: Improve this
|
142
|
+
remove_song song
|
143
|
+
new_song = yield song
|
144
|
+
song = new_song if new_song.is_a? Song
|
145
|
+
insert_song song
|
146
|
+
end
|
147
|
+
|
139
148
|
def remove_song song
|
149
|
+
# TODO: Improve this
|
140
150
|
song_node = nil
|
141
151
|
if song.is_a? TreeIter
|
142
152
|
song_node = song
|
@@ -153,9 +163,11 @@ module Sh
|
|
153
163
|
artist_node = album_node.parent
|
154
164
|
@model.remove song_node
|
155
165
|
album_node[1].delete song
|
156
|
-
|
166
|
+
# Removal of these nodes are commented out because they can result
|
167
|
+
# in parentless song nodes
|
168
|
+
#@model.remove album_node unless album_node.has_child?
|
157
169
|
artist_node[1].delete song
|
158
|
-
|
170
|
+
#@model.remove artist_node unless artist_node.has_child?
|
159
171
|
end
|
160
172
|
end
|
161
173
|
|
data/lib/sh_cover_browse.rb
CHANGED
data/lib/sh_database.rb
CHANGED
@@ -97,6 +97,15 @@ module Sh
|
|
97
97
|
s.album = album
|
98
98
|
s.title = tags[:title]
|
99
99
|
s.track_num = tags[:track_num]
|
100
|
+
|
101
|
+
image = tags[:cover_art]
|
102
|
+
if image
|
103
|
+
image_path = File.join(Global::PATHS[:cover_dir], image.to_md5)
|
104
|
+
open(image_path, 'w') do |file|
|
105
|
+
file.write image
|
106
|
+
end
|
107
|
+
s.image_path = image_path
|
108
|
+
end
|
100
109
|
end
|
101
110
|
|
102
111
|
return song
|
@@ -158,12 +167,13 @@ module Sh
|
|
158
167
|
many_to_one :album
|
159
168
|
|
160
169
|
def to_s
|
161
|
-
|
170
|
+
metadata = [artist, album, track_num, title || File.basename(path)]
|
171
|
+
return "%s, %s, %.2d - %s" % metadata
|
162
172
|
end
|
163
173
|
|
164
174
|
def to_html
|
165
175
|
t = title
|
166
|
-
t =
|
176
|
+
t = File.basename(path) if not t or t.strip == ""
|
167
177
|
t = CGI.escapeHTML t
|
168
178
|
ar = artist.name
|
169
179
|
ar = "Unknown" if not ar or ar.strip == ""
|
data/lib/sh_fingerprint.rb
CHANGED
@@ -7,8 +7,8 @@ module Sh
|
|
7
7
|
Log.debug "Earworming #{song.path}"
|
8
8
|
ew = Earworm::Client.new(KEYS[:music_dns])
|
9
9
|
info = ew.identify :file => song.path
|
10
|
-
title =
|
11
|
-
artist_name =
|
10
|
+
title = info.title.unescape_html
|
11
|
+
artist_name = info.artist_name.unescape_html
|
12
12
|
puids = info.puid_list || []
|
13
13
|
return false unless title and artist_name
|
14
14
|
|
@@ -47,18 +47,5 @@ module Sh
|
|
47
47
|
|
48
48
|
return true
|
49
49
|
end
|
50
|
-
|
51
|
-
def self.unescape_html str
|
52
|
-
entities = {
|
53
|
-
""" => "\"",
|
54
|
-
"'" => "'",
|
55
|
-
"&" => "&",
|
56
|
-
"<" => "<",
|
57
|
-
">" => ">",
|
58
|
-
" " => " "
|
59
|
-
}
|
60
|
-
|
61
|
-
return CGI.unescapeHTML(str.gsub(/&\w*;/) {|e| entities[e] || e})
|
62
|
-
end
|
63
50
|
end
|
64
51
|
end
|
data/lib/sh_global.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'pathname'
|
2
3
|
require 'yaml'
|
3
4
|
require 'libglade2'
|
4
5
|
require 'ping'
|
@@ -12,7 +13,7 @@ module Sh
|
|
12
13
|
}
|
13
14
|
|
14
15
|
class Global
|
15
|
-
SUPPORTED_EXTENSIONS =
|
16
|
+
SUPPORTED_EXTENSIONS = %w{.mp3 .m4a .ogg .oga .flac .wma .wav}
|
16
17
|
GLADE = {}
|
17
18
|
PATHS = {}
|
18
19
|
|
@@ -56,7 +57,8 @@ module Sh
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def self.locate(file)
|
59
|
-
find_in_load_path("
|
60
|
+
signpost = find_in_load_path(File.join("res", "shroom_resources_signpost"))
|
61
|
+
return Pathname.new(signpost).dirname.join(file).expand_path.to_s if signpost
|
60
62
|
end
|
61
63
|
|
62
64
|
def self.prefs
|
data/lib/sh_lastfm.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'hpricot'
|
2
|
+
|
3
|
+
module Sh
|
4
|
+
class LastFM
|
5
|
+
@album_getInfo = Rest::Get.new("http://ws.audioscrobbler.com/2.0",
|
6
|
+
:api_key => KEYS[:lastfm], :method => "album.getInfo")
|
7
|
+
@artist_getInfo = Rest::Get.new("http://ws.audioscrobbler.com/2.0",
|
8
|
+
:api_key => KEYS[:lastfm], :method => "artist.getInfo")
|
9
|
+
|
10
|
+
def self.get_album_info album
|
11
|
+
artist = album.artist.name
|
12
|
+
title = album.title
|
13
|
+
|
14
|
+
if artist and title
|
15
|
+
image_path = File.join(Global::PATHS[:cover_dir], "#{artist.to_md5}_#{title.to_md5}")
|
16
|
+
doc = Hpricot(@album_getInfo[:artist => artist, :album => title])
|
17
|
+
|
18
|
+
if File.exists? image_path and File.size?(image_path) and File.size?(image_path) > 0
|
19
|
+
album.image_path = image_path
|
20
|
+
else
|
21
|
+
begin
|
22
|
+
img_url = doc.at('/lfm/album/image[@size="extralarge"]').inner_html.strip
|
23
|
+
input = open(img_url).read
|
24
|
+
if input and not input.empty?
|
25
|
+
open(image_path, 'w') {|output| output << input}
|
26
|
+
album.image_path = image_path
|
27
|
+
end
|
28
|
+
rescue
|
29
|
+
album.image_path = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
(album.info ||= (doc/'/lfm/album/wiki/content').inner_text.strip.unescape_html) rescue Exception
|
34
|
+
(album.mbid ||= (doc/'/lfm/album/mbid').inner_html.strip) rescue Exception
|
35
|
+
end
|
36
|
+
album.save
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.get_artist_info artist
|
40
|
+
name = artist.name
|
41
|
+
|
42
|
+
if name
|
43
|
+
image_path = File.join(Global::PATHS[:cover_dir], name.to_md5)
|
44
|
+
doc = Hpricot(@artist_getInfo[:artist => name])
|
45
|
+
|
46
|
+
size = File.size?(image_path)
|
47
|
+
if File.exists? image_path and size and size > 0
|
48
|
+
artist.image_path = image_path
|
49
|
+
else
|
50
|
+
begin
|
51
|
+
img_url = doc.at('/lfm/artist/image[@size="extralarge"]').inner_html.strip
|
52
|
+
open(image_path, 'w') {|output| output << open(img_url).read}
|
53
|
+
artist.image_path = image_path
|
54
|
+
rescue
|
55
|
+
artist.image_path = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
(artist.info ||= (doc/'/lfm/artist/bio/content').inner_text.strip.unescape_html) rescue Exception
|
61
|
+
(artist.mbid ||= (doc/'/lfm/artist/mbid').inner_html.strip) rescue Exception
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/sh_log.rb
CHANGED
@@ -6,22 +6,24 @@ module Sh
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def write str
|
9
|
-
@buffer ||=
|
9
|
+
@buffer ||= ""
|
10
10
|
@buffer << str
|
11
|
-
if @buffer.end_with? "\n"
|
12
|
-
case @type
|
13
|
-
when :stderr
|
14
|
-
Log.error '> ' + @buffer
|
15
|
-
when :stdout
|
16
|
-
Log.info '> ' + @buffer
|
17
|
-
end
|
18
|
-
@buffer = nil
|
19
|
-
end
|
11
|
+
flush if @buffer.end_with? "\n"
|
20
12
|
end
|
21
13
|
|
22
14
|
def puts str
|
23
|
-
write str
|
15
|
+
write "#{str}\n"
|
24
16
|
end
|
17
|
+
|
18
|
+
def flush
|
19
|
+
case @type
|
20
|
+
when :stderr
|
21
|
+
Log.error "> #{@buffer}"
|
22
|
+
when :stdout
|
23
|
+
Log.info "> #{@buffer}"
|
24
|
+
end
|
25
|
+
@buffer = ""
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
LEVELS = [:debug, :info, :warning, :error]
|
data/lib/sh_main.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
# Problems occur when 'socket' is not required first
|
4
4
|
require 'socket'
|
@@ -20,7 +20,7 @@ module Sh
|
|
20
20
|
class Main
|
21
21
|
def initialize
|
22
22
|
Log.info 'Shroom started'
|
23
|
-
|
23
|
+
|
24
24
|
# See sh_player.rb for why this Wx stuff is necessary
|
25
25
|
Wx::App.run do
|
26
26
|
View.new.show
|
data/lib/sh_playlist.rb
CHANGED
@@ -14,8 +14,14 @@ module Sh
|
|
14
14
|
line.strip!
|
15
15
|
unless line[0] == ?# or line.empty?
|
16
16
|
begin
|
17
|
-
|
18
|
-
|
17
|
+
ref = line
|
18
|
+
begin
|
19
|
+
ref = GLib.filename_from_uri(ref)
|
20
|
+
rescue
|
21
|
+
# TODO: make cross-platform
|
22
|
+
ref = File.expand_path(ref.gsub('\\', '/'), File.dirname(path))
|
23
|
+
end
|
24
|
+
|
19
25
|
if File.exists? ref
|
20
26
|
if Global::SUPPORTED_EXTENSIONS.include? File.extname(ref)
|
21
27
|
list << (Song.first(:path => ref) || Database.add_song(ref))
|
data/lib/sh_queue.rb
CHANGED
data/lib/sh_tagreader.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'sh_util'
|
2
2
|
require 'sh_log'
|
3
|
+
require 'base64'
|
3
4
|
|
4
5
|
module Sh
|
5
6
|
class TagReader
|
6
|
-
def self.read path
|
7
|
+
def self.read path
|
7
8
|
# Ensure that the path is absolute
|
8
9
|
@path = File.expand_path path
|
9
10
|
|
@@ -15,7 +16,7 @@ module Sh
|
|
15
16
|
else
|
16
17
|
# Attempt to use the `file` command
|
17
18
|
begin
|
18
|
-
type = `file --mime-type -b #{@path}
|
19
|
+
type = `file --mime-type -b "#{@path.gsub('"', '\\"')}"`.strip
|
19
20
|
@mime = type if type[0..5] == 'audio/'
|
20
21
|
rescue Exception
|
21
22
|
@mime = nil
|
@@ -30,7 +31,7 @@ module Sh
|
|
30
31
|
'.ogg' => 'audio/ogg',
|
31
32
|
'.wav' => 'audio/x-wav',
|
32
33
|
'.wma' => 'audio/x-ms-wma'
|
33
|
-
}[File.extname
|
34
|
+
}[File.extname(@path)]
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -57,12 +58,12 @@ module Sh
|
|
57
58
|
end
|
58
59
|
|
59
60
|
# Report on our metadata findings
|
60
|
-
yield metadata if
|
61
|
+
yield metadata if block_given?
|
61
62
|
return metadata
|
62
63
|
end
|
63
64
|
|
64
65
|
# Read metadata from MP3 file
|
65
|
-
def self.read_mp3 path
|
66
|
+
def self.read_mp3 path
|
66
67
|
metadata = {}
|
67
68
|
if try_require 'mp3info'
|
68
69
|
Mp3Info.open path do |mp3|
|
@@ -73,16 +74,25 @@ module Sh
|
|
73
74
|
metadata[:year] = t.year.to_i
|
74
75
|
metadata[:track_num] = t.tracknum.to_i
|
75
76
|
metadata[:duration] = mp3.length
|
77
|
+
|
78
|
+
begin
|
79
|
+
if mp3.tag2 and mp3.tag2['APIC']
|
80
|
+
a = mp3.tag2['APIC'].last
|
81
|
+
a = a[1..-1].sub(/[^\0]*\0/, "")[1..-1].sub(/[^\0]*\0/, "")
|
82
|
+
metadata[:cover_art] = a
|
83
|
+
end
|
84
|
+
rescue
|
85
|
+
end
|
76
86
|
end
|
77
87
|
else
|
78
|
-
Log.info 'Please install the "mp3info" gem in order to read MP3 info'
|
88
|
+
Log.info 'Please install the "ruby-mp3info" gem in order to read MP3 info'
|
79
89
|
end
|
80
|
-
yield metadata if
|
90
|
+
yield metadata if block_given?
|
81
91
|
return metadata
|
82
92
|
end
|
83
93
|
|
84
94
|
# Read metadata from M4A file
|
85
|
-
def self.read_m4a path
|
95
|
+
def self.read_m4a path
|
86
96
|
metadata = {}
|
87
97
|
if try_require 'mp4info'
|
88
98
|
mp4 = MP4Info.open path
|
@@ -92,35 +102,55 @@ module Sh
|
|
92
102
|
metadata[:year] = mp4.DAY.to_i
|
93
103
|
metadata[:track_num] = mp4.TRKN.first.to_i
|
94
104
|
metadata[:duration] = mp4.SECS
|
105
|
+
metadata[:cover_art] = mp4.COVR if mp4.COVR
|
95
106
|
else
|
96
|
-
Log.info 'Please install the "
|
107
|
+
Log.info 'Please install the "MP4Info" gem in order to read M4A info'
|
97
108
|
end
|
98
109
|
yield metadata if block
|
99
110
|
return metadata
|
100
111
|
end
|
101
112
|
|
102
|
-
# Read metadata from
|
103
|
-
def self.read_ogg path
|
113
|
+
# Read metadata from Ogg Vorbis file
|
114
|
+
def self.read_ogg path
|
104
115
|
metadata = {}
|
105
|
-
if try_require '
|
106
|
-
|
107
|
-
|
108
|
-
metadata[:
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
116
|
+
if try_require 'vorbis'
|
117
|
+
Vorbis::Info.open path do |info|
|
118
|
+
dur = info.duration
|
119
|
+
metadata[:duration] = dur if dur and dur > 0
|
120
|
+
|
121
|
+
info.comments.each do |k, vs|
|
122
|
+
if vs and vs.any?
|
123
|
+
v = vs.first
|
124
|
+
|
125
|
+
case k
|
126
|
+
when 'TITLE'
|
127
|
+
metadata[:title] = v.to_u
|
128
|
+
when 'ARTIST'
|
129
|
+
metadata[:artist] = v.to_u
|
130
|
+
when 'ALBUM'
|
131
|
+
metadata[:album] = v.to_u
|
132
|
+
when 'YEAR'
|
133
|
+
metadata[:year] = v.to_i
|
134
|
+
when 'TRACKNUMBER'
|
135
|
+
metadata[:track_num] = v.to_i
|
136
|
+
when 'COVERART'
|
137
|
+
metadata[:cover_art] = Base64.decode64(v)
|
138
|
+
when 'METADATA_BLOCK_PICTURE'
|
139
|
+
# TODO: Support this:
|
140
|
+
# http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
|
141
|
+
end
|
142
|
+
end rescue Exception
|
143
|
+
end
|
114
144
|
end rescue Exception
|
115
145
|
else
|
116
|
-
Log.info 'Please install the "
|
146
|
+
Log.info 'Please install the "ruby-ogg" gem in order to read Vorbis info'
|
117
147
|
end
|
118
|
-
yield metadata if
|
148
|
+
yield metadata if block_given?
|
119
149
|
return metadata
|
120
150
|
end
|
121
151
|
|
122
|
-
|
123
|
-
def self.read_flac path
|
152
|
+
# Read metadata from FLAC file
|
153
|
+
def self.read_flac path
|
124
154
|
metadata = {}
|
125
155
|
if try_require 'flacinfo'
|
126
156
|
flac = FlacInfo.new(path)
|
@@ -142,15 +172,17 @@ module Sh
|
|
142
172
|
metadata[:track_num] = value.to_i
|
143
173
|
end
|
144
174
|
end
|
175
|
+
|
176
|
+
#TODO: Support METADATA_BLOCK_PICTURE
|
145
177
|
else
|
146
|
-
Log.info 'Please install the "flacinfo" gem in order to read FLAC info'
|
178
|
+
Log.info 'Please install the "flacinfo-rb" gem in order to read FLAC info'
|
147
179
|
end
|
148
|
-
yield metadata if
|
180
|
+
yield metadata if block_given?
|
149
181
|
return metadata
|
150
182
|
end
|
151
183
|
|
152
|
-
|
153
|
-
def self.read_wma path
|
184
|
+
# Read metadata from WMA file
|
185
|
+
def self.read_wma path
|
154
186
|
metadata = {}
|
155
187
|
if try_require 'wmainfo'
|
156
188
|
wma = WmaInfo.new(path)
|
@@ -172,14 +204,14 @@ module Sh
|
|
172
204
|
end
|
173
205
|
metadata[:duration] = wma.info["playtime_seconds"]
|
174
206
|
else
|
175
|
-
Log.info 'Please install the "wmainfo" gem in order to read WMA info'
|
207
|
+
Log.info 'Please install the "wmainfo-rb" gem in order to read WMA info'
|
176
208
|
end
|
177
|
-
yield metadata if
|
209
|
+
yield metadata if block_given?
|
178
210
|
return metadata
|
179
211
|
end
|
180
212
|
|
181
|
-
|
182
|
-
def self.read_wave path
|
213
|
+
# Read metadata from Wave file
|
214
|
+
def self.read_wave path
|
183
215
|
metadata = {}
|
184
216
|
if try_require 'waveinfo'
|
185
217
|
wave = WaveInfo.new path
|
@@ -187,7 +219,7 @@ module Sh
|
|
187
219
|
else
|
188
220
|
Log.info 'Please install the "waveinfo" gem in order to read WAV info'
|
189
221
|
end
|
190
|
-
yield metadata if
|
222
|
+
yield metadata if block_given?
|
191
223
|
return metadata
|
192
224
|
end
|
193
225
|
end
|