def mergemessages(run): names_envelope_criteria = ('editype', 'messagetype', 'frompartner', 'topartner', 'testindicator', 'charset', 'contenttype', 'envelope', 'rsrv3') merge_yes = {} merge_no = [] #can be non-unique: as a list #walk over run.translated; sort by envelope-criteria in 2 dicts for translated in run.translated: filename = translated.get('filename') infilename = translated.get('infilename') nrmessages = translated.get('nrmessages') if translated.get('merge'): env_criteria = tuple( translated.get(field) for field in names_envelope_criteria) if env_criteria in merge_yes: merge_yes[env_criteria][0].append(filename) merge_yes[env_criteria][1].append(infilename) merge_yes[env_criteria][2] += nrmessages else: merge_yes[env_criteria] = [[filename], [infilename], nrmessages] else: ta_info = dict((field, translated.get(field)) for field in names_envelope_criteria) ta_info['nrmessages'] = nrmessages merge_no.append((ta_info, [filename], [infilename])) #envelope for env_criteria, rest_of_info in merge_yes.iteritems(): ta_info = dict(zip(names_envelope_criteria, env_criteria)) ta_info['filename'] = transform.unique( 'bots_file_name') #create filename for enveloped message ta_info['nrmessages'] = rest_of_info[2] ta_info['infilename'] = rest_of_info[ 1] #for reference: list of infilenames ta_info['error'] = '' try: envelope.envelope(ta_info, rest_of_info[0]) except: txt = botslib.txtexc() ta_info['error'] = txt.strip() finally: run.outgoing.append(ta_info) for ta_info, filenames, infilenames in merge_no: ta_info['filename'] = transform.unique( 'bots_file_name') #create filename for enveloped message ta_info[ 'infilename'] = infilenames #for reference: list of infilenames ta_info['error'] = '' try: envelope.envelope(ta_info, filenames) except: txt = botslib.txtexc() ta_info['error'] = txt.strip() finally: run.outgoing.append(ta_info)
def mergemessages(run): names_envelope_criteria = ('editype', 'messagetype', 'frompartner', 'topartner', 'testindicator', 'charset', 'contenttype', 'envelope', 'rsrv3') merge_yes = {} merge_no = [] # can be non-unique: as a list #walk over run.translated; sort by envelope-criteria in 2 dicts for translated in run.translated: filename = translated.get('filename') infilename = translated.get('infilename') nrmessages = translated.get('nrmessages') if translated.get('merge'): env_criteria = tuple(translated.get(field) for field in names_envelope_criteria) if env_criteria in merge_yes: merge_yes[env_criteria][0].append(filename) merge_yes[env_criteria][1].append(infilename) merge_yes[env_criteria][2] += nrmessages else: merge_yes[env_criteria] = [[filename], [infilename], nrmessages] else: ta_info = dict((field, translated.get(field)) for field in names_envelope_criteria) ta_info['nrmessages'] = nrmessages merge_no.append((ta_info, [filename], [infilename])) #envelope for env_criteria, rest_of_info in merge_yes.items(): ta_info = dict(zip(names_envelope_criteria, env_criteria)) ta_info['filename'] = transform.unique('bots_file_name') # create filename for enveloped message ta_info['nrmessages'] = rest_of_info[2] ta_info['infilename'] = rest_of_info[1] # for reference: list of infilenames ta_info['error'] = '' try: envelope.envelope(ta_info, rest_of_info[0]) except: txt = botslib.txtexc() ta_info['error'] = txt.strip() finally: run.outgoing.append(ta_info) for ta_info, filenames, infilenames in merge_no: ta_info['filename'] = transform.unique('bots_file_name') # create filename for enveloped message ta_info['infilename'] = infilenames # for reference: list of infilenames ta_info['error'] = '' try: envelope.envelope(ta_info, filenames) except: txt = botslib.txtexc() ta_info['error'] = txt.strip() finally: run.outgoing.append(ta_info)
def read_incoming(run): outputdir = botslib.join(run.inpath,run.infilename) filelist = sorted(filename for filename in glob.iglob(outputdir) if os.path.isfile(filename)) for infilename in filelist: try: filename = transform.unique('bots_file_name') abs_filename = botslib.abspathdata(filename) shutil.copy(infilename,abs_filename) #move if to be delted except: txt = botslib.txtexc() else: txt = '' #no errors finally: run.incoming.append({'infilename':infilename,'filename':filename,'error':txt,'editype':run.translation['editype'],'messagetype':run.translation['messagetype']})
def translate(run): for messagedict in run.incoming: try: #read whole edi-file: read, parse and made into a inmessage-object. Message is represented as a tree (inmessage.root is the root of the tree). edifile = inmessage.parse_edi_file(frompartner='', topartner='', filename=messagedict['filename'], messagetype=run.translation['messagetype'], testindicator='', editype=run.translation['editype'], charset='', alt='', fromchannel='', idroute='', command='') edifile.checkforerrorlist() #no exception if infile has been lexed and parsed OK else raises an error #~ if int(routedict['translateind']) == 3: #parse & passthrough; file is parsed, partners are known, no mapping, does confirm. #~ raise botslib.GotoException('dummy') #~ continue #file is parsed; no errors. no translation #edifile.ta_info contains info about incoming file: QUERIES, charset etc for inn_splitup in edifile.nextmessage(): #splitup messages in parsed edifile try: #inn_splitup.ta_info: parameters from inmessage.parse_edi_file(), syntax-information and parse-information number_of_loops_with_same_alt = 0 while 1: #continue as long as there are (alt-)translations #lookup the translation************************ tscript,toeditype,tomessagetype = 'orders_edifact2xml' ,'xml','orders' if 'tscript' in run.translation: tscript = run.translation['tscript'] toeditype = run.translation['toeditype'] tomessagetype = run.translation['tomessagetype'] else: tscript,toeditype,tomessagetype = botslib.lookup_translation(fromeditype=inn_splitup.ta_info['editype'], frommessagetype=inn_splitup.ta_info['messagetype'], frompartner=inn_splitup.ta_info['frompartner'], topartner=inn_splitup.ta_info['topartner'], alt=inn_splitup.ta_info['alt']) #run mapping script************************ filename_translated = transform.unique('bots_file_name') out_translated = outmessage.outmessage_init(editype=toeditype, messagetype=tomessagetype, filename=filename_translated, reference=transform.unique('messagecounter'), statust=OK, divtext=tscript) #make outmessage object #~ botsglobal.logger.debug(_(u'Mappingscript "%(tscript)s" translates messagetype "%(messagetype)s" to messagetype "%(tomessagetype)s".'), #~ {'tscript':tscript,'messagetype':inn_splitup.ta_info['messagetype'],'tomessagetype':out_translated.ta_info['messagetype']}) translationscript,scriptfilename = botslib.botsimport('mappings',inn_splitup.ta_info['editype'],tscript) #import mappingscript alt_from_previous_run = inn_splitup.ta_info['alt'] #needed to check for infinite loop doalttranslation = botslib.runscript(translationscript,scriptfilename,'main',inn=inn_splitup,out=out_translated) botsglobal.logger.debug(_(u'Mappingscript "%(tscript)s" finished.'),{'tscript':tscript}) #manipulate for some attributes after mapping script if 'topartner' not in out_translated.ta_info: #out_translated does not contain values from run...... out_translated.ta_info['topartner'] = inn_splitup.ta_info['topartner'] if 'botskey' in inn_splitup.ta_info: inn_splitup.ta_info['reference'] = inn_splitup.ta_info['botskey'] if 'botskey' in out_translated.ta_info: #out_translated does not contain values from run...... out_translated.ta_info['reference'] = out_translated.ta_info['botskey'] #check the value received from the mappingscript to determine what to do in this while-loop. Handling of chained trasnlations. if doalttranslation is None: #translation(s) are done; handle out-message out_translated.writeall() #write result of translation. #make translated record (if all is OK) translated_dict = inn_splitup.ta_info.copy() translated_dict.update(messagedict) translated_dict.update(out_translated.ta_info) run.translated.append(translated_dict) del out_translated break #break out of while loop elif isinstance(doalttranslation,dict): #some extended cases; a dict is returned that contains 'instructions' for some type of chained translations if 'type' not in doalttranslation or 'alt' not in doalttranslation: raise botslib.BotsError(_(u"Mappingscript returned '%(alt)s'. This dict should not have 'type' and 'alt'."),{'alt':doalttranslation}) if alt_from_previous_run == doalttranslation['alt']: number_of_loops_with_same_alt += 1 else: number_of_loops_with_same_alt = 0 if doalttranslation['type'] == u'out_as_inn': #do chained translation: use the out-object as inn-object, new out-object #use case: detected error in incoming file; use out-object to generate warning email handle_out_message(out_translated,ta_translated) inn_splitup = out_translated #out-object is now inn-object if isinstance(inn_splitup,outmessage.fixed): #for fixed: strip all values in node inn_splitup.root.stripnode() inn_splitup.ta_info['alt'] = doalttranslation['alt'] #get the alt-value for the next chained translation if not 'frompartner' in inn_splitup.ta_info: inn_splitup.ta_info['frompartner'] = '' if not 'topartner' in inn_splitup.ta_info: inn_splitup.ta_info['topartner'] = '' inn_splitup.ta_info.pop('statust') elif doalttranslation['type'] == u'no_check_on_infinite_loop': #do chained translation: allow many loops wit hsame alt-value. #mapping script will have to handle this correctly. number_of_loops_with_same_alt = 0 handle_out_message(out_translated,ta_translated) del out_translated inn_splitup.ta_info['alt'] = doalttranslation['alt'] #get the alt-value for the next chained translation else: #there is nothing else raise botslib.BotsError(_(u'Mappingscript returned dict with an unknown "type": "%(doalttranslation)s".'),{'doalttranslation':doalttranslation}) else: #note: this includes alt '' (empty string) if alt_from_previous_run == doalttranslation: number_of_loops_with_same_alt += 1 else: number_of_loops_with_same_alt = 0 #do normal chained translation: same inn-object, new out-object out_translated.writeall() del out_translated inn_splitup.ta_info['alt'] = doalttranslation #get the alt-value for the next chained translation if number_of_loops_with_same_alt > 10: raise botslib.BotsError(_(u'Mappingscript returns same alt value over and over again (infinite loop?). Alt: "%(doalttranslation)s".'),{'doalttranslation':doalttranslation}) #end of while-loop (trans********************************************************************************** #exceptions file_out-level: exception in mappingscript or writing of out-file except: #2 modes: either every error leads to skipping of whole infile (old mode) or errors in mappingscript/outfile only affect that branche txt = botslib.txtexc() print txt messagedict['error'] += txt.strip() else: pass #~ print 'succes' #exceptions file_in-level except botslib.GotoException: #edi-file is OK, file is passed-through after parsing. #~ edifile.handleconfirm(ta_fromfile,error=False) #~ botsglobal.logger.debug(_(u'Parse & passthrough for input file "%(filename)s".'),row) txt = botslib.txtexc() print txt except: txt = botslib.txtexc() messagedict['error'] += txt.strip() #~ edifile.handleconfirm(ta_fromfile,error=True) #~ botsglobal.logger.debug(u'Error in translating input file "%(filename)s":\n%(msg)s',{'filename':row['filename'],'msg':txt}) else: pass
def translate(run): for messagedict in run.incoming: try: #read whole edi-file: read, parse and made into a inmessage-object. Message is represented as a tree (inmessage.root is the root of the tree). edifile = inmessage.parse_edi_file(frompartner='', topartner='', filename=messagedict['filename'], messagetype=run.translation['messagetype'], testindicator='', editype=run.translation['editype'], charset='', alt='', fromchannel='', idroute='', command='') edifile.checkforerrorlist() #no exception if infile has been lexed and parsed OK else raises an error #~ if int(routedict['translateind']) == 3: #parse & passthrough; file is parsed, partners are known, no mapping, does confirm. #~ raise botslib.GotoException('dummy') #~ continue #file is parsed; no errors. no translation #edifile.ta_info contains info about incoming file: QUERIES, charset etc for inn_splitup in edifile.nextmessage(): #splitup messages in parsed edifile try: #inn_splitup.ta_info: parameters from inmessage.parse_edi_file(), syntax-information and parse-information number_of_loops_with_same_alt = 0 while True: #continue as long as there are (alt-)translations #lookup the translation************************ tscript,toeditype,tomessagetype = 'orders_edifact2xml' ,'xml','orders' if 'tscript' in run.translation: tscript = run.translation['tscript'] toeditype = run.translation['toeditype'] tomessagetype = run.translation['tomessagetype'] else: tscript,toeditype,tomessagetype = botslib.lookup_translation(fromeditype=inn_splitup.ta_info['editype'], frommessagetype=inn_splitup.ta_info['messagetype'], frompartner=inn_splitup.ta_info['frompartner'], topartner=inn_splitup.ta_info['topartner'], alt=inn_splitup.ta_info['alt']) #run mapping script************************ filename_translated = transform.unique('bots_file_name') out_translated = outmessage.outmessage_init(editype=toeditype, messagetype=tomessagetype, filename=filename_translated, reference=transform.unique('messagecounter'), statust=OK, divtext=tscript) #make outmessage object #~ botsglobal.logger.debug(_('Mappingscript "%(tscript)s" translates messagetype "%(messagetype)s" to messagetype "%(tomessagetype)s".'), #~ {'tscript':tscript,'messagetype':inn_splitup.ta_info['messagetype'],'tomessagetype':out_translated.ta_info['messagetype']}) translationscript,scriptfilename = botslib.botsimport('mappings',inn_splitup.ta_info['editype'],tscript) #import mappingscript alt_from_previous_run = inn_splitup.ta_info['alt'] #needed to check for infinite loop doalttranslation = botslib.runscript(translationscript,scriptfilename,'main',inn=inn_splitup,out=out_translated) botsglobal.logger.debug(_('Mappingscript "%(tscript)s" finished.'),{'tscript':tscript}) #manipulate for some attributes after mapping script if 'topartner' not in out_translated.ta_info: #out_translated does not contain values from run...... out_translated.ta_info['topartner'] = inn_splitup.ta_info['topartner'] if 'botskey' in inn_splitup.ta_info: inn_splitup.ta_info['reference'] = inn_splitup.ta_info['botskey'] if 'botskey' in out_translated.ta_info: #out_translated does not contain values from run...... out_translated.ta_info['reference'] = out_translated.ta_info['botskey'] #check the value received from the mappingscript to determine what to do in this while-loop. Handling of chained trasnlations. if doalttranslation is None: #translation(s) are done; handle out-message out_translated.writeall() #write result of translation. #make translated record (if all is OK) translated_dict = inn_splitup.ta_info.copy() translated_dict.update(messagedict) translated_dict.update(out_translated.ta_info) run.translated.append(translated_dict) del out_translated break #break out of while loop elif isinstance(doalttranslation,dict): #some extended cases; a dict is returned that contains 'instructions' for some type of chained translations if 'type' not in doalttranslation or 'alt' not in doalttranslation: raise botslib.BotsError(_('Mappingscript returned "%(alt)s". This dict should not have "type" and "alt".'),{'alt':doalttranslation}) if alt_from_previous_run == doalttranslation['alt']: number_of_loops_with_same_alt += 1 else: number_of_loops_with_same_alt = 0 if doalttranslation['type'] == 'out_as_inn': #do chained translation: use the out-object as inn-object, new out-object #use case: detected error in incoming file; use out-object to generate warning email handle_out_message(out_translated,ta_translated) inn_splitup = out_translated #out-object is now inn-object if isinstance(inn_splitup,outmessage.fixed): #for fixed: strip all values in node inn_splitup.root.stripnode() inn_splitup.ta_info['alt'] = doalttranslation['alt'] #get the alt-value for the next chained translation if not 'frompartner' in inn_splitup.ta_info: inn_splitup.ta_info['frompartner'] = '' if not 'topartner' in inn_splitup.ta_info: inn_splitup.ta_info['topartner'] = '' inn_splitup.ta_info.pop('statust') elif doalttranslation['type'] == 'no_check_on_infinite_loop': #do chained translation: allow many loops wit hsame alt-value. #mapping script will have to handle this correctly. number_of_loops_with_same_alt = 0 handle_out_message(out_translated,ta_translated) del out_translated inn_splitup.ta_info['alt'] = doalttranslation['alt'] #get the alt-value for the next chained translation else: #there is nothing else raise botslib.BotsError(_('Mappingscript returned dict with an unknown "type": "%(doalttranslation)s".'),{'doalttranslation':doalttranslation}) else: #note: this includes alt '' (empty string) if alt_from_previous_run == doalttranslation: number_of_loops_with_same_alt += 1 else: number_of_loops_with_same_alt = 0 #do normal chained translation: same inn-object, new out-object out_translated.writeall() del out_translated inn_splitup.ta_info['alt'] = doalttranslation #get the alt-value for the next chained translation if number_of_loops_with_same_alt > 10: raise botslib.BotsError(_('Mappingscript returns same alt value over and over again (infinite loop?). Alt: "%(doalttranslation)s".'),{'doalttranslation':doalttranslation}) #end of while-loop (trans********************************************************************************** #exceptions file_out-level: exception in mappingscript or writing of out-file except: #2 modes: either every error leads to skipping of whole infile (old mode) or errors in mappingscript/outfile only affect that branche txt = botslib.txtexc() print(txt) messagedict['error'] += txt.strip() else: pass #exceptions file_in-level except botslib.GotoException: #edi-file is OK, file is passed-through after parsing. #~ edifile.handleconfirm(ta_fromfile,error=False) #~ botsglobal.logger.debug(_('Parse & passthrough for input file "%(filename)s".'),row) txt = botslib.txtexc() print(txt) except: txt = botslib.txtexc() messagedict['error'] += txt.strip() #~ edifile.handleconfirm(ta_fromfile,error=True) #~ botsglobal.logger.debug('Error in translating input file "%(filename)s":\n%(msg)s',{'filename':row['filename'],'msg':txt}) else: pass