def __init__(self, mailbox, metadata, headers, metadata_pattern): self.mailbox = mailbox self.account = mailbox.account self.conn = self.account.connection metadata_rs = metadata_pattern.match(metadata) if not metadata_rs: _log.error("Bad formatted metadata string") _log.error(metadata) self.id, self.gmail_id, labels, self.uid, internal_date = metadata_rs.groups() self.internal_date = Internaldate2tuple(metadata) self.flags = ParseFlags(metadata) or [] self.labels_raw = labels ### First parse out the metadata about the email message self.headers = HEADER_PARSER.parsestr(headers) for attr, single_header in (('date', 'Date'), ('subject', 'Subject')): header_value = self.get_header(single_header) setattr(self, attr, header_value[0] if header_value else '') self.sender = self.get_header("From") self.to = self.get_header('To') self.cc = self.get_header("Cc") message_ids = self.get_header('Message-Id') if len(message_ids) == 0: self.message_id = None else: self.message_id = message_ids[0]
def check_for_response_error(imap_response, require_ok=True): """Checks to see if the given response, from a raw imaplib2 call, is an error. Args: imap_response -- The 3 part tuple (response, cb_arg, error) that imaplib2 returns as a result of any callback response Keyword Args: require_ok -- Whether responses other than "OK" from the IMAP server should trigger an error Returns: An IMAPError object encapsulating the error (in the case of an error), or None (in the case of no error). """ # A three item response means a response from an async request, while # a two item response is a result from a standard blocking request if len(imap_response) == 3: response, cb_arg, error = imap_response if response is None: if __debug__: _log.error(error[1]) return IMAPError(error[1]) else: typ, data = response if typ != "OK" and require_ok: return IMAPError(desc=data, type=typ) else: return None else: typ, data = imap_response if typ != "OK" and require_ok: return IMAPError(desc=data, type=typ) else: return None
def _on_search_for_message_complete(imap_response): data = extract_data(imap_response) # Its possible here that we've tried to select the message # we want to delete from the trash bin before google has # registered it there for us. If our search attempt returned # a uid, then we're good to go and can continue. try: deleted_uid = data[0].split()[-1] cbp = dict(deleted_uid=deleted_uid) return _cmd_cb(self.conn, _on_received_connection_4, bool(callback), callback_args=cbp) # If not though, we should wait a couple of seconds and try # again. We'll do this a maximum of 5 times. If we still # haven't had any luck at this point, we give up and return # False, indiciating we weren't able to delete the message # fully. except IndexError: self.num_tries += 1 # If this is the 5th time we're trying to delete this # message, we're going to call it a loss and stop trying. # We do some minimal clean up and then just bail out # Otherwise, schedule another attempt in 2 seconds and # hope that gmail has updated its indexes by then if self.num_tries == 5: del self.num_tries if __debug__: _log.error(u"Giving up trying to delete message {subject} - {id}".format(subject=self.subject, id=self.message_id)) _log.error("got response: {response}".format(response=str(imap_response))) return _cmd(callback, False) else: if __debug__: _log.error("Try {num} to delete deleting message {subject} - {id} failed. Waiting".format(num=self.num_tries, subject=self.subject, id=self.message_id)) _log.error("got response: {response}".format(response=str(imap_response))) return _cmd_in(_on_trash_selected, 2, bool(callback), force_success=True)