Created
January 13, 2016 03:43
-
-
Save gruen/f9023d7e26e4b81fac6d to your computer and use it in GitHub Desktop.
Ugly-ass script to convert recentsd-com.apple.mail.recents.plist to CSV for e-mailing purposes. Woohoo.
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
# encoding: UTF-8 | |
#### | |
# Ugly script that converts Mac OS X's recent history (recentsd-com.apple.mail.recents.plist) into a tsv (csv that is tab-delimited) | |
# Dependency: nokogiri | |
# Usage: ruby plist-to-tsv.rb input.plist output.tsv | |
# Thanks to: https://gist.github.com/patrikjohansson/3896557 | |
### | |
require "nokogiri" | |
if ARGV.size != 2 | |
puts "Usage: ruby plist-to-tsv.rb input.plist output" | |
end | |
input_file = File.open(ARGV[0]) | |
output_file = File.open(ARGV[1], "w+") | |
results = [] | |
def get_key_code(key) | |
return case key | |
when 's' | |
:from | |
when 'a' | |
:to | |
when 'n' | |
:to_name | |
else nil | |
end | |
end | |
doc = Nokogiri::XML.parse(input_file) | |
doc.xpath("//dict/dict/dict").each do |dict| | |
item = {} | |
multi_bin = [] | |
last_key = nil | |
dict.children.each do |gc| | |
next if gc.name == 'text' | |
# binding.pry | |
if gc.name == 'key' | |
last_key = get_key_code(gc.inner_text) | |
elsif gc.name == 'string' | |
item[last_key] = gc.inner_text | |
elsif gc.name == 'array' | |
multi_last_key = nil | |
gc.children.each do |ggc| | |
next if ggc.name == 'text' | |
if ggc.name == 'dict' | |
multi_item = {} | |
ggc.children.each do |gggc| | |
if gggc.name == 'key' | |
multi_last_key = get_key_code(gggc.inner_text) | |
elsif gggc.name == 'string' | |
multi_item[multi_last_key] = gggc.inner_text | |
end | |
end | |
multi_bin << multi_item | |
end | |
end | |
item[:multi] = multi_bin | |
end | |
end | |
item[:multi] ||= [] | |
results << item | |
end | |
output_file.puts "from_address\to_name\tto_address" | |
results.each do |item| | |
if item[:multi].empty? | |
output_file.puts "#{item[:from]}\t#{item[:to_name]}\t#{item[:to]}" | |
else | |
item[:multi].each do |i| | |
output_file.puts "#{item[:from]}\t#{i[:to_name]}\t#{i[:to]}" | |
end | |
end | |
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