-
Notifications
You must be signed in to change notification settings - Fork 0
/
calls_xml_to_tsv.py
105 lines (76 loc) · 3.05 KB
/
calls_xml_to_tsv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#########################################
# .: calls_xml_to_tsv.py :.
# Parses a calls xml backup file from Android app SMS Backup and Restore, parses out select data and generates a TSV file
# Usage: python3 calls_xml_to_tsv.py <your_sms_xml_file>
# eg: python3 calls_xml_to_tsv.py calls-20200917002015.xml
# .: Other :.
# Author: Timothy C. Quinn
# Home: https://github.com/JavaScriptDude/SMSBackupToTSV
# Licence: https://opensource.org/licenses/MIT
#########################################
import os, csv, traceback, sys
from xml.etree.ElementTree import parse as parse_xml
import common as smr
pc = smr.pc
def test(sDate):
sDate = sDate.replace('a.m.', 'AM').replace('p.m.', 'PM').replace('.', '').replace(',', '')
d = datetime.strptime(sDate, "%b %d, %Y %H:%M:%S %p")
def main(argv):
try:
(sFile) = smr.loadArgs(argv, 'calls')
sFilePrefix = sFile
aColumns = ['year', 'mon', 'day', 'time', 'dur(m)', 'contact', 'phone', 'type', 'timestamp']
out_fname = 'z_{}.tsv'.format(sFilePrefix)
tree = parse_xml(sFile)
calls = tree.getroot()
pc("""Backup info:
File: {}
count={}
backup_set={}
backup_date={}""".format(
sFile, calls.get('count'), calls.get('backup_set'), calls.get('backup_date')))
rows = []; iC = 0
for m in calls.findall('call'):
iC = iC + 1
# pc('type(m) = {}', type(m))
# pc('m = {}', smr.dump(m, True))
iType = smr.aget("m", m, 'type', req=True, toint=True)
if iType == 1:
sType = "1"
elif iType == 2:
sType = "2"
elif iType == 3:
sType = "3"
elif iType == 5:
sType = "5"
else:
raise Exception("Unexpected type {} in xml: {}".format(iType, smr.dump(m)))
sPhone = smr.fixPhone(smr.aget("m", m, 'number', req=True))
d = smr.dateFromTimestamp(smr.aget("m", m, 'date', req=True))
rows.append([
d.year, d.month, d.day, d.strftime('%H:%M:%S')
,round(smr.aget("m", m, 'duration', req=True, toint=True)/60, 1)
,smr.aget("m", m, 'contact_name', req=True)
,sPhone
,sType
,d.strftime('%y%m%d-%H%M%S')
])
pc("calls found: {}", iC)
# Sort
rows = sorted(rows, key=lambda r: (r[0], r[1], r[2], r[3]) )
fTmp = open(out_fname,'w', newline='')
bNewFile=True
wri = csv.writer(fTmp, delimiter='\t')
wri.writerow(aColumns)
for r in rows:
wri.writerow(r)
fTmp.close()
pc("Data written to: {}".format(out_fname))
pc('.: done :.')
pc('.')
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
sTB = '\n'.join(traceback.format_tb(exc_traceback))
pc("Fatal exception: {}\n - msg: {}\n stack: {}".format(exc_type, exc_value, sTB))
if __name__ == '__main__':
main(sys.argv[1:])