Skip to content

Instantly share code, notes, and snippets.

@patrikjohansson
Created October 16, 2012 00:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrikjohansson/3896557 to your computer and use it in GitHub Desktop.
Save patrikjohansson/3896557 to your computer and use it in GitHub Desktop.
Convert history.plist to csv
# encoding: UTF-8
####
# Converts Safaris history file (history.plist) into csv (tab)
# Dependency: nokogiri
# Usage: ruby read.rb input.plist output.csv
###
require "rubygems"
require "nokogiri"
if ARGV.size != 2
puts "Usage: ruby read.rb input.plist output"
end
input_file = File.open(ARGV[0])
output_file = File.open(ARGV[1], "w+")
results = []
doc = Nokogiri::XML.parse(input_file)
doc.xpath("//dict/array/dict").each do |dict|
item = {}
dict.children.each do |child|
next if child.name == 'text'
if child.name == "key"
case child.inner_text
when ""
item[:url] = nil
when "lastVisitedDate"
item[:last_visit] = nil
when "title"
item[:title] = nil
when "visitCount"
item[:visits] = nil
end
else
if item.include?(:url) && item[:url].nil? && child.name == "string" && child.inner_text.start_with?("http")
item[:url] = child.inner_text
elsif item.include?(:last_visit) && item[:last_visit].nil? && child.name == "string"
time = Time.at("1#{child.inner_text}".to_f)
item[:last_visit] = time
elsif item.include?(:title) && item[:title].nil? && child.name == "string"
item[:title] = child.inner_text
elsif item.include?(:visits) && item[:visits].nil? && child.name == "integer"
item[:visits] = child.inner_text.to_i
end
end
end
results << item
end
results.each do |item|
output_file.puts "#{item[:url]}\t#{item[:title]}\t#{item[:visits]}\t#{item[:last_visit]}"
end
output_file.close
input_file.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment