예제 #1
0
 def flags(self) -> (str, ):
     """
     Message flags
     *This attribute will not be changed after actions: flag, seen
     """
     result = []
     if type(self._raw_flag_data) is bytes:
         result = imaplib.ParseFlags(self._raw_flag_data)
     else:
         for raw_flag_item in self._raw_flag_data:
             result.extend(imaplib.ParseFlags(raw_flag_item))
     return tuple(i.decode().strip().replace('\\', '').upper()
                  for i in result)
예제 #2
0
 def flags(self):
     'Get flags'
     r, data = self.server.uid('fetch', self.uid, '(FLAGS)')
     if r != 'OK':
         raise IMAPError(self.format_error('Could not get flags', data))
     string = data[0]
     return imaplib.ParseFlags(string) if string else ()
예제 #3
0
	def moveMsg(self,boxname):
		# Move messages from defined boxname

		selectedbox = self.From.select(boxname)
		print("Fetching emails from %s"%boxname)
		
		# Clear up the flag emails (incase it has stalled and you've started again)
		self.expunge()

		typ, data = self.From.search(None, 'ALL')
		print(">>>>" + typ)
		
		print("Found %d Messages"%len(data[0].split()))
		regex = r"Message-ID:[\s|\S]?<(.*?)>\s"
		for muid in data[0].split():
			# start messageUID process
			status, msg = self.From.fetch(muid,"(FLAGS INTERNALDATE BODY.PEEK[])") #Get email
			Email = msg[0][1]
			flags = imaplib.ParseFlags(msg[0][0]) # get Flags
			if "\\Recent" in flags:
				flag_str = "\\Seen"
			else:
				flag_str = " ".join(flags)
			print(">>>>>" + flag_str)
			date = imaplib.Time2Internaldate(imaplib.Internaldate2tuple(msg[0][0])) #get date
			copy_result = self.To.append(boxname, flag_str, date, Email) # Copy to Archive
			if copy_result[0] == 'OK':
				del_msg = self.From.store(muid, '+FLAGS', '\\Deleted') # Mark for deletion (this is deleted via expunge)
		self.expunge()
예제 #4
0
 def list_last_emails(self, nb=20):
     """List last messages"""
     res, data = self.connection.search(None, 'ALL')
     if res != "OK":
         logger.error("Unable to fetch mails")
         return []
     lst = []
     for mail_id in data[0].split()[-nb:]:
         res, flags_data = self.connection.fetch(mail_id, '(FLAGS)')
         if res != "OK":
             logger.error(
                 "Unable to fetch flags for mail {0}".format(mail_id))
             continue
         flags = imaplib.ParseFlags(flags_data[0])
         mail = self.get_mail(mail_id)
         if not mail:
             continue
         parser = Parser(mail)
         parsed_orig_mail = MailParser(mail)
         if isinstance(mail_id, bytes):
             mail_id = mail_id.decode()
             flags = [fl.decode() for fl in flags]
         lst.append(u"{}: '{}', '{}', {}, ''{}".format(
             mail_id, parsed_orig_mail.subject, parser.headers['Subject'],
             parsed_orig_mail.headers['From'], flags))
         logger.info(lst[-1])
     return lst
예제 #5
0
    def parse_mail(self):
        """
        Retrieves a message's header from the IMAP server and parses its
        headers in the email header data structure used by the user's filters.
        This method is invoked by the parent class' constructor.
        """

        # Mail has already been parsed in this case
        if not (self._headers is None and self.message_flags is None):
            return True

        self._processor.log("")
        self._processor.log("New mail detected with UID {0}:".format(self.uid))

        try:
            ret, data = self._processor.imap.uid('fetch', self.uid,
                                                 "(FLAGS BODY.PEEK[HEADER])")
        except self._processor.imap.error as e:
            # Anything imaplib raises an exception for is fatal here.
            self._processor.fatal_error("Error retrieving message "
                                        "with UID %s: %s" % (self.uid, e))
        if ret != 'OK':
            self._processor.log_error(
                "Error: Could not retrieve message {0}: {1}".format(
                    self.uid, ret))
            return False

        flags = imaplib.ParseFlags(data[0][0])

        if self.message_flags is None:
            self.message_flags = []
            for flag in flags:
                self.message_flags.append(flag.decode('ascii'))

        headers = email_parser.Parser().parsestr(data[0][1].decode('ascii'),
                                                 headersonly=True)

        if self._headers is None:
            self._headers = {}
            for name in headers.keys():
                value_parts = []
                for header in headers.get_all(name, []):
                    try:
                        for (s, c) in email_header.decode_header(header):
                            # email.header.decode_header in Python 3.x may
                            # return either [(str, None)] or [(bytes,
                            # None), ..., (bytes, encoding)]. We must
                            # compensate for this.
                            if not isinstance(s, str):
                                s = s.decode(c if c else "ascii")
                            value_parts.append(s)
                    except (email_errors.HeaderParseError, LookupError,
                            ValueError):
                        self._processor.log_error(
                            "Error: Could not decode header {0} in message "
                            "UID {1}".format(ascii(header), self.uid))
                        value_parts.append(header)
                self._headers[name.lower()] = " ".join(value_parts)

        return True
예제 #6
0
    def refresh_flags(self):
        """
        Refreshes message flags for all messages in header cache.
        """

        self.log_info("==> Updating message flags...")
        for folder in self.header_cache:
            try:
                ret, data = self.get_flags(folder)
            except self.imap.abort:
                self.log_error("IMAP connection aborted, reconnecting.")
                # Reconnect if the connection has timed out due to the header
                # cache update taking too long (may happen on mailboxes with
                # lots of messages).
                self.reconnect()
                ret, data = self.get_flags(folder)
            for msg in data:
                flags = []
                flags_raw = imaplib.ParseFlags(msg)
                for flag in flags_raw:
                    flags.append(flag.decode('ascii'))
                uid = re.search('UID (\d+)',
                                msg.decode('ascii')).group().split(" ")[1]
                self.log_debug("UID: %s" % uid)
                self.log_debug("  server flags: %s" % flags)
                self.log_debug("   cache flags: %s" %
                               self.header_cache[folder]['uids'][uid]['flags'])
                self.header_cache[folder]['uids'][uid]['flags'] = flags
                self.header_cache[folder]['uids'][uid]['obj'].message_flags = flags
        self.log_info("==> Message flags updated.")
예제 #7
0
    def refresh_flags(self):
        """
        Refreshes message flags for all messages in header cache.
        """

        self.log_info("==> Updating message flags...")
        for folder in self.header_cache:
            self.select(folder)
            uids = ",".join(self.header_cache[folder]['uids'])
            try:
                ret, data = self.imap.uid('fetch', uids, "FLAGS")
            except self.imap.error as e:
                self.fatal_error(
                    "Error forwarding: Could not retrieve message flags for folder {0}: {1}"
                    "{1}".format(folder, e))
            for msg in data:
                flags = []
                flags_raw = imaplib.ParseFlags(msg)
                for flag in flags_raw:
                   flags.append(flag.decode('ascii'))
                uid = m = re.search('UID (\d+)',
                                    msg.decode('ascii')).group().split(" ")[1]
                self.log_debug ("UID: %s" % uid)
                self.log_debug("  server flags: %s" % flags)
                self.log_debug("   cache flags: %s" %
                               self.header_cache[folder]['uids'][uid]['flags'])
                self.header_cache[folder]['uids'][uid]['flags'] = flags
                self.header_cache[folder]['uids'][uid]['obj'].message_flags = flags
        self.log_info("==> Message flags updated.")
예제 #8
0
def parse_imap_flags(flagstr: List[bytes]) -> List[EmailFlag]:
    parsed_flag_strings = [f.decode() for f in imaplib.ParseFlags(flagstr[0])]
    flags = []
    for flag in EmailFlag:
        if MAP_FLAG_TO_IMAP[flag] in parsed_flag_strings:
            flags.append(flag)
    return flags
예제 #9
0
def parse_flags(headers):
    """Copied from https://github.com/girishramnani/gmail/blob/master/gmail/message.py"""
    if len(headers) == 0:
        return []
    if sys.version_info[0] == 3:
        headers = bytes(headers, "ascii")
    return list(imaplib.ParseFlags(headers))
예제 #10
0
async def get_list(request, username, tag):
    global clients
    client, timestamp = clients.get(username, [None, None])
    if client and time.time() - timestamp > 60 * 60:  # over an hour
        del clients[username]
        client = None
    if not client:
        return json(None, status=401)
    messages = []
    if client.selected is not tag:
        for item in client.connection.list()[1]:
            real_tag = shlex.split(item.decode())[-1]
            if real_tag.lower().count(tag):
                break
        client.connection.select(quote_folder_name(real_tag))
    client.selected = tag
    uids = client.connection.uid('search', None, '(ALL)')[1][0].split()
    if not uids:
        return json([])
    response = client.connection.uid(
        "fetch", b",".join(uids[-100:]),
        "(BODY.PEEK[HEADER.FIELDS (FROM TO DATE SUBJECT)] FLAGS)")
    for labels, message in response[1][::2]:
        message = parser.parse_email(message)
        message.uid = labels.split()[2]
        message.flags = imaplib.ParseFlags(labels)
        del message.raw_email
        messages.append(message)
    return json(reversed(messages))
예제 #11
0
 def __iter__(self):
     from kryptomime.mail import protect_mail
     filter = "(OR UNSEEN FLAGGED)" if self.filter else 'ALL'
     status, response = self.imap.uid('search', None, filter)
     if not status == 'OK': return
     email_ids = response[0].split()
     for e_id in email_ids:
         status, response = self.imap.uid('fetch', e_id, '(FLAGS)')
         flags = ''
         for flag in imaplib.ParseFlags(response[0]):
             if 'Flagged' in flag: flags += 'F'
             elif 'Seen' in flag: flags += 'S'
             elif 'Deleted' in flag: flags += 'D'
         if 'D' in flags: continue
         # mark for processing
         status, response = self.imap.uid('store', e_id, '+FLAGS',
                                          r'(\Flagged)')
         status, response = self.imap.uid('fetch', e_id, '(RFC822)')
         raw = response[0][1]
         yield protect_mail(raw), flags
         if self.keep:
             status, response = self.imap.uid('store', e_id, '-FLAGS',
                                              r'(\Flagged)')
         else:
             status, response = self.imap.uid('store', e_id, '+FLAGS',
                                              r'(\Deleted)')
예제 #12
0
async def add_flag(request, username, tag, uid, flag):
    client, _ = clients.get(username)
    flag = FLAGS[flag]
    flags = client.connection.uid("store", uid, "+FLAGS", flag)[1][0]
    if flags is None:
        flags = ""
    flags = imaplib.ParseFlags(flags)
    return json(flags)
예제 #13
0
    def get_flags_from_struct(data):
        """Get flags to copy old flags to new message."""

        flags = imaplib.ParseFlags(data[1])
        flags = b" ".join(flags) if flags != () else b""
        flags = flags.decode("utf-8")
        flags = flags.replace("\\Recent", "")  # read-only attribute
        return flags.strip()
예제 #14
0
 def _clean_message_data(fetch_data):
     """
     :param fetch_data: Message object model
     :returns [message_data: bytes, uid_data: bytes, flag_data: list]
     *Elements may contain byte strings in any order, like: b'4517 (FLAGS (\\Recent NonJunk))'
     """
     message_data = b''
     uid_data = b''
     flag_data = []
     for fetch_item in fetch_data:
         # flags
         if type(fetch_item) is bytes and imaplib.ParseFlags(fetch_item):
             flag_data.extend(imaplib.ParseFlags(fetch_item))
         # data, uid
         if type(fetch_item) is tuple:
             uid_data = fetch_item[0]
             message_data = fetch_item[1]
     return message_data, uid_data, flag_data
예제 #15
0
 def flags(self) -> [str]:
     """
     Message flags
     *This attribute will not be changed after actions: flag, seen
     """
     result = []
     for raw_flag_item in self._raw_flag_data:
         result.extend(imaplib.ParseFlags(raw_flag_item))
     return [i.decode().strip().replace('\\', '').upper() for i in result]
예제 #16
0
 def should_handle(self, mail_id):
     res, flags_data = self.connection.fetch(mail_id, '(FLAGS)')
     if res != "OK":
         logger.error("Unable to fetch flags for mail {0}".format(mail_id))
         return False
     flags = imaplib.ParseFlags(flags_data[0])
     if b"imported" in flags or b"error" in flags or b"unsupported" in flags:
         return False
     return True
예제 #17
0
파일: message.py 프로젝트: ikvk/imap_tools
 def flags(self) -> Tuple[str, ...]:
     """
     Message flags
     *This attribute will not be changed after "flag" actions
     """
     result = []
     for raw_flag_item in self._raw_flag_data:
         result.extend(imaplib.ParseFlags(raw_flag_item))
     return tuple(i.decode().strip() for i in result)  # noqa
예제 #18
0
 def __init__(self, email, uid, folders, msg, flags=None):
     self.email = email
     self.uid = uid
     self.folders = folders
     self.msg = email_lib.message_from_bytes(msg[1])
     try:
         self.flags = imaplib.ParseFlags(flags)
     except:
         self.flags = None
예제 #19
0
 def flag_from_string(self, data_set):
     result = []
     for raw_flag_item in data_set:
         if isinstance(raw_flag_item, string_types):
             raw_flag_item = raw_flag_item.encode("utf-8")
         result.extend(imaplib.ParseFlags(raw_flag_item))
     flags = tuple(item.decode().strip().replace('\\', '').upper()
                   for item in result)
     self.flags = flags
     return flags
예제 #20
0
파일: imapobj.py 프로젝트: chyser/bin
 def getMsgHdr(self, num):
     #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     num = str(num)
     typ, data = self.mb.fetch(num, '(FLAGS RFC822.HEADER)')
     hdr = data[0][1]
     imh = email.parser.Parser(IMAPMsgHdr).parsestr(hdr, True)
     imh.msgid = num
     imh.flags = imaplib.ParseFlags(data[0][0])
     imh.server = self
     return imh
예제 #21
0
파일: mbox.py 프로젝트: IwaoWatanabe/hitk
    def fetch_header(self, mid):
        "ヘッダ情報を取得する"
        if not self.imap: raise IOError(self.not_connected)

        parts = '(UID FLAGS INTERNALDATE RFC822.HEADER)'
        rc, res = self.imap.fetch(mid, parts)
        if not rc == 'OK':
            raise IOError('unkown fetch response(%s)' % res)

        msgs = []
        rlen = len(res)
        #print mid, 'rlen:', rlen

        ct = 0
        ect = 0
        mid = 0
        while ct + 2 <= rlen:
            try:
                #print res[ct:ct+2]
                ((res1, rawhead), ep) = res[ct:ct + 2]

                emsg = EMessage()
                mid = res1.split()[0]
                emsg.id = int(mid)
                emsg.received = imaplib.Internaldate2tuple(res1)

                flags = imaplib.ParseFlags(res1)
                emsg.flags = flag_text(flags)

                mr = UID_PATTERN.search(res1)
                if not mr: raise IOError('no uid response(%s)' % res1)
                emsg.uid = int(mr.group(1))

                mr = SIZE_PATTERN.search(res1)
                emsg.size = int(mr.group(1)) if mr else None

                #print res1, ep
                #print 'uid', uid, 'received', received
                emsg.parse(rawhead, headersonly=True)

                msgs.append(emsg)
            except Exception as e:
                ect += 1
                if log:
                    if ect == 1:
                        log.exception('parse: %s: %s', mid, e)
                    else:
                        log.warn('parse: %s: %s', mid, e)
                else:
                    log.debug('WARN: parse: %s: %s', mid, e)
            finally:
                ct += 2

        return msgs
예제 #22
0
def createMail(imap, mailbox, new_message, flags):
    now = time.time()
    if not new_message.has_key("date"):
        new_message["date"] = imaplib.Time2Internaldate(now)

    response = imap.append(mailbox, imaplib.ParseFlags(flags), now, new_message.as_string(True))
    if (response[0] != "OK"):
        return -1
    else:
        uid = response[1][0].split("]")[0].split(" ")
        return int(uid[len(uid)-1])
예제 #23
0
파일: mail.py 프로젝트: kirin123kirin/cmd
 def _get_message_data_parts(fetch_data) -> (bytes, bytes, [bytes]):
     raw_message_data = b''
     raw_uid_data = b''
     raw_flag_data = []
     for fetch_item in fetch_data:
         # flags
         if type(fetch_item) is bytes and imaplib.ParseFlags(fetch_item):
             raw_flag_data.append(fetch_item)
         # data, uid
         if type(fetch_item) is tuple:
             raw_uid_data = fetch_item[0]
             raw_message_data = fetch_item[1]
     return raw_message_data, raw_uid_data, raw_flag_data
예제 #24
0
파일: mbox.py 프로젝트: IwaoWatanabe/hitk
    def __flag(self, msgset, cmd, flags, with_silent=True):
        ft = type(flags)
        if ft == list or ft == tuple or ft == set:
            flags = ' '.join(flags)

        rc, res = self.imap.store(msgset, cmd, flags)
        if not rc == 'OK' or with_silent: return None

        rc = []
        for rt in res:
            mid = int(rt[0:rt.find(' ')])
            flags = imaplib.ParseFlags(rt)
            rc.append((mid, flags))
예제 #25
0
 def get_imapflags(self, uid):
     """ Return a list of imap flags for the message with UID
         Raise exception if there if there is no message with that UID.
     """
     try:
         (code, data) = self._server.uid('fetch', uid, '(FLAGS)')
         flagresult = data[0]
         if code != 'OK':
             raise ImapNotOkError("%s in get_imapflags(%s)" % (code, uid))
         return list(imaplib.ParseFlags(flagresult))
     except (TypeError, ValueError):
         raise ValueError("Unexpected results while fetching flags " \
                      + "from server for message %s; response was (%s, %s)" \
                                                          % (uid, code, data))
예제 #26
0
    def get_email_seen_status(self, uid, flag_string):
        """ parse the email FLAGS response """
        if not flag_string:
            return None

        flags = []
        for flag in imaplib.ParseFlags(flag_string) or []:
            pattern = re.compile("\w+")
            match = re.search(pattern, frappe.as_unicode(flag))
            flags.append(match.group(0))

        if "Seen" in flags:
            self.seen_status.update({uid: "SEEN"})
        else:
            self.seen_status.update({uid: "UNSEEN"})
예제 #27
0
 def _get_message_data_parts(fetch_data) -> (bytes, bytes, [bytes]):
     """
     :param fetch_data: Message object model
     :returns (raw_message_data: bytes, raw_uid_data: bytes, raw_flag_data: [bytes])
     *Elements may contain byte strings in any order, like: b'4517 (FLAGS (\\Recent NonJunk))'
     """
     raw_message_data = b''
     raw_uid_data = b''
     raw_flag_data = []
     for fetch_item in fetch_data:
         # flags
         if type(fetch_item) is bytes and imaplib.ParseFlags(fetch_item):
             raw_flag_data.append(fetch_item)
         # data, uid
         if type(fetch_item) is tuple:
             raw_uid_data = fetch_item[0]
             raw_message_data = fetch_item[1]
     return raw_message_data, raw_uid_data, raw_flag_data
예제 #28
0
    def retrieve_messages(self,
                          message_ids: t.List[int],
                          folder: t.Optional[str] = None,
                          headers_only: bool = False) -> t.List[Message]:
        """For each message ID request message flags and contents and parse it to Message."""

        requested_parts = ['FLAGS']
        # The BODY.PEEK[] is a functional equivalent of obsolete RFC822.PEEK,
        # see https://www.ietf.org/rfc/rfc2062 for details.
        requested_parts.append(
            'BODY.PEEK[HEADER]' if headers_only else 'BODY.PEEK[]')

        # flags_data = self.retrieve_messages_parts(message_ids, ['FLAGS'], folder)
        # print(flags_data[0])
        # all_data = self.retrieve_messages_parts(message_ids, ['FLAGS', 'BODY.PEEK[]'], folder)
        # print(all_data[0])
        messages_data = self.retrieve_messages_parts(message_ids,
                                                     requested_parts, folder)

        messages = []
        for message_id, (metadata, message) in zip(message_ids, messages_data):
            email_message = email.message_from_bytes(message)
            if headers_only:
                email_message.defects = [
                    defect for defect in email_message.defects
                    if not isinstance(defect, HEADER_ONLY_IGNORED_DEFECTS)
                ]
            if email_message.defects:
                _LOG.error('%s: message #%i in "%s" has defects: %s', self,
                           message_id, self._folder, email_message.defects)

            message = Message(email_message, self, self._folder, message_id)
            flags = imaplib.ParseFlags(metadata)
            for raw_flag in flags:
                flag = raw_flag.decode()
                if flag.startswith('\\'):
                    flag = flag[1:]
                else:
                    _LOG.warning('atypical flag "%s" detected in "%s"', flag,
                                 flags)
                message.flags.add(flag)
            messages.append(message)

        return messages
예제 #29
0
def Mail(session, mailbox, message_uid, expunge=False):

    # select mailbox
    ok, response = session.select(mailbox)
    if ok != "OK":
        raise Exception(response)

    # fetch message and split response
    ok, response = session.uid('fetch', str(message_uid), "(FLAGS INTERNALDATE RFC822)")
    if ok != "OK":
        raise Exception(response)

    metadata = response[0][0]
    rfcbody = response[0][1]

    # parse flags, date and message body
    flags = " ".join([f.decode() for f in imaplib.ParseFlags(metadata)])
    date = imaplib.Internaldate2tuple(metadata)
    mail = email.message_from_bytes(rfcbody)

    # debug
    with color(COLOR.BLUE):
        print("Message UID:", mailbox, f"({message_uid})")
        print("From    :", mail["From"])
        print("Date    :", mail["Date"])
        print("Subject :", mail["Subject"])

    # yield mail for editing
    state = {"mail": mail, "dirty": False}
    yield state

    # if message was edited, append to mailbox and
    # set deletion flag on old message
    if state["dirty"] == True:
        with color(COLOR.RED):
            print("Message modified. Reuploading ..")
        session.append(mailbox, flags, date, mail.as_bytes())
        session.uid('store', message_uid, "+FLAGS", "\\DELETED")

        # optionally directly expunge
        if expunge:
            session.expunge()
예제 #30
0
 def stats(self):
     """List all flags"""
     res, data = self.connection.search(None, 'ALL')
     if res != "OK":
         logger.error("Unable to fetch mails")
         return []
     lst = []
     stats = {'tot': 0, 'flags': {}}
     for mail_id in data[0].split():
         stats['tot'] += 1
         res, flags_data = self.connection.fetch(mail_id, '(FLAGS)')
         if res != "OK":
             logger.error(
                 "Unable to fetch flags for mail {0}".format(mail_id))
             continue
         for flag in imaplib.ParseFlags(flags_data[0]):
             flag = flag.decode()
             if flag not in stats['flags']:
                 stats['flags'][flag] = 0
             stats['flags'][flag] += 1
     return stats