Class: IpodDB

Inherits:
Object
  • Object
show all
Defined in:
lib/ipod_db.rb,
lib/ipod_db/version.rb

Defined Under Namespace

Classes: NotAnIpod, PState, SD, Stats

Constant Summary collapse

ExtToFileType =
{
  '.mp3' => 1,
  '.aa' => 1,
  '.m4a' => 2,
  '.m4b' => 2,
  '.m4p' => 2,
  '.wav' => 4
}
VERSION =
'0.2.13'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root_dir) ⇒ IpodDB

Returns a new instance of IpodDB.



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ipod_db.rb', line 38

def initialize root_dir
  @root_dir = root_dir
  begin
    read
  rescue Errno::ENOENT
    raise NotAnIpod.new @root_dir
  rescue IOError => error
    puts "Corrupt database, creating a-new"
    init_db
  end
end

Instance Attribute Details

#playback_stateObject (readonly)

Returns the value of attribute playback_state.



21
22
23
# File 'lib/ipod_db.rb', line 21

def playback_state
  @playback_state
end

Class Method Details

.looks_like_ipod?(path) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/ipod_db.rb', line 50

def IpodDB.looks_like_ipod? path
  Dir.exists? File.join(path,'iPod_Control','iTunes')
end

.sanitize_filename(filename) ⇒ Object



159
160
161
# File 'lib/ipod_db.rb', line 159

def self.sanitize_filename filename
  ActiveSupport::Inflector.transliterate(filename, '_')
end

Instance Method Details

#[](filename_or_index) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/ipod_db.rb', line 142

def [] filename_or_index
  case filename_or_index
  when Integer
    @tracks.values[filename_or_index]
  else
    @tracks[filename_or_index]
  end
end

#current_filenameObject



71
72
73
# File 'lib/ipod_db.rb', line 71

def current_filename
  @tracks.keys[ @playback_state.trackno ]
end

#each_trackObject



134
135
136
# File 'lib/ipod_db.rb', line 134

def each_track
  @tracks.each_value {|track| yield track}
end

#each_track_with_indexObject



138
139
140
# File 'lib/ipod_db.rb', line 138

def each_track_with_index
  @tracks.each_with_index {|path_track,i| yield path_track[1], i}
end

#include?(track) ⇒ Boolean

Returns:

  • (Boolean)


81
# File 'lib/ipod_db.rb', line 81

def include? track ; @tracks.include? track ; end

#init_dbObject



66
67
68
69
# File 'lib/ipod_db.rb', line 66

def init_db
  @playback_state = PState.new
  @tracks = Map.new
end

#inspectObject



151
152
153
# File 'lib/ipod_db.rb', line 151

def inspect
  "<IpodDB>"
end

#make_filename(suffix) ⇒ Object



155
156
157
# File 'lib/ipod_db.rb', line 155

def make_filename suffix
  "#{@root_dir}/iPod_Control/iTunes/iTunes#{suffix}"
end

#readObject



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ipod_db.rb', line 54

def read
  @playback_state = read_records PState, 'PState'
  stats = read_records Stats, 'Stats'
  sd = read_records SD, 'SD'
  @tracks = Map.new
  stats.records.each_with_index do |stat,i|
    h = stat.snapshot.merge( sd.records[i].snapshot )
    h.delete :reclen
    @tracks[ h[:filename].to_s ] = h
  end
end

#read_records(bindata, file_suffix) ⇒ Object



75
76
77
78
79
# File 'lib/ipod_db.rb', line 75

def read_records bindata, file_suffix
  File.open make_filename(file_suffix) do |io|
    bindata.read io
  end
end

#saveObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ipod_db.rb', line 112

def save
  stats = Stats.new
  sd = SD.new
  @tracks.each_value do |track|
    stats.records << track.subset(:bookmarktime, :playcount, :skippedcount)
    sd.records << track.subset(:starttime, :stoptime, :volume, :file_type, :filename,
                                :shuffleflag, :bookmarkflag)
  end
  write_records @playback_state, 'PState'
  write_records stats, 'Stats'
  write_records sd, 'SD'

  shuffle = make_filename('Shuffle')
  File.delete shuffle if File.exists? shuffle
end

#update(*args) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ipod_db.rb', line 83

def update *args
  opts = Map.options(args)
  new_books = opts.getopt :books, default: []
  new_songs = opts.getopt :songs, default: []
  new_tracks = new_books + new_songs
  prev_current_filename = current_filename

  old_tracks = @tracks.keys.clone # clone because otherwise it'll change during iteration
  old_tracks.each do |filename|
    @tracks.delete filename unless new_tracks.include? filename
  end
  old_tracks = @tracks
  @tracks = Map.new
  new_books.each do |filename|
    @tracks[filename] = old_tracks[filename] || {:filename => filename}
    @tracks[filename].merge! shuffleflag: false, bookmarkflag: true
  end
  new_songs.each do |filename|
    @tracks[filename] = old_tracks[filename] || {:filename => filename}
    @tracks[filename].merge! shuffleflag: true, bookmarkflag: false
  end
  if @tracks.include? prev_current_filename
    @playback_state.trackno = @tracks.find_index{|filename,t|filename == prev_current_filename}
  else
    @playback_state.trackno = -1
    @playback_state.trackpos = -1
  end
end

#write_records(bindata, file_suffix) ⇒ Object



128
129
130
131
132
# File 'lib/ipod_db.rb', line 128

def write_records bindata, file_suffix
  File.open( make_filename(file_suffix), 'w' ) do |io|
    bindata.write io
  end
end