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

charset.py (6277B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\email\charset.py
      2 __all__ = ['Charset',
      3  'add_alias',
      4  'add_charset',
      5  'add_codec']
      6 import codecs
      7 import email.base64mime
      8 import email.quoprimime
      9 from email import errors
     10 from email.encoders import encode_7or8bit
     11 QP = 1
     12 BASE64 = 2
     13 SHORTEST = 3
     14 MISC_LEN = 7
     15 DEFAULT_CHARSET = 'us-ascii'
     16 CHARSETS = {'iso-8859-1': (QP, QP, None),
     17  'iso-8859-2': (QP, QP, None),
     18  'iso-8859-3': (QP, QP, None),
     19  'iso-8859-4': (QP, QP, None),
     20  'iso-8859-9': (QP, QP, None),
     21  'iso-8859-10': (QP, QP, None),
     22  'iso-8859-13': (QP, QP, None),
     23  'iso-8859-14': (QP, QP, None),
     24  'iso-8859-15': (QP, QP, None),
     25  'iso-8859-16': (QP, QP, None),
     26  'windows-1252': (QP, QP, None),
     27  'viscii': (QP, QP, None),
     28  'us-ascii': (None, None, None),
     29  'big5': (BASE64, BASE64, None),
     30  'gb2312': (BASE64, BASE64, None),
     31  'euc-jp': (BASE64, None, 'iso-2022-jp'),
     32  'shift_jis': (BASE64, None, 'iso-2022-jp'),
     33  'iso-2022-jp': (BASE64, None, None),
     34  'koi8-r': (BASE64, BASE64, None),
     35  'utf-8': (SHORTEST, BASE64, 'utf-8'),
     36  '8bit': (None, BASE64, 'utf-8')}
     37 ALIASES = {'latin_1': 'iso-8859-1',
     38  'latin-1': 'iso-8859-1',
     39  'latin_2': 'iso-8859-2',
     40  'latin-2': 'iso-8859-2',
     41  'latin_3': 'iso-8859-3',
     42  'latin-3': 'iso-8859-3',
     43  'latin_4': 'iso-8859-4',
     44  'latin-4': 'iso-8859-4',
     45  'latin_5': 'iso-8859-9',
     46  'latin-5': 'iso-8859-9',
     47  'latin_6': 'iso-8859-10',
     48  'latin-6': 'iso-8859-10',
     49  'latin_7': 'iso-8859-13',
     50  'latin-7': 'iso-8859-13',
     51  'latin_8': 'iso-8859-14',
     52  'latin-8': 'iso-8859-14',
     53  'latin_9': 'iso-8859-15',
     54  'latin-9': 'iso-8859-15',
     55  'latin_10': 'iso-8859-16',
     56  'latin-10': 'iso-8859-16',
     57  'cp949': 'ks_c_5601-1987',
     58  'euc_jp': 'euc-jp',
     59  'euc_kr': 'euc-kr',
     60  'ascii': 'us-ascii'}
     61 CODEC_MAP = {'gb2312': 'eucgb2312_cn',
     62  'big5': 'big5_tw',
     63  'us-ascii': None}
     64 
     65 def add_charset(charset, header_enc = None, body_enc = None, output_charset = None):
     66     if body_enc == SHORTEST:
     67         raise ValueError('SHORTEST not allowed for body_enc')
     68     CHARSETS[charset] = (header_enc, body_enc, output_charset)
     69 
     70 
     71 def add_alias(alias, canonical):
     72     ALIASES[alias] = canonical
     73 
     74 
     75 def add_codec(charset, codecname):
     76     CODEC_MAP[charset] = codecname
     77 
     78 
     79 class Charset:
     80 
     81     def __init__(self, input_charset = DEFAULT_CHARSET):
     82         try:
     83             if isinstance(input_charset, unicode):
     84                 input_charset.encode('ascii')
     85             else:
     86                 input_charset = unicode(input_charset, 'ascii')
     87         except UnicodeError:
     88             raise errors.CharsetError(input_charset)
     89 
     90         input_charset = input_charset.lower()
     91         if not (input_charset in ALIASES or input_charset in CHARSETS):
     92             try:
     93                 input_charset = codecs.lookup(input_charset).name
     94             except LookupError:
     95                 pass
     96 
     97         self.input_charset = ALIASES.get(input_charset, input_charset)
     98         henc, benc, conv = CHARSETS.get(self.input_charset, (SHORTEST, BASE64, None))
     99         if not conv:
    100             conv = self.input_charset
    101         self.header_encoding = henc
    102         self.body_encoding = benc
    103         self.output_charset = ALIASES.get(conv, conv)
    104         self.input_codec = CODEC_MAP.get(self.input_charset, self.input_charset)
    105         self.output_codec = CODEC_MAP.get(self.output_charset, self.output_charset)
    106 
    107     def __str__(self):
    108         return self.input_charset.lower()
    109 
    110     __repr__ = __str__
    111 
    112     def __eq__(self, other):
    113         return str(self) == str(other).lower()
    114 
    115     def __ne__(self, other):
    116         return not self.__eq__(other)
    117 
    118     def get_body_encoding(self):
    119         if self.body_encoding == QP:
    120             return 'quoted-printable'
    121         elif self.body_encoding == BASE64:
    122             return 'base64'
    123         else:
    124             return encode_7or8bit
    125 
    126     def convert(self, s):
    127         if self.input_codec != self.output_codec:
    128             return unicode(s, self.input_codec).encode(self.output_codec)
    129         else:
    130             return s
    131 
    132     def to_splittable(self, s):
    133         if isinstance(s, unicode) or self.input_codec is None:
    134             return s
    135         try:
    136             return unicode(s, self.input_codec, 'replace')
    137         except LookupError:
    138             return s
    139 
    140     def from_splittable(self, ustr, to_output = True):
    141         if to_output:
    142             codec = self.output_codec
    143         else:
    144             codec = self.input_codec
    145         if not isinstance(ustr, unicode) or codec is None:
    146             return ustr
    147         try:
    148             return ustr.encode(codec, 'replace')
    149         except LookupError:
    150             return ustr
    151 
    152     def get_output_charset(self):
    153         return self.output_charset or self.input_charset
    154 
    155     def encoded_header_len(self, s):
    156         cset = self.get_output_charset()
    157         if self.header_encoding == BASE64:
    158             return email.base64mime.base64_len(s) + len(cset) + MISC_LEN
    159         elif self.header_encoding == QP:
    160             return email.quoprimime.header_quopri_len(s) + len(cset) + MISC_LEN
    161         elif self.header_encoding == SHORTEST:
    162             lenb64 = email.base64mime.base64_len(s)
    163             lenqp = email.quoprimime.header_quopri_len(s)
    164             return min(lenb64, lenqp) + len(cset) + MISC_LEN
    165         else:
    166             return len(s)
    167 
    168     def header_encode(self, s, convert = False):
    169         cset = self.get_output_charset()
    170         if convert:
    171             s = self.convert(s)
    172         if self.header_encoding == BASE64:
    173             return email.base64mime.header_encode(s, cset)
    174         if self.header_encoding == QP:
    175             return email.quoprimime.header_encode(s, cset, maxlinelen=None)
    176         if self.header_encoding == SHORTEST:
    177             lenb64 = email.base64mime.base64_len(s)
    178             lenqp = email.quoprimime.header_quopri_len(s)
    179             if lenb64 < lenqp:
    180                 return email.base64mime.header_encode(s, cset)
    181             else:
    182                 return email.quoprimime.header_encode(s, cset, maxlinelen=None)
    183         else:
    184             return s
    185 
    186     def body_encode(self, s, convert = True):
    187         if convert:
    188             s = self.convert(s)
    189         if self.body_encoding is BASE64:
    190             return email.base64mime.body_encode(s)
    191         elif self.body_encoding is QP:
    192             return email.quoprimime.body_encode(s)
    193         else:
    194             return s