示例#1
0
文件: imap.py 项目: CrabbyPete/spot
    def get_text(self, mess):
        text =[]
        html =[]
        char_set = mess.get_charsets()

        for part in mess.walk():
            type    = part.get_content_type()
            charset = part.get_content_charset()
            if type == 'text/plain':
                body = part.get_payload()

                # Determine what character set they use and convert to utf8
                body = quopri.decodestring(body)
                body = decode_heuristically(body, enc = charset, denc = "utf-8")
                if body != None:
                    text.append(body[0])
   
            elif type == 'multipart/alternative':
                body = part.get_payload()
                if isinstance(body,ListType):
                    for b in body:
                        tx,ht = self.get_text(b)
                        text.append(tx)
                        html.append(ht)
                        
                else:
                    body = quopri.decodestring(body)
                    body = quopri.decodestring(body)
                    body = decode_heuristically(body, enc = charset, denc = "utf-8")
                    if body != None:
                        htlm.append(body[0])
                
        return text,html
def handleOutgoingMail (ctx, mail):
	#imprime(mail)
	uri = __aps__['uri']
	if uri:
		found = None
		for line in mail.head:
			if line.lower ().startswith ('list-unsubscribe:'):
				found = line
				break
		if found is None:	
			# Tentando extrair link embutido na newsletter
			if mail.body is not None:
				soup = BeautifulSoup(quopri.decodestring(mail.body), "html.parser")
				linkSair = soup.find('a',id='linkUnsubscribe')
				
				if linkSair is not None:
					if linkSair['href'].lower().find("form.do") != -1:
						novoLink = linkSair['href']
					else:
					# Substituindo link pelo mnemônico, a fim de permitir reconhecimento em alguns leitores de e-mails
						novoLink = (uri % linkSair['href'][linkSair['href'].lower().find("uid=")+4:])
						er = re.compile(r"<a[^<]*linkUnsubscribe.*?>",re.IGNORECASE|re.DOTALL)
						
						linkInserido = quopri.decodestring(re.search(er,mail.body).group())
						erStyle = re.compile(r"(style=.*?)[a-z].=",re.IGNORECASE|re.DOTALL)
						styleAdd = re.search(erStyle,linkInserido).group(1) if re.search(erStyle,linkInserido) else ""

						mail.body = re.sub(er,quopri.encodestring(("<a %s href=%s>" % (styleAdd,novoLink))),mail.body)
						
					mail.head.append ('List-Unsubscribe: <%s>' % novoLink)
					#imprime(mail)
					return
示例#3
0
 def hashLoginPassword(username, password, sessionid):
     """ Hashes login password """
     username = quopri.decodestring(username)
     username = username.lower()
     password = quopri.decodestring(password)
     sha = hashlib.sha1(username + password).hexdigest()
     sha = hashlib.sha1(sha + sessionid).hexdigest()
     return sha
def headerUnicode(mimebytestring):
    h = email.header.decode_header(mimebytestring)
    res = []
    for hh in h:
        if hh[1] is None:
            res.append(unicode(quopri.decodestring(hh[0])))
        else:
            res.append(unicode(quopri.decodestring(hh[0]).decode(hh[1])))
    return u" ".join(res)
示例#5
0
def maintain_rfc_parse(message):
    """
    This function parses an email and returns an array with different parts of the message
    but leaves the email still RFC compliant so that it works with Mail-Parser Plus app.
    Attachment headers are left in tact.
    :param message: This represents the email to be checked for attached email.
    :type message: email message object
    :return: Returns a email message formatted as a string
      :rtype: str
    """
    if not message.is_multipart():
        reformatted_message = quopri.decodestring(
                                message.as_string().encode('ascii', 'ignore')
                            ).decode("utf-8",'ignore')
        return reformatted_message
    boundary = message.get_boundary()
    new_payload = '--' + boundary
    for i in message.get_payload():
        content_type = i.get_content_type()
        extension = str(os.path.splitext(i.get_filename() or '')[1]).lower()
        if extension in TEXT_FILE_EXTENSIONS or content_type in SUPPORTED_CONTENT_TYPES or \
           i.get_content_maintype() == 'text':
            text_content = i.as_string().encode('ascii', 'ignore')
            text_content = quopri.decodestring(text_content).decode("utf-8",'ignore')
            new_payload += '\n' + text_content
        else:
            replace = re.sub(r'(?:\n\n)[\s\S]+',r'\n\n#UNSUPPORTED_ATTACHMENT:',i.as_string())
            filename = i.get_filename()
            charset = i.get_content_charset()
            try:
                md5 = hashlib.md5(i.get_payload(None,True)).hexdigest()
                sha256 = hashlib.sha256(i.get_payload(None,True)).hexdigest()
            except:
                md5 = ''
                sha256 = ''
            replace_string = """
file_name = %(filename)s
type = %(content_type)s
charset = %(charset)s
md5 = %(md5)s
sha256 = %(sha256)s
"""
            metadata = replace_string % dict(
                content_type=content_type, 
                filename=filename, 
                charset=charset,
                md5=md5,
                sha256=sha256,
            )
            new_payload += '\n' \
                + replace \
                + metadata
        new_payload += '\n--' + boundary
    new_payload += '--'
    message.set_payload(new_payload)
    return message.as_string()
示例#6
0
 def set_message(self, message):
     self.sender = get_sender(message['Subject'])
     self.to = message['To']
     if message.is_multipart():
         src = unicode(quopri.decodestring(message.get_payload()[0]))
     else:
         src = unicode(quopri.decodestring(message.get_payload()))
     self.body, rest = split_body(src)
     self.loc = get_loc(rest)
     self.url = get_link(rest)
     self.raw = message.as_string()
     self.sent = datetime.datetime(*rfc822.parsedate(message['Date'])[:6])
def decodeContentType(part):
    tmp = re.search('(?si)Content-Type: +(.*?)(?: |\n|;)', part)
    if tmp!=None:
        content_type = tmp.group(1)
    else:
        content_type = ''
    tmp = re.search('charset="{0,1}([A-Za-z0-9\-]+)', part)
    if tmp!=None:
        enc = tmp.group(1)
    else:
        enc = ''
    tmp = re.search('(?s).*?(?:\n\n|\r\n\r\n)(.*)', part)
    if tmp!=None:
        body = tmp.group(1)
    else:
        body = ''
    tmp = re.search('(?si)(content-disposition: *attachment)', part)
    if tmp == None:
        tmp = re.search('(?si)(content-disposition: *inline)', part)
    if tmp!=None:
        attachment = 1
        tmp = re.search('(?si)content-type:.*?(?:\n\n|\r\n\r\n)(.*)', body)
        if tmp!=None:
            body = tmp.group(1)
    else:
        attachment = 0
    tmp = re.search('Content-Transfer-Encoding: +([a-zA-Z0-9\-]*)', part)
    if tmp!=None:
        cte = tmp.group(1)
        if cte.lower() == 'base64' and (content_type=='text/plain' or content_type=='text/html') and attachment==0:
            if (enc==''):
                body = base64.b64decode(body.encode('utf-8')).decode('utf-8', 'replace')
            else:
                body = base64.b64decode(body.encode('utf-8')).decode(enc, 'replace')
        if cte.lower() == 'quoted-printable' and (content_type=='text/plain' or content_type=='text/html') and attachment==0:
            if enc=='':
                body = quopri.decodestring(body.encode('utf-8')).decode('utf-8')
            else:
                body = quopri.decodestring(body.encode('utf-8')).decode(enc)

    tmp = re.search('(?si)filename="{0,1}(.*?)(?:"|\n)', part)
    if tmp!=None:
        filename = decodeHeader(tmp.group(1))
    else:
        filename = ''
    tmp = re.search('(?si)Content-Id: *<([^>]*)>', part)
    if tmp!=None:
        content_id = tmp.group(1)
    else:
        content_id = ''
    return content_type, enc, body, attachment, filename, content_id
示例#8
0
 def do_search(self, request):
     import quopri, re
     a = request.args
     login = request.getUser()
     obj = yield self.buckets['mailmeta'].get(login)
     user_emails = obj.get_data().keys()
     terms = a.get('terms')[0]
     print 'TERMS:', terms
     res = yield self.buckets['mailbody'].search(terms)
     request.write('search found this:')
     r1 = re.compile(r".*Delivered-To:\s([a-zA-Z0-9.-]+)@.*?\n.*", re.DOTALL)  # is this all?
     for doc in res['docs']:
         data = doc['value']
         m = r1.match(data)
         if m.group(1) != login:
             continue  # this msg was not for this user, skip it.
         content_trans = 'Content-Transfer-Encoding: quoted-printable'
         if content_trans in data:
             headers, _, body = data.partition(content_trans)
         else:
             headers, body = data, ''
         out = headers.decode('ascii')  # headers should always be ascii-onl
         s = quopri.decodestring(body).decode('utf-8', errors='replace')
         print type(out),type(s)
         out = out + s
         out = out.encode('utf-8')
         request.write('<pre>' + out + '</pre>')
示例#9
0
def str_conv(str, ):
    """ Конвертирование Subject во входящих Email """
    error = False

    if not str:
        return str, error

    values = str.split('\n')
    value_results = []

    for value in values:
        match = re.search(r'=\?((?:\w|-)+)\?(Q|q|B|b)\?(.+)\?=', value)
        if match:
            encoding, type_, code = match.groups()
            if type_.upper() == 'Q':
                value = quopri.decodestring(code)
            elif type_.upper() == 'B':
                value = base64.decodestring(code)
            try:
                value = str_encode(string=value, encoding=encoding, )
            except UnicodeDecodeError:
                value = str_encode(string=value, encoding=encoding, errors='replace', )
                error = True
            value_results.append(value)

    if len(value_results) > 0:
        return ''.join(value_results), error

    return str, error
    def test_notifications_for_new_reply(self):
        ws = self.portal['workspaces']['workspace-1']
        people = self.portal['people']
        post = ws['post-2']
        self.mailhost.messages = []
        login(self.portal, 'test_user_1')
        helpers.create_reply(post, 'new-reply',
            text=richtextify(u"<p>test</p><p>test</p>123"))

        self.assertEqual(len(self.mailhost.messages), 2)

        recipients = [unicode(m['To']) for m in self.mailhost.messages]
        expected_recipients = []
        for uid in ['test_user_1', 'test_user_2']:
            name = getattr(people.get(uid, None), 'title', uid)
            email = getattr(people.get(uid, None), 'emailAddress', None)
            expected_recipients.append('{0} <{1}>'.format(name, email))
        self.assertEqual(recipients, expected_recipients)

        for message in self.mailhost.messages:
            self.assertEqual(unicode(message['Subject']), u"[Plone site] " +
                u"Test User replied to “Post 2” in Workspace 1")

            msg_text = quopri.decodestring(message.get_payload())
            expected_msg_text = u"test\n\ntest\n123"
            self.assertEqual(msg_text, expected_msg_text)
示例#11
0
    def detachFile(self, att_name, filecontent, date=None):
        """ Writes the file and return the corresponding html

            The html file will store a link to the detached file
            If the file already exists, we compute a new name and create a link to the computed name file
            and to the file that has the same name...
            date is the date to use for the detached file
        """
        att_name=os.path.split(att_name)[1] # sometimes, the name of the attached file contains the whole path which is not wanted
        if att_name.find('=?') != -1: # If the filename is encoded, we decode it
            filename=quopri.decodestring(self.decode_Q(att_name).encode('latin1')) # and encode it in latin1 (you may change this to utf-8)
        else:
            filename=att_name
        filelist=[filename] # 
        # we write the attached file
        # Sometimes, due to formating, we find \n, \r or \t characters in the filenames. So we cut them off
        ofname=os.path.join(prm.attachedFilesDir, filename.strip().replace('\n','').replace('\r','').replace('?','').expandtabs(0))
        if os.path.exists(ofname):
            i=1
            fname=ofname
            sfname=os.path.splitext(fname)
            while os.path.exists(fname):
                fname="%s[%d]%s" % (sfname[0], i, sfname[1])
                i+=1
            filelist.append(os.path.split(fname)[-1])
            ofname=fname # the outfile name is the new one
        of=open(ofname,'wb')
        of.write(filecontent)
        of.close()
        if date:
            os.utime(ofname, (date, date))
        return self.getHtmlLinksFileContent(filelist)
示例#12
0
  def decode_body(self, bodyonly, charset, encoding):
    new_body = ""
    if encoding=="base64":
      try :
        new_body = base64.b64decode(bodyonly)
      except:
        dbgprint("into except base64")
        pass
    elif encoding=="quoted-printable" :
      try:
        #new_body = decode_header(new_body)[0][0].decode('utf-8')
        #new_body = str(quopri.decodestring(new_body).decode('utf-8')).strip()
        new_body = quopri.decodestring(bodyonly)
      except:
        dbgprint("into except qp")
        pass
    else :
      new_body = bodyonly
      dbgprint("unknown encoding:", encoding)

    #now decode the charset
    try :
      new_body = new_body.decode(charset)
    except:
      #make sure a string is passed, also if failed
      new_body = "".join(map(chr,new_body))
      dbgprint("decoding failed")
      pass
    return new_body
示例#13
0
文件: views.py 项目: averrin/eliar
def get_msg_content(msg):
    from BeautifulSoup import BeautifulSoup
    text=''
    last=msg['id']
    if msg.is_multipart():
        text=get_from_mp(msg)
    else:
        text=msg.get_payload(decode=True)

    text=quopri.decodestring(text)
    enc=BeautifulSoup(text).originalEncoding
    msg['enc']=enc
    subre="<b><span style='font-weight:bold'>Subject:</span></b> Re:"
    print msg['subj_e']


    if enc and enc in ['ISO-8859-2']:
        try:
            msg['text']=text.decode('cp1251')
        except:
            msg['text']=text.replace('\x98','').decode('cp1251')
    elif enc and enc not in ['utf8','utf-8']:
        msg['text']=text.decode(enc)
    else:
        msg['text']=text

    return msg['text']
    def read(self, n = None):
        """
python.org: Read up to n bytes from the object and return them.

:param n: How many bytes to read from the current position (0 means until
          EOF)

:return: (bytes) Data; None if EOF
:since:  v0.2.00
        """

        raw_data = self.raw_read(n)

        decoded_data = (Binary.BYTES_TYPE() if (self.decoded_data is None) else self.decoded_data)

        if (raw_data is not None):
            if (raw_data[-1:] == QuotedPrintableDecoder.BINARY_EQUAL_SIGN):
                additional_raw_data = self.raw_read(3)
                if (additional_raw_data is not None): raw_data += additional_raw_data
            #

            decoded_data += decodestring(raw_data)
        #

        if (len(decoded_data) > n): self.decoded_data = decoded_data[n:]
        return decoded_data[:n]
示例#15
0
def linksToEpisodesSY(msg):
    """extract the links to episodes in a seriesyonkis email"""
    # TESTED
    if msg is None:
        raise TypeError

    # TODO testing how to encode an email right
    #logging.info(repr(str_msg))

    #syMsg = f.parsestr(str)
    #syMsg = f.parsestr(str_msg)
    #syMsg = msg
    # TODO: aclarar si esto es asi, o no. mientras tanto, esta funcion
    # falla con errores de encoding, asi que no me vale.
    # con nosetes funciona, con normal falla  -> con encode
    # syMsg = quopri.decodestring(msg.encode("UTF-8"))
    # con nosetest falla, con normal funcion -> sin encode
    syMsg = quopri.decodestring(msg)
    soup = bs4.BeautifulSoup(syMsg)

    episodes = set()

    for link in soup.find_all("a"):
        cleanLink = link.get('href', '')
        if "capitulo" in cleanLink:
            episodes.add(cleanLink.decode())

    lst = list(episodes)
    lst.sort()

    return lst
示例#16
0
 def _infer_text_fragment_inner(self, title, body, post_id):
     # dead code? If not needs to be refactored with langstrings
     body = sanitize_html(body, [])
     quote = self.body.replace("\r", "")
     try:
         # for historical reasons
         quote = quopri.decodestring(quote)
     except:
         pass
     quote = sanitize_html(quote, [])
     if quote != self.body:
         self.body = quote
     quote = quote.replace("\n", "")
     start = body.find(quote)
     lookin = 'message-body'
     if start < 0:
         xpath = "//div[@id='%s']/div[class='post_title']" % (post_id)
         start = title.find(quote)
         if start < 0:
             return None
         lookin = 'message-subject'
     xpath = "//div[@id='message-%s']//div[@class='%s']" % (
         Post.uri_generic(post_id), lookin)
     tfi = self.db.query(TextFragmentIdentifier).filter_by(
         extract=self).first()
     if not tfi:
         tfi = TextFragmentIdentifier(extract=self)
     tfi.xpath_start = tfi.xpath_end = xpath
     tfi.offset_start = start
     tfi.offset_end = start + len(quote)
     return tfi
示例#17
0
def decode_transfer_encoding(encoding, body):
    if encoding == "base64":
        return base64.b64decode(body)
    elif encoding == "quoted-printable":
        return quopri.decodestring(body)
    else:
        return body
示例#18
0
    def __init__(self, replay_response, method=None):
        self.reason = replay_response['status']['message']
        self.status = replay_response['status']['code']
        self.version = None

        if 'body_text' in replay_response:
            # JSON decoder returns unicode, not str, so this needs to be
            # encoded to properly reproduce content off the wire.
            self._content = replay_response['body_text'].encode('utf8')
        elif 'body_quoted_printable' in replay_response:
            # quopri.decodestring returns str, which is correct for content off
            # the wire.
            self._content = quopri.decodestring(replay_response['body_quoted_printable'])
        else:
            # .decode('base64') returns str, which is correct for content off
            # the wire.
            self._content = replay_response['body'].decode('base64')
        self.fp = StringIO(self._content)

        msg_fp = StringIO('\r\n'.join('{}: {}'.format(h, v)
            for h, v in replay_response['headers'].iteritems()))
        self.msg = HTTPMessage(msg_fp)
        self.msg.fp = None  # httplib does this, okay?

        length = self.msg.getheader('content-length')
        self.length = int(length) if length else None

        # Save method to handle HEAD specially as httplib does
        self._method = method
示例#19
0
    def get(self):
        user = users.get_current_user()
        restaurant_name = self.request.get('restaurant_name')
        # self.response.write(restaurant_name)
        restaurant = RestaurantModel.query(RestaurantModel.name == restaurant_name).fetch()[0]
        # str = restaurant.payment
        str = quopri.decodestring(restaurant.payment)
        cart = CartModel.query(CartModel.user==user, CartModel.restaurant_name==restaurant_name).fetch()[0]
        cart_id = cart.key.id()
        ######################################################Save the customer information (user address|phone|notes)###########################################################
        cart.customer_address = self.request.get('customer_address')
        cart.customer_phone = self.request.get('customer_phone')
        cart.customer_time = self.request.get('customer_time')
        cart.customer_notes = self.request.get('customer_notes')
        cart.put()

        shipping_fee = restaurant.shipping_fee
        template = JINJA_ENVIRONMENT.get_template('templates/confirm.html')
        template_values = {
            'restaurant_name': restaurant_name,
            'total_cost': cart.total,
            'shipping_fee': shipping_fee,
            'payment': str,
            'cart_id': cart_id,

            'customer_address': cart.customer_address,
            'customer_phone': cart.customer_phone,
            'customer_time': cart.customer_time,
            'customer_notes': cart.customer_notes,
        }
        self.response.write(template.render(template_values))
示例#20
0
文件: helpers.py 项目: miing/mci_migo
    def _get_verification_data(self, email_address):
        """A private helper for public helpers below.

        Note: We have two different public helpers here for verification
        code and link so that functional tests don't need to deal with
        idioms like:
            vcode, ignored = get_verification_for_address(email_address).
        """
        email_msg = mail.get_latest_email_sent_to(email_address)
        vcode = link = None
        if email_msg:
            # The body is encoded as quoted-printable. This affects any line
            # longer than a certain length.  Decode now to not have to worry
            # about it in the regexen.
            body = quopri.decodestring(email_msg.get_payload())
            # get code
            match = re.search(
                '(Here is your confirmation code:|Copy and paste the '
                'confirmation code below into the desktop application.)'
                '(.*?)(Enter|If you made|If you don)',
                body, re.S)
            if match:
                vcode = match.group(2).strip()
            else:
                vcode = None
            # get link
            match = re.search(
                'confirm your (?:account|email address|reset):(.*)If',
                body, re.S)
            link = None
            if match:
                link = match.group(1).strip()
        return vcode, link
	def parseUTCDateTime(cls, dt_str):
		m = re.match(r"(\w+ \w+ \d+ \d+:\d+:\d+ )(\S.*\S)( \d+)",  dt_str, re.U)
		if m is None:
			logging.warning("Datetime has unknown format: '" + dt_str + "' " + repr(dt_str))
			return (None, "format_unknown")
		try:
			tm = datetime.strptime(m.group(1) + m.group(3), r"%a %b %d %H:%M:%S %Y")
		except ValueError:
			logging.warning("Can't parse datetime from: '" + m.group(1) + m.group(3) + "'")
			return (None, "parsing_failed")
		try:
			tzname = m.group(2)
			tz = timezone(tzname)
		except UnknownTimeZoneError:
			# Alternative timezone formats
			newtzname = re.sub(r"^GMT\+03:30$", r"Asia/Tehran", tzname)
			newtzname = re.sub(r"^(\w+[+-])0?(\d*)[:.]00$", r"\1\2", newtzname)
			newtzname = re.sub(r"^(GMT[+-]\d*)$", r"Etc/\1", newtzname)
			newtzname = re.sub(r"^GMT$", r"Etc/GMT+0", newtzname)
			newtzname = re.sub(r"^(EDT)$", r"EST5\1", newtzname)
			newtzname = re.sub(r"^(CDT)$", r"CST6\1", newtzname)
			newtzname = re.sub(r"^(MDT)$", r"MST7\1", newtzname)
			newtzname = re.sub(r"^(PDT)$", r"PST8\1", newtzname)
			newtzname = re.sub(r"^PST$", r"Etc/GMT-8", newtzname)
			newtzname = re.sub(r"^CST$", r"Etc/GMT-6", newtzname)
			newtzname = re.sub(r"^JST$", r"Japan", newtzname)
			newtzname = re.sub(r"^MEZ$", r"CET", newtzname)
			newtzname = re.sub(r"^CEST$", r"CET", newtzname)
			newtzname = re.sub(r"^HAEC$", r"CET", newtzname)
			newtzname = re.sub(r"^HNEC$", r"CET", newtzname)
			newtzname = re.sub(r"^AKST$", r"US/Alaska", newtzname)
			newtzname = re.sub(r"^MESZ$", r"Europe/Berlin", newtzname)
			newtzname = re.sub(r"^AWST$", r"Australia/Perth", newtzname)
			newtzname = re.sub(r"^ACDT$", r"Australia/Adelaide", newtzname)
			newtzname = re.sub(r"^AEDT$", r"Australia/Sydney", newtzname)
			newtzname = re.sub(r"^AEST$", r"Australia/Brisbane", newtzname)
			newtzname = re.sub(r"^NZDT$", r"Pacific/Auckland", newtzname)
			newtzname = re.sub(r"^CAT$", r"Etc/GMT+2", newtzname)
			newtzname = re.sub(r"^SAST$", r"Africa/Johannesburg", newtzname)
			newtzname = re.sub(r"^BRT$", r"America/Recife", newtzname)
			# See if timezone is Quoted-Printable UTF-8
			logging.debug(str(ord(newtzname[0])) +' ' + str(ord(newtzname[1])) + ' ' + str(len(newtzname)) + ' ' + repr(newtzname))
			if re.search('^[=A-Fa-f0-9 ]a$', newtzname):
				logging.debug("Trying for Quoted-Printable UTF-8 string for timezone")
				newtzname = decodestring(newtzname).decode('utf-8')
			if newtzname == u'\u041c\u043e\u0441\u043a\u043e\u0432\u0441\u043a\u043e\u0435 \u043b\u0435\u0442\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f':
				newtzname = "Europe/Moscow"
			logging.debug("Changed timezone from '" + tzname + "' to '" + newtzname + "'")
			try:
				tz = timezone(newtzname)
			except UnknownTimeZoneError:
				logging.warning("Unknown timezone: '" + tzname + "'")
				return (None, "timezone_unknown")
		try:
			tm = tz.localize(tm)
		except (ValueError, NonExistentTimeError):
			logging.warning("Error while localizing datetime '" + tm.strftime(r"%d/%m/%Y %H:%M:%S") + "' to '" + tz.zone + "'")
			return (None, "localizing_failed")
		logging.debug("UTC time parsed: '" + tm.astimezone(pytz.utc).strftime(r"%d/%m/%Y %H:%M:%S %Z") + "'")
		return (tm.astimezone(pytz.utc), "")
示例#22
0
    def process_message(self, peer, mailfrom, rcpttos, data):
        print 'Received mail from %s to %s.' % (mailfrom, rcpttos,)
        mail = email.message_from_string(data)

        subject = email.header.decode_header(mail['Subject'])[0][0]
        message_id = email.header.decode_header(mail['Message-ID'])[0][0]
        in_reply_to = email.header.decode_header(mail['In-Reply-To'])[0][0]

        text = mail.get_payload()
        encoding = mail['Content-Transfer-Encoding']
        if encoding != None:
            if encoding.lower() in ('7bit', '8bit', 'binary'):
                pass # no conversion needed
            elif encoding.lower() == 'base64':
                text = base64.b64decode(text)
            elif encoding.lower() == 'quoted-printable':
                text = quopri.decodestring(text)
            else:
                print('WARNING: Unknown encoding, skipping decoding: '
                            '%s\n'
                            'text:\n%s\n' % (encoding, text))
        charset = mail.get_content_charset()
        text = utf8(text, charset)
        text = normalize_str(text)

        message_from_mail(mailfrom, rcpttos,
                          subject, message_id, in_reply_to,
                          text)
示例#23
0
    def __init__(self, message, message_id=None, gpg=None):
        """
        :arg str message: raw text of the email
        :arg str message_id: IMAP message ID or maildir message path
        :arg gpg: :class:`GnuPG` instance or None (which will create one)
        """

        Message.__init__(self, message)
        self._message_id = message_id
        if not gpg:
            self._gpg = GnuPG()
        else:
            self._gpg = gpg

        self._content_types = ["text/plain", "text/html",
            "application/pgp-signature", "application/pgp-keys",
            "application/octet-stream"]

        self._parts = []
        for part in self.walk():
            content_type = part.get_content_type()
            if content_type in self._content_types:
                payload = quopri.decodestring(part.get_payload().strip())
                self._parts.append( (content_type, payload) )

        self._parse_for_openpgp()
    def test_notifications_for_new_post(self):
        ws = self.portal['workspaces']['workspace-1']
        people = self.portal['people']
        self.mailhost.messages = []
        login(self.portal, 'test_user_1')

        post = helpers.create_post(ws, 'new-post', title=u"New Post",
            text=richtextify(u"<p>test</p><p>test</p>123"))

        self.assertEqual(len(self.mailhost.messages), 0)

        helpers.publish_post(post)

        self.assertEqual(len(self.mailhost.messages), 2)

        recipients = [unicode(m['To']) for m in self.mailhost.messages]
        expected_recipients = []
        for uid in ws.getMemberIds():
            name = getattr(people.get(uid, None), 'title', uid)
            email = getattr(people.get(uid, None), 'emailAddress', None)
            if not email:
                continue
            expected_recipients.append('{0} <{1}>'.format(name, email))
        self.assertEqual(recipients, expected_recipients)

        for message in self.mailhost.messages:
            self.assertEqual(unicode(message['Subject']), u"[Plone site] " +
                u"New post: “New Post” by Test User in Workspace 1")

            msg_text = quopri.decodestring(message.get_payload())
            expected_msg_text = u"test\n\ntest\n123"
            self.assertEqual(msg_text, expected_msg_text)
示例#25
0
    def _decode_single_body(self):
        self.body = self.body.strip()
        cte = self.headers.get('Content-Transfer-Encoding', '').lower()
        if 'quoted-printable' in cte:
            LOG.debug("Detected quoted-printable encoding, decoding")
            self.body = quopri.decodestring(self.body)
        if 'base64' in cte:
            LOG.debug("Detected base64 encoding, decoding")
            try:
                self.body = base64.decodestring(self.body)
            except base64.binascii.Error:
                LOG.info("base64 decoder failed, trying partial decoding")
                self.body = base64_partial_decode(self.body)

        LOG.debug("Detected charset: %s", self.charset)
        try:
            self.body = self.body.decode(
                validate_charset(self.charset) and self.charset or 'ascii',
                'strict'
            )
        except UnicodeDecodeError:
            LOG.info('Error during strict decoding')
            self.email_stats['charset_errors'] = 1
            self.body = self.body.decode(
                validate_charset(self.charset) and self.charset or 'ascii',
                'ignore'
            )

        if self._guess_html():
            LOG.debug("Message recognized as HTML")
            self._parse_html()
        else:
            LOG.debug("Message recognized as plaintext")
def parse_message(msg):
    """returns a tuple
    (<from email address>, <subject>, <body>)
    the function will attempt to decode the email
    supported encodings are "quoted-printable" and "base64"
    not supported - emails using language - specific encodings
    """
    sender = msg.get('From')
    subject = msg.get('Subject').replace('\r','').replace('\n','')
    if msg.is_multipart():
        # BL: Wind always sends 2 payloads: 1 plain-text, the other html
        msg = msg.get_payload()[0]
        if isinstance(msg, list):
            raise CannotParseEmail(sender, subject)

    ctype = msg.get_content_type()#text/plain only
    raw_body = msg.get_payload()#text/plain only
    encoding = msg.get('Content-Transfer-Encoding')
    if encoding == 'base64':
        body = base64.b64decode(raw_body)
    elif encoding == 'quoted-printable':
        body = quopri.decodestring(raw_body)
    else:
        body = raw_body
    return (sender, subject, body)
示例#27
0
文件: steps.py 项目: petrem/behaving
def parse_email_set_var(context, address, expression):
    assert context.persona is not None, u'no persona is setup'
    msgs = context.mail.user_messages(address)
    assert msgs, u'no email received'
    mail = email.message_from_string(msgs[-1])
    text = quopri.decodestring(mail.get_payload()).decode("utf-8")
    parse_text(context, text, expression)
示例#28
0
文件: part.py 项目: nylas/flanker
def decode_transfer_encoding(encoding, body):
    if encoding == 'base64':
        return _base64_decode(body)
    elif encoding == 'quoted-printable':
        return quopri.decodestring(body)
    else:
        return body
示例#29
0
def parse_part(part):
	part = part.strip();
	# parse the part description (first three lines)
	# get Content-Type
	pat1 = 'Content-Type: (.*)';
	pat1_res = re.search(pat1, part, re.I);
	ctype = pat1_res.groups()[0].strip() if pat1_res else '';
	# get Content-Transfer-Encoding
	pat2 = 'Content-Transfer-Encoding: (.*)';
	pat2_res = re.search(pat2, part, re.I);
	cenc = pat2_res.groups()[0].strip() if pat2_res else '';
	# get Content-Location
	pat3 = 'Content-Location: (.*)';
	pat3_res = re.search(pat3, part, re.I);
	cloc = pat3_res.groups()[0].strip() if pat3_res else '';
	# check part description
	if cenc == '':
		return (-1, ctype, cenc, cloc, '');
	# parse the contents
	try:
		contents = part.split('\n\n', 1)[1];
	except:
		contents = part.split('\n\r\n', 1)[1];
	if cenc == 'base64':
		s = base64.b64decode(contents);
	elif cenc == 'quoted-printable':
		s = quopri.decodestring(contents);
	return (0, ctype, cenc, cloc, s);
示例#30
0
def decode_mime(msg_str):
    pattern = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
    match = re.search(pattern, msg_str)
    if match:
        charset, encoding, text = match.groups()
        if encoding is 'B':
            byte_string = base64.b64decode(text)
        elif encoding is 'Q':
            byte_string = quopri.decodestring(text)
        return byte_string.decode(charset)
    else:
        return msg_str
示例#31
0
 def decode(self, line):
     line = self._consumed_lines + line # add potentially stored previous lines
     self._consumed_lines = ''
     m = QuotedPrintableDecoder.quoted.match(line)
     if m:
         line = line[:m.start(1)] + line[m.end(1):] # remove the matched group 1 from line
         decoded_line = quopri.decodestring(line).decode('UTF-8')
         # Escape newlines, but preserve the last one (which must be '\n', since we read the file in universal newliens mode)
         decoded_line = decoded_line[:-1].replace('\r\n', '\\n')
         decoded_line = decoded_line.replace('\n', '\\n')
         return decoded_line + '\n'
     return line
    def save_mail(self, email):
        [(subj, code)] = decode_header(email[1]['Subject'])

        new_email = Email(title=subj.decode(code),
                          sender=email[1]['From'],
                          date=email[1]['Date'],
                          text=quopri.decodestring(
                              email[0].encode('utf-8')).decode(
                                  'utf-8', 'backslashreplace'))
        new_email.save()

        return new_email
示例#33
0
def from_html(html, transfer_encoding):
    inputs = html
    if transfer_encoding == 'base64':
        inputs = base64.urlsafe_b64decode(inputs)
    elif transfer_encoding == 'quoted-printable' or transfer_encoding == '8bit' or transfer_encoding == '7bit':
        inputs = quopri.decodestring(base64.urlsafe_b64decode(inputs))

    soup = BeautifulSoup(inputs)
    # kill all script and style elements
    for script in soup(["script", "style"]):
        script.extract()
    return clean_str(soup.get_text())
示例#34
0
def replace(msg: Message, old, new) -> Message:
    content_type = msg.get_content_type()

    if (content_type.startswith("image/") or content_type.startswith("video/")
            or content_type.startswith("audio/")
            or content_type == "multipart/signed"
            or content_type.startswith("application/")
            or content_type == "text/calendar"
            or content_type == "text/directory" or content_type == "text/csv"
            or content_type == "text/x-python-script"):
        LOG.d("not applicable for %s", content_type)
        return msg

    if content_type in ("text/plain", "text/html"):
        encoding = get_encoding(msg)
        payload = msg.get_payload()
        if type(payload) is str:
            if encoding == EmailEncoding.QUOTED:
                LOG.d("handle quoted-printable replace %s -> %s", old, new)
                # first decode the payload
                try:
                    new_payload = quopri.decodestring(payload).decode("utf-8")
                except UnicodeDecodeError:
                    LOG.w("cannot decode payload:%s", payload)
                    return msg
                # then replace the old text
                new_payload = new_payload.replace(old, new)
                clone_msg = copy(msg)
                clone_msg.set_payload(quopri.encodestring(
                    new_payload.encode()))
                return clone_msg
            else:
                clone_msg = copy(msg)
                new_payload = payload.replace(encode_text(old, encoding),
                                              encode_text(new, encoding))
                clone_msg.set_payload(new_payload)
                return clone_msg

    elif content_type in (
            "multipart/alternative",
            "multipart/related",
            "multipart/mixed",
            "message/rfc822",
    ):
        new_parts = []
        for part in msg.get_payload():
            new_parts.append(replace(part, old, new))
        clone_msg = copy(msg)
        clone_msg.set_payload(new_parts)
        return clone_msg

    LOG.w("Cannot replace text for %s", msg.get_content_type())
    return msg
示例#35
0
def parse_and_split_field(field):
    '''Parses a VCARD field. field is a tuple consisting of the field name and the field content.
       The content is decoded (if quoted printable) and de-splited by ";". The return value is a
       list consisting of the splitted values.'''
    result = []
    if len(field) != 2:
        return result
    if field[0].find("ENCODING=QUOTED-PRINTABLE") > 0:
        result = quopri.decodestring(field[1]).split(";")
    else:
        result = field[1].split(";")
    return result
示例#36
0
def encoded_words_to_text(encoded_words):
    encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
    groups = re.match(encoded_word_regex, encoded_words)
    if not groups:
        return encoded_words
    charset, encoding, encoded_text = re.match(encoded_word_regex,
                                               encoded_words).groups()
    if encoding == 'B':
        byte_string = base64.b64decode(encoded_text)
    elif encoding == 'Q':
        byte_string = quopri.decodestring(encoded_text)
    return byte_string.decode(charset)
示例#37
0
 def process_request(self, request):
     if request.method == 'POST' and 'HTTP_X_APPENGINE_BLOBUPLOAD' in request.META and request.META['HTTP_X_APPENGINE_BLOBUPLOAD'] == 'true':
         request.POST = request.POST.copy()
         log.info('POST before decoding: %s' % request.POST)
         for key in request.POST:
             if key.startswith('_') or key == u'csrfmiddlewaretoken':
                 continue
             value = request.POST[key]
             if isinstance(value,(str, unicode)):
                 request.POST[key] = unicode(quopri.decodestring(value), 'iso_8859-2')
         log.info('POST after decoding: %s' % request.POST) 
     return None
示例#38
0
def get_email_body(msg, message_type):
    output = ""
    if "multipart" in message_type:
        for part in msg.get_payload():
            m_type = part["Content-Type"].split()[0].replace(";", "")
            if "multipart" in m_type:
                output = get_email_body(part, m_type)
            elif "text" in m_type and "html" not in m_type:
                try:
                    encoded_word_regex = r"=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}="
                    charset, encoding, encoded_text = re.match(
                        encoded_word_regex, part.get_payload()).groups()
                    if encoding is "B":
                        body = base64.b64decode(encoded_text)
                    elif encoding is "Q":
                        body = quopri.decodestring(encoded_text)
                    output = body.decode()
                    # output = base64.urlsafe_b64decode(part.get_payload()).decode(encoding)
                except:
                    try:
                        output = base64.b64decode(part.get_payload()).decode()
                    except:
                        output = part.get_payload()
                break
    elif "text" in m_type and "html" not in m_type:
        try:
            encoded_word_regex = r"=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}="
            charset, encoding, encoded_text = re.match(
                encoded_word_regex, part.get_payload()).groups()
            if encoding is "B":
                body = base64.b64decode(encoded_text)
            elif encoding is "Q":
                body = quopri.decodestring(encoded_text)
            output = body.decode()
        except:
            try:
                output = base64.b64decode(part.get_payload()).decode()
            except:
                output = part.get_payload()
    return output
示例#39
0
def get_tracking(sdata, account, shipper):
    """Parse tracking numbers from email subject lines"""
    _LOGGER.debug("Searching for tracking numbers for (%s)", shipper)
    tracking = []
    pattern = None
    mail_list = sdata.split()
    body = None

    if shipper == "usps":
        pattern = re.compile(r"{}".format(const.USPS_TRACKING_PATTERN))
    elif shipper == "ups":
        pattern = re.compile(r"{}".format(const.UPS_TRACKING_PATTERN))
    elif shipper == "fedex":
        pattern = re.compile(r"{}".format(const.FEDEX_TRACKING_PATTERN))
    elif shipper == "dhl":
        body = True
        pattern = re.compile(r"{}".format(const.DHL_TRACKING_PATTERN))

    for i in mail_list:
        typ, data = account.fetch(i, "(RFC822)")
        for response_part in data:
            if not isinstance(response_part, tuple):
                continue
            msg = email.message_from_bytes(response_part[1])
            if body is None:
                email_subject = msg["subject"]
                found = pattern.findall(email_subject)
                if len(found) > 0:
                    _LOGGER.debug(
                        "Found (%s) tracking number in email: (%s)", shipper, found[0]
                    )
                    if found[0] in tracking:
                        continue
                    tracking.append(found[0])
                    continue
                _LOGGER.debug("No tracking number found for %s", shipper)
            else:
                # Search in email body for tracking number
                email_msg = quopri.decodestring(str(msg.get_payload(0)))
                email_msg = email_msg.decode("utf-8")
                found = pattern.findall(email_msg)
                if len(found) > 0:
                    _LOGGER.debug(
                        "Found (%s) tracking number in email: %s", shipper, found[0]
                    )
                    if found[0] in tracking:
                        continue
                    tracking.append(found[0])
                    continue
                _LOGGER.debug("No tracking number found for %s", shipper)

    return tracking
示例#40
0
    def save_mail(self, i_d, filename='email_data.csv', verbose=False):
        """
        Writes email data to csv
        
        ARGS: 
        mail - logged in mail object
        
        i_d - list of i_ds
        ids of messages to get
        
        filename - string ending in .csv (default: 'email_data.csv')
        name of file to write to 
        
        Returns: None, saves data to csv
        """
        csv_file = open(filename, 'w', encoding='utf-8')
        csv_writer = csv.writer(csv_file)
        csv_writer.writerow(
            ['id', 'uid', 'from_', 'subject', 'msg', 'content_type'])

        for i in i_d:
            try:
                typ, data = self.mail.fetch(str(i).encode(), '(UID RFC822)')

                uid = email.message_from_bytes(data[0][0])
                uid = uid.get_payload()
                uid = uid.split()[-3]

                meta = email.message_from_bytes(data[0][1])
                from_ = meta['From']
                subject = meta['Subject']
                content_type = meta['Content-Type'].split(';')[0]

                msg = meta.get_payload()
                while type(msg) != str:
                    msg = msg[0].get_payload()

                print(i)
                if verbose:
                    print('UID: ', uid)
                    print('From: ', from_)
                    print('Subject: ', subject)
                    print('Content-Type: ', content_type)
                    print('Message: ', quopri.decodestring(msg))

                from_, msg = self.clean_text(from_, msg)

                csv_writer.writerow(
                    [i, uid, from_, subject, msg, content_type])
                print('Message saved')
            except Exception as e:
                print(e)
示例#41
0
 def get_text(self):
     result = ""
     if self.content_type.startswith("text"):
         if self.encoding == "base64":
             self.data = base64.b64decode(self.data).decode()
         if self.encoding == "quoted-printable":
             self.data = quopri.decodestring(self.data).decode()
         return self.data
     for record in self.records:
         result = record.get_text()
         if result:
             return result
     return result
示例#42
0
    def parse_status_email_thread(self, data):
        statuses = []
        for email_id in data[0].split():
            response, message_data = self.connection.fetch(
                email_id, '(BODY.PEEK[TEXT])')
            message = ""
            for response_part in message_data:
                if isinstance(response_part, tuple):
                    body = email.message_from_string(response_part[1])  # body

                    if body.is_multipart():
                        for payload in body.get_payload():
                            message += quopri.decodestring(payload)
                    else:
                        message = quopri.decodestring(body.get_payload())

            response, headers_data = self.connection.fetch(
                email_id, '(BODY[HEADER.FIELDS (SUBJECT FROM)])')
            headers = email.message_from_string(headers_data[0][1])
            statuses.append({"from": headers['FROM'], "body": message})

        return statuses
示例#43
0
def info_from_html_for_naverpay(msg_content):
    global price, purchasing_item, purchasing_office
    soup = BeautifulSoup(msg_content, 'html.parser')
    soup.prettify()
    # 결제금액
    for tag in soup.find_all('td'):
        temp = quopri.decodestring(tag.text)
        temp = temp.decode('utf-8')
        if "최종결제금액" in temp:
            price_index = temp.find("최종결제금액")
            price_content = temp[price_index + 6:]
            price = price_content.strip()
            break
    # case1:주문상품명만
    if soup.find('html') is None:
        for tag in soup.find_all('td'):
            temp = quopri.decodestring(tag.text)
            temp = temp.decode('utf-8')
            if "주문상품" in temp:
                purchasing_index = temp.find("주문상품")
                purchasing_item = temp[purchasing_index + 4:]
                purchasing_item = purchasing_item.strip()
                purchasing_item = purchasing_item[:50].strip()
                purchasing_office = "none"
                break
    # case2:주문상품명,구매상점명
    else:
        for tag in soup.find_all('td'):
            temp = quopri.decodestring(tag.text)
            temp = temp.decode('utf-8')
            if "판매자" in temp:
                purchasing_office_index = temp.find("판매자")
                purchasing_office = temp[purchasing_office_index +
                                         10:purchasing_office_index + 150]
                purchasing_office = purchasing_office.strip()
                purchasing_item_index = temp.find("상품정보")
                purchasing_item = temp[purchasing_item_index + 10:]
                purchasing_item = purchasing_item.strip()
                break
示例#44
0
def encoded_words_to_text(encoded_words):
    encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='  #กำหนดรูปแบบที่ต้องการค้นหา
    try:
        charset, encoding, encoded_text = re.match(
            encoded_word_regex, encoded_words).groups(
            )  #ค้นหาตามรูปแบบที่กำหนดโดยใช้ฟังก์ชั่น match
        if encoding is 'B':
            byte_string = base64.b64decode(encoded_text)
        elif encoding is 'Q':
            byte_string = quopri.decodestring(encoded_text)
        return byte_string.decode(charset)  #ถอดรหัสเป็น utf-8
    except:
        return encoded_words  #ถ้าเกิดปัญหาอันเนื่องมาจากรูปแบบไม่ match กันจะคือค่าเดิมออกไป
示例#45
0
def get_msg_payload(msg):
    encoding = msg.get('Content-Transfer-Encoding')
    payload = msg.get_payload()
    if type(payload) == list:
        a_msg = payload[0] # first is plaintext, second - html
        encoding = a_msg.get('Content-Transfer-Encoding')
        payload = a_msg.get_payload()
    DEBUG(u'Extracted email msg %r with encoding %r' % (payload, encoding))
    if encoding == 'quoted-printable':
        payload = quopri.decodestring(payload)
    elif encoding == 'base64':
        payload = b64decode(payload)
    return payload
示例#46
0
 def arion_parse(self, payload):
     """Non-multipart but with the plaintext in HTML comment"""
     s = payload[:payload.index("-->")]
     lines = s.splitlines()
     # Fault tolerance, it changes around a bit
     try:
         amount = int(re.sub(r"[^0-9]", "", lines[9].split(": ")[1]))
         raw = quopri.decodestring(lines[11]).split(": ")[1]
     except IndexError:
         raise ValueError("2 Arion Bankmail without plaintext encoutered")
     # Not sure if nessesary or formed user input from user "Numi"
     skyring = raw.strip().decode("tis-620")
     return skyring, amount, "arion"
示例#47
0
    def parse(self, fname):
        'parse bill content from eml(fname)'

        f = open(fname, 'rb')
        eml_bytes = f.read()
        f.close()

        # quoted-printable decode
        quo_dec = quopri.decodestring(eml_bytes)
        quo_dec = quo_dec.decode('utf-8')

        self.parse_year(quo_dec)
        self.parse_contents(quo_dec)
示例#48
0
def encoded_words_to_text(encoded_words):
    """
    Not used, left for reference only
    https://dmorgan.info/posts/encoded-word-syntax/
    """
    encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
    # encoded_word_regex = r'=\?{1}.+\?{1}[B|Q|b|q]\?{1}.+\?{1}='
    charset, encoding, encoded_text = re.match(encoded_word_regex, encoded_words, re.IGNORECASE).groups()
    if encoding.upper() == 'B':
        byte_string = base64.b64decode(encoded_text)
    elif encoding.upper() == 'Q':
        byte_string = quopri.decodestring(encoded_text)
    return byte_string.decode(charset)
示例#49
0
 def uq(m):
     cs, how, data = m.group(1), m.group(2), m.group(3)
     if how in ('b', 'B'):
         try:
             data = base64.b64decode(''.join(data.split())+'===')
         except TypeError:
             print('FAILED TO B64DECODE: %s' % data)
     else:
         data = quopri.decodestring(data, header=True)
     try:
         return data.decode(cs)
     except LookupError:
         return data.decode('iso-8859-1')  # Always works
示例#50
0
def sendmail(to, message):
    mail_charset = 'utf-8'
    msg = MIMEText(quopri.decodestring(message), _charset=mail_charset)
    msg['Subject'] = Header(MAIL_SUBJECT, mail_charset)
    msg['From'] = MAIL_FROM
    msg['To'] = to
    try:
        smtpObj = SMTP(SMTP_HOST, SMTP_PORT)
        smtpObj.sendmail(MAIL_FROM, [to], msg.as_string())
        smtpObj.quit()
        logger.info('Successfully sent email to %s' % to)
    except SMTPException:
        logger.error('Error: unable to send email to %s' % to)
示例#51
0
def clean_content(content):
    # decode message from "quoted printable" format
    content = quopri.decodestring(content)

    # try to strip HTML tags
    # if errors happen in BeautifulSoup (for unknown encodings), then bail
    try:
        soup = BeautifulSoup(content,
                             "html.parser",
                             from_encoding="iso-8859-1")
    except Exception as e:
        return ''
    return ''.join(soup.findAll(text=True))
示例#52
0
文件: mail.py 项目: TangoMan75/pymail
 def message(self) -> Optional[str]:
     """Get message body"""
     message = ''
     if self._raw.is_multipart():
         for payload in self._raw.get_payload():
             message += payload.get_payload()
     else:
         message = self._raw.get_payload()
     # decode base64 encoded message
     if self._raw['Content-Transfer-Encoding'] == 'base64':
         message = b64decode(message)
     # decode MIME quoted-printable data
     return decodestring(message)
示例#53
0
def readXML(filename):
    import quopri
    from lxml import etree
    with open(filename,encoding='utf-8') as f:
        root = etree.parse(f)
    emails = root.getroot().getchildren()
    text = []
    for e in emails:
        aux = replaceNonAscii(e.text)
        aux = quopri.decodestring(aux)
        aux = aux.decode('latin-1')
        text.append(aux)
    return text
示例#54
0
def encoded_words_to_text(encoded_words):
    """ from https://dmorgan.info/posts/encoded-word-syntax/  """
    if not encoded_words.startswith("=?"):
        return encoded_words
    encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
    charset, encoding, encoded_text = re.match(encoded_word_regex,
                                               encoded_words,
                                               flags=re.IGNORECASE).groups()
    if encoding.upper() == 'B':
        byte_string = base64.b64decode(encoded_text)
    elif encoding.upper() == 'Q':
        byte_string = quopri.decodestring(encoded_text)
    return byte_string.decode(charset)
示例#55
0
def get_tracking(
    sdata: Any, account: Type[imaplib.IMAP4_SSL], the_format: Optional[str] = None
) -> list:
    """Parse tracking numbers from email.

    Returns list of tracking numbers
    """
    tracking = []
    pattern = None
    mail_list = sdata.split()
    _LOGGER.debug("Searching for tracking numbers in %s messages...", len(mail_list))

    pattern = re.compile(r"{}".format(the_format))
    for i in mail_list:
        data = email_fetch(account, i, "(RFC822)")[1]
        for response_part in data:
            if isinstance(response_part, tuple):
                msg = email.message_from_bytes(response_part[1])
                _LOGGER.debug("Checking message subject...")

                # Search subject for a tracking number
                email_subject = msg["subject"]
                found = pattern.findall(email_subject)
                if len(found) > 0:
                    _LOGGER.debug(
                        "Found tracking number in email subject: (%s)",
                        found[0],
                    )
                    if found[0] not in tracking:
                        tracking.append(found[0])
                    continue

                # Search in email body for tracking number
                _LOGGER.debug("Checking message body...")
                email_msg = quopri.decodestring(str(msg.get_payload(0)))
                email_msg = email_msg.decode("utf-8", "ignore")
                found = pattern.findall(email_msg)
                if len(found) > 0:
                    # DHL is special
                    if " " in the_format:
                        found[0] = found[0].split(" ")[1]

                    _LOGGER.debug("Found tracking number in email body: %s", found[0])
                    if found[0] not in tracking:
                        tracking.append(found[0])
                    continue

    if len(tracking) == 0:
        _LOGGER.debug("No tracking numbers found")

    return tracking
示例#56
0
def verify(signed_text, capath, check_crl):
    '''
    Verify the signed message has been signed by the certificate (attached to the
    supplied SMIME message) it claims to have, by one of the accepted CAs in
    capath.

    Returns a tuple including the signer's certificate and the plain-text of the
    message if it has been verified.  If the content transfer encoding is specified
    as 'quoted-printable' or 'base64', decode the message body accordingly.
    '''
    if signed_text is None or capath is None:
        raise CryptoException('Invalid None argument to verify().')
    # This ensures that openssl knows that the string is finished.
    # It makes no difference if the signed message is correct, but
    # prevents it from hanging in the case of an empty string.
    signed_text += '\n\n'

    signer = get_signer_cert(signed_text)

    if not verify_cert(signer, capath, check_crl):
        raise CryptoException('Unverified signer')

    # The -noverify flag removes the certificate verification.  The certificate
    # is verified above; this check would also check that the certificate
    # is allowed to sign with SMIME, which host certificates sometimes aren't.
    p1 = Popen(['openssl', 'smime', '-verify', '-CApath', capath, '-noverify'],
               stdin=PIPE,
               stdout=PIPE,
               stderr=PIPE)

    message, error = p1.communicate(signed_text)

    # SMIME header and message body are separated by a blank line
    lines = message.strip().splitlines()
    blankline = lines.index('')
    headers = '\n'.join(lines[:blankline])
    body = '\n'.join(lines[blankline + 1:])
    # two possible encodings
    if 'quoted-printable' in headers:
        body = quopri.decodestring(body)
    elif 'base64' in headers:
        body = base64.decodestring(body)
    # otherwise, plain text

    # Interesting problem here - we get a message 'Verification successful'
    # to standard error.  We don't want to log this as an error each time,
    # but we do want to see if there's a genuine error...
    log.info(str(error).strip())

    subj = get_certificate_subject(signer)
    return body, subj
示例#57
0
    def _get_attrs(self):
        """ Get the attributes to update the context with from the 
        """

        attrs = {}
        error = u''

        params = self.request.params
        uploads = self._get_uploads()

        attrs['title'] = params.get('title')
        description = params.get('description')
        attrs['description'] = quopri.decodestring(description)

        url = params.get('url', None)
        if url:
            try:
                model.Design.url.validate(url)
            except datastore_errors.BadValueError:
                msg = self._(u'Web link is not a valid URL.')
                hint = self._(
                    u'(If you don\'t have a web link, leave the field blank)')
                error = '%s %s' % (msg, hint)
            else:
                attrs['url'] = url

        series = params.getall('series')
        keys = [db.Key.from_path('Series', item) for item in series]
        instances = model.Series.get(keys)
        if None in instances:
            i = instances.index(None)
            msg = self._(u'Series does not exist:')
            error = '%s `%s`' % (msg, series[i])
        attrs['series'] = keys

        if not error:
            google_user = users.get_current_user()
            google_user_id = google_user.user_id()
            user = model.User.get_by_user_id(google_user_id)
            # If this user has not been stored yet, create and store it.
            if user is None:
                try:
                    user = model.User(google_user=google_user,
                                      google_user_id=google_user_id)
                    # If they're an admin (and thus won't be moderated) make sure
                    # they have an avatar here.
                    if users.is_current_user_admin() and not user.avatar:
                        user.set_avatar()
                    user.put()
                except db.Error, err:
                    error = unicode(err)
示例#58
0
 def getPostLinks(self, post):
     html = self.getPostContentHtml(post)
     # print(f"Html: {html}")
     import quopri
     html = quopri.decodestring(html)
     soup = BeautifulSoup(html, 'lxml')
     res = soup.find_all('a', href=True)
     # print(f"Res: {res}")
     links = []
     for element in res:
         link = element['href']
         if not link in links:
             links.append(link)
     return links
示例#59
0
def decode_message(message):
    ret = ''
    for s in message.split('\n'):
        if len(s.split('?')) > 4:
            charset = s.split('?')[1]
            mode = s.split('?')[2]
            code = s.split('?')[3]
            if mode.upper() == 'B':
                ret += str(base64.decodebytes(code.encode(encoding=charset)),
                           encoding=charset)
            else:
                ret += str(quopri.decodestring(code.encode(encoding=charset)),
                           encoding=charset)
    return ret
示例#60
-1
 def get_first_text_part(self, msg):
     maintype = msg.get_content_maintype()
     if maintype == 'multipart':
         for part in msg.get_payload():
             print part.get_content_charset(part.get_payload())
             if part.get_content_maintype() == 'text':
                 resp= ' '
                 if part['Content-Transfer-Encoding'] == 'quoted-printable':
                     resp= quopri.decodestring(part.get_payload())
                 if part.get_content_charset(False):
                     resp = part.get_payload().decode(part.get_content_charset())
                     print resp
                 return resp
         for part in msg.get_payload():             
             return self.get_first_text_part(part)
     elif maintype == 'text':
         resp= ''
         print msg.get_content_charset(msg.get_payload())
         if msg['Content-Transfer-Encoding'] == 'quoted-printable':
             resp= quopri.decodestring(msg.get_payload())
         if msg.get_content_charset(False):
             resp = msg.get_payload().decode(msg.get_content_charset())
         print resp
         return resp
     else:
         return ' '