From a2c6c26d30f6bfa99a86c9baa77ed0364aa59e30 Mon Sep 17 00:00:00 2001 From: alswl Date: Sun, 22 Jan 2012 11:46:05 +0800 Subject: [PATCH] support Sms backup & restore! --- model/contact.py | 1 + parser/best_message_storer_parser.py | 33 ++--------- parser/parser.py | 31 +++++++++++ parser/sms_backup_and_restore_parser.py | 73 +++++++++++++++++++++++++ smsir.py | 21 +++++-- 5 files changed, 126 insertions(+), 33 deletions(-) create mode 100644 parser/sms_backup_and_restore_parser.py diff --git a/model/contact.py b/model/contact.py index dc51db1..13d2987 100644 --- a/model/contact.py +++ b/model/contact.py @@ -27,3 +27,4 @@ def adjust_name(self): # TODO update for first name / last name self.name = self.name.replace(' ', '') self.name = self.name.replace('!', '') + self.name = self.name.replace('!', '') diff --git a/parser/best_message_storer_parser.py b/parser/best_message_storer_parser.py index d43baad..d96aa60 100644 --- a/parser/best_message_storer_parser.py +++ b/parser/best_message_storer_parser.py @@ -1,7 +1,7 @@ #!/usr/bin/env python #coding=utf-8 -# desc: Parser +# desc: Parser for Best message storer on Symbian # author: alswl # date: 2011-01-07 @@ -96,29 +96,8 @@ def process_block(self, text): if number.find('+86') < 0: # fix number don't has +86 number = '+86' + number - contact_phone_items = session.query(Contact, Phone). \ - filter(Contact.id == Phone.contact_id). \ - filter(Phone.number == number).all() - if len(contact_phone_items) > 0: - contact, phone = contact_phone_items[0] - else: - contact = Contact(name=name) - phone = Phone(number) - phone.contact = contact - contact.adjust_name() - session.add(contact) - session.commit() - - sms = session.query(Sms).filter_by(number=number, - create_at=create_at).first() - if not sms is None: # 重复的短信 - raise DuplicateError - - sms = Sms() - sms.create_at = create_at - sms.number = number - sms.phone = phone - sms.content = content - sms.type = type_number - sms.contact = contact - self.smses.append(sms) + super(Best_message_storer_parser, self).save_sms(type, + name, + number, + content, + create_at) diff --git a/parser/parser.py b/parser/parser.py index ea87b81..123fc50 100644 --- a/parser/parser.py +++ b/parser/parser.py @@ -6,6 +6,9 @@ # date: 2011-01-07 from model.sms import Sms +from model.contact import Contact +from model.phone import Phone +from config import Base, session class Parser(object): def __init__(self): @@ -17,6 +20,34 @@ def __init__(self): def parse(self, text): pass + def save_sms(self, type, name, number, content, create_at): + contact_phone_items = session.query(Contact, Phone). \ + filter(Contact.id == Phone.contact_id). \ + filter(Phone.number == number).all() + if len(contact_phone_items) > 0: + contact, phone = contact_phone_items[0] + else: + contact = Contact(name=name) + phone = Phone(number) + phone.contact = contact + contact.adjust_name() + session.add(contact) + session.commit() + + sms = session.query(Sms).filter_by(number=number, + create_at=create_at).first() + if not sms is None: # 重复的短信 + raise DuplicateError + + sms = Sms() + sms.create_at = create_at + sms.number = number + sms.phone = phone + sms.content = content + sms.type = type + sms.contact = contact + self.smses.append(sms) + class FormatError(ValueError): """非法格式""" pass diff --git a/parser/sms_backup_and_restore_parser.py b/parser/sms_backup_and_restore_parser.py new file mode 100644 index 0000000..0bdc732 --- /dev/null +++ b/parser/sms_backup_and_restore_parser.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +#coding=utf-8 + +# desc: Parser for sms backup & restore on Android +# author: alswl +# date: 2011-01-21 + +import logging +import re +from datetime import datetime + +from BeautifulSoup import BeautifulSoup + +from model.sms import Sms +from model.contact import Contact +from model.phone import Phone +from parser import Parser, FormatError, DuplicateError +from config import Base, session + +logger = logging.getLogger(__name__) + +class SmsBackupAndRestoreParser(Parser): + + def __init__(self, xml): + super(SmsBackupAndRestoreParser, self).__init__() + self.xml = xml + self.smses = [] + + def parse(self): + soup = BeautifulSoup(self.xml) + for sms_node in soup.findAll('sms'): + try: + self.process_block(sms_node) + self.success_count += 1 + except FormatError, e: + #logger.info('%s is not illegal format' %block) # FIXME + self.format_error_count += 1 + self.fail_count +=1 + continue + except DuplicateError, e: + self.duplicate_error_count +=1 + self.fail_count +=1 + continue + return self.smses + + def print_result(self): + print '# Success:\t%d' %self.success_count + print '# Failed:\t%d' %self.fail_count + print '# duplicate error\t%d' %self.duplicate_error_count + print '# format error\t%d' %self.format_error_count + + def process_block(self, node): + type_text = node.get('type') + number = node.get('address') + content = node.get('body') + create_at = node.get('date') + name = node.get('contact_name') + + if not type_text.isdigit() or \ + not create_at.isdigit(): + raise FormatError + type = int(type_text) + if number.find('+86') < 0: # fix number don't has +86 + number = '+86' + number + if name is None: + name = unicode(number) + create_at = datetime.fromtimestamp(float(create_at) / 1000) + + super(SmsBackupAndRestoreParser, self).save_sms(type, + name, + number, + content, + create_at) diff --git a/smsir.py b/smsir.py index 67c848c..ed0949d 100755 --- a/smsir.py +++ b/smsir.py @@ -11,6 +11,7 @@ from model.sms import Sms from model.contact import Contact from parser.best_message_storer_parser import Best_message_storer_parser +from parser.sms_backup_and_restore_parser import SmsBackupAndRestoreParser logger = logging.getLogger(__name__) @@ -32,23 +33,22 @@ def run(self): parser.add_argument('--list-messages', '-l', action='store_true', help='list all messages') - parser.add_argument('--import-sms-backup-restore', '-b', - type=argparse.FileType('r'), - metavar='FILE', - help='import messages from SMS Backup & Restore') parser.add_argument('--import-best-message-storer', '-B', type=argparse.FileType('r'), metavar='FILE', nargs='+', help='import messages from Best MessageStorer backups') + parser.add_argument('--import-sms-backup-and-restore', '-S', + type=argparse.FileType('r'), + metavar='FILE', + nargs='+', + help='import messages from Sms Backup & Restore') args = parser.parse_args() if args.create: self.create_all() elif args.list_messages: self.list_messages() - elif args.import_sms_backup_restore != None: - pass elif args.import_best_message_storer != None: for text in args.import_best_message_storer: best_message_storer_parser = Best_message_storer_parser( @@ -58,6 +58,15 @@ def run(self): session.add_all(smses) session.commit() best_message_storer_parser.print_result() + elif not args.import_sms_backup_and_restore is None: + for xml in args.import_sms_backup_and_restore: + sms_backup_restore_parser = SmsBackupAndRestoreParser( + xml.read().decode('utf-8') + ) + smses = sms_backup_restore_parser.parse() + session.add_all(smses) + session.commit() + sms_backup_restore_parser.print_result() else: parser.print_help()