예제 #1
0
def _import_one_sms(data, current_number=None, dry_run=False):
    # define who's the actor and who's the receiver
    other_number = unicode(data['Number'])
    if data['State'] == 'Sent':
        sent_by, sent_to = current_number, other_number
    else:
        sent_by, sent_to = other_number, current_number

    fields = dict(
        sent_by = sent_by,
        sent_to = sent_to,
        date_time = data['DateTime'],
        #is_confirmed = True,  # it is sent, yup
        summary = data['Text'] or u'[text missing]',  # u'' is invalid, None not accepted
    )
    search_fields = dict(fields)
    search_fields.pop('summary')

    # workaround: we don't know which number was "current" when the message was
    # last imported, so we look for any "our" number.
    my_numbers = _get_my_numbers()
    k = 'sent_by' if data['State']=='Sent' else 'sent_to'
    search_fields.pop(k)
    search_fields.update({'{0}__in'.format(k): my_numbers.values()})

    db = app.get_feature('document_storage').default_db
    if not GammuSMS.objects(db).where(**search_fields).count():
        #print 'NOT FOUND:', search_fields
        print u'SAVING {0} {1} → {2} {3}{4}'.format(
            fields['date_time'], sent_by, sent_to, fields['summary'][:20],
            u'…' if 20 < len(fields['summary']) else '')
        if dry_run:
            return '(stub: dry run)'
        else:
            return GammuSMS(**fields).save(db)
예제 #2
0
def import_sms(args):
    """Imports SMS from mobile phone.

    :param current_phone:
        Expects "current phone" so that incoming and outgoing messages can be
        correctly populated with both sender and receiver numbers (the phone only
        stores the "other" number) and you have to manually specify yours). Can be
        omitted if there's only one "my number" in the settings.

        Note that you should specify the label (e.g. "personal", "work" or
        "primary") instead of the number itself. The labels are defined in the
        "my_numbers" setting for the bundle::

            extensions:
                orgtool.ext.mobile.MobileETL:
                    my_numbers:
                        home: +1234567890
                        work: +0987654321

    :param full_archive:
        If True, attempts to import all messages in the phone. Despite this
        implies checking for duplicates, the process takes longer and issues
        with dates and phone numbers may arise. By default this option is off
        and only "new" messages are imported. Message is considered "new" if
        its date is greater than the last known message's date. Time is
        ignored in this check.

    :param dry_run:
        If True, newly imported messages are not saved. Use this for testing.
        Default is False.

    """
    if args.dry_run:
        yield 'Dry run, no data will be changed.'

    db = app.get_feature('document_storage').default_db
    my_numbers = _get_my_numbers()
    current_number = None
    if args.current_phone:
        assert args.current_phone in my_numbers, (
            'unknown number label "{0}"'.format(args.current_phone))
        current_number = my_numbers[args.current_phone]
    else:
        if len(my_numbers) != 1:
            raise CommandError('Which phone (SIM card) is that? Choices: '
                               '{0}'.format(', '.join(my_numbers)))
        the_only_label = my_numbers.keys()[0]
        current_number = my_numbers[the_only_label]
    assert current_number

    # find latest known message date
    if args.full_archive:
        last_imported_date = None
        yield 'Importing all messages from the phone...'
    else:
        msgs = GammuSMS.objects(db).order_by('date_time', reverse=True)
        last_imported_date = msgs[0].date_time.date() if msgs.count() else None
        yield 'Importing messages since {0}...'.format(last_imported_date)

    sm = _get_state_machine()

    seen_cnt = saved_cnt = 0
    for data in _iterate_results(sm.GetNextSMS, Folder=0):
        if last_imported_date and not args.full_archive:
            # skip message without full check if a later message had been
            # already imported
            if data['DateTime'].date() < last_imported_date:
                continue
        saved = _import_one_sms(data, current_number, dry_run=args.dry_run)
        if saved:
            saved_cnt += 1
        seen_cnt += 1

    yield 'Imported {saved_cnt} of {seen_cnt}.'.format(**locals())
    if args.dry_run:
        yield '(Dry run, nothing really changed.)'