def set_remote_unread(account, thread_id, unread, db_session): def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.set_unread(g_thrid, unread) for folder in [account.all_folder.name, account.trash_folder.name, account.spam_folder.name]: syncback_action(fn, account, folder, db_session)
def set_remote_unread(account, thread_id, unread, db_session): def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.set_unread(g_thrid, unread) for folder in [ account.all_folder.name, account.trash_folder.name, account.spam_folder.name ]: syncback_action(fn, account, folder, db_session)
def remote_move(account, thread_id, from_folder, to_folder, db_session): if from_folder == to_folder: return def fn(account, db_session, crispin_client): folders = crispin_client.folder_names() if from_folder not in folders.values() and \ from_folder not in folders['extra']: raise Exception("Unknown from_folder '{}'".format(from_folder)) if to_folder not in folders.values() and \ to_folder not in folders['extra']: raise Exception("Unknown to_folder '{}'".format(to_folder)) crispin_client.select_folder(from_folder, uidvalidity_cb) uids = [] thread = get_thread_uids(db_session, thread_id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.copy_uids(uids, to_folder) crispin_client.delete_uids(uids) return syncback_action(fn, account, from_folder, db_session)
def remote_delete(account, thread_id, folder_name, db_session): def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) inbox_folder = crispin_client.folder_names()['inbox'] all_folder = crispin_client.folder_names()['all'] drafts_folder = crispin_client.folder_names()['drafts'] # Move to All Mail if folder_name == inbox_folder: return _archive(g_thrid, crispin_client) # Remove \Draft, move to Trash elif folder_name == drafts_folder: crispin_client.select_folder( crispin_client.folder_names()['all'], uidvalidity_cb) crispin_client.delete(g_thrid, folder_name) # Remove label, keep in All Mail elif folder_name in crispin_client.folder_names()['labels']: crispin_client.select_folder( crispin_client.folder_names()['all'], uidvalidity_cb) crispin_client.remove_label(g_thrid, folder_name) # Move to Trash elif folder_name == all_folder: # delete thread from all mail: really delete it (move it to trash # where it will be permanently deleted after 30 days, see # https://support.google.com/mail/answer/78755?hl=en) # XXX: does copy() work here, or do we have to actually _move_ # the message? do we also need to delete it from all labels and # stuff? not sure how this works really. crispin_client.copy_thread( g_thrid, crispin_client.folder_names()['trash']) else: raise Exception("Unknown folder_name '{0}'".format(folder_name)) return syncback_action(fn, account, folder_name, db_session)
def remote_delete(account, thread_id, folder_name, db_session): def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) inbox_folder = crispin_client.folder_names()['inbox'] all_folder = crispin_client.folder_names()['all'] drafts_folder = crispin_client.folder_names()['drafts'] # Move to All Mail if folder_name == inbox_folder: return _archive(g_thrid, crispin_client) # Remove \Draft, move to Trash # Note: this only moves *drafts* in the thread, not the whole thread. elif folder_name == drafts_folder: crispin_client.delete(g_thrid, folder_name) # Remove label, keep in All Mail elif folder_name in crispin_client.folder_names()['labels']: crispin_client.select_folder(crispin_client.folder_names()['all'], uidvalidity_cb) crispin_client.remove_label(g_thrid, folder_name) # Move to Trash elif folder_name == all_folder: # delete thread from all mail: really delete it (move it to trash # where it will be permanently deleted after 30 days, see # https://support.google.com/mail/answer/78755?hl=en) # XXX: does copy() work here, or do we have to actually _move_ # the message? do we also need to delete it from all labels and # stuff? not sure how this works really. crispin_client.copy_thread(g_thrid, crispin_client.folder_names()['trash']) else: raise Exception("Unknown folder_name '{0}'".format(folder_name)) return syncback_action(fn, account, folder_name, db_session)
def remote_move(account, thread_id, from_folder, to_folder, db_session, create_destination=False): if from_folder == to_folder: return def fn(account, db_session, crispin_client): folders = crispin_client.folder_names() if from_folder not in folders.values() and \ from_folder not in folders['extra']: raise Exception("Unknown from_folder '{}'".format(from_folder)) if to_folder not in folders.values() and \ to_folder not in folders['extra']: if create_destination: crispin_client.create_folder(to_folder) else: raise Exception("Unknown to_folder '{}'".format(to_folder)) crispin_client.select_folder(from_folder, uidvalidity_cb) uids = [] thread = get_thread_uids(db_session, thread_id, account.namespace.id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.copy_uids(uids, to_folder) crispin_client.delete_uids(uids) return syncback_action(fn, account, from_folder, db_session)
def set_remote_unread(account, thread_id, unread, db_session): def fn(account, db_session, crispin_client): uids = [] thread = get_thread_uids(db_session, thread_id, account.namespace.id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.set_unread(uids, unread) return syncback_action(fn, account, account.inbox_folder.name, db_session)
def set_remote_unread(account, thread_id, unread, db_session): def fn(account, db_session, crispin_client): uids = [] thread = get_thread_uids(db_session, thread_id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.set_unread(uids, unread) return syncback_action(fn, account, account.inbox_folder.name, db_session)
def remote_delete(account, thread_id, folder_name, db_session): def fn(account, db_session, crispin_client): uids = [] thread = get_thread_uids(db_session, thread_id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.delete_uids(uids) return syncback_action(fn, account, folder_name, db_session)
def remote_save_sent(account, folder_name, message, db_session, date=None, create_backend_sent_folder=False): def fn(account, db_session, crispin_client): if create_backend_sent_folder: if 'sent' not in crispin_client.folder_names(): crispin_client.create_folder('Sent') crispin_client.select_folder(folder_name, uidvalidity_cb) crispin_client.create_message(message, date) return syncback_action(fn, account, folder_name, db_session, select_folder=False)
def remote_delete(account, thread_id, folder_name, db_session): """ We currently only allow this for Drafts. """ def fn(account, db_session, crispin_client): if folder_name == crispin_client.folder_names()['drafts']: uids = [] thread = get_thread_uids(db_session, thread_id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.delete_uids(uids) return syncback_action(fn, account, folder_name, db_session)
def remote_delete(account, thread_id, folder_name, db_session): """ We currently only allow this for Drafts. """ def fn(account, db_session, crispin_client): if folder_name == crispin_client.folder_names()['drafts']: uids = [] thread = get_thread_uids(db_session, thread_id, account.namespace.id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.delete_uids(uids) return syncback_action(fn, account, folder_name, db_session)
def remote_move(account, thread_id, from_folder_name, to_folder_name, db_session): if from_folder_name == to_folder_name: return def fn(account, db_session, crispin_client): inbox_folder_name = crispin_client.folder_names()['inbox'] all_folder_name = crispin_client.folder_names()['all'] labels = crispin_client.folder_names().get('labels', []) if from_folder_name == inbox_folder_name: if to_folder_name == all_folder_name: return _archive(thread_id, crispin_client) else: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) _archive(g_thrid, crispin_client) crispin_client.add_label(g_thrid, to_folder_name) elif from_folder_name in labels: if to_folder_name in labels: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.add_label(g_thrid, to_folder_name) elif to_folder_name == inbox_folder_name: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.copy_thread(g_thrid, to_folder_name) elif to_folder_name != all_folder_name: raise Exception( "Should never get here! to_folder_name: {}".format( to_folder_name)) crispin_client.select_folder(crispin_client.folder_names()['all'], uidvalidity_cb) crispin_client.remove_label(g_thrid, from_folder_name) # do nothing if moving to all mail elif from_folder_name == all_folder_name: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) if to_folder_name in labels: crispin_client.add_label(g_thrid, to_folder_name) elif to_folder_name == inbox_folder_name: crispin_client.copy_thread(g_thrid, to_folder_name) else: raise Exception( "Should never get here! to_folder_name: {}".format( to_folder_name)) else: raise Exception( "Unknown from_folder_name '{}'".format(from_folder_name)) return syncback_action(fn, account, from_folder_name, db_session)
def set_remote_archived(account, thread_id, archived, db_session): if not archived: # For now, implement unarchive as a move from all mail to inbox. return remote_move(account, thread_id, account.all_folder.name, account.inbox_folder.name, db_session) def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) _archive(g_thrid, crispin_client) inbox_folder = account.inbox_folder assert inbox_folder is not None inbox_folder_name = inbox_folder.name return syncback_action(fn, account, inbox_folder_name, db_session)
def remote_delete_draft(account, folder_name, inbox_uid, db_session): def fn(account, db_session, crispin_client): assert folder_name == crispin_client.folder_names()['drafts'] message = db_session.query(Message). \ filter_by(public_id=inbox_uid).one() uids = [] if message.resolved_message is not None: for imapuid in message.resolved_message.imapuids: uids.append(imapuid.msg_uid) if uids != []: crispin_client.delete_uids(uids) return syncback_action(fn, account, folder_name, db_session)
def remote_move(account, thread_id, from_folder_name, to_folder_name, db_session): if from_folder_name == to_folder_name: return def fn(account, db_session, crispin_client): inbox_folder_name = crispin_client.folder_names()['inbox'] all_folder_name = crispin_client.folder_names()['all'] labels = crispin_client.folder_names().get('labels', []) if from_folder_name == inbox_folder_name: if to_folder_name == all_folder_name: return _archive(thread_id, crispin_client) else: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) _archive(g_thrid, crispin_client) crispin_client.add_label(g_thrid, to_folder_name) elif from_folder_name in labels: if to_folder_name in labels: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.add_label(g_thrid, to_folder_name) elif to_folder_name == inbox_folder_name: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.copy_thread(g_thrid, to_folder_name) elif to_folder_name != all_folder_name: raise Exception("Should never get here! to_folder_name: {}" .format(to_folder_name)) crispin_client.select_folder(crispin_client.folder_names()['all'], uidvalidity_cb) crispin_client.remove_label(g_thrid, from_folder_name) # do nothing if moving to all mail elif from_folder_name == all_folder_name: g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) if to_folder_name in labels: crispin_client.add_label(g_thrid, to_folder_name) elif to_folder_name == inbox_folder_name: crispin_client.copy_thread(g_thrid, to_folder_name) else: raise Exception("Should never get here! to_folder_name: {}" .format(to_folder_name)) else: raise Exception("Unknown from_folder_name '{}'". format(from_folder_name)) return syncback_action(fn, account, from_folder_name, db_session)
def _remote_copy(account, thread_id, from_folder, to_folder, db_session): """ NOTE: We are not planning to use this function yet since Inbox never modifies Gmail IMAP labels. """ if from_folder == to_folder: return def fn(account, db_session, crispin_client): inbox_folder = crispin_client.folder_names()['inbox'] all_folder = crispin_client.folder_names()['all'] g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) if to_folder == inbox_folder: crispin_client.copy_thread(g_thrid, to_folder) elif to_folder != all_folder: crispin_client.add_label(g_thrid, to_folder) # copy a thread to all mail is a noop return syncback_action(fn, account, from_folder, db_session)
def set_remote_spam(account, thread_id, spam, db_session): all_folder_name = account.all_folder.name def fn(account, db_session, crispin_client): thread = db_session.query(ImapThread).filter_by( namespace_id=account.namespace.id, id=thread_id).one() g_thrid = thread.g_thrid if spam: labels = crispin_client.get_labels(g_thrid) if '\\Inbox' in labels: crispin_client.remove_label(g_thrid, '\\Inbox') crispin_client.add_label(g_thrid, account.spam_folder.name) else: crispin_client.remove_label(g_thrid, account.spam_folder.name) crispin_client.add_label(g_thrid, '\\Inbox') return syncback_action(fn, account, all_folder_name, db_session)
def set_remote_trash(account, thread_id, trash, db_session): all_folder_name = account.all_folder.name def fn(account, db_session, crispin_client): thread = db_session.query(ImapThread).filter_by( namespace_id=account.namespace.id, id=thread_id).options(load_only('g_thrid')).one() g_thrid = thread.g_thrid if trash: labels = crispin_client.get_labels(g_thrid) if '\\Inbox' in labels: crispin_client.remove_label(g_thrid, '\\Inbox') crispin_client.add_label(g_thrid, account.trash_folder.name) else: crispin_client.remove_label(g_thrid, account.trash_folder.name) crispin_client.add_label(g_thrid, '\\Inbox') return syncback_action(fn, account, all_folder_name, db_session)
def remote_copy(account, thread_id, from_folder, to_folder, db_session): if from_folder == to_folder: return def fn(account, db_session, crispin_client): uids = [] folders = crispin_client.folder_names() if from_folder not in folders.values() and \ from_folder not in folders['extra']: raise Exception("Unknown from_folder '{}'".format(from_folder)) if to_folder not in folders.values() and \ to_folder not in folders['extra']: raise Exception("Unknown to_folder '{}'".format(to_folder)) thread = get_thread_uids(db_session, thread_id, account.namespace.id) for msg in thread.messages: uids.extend([uid.msg_uid for uid in msg.imapuids]) crispin_client.copy_uids(uids, to_folder) return syncback_action(fn, account, from_folder, db_session)
def remote_delete_draft(account, folder_name, inbox_uid, db_session): def fn(account, db_session, crispin_client): assert folder_name == crispin_client.folder_names()['drafts'] crispin_client.delete_draft(inbox_uid) return syncback_action(fn, account, folder_name, db_session)
def remote_save_draft(account, folder_name, message, db_session, date=None): def fn(account, db_session, crispin_client): assert folder_name == crispin_client.folder_names()['drafts'] crispin_client.save_draft(message, date) return syncback_action(fn, account, folder_name, db_session)
def set_remote_unread(account, thread_id, unread, db_session): def fn(account, db_session, crispin_client): g_thrid = _get_g_thrid(account.namespace.id, thread_id, db_session) crispin_client.set_unread(g_thrid, unread) return syncback_action(fn, account, account.all_folder.name, db_session)