Created
September 17, 2008 11:04
-
-
Save atog/11226 to your computer and use it in GitHub Desktop.
Backup your iTunes library to Amazon S3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
itunes-s3.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# This little script backs up your iTunes Library to Amazon S3. | |
# | |
# You a need file 'itunes-s3.yml' with config settings | |
# containing the following info: | |
# | |
# s3_backup_bucket: your-itunes-backup | |
# s3_access_key_id: your_S3_id | |
# s3_secret_access_key: your_S3_access_key | |
# max_nr_per_run: 10 | |
# purchased_first: true | |
# | |
# Run by providing your iTunes Library xml file | |
# | |
# Changes 25/09: use filename as key in memory file instead of iTunes track_id. Too many problems. | |
# Changes 25/09: drop the whole memory thing. Too many problems. | |
# | |
# | |
require "rubygems" | |
require "libxml" | |
require "yaml" | |
require "aws/s3" | |
require "uri" | |
class Song | |
attr_accessor :filename, :purchased, :name, :artist, :key | |
def self.create(node) | |
song = Song.new | |
song.purchased = false | |
node.find('key').each do |k| | |
case k.content | |
when "Location": | |
song.filename = URI.decode(k.next.content.gsub('file://localhost', '')) | |
song.key = File.basename(song.filename) | |
when "Name": | |
song.name = k.next.content | |
when "Purchased": | |
song.purchased = true | |
when "Artist": | |
song.artist = k.next.content | |
end | |
end | |
song | |
end | |
def to_s | |
rvalue = "#{artist} - #{name} (#{key}, #{purchased.nil? ? false : true})" | |
end | |
end | |
class BackupManager | |
attr_reader :nr, :purchased_first, :counter, :bucket, :songs, :songs_done | |
def initialize | |
@settings = YAML.load_file('itunes-s3.yml') | |
@nr = @settings['max_nr_per_run'] || 10; | |
@purchased_first = @settings['purchased_first'] || true; | |
@bucket = @settings['s3_backup_bucket'] | |
@counter = 0; @songs = [] | |
AWS::S3::Base.establish_connection!( | |
:access_key_id => @settings['s3_access_key_id'], | |
:secret_access_key => @settings['s3_secret_access_key'] | |
) | |
fetch_stored | |
end | |
def backup(lib_xml) | |
load_lib(lib_xml) | |
for song in @songs | |
break if max? | |
save(song) | |
end | |
end | |
private | |
def load_lib(lib_xml) | |
doc = LibXML::XML::Document.file(lib_xml) | |
root = doc.root | |
doc.find('//plist/dict/dict/dict').each do |node| | |
@songs << Song.create(node) | |
end | |
if @purchased_first | |
@songs.sort!{|x,y| y.purchased.to_s <=> x.purchased.to_s} | |
end | |
end | |
def max? | |
@counter == @nr | |
end | |
# save the song to S3 | |
def save(song) | |
unless @songs_done.include?(song.key) | |
puts "Save #{song}" | |
AWS::S3::S3Object.store(song.key, open(song.filename), bucket) | |
@counter += 1 | |
@songs_done << song.key | |
end | |
end | |
def fetch_stored | |
puts "Fetching stored from S3" | |
@songs_done = AWS::S3::Bucket.find(bucket).objects.collect { |o| o.key } | |
puts "Done! (#{songs_done.size} songs)" | |
end | |
end | |
BackupManager.new.backup(ARGV[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment