Class: AudioInfo::Album

Inherits:
Object
  • Object
show all
Defined in:
lib/audioinfo/album.rb

Constant Summary collapse

IMAGE_EXTENSIONS =
%w[jpg jpeg gif png].freeze
MULTICD_REGEXP =

a regexp to match the “multicd” suffix of a “multicd” string example: “toto (disc 1)” will match ‘ (disc 1)’

/\s*(\(|\[)?\s*(disc|cd):?-?\s*(\d+).*(\)|\])?\s*$/i.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, fast_lookup = false) ⇒ Album

open the Album with path. fast_lookup will only check first and last file of the directory



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/audioinfo/album.rb', line 45

def initialize(path, fast_lookup = false)
  @path = path
  @multicd = false
  @basename = @path
  exts = AudioInfo::SUPPORTED_EXTENSIONS.collect do |ext|
    ext.gsub(/[a-z]/) { |c| "[#{c.downcase}#{c.upcase}]" }
  end.join(',')

  # need to escape the glob path
  glob_escaped_path = @path.gsub(/([{}?*\[\]])/) { |s| '\\' << s }

  glob_val = File.join(glob_escaped_path, "*.{#{exts}}")
  file_names = Dir.glob(glob_val).sort

  file_names = [file_names.first, file_names.last] if fast_lookup

  @files = file_names.collect do |f|
    AudioInfo.new(f)
  end

  @infos = {}
  @infos['album'] = @files.collect(&:album).uniq
  @infos['album'] = @infos['album'].first if @infos['album'].size == 1
  artists = @files.collect(&:artist).uniq
  @infos['artist'] = artists.size > 1 ? 'various' : artists.first
  @discnum = self.class.discnum(@infos['album'])

  unless @discnum.zero?
    @multicd = true
    @basename = self.class.basename(@infos['album'])
  end
end

Instance Attribute Details

#basenameObject (readonly)

Returns the value of attribute basename.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def basename
  @basename
end

#discnumObject (readonly)

Returns the value of attribute discnum.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def discnum
  @discnum
end

#filesObject (readonly)

Returns the value of attribute files.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def files
  @files
end

#infosObject (readonly)

Returns the value of attribute infos.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def infos
  @infos
end

#multicdObject (readonly)

Returns the value of attribute multicd.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def multicd
  @multicd
end

#pathObject (readonly)

Returns the value of attribute path.



13
14
15
# File 'lib/audioinfo/album.rb', line 13

def path
  @path
end

Class Method Details

.basename(name) ⇒ Object

strip the “multicd” string from the given name



30
31
32
# File 'lib/audioinfo/album.rb', line 30

def self.basename(name)
  name.sub(MULTICD_REGEXP, '')
end

.discnum(name) ⇒ Object

return the number of the disc in the box or 0



35
36
37
38
39
40
41
# File 'lib/audioinfo/album.rb', line 35

def self.discnum(name)
  if name =~ MULTICD_REGEXP
    Regexp.last_match(3).to_i
  else
    0
  end
end

.images(path) ⇒ Object

return the list of images in the album directory, with “folder.*” in first



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/audioinfo/album.rb', line 16

def self.images(path)
  path = path.dup.force_encoding('binary')
  arr = Dir.glob(File.join(path, "*.{#{IMAGE_EXTENSIONS.join(',')}}"), File::FNM_CASEFOLD).collect do |f|
    File.expand_path(f)
  end
  # move "folder.*" image on top of the array
  if folder = arr.detect { |f| f =~ /folder\.[^.]+$/ }
    arr.delete(folder)
    arr.unshift(folder)
  end
  arr
end

Instance Method Details

#empty?Boolean

is the album empty?

Returns:

  • (Boolean)


79
80
81
# File 'lib/audioinfo/album.rb', line 79

def empty?
  @files.empty?
end

#imagesObject

return an array of images with “folder.*” in first



95
96
97
# File 'lib/audioinfo/album.rb', line 95

def images
  self.class.images(@path)
end

#inspectObject



141
142
143
# File 'lib/audioinfo/album.rb', line 141

def inspect
  @infos.inspect
end

#mb_tagged?Boolean

are all the files of the album MusicBrainz tagged ?

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
92
# File 'lib/audioinfo/album.rb', line 84

def mb_tagged?
  return false if @files.empty?

  mb = true
  @files.each do |f|
    mb &&= f.mb_tagged?
  end
  mb
end

#mbidObject

mbid (MusicBrainz ID) of the album



111
112
113
114
115
# File 'lib/audioinfo/album.rb', line 111

def mbid
  return nil unless mb_tagged?

  @files.collect { |f| f.musicbrainz_infos['albumid'] }.uniq.first
end

#titleObject

title of the album



100
101
102
103
104
105
106
107
108
# File 'lib/audioinfo/album.rb', line 100

def title
  # count the occurences of the title and take the one who has most
  hash_counted = files.collect(&:album).each_with_object(Hash.new(0)) { |album, hash| hash[album] += 1; }
  if hash_counted.empty?
    nil
  else
    hash_counted.max_by { |_k, v| v }[0]
  end
end

#to_sObject

pretty print



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/audioinfo/album.rb', line 123

def to_s
  out = StringIO.new
  out.puts(@path)
  out.print "'#{title}'"

  out.print " by '#{@files.first.artist}' " unless va?

  out.puts

  @files.sort_by(&:tracknum).each do |f|
    out.printf('%02d %s %3d %s', f.tracknum, f.extension, f.bitrate, f.title)
    out.print(" #{f.artist}") if va?
    out.puts
  end

  out.string
end

#va?Boolean

is the album multi-artist?

Returns:

  • (Boolean)


118
119
120
# File 'lib/audioinfo/album.rb', line 118

def va?
  @files.collect(&:artist).uniq.size > 1
end