2024-10-31 18:31:15 +00:00
|
|
|
"""Backend for SyncTech Backup & Restore.
|
|
|
|
|
|
|
|
[SyncTech Backup & Restore](https://www.synctech.com.au/sms-backup-restore/)
|
|
|
|
for Android is a free app for backing up your SMS and MMS messages. It uses an
|
|
|
|
XML format as backup format, which this backend reads and converts to the
|
|
|
|
standardized Message format.
|
|
|
|
"""
|
2024-10-31 21:38:22 +00:00
|
|
|
|
2024-10-31 18:31:15 +00:00
|
|
|
import datetime
|
|
|
|
import logging
|
2024-10-31 19:36:38 +00:00
|
|
|
from collections.abc import Iterator
|
2024-10-31 18:31:15 +00:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
import bs4
|
|
|
|
|
2024-10-31 21:38:22 +00:00
|
|
|
from .data import MYSELF, Message
|
2024-10-31 18:31:15 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2024-10-31 23:36:30 +00:00
|
|
|
def normalize_phone_number(num: str) -> str:
|
|
|
|
num = num.replace(' ', '')
|
|
|
|
if num.startswith('00'):
|
|
|
|
num = '+' + num.removeprefix('00')
|
|
|
|
if len(num) == 8:
|
|
|
|
num = '+45' + num
|
|
|
|
elif len(num) >= 10 and num[0] != '+':
|
|
|
|
num = '+' + num
|
|
|
|
return num
|
|
|
|
|
2024-10-31 18:31:15 +00:00
|
|
|
|
2024-10-31 19:36:38 +00:00
|
|
|
def sms_soup_to_message(soup: bs4.BeautifulSoup) -> Message:
|
|
|
|
# TODO: Require myself
|
2024-10-31 21:38:22 +00:00
|
|
|
sent_at = datetime.datetime.fromtimestamp(int(soup['date']) / 1000)
|
2024-10-31 18:31:15 +00:00
|
|
|
|
2024-10-31 23:36:30 +00:00
|
|
|
phone_num = normalize_phone_number(soup['address'])
|
|
|
|
contact_name = soup.get('contact_name') or phone_num
|
2024-10-31 19:36:38 +00:00
|
|
|
if soup['type'] == '2':
|
2024-10-31 21:38:22 +00:00
|
|
|
sender = MYSELF
|
2024-10-31 19:36:38 +00:00
|
|
|
else:
|
2024-10-31 23:36:30 +00:00
|
|
|
sender = contact_name
|
2024-10-31 19:36:38 +00:00
|
|
|
|
|
|
|
text = soup['body']
|
2024-10-31 23:36:30 +00:00
|
|
|
chat_id = f'SMS {contact_name} {phone_num}'
|
2024-10-31 21:38:22 +00:00
|
|
|
return Message(sent_at, sender, text, chat_id=chat_id)
|
|
|
|
|
2024-10-31 19:36:38 +00:00
|
|
|
|
|
|
|
def parse_messages_in_backup_xml_file(path: Path) -> Iterator[Message]:
|
2024-10-31 18:31:15 +00:00
|
|
|
logger.info('Parsing %s', path)
|
|
|
|
|
|
|
|
with open(path) as f:
|
|
|
|
soup = bs4.BeautifulSoup(f, 'lxml-xml')
|
|
|
|
|
2024-10-31 19:36:38 +00:00
|
|
|
for sms in soup.find_all('sms'):
|
|
|
|
yield sms_soup_to_message(sms)
|
|
|
|
del sms
|