class Kagu::Finder
Constants
- MANDATORY_ATTRIBUTES
Public Class Methods
new(options = {})
click to toggle source
# File lib/kagu/finder.rb, line 21 def initialize(options = {}) @semaphore = Mutex.new reload(options) end
replace(value, replacements = {})
click to toggle source
# File lib/kagu/finder.rb, line 9 def self.replace(value, replacements = {}) replaced = value.to_s.dup replacements.each do |pattern, replacement| replaced.gsub!(pattern, replacement) end replaced.presence end
transliterate(value)
click to toggle source
# File lib/kagu/finder.rb, line 17 def self.transliterate(value) ActiveSupport::Inflector.transliterate(value.to_s).squish.downcase.presence end
Public Instance Methods
find(attributes = {})
click to toggle source
# File lib/kagu/finder.rb, line 26 def find(attributes = {}) attributes.stringify_keys! results = [].tap do |matches| tracks_digests.each_with_index do |hash, digests_index| digests(attributes).each_with_index do |digest, digest_index| tracks = hash[digest].presence || next tracks = tracks.reject { |track| matches.any? { |match| match.try(:include?, track) } } next if tracks.empty? index = [digests_index, digest_index].max matches[index] ||= [] matches[index].push(*tracks) end end end results.compact! replacements.any? ? results : results.flatten end
ignored()
click to toggle source
# File lib/kagu/finder.rb, line 44 def ignored @ignored ||= [] end
ignored?(track)
click to toggle source
# File lib/kagu/finder.rb, line 48 def ignored?(track) track.present? && digests(track).any? { |digest| ignored.include?(digest) } end
reload(options = {})
click to toggle source
# File lib/kagu/finder.rb, line 52 def reload(options = {}) @ignored = nil @replacements = nil @tracks_digests = nil options.each do |name, value| send("#{name}=", value) if respond_to?("#{name}=", true) end self end
reload!(options = {})
click to toggle source
# File lib/kagu/finder.rb, line 62 def reload!(options = {}) @tracks = nil reload(options) end
replacements()
click to toggle source
# File lib/kagu/finder.rb, line 67 def replacements @replacements ||= [] end
Private Instance Methods
digests(attributes)
click to toggle source
# File lib/kagu/finder.rb, line 73 def digests(attributes) attributes = { 'artist' => attributes.artist, 'title' => attributes.title } unless attributes.is_a?(Hash) attributes.stringify_keys! return [] if attributes['artist'].blank? || attributes['title'].blank? digests = [transliterate("#{attributes['artist']} #{attributes['title']}")] replacements.each do |item| digests << replace(digests.last, item) end digests.uniq end
ignored=(values)
click to toggle source
# File lib/kagu/finder.rb, line 84 def ignored=(values) @ignored = [values].flatten.map do |value| case value when Hash value = value.stringify_keys value = "#{value['artist']} #{value['title']}" when Track value = "#{value.artist} #{value.title}" else value = value.to_s end self.class.transliterate(value) end.compact.uniq end
replacements=(value)
click to toggle source
# File lib/kagu/finder.rb, line 99 def replacements=(value) if value.nil? @replacements = [] elsif value.is_a?(Hash) @replacements = [value] elsif value.is_a?(Array) @replacements = value else raise("Replacements must be an array or a hash, #{value.inspect} given") end replacements.each do |item| raise('Replacements must contain only hashes or arrays') unless item.is_a?(Hash) || item.is_a?(Array) end end
tracks()
click to toggle source
# File lib/kagu/finder.rb, line 114 def tracks @semaphore.synchronize do unless @tracks @tracks = Tracks.new.to_a Kagu.logger.debug('Kagu') { "Loaded #{@tracks.size} track(s) from library" } end @tracks end end
tracks_digests()
click to toggle source
# File lib/kagu/finder.rb, line 124 def tracks_digests @tracks_digests ||= begin [].tap do |tracks_digests| tracks.each do |track| digests = digests(track) next if digests.any? { |digest| ignored.include?(digest) } digests.each_with_index do |digest, index| tracks_digests[index] ||= {} tracks_digests[index][digest] ||= [] tracks_digests[index][digest].push(track) end end end end end