lib/audioinfo/album.rb in ruby-audioinfo-0.5.2 vs lib/audioinfo/album.rb in ruby-audioinfo-0.5.4

- old
+ new

@@ -1,146 +1,145 @@ -require "audioinfo" +# frozen_string_literal: true -class AudioInfo::Album +require 'audioinfo' - IMAGE_EXTENSIONS = %w{jpg jpeg gif png} +module AudioInfo + class Album + IMAGE_EXTENSIONS = %w[jpg jpeg gif png].freeze - # a regexp to match the "multicd" suffix of a "multicd" string - # example: "toto (disc 1)" will match ' (disc 1)' - MULTICD_REGEXP = /\s*(\(|\[)?\s*(disc|cd):?-?\s*(\d+).*(\)|\])?\s*$/i + # a regexp to match the "multicd" suffix of a "multicd" string + # example: "toto (disc 1)" will match ' (disc 1)' + MULTICD_REGEXP = /\s*(\(|\[)?\s*(disc|cd):?-?\s*(\d+).*(\)|\])?\s*$/i.freeze - attr_reader :files, :discnum, :multicd, :basename, :infos, :path + attr_reader :files, :discnum, :multicd, :basename, :infos, :path - # return the list of images in the album directory, with "folder.*" in first - 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) + # return the list of images in the album directory, with "folder.*" in first + 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 - # move "folder.*" image on top of the array - if folder = arr.detect { |f| f =~ /folder\.[^.]+$/ } - arr.delete(folder) - arr.unshift(folder) + + # strip the "multicd" string from the given +name+ + def self.basename(name) + name.sub(MULTICD_REGEXP, '') end - arr - end - # strip the "multicd" string from the given +name+ - def self.basename(name) - name.sub(MULTICD_REGEXP, '') - end - - # return the number of the disc in the box or 0 - def self.discnum(name) - if name =~ MULTICD_REGEXP - $3.to_i - else - 0 + # return the number of the disc in the box or 0 + def self.discnum(name) + if name =~ MULTICD_REGEXP + Regexp.last_match(3).to_i + else + 0 + end end - end - # open the Album with +path+. +fast_lookup+ will only check - # first and last file of the directory - 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(",") + # open the Album with +path+. +fast_lookup+ will only check + # first and last file of the directory + 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 } + # 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 + glob_val = File.join(glob_escaped_path, "*.{#{exts}}") + file_names = Dir.glob(glob_val).sort - if fast_lookup - file_names = [file_names.first, file_names.last] + 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 - @files = file_names.collect do |f| - AudioInfo.new(f) + # is the album empty? + def empty? + @files.empty? end - @infos = {} - @infos["album"] = @files.collect { |i| i.album }.uniq - @infos["album"] = @infos["album"].first if @infos["album"].size == 1 - artists = @files.collect { |i| i.artist }.uniq - @infos["artist"] = artists.size > 1 ? "various" : artists.first - @discnum = self.class.discnum(@infos["album"]) + # are all the files of the album MusicBrainz tagged ? + def mb_tagged? + return false if @files.empty? - if not @discnum.zero? - @multicd = true - @basename = self.class.basename(@infos["album"]) + mb = true + @files.each do |f| + mb &&= f.mb_tagged? + end + mb end - end - # is the album empty? - def empty? - @files.empty? - end + # return an array of images with "folder.*" in first + def images + self.class.images(@path) + end - # are all the files of the album MusicBrainz tagged ? - def mb_tagged? - return false if @files.empty? - mb = true - @files.each do |f| - mb &&= f.mb_tagged? + # title of the album + 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 - mb - end - # return an array of images with "folder.*" in first - def images - self.class.images(@path) - end + # mbid (MusicBrainz ID) of the album + def mbid + return nil unless mb_tagged? - # title of the album - def title - # count the occurences of the title and take the one who has most - hash_counted = self.files.collect { |f| f.album }.inject(Hash.new(0)) { |hash, album| hash[album] += 1; hash } - if hash_counted.empty? - nil - else - hash_counted.sort_by { |k, v| v }.last[0] + @files.collect { |f| f.musicbrainz_infos['albumid'] }.uniq.first end - end - # mbid (MusicBrainz ID) of the album - def mbid - return nil unless mb_tagged? - @files.collect { |f| f.musicbrainz_infos["albumid"] }.uniq.first - end + # is the album multi-artist? + def va? + @files.collect(&:artist).uniq.size > 1 + end - # is the album multi-artist? - def va? - @files.collect { |f| f.artist }.uniq.size > 1 - end + # pretty print + def to_s + out = StringIO.new + out.puts(@path) + out.print "'#{title}'" - # pretty print - def to_s - out = StringIO.new - out.puts(@path) - out.print "'#{title}'" + out.print " by '#{@files.first.artist}' " unless va? - unless va? - out.print " by '#{@files.first.artist}' " - end + out.puts - out.puts - - @files.sort_by { |f| f.tracknum }.each do |f| - out.printf("%02d %s %3d %s", f.tracknum, f.extension, f.bitrate, f.title) - if va? - out.print(" "+f.artist) + @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.puts + + out.string end - out.string - end - - def inspect - @infos.inspect + def inspect + @infos.inspect + end end end