NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

utils.py (6223B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\email\utils.py
      2 __all__ = ['collapse_rfc2231_value',
      3  'decode_params',
      4  'decode_rfc2231',
      5  'encode_rfc2231',
      6  'formataddr',
      7  'formatdate',
      8  'getaddresses',
      9  'make_msgid',
     10  'mktime_tz',
     11  'parseaddr',
     12  'parsedate',
     13  'parsedate_tz',
     14  'unquote']
     15 import os
     16 import re
     17 import time
     18 import base64
     19 import random
     20 import socket
     21 import urllib
     22 import warnings
     23 from email._parseaddr import quote
     24 from email._parseaddr import AddressList as _AddressList
     25 from email._parseaddr import mktime_tz
     26 from email._parseaddr import parsedate as _parsedate
     27 from email._parseaddr import parsedate_tz as _parsedate_tz
     28 from quopri import decodestring as _qdecode
     29 from email.encoders import _bencode, _qencode
     30 COMMASPACE = ', '
     31 EMPTYSTRING = ''
     32 UEMPTYSTRING = u''
     33 CRLF = '\r\n'
     34 TICK = "'"
     35 specialsre = re.compile('[][\\\\()<>@,:;".]')
     36 escapesre = re.compile('[][\\\\()"]')
     37 
     38 def _identity(s):
     39     return s
     40 
     41 
     42 def _bdecode(s):
     43     if not s:
     44         return s
     45     return base64.decodestring(s)
     46 
     47 
     48 def fix_eols(s):
     49     s = re.sub('(?<!\\r)\\n', CRLF, s)
     50     s = re.sub('\\r(?!\\n)', CRLF, s)
     51     return s
     52 
     53 
     54 def formataddr(pair):
     55     name, address = pair
     56     if name:
     57         quotes = ''
     58         if specialsre.search(name):
     59             quotes = '"'
     60         name = escapesre.sub('\\\\\\g<0>', name)
     61         return '%s%s%s <%s>' % (quotes,
     62          name,
     63          quotes,
     64          address)
     65     return address
     66 
     67 
     68 def getaddresses(fieldvalues):
     69     all = COMMASPACE.join(fieldvalues)
     70     a = _AddressList(all)
     71     return a.addresslist
     72 
     73 
     74 ecre = re.compile('\n  =\\?                   # literal =?\n  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset\n  \\?                    # literal ?\n  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive\n  \\?                    # literal ?\n  (?P<atom>.*?)         # non-greedy up to the next ?= is the atom\n  \\?=                   # literal ?=\n  ', re.VERBOSE | re.IGNORECASE)
     75 
     76 def formatdate(timeval = None, localtime = False, usegmt = False):
     77     if timeval is None:
     78         timeval = time.time()
     79     if localtime:
     80         now = time.localtime(timeval)
     81         if time.daylight and now[-1]:
     82             offset = time.altzone
     83         else:
     84             offset = time.timezone
     85         hours, minutes = divmod(abs(offset), 3600)
     86         if offset > 0:
     87             sign = '-'
     88         else:
     89             sign = '+'
     90         zone = '%s%02d%02d' % (sign, hours, minutes // 60)
     91     else:
     92         now = time.gmtime(timeval)
     93         if usegmt:
     94             zone = 'GMT'
     95         else:
     96             zone = '-0000'
     97     return '%s, %02d %s %04d %02d:%02d:%02d %s' % (['Mon',
     98       'Tue',
     99       'Wed',
    100       'Thu',
    101       'Fri',
    102       'Sat',
    103       'Sun'][now[6]],
    104      now[2],
    105      ['Jan',
    106       'Feb',
    107       'Mar',
    108       'Apr',
    109       'May',
    110       'Jun',
    111       'Jul',
    112       'Aug',
    113       'Sep',
    114       'Oct',
    115       'Nov',
    116       'Dec'][now[1] - 1],
    117      now[0],
    118      now[3],
    119      now[4],
    120      now[5],
    121      zone)
    122 
    123 
    124 def make_msgid(idstring = None):
    125     timeval = time.time()
    126     utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))
    127     pid = os.getpid()
    128     randint = random.randrange(100000)
    129     if idstring is None:
    130         idstring = ''
    131     else:
    132         idstring = '.' + idstring
    133     idhost = socket.getfqdn()
    134     msgid = '<%s.%s.%s%s@%s>' % (utcdate,
    135      pid,
    136      randint,
    137      idstring,
    138      idhost)
    139     return msgid
    140 
    141 
    142 def parsedate(data):
    143     if not data:
    144         return None
    145     return _parsedate(data)
    146 
    147 
    148 def parsedate_tz(data):
    149     if not data:
    150         return None
    151     return _parsedate_tz(data)
    152 
    153 
    154 def parseaddr(addr):
    155     addrs = _AddressList(addr).addresslist
    156     if not addrs:
    157         return ('', '')
    158     return addrs[0]
    159 
    160 
    161 def unquote(str):
    162     if len(str) > 1:
    163         if str.startswith('"') and str.endswith('"'):
    164             return str[1:-1].replace('\\\\', '\\').replace('\\"', '"')
    165         if str.startswith('<') and str.endswith('>'):
    166             return str[1:-1]
    167     return str
    168 
    169 
    170 def decode_rfc2231(s):
    171     parts = s.split(TICK, 2)
    172     if len(parts) <= 2:
    173         return (None, None, s)
    174     return parts
    175 
    176 
    177 def encode_rfc2231(s, charset = None, language = None):
    178     import urllib
    179     s = urllib.quote(s, safe='')
    180     if charset is None and language is None:
    181         return s
    182     if language is None:
    183         language = ''
    184     return "%s'%s'%s" % (charset, language, s)
    185 
    186 
    187 rfc2231_continuation = re.compile('^(?P<name>\\w+)\\*((?P<num>[0-9]+)\\*?)?$')
    188 
    189 def decode_params(params):
    190     params = params[:]
    191     new_params = []
    192     rfc2231_params = {}
    193     name, value = params.pop(0)
    194     new_params.append((name, value))
    195     while params:
    196         name, value = params.pop(0)
    197         if name.endswith('*'):
    198             encoded = True
    199         else:
    200             encoded = False
    201         value = unquote(value)
    202         mo = rfc2231_continuation.match(name)
    203         if mo:
    204             name, num = mo.group('name', 'num')
    205             if num is not None:
    206                 num = int(num)
    207             rfc2231_params.setdefault(name, []).append((num, value, encoded))
    208         else:
    209             new_params.append((name, '"%s"' % quote(value)))
    210 
    211     if rfc2231_params:
    212         for name, continuations in rfc2231_params.items():
    213             value = []
    214             extended = False
    215             continuations.sort()
    216             for num, s, encoded in continuations:
    217                 if encoded:
    218                     s = urllib.unquote(s)
    219                     extended = True
    220                 value.append(s)
    221 
    222             value = quote(EMPTYSTRING.join(value))
    223             if extended:
    224                 charset, language, value = decode_rfc2231(value)
    225                 new_params.append((name, (charset, language, '"%s"' % value)))
    226             else:
    227                 new_params.append((name, '"%s"' % value))
    228 
    229     return new_params
    230 
    231 
    232 def collapse_rfc2231_value(value, errors = 'replace', fallback_charset = 'us-ascii'):
    233     if isinstance(value, tuple):
    234         rawval = unquote(value[2])
    235         charset = value[0] or 'us-ascii'
    236         try:
    237             return unicode(rawval, charset, errors)
    238         except LookupError:
    239             return unicode(rawval, fallback_charset, errors)
    240 
    241     else:
    242         return unquote(value)