<s> from __future__ import absolute_import <EOL> import os <EOL> import csv <EOL> import zipfile <EOL> from cStringIO import StringIO <EOL> from email . mime . text import MIMEText <EOL> from email . mime . base import MIMEBase <EOL> from email . encoders import encode_base64 <EOL> from . utils import force_decode <EOL> from . import events <EOL> class TemplateError ( Exception ) : <EOL> pass <EOL> class Formatter ( object ) : <EOL> def check ( self , * args ) : <EOL> pass <EOL> def format ( self , result , events , * args ) : <EOL> raise NotImplementedError ( ) <EOL> class Const ( Formatter ) : <EOL> def __init__ ( self , value ) : <EOL> self . value = value <EOL> def check ( self , * args ) : <EOL> if args : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> def format ( self , obj , events , * args ) : <EOL> return self . value <EOL> class Event ( Formatter ) : <EOL> def __init__ ( self , * args , ** keys ) : <EOL> self . _event = events . Event ( * args , ** keys ) <EOL> def check ( self , * args ) : <EOL> if not args : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> if len ( args ) > <NUM_LIT:1> : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> def format ( self , obj , events , key ) : <EOL> return u"<STR_LIT:U+002CU+0020>" . join ( self . _event . values ( key ) ) <EOL> class AttachAndEmbedUnicode ( Formatter ) : <EOL> def __init__ ( self , formatter , subtype = "<STR_LIT>" ) : <EOL> self . formatter = formatter <EOL> self . subtype = subtype <EOL> def check ( self , filename = None , * args ) : <EOL> if filename is None : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> def format ( self , parts , events , filename , * args ) : <EOL> data = self . formatter . format ( parts , events , * args ) <EOL> part = MIMEText ( data . encode ( "<STR_LIT:utf-8>" ) , self . subtype , "<STR_LIT:utf-8>" ) <EOL> part . add_header ( "<STR_LIT>" , "<STR_LIT>" , filename = filename ) <EOL> parts . append ( part ) <EOL> return data <EOL> class AttachZip ( Formatter ) : <EOL> def __init__ ( self , formatter ) : <EOL> self . formatter = formatter <EOL> def check ( self , filename = None , * args ) : <EOL> if filename is None : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> def format ( self , parts , events , filename , * args ) : <EOL> prefix , ext = os . path . splitext ( filename ) <EOL> if ext . lower ( ) == "<STR_LIT>" : <EOL> zip_name = filename <EOL> raw_name = prefix <EOL> else : <EOL> zip_name = filename + "<STR_LIT>" <EOL> raw_name = filename <EOL> data = self . formatter . format ( parts , events , * args ) <EOL> memfile = StringIO ( ) <EOL> zipped = zipfile . ZipFile ( memfile , '<STR_LIT:w>' , zipfile . ZIP_DEFLATED ) <EOL> zipped . writestr ( raw_name , data . encode ( "<STR_LIT:utf-8>" ) ) <EOL> zipped . close ( ) <EOL> memfile . flush ( ) <EOL> memfile . seek ( <NUM_LIT:0> ) <EOL> part = MIMEBase ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> part . set_payload ( memfile . read ( ) ) <EOL> encode_base64 ( part ) <EOL> part . add_header ( "<STR_LIT>" , "<STR_LIT>" , filename = zip_name ) <EOL> parts . append ( part ) <EOL> return u"<STR_LIT>" <EOL> class AttachUnicode ( AttachAndEmbedUnicode ) : <EOL> def format ( self , * args , ** keys ) : <EOL> AttachAndEmbedUnicode . format ( self , * args , ** keys ) <EOL> return u"<STR_LIT>" <EOL> class _EventDict ( object ) : <EOL> def __init__ ( self , event , encoder = unicode ) : <EOL> self . event = event <EOL> self . encoder = encoder <EOL> def __getitem__ ( self , key ) : <EOL> value = self . event . value ( key , u"<STR_LIT>" ) <EOL> return self . encoder ( value ) <EOL> class CSVFormatter ( Formatter ) : <EOL> def __init__ ( self , keys = True ) : <EOL> self . keys = keys <EOL> def _encode ( self , string ) : <EOL> return string . encode ( "<STR_LIT:utf-8>" ) <EOL> def _decode ( self , string ) : <EOL> return string . decode ( "<STR_LIT:utf-8>" ) <EOL> def parse_fields ( self , fields ) : <EOL> for field in fields : <EOL> split = field . split ( "<STR_LIT:=>" , <NUM_LIT:1> ) <EOL> if len ( split ) != <NUM_LIT:2> : <EOL> yield split [ <NUM_LIT:0> ] , "<STR_LIT>" + split [ <NUM_LIT:0> ] + "<STR_LIT>" <EOL> else : <EOL> yield tuple ( split ) <EOL> def check ( self , delimiter = None , * fields ) : <EOL> if delimiter is None : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> if len ( delimiter ) != <NUM_LIT:1> : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> def format ( self , obj , events , delimiter , * fields ) : <EOL> stringio = StringIO ( ) <EOL> fields = list ( self . parse_fields ( fields ) ) <EOL> writer = csv . writer ( stringio , delimiter = delimiter ) <EOL> if self . keys : <EOL> writer . writerow ( [ key for ( key , _ ) in fields ] ) <EOL> for event in events : <EOL> event = _EventDict ( event , self . _encode ) <EOL> writer . writerow ( [ format % event for ( _ , format ) in fields ] ) <EOL> return self . _decode ( stringio . getvalue ( ) ) <EOL> class Template ( object ) : <EOL> class _Null ( object ) : <EOL> def format ( self , name , * args ) : <EOL> return "<STR_LIT>" <EOL> def __getitem__ ( self , key ) : <EOL> for row in csv . reader ( [ key ] , skipinitialspace = True ) : <EOL> if not row : <EOL> return u"<STR_LIT>" <EOL> row = [ x . strip ( ) for x in row ] <EOL> return self . format ( * row ) <EOL> return u"<STR_LIT>" <EOL> class _Checker ( _Null ) : <EOL> def __init__ ( self , formatters ) : <EOL> self . formatters = formatters <EOL> def format ( self , name , * args ) : <EOL> if name not in self . formatters : <EOL> raise TemplateError ( "<STR_LIT>" . format ( name ) ) <EOL> formatter = self . formatters [ name ] <EOL> try : <EOL> formatter . check ( * args ) <EOL> except TemplateError as err : <EOL> raise TemplateError ( "<STR_LIT>" . format ( name , err ) ) <EOL> return u"<STR_LIT>" <EOL> class _Formatter ( _Null ) : <EOL> def __init__ ( self , obj , events , formatters ) : <EOL> self . obj = obj <EOL> self . events = events <EOL> self . formatters = formatters <EOL> def format ( self , name , * args ) : <EOL> formatter = self . formatters [ name ] <EOL> return formatter . format ( self . obj , self . events , * args ) <EOL> def __init__ ( self , data , ** formatters ) : <EOL> self . data = force_decode ( data ) <EOL> self . formatters = formatters <EOL> try : <EOL> self . data % self . _Null ( ) <EOL> except ValueError : <EOL> raise TemplateError ( "<STR_LIT>" ) <EOL> except TypeError as type_error : <EOL> raise TemplateError ( str ( type_error ) ) <EOL> self . data % self . _Checker ( self . formatters ) <EOL> def format ( self , obj , events ) : <EOL> formatter = self . _Formatter ( obj , events , self . formatters ) <EOL> return self . data % formatter </s>
