Created
February 12, 2014 17:54
-
-
Save pingw33n/8960898 to your computer and use it in GitHub Desktop.
iBackup SMS to XML converter
This file contains hidden or 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 python | |
####################################################################### | |
# This is a script that converts iTunes SMS backup database (that is stored | |
# inf 3d0d7e5fb2ce288813306e4d4636395e047a3d28 file) into | |
# an XML file that can be restored on Android with SMS Backup & Restore | |
# app (https://play.google.com/store/apps/details?id=com.riteshsahu.SMSBackupRestore) | |
# | |
# Usage: | |
# python ibackup-sms-xml-converter.py /path/to/3d0d7e5fb2ce288813306e4d4636395e047a3d28 /path/to/smses.xml | |
# | |
# Use the generated smses.xml in the app on the target Android device. | |
####################################################################### | |
import xml.sax.saxutils | |
import xml.sax.xmlreader | |
import sqlite3 | |
import sys | |
def idate_to_unix(idate): | |
# The iEpoch starts from 01.01.2001 00:00:00. | |
return 978307200 + idate | |
def xml_start_element(xml_gen, name, attrs): | |
values = {} | |
qnames = {} | |
for attr_name, attr_value in attrs.items(): | |
values[(None, attr_name)] = unicode(attr_value) | |
qnames[(None, attr_name)] = attr_name | |
xml_gen.startElementNS((None, name), name, | |
xml.sax.xmlreader.AttributesNSImpl(values, qnames)) | |
def xml_end_element(xml, name): | |
xml.endElementNS((None, name), name) | |
input_filename = sys.argv[1] | |
output_filename = sys.argv[2] | |
print "Reading %s..." % input_filename | |
conn = sqlite3.connect(input_filename) | |
conn.row_factory = sqlite3.Row | |
c = conn.cursor() | |
c.execute( | |
""" | |
SELECT | |
h.uncanonicalized_id, id, m.text, m.date, m.is_from_me | |
FROM chat_message_join cmj | |
JOIN message m ON cmj.message_id = m.rowid | |
JOIN chat c ON cmj.chat_id = c.rowid | |
JOIN handle h ON m.handle_id = h.rowid | |
WHERE c.service_name = "SMS" | |
"""); | |
rows = c.fetchall() | |
print "Read %s SMS message(s)" % len(rows) | |
print "Creating %s..." % output_filename | |
output_file = file(output_filename, "wb+") | |
xml_gen = xml.sax.saxutils.XMLGenerator(output_file, "UTF-8") | |
xml_gen.startDocument() | |
xml_start_element(xml_gen, "smses", {"count": len(rows)}) | |
for row in rows: | |
id = row["id"] | |
uncanonicalized_id = row["uncanonicalized_id"] | |
address = uncanonicalized_id if not id.startswith("+") and uncanonicalized_id else id | |
type = 2 if row["is_from_me"] else 1 | |
xml_start_element(xml_gen, "sms", { | |
"protocol": 0, | |
"address": address, | |
"date": str(idate_to_unix(row["date"])) + "000", | |
"subject": "null", | |
"body": row["text"], | |
"toa": "null", | |
"sc_toa": "null", | |
"service_center": "null", | |
"read": 1, | |
"status": -1, | |
"type": type}) | |
xml_end_element(xml_gen, "smses") | |
xml_gen.endDocument() | |
print "Done" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment