def writeall(self): ''' Very different writeall: there is no tree of nodes; there is no grammar.structure/recorddefs; kid opens file by itself. ''' try: from genshi.template import TemplateLoader except: txt=botslib.txtexc() raise ImportError(_(u'Dependency failure: editype "template" requires python library "genshi". Error:\n%s'%txt)) #for template-grammar: only syntax is used. Section 'syntax' has to have 'template' self.outmessagegrammarread(self.ta_info['editype'],self.ta_info['messagetype']) templatefile = botslib.abspath(u'templateshtml',self.ta_info['template']) try: botsglobal.logger.debug(u'Start writing to file "%s".',self.ta_info['filename']) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) try: f = botslib.opendata(self.ta_info['filename'],'wb') stream = tmpl.generate(data=self.data) stream.render(method='xhtml',encoding=self.ta_info['charset'],out=f) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) botsglobal.logger.debug(_(u'End writing to file "%s".'),self.ta_info['filename'])
def writeall(self): ''' Very different writeall: there is no tree of nodes; there is no grammar.structure/recorddefs; kid opens file by itself. ''' try: import kid except: txt=botslib.txtexc() raise ImportError(_(u'Dependency failure: editype "template" requires python library "kid". Error:\n%s'%txt)) #for template-grammar: only syntax is used. Section 'syntax' has to have 'template' self.outmessagegrammarread(self.ta_info['editype'],self.ta_info['messagetype']) templatefile = botslib.abspath(u'templates',self.ta_info['template']) try: botsglobal.logger.debug(u'Start writing to file "%s".',self.ta_info['filename']) ediprint = kid.Template(file=templatefile, data=self.data) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) try: f = botslib.opendata(self.ta_info['filename'],'wb') ediprint.write(f, #~ ediprint.write(botslib.abspathdata(self.ta_info['filename']), encoding=self.ta_info['charset'], output=self.ta_info['output'], #output is specific parameter for class; init from grammar.syntax fragment=self.ta_info['merge']) except: txt=botslib.txtexc() raise botslib.OutMessageError(_(u'While templating "$editype.$messagetype", error:\n$txt'),editype=self.ta_info['editype'],messagetype=self.ta_info['messagetype'],txt=txt) botsglobal.logger.debug(_(u'End writing to file "%s".'),self.ta_info['filename'])
def run(self): ''' class for (test) orderprint; delevers a valid html-file. Uses a kid-template for the enveloping/merging. use kid to write; no envelope grammar is used ''' try: from genshi.template import TemplateLoader except: txt = botslib.txtexc() raise ImportError( _(u'Dependency failure: editype "template" requires python library "genshi". Error:\n%s' % txt)) defmessage = grammar.grammarread( self.ta_info['editype'], self.ta_info['messagetype'] ) #needed because we do not know envelope; read syntax for editype/messagetype self.ta_info.update(defmessage.syntax) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError(_( u'While enveloping in "$editype.$messagetype": syntax option "envelope-template" not filled; is required.' ), editype=self.ta_info['editype'], messagetype=self. ta_info['messagetype']) templatefile = botslib.abspath('templateshtml', self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug(u'Start writing envelope to file "%s".', self.ta_info['filename']) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "$editype.$messagetype", error:\n$txt' ), editype=self.ta_info['editype'], messagetype=self.ta_info['messagetype'], txt=txt) try: filehandler = botslib.opendata(self.ta_info['filename'], 'wb') stream = tmpl.generate(data=ta_list) stream.render(method='xhtml', encoding=self.ta_info['charset'], out=filehandler) except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "$editype.$messagetype", error:\n$txt' ), editype=self.ta_info['editype'], messagetype=self.ta_info['messagetype'], txt=txt)
def run(self): ''' class for (test) orderprint; delevers a valid html-file. Uses a kid-template for the enveloping/merging. use kid to write; no envelope grammar is used ''' try: import kid except: txt = botslib.txtexc() raise ImportError( _(u'Dependency failure: editype "template" requires python library "kid". Error:\n%s' % txt)) defmessage = grammar.grammarread( self.ta_info['editype'], self.ta_info['messagetype'] ) #needed because we do not know envelope; read syntax for editype/messagetype self.ta_info.update(defmessage.syntax) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError(_( u'While enveloping in "$editype.$messagetype": syntax option "envelope-template" not filled; is required.' ), editype=self.ta_info['editype'], messagetype=self. ta_info['messagetype']) templatefile = botslib.abspath('templates', self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug(u'Start writing envelope to file "%s".', self.ta_info['filename']) ediprint = kid.Template( file=templatefile, data=ta_list) #init template; pass list with filenames except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "$editype.$messagetype", error:\n$txt' ), editype=self.ta_info['editype'], messagetype=self.ta_info['messagetype'], txt=txt) try: filehandler = botslib.opendata(self.ta_info['filename'], 'wb') ediprint.write(filehandler, encoding=self.ta_info['charset'], output=self.ta_info['output']) except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "$editype.$messagetype", error:\n$txt' ), editype=self.ta_info['editype'], messagetype=self.ta_info['messagetype'], txt=txt)
def run(self): try: from genshi.template import TemplateLoader except: raise ImportError( u'Dependency failure: editype "templatehtml" requires python library "genshi".' ) self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) if not self.ta_info['envelope-template']: raise botslib.OutMessageError( _(u'While enveloping in "%(editype)s.%(messagetype)s": syntax option "envelope-template" not filled; is required.' ), self.ta_info) templatefile = botslib.abspath(self.__class__.__name__, self.ta_info['envelope-template']) ta_list = self.filelist2absolutepaths() try: botsglobal.logger.debug( u'Start writing envelope to file "%(filename)s".', self.ta_info) loader = TemplateLoader(auto_reload=False) tmpl = loader.load(templatefile) except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s' ), { 'editype': self.ta_info['editype'], 'messagetype': self.ta_info['messagetype'], 'txt': txt }) try: filehandler = botslib.opendata(self.ta_info['filename'], 'wb') stream = tmpl.generate(data=ta_list) stream.render(method='xhtml', encoding=self.ta_info['charset'], out=filehandler) except: txt = botslib.txtexc() raise botslib.OutMessageError( _(u'While enveloping in "%(editype)s.%(messagetype)s", error:\n%(txt)s' ), { 'editype': self.ta_info['editype'], 'messagetype': self.ta_info['messagetype'], 'txt': txt })
def writeall(self): ''' writeall is called for writing all 'real' outmessage objects; but not for enveloping. writeall is call from transform.translate() ''' self.nrmessagewritten = 0 if not self.root.children: raise botslib.OutMessageError( _(u'No outgoing message')) #then there is nothing to write... for message in self.root.getloop({'BOTSID': 'STX'}, {'BOTSID': 'MHD'}): self.outmessagegrammarread( self.ta_info['editype'], message.get({ 'BOTSID': 'MHD', 'TYPE.01': None }) + message.get({ 'BOTSID': 'MHD', 'TYPE.02': None })) if not self.nrmessagewritten: self._initwrite() self.normalisetree(message) self._write(message) self.nrmessagewritten += 1 self._closewrite() self.ta_info['nrmessages'] = self.nrmessagewritten
def _node2xmlfields(self,noderecord): ''' fields in a node are written to xml fields; output is sorted according to grammar ''' if 'BOTSID' not in noderecord: raise botslib.OutMessageError(_(u'No field "BOTSID" in xml-output in: "$record"'),record=noderecord) #first generate the xml-'record' attributedict = {} recordtag = noderecord['BOTSID'] attributemarker = recordtag + self.ta_info['attributemarker'] for key,value in noderecord.items(): #find the attributes for the xml-record, put these in attributedict if key.startswith(attributemarker): attributedict[key[len(attributemarker):]] = value xmlrecord = ET.Element(recordtag,attributedict) #make the xml ET node if 'BOTSCONTENT' in noderecord: xmlrecord.text = noderecord['BOTSCONTENT'] del noderecord['BOTSCONTENT'] for key in attributedict.keys(): #remove used fields del noderecord[attributemarker+key] del noderecord['BOTSID'] #remove 'record' tag #generate xml-'fields' in xml-'record'; not sorted noderecordcopy = noderecord.copy() for key,value in noderecordcopy.items(): if key not in noderecord or self.ta_info['attributemarker'] in key: #if field not in outmessage: skip continue attributedict = {} attributemarker = key + self.ta_info['attributemarker'] for key2,value2 in noderecord.items(): if key2.startswith(attributemarker): attributedict[key2[len(attributemarker):]] = value2 ET.SubElement(xmlrecord, key,attributedict).text=value #add xml element to xml record for key2 in attributedict.keys(): #remove used fields del noderecord[attributemarker+key2] del noderecord[key] #remove xml entity tag return xmlrecord
def _record2string(self, record): ''' write (all fields of) a record using the right separators, escape etc ''' sfield_sep = self.ta_info['sfield_sep'] if self.ta_info['record_tag_sep']: record_tag_sep = self.ta_info['record_tag_sep'] else: record_tag_sep = self.ta_info['field_sep'] field_sep = self.ta_info['field_sep'] quote_char = self.ta_info['quote_char'] escape = self.ta_info['escape'] record_sep = self.ta_info['record_sep'] + self.ta_info[ 'add_crlfafterrecord_sep'] forcequote = self.ta_info['forcequote'] escapechars = self.getescapechars() value = u'' #to collect separator/escape plus field content fieldcount = 0 mode_quote = False if self.ta_info[ 'noBOTSID']: #for some csv-files: do not write BOTSID so remove it del record[0] for field in record: #loop all fields in record if field[SFIELD]: value += sfield_sep else: #is a field: if fieldcount == 0: #do nothing because first field in record is not preceeded by a separator fieldcount = 1 elif fieldcount == 1: value += record_tag_sep fieldcount = 2 else: value += field_sep if quote_char and (forcequote or field_sep in field[VALUE] or quote_char in field[VALUE] or record_sep in field[VALUE]): #TO DO test. if quote_char='' this works OK. Alt: check first if quote_char value += quote_char mode_quote = True for char in field[ VALUE]: #use escape (edifact, tradacom). For x12 is warned if content contains separator if char in escapechars: if isinstance(self, x12): if self.ta_info['replacechar']: char = self.ta_info['replacechar'] else: raise botslib.OutMessageError(_( u'Character "$char" is in use as separator in this x12 file. Field: "$data".' ), char=char, data=field[VALUE]) else: value += escape elif mode_quote and char == quote_char: value += quote_char value += char if mode_quote: value += quote_char mode_quote = False value += record_sep return value
def writeall(self): ''' writeall is called for writing all 'real' outmessage objects; but not for envelopes. writeall is call from transform.translate() ''' self.outmessagegrammarread(self.ta_info['editype'], self.ta_info['messagetype']) self.nrmessagewritten = 0 if self.root.record: #root record contains information; write whole tree in one time self.multiplewrite = False self.normalisetree(self.root) self._initwrite() self._write(self.root) self.nrmessagewritten = 1 self._closewrite() elif not self.root.children: raise botslib.OutMessageError( _(u'No outgoing message')) #then there is nothing to write... else: self.multiplewrite = True for childnode in self.root.children: self.normalisetree(childnode) self._initwrite() for childnode in self.root.children: self._write(childnode) self.nrmessagewritten += 1 self._closewrite()
def outmessage_init(**ta_info): ''' dispatch function class Outmessage or subclass ta_info: needed is editype, messagetype, filename, charset, merge ''' try: classtocall = globals()[ta_info['editype']] except KeyError: raise botslib.OutMessageError(_(u'Unknown editype for outgoing message: $editype'),editype=ta_info['editype']) return classtocall(ta_info)
def writeall(self): if self.root is None: raise botslib.OutMessageError(_(u'No outgoing message')) #then there is nothing to write... botsglobal.logger.debug(u'Start writing to file "%s".',self.ta_info['filename']) self._outstream = botslib.opendata(self.ta_info['filename'],'wb') self._outstream.write(self.root) self._outstream.close() botsglobal.logger.debug(u'End writing to file "%s".',self.ta_info['filename']) self.ta_info['envelope'] = 'raw' #use right enveloping for raw: no coping etc, use same file.
def _records2file(self): ''' convert self.records to a file. using the right editype (edifact, x12, etc) and charset. ''' wrap_length = int(self.ta_info.get('wrap_length', 0)) if wrap_length: s = ''.join(self._record2string(r) for r in self.records) # join all records for i in range(0,len(s),wrap_length): # then split in fixed lengths try: self._outstream.write(s[i:i+wrap_length] + '\r\n') except UnicodeEncodeError: raise botslib.OutMessageError(_(u'Chars in outmessage not in charset "$char": $content'),char=self.ta_info['charset'],content=s[i:i+wrap_length]) else: for record in self.records: #loop all records try: self._outstream.write(self._record2string(record)) except UnicodeEncodeError: #, flup: testing with 2.7: flup did not contain the content. raise botslib.OutMessageError(_(u'Chars in outmessage not in charset "$char": $content'),char=self.ta_info['charset'],content=str(record))
def _records2file(self): ''' convert self.records to a file. using the right editype (edifact, x12, etc) and charset. ''' for record in self.records: #loop all records try: self._outstream.write(self._record2string(record)) except UnicodeEncodeError, flup: raise botslib.OutMessageError( _(u'Chars in outmessage not in charset "$char": $content'), char=self.ta_info['charset'], content=flup)
def envelope(ta_info, ta_list): ''' dispatch function for class Envelope and subclasses. editype, edimessage and envelope essential for enveloping. determine the class for enveloping: 1. empty string: no enveloping (class noenvelope); file(s) is/are just copied. No user scripting for envelope. 2. if user defined enveloping in usersys/envelope/<editype>/<envelope>.<envelope>, use it (user defined scripting overrides) user exits extends/replaces default enveloping. 3. if editype is a class in this module, use it. Complex is how enveloping and grammar/syntax work together for enveloping: 1. no envelope script: noenvelope syntax: - 2. user scripted script: envelopescripts.editype.envelope syntax: grammar.editype.envelope (alt could be envelopescripts.editype.envelope; but this is inline with incoming) grammar.editype.messagetype 3. class editype script: envelope.editype syntax: grammar.editype.envelope grammar.editype.messagetype ''' classtocall = userscript = scriptname = None if not ta_info['envelope']: #used when enveloping is just appending files. classtocall = noenvelope else: try: #check for user scripted enveloping userscript, scriptname = botslib.botsimport( 'envelopescripts', ta_info['editype'], ta_info['envelope']) #check if there is a user scripted class with name ta_info['envelope']. classtocall = getattr(userscript, ta_info['envelope'], None) except botslib.BotsImportError: #no user enveloping. pass if classtocall is None: try: classtocall = globals()[ta_info['editype']] except KeyError: raise botslib.OutMessageError( _(u'Not found envelope "%(envelope)s" for editype "%(editype)s".' ), ta_info) env = classtocall(ta_info, ta_list, userscript, scriptname) env.run()
def envelope(ta_info, ta_list): ''' dispatch function for class Envelope and subclasses. editype, edimessage and envelope essential for enveloping. determine the class for enveloping: 1. empty string: no enveloping (class noenvelope); file(s) is/are just copied. No user scripting for envelope. 2. if envelope is a class in this module, use it 3. if editype is a class in this module, use it 4. if user defined enveloping in usersys/envelope/<editype>/<envelope>.<envelope>, use it (user defined scripting overrides) Always check if user envelope script. user exits extends/replaces default enveloping. ''' #determine which class to use for enveloping userscript = scriptname = None if not ta_info['envelope']: #used when enveloping is just appending files. classtocall = noenvelope else: try: #see if the is user scripted enveloping userscript, scriptname = botslib.botsimport( 'envelopescripts', ta_info['editype'] + '.' + ta_info['envelope']) except ImportError: #other errors, eg syntax errors are just passed pass #first: check if there is a class with name ta_info['envelope'] in the user scripting #this allows complete enveloping in user scripting if userscript and hasattr(userscript, ta_info['envelope']): classtocall = getattr(userscript, ta_info['envelope']) else: try: #check if there is a envelope class with name ta_info['envelope'] in this file (envelope.py) classtocall = globals()[ta_info['envelope']] except KeyError: try: #check if there is a envelope class with name ta_info['editype'] in this file (envelope.py). #20110919: this should disappear in the long run....use this now for orders2printenvelope and myxmlenvelop #reason to disappear: confusing when setting up. classtocall = globals()[ta_info['editype']] except KeyError: raise botslib.OutMessageError( _(u'Not found envelope "$envelope".'), envelope=ta_info['editype']) env = classtocall(ta_info, ta_list, userscript, scriptname) env.run()
def envelope(ta_info, ta_list): ''' despatch function for class Envelope and subclasses. editype, edimessage and envelope essential for enveloping. determine the class for enveloping: 1. empty string: no enveloping (class noenvelope); file(s) is/are just copied. No user scripting for envelope. 2. if envelope is a class in this module, use it 3. if editype is a class in this module, use it 4. if user defined enveloping in usersys/envelope/<editype>/<envelope>.<envelope>, use it (user defined scripting overrides) Always check if user envelope script. user exits extends/replaces default enveloping. ''' #determine which class to use for enveloping userscript = scriptname = None if not ta_info['envelope']: classtocall = noenvelope else: try: #see if the is user scripted enveloping botsglobal.logger.debug( u'(try) to read user envelopescript editype "%s", envelope "%s".', ta_info['editype'], ta_info['envelope']) userscript, scriptname = botslib.botsimport( 'envelopescripts', ta_info['editype'] + '.' + ta_info['envelope']) except ImportError: #other errors, eg syntax errors are just passed pass try: classtocall = globals()[ta_info['envelope']] except KeyError: try: classtocall = globals()[ta_info['editype']] except KeyError: raise botslib.OutMessageError( _(u'Not found envelope "$envelope".'), envelope=ta_info['editype']) if userscript and hasattr(userscript, ta_info['envelope']): classtocall = getattr(userscript, ta_info['envelope']) env = classtocall(ta_info, ta_list, userscript, scriptname) env.run()
def run(self): if not self.ta_info['topartner'] or not self.ta_info['frompartner']: raise botslib.OutMessageError( _(u'In enveloping "frompartner" or "topartner" unknown: "%(ta_info)s".' ), {'ta_info': self.ta_info}) self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) #prepare data for envelope isa09date = botslib.strftime('%y%m%d') #test indicator can either be from configuration (self.ta_info['ISA15']) or by mapping (self.ta_info['testindicator']) #mapping overrules. if self.ta_info['testindicator'] and self.ta_info[ 'testindicator'] != '0': #'0' is default value (in db) testindicator = self.ta_info['testindicator'] else: testindicator = self.ta_info['ISA15'] #~ print self.ta_info['messagetype'], 'grammar:',self.ta_info['ISA15'],'ta:',self.ta_info['testindicator'],'out:',testindicator if botsglobal.ini.getboolean('settings', 'interchangecontrolperpartner', False): self.ta_info['reference'] = unicode( botslib.unique('isacounter_' + self.ta_info['topartner'])) else: self.ta_info['reference'] = unicode( botslib.unique('isacounter_' + self.ta_info['frompartner'])) #ISA06 and GS02 can be different; eg ISA06 is a service provider. #ISA06 and GS02 can be in the syntax.... isa06sender = self.ta_info.get('ISA06', self.ta_info['frompartner']) isa06sender = isa06sender.ljust(15) #add spaces; is fixed length gs02sender = self.ta_info.get('GS02', self.ta_info['frompartner']) #also for ISA08 and GS03 isa08receiver = self.ta_info.get('ISA08', self.ta_info['topartner']) isa08receiver = isa08receiver.ljust(15) #add spaces; is fixed length gs03receiver = self.ta_info.get('GS03', self.ta_info['topartner']) #build the envelope segments (that is, the tree from which the segments will be generated) self.out.put( { 'BOTSID': 'ISA', 'ISA01': self.ta_info['ISA01'], 'ISA02': self.ta_info['ISA02'], 'ISA03': self.ta_info['ISA03'], 'ISA04': self.ta_info['ISA04'], 'ISA05': self.ta_info['ISA05'], 'ISA06': isa06sender, 'ISA07': self.ta_info['ISA07'], 'ISA08': isa08receiver, 'ISA09': isa09date, 'ISA10': botslib.strftime('%H%M'), 'ISA11': self.ta_info[ 'ISA11'], #if ISA version > 00403, replaced by reprtion separator 'ISA12': self.ta_info['version'], 'ISA13': self.ta_info['reference'], 'ISA14': self.ta_info['ISA14'], 'ISA15': testindicator }, strip=False ) #MIND: strip=False: ISA fields shoudl not be stripped as it is soemwhat like fixed-length self.out.put({'BOTSID': 'ISA'}, { 'BOTSID': 'IEA', 'IEA01': '1', 'IEA02': self.ta_info['reference'] }) gs08messagetype = self.ta_info['messagetype'][3:] if gs08messagetype[:6] < '004010': gs04date = botslib.strftime('%y%m%d') else: gs04date = botslib.strftime('%Y%m%d') self.out.put({'BOTSID': 'ISA'}, { 'BOTSID': 'GS', 'GS01': self.ta_info['functionalgroup'], 'GS02': gs02sender, 'GS03': gs03receiver, 'GS04': gs04date, 'GS05': botslib.strftime('%H%M'), 'GS06': self.ta_info['reference'], 'GS07': self.ta_info['GS07'], 'GS08': gs08messagetype }) self.out.put({'BOTSID': 'ISA'}, {'BOTSID': 'GS'}, { 'BOTSID': 'GE', 'GE01': self.ta_info['nrmessages'], 'GE02': self.ta_info['reference'] }) #dummy segment; is not used #user exit botslib.tryrunscript(self.userscript, self.scriptname, 'envelopecontent', ta_info=self.ta_info, out=self.out) #convert the tree into segments; here only the UNB is written (first segment) self.out.checkmessage(self.out.root, self.out.defmessage) self.out.checkforerrorlist() self.out.tree2records(self.out.root) #start doing the actual writing: tofile = botslib.opendata(self.ta_info['filename'], 'wb', self.ta_info['charset']) isa_string = self.out.record2string(self.out.lex_records[0:1]) #ISA has the used separators at certain positions. Normally bots would give errors for this (can not use sep as data) or compress these aways. So this is hardcoded. if self.ta_info['version'] < '00403': isa_string = isa_string[:103] + self.ta_info[ 'field_sep'] + self.ta_info['sfield_sep'] + isa_string[103:] else: isa_string = isa_string[:82] + self.ta_info[ 'reserve'] + isa_string[83:103] + self.ta_info[ 'field_sep'] + self.ta_info['sfield_sep'] + isa_string[103:] tofile.write(isa_string) #write ISA tofile.write(self.out.record2string( self.out.lex_records[1:2])) #write GS self.writefilelist(tofile) tofile.write(self.out.record2string( self.out.lex_records[2:])) #write GE and IEA tofile.close()
def run(self): if not self.ta_info['topartner'] or not self.ta_info['frompartner']: raise botslib.OutMessageError( _(u'In enveloping "frompartner" or "topartner" unknown: "%(ta_info)s".' ), {'ta_info': self.ta_info}) self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) #prepare data for envelope if botsglobal.ini.getboolean('settings', 'interchangecontrolperpartner', False): self.ta_info['reference'] = unicode( botslib.unique('stxcounter_' + self.ta_info['topartner'])) else: self.ta_info['reference'] = unicode( botslib.unique('stxcounter_' + self.ta_info['frompartner'])) #build the envelope segments (that is, the tree from which the segments will be generated) self.out.put({ 'BOTSID': 'STX', 'STDS1': self.ta_info['STX.STDS1'], 'STDS2': self.ta_info['STX.STDS2'], 'FROM.01': self.ta_info['frompartner'], 'UNTO.01': self.ta_info['topartner'], 'TRDT.01': botslib.strftime('%y%m%d'), 'TRDT.02': botslib.strftime('%H%M%S'), 'SNRF': self.ta_info['reference'] }) if self.ta_info['STX.FROM.02']: self.out.put({ 'BOTSID': 'STX', 'FROM.02': self.ta_info['STX.FROM.02'] }) if self.ta_info['STX.UNTO.02']: self.out.put({ 'BOTSID': 'STX', 'UNTO.02': self.ta_info['STX.UNTO.02'] }) if self.ta_info['STX.APRF']: self.out.put({'BOTSID': 'STX', 'APRF': self.ta_info['STX.APRF']}) if self.ta_info['STX.PRCD']: self.out.put({'BOTSID': 'STX', 'PRCD': self.ta_info['STX.PRCD']}) self.out.put({'BOTSID': 'STX'}, { 'BOTSID': 'END', 'NMST': self.ta_info['nrmessages'] }) #dummy segment; is not used #user exit botslib.tryrunscript(self.userscript, self.scriptname, 'envelopecontent', ta_info=self.ta_info, out=self.out) #convert the tree into segments; here only the STX is written (first segment) self.out.checkmessage(self.out.root, self.out.defmessage) self.out.checkforerrorlist() self.out.tree2records(self.out.root) #start doing the actual writing: tofile = botslib.opendata(self.ta_info['filename'], 'wb', self.ta_info['charset']) tofile.write(self.out.record2string(self.out.lex_records[0:1])) self.writefilelist(tofile) tofile.write(self.out.record2string(self.out.lex_records[1:2])) tofile.close()
def run(self): if not self.ta_info['topartner'] or not self.ta_info['frompartner']: raise botslib.OutMessageError( _(u'In enveloping "frompartner" or "topartner" unknown: "%(ta_info)s".' ), {'ta_info': self.ta_info}) self._openoutenvelope() self.ta_info.update(self.out.ta_info) botslib.tryrunscript(self.userscript, self.scriptname, 'ta_infocontent', ta_info=self.ta_info) #version dependent enveloping if self.ta_info['version'] < '4': date = botslib.strftime('%y%m%d') reserve = ' ' else: date = botslib.strftime('%Y%m%d') reserve = self.ta_info['reserve'] #UNB reference is counter is per sender or receiver if botsglobal.ini.getboolean('settings', 'interchangecontrolperpartner', False): self.ta_info['reference'] = unicode( botslib.unique('unbcounter_' + self.ta_info['topartner'])) else: self.ta_info['reference'] = unicode( botslib.unique('unbcounter_' + self.ta_info['frompartner'])) #testindicator is more complex: if self.ta_info['testindicator'] and self.ta_info[ 'testindicator'] != '0': #first check value from ta; do not use default testindicator = '1' elif self.ta_info['UNB.0035'] != '0': #than check values from grammar testindicator = '1' else: testindicator = '' #build the envelope segments (that is, the tree from which the segments will be generated) self.out.put({ 'BOTSID': 'UNB', 'S001.0001': self.ta_info['charset'], 'S001.0002': self.ta_info['version'], 'S002.0004': self.ta_info['frompartner'], 'S003.0010': self.ta_info['topartner'], 'S004.0017': date, 'S004.0019': botslib.strftime('%H%M'), '0020': self.ta_info['reference'] }) #the following fields are conditional; do not write these when empty string (separator compression does take empty strings into account) for field in ('S001.0080', 'S001.0133', 'S002.0007', 'S002.0008', 'S002.0042', 'S003.0007', 'S003.0014', 'S003.0046', 'S005.0022', 'S005.0025', '0026', '0029', '0031', '0032'): if self.ta_info['UNB.' + field]: self.out.put({ 'BOTSID': 'UNB', field: self.ta_info['UNB.' + field] }) if testindicator: self.out.put({'BOTSID': 'UNB', '0035': testindicator}) self.out.put({'BOTSID': 'UNB'}, { 'BOTSID': 'UNZ', '0036': self.ta_info['nrmessages'], '0020': self.ta_info['reference'] }) #dummy segment; is not used #user exit botslib.tryrunscript(self.userscript, self.scriptname, 'envelopecontent', ta_info=self.ta_info, out=self.out) #convert the tree into segments; here only the UNB is written (first segment) self.out.checkmessage(self.out.root, self.out.defmessage) self.out.checkforerrorlist() self.out.tree2records(self.out.root) #start doing the actual writing: tofile = botslib.opendata(self.ta_info['filename'], 'wb', self.ta_info['charset']) if self.ta_info['forceUNA'] or self.ta_info['charset'] != 'UNOA': tofile.write('UNA' + self.ta_info['sfield_sep'] + self.ta_info['field_sep'] + self.ta_info['decimaal'] + self.ta_info['escape'] + reserve + self.ta_info['record_sep'] + self.ta_info['add_crlfafterrecord_sep']) tofile.write(self.out.record2string(self.out.lex_records[0:1])) self.writefilelist(tofile) tofile.write(self.out.record2string(self.out.lex_records[1:2])) tofile.close()
def _formatfield(self, value, grammarfield, record): ''' Input: value (as a string) and field definition. Some parameters of self.syntax are used: decimaal Format is checked and converted (if needed). return the formatted value ''' #~ value = value[:] if grammarfield[BFORMAT] == 'A': if grammarfield[ FORMAT] == 'AR': #if field format is alfanumeric right aligned value = value.rjust(grammarfield[MINLENGTH]) else: value = value.ljust( grammarfield[MINLENGTH] ) #add spaces (left, because A-field is right aligned) valuelength = len(value) if valuelength > grammarfield[LENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" too big (max $max): "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH], max=grammarfield[LENGTH]) elif grammarfield[BFORMAT] == 'D': try: lenght = len(value) if lenght == 6: time.strptime(value, '%y%m%d') elif lenght == 8: time.strptime(value, '%Y%m%d') else: raise ValueError except ValueError: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" no valid date: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) valuelength = len(value) if valuelength > grammarfield[LENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" too big (max $max): "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH], max=grammarfield[LENGTH]) if valuelength < grammarfield[MINLENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" too small (min $min): "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH], min=grammarfield[MINLENGTH]) elif grammarfield[BFORMAT] == 'T': try: lenght = len(value) if lenght == 4: time.strptime(value, '%H%M') elif lenght == 6: time.strptime(value, '%H%M%S') else: #lenght==8: #tsja...just use first part of field raise ValueError except ValueError: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" no valid time: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) valuelength = len(value) if valuelength > grammarfield[LENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" too big (max $max): "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH], max=grammarfield[LENGTH]) if valuelength < grammarfield[MINLENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" too small (min $min): "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH], min=grammarfield[MINLENGTH]) else: #numerics if value or isinstance( self, fixed ): #if empty string for non-fixed: just return. Later on, ta_info[stripemptyfield] determines what to do with them if not value: #see last if; if a numerical fixed field has content '' , change this to '0' (init) value = '0' else: value = value.strip() if value[0] == '-': minussign = '-' absvalue = value[1:] else: minussign = '' absvalue = value digits, decimalsign, decimals = absvalue.partition('.') if not digits and not decimals: # and decimalsign: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" numerical format not valid: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) if not digits: digits = '0' lengthcorrection = 0 #for some formats (if self.ta_info['lengthnumericbare']=True; eg edifact) length is calculated without decimal sing and/or minus sign. if grammarfield[ BFORMAT] == 'R': #floating point: use all decimals received if self.ta_info['lengthnumericbare']: if minussign: lengthcorrection += 1 if decimalsign: lengthcorrection += 1 try: value = str( decimal.Decimal(minussign + digits + decimalsign + decimals).quantize( decimal.Decimal(10)** -len(decimals))) except: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" numerical format not valid: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) value = value.zfill(grammarfield[MINLENGTH] + lengthcorrection) value = value.replace( '.', self.ta_info['decimaal'], 1) #replace '.' by required decimal sep. elif grammarfield[BFORMAT] == 'N': #fixed decimals; round if self.ta_info['lengthnumericbare']: if minussign: lengthcorrection += 1 if grammarfield[DECIMALS]: lengthcorrection += 1 try: value = str( decimal.Decimal(minussign + digits + decimalsign + decimals).quantize( decimal.Decimal(10)** -grammarfield[DECIMALS])) except: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" numerical format not valid: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) value = value.zfill(grammarfield[MINLENGTH] + lengthcorrection) value = value.replace( '.', self.ta_info['decimaal'], 1) #replace '.' by required decimal sep. elif grammarfield[BFORMAT] == 'I': #implicit decimals if self.ta_info['lengthnumericbare']: if minussign: lengthcorrection += 1 try: d = decimal.Decimal( minussign + digits + decimalsign + decimals) * 10**grammarfield[DECIMALS] except: raise botslib.OutMessageError(_( u'record "$mpath" field "$field" numerical format not valid: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) value = str(d.quantize(NODECIMAL)) value = value.zfill(grammarfield[MINLENGTH] + lengthcorrection) if len(value) - lengthcorrection > grammarfield[LENGTH]: raise botslib.OutMessageError(_( u'record "$mpath" field "$field": content to large: "$content".' ), field=grammarfield[ID], content=value, mpath=record[MPATH]) return value