def update_thread_labels(thread, folder_name, g_labels, db_session): """ Make sure `thread` has all the right labels. """ existing_labels = {folder.name.lower() for folder in thread.folders if folder.name is not None} | \ {folder.canonical_name for folder in thread.folders if folder.canonical_name is not None} new_labels = { l.lstrip('\\').lower() if isinstance(l, unicode) else unicode(l) for l in g_labels if l is not None } new_labels.add(folder_name.lower()) # Remove labels that have been deleted -- note that the \Inbox, \Sent, # \Important, \Starred, and \Drafts labels are per-message, not per-thread, # but since we always work at the thread level, _we_ apply the label to the # whole thread. # TODO: properly aggregate \Inbox, \Sent, \Important, and \Drafts # per-message so we can detect deletions properly. folders_to_discard = [] for folder in thread.folders: if folder.canonical_name not in ('inbox', 'sent', 'drafts', 'important', 'starred', 'all'): if folder.lowercase_name not in new_labels: folders_to_discard.append(folder) for folder in folders_to_discard: thread.folders.discard(folder) # add new labels for label in new_labels: if label.lower() not in existing_labels: # The problem here is that Gmail's attempt to squash labels and # IMAP folders into the same abstraction doesn't work perfectly. In # particular, there is a '[Gmail]/Sent' folder, but *also* a 'Sent' # label, and so on. We handle this by only maintaining one folder # object that encapsulates both of these. If a Gmail user does not # have these folders enabled via IMAP, we create Folder rows # with no 'name' attribute and fill in the 'name' if the account # is later reconfigured. canonical_labels = { 'sent': thread.namespace.account.sent_folder, 'draft': thread.namespace.account.drafts_folder, 'starred': thread.namespace.account.starred_folder, 'important': thread.namespace.account.important_folder } if label in canonical_labels: folder = canonical_labels[label] if folder: thread.folders.add(folder) else: folder = Folder.find_or_create(db_session, thread.namespace.account, None, label) thread.folders.add(folder) else: folder = Folder.find_or_create(db_session, thread.namespace.account, label) thread.folders.add(folder) return new_labels
def update_thread_labels(thread, folder_name, g_labels, db_session): """ Make sure `thread` has all the right labels. """ existing_labels = {folder.name.lower() for folder in thread.folders if folder.name is not None} | \ {folder.canonical_name for folder in thread.folders if folder.canonical_name is not None} new_labels = {l.lstrip('\\').lower() if isinstance(l, unicode) else unicode(l) for l in g_labels if l is not None} new_labels.add(folder_name.lower()) # Remove labels that have been deleted -- note that the \Inbox, \Sent, # \Important, \Starred, and \Drafts labels are per-message, not per-thread, # but since we always work at the thread level, _we_ apply the label to the # whole thread. # TODO: properly aggregate \Inbox, \Sent, \Important, and \Drafts # per-message so we can detect deletions properly. folders_to_discard = [] for folder in thread.folders: if folder.canonical_name not in ('inbox', 'sent', 'drafts', 'important', 'starred', 'all'): if folder.lowercase_name not in new_labels: folders_to_discard.append(folder) for folder in folders_to_discard: thread.folders.discard(folder) # add new labels for label in new_labels: if label.lower() not in existing_labels: # The problem here is that Gmail's attempt to squash labels and # IMAP folders into the same abstraction doesn't work perfectly. In # particular, there is a '[Gmail]/Sent' folder, but *also* a 'Sent' # label, and so on. We handle this by only maintaining one folder # object that encapsulates both of these. If a Gmail user does not # have these folders enabled via IMAP, we create Folder rows # with no 'name' attribute and fill in the 'name' if the account # is later reconfigured. canonical_labels = { 'sent': thread.namespace.account.sent_folder, 'draft': thread.namespace.account.drafts_folder, 'starred': thread.namespace.account.starred_folder, 'important': thread.namespace.account.important_folder} if label in canonical_labels: folder = canonical_labels[label] if folder: thread.folders.add(folder) else: folder = Folder.find_or_create( db_session, thread.namespace.account, None, label) thread.folders.add(folder) else: folder = Folder.find_or_create(db_session, thread.namespace.account, label) thread.folders.add(folder) return new_labels
def set_remote_spam(account, thread_id, spam, db_session): if account.spam_folder is None: # account has no detected spam folder - create one. spam_folder = Folder.find_or_create(db_session, account, 'Spam', 'spam') account.spam_folder = spam_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if spam: for folder in folders: remote_move(account, thread_id, folder, account.spam_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.spam_folder.name, account.inbox_folder.name, db_session)
def set_remote_trash(account, thread_id, trash, db_session): thread = db_session.query(Thread).get(thread_id) if account.trash_folder is None: # account has no detected trash folder - create one. trash_folder = Folder.find_or_create(db_session, account, 'Trash', 'trash') account.trash_folder = trash_folder if trash: # apparently it's not possible to index an association # proxy. folders = [folder for folder in thread.folders] assert len(folders) == 1, "A thread belongs to only one folder" # Arbitrarily pick the first folder since there's no support for # threads belonging to multiple folders on non-gmail backends. return remote_move(account, thread_id, folders[0].name, account.trash_folder.name, db_session, create_destination=True) else: return remote_move(account, thread_id, account.trash_folder.name, account.inbox_folder.name, db_session)
def add_fake_folder(db_session, default_account, display_name='All Mail', name='all'): from inbox.models.folder import Folder return Folder.find_or_create(db_session, default_account, display_name, name)
def set_remote_archived(account, thread_id, archived, db_session): if account.archive_folder is None: # account has no detected archive folder - create one. archive_folder = Folder.find_or_create(db_session, account, 'Archive', 'archive') account.archive_folder = archive_folder if archived: return remote_move(account, thread_id, account.inbox_folder.name, account.archive_folder.name, db_session, create_destination=True) else: return remote_move(account, thread_id, account.archive_folder.name, account.inbox_folder.name, db_session)
def set_remote_archived(account, thread_id, archived, db_session): if account.archive_folder is None: # account has no detected archive folder - create one. archive_folder = Folder.find_or_create(db_session, account, 'Archive', 'archive') account.archive_folder = archive_folder if archived: return remote_move(account, thread_id, account.inbox_folder.name, account.archive_folder.name, db_session, create_destination=True) else: return remote_move(account, thread_id, account.archive_folder.name, account.inbox_folder.name, db_session)
def set_remote_archived(account, thread_id, archived, db_session): if account.archive_folder is None: # account has no detected archive folder - create one. archive_folder = Folder.find_or_create(db_session, account, 'Archive', 'archive') account.archive_folder = archive_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if archived: for folder in folders: remote_move(account, thread_id, folder, account.archive_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.archive_folder.name, account.inbox_folder.name, db_session)
def set_remote_trash(account, thread_id, trash, db_session): if account.trash_folder is None: # account has no detected trash folder - create one. trash_folder = Folder.find_or_create(db_session, account, 'Trash', 'trash') account.trash_folder = trash_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if trash: for folder in folders: remote_move(account, thread_id, folder, account.trash_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.trash_folder.name, account.inbox_folder.name, db_session)
def set_remote_archived(account, thread_id, archived, db_session): if account.archive_folder is None: # account has no detected archive folder - create one. archive_folder = Folder.find_or_create(db_session, account, 'Archive', 'archive') account.archive_folder = archive_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if archived: for folder in folders: remote_move(account, thread_id, folder, account.archive_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.archive_folder.name, account.inbox_folder.name, db_session)
def set_remote_trash(account, thread_id, trash, db_session): if account.trash_folder is None: # account has no detected trash folder - create one. trash_folder = Folder.find_or_create(db_session, account, 'Trash', 'trash') account.trash_folder = trash_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if trash: for folder in folders: remote_move(account, thread_id, folder, account.trash_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.trash_folder.name, account.inbox_folder.name, db_session)
def set_remote_trash(account, thread_id, trash, db_session): thread = db_session.query(Thread).get(thread_id) if account.trash_folder is None: # account has no detected trash folder - create one. trash_folder = Folder.find_or_create(db_session, account, 'Trash', 'trash') account.trash_folder = trash_folder if trash: # apparently it's not possible to index an association # proxy. folders = [folder for folder in thread.folders] assert len(folders) == 1, "A thread belongs to only one folder" # Arbitrarily pick the first folder since there's no support for # threads belonging to multiple folders on non-gmail backends. return remote_move(account, thread_id, folders[0].name, account.trash_folder.name, db_session, create_destination=True) else: return remote_move(account, thread_id, account.trash_folder.name, account.inbox_folder.name, db_session)
def set_remote_spam(account, thread_id, spam, db_session): if account.spam_folder is None: # account has no detected spam folder - create one. spam_folder = Folder.find_or_create(db_session, account, 'Spam', 'spam') account.spam_folder = spam_folder db_session.commit() thread = db_session.query(Thread).get(thread_id) # FIXME @karim: not sure if we should exclude sent or not. folders = [folder.name for folder in thread.folders] if spam: for folder in folders: remote_move(account, thread_id, folder, account.spam_folder.name, db_session, create_destination=True) else: remote_move(account, thread_id, account.spam_folder.name, account.inbox_folder.name, db_session)
def update_thread_labels(thread, folder_name, g_labels, db_session): existing_labels = {folder.name.lower() for folder in thread.folders} new_labels = {l.lstrip('\\').lower() for l in g_labels} new_labels.add(folder_name.lower()) # Remove labels that have been deleted -- note that the \Inbox, \Sent, # \Important, and \Drafts labels are per-message, not per-thread, but # since we always work at the thread level, _we_ apply the label to the # whole thread. thread.folders = {folder for folder in thread.folders if folder.name.lower() in new_labels or folder.name.lower() in ('inbox', 'sent', 'drafts', 'important')} # add new labels for label in new_labels: if label.lower() not in existing_labels: # The problem here is that Gmail's attempt to squash labels and # IMAP folders into the same abstraction doesn't work # perfectly. In particular, there is a '[Gmail]/Sent' folder, # but *also* a 'Sent' label, and so on. We handle this by only # maintaining one folder object that encapsulates both of # these. if label == 'sent': thread.folders.add(thread.namespace.account.sent_folder) elif label == 'draft': thread.folders.add(thread.namespace.account.drafts_folder) elif label == 'starred': thread.folders.add(thread.namespace.account.starred_folder) elif label == 'important': thread.folders.add( thread.namespace.account.important_folder) else: folder = Folder.find_or_create(db_session, thread.namespace.account, label) thread.folders.add(folder) return new_labels
def folder(db, default_account): from inbox.models.folder import Folder return Folder.find_or_create(db.session, default_account, '[Gmail]/All Mail', 'all')
def folder(db, default_account): from inbox.models.folder import Folder return Folder.find_or_create(db.session, default_account, '[Gmail]/All Mail', 'all')
def add_fake_folder(db_session, default_account, display_name='All Mail', name='all'): from inbox.models.folder import Folder return Folder.find_or_create(db_session, default_account, display_name, name)
def add_fake_folder(db, default_account): from inbox.models.folder import Folder return Folder.find_or_create(db.session, default_account, "All Mail", "all")
def add_fake_folder(db_session, default_account): from inbox.models.folder import Folder return Folder.find_or_create(db_session, default_account, 'All Mail', 'all')
def add_fake_folder(db_session, default_account): from inbox.models.folder import Folder return Folder.find_or_create(db_session, default_account, 'All Mail', 'all')