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

quoprimime.py (4684B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\email\quoprimime.py
      2 __all__ = ['body_decode',
      3  'body_encode',
      4  'body_quopri_check',
      5  'body_quopri_len',
      6  'decode',
      7  'decodestring',
      8  'encode',
      9  'encodestring',
     10  'header_decode',
     11  'header_encode',
     12  'header_quopri_check',
     13  'header_quopri_len',
     14  'quote',
     15  'unquote']
     16 import re
     17 from string import hexdigits
     18 from email.utils import fix_eols
     19 CRLF = '\r\n'
     20 NL = '\n'
     21 MISC_LEN = 7
     22 hqre = re.compile('[^-a-zA-Z0-9!*+/ ]')
     23 bqre = re.compile('[^ !-<>-~\\t]')
     24 
     25 def header_quopri_check(c):
     26     return bool(hqre.match(c))
     27 
     28 
     29 def body_quopri_check(c):
     30     return bool(bqre.match(c))
     31 
     32 
     33 def header_quopri_len(s):
     34     count = 0
     35     for c in s:
     36         if hqre.match(c):
     37             count += 3
     38         else:
     39             count += 1
     40 
     41     return count
     42 
     43 
     44 def body_quopri_len(str):
     45     count = 0
     46     for c in str:
     47         if bqre.match(c):
     48             count += 3
     49         else:
     50             count += 1
     51 
     52     return count
     53 
     54 
     55 def _max_append(L, s, maxlen, extra = ''):
     56     if not L:
     57         L.append(s.lstrip())
     58     elif len(L[-1]) + len(s) <= maxlen:
     59         L[-1] += extra + s
     60     else:
     61         L.append(s.lstrip())
     62 
     63 
     64 def unquote(s):
     65     return chr(int(s[1:3], 16))
     66 
     67 
     68 def quote(c):
     69     return '=%02X' % ord(c)
     70 
     71 
     72 def header_encode(header, charset = 'iso-8859-1', keep_eols = False, maxlinelen = 76, eol = NL):
     73     if not header:
     74         return header
     75     if not keep_eols:
     76         header = fix_eols(header)
     77     quoted = []
     78     if maxlinelen is None:
     79         max_encoded = 100000
     80     else:
     81         max_encoded = maxlinelen - len(charset) - MISC_LEN - 1
     82     for c in header:
     83         if c == ' ':
     84             _max_append(quoted, '_', max_encoded)
     85         elif not hqre.match(c):
     86             _max_append(quoted, c, max_encoded)
     87         else:
     88             _max_append(quoted, '=%02X' % ord(c), max_encoded)
     89 
     90     joiner = eol + ' '
     91     return joiner.join([ '=?%s?q?%s?=' % (charset, line) for line in quoted ])
     92 
     93 
     94 def encode(body, binary = False, maxlinelen = 76, eol = NL):
     95     if not body:
     96         return body
     97     if not binary:
     98         body = fix_eols(body)
     99     encoded_body = ''
    100     lineno = -1
    101     lines = body.splitlines(1)
    102     for line in lines:
    103         if line.endswith(CRLF):
    104             line = line[:-2]
    105         elif line[-1] in CRLF:
    106             line = line[:-1]
    107         lineno += 1
    108         encoded_line = ''
    109         prev = None
    110         linelen = len(line)
    111         for j in range(linelen):
    112             c = line[j]
    113             prev = c
    114             if bqre.match(c):
    115                 c = quote(c)
    116             elif j + 1 == linelen:
    117                 if c not in ' \t':
    118                     encoded_line += c
    119                 prev = c
    120                 continue
    121             if len(encoded_line) + len(c) >= maxlinelen:
    122                 encoded_body += encoded_line + '=' + eol
    123                 encoded_line = ''
    124             encoded_line += c
    125 
    126         if prev and prev in ' \t':
    127             if lineno + 1 == len(lines):
    128                 prev = quote(prev)
    129                 if len(encoded_line) + len(prev) > maxlinelen:
    130                     encoded_body += encoded_line + '=' + eol + prev
    131                 else:
    132                     encoded_body += encoded_line + prev
    133             else:
    134                 encoded_body += encoded_line + prev + '=' + eol
    135             encoded_line = ''
    136         if lines[lineno].endswith(CRLF) or lines[lineno][-1] in CRLF:
    137             encoded_body += encoded_line + eol
    138         else:
    139             encoded_body += encoded_line
    140         encoded_line = ''
    141 
    142     return encoded_body
    143 
    144 
    145 body_encode = encode
    146 encodestring = encode
    147 
    148 def decode(encoded, eol = NL):
    149     if not encoded:
    150         return encoded
    151     decoded = ''
    152     for line in encoded.splitlines():
    153         line = line.rstrip()
    154         if not line:
    155             decoded += eol
    156             continue
    157         i = 0
    158         n = len(line)
    159         while i < n:
    160             c = line[i]
    161             if c != '=':
    162                 decoded += c
    163                 i += 1
    164             elif i + 1 == n:
    165                 i += 1
    166                 continue
    167             elif i + 2 < n and line[i + 1] in hexdigits and line[i + 2] in hexdigits:
    168                 decoded += unquote(line[i:i + 3])
    169                 i += 3
    170             else:
    171                 decoded += c
    172                 i += 1
    173             if i == n:
    174                 decoded += eol
    175 
    176     if not encoded.endswith(eol) and decoded.endswith(eol):
    177         decoded = decoded[:-1]
    178     return decoded
    179 
    180 
    181 body_decode = decode
    182 decodestring = decode
    183 
    184 def _unquote_match(match):
    185     s = match.group(0)
    186     return unquote(s)
    187 
    188 
    189 def header_decode(s):
    190     s = s.replace('_', ' ')
    191     return re.sub('=[a-fA-F0-9]{2}', _unquote_match, s)