Class: Muzak::Index

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/muzak/index.rb

Overview

Represents muzak's music index.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

album_art?, #build_response, #danger, #debug, #debug?, #error, #error!, music?, #output, #pretty, #verbose, #verbose?, which?

Constructor Details

#initialize(file: Config::INDEX_FILE) ⇒ Index

Returns a new instance of Index.

Parameters:

  • file (String) (defaults to: Config::INDEX_FILE)

    the path of the index data file



25
26
27
28
29
30
31
32
33
# File 'lib/muzak/index.rb', line 25

def initialize(file: Config::INDEX_FILE)
  debug "loading index from '#{file}'..."

  @file = file

  @hash = Marshal.load(File.read file)

  memoize_collections!
end

Instance Attribute Details

#fileString

Returns the path of the index data file.

Returns:

  • (String)

    the path of the index data file



16
17
18
# File 'lib/muzak/index.rb', line 16

def file
  @file
end

#hashHash

Returns the index hash.

Returns:

  • (Hash)

    the index hash



22
23
24
# File 'lib/muzak/index.rb', line 22

def hash
  @hash
end

#treeString

Returns the path of the root of the music tree.

Returns:

  • (String)

    the path of the root of the music tree



19
20
21
# File 'lib/muzak/index.rb', line 19

def tree
  @tree
end

Class Method Details

.load_index!Index

Returns a Muzak::Index instance instantiated with Config::INDEX_FILE.

Returns:



7
8
9
10
11
12
13
# File 'lib/muzak/index.rb', line 7

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

Instance Method Details

#album_namesArray<String>

Note:

albums with the same name will appear, but can't be disambiguated from here

Returns a list of all albums in the index.

Returns:

  • (Array<String>)

    a list of all albums in the index



95
96
97
# File 'lib/muzak/index.rb', line 95

def album_names
  artists.map { |a| @hash["artists"][a]["albums"].keys }.flatten
end

#albumsHash{String => Album}

Returns a hash of all album names with their Album objects.

Returns:

  • (Hash{String => Album})

    a hash of all album names with their Album objects



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/muzak/index.rb', line 62

def albums
  @albums_hash ||= begin
    albums_hash = {}

    artists.each do |a|
      @hash["artists"][a]["albums"].each do |title, album_hash|
        if deep?
          songs = album_hash["deep-songs"]
        else
          songs = album_hash["songs"].map { |s| Song.new(s) }
        end
        albums_hash[title] = Album.new(title, songs, album_hash["cover"])
      end
    end

    albums_hash
  end
end

#albums_by(artist) ⇒ Array<Album>

Returns all albums by the given artist.

Parameters:

  • artist (String)

    the artist's name

Returns:

  • (Array<Album>)

    all albums by the given artist



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/muzak/index.rb', line 101

def albums_by(artist)
  if artists.include?(artist)
    @hash["artists"][artist]["albums"].map do |title, album_hash|
      if deep?
        songs = album_hash["deep-songs"]
      else
        songs = album_hash["songs"].map { |s| Song.new(s) }
      end
      Album.new(title, songs, album_hash["cover"])
    end
  else
    error "no such artist: '#{artist}'" unless @hash["artists"].key?(artist)
    []
  end
end

#artistsArray<String>

Returns a list of all artists in the index.

Returns:

  • (Array<String>)

    a list of all artists in the index



56
57
58
# File 'lib/muzak/index.rb', line 56

def artists
  @hash["artists"].keys
end

#deep?Boolean

Returns whether or not the current index is deep.

Returns:

  • (Boolean)

    whether or not the current index is deep



46
47
48
# File 'lib/muzak/index.rb', line 46

def deep?
  @hash["deep"]
end

#jukebox(count = 50) ⇒ Array<Song>

Produces a 'jukebox' of random songs.

Parameters:

  • count (Integer) (defaults to: 50)

    the number of random songs to return

Returns:

  • (Array<Song>)

    an array of randomly chosen songs



120
121
122
123
124
125
126
# File 'lib/muzak/index.rb', line 120

def jukebox(count = 50)
  if deep?
    @all_deep_songs.sample(count)
  else
    @all_songs.sample(count).map { |s| Song.new(s) }
  end
end

#memoize_collections!void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Create some frequently accessed collections to speed things up a bit.



147
148
149
150
151
152
153
154
155
# File 'lib/muzak/index.rb', line 147

def memoize_collections!
  @all_albums = @hash["artists"].map { |_, a| a["albums"] }.flatten

  if deep?
    @all_deep_songs = @all_albums.map { |aa| aa.map { |_, a| a["deep-songs"] } }.flatten
  else
    @all_songs = @all_albums.map { |aa| aa.map { |_, a| a["songs"] } }.flatten
  end
end

#reload!void

Note:

This method does not rebuild the index data file.

This method returns an undefined value.

Refresh the Muzak::Index instance's state from the index data file.



38
39
40
41
42
43
# File 'lib/muzak/index.rb', line 38

def reload!
  debug "reloading index from '#{file}'..."
  @hash = Marshal.load(File.read file)
  @albums_hash = nil
  memoize_collections!
end

#songsArray<Song>

Note:

This method requires a deep index.

Returns a list of all Song objects in the index.

Returns:

  • (Array<Song>)

    a list of all Song objects in the index



83
84
85
86
87
88
89
90
# File 'lib/muzak/index.rb', line 83

def songs
  unless deep?
    danger "tried to call a deep-index-only method with a shallow index"
    return []
  end

  @all_deep_songs
end

#songs_by(artist) ⇒ Array<Song>

Note:

no inter-album order is guaranteed. songs within an album are generally sorted by track number.

Returns an array of all the artist's songs.

Parameters:

  • artist (String)

    the artist's name

Returns:

  • (Array<Song>)

    an array of all the artist's songs



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/muzak/index.rb', line 132

def songs_by(artist)
  error "no such artist: '#{artist}'" unless @hash["artists"].key?(artist)

  begin
    albums_by(artist).map do |album|
      album.songs
    end.flatten
  rescue Exception => e
    []
  end
end

#timestampInteger

Returns the UNIX timestamp from when the index was built.

Returns:

  • (Integer)

    the UNIX timestamp from when the index was built



51
52
53
# File 'lib/muzak/index.rb', line 51

def timestamp
  @hash["timestamp"]
end