Example #1
0
def add_fake_message(db_session, namespace_id, thread=None, from_addr=None,
                     to_addr=None, cc_addr=None, bcc_addr=None,
                     received_date=None, subject='',
                     body='', snippet='', add_sent_category=False):
    from inbox.models import Message, Category
    from inbox.contacts.process_mail import update_contacts_from_message
    m = Message()
    m.namespace_id = namespace_id
    m.from_addr = from_addr or []
    m.to_addr = to_addr or []
    m.cc_addr = cc_addr or []
    m.bcc_addr = bcc_addr or []
    m.received_date = received_date or datetime.utcnow()
    m.size = 0
    m.is_read = False
    m.is_starred = False
    m.body = body
    m.snippet = snippet
    m.subject = subject

    if thread:
        thread.messages.append(m)
        update_contacts_from_message(db_session, m, thread.namespace)

        db_session.add(m)
        db_session.commit()

    if add_sent_category:
        category = Category.find_or_create(
            db_session, namespace_id, 'sent', 'sent', type_='folder')
        if category not in m.categories:
            m.categories.add(category)
        db_session.commit()

    return m
Example #2
0
    def handle_raw_folder_change(self, db_session, account, raw_folder):
        folder = db_session.query(Folder).filter(
            Folder.account_id == account.id,
            Folder.canonical_name == raw_folder.role).first()
        if folder:
            if folder.name != raw_folder.display_name:
                log.info('Folder name changed on remote',
                         account_id=self.account_id,
                         role=raw_folder.role,
                         new_name=raw_folder.display_name,
                         name=folder.name)
                folder.name = raw_folder.display_name

            if folder.category:
                if folder.category.display_name != \
                        raw_folder.display_name:
                    folder.category.display_name = raw_folder.display_name  # noqa
            else:
                log.info('Creating category for folder',
                         account_id=self.account_id,
                         folder_name=folder.name)
                folder.category = Category.find_or_create(
                    db_session, namespace_id=account.namespace.id,
                    name=raw_folder.role,
                    display_name=raw_folder.display_name,
                    type_='folder')
        else:
            Folder.find_or_create(db_session, account,
                                  raw_folder.display_name,
                                  raw_folder.role)
Example #3
0
def add_fake_category(db_session, namespace_id, display_name, name=None):
    from inbox.models import Category
    category = Category(namespace_id=namespace_id,
                        display_name=display_name,
                        name=name)
    db_session.add(category)
    db_session.commit()
    return category
def create_categories_for_folders(account, db_session):
    from inbox.models import Folder, Category
    for folder in db_session.query(Folder).filter(
            Folder.account_id == account.id):
        cat = Category.find_or_create(
            db_session, namespace_id=account.namespace.id,
            name=folder.canonical_name, display_name=folder.name,
            type_='folder')
        folder.category = cat
    db_session.commit()
def create_categories_for_folders(account, db_session):
    from inbox.models import Folder, Category
    for folder in db_session.query(Folder).filter(
            Folder.account_id == account.id):
        cat = Category.find_or_create(db_session,
                                      namespace_id=account.namespace.id,
                                      name=folder.canonical_name,
                                      display_name=folder.name,
                                      type_='folder')
        folder.category = cat
    db_session.commit()
Example #6
0
def add_fake_message(
    db_session,
    namespace_id,
    thread=None,
    from_addr=None,
    to_addr=None,
    cc_addr=None,
    bcc_addr=None,
    received_date=None,
    subject="",
    body="",
    snippet="",
    g_msgid=None,
    add_sent_category=False,
):
    from inbox.contacts.processing import update_contacts_from_message
    from inbox.models import Category, Message

    m = Message()
    m.namespace_id = namespace_id
    m.from_addr = from_addr or []
    m.to_addr = to_addr or []
    m.cc_addr = cc_addr or []
    m.bcc_addr = bcc_addr or []
    m.received_date = received_date or datetime.utcnow()
    m.size = 0
    m.is_read = False
    m.is_starred = False
    m.body = body
    m.snippet = snippet
    m.subject = subject
    m.g_msgid = g_msgid

    if thread:
        thread.messages.append(m)
        update_contacts_from_message(db_session, m, thread.namespace.id)

        db_session.add(m)
        db_session.commit()

    if add_sent_category:
        category = Category.find_or_create(db_session,
                                           namespace_id,
                                           "sent",
                                           "sent",
                                           type_="folder")
        if category not in m.categories:
            m.categories.add(category)
        db_session.commit()

    return m
Example #7
0
def test_query_target(db, api_client, thread, default_namespace):
    cat = Category(namespace_id=default_namespace.id,
                   name='inbox', display_name='Inbox', type_='label')
    for _ in range(3):
        message = add_fake_message(db.session, default_namespace.id, thread,
                                   to_addr=[('Bob', '*****@*****.**')],
                                   from_addr=[('Alice', '*****@*****.**')],
                                   subject='some subject')
        message.categories.add(cat)
    db.session.commit()

    results = api_client.get_data('/messages?in=inbox')
    assert len(results) == 3

    count = api_client.get_data('/messages?in=inbox&view=count')
    assert count['count'] == 3
Example #8
0
def add_fake_message(db_session,
                     namespace_id,
                     thread=None,
                     from_addr=None,
                     to_addr=None,
                     cc_addr=None,
                     bcc_addr=None,
                     received_date=None,
                     subject='',
                     body='',
                     snippet='',
                     add_sent_category=False):
    from inbox.models import Message, Category
    from inbox.contacts.process_mail import update_contacts_from_message
    m = Message()
    m.namespace_id = namespace_id
    m.from_addr = from_addr or []
    m.to_addr = to_addr or []
    m.cc_addr = cc_addr or []
    m.bcc_addr = bcc_addr or []
    m.received_date = received_date or datetime.utcnow()
    m.size = 0
    m.is_read = False
    m.is_starred = False
    m.body = body
    m.snippet = snippet
    m.subject = subject

    if thread:
        thread.messages.append(m)
        update_contacts_from_message(db_session, m, thread.namespace)

        db_session.add(m)
        db_session.commit()

    if add_sent_category:
        category = Category.find_or_create(db_session,
                                           namespace_id,
                                           'sent',
                                           'sent',
                                           type_='folder')
        if category not in m.categories:
            m.categories.add(category)
        db_session.commit()

    return m
Example #9
0
def folders_labels_create_api():
    category_type = g.namespace.account.category_type
    data = request.get_json(force=True)
    display_name = data.get('display_name')

    valid_display_name(g.namespace.id, category_type, display_name,
                       g.db_session)

    category = Category.find_or_create(g.db_session, g.namespace.id,
                                       name=None, display_name=display_name,
                                       type_=category_type)
    g.db_session.flush()

    if category_type == 'folder':
        schedule_action('create_folder', category, g.namespace.id, g.db_session)
    else:
        schedule_action('create_label', category, g.namespace.id, g.db_session)

    return g.encoder.jsonify(category)
Example #10
0
    def handle_raw_folder_change(self, db_session, account, raw_folder):
        folder = (
            db_session.query(Folder)
            .filter(
                Folder.account_id == account.id,
                Folder.canonical_name == raw_folder.role,
            )
            .first()
        )
        if folder:
            if folder.name != raw_folder.display_name:
                log.info(
                    "Folder name changed on remote",
                    account_id=self.account_id,
                    role=raw_folder.role,
                    new_name=raw_folder.display_name,
                    name=folder.name,
                )
                folder.name = raw_folder.display_name

            if folder.category:
                if folder.category.display_name != raw_folder.display_name:
                    folder.category.display_name = raw_folder.display_name
            else:
                log.info(
                    "Creating category for folder",
                    account_id=self.account_id,
                    folder_id=folder.id,
                )
                folder.category = Category.find_or_create(
                    db_session,
                    namespace_id=account.namespace.id,
                    name=raw_folder.role,
                    display_name=raw_folder.display_name,
                    type_="folder",
                )
        else:
            Folder.find_or_create(
                db_session, account, raw_folder.display_name, raw_folder.role
            )
Example #11
0
def folders_labels_create_api():
    category_type = g.namespace.account.category_type
    data = request.get_json(force=True)
    display_name = data.get('display_name')

    valid_display_name(g.namespace.id, category_type, display_name,
                       g.db_session)

    category = Category.find_or_create(g.db_session,
                                       g.namespace.id,
                                       name=None,
                                       display_name=display_name,
                                       type_=category_type)
    g.db_session.flush()

    if category_type == 'folder':
        schedule_action('create_folder', category, g.namespace.id,
                        g.db_session)
    else:
        schedule_action('create_label', category, g.namespace.id, g.db_session)

    return g.encoder.jsonify(category)
Example #12
0
def test_query_target(db, api_client, thread, default_namespace):
    cat = Category(
        namespace_id=default_namespace.id,
        name="inbox",
        display_name="Inbox",
        type_="label",
    )
    for _ in range(3):
        message = add_fake_message(
            db.session,
            default_namespace.id,
            thread,
            to_addr=[("Bob", "*****@*****.**")],
            from_addr=[("Alice", "*****@*****.**")],
            subject="some subject",
        )
        message.categories.add(cat)
    db.session.commit()

    results = api_client.get_data("/messages?in=inbox")
    assert len(results) == 3

    count = api_client.get_data("/messages?in=inbox&view=count")
    assert count["count"] == 3
Example #13
0
def test_filtering(db, api_client, default_namespace):
    thread = add_fake_thread(db.session, default_namespace.id)
    message = add_fake_message(db.session,
                               default_namespace.id,
                               thread,
                               to_addr=[('Bob', '*****@*****.**')],
                               from_addr=[('Alice', '*****@*****.**')],
                               subject='some subject')
    message.categories.add(
        Category(namespace_id=message.namespace_id,
                 name='inbox',
                 display_name='Inbox',
                 type_='label'))
    thread.subject = message.subject
    db.session.commit()

    t_start = dt_to_timestamp(thread.subjectdate)
    t_lastmsg = dt_to_timestamp(thread.recentdate)
    subject = message.subject
    to_addr = message.to_addr[0][1]
    from_addr = message.from_addr[0][1]
    received_date = message.received_date
    unread = not message.is_read
    starred = message.is_starred

    results = api_client.get_data('/threads?thread_id={}'.format(
        thread.public_id))
    assert len(results) == 1

    results = api_client.get_data('/messages?thread_id={}'.format(
        thread.public_id))
    assert len(results) == 1

    results = api_client.get_data('/threads?cc={}'.format(message.cc_addr))
    assert len(results) == 0

    results = api_client.get_data('/messages?cc={}'.format(message.cc_addr))
    assert len(results) == 0

    results = api_client.get_data('/threads?bcc={}'.format(message.bcc_addr))
    assert len(results) == 0

    results = api_client.get_data('/messages?bcc={}'.format(message.bcc_addr))
    assert len(results) == 0

    results = api_client.get_data('/threads?filename=test')
    assert len(results) == 0

    results = api_client.get_data('/messages?filename=test')
    assert len(results) == 0

    results = api_client.get_data('/threads?started_after={}'.format(t_start -
                                                                     1))
    assert len(results) == 1

    results = api_client.get_data('/messages?started_after={}'.format(t_start -
                                                                      1))
    assert len(results) == 1

    results = api_client.get_data(
        '/messages?last_message_before={}&limit=1'.format(t_lastmsg + 1))
    assert len(results) == 1

    results = api_client.get_data(
        '/threads?last_message_before={}&limit=1'.format(t_lastmsg + 1))
    assert len(results) == 1

    results = api_client.get_data('/threads?in=inbox&limit=1')
    assert len(results) == 1

    results = api_client.get_data('/messages?in=inbox&limit=1')
    assert len(results) == 1

    results = api_client.get_data('/messages?in=banana%20rama')
    assert len(results) == 0

    results = api_client.get_data('/threads?subject={}'.format(subject))
    assert len(results) == 1

    results = api_client.get_data('/messages?subject={}'.format(subject))
    assert len(results) == 1

    results = api_client.get_data('/threads?unread={}'.format(unread))
    assert len(results) == 1

    results = api_client.get_data('/messages?unread={}'.format((not unread)))
    assert len(results) == 0

    results = api_client.get_data('/threads?starred={}'.format((not starred)))
    assert len(results) == 0

    results = api_client.get_data('/messages?starred={}'.format(starred))
    assert len(results) == 1

    for _ in range(3):
        add_fake_message(db.session,
                         default_namespace.id,
                         to_addr=[('', '*****@*****.**')],
                         thread=add_fake_thread(db.session,
                                                default_namespace.id))

    results = api_client.get_data(
        '/messages?any_email={}'.format('*****@*****.**'))
    assert len(results) > 1

    # Test multiple any_email params
    multiple_results = api_client.get_data(
        '/messages?any_email={},{},{}'.format('*****@*****.**',
                                              '*****@*****.**',
                                              '*****@*****.**'))
    assert len(multiple_results) > len(results)

    # Check that we canonicalize when searching.
    alternate_results = api_client.get_data(
        '/threads?any_email={}'.format('*****@*****.**'))
    assert len(alternate_results) == len(results)

    results = api_client.get_data('/messages?from={}'.format(from_addr))
    assert len(results) == 1
    results = api_client.get_data('/threads?from={}'.format(from_addr))
    assert len(results) == 1

    early_time = received_date - datetime.timedelta(seconds=1)
    late_time = received_date + datetime.timedelta(seconds=1)
    early_ts = calendar.timegm(early_time.utctimetuple())
    late_ts = calendar.timegm(late_time.utctimetuple())

    results = api_client.get_data(
        '/messages?subject={}&started_before={}'.format(subject, early_ts))
    assert len(results) == 0
    results = api_client.get_data(
        '/threads?subject={}&started_before={}'.format(subject, early_ts))
    assert len(results) == 0

    results = api_client.get_data(
        '/messages?subject={}&started_before={}'.format(subject, late_ts))
    assert len(results) == 1
    results = api_client.get_data(
        '/threads?subject={}&started_before={}'.format(subject, late_ts))
    assert len(results) == 1

    results = api_client.get_data(
        '/messages?subject={}&last_message_after={}'.format(subject, early_ts))
    assert len(results) == 1
    results = api_client.get_data(
        '/threads?subject={}&last_message_after={}'.format(subject, early_ts))
    assert len(results) == 1

    results = api_client.get_data(
        '/messages?subject={}&last_message_after={}'.format(subject, late_ts))
    assert len(results) == 0
    results = api_client.get_data(
        '/threads?subject={}&last_message_after={}'.format(subject, late_ts))
    assert len(results) == 0

    results = api_client.get_data(
        '/messages?subject={}&started_before={}'.format(subject, early_ts))
    assert len(results) == 0
    results = api_client.get_data(
        '/threads?subject={}&started_before={}'.format(subject, early_ts))
    assert len(results) == 0

    results = api_client.get_data(
        '/messages?subject={}&started_before={}'.format(subject, late_ts))
    assert len(results) == 1
    results = api_client.get_data(
        '/threads?subject={}&started_before={}'.format(subject, late_ts))
    assert len(results) == 1

    results = api_client.get_data('/messages?from={}&to={}'.format(
        from_addr, to_addr))
    assert len(results) == 1

    results = api_client.get_data('/threads?from={}&to={}'.format(
        from_addr, to_addr))
    assert len(results) == 1

    results = api_client.get_data('/messages?to={}&limit={}&offset={}'.format(
        '*****@*****.**', 2, 1))
    assert len(results) == 2

    results = api_client.get_data('/threads?to={}&limit={}'.format(
        '*****@*****.**', 3))
    assert len(results) == 3

    results = api_client.get_data('/threads?view=count')

    assert results['count'] == 4

    results = api_client.get_data('/threads?view=ids&to={}&limit=3'.format(
        '*****@*****.**', 3))

    assert len(results) == 3
    assert all(isinstance(r, basestring)
               for r in results), "Returns a list of string"
Example #14
0
    def save_folder_names(self, db_session, raw_folders):
        """
        Save the folders, labels present on the remote backend for an account.

        * Create Folder/ Label objects.
        * Delete Folders/ Labels that no longer exist on the remote.

        Notes
        -----
        Gmail uses IMAP folders and labels.
        Canonical folders ('all', 'trash', 'spam') are therefore mapped to both
        Folder and Label objects, everything else is created as a Label only.

        We don't canonicalize names to lowercase when saving because
        different backends may be case-sensitive or otherwise - code that
        references saved names should canonicalize if needed when doing
        comparisons.

        """
        account = db_session.query(Account).get(self.account_id)

        old_labels = {label for label in db_session.query(Label).filter(
            Label.account_id == self.account_id,
            Label.deleted_at == None)}

        new_labels = set()

        # Create new labels, folders
        for raw_folder in raw_folders:
            if raw_folder.role == 'starred':
                # The starred state of messages is tracked separately
                # (we set Message.is_starred from the '\\Flagged' flag)
                continue

            label = Label.find_or_create(db_session, account,
                                         raw_folder.display_name,
                                         raw_folder.role)
            new_labels.add(label)

            if label.deleted_at is not None:
                # This is a label which was previously marked as deleted
                # but which mysteriously reappeared. Unmark it.
                log.info('Deleted label recreated on remote',
                         name=raw_folder.display_name)
                label.deleted_at = None
                label.category.deleted_at = None

            if raw_folder.role in ('all', 'spam', 'trash'):
                folder = db_session.query(Folder).filter(
                    Folder.account_id == account.id,
                    Folder.canonical_name == raw_folder.role).first()
                if folder:
                    if folder.name != raw_folder.display_name:
                        log.info('Folder name changed on remote',
                                 account_id=self.account_id,
                                 role=raw_folder.role,
                                 new_name=raw_folder.display_name,
                                 name=folder.name)
                        folder.name = raw_folder.display_name

                    if folder.category:
                        if folder.category.display_name != \
                                raw_folder.display_name:
                            folder.category.display_name = raw_folder.display_name  # noqa
                    else:
                        log.info('Creating category for folder',
                                 account_id=self.account_id,
                                 folder_name=folder.name)
                        folder.category = Category.find_or_create(
                            db_session, namespace_id=account.namespace.id,
                            name=raw_folder.role,
                            display_name=raw_folder.display_name,
                            type_='folder')
                else:
                    Folder.find_or_create(db_session, account,
                                          raw_folder.display_name,
                                          raw_folder.role)

        # Ensure sync_should_run is True for the folders we want to sync (for
        # Gmail, that's just all folders, since we created them above if
        # they didn't exist.)
        for folder in account.folders:
            if folder.imapsyncstatus:
                folder.imapsyncstatus.sync_should_run = True

        # Go through the labels which have been "deleted" (i.e: they don't
        # show up when running LIST) and mark them as such.
        # We can't delete labels directly because Gmail allows users to hide
        # folders --- we need to check that there's no messages still
        # associated with the label.
        deleted_labels = old_labels - new_labels
        for deleted_label in deleted_labels:
            deleted_label.deleted_at = datetime.now()
            cat = deleted_label.category
            cat.deleted_at = datetime.now()

        db_session.commit()
Example #15
0
    def save_folder_names(self, db_session, raw_folders):
        """
        Save the folders, labels present on the remote backend for an account.

        * Create Folder/ Label objects.
        * Delete Folders/ Labels that no longer exist on the remote.

        Notes
        -----
        Gmail uses IMAP folders and labels.
        Canonical folders ('all', 'trash', 'spam') are therefore mapped to both
        Folder and Label objects, everything else is created as a Label only.

        We don't canonicalize names to lowercase when saving because
        different backends may be case-sensitive or otherwise - code that
        references saved names should canonicalize if needed when doing
        comparisons.

        """
        account = db_session.query(Account).get(self.account_id)

        old_labels = {
            label
            for label in db_session.query(Label).filter(
                Label.account_id == self.account_id, Label.deleted_at == None)
        }

        new_labels = set()

        # Create new labels, folders
        for raw_folder in raw_folders:
            if raw_folder.role == 'starred':
                # The starred state of messages is tracked separately
                # (we set Message.is_starred from the '\\Flagged' flag)
                continue

            label = Label.find_or_create(db_session, account,
                                         raw_folder.display_name,
                                         raw_folder.role)
            new_labels.add(label)

            if label.deleted_at is not None:
                # This is a label which was previously marked as deleted
                # but which mysteriously reappeared. Unmark it.
                log.info('Deleted label recreated on remote',
                         name=raw_folder.display_name)
                label.deleted_at = None
                label.category.deleted_at = None

            if raw_folder.role in ('all', 'spam', 'trash'):
                folder = db_session.query(Folder).filter(
                    Folder.account_id == account.id,
                    Folder.canonical_name == raw_folder.role).first()
                if folder:
                    if folder.name != raw_folder.display_name:
                        log.info('Folder name changed on remote',
                                 account_id=self.account_id,
                                 role=raw_folder.role,
                                 new_name=raw_folder.display_name,
                                 name=folder.name)
                        folder.name = raw_folder.display_name

                    if folder.category:
                        if folder.category.display_name != \
                                raw_folder.display_name:
                            folder.category.display_name = raw_folder.display_name  # noqa
                    else:
                        log.info('Creating category for folder',
                                 account_id=self.account_id,
                                 folder_name=folder.name)
                        folder.category = Category.find_or_create(
                            db_session,
                            namespace_id=account.namespace.id,
                            name=raw_folder.role,
                            display_name=raw_folder.display_name,
                            type_='folder')
                else:
                    Folder.find_or_create(db_session, account,
                                          raw_folder.display_name,
                                          raw_folder.role)

        # Ensure sync_should_run is True for the folders we want to sync (for
        # Gmail, that's just all folders, since we created them above if
        # they didn't exist.)
        for folder in account.folders:
            if folder.imapsyncstatus:
                folder.imapsyncstatus.sync_should_run = True

        # Go through the labels which have been "deleted" (i.e: they don't
        # show up when running LIST) and mark them as such.
        # We can't delete labels directly because Gmail allows users to hide
        # folders --- we need to check that there's no messages still
        # associated with the label.
        deleted_labels = old_labels - new_labels
        for deleted_label in deleted_labels:
            deleted_label.deleted_at = datetime.now()
            cat = deleted_label.category
            cat.deleted_at = datetime.now()

        db_session.commit()
Example #16
0
    def save_folder_names(self, db_session, raw_folders):
        """
        Save the folders, labels present on the remote backend for an account.

        * Create Folder/ Label objects.
        * Delete Folders/ Labels that no longer exist on the remote.

        Notes
        -----
        Gmail uses IMAP folders and labels.
        Canonical folders ('all', 'trash', 'spam') are therefore mapped to both
        Folder and Label objects, everything else is created as a Label only.

        We don't canonicalize names to lowercase when saving because
        different backends may be case-sensitive or otherwise - code that
        references saved names should canonicalize if needed when doing
        comparisons.

        """
        account = db_session.query(Account).get(self.account_id)

        # Create new labels, folders
        for raw_folder in raw_folders:
            if raw_folder.role == 'starred':
                # The starred state of messages is tracked separately
                # (we set Message.is_starred from the '\\Flagged' flag)
                continue

            Label.find_or_create(db_session, account,
                                 raw_folder.display_name, raw_folder.role)

            if raw_folder.role in ('all', 'spam', 'trash'):
                folder = db_session.query(Folder). \
                        filter(Folder.account_id == account.id,
                                Folder.canonical_name == raw_folder.role). \
                        first()
                if folder:
                    if folder.name != raw_folder.display_name:
                        log.info('Folder name changed on remote',
                                 account_id=self.account_id,
                                 role=raw_folder.role,
                                 new_name=raw_folder.display_name,
                                 name=folder.name)
                        folder.name = raw_folder.display_name

                    if folder.category:
                        if folder.category.display_name != \
                                raw_folder.display_name:
                            folder.category.display_name = raw_folder.display_name
                    else:
                        log.info('Creating category for folder',
                                 account_id=self.account_id,
                                 folder_name=folder.name)
                        folder.category = Category.find_or_create(
                            db_session, namespace_id=account.namespace.id,
                            name=raw_folder.role,
                            display_name=raw_folder.display_name,
                            type_='folder')
                else:
                    Folder.find_or_create(db_session, account,
                                          raw_folder.display_name,
                                          raw_folder.role)

        # Ensure sync_should_run is True for the folders we want to sync (for
        # Gmail, that's just all folders, since we created them above if
        # they didn't exist.)
        for folder in account.folders:
            if folder.imapsyncstatus:
                folder.imapsyncstatus.sync_should_run = True
        db_session.commit()
Example #17
0
    def save_folder_names(self, db_session, raw_folders):
        """
        Save the folders, labels present on the remote backend for an account.

        * Create Folder/ Label objects.
        * Delete Folders/ Labels that no longer exist on the remote.

        Notes
        -----
        Gmail uses IMAP folders and labels.
        Canonical folders ('all', 'trash', 'spam') are therefore mapped to both
        Folder and Label objects, everything else is created as a Label only.

        We don't canonicalize names to lowercase when saving because
        different backends may be case-sensitive or otherwise - code that
        references saved names should canonicalize if needed when doing
        comparisons.

        """
        account = db_session.query(Account).get(self.account_id)

        # Create new labels, folders
        for raw_folder in raw_folders:
            if raw_folder.role == 'starred':
                # The starred state of messages is tracked separately
                # (we set Message.is_starred from the '\\Flagged' flag)
                continue

            Label.find_or_create(db_session, account,
                                 raw_folder.display_name, raw_folder.role)

            if raw_folder.role in ('all', 'spam', 'trash'):
                folder = db_session.query(Folder). \
                        filter(Folder.account_id == account.id,
                                Folder.canonical_name == raw_folder.role). \
                        first()
                if folder:
                    if folder.name != raw_folder.display_name:
                        log.info('Folder name changed on remote',
                                 account_id=self.account_id,
                                 role=raw_folder.role,
                                 new_name=raw_folder.display_name,
                                 name=folder.name)
                        folder.name = raw_folder.display_name

                    if folder.category:
                        if folder.category.display_name != \
                                raw_folder.display_name:
                            folder.category.display_name = raw_folder.display_name
                    else:
                        log.info('Creating category for folder',
                                 account_id=self.account_id,
                                 folder_name=folder.name)
                        folder.category = Category.find_or_create(
                            db_session, namespace_id=account.namespace.id,
                            name=raw_folder.role,
                            display_name=raw_folder.display_name,
                            type_='folder')
                else:
                    Folder.find_or_create(db_session, account,
                                          raw_folder.display_name,
                                          raw_folder.role)

        # Ensure sync_should_run is True for the folders we want to sync (for
        # Gmail, that's just all folders, since we created them above if
        # they didn't exist.)
        for folder in account.folders:
            if folder.imapsyncstatus:
                folder.imapsyncstatus.sync_should_run = True
        db_session.commit()
Example #18
0
def test_received_before_after(db, api_client, default_namespace):
    thread = add_fake_thread(db.session, default_namespace.id)
    message = add_fake_message(db.session,
                               default_namespace.id,
                               thread,
                               to_addr=[('Bob', '*****@*****.**')],
                               from_addr=[('Alice', '*****@*****.**')],
                               received_date=datetime.datetime(year=1999,
                                                               day=20,
                                                               month=03),
                               subject='some subject')

    thread2 = add_fake_thread(db.session, default_namespace.id)
    message2 = add_fake_message(db.session,
                                default_namespace.id,
                                thread,
                                to_addr=[('Bob', '*****@*****.**')],
                                from_addr=[('Alice', '*****@*****.**')],
                                received_date=datetime.datetime(year=2000,
                                                                day=20,
                                                                month=03),
                                subject='another subject')

    inbox = Category(namespace_id=message.namespace_id,
                     name='inbox',
                     display_name='Inbox',
                     type_='label')
    message.categories.add(inbox)
    thread.subject = message.subject

    message2.categories.add(inbox)
    thread2.subject = message2.subject

    db.session.commit()

    received_date = message.received_date
    t_epoch = dt_to_timestamp(datetime.datetime(year=1998, month=2, day=3))
    t_firstmsg = dt_to_timestamp(received_date)

    results = api_client.get_data(
        '/messages?received_before={}'.format(t_epoch))
    assert len(results) == 0

    # received_before should be inclusive (i.e: match <=, not just <).
    results = api_client.get_data(
        '/messages?received_before={}'.format(t_firstmsg))
    assert len(results) == 1

    t1 = dt_to_timestamp(received_date + datetime.timedelta(days=1))
    results = api_client.get_data('/messages?received_after={}'.format(t1))
    assert len(results) == 1

    results = api_client.get_data(
        '/messages?received_before={}&received_after={}'.format(
            t1, t_firstmsg))
    assert len(results) == 0

    # bogus values
    results = api_client.get_data(
        '/messages?received_before={}&received_after={}'.format(t_epoch, t1))
    assert len(results) == 0