class Muzak::Index
Represents muzak's music index.
Attributes
@return [String] the path of the index data file
@return [Hash] the index hash
@return [String] the path of the root of the music tree
Public Class Methods
@return [Index] a {Index} instance instantiated with {Config::INDEX_FILE}
# File lib/muzak/index.rb, line 9 def self.load_index! if File.exist?(Config::INDEX_FILE) Index.new else error! "#{Config::INDEX_FILE} missing, did you forget to run muzak-index?" end end
@param file [String] the path of the index data file
# File lib/muzak/index.rb, line 27 def initialize(file: Config::INDEX_FILE) debug "loading index from '#{file}'..." @file = file @hash = Marshal.load File.read(file) # rubocop:disable Security/MarshalLoad memoize_collections! end
Public Instance Methods
@return [Array<String>] a list of all albums in the index @note albums with the same name will appear, but can't be disambiguated
from here
# File lib/muzak/index.rb, line 92 def album_names artists.map { |a| @hash["artists"][a]["albums"].keys }.flatten end
@return [Hash{String => Album}] a hash of all album names with their
{Album} objects
# File lib/muzak/index.rb, line 63 def albums @albums_hash ||= begin albums_hash = {} artists.each do |a| @hash["artists"][a]["albums"].each do |title, album_hash| songs = load_songs album_hash albums_hash[title] = Album.new(title, songs, album_hash["cover"]) end end albums_hash end end
@param artist [String] the artist's name @return [Array<Album>] all albums by the given artist
# File lib/muzak/index.rb, line 98 def albums_by(artist) if artists.include?(artist) @hash["artists"][artist]["albums"].map do |title, album_hash| songs = load_songs album_hash Album.new(title, songs, album_hash["cover"]) end else error "no such artist: '#{artist}'" unless @hash["artists"].key?(artist) [] end end
@return [Array<String>] a list of all artists in the index
# File lib/muzak/index.rb, line 57 def artists @hash["artists"].keys end
@return [Boolean] whether or not the current index is deep
# File lib/muzak/index.rb, line 47 def deep? @hash["deep"] end
Produces a 'jukebox' of random songs. @param count [Integer] the number of random songs to return @return [Array<Song>] an array of randomly chosen songs
# File lib/muzak/index.rb, line 113 def jukebox(count = 50) if deep? @all_deep_songs.sample(count) else @all_songs.sample(count).map { |s| Song.new(s) } end end
Load the songs from an album hash into {Song} instances. @param ah [Hash] the album hash @api private
# File lib/muzak/index.rb, line 153 def load_songs(ah) if deep? ah["deep-songs"] else ah["songs"].map { |s| Song.new s } end end
Create some frequently accessed collections to speed things up a bit. @return [void] @api private
# File lib/muzak/index.rb, line 138 def memoize_collections! @all_albums = @hash["artists"].map { |_, a| a["albums"] }.flatten if deep? @all_deep_songs = @all_albums.map do |aa| aa.map { |_, a| a["deep-songs"] } end.flatten else @all_songs = @all_albums.map { |aa| aa.map { |_, a| a["songs"] } }.flatten end end
Refresh the {Index} instance's state from the index data file. @note This method does not rebuild the index data file. @return [void]
# File lib/muzak/index.rb, line 39 def reload! debug "reloading index from '#{file}'..." @hash = Marshal.load File.read(file) # rubocop:disable Security/MarshalLoad @albums_hash = nil memoize_collections! end
@return [Array<Song>] a list of all Song
objects in the index @note This method requires a deep index.
# File lib/muzak/index.rb, line 80 def songs unless deep? danger "tried to call a deep-index-only method with a shallow index" return [] end @all_deep_songs end
@param artist [String] the artist's name @return [Array<Song>] an array of all the artist's songs @note no inter-album order is guaranteed. songs within an album are
generally sorted by track number.
# File lib/muzak/index.rb, line 125 def songs_by(artist) error "no such artist: '#{artist}'" unless @hash["artists"].key?(artist) begin albums_by(artist).map(&:songs).flatten rescue [] end end
@return [Integer] the UNIX timestamp from when the index was built
# File lib/muzak/index.rb, line 52 def timestamp @hash["timestamp"] end