-
-
Save shanemcd/1175706 to your computer and use it in GitHub Desktop.
convert itunes music library to database sqlite3 using ruby
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
#!/usr/bin/env ruby | |
=begin | |
* Name: xml.rb | |
* Description parses xml iTunes Music Library and inserts into database | |
so other apps can use, rather than each time parsing xml file | |
* Author: Original - Aaron Patterson (xml parsing portion) | |
http://groups.google.com/group/nokogiri-talk/browse_thread/thread/97973521c6f5f0dc | |
* Additions by rkumar | |
* Date: 2010-08-04 | |
* License: | |
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt) | |
* create the itunes.sqlite file using http://gist.github.com/508400 | |
@usage | |
./xml2db.rb iTunes\ Music\ Library.xml | |
=end | |
require 'rubygems' | |
require 'nokogiri' | |
require 'sqlite3' | |
require 'arrayfields' | |
require "highline/import" | |
def table_insert_hash db, table, hash | |
str = "INSERT INTO #{table} (" | |
qstr = [] # question marks | |
fields = [] # field names | |
bind_vars = [] # values to insert | |
hash.each_pair { |name, val| | |
fields << name | |
bind_vars << val | |
qstr << "?" | |
} | |
fstr = fields.join(",") | |
str << fstr | |
str << ") values (" | |
str << qstr.join(",") | |
str << ")" | |
#puts str | |
db.execute(str, *bind_vars) | |
rowid = db.get_first_value( "select last_insert_rowid();") | |
return rowid | |
end | |
counter = 0 | |
dbname = "itunes.sqlite" | |
raise " #{dbname} must exist with tables in it - use http://gist.github.com/508400" | |
db = SQLite3::Database.new(dbname) | |
list = [] | |
filename = ARGV[0] || File.expand_path("~/Music/iTunes/iTunes Music Library.xml") | |
doc = Nokogiri::XML(File.open(filename, 'r')) | |
# Find each dictionary item and loop through it | |
doc.xpath('/plist/dict/dict/dict').each do |node| | |
#hash = {} | |
hash = Hash.new("Not found") | |
last_key = nil | |
# Stuff the key value pairs in to hash. We know a key is followed by | |
# a value, so we'll just skip blank nodes, save the key, then when we | |
# find the value, add it to the hash | |
node.children.each do |child| | |
next if child.blank? # Don't care about blank nodes | |
if child.name == 'key' | |
# Save off the key, lowercasing and putting _ for space | |
last_key = child.text.tr('A-Z','a-z').tr(' ','_') | |
else | |
# Use the key we saved | |
hash[last_key] = child.text | |
end | |
end | |
list << hash # push on to our list | |
hash["track_id"] = hash["track_id"].to_i | |
table_insert_hash db, "tracks", hash | |
print "." | |
counter += 1 | |
# for testing | |
if counter > 100 | |
#puts "exiting during testing" | |
#exit | |
end | |
end | |
puts "#{counter} items" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment