<s> """<STR_LIT>""" <EOL> from __future__ import unicode_literals <EOL> from __future__ import division <EOL> from __future__ import absolute_import <EOL> from future . builtins import bytes , range , str , super , zip <EOL> __all__ = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> import re <EOL> import binascii <EOL> from future . backports import email <EOL> from future . backports . email import base64mime <EOL> from future . backports . email . errors import HeaderParseError <EOL> import future . backports . email . charset as _charset <EOL> from future . backports . email . quoprimime import _max_append , header_decode <EOL> Charset = _charset . Charset <EOL> NL = '<STR_LIT:\n>' <EOL> SPACE = '<STR_LIT:U+0020>' <EOL> BSPACE = b'<STR_LIT:U+0020>' <EOL> SPACE8 = '<STR_LIT:U+0020>' * <NUM_LIT:8> <EOL> EMPTYSTRING = '<STR_LIT>' <EOL> MAXLINELEN = <NUM_LIT> <EOL> FWS = '<STR_LIT>' <EOL> USASCII = Charset ( '<STR_LIT>' ) <EOL> UTF8 = Charset ( '<STR_LIT:utf-8>' ) <EOL> ecre = re . compile ( r'''<STR_LIT>''' , re . VERBOSE | re . IGNORECASE | re . MULTILINE ) <EOL> fcre = re . compile ( r'<STR_LIT>' ) <EOL> _embeded_header = re . compile ( r'<STR_LIT>' ) <EOL> def decode_header ( header ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( header , '<STR_LIT>' ) : <EOL> return [ ( _charset . _encode ( string , str ( charset ) ) , str ( charset ) ) <EOL> for string , charset in header . _chunks ] <EOL> if not ecre . search ( header ) : <EOL> return [ ( header , None ) ] <EOL> words = [ ] <EOL> for line in header . splitlines ( ) : <EOL> parts = ecre . split ( line ) <EOL> first = True <EOL> while parts : <EOL> unencoded = parts . pop ( <NUM_LIT:0> ) <EOL> if first : <EOL> unencoded = unencoded . lstrip ( ) <EOL> first = False <EOL> if unencoded : <EOL> words . append ( ( unencoded , None , None ) ) <EOL> if parts : <EOL> charset = parts . pop ( <NUM_LIT:0> ) . lower ( ) <EOL> encoding = parts . pop ( <NUM_LIT:0> ) . lower ( ) <EOL> encoded = parts . pop ( <NUM_LIT:0> ) <EOL> words . append ( ( encoded , encoding , charset ) ) <EOL> import sys <EOL> droplist = [ ] <EOL> for n , w in enumerate ( words ) : <EOL> if n > <NUM_LIT:1> and w [ <NUM_LIT:1> ] and words [ n - <NUM_LIT:2> ] [ <NUM_LIT:1> ] and words [ n - <NUM_LIT:1> ] [ <NUM_LIT:0> ] . isspace ( ) : <EOL> droplist . append ( n - <NUM_LIT:1> ) <EOL> for d in reversed ( droplist ) : <EOL> del words [ d ] <EOL> decoded_words = [ ] <EOL> for encoded_string , encoding , charset in words : <EOL> if encoding is None : <EOL> decoded_words . append ( ( encoded_string , charset ) ) <EOL> elif encoding == '<STR_LIT:q>' : <EOL> word = header_decode ( encoded_string ) <EOL> decoded_words . append ( ( word , charset ) ) <EOL> elif encoding == '<STR_LIT:b>' : <EOL> paderr = len ( encoded_string ) % <NUM_LIT:4> <EOL> if paderr : <EOL> encoded_string += '<STR_LIT>' [ : <NUM_LIT:4> - paderr ] <EOL> try : <EOL> word = base64mime . decode ( encoded_string ) <EOL> except binascii . Error : <EOL> raise HeaderParseError ( '<STR_LIT>' ) <EOL> else : <EOL> decoded_words . append ( ( word , charset ) ) <EOL> else : <EOL> raise AssertionError ( '<STR_LIT>' + encoding ) <EOL> collapsed = [ ] <EOL> last_word = last_charset = None <EOL> for word , charset in decoded_words : <EOL> if isinstance ( word , str ) : <EOL> word = bytes ( word , '<STR_LIT>' ) <EOL> if last_word is None : <EOL> last_word = word <EOL> last_charset = charset <EOL> elif charset != last_charset : <EOL> collapsed . append ( ( last_word , last_charset ) ) <EOL> last_word = word <EOL> last_charset = charset <EOL> elif last_charset is None : <EOL> last_word += BSPACE + word <EOL> else : <EOL> last_word += word <EOL> collapsed . append ( ( last_word , last_charset ) ) <EOL> return collapsed <EOL> def make_header ( decoded_seq , maxlinelen = None , header_name = None , <EOL> continuation_ws = '<STR_LIT:U+0020>' ) : <EOL> """<STR_LIT>""" <EOL> h = Header ( maxlinelen = maxlinelen , header_name = header_name , <EOL> continuation_ws = continuation_ws ) <EOL> for s , charset in decoded_seq : <EOL> if charset is not None and not isinstance ( charset , Charset ) : <EOL> charset = Charset ( charset ) <EOL> h . append ( s , charset ) <EOL> return h <EOL> class Header ( object ) : <EOL> def __init__ ( self , s = None , charset = None , <EOL> maxlinelen = None , header_name = None , <EOL> continuation_ws = '<STR_LIT:U+0020>' , errors = '<STR_LIT:strict>' ) : <EOL> """<STR_LIT>""" <EOL> if charset is None : <EOL> charset = USASCII <EOL> elif not isinstance ( charset , Charset ) : <EOL> charset = Charset ( charset ) <EOL> self . _charset = charset <EOL> self . _continuation_ws = continuation_ws <EOL> self . _chunks = [ ] <EOL> if s is not None : <EOL> self . append ( s , charset , errors ) <EOL> if maxlinelen is None : <EOL> maxlinelen = MAXLINELEN <EOL> self . _maxlinelen = maxlinelen <EOL> if header_name is None : <EOL> self . _headerlen = <NUM_LIT:0> <EOL> else : <EOL> self . _headerlen = len ( header_name ) + <NUM_LIT:2> <EOL> def __str__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _normalize ( ) <EOL> uchunks = [ ] <EOL> lastcs = None <EOL> lastspace = None <EOL> for string , charset in self . _chunks : <EOL> nextcs = charset <EOL> if nextcs == _charset . UNKNOWN8BIT : <EOL> original_bytes = string . encode ( '<STR_LIT:ascii>' , '<STR_LIT>' ) <EOL> string = original_bytes . decode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) <EOL> if uchunks : <EOL> hasspace = string and self . _nonctext ( string [ <NUM_LIT:0> ] ) <EOL> if lastcs not in ( None , '<STR_LIT>' ) : <EOL> if nextcs in ( None , '<STR_LIT>' ) and not hasspace : <EOL> uchunks . append ( SPACE ) <EOL> nextcs = None <EOL> elif nextcs not in ( None , '<STR_LIT>' ) and not lastspace : <EOL> uchunks . append ( SPACE ) <EOL> lastspace = string and self . _nonctext ( string [ - <NUM_LIT:1> ] ) <EOL> lastcs = nextcs <EOL> uchunks . append ( string ) <EOL> return EMPTYSTRING . join ( uchunks ) <EOL> def __eq__ ( self , other ) : <EOL> return other == str ( self ) <EOL> def __ne__ ( self , other ) : <EOL> return not self == other <EOL> def append ( self , s , charset = None , errors = '<STR_LIT:strict>' ) : <EOL> """<STR_LIT>""" <EOL> if charset is None : <EOL> charset = self . _charset <EOL> elif not isinstance ( charset , Charset ) : <EOL> charset = Charset ( charset ) <EOL> if not isinstance ( s , str ) : <EOL> input_charset = charset . input_codec or '<STR_LIT>' <EOL> if input_charset == _charset . UNKNOWN8BIT : <EOL> s = s . decode ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> else : <EOL> s = s . decode ( input_charset , errors ) <EOL> output_charset = charset . output_codec or '<STR_LIT>' <EOL> if output_charset != _charset . UNKNOWN8BIT : <EOL> try : <EOL> s . encode ( output_charset , errors ) <EOL> except UnicodeEncodeError : <EOL> if output_charset != '<STR_LIT>' : <EOL> raise <EOL> charset = UTF8 <EOL> self . _chunks . append ( ( s , charset ) ) <EOL> def _nonctext ( self , s ) : <EOL> """<STR_LIT>""" <EOL> return s . isspace ( ) or s in ( '<STR_LIT:(>' , '<STR_LIT:)>' , '<STR_LIT:\\>' ) <EOL> def encode ( self , splitchars = '<STR_LIT>' , maxlinelen = None , linesep = '<STR_LIT:\n>' ) : <EOL> r"""<STR_LIT>""" <EOL> self . _normalize ( ) <EOL> if maxlinelen is None : <EOL> maxlinelen = self . _maxlinelen <EOL> if maxlinelen == <NUM_LIT:0> : <EOL> maxlinelen = <NUM_LIT> <EOL> formatter = _ValueFormatter ( self . _headerlen , maxlinelen , <EOL> self . _continuation_ws , splitchars ) <EOL> lastcs = None <EOL> hasspace = lastspace = None <EOL> for string , charset in self . _chunks : <EOL> if hasspace is not None : <EOL> hasspace = string and self . _nonctext ( string [ <NUM_LIT:0> ] ) <EOL> import sys <EOL> if lastcs not in ( None , '<STR_LIT>' ) : <EOL> if not hasspace or charset not in ( None , '<STR_LIT>' ) : <EOL> formatter . add_transition ( ) <EOL> elif charset not in ( None , '<STR_LIT>' ) and not lastspace : <EOL> formatter . add_transition ( ) <EOL> lastspace = string and self . _nonctext ( string [ - <NUM_LIT:1> ] ) <EOL> lastcs = charset <EOL> hasspace = False <EOL> lines = string . splitlines ( ) <EOL> if lines : <EOL> formatter . feed ( '<STR_LIT>' , lines [ <NUM_LIT:0> ] , charset ) <EOL> else : <EOL> formatter . feed ( '<STR_LIT>' , '<STR_LIT>' , charset ) <EOL> for line in lines [ <NUM_LIT:1> : ] : <EOL> formatter . newline ( ) <EOL> if charset . header_encoding is not None : <EOL> formatter . feed ( self . _continuation_ws , '<STR_LIT:U+0020>' + line . lstrip ( ) , <EOL> charset ) <EOL> else : <EOL> sline = line . lstrip ( ) <EOL> fws = line [ : len ( line ) - len ( sline ) ] <EOL> formatter . feed ( fws , sline , charset ) <EOL> if len ( lines ) > <NUM_LIT:1> : <EOL> formatter . newline ( ) <EOL> if self . _chunks : <EOL> formatter . add_transition ( ) <EOL> value = formatter . _str ( linesep ) <EOL> if _embeded_header . search ( value ) : <EOL> raise HeaderParseError ( "<STR_LIT>" <EOL> "<STR_LIT>" . format ( value ) ) <EOL> return value <EOL> def _normalize ( self ) : <EOL> chunks = [ ] <EOL> last_charset = None <EOL> last_chunk = [ ] <EOL> for string , charset in self . _chunks : <EOL> if charset == last_charset : <EOL> last_chunk . append ( string ) <EOL> else : <EOL> if last_charset is not None : <EOL> chunks . append ( ( SPACE . join ( last_chunk ) , last_charset ) ) <EOL> last_chunk = [ string ] <EOL> last_charset = charset <EOL> if last_chunk : <EOL> chunks . append ( ( SPACE . join ( last_chunk ) , last_charset ) ) <EOL> self . _chunks = chunks <EOL> class _ValueFormatter ( object ) : <EOL> def __init__ ( self , headerlen , maxlen , continuation_ws , splitchars ) : <EOL> self . _maxlen = maxlen <EOL> self . _continuation_ws = continuation_ws <EOL> self . _continuation_ws_len = len ( continuation_ws ) <EOL> self . _splitchars = splitchars <EOL> self . _lines = [ ] <EOL> self . _current_line = _Accumulator ( headerlen ) <EOL> def _str ( self , linesep ) : <EOL> self . newline ( ) <EOL> return linesep . join ( self . _lines ) <EOL> def __str__ ( self ) : <EOL> return self . _str ( NL ) <EOL> def newline ( self ) : <EOL> end_of_line = self . _current_line . pop ( ) <EOL> if end_of_line != ( '<STR_LIT:U+0020>' , '<STR_LIT>' ) : <EOL> self . _current_line . push ( * end_of_line ) <EOL> if len ( self . _current_line ) > <NUM_LIT:0> : <EOL> if self . _current_line . is_onlyws ( ) : <EOL> self . _lines [ - <NUM_LIT:1> ] += str ( self . _current_line ) <EOL> else : <EOL> self . _lines . append ( str ( self . _current_line ) ) <EOL> self . _current_line . reset ( ) <EOL> def add_transition ( self ) : <EOL> self . _current_line . push ( '<STR_LIT:U+0020>' , '<STR_LIT>' ) <EOL> def feed ( self , fws , string , charset ) : <EOL> if charset . header_encoding is None : <EOL> self . _ascii_split ( fws , string , self . _splitchars ) <EOL> return <EOL> encoded_lines = charset . header_encode_lines ( string , self . _maxlengths ( ) ) <EOL> try : <EOL> first_line = encoded_lines . pop ( <NUM_LIT:0> ) <EOL> except IndexError : <EOL> return <EOL> if first_line is not None : <EOL> self . _append_chunk ( fws , first_line ) <EOL> try : <EOL> last_line = encoded_lines . pop ( ) <EOL> except IndexError : <EOL> return <EOL> self . newline ( ) <EOL> self . _current_line . push ( self . _continuation_ws , last_line ) <EOL> for line in encoded_lines : <EOL> self . _lines . append ( self . _continuation_ws + line ) <EOL> def _maxlengths ( self ) : <EOL> yield self . _maxlen - len ( self . _current_line ) <EOL> while True : <EOL> yield self . _maxlen - self . _continuation_ws_len <EOL> def _ascii_split ( self , fws , string , splitchars ) : <EOL> parts = re . split ( "<STR_LIT>" + FWS + "<STR_LIT>" , fws + string ) <EOL> if parts [ <NUM_LIT:0> ] : <EOL> parts [ : <NUM_LIT:0> ] = [ '<STR_LIT>' ] <EOL> else : <EOL> parts . pop ( <NUM_LIT:0> ) <EOL> for fws , part in zip ( * [ iter ( parts ) ] * <NUM_LIT:2> ) : <EOL> self . _append_chunk ( fws , part ) <EOL> def _append_chunk ( self , fws , string ) : <EOL> self . _current_line . push ( fws , string ) <EOL> if len ( self . _current_line ) > self . _maxlen : <EOL> for ch in self . _splitchars : <EOL> for i in range ( self . _current_line . part_count ( ) - <NUM_LIT:1> , <NUM_LIT:0> , - <NUM_LIT:1> ) : <EOL> if ch . isspace ( ) : <EOL> fws = self . _current_line [ i ] [ <NUM_LIT:0> ] <EOL> if fws and fws [ <NUM_LIT:0> ] == ch : <EOL> break <EOL> prevpart = self . _current_line [ i - <NUM_LIT:1> ] [ <NUM_LIT:1> ] <EOL> if prevpart and prevpart [ - <NUM_LIT:1> ] == ch : <EOL> break <EOL> else : <EOL> continue <EOL> break <EOL> else : <EOL> fws , part = self . _current_line . pop ( ) <EOL> if self . _current_line . _initial_size > <NUM_LIT:0> : <EOL> self . newline ( ) <EOL> if not fws : <EOL> fws = '<STR_LIT:U+0020>' <EOL> self . _current_line . push ( fws , part ) <EOL> return <EOL> remainder = self . _current_line . pop_from ( i ) <EOL> self . _lines . append ( str ( self . _current_line ) ) <EOL> self . _current_line . reset ( remainder ) <EOL> class _Accumulator ( list ) : <EOL> def __init__ ( self , initial_size = <NUM_LIT:0> ) : <EOL> self . _initial_size = initial_size <EOL> super ( ) . __init__ ( ) <EOL> def push ( self , fws , string ) : <EOL> self . append ( ( fws , string ) ) <EOL> def pop_from ( self , i = <NUM_LIT:0> ) : <EOL> popped = self [ i : ] <EOL> self [ i : ] = [ ] <EOL> return popped <EOL> def pop ( self ) : <EOL> if self . part_count ( ) == <NUM_LIT:0> : <EOL> return ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return super ( ) . pop ( ) <EOL> def __len__ ( self ) : <EOL> return sum ( ( len ( fws ) + len ( part ) for fws , part in self ) , <EOL> self . _initial_size ) <EOL> def __str__ ( self ) : <EOL> return EMPTYSTRING . join ( ( EMPTYSTRING . join ( ( fws , part ) ) <EOL> for fws , part in self ) ) <EOL> def reset ( self , startval = None ) : <EOL> if startval is None : <EOL> startval = [ ] <EOL> self [ : ] = startval <EOL> self . _initial_size = <NUM_LIT:0> <EOL> def is_onlyws ( self ) : <EOL> return self . _initial_size == <NUM_LIT:0> and ( not self or str ( self ) . isspace ( ) ) <EOL> def part_count ( self ) : <EOL> return super ( ) . __len__ ( ) </s>
