43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
BPATH = "/L/backups/SMSBackupRestore"
|
|
import re
|
|
import pytz
|
|
_RE = re.compile(r'calls-\d+.xml')
|
|
|
|
from typing import Dict, List, NamedTuple, Iterator, Iterable
|
|
from datetime import datetime
|
|
|
|
class Call(NamedTuple):
|
|
dt: datetime
|
|
duration_s: int
|
|
who: str
|
|
|
|
@property
|
|
def summary(self) -> str:
|
|
return f"talked with {self.who} for {self.duration_s}"
|
|
|
|
|
|
def _extract_calls(fname: str) -> Iterator[Call]:
|
|
from lxml import etree # type: ignore
|
|
tr = etree.parse(fname)
|
|
for cxml in tr.findall('call'):
|
|
# TODO we've got local tz herer, not sure if useful..
|
|
# ok, so readable date is local datetime, cahnging throughout the backup
|
|
dt = pytz.utc.localize(datetime.utcfromtimestamp(int(cxml.get('date')) / 1000))
|
|
yield Call(
|
|
dt=dt,
|
|
duration_s=int(cxml.get('duration')),
|
|
who=cxml.get('contact_name') # TODO number if contact is unavail??
|
|
# TODO type? must be missing/outgoing/incoming
|
|
)
|
|
|
|
def get_calls():
|
|
import os
|
|
calls: Dict[datetime, Call] = {}
|
|
for n in sorted([x for x in os.listdir(BPATH) if _RE.match(x)]):
|
|
# for c in _extract_calls(os.path.join(BPATH, n)):
|
|
# cc = calls.get(c.dt, None)
|
|
# if cc is not None and cc != c:
|
|
# print(f"WARNING: {cc} vs {c}")
|
|
calls.update({c.dt: c for c in _extract_calls(os.path.join(BPATH, n))})
|
|
# always replacing with latter is good, we get better contact names
|
|
return sorted(calls.values(), key=lambda c: c.dt)
|