def datemask(value, frommask, tomask): ''' value is formatted according as in frommask; returned is the value formatted according to tomask. example: datemask('12/31/2012','MM/DD/YYYY','YYYYMMDD') returns '20121231' ''' if not value: return value convdict = collections.defaultdict(list) for key, val in zip(frommask, value): convdict[key].append(val) #convdict contains for example: {'Y': [u'2', u'0', u'1', u'2'], 'M': [u'1', u'2'], 'D': [u'3', u'1'], '/': [u'/', u'/']} terug = '' try: # alternative implementation: return ''.join([convdict.get(c,[c]).pop(0) for c in tomask]) #very short, but not faster.... for char in tomask: terug += convdict.get(char, [char]).pop( 0 ) #for this character, lookup value in convdict (a list). pop(0) this list: get first member of list, and drop it. If char not in convdict as key, use char itself. except: raise botslib.BotsError(_( u'Error in function datamask("$value", "$frommask", "$tomask").'), value=value, frommask=frommask, tomask=tomask) return terug
def get(self, section, option, default=''): try: return ConfigParser.SafeConfigParser.get(self, section, option) except: #if there is no such section,option if default == '': raise botslib.BotsError(_( u'No entry "$entry" in section "$section" in "bots.ini".'), entry=option, section=section) return default
def get(self, section, option, default=''): if self.has_option(section, option): return ConfigParser.RawConfigParser.get(self, section, option) elif default == '': raise botslib.BotsError( u'No entry "%(option)s" in section "%(section)s" in "bots.ini".', { 'option': option, 'section': section }) else: return default
def dateformat(date): ''' for edifact: return right format code for the date. ''' if not date: return None if len(date) == 8: return '102' if len(date) == 12: return '203' if len(date) == 16: return '718' raise botslib.BotsError(_(u'No valid edifact date format for "%(date)s".'), {'date': date})
def translate(startstatus=TRANSLATE, endstatus=TRANSLATED, idroute=''): ''' translates edifiles in one or more edimessages. reads and parses edifiles that have to be translated. tries to split files into messages (using 'nextmessage' of grammar); if no splitting: edifile is one message. searches the right translation in translate-table; runs the mapping-script for the translation; Function takes db-ta with status=TRANSLATE->PARSED->SPLITUP->TRANSLATED ''' #select edifiles to translate; fill ta-object for row in botslib.query( u'''SELECT idta,frompartner,topartner,filename,messagetype,testindicator,editype,charset,alt,fromchannel FROM ta WHERE idta>%(rootidta)s AND status=%(status)s AND statust=%(statust)s AND idroute=%(idroute)s ''', { 'status': startstatus, 'statust': OK, 'idroute': idroute, 'rootidta': botslib.get_minta4query() }): try: ta_fromfile = botslib.OldTransaction(row['idta']) #TRANSLATE ta ta_parsedfile = ta_fromfile.copyta( status=PARSED) #copy TRANSLATE to PARSED ta #read whole edi-file: read, parse and made into a inmessage-object. Message is represented a a tree. edifile = inmessage.edifromfile(frompartner=row['frompartner'], topartner=row['topartner'], filename=row['filename'], messagetype=row['messagetype'], testindicator=row['testindicator'], editype=row['editype'], charset=row['charset'], alt=row['alt'], fromchannel=row['fromchannel'], idroute=idroute) botsglobal.logger.debug( u'start read and parse input file "%s" editype "%s" messagetype "%s".', row['filename'], row['editype'], row['messagetype']) for inn in edifile.nextmessage( ): #for each message in the edifile: #inn.ta_info: parameters from inmessage.edifromfile(), syntax-information and parse-information ta_frommes = ta_parsedfile.copyta( status=SPLITUP) #copy PARSED to SPLITUP ta inn.ta_info[ 'idta_fromfile'] = ta_fromfile.idta #for confirmations in user script; used to give idta of 'confirming message' ta_frommes.update( **inn.ta_info ) #update ta-record SLIPTUP with info from message content and/or grammar while 1: #whileloop continues as long as there are alt-translations #************select parameters for translation(script): for row2 in botslib.query( u'''SELECT tscript,tomessagetype,toeditype FROM translate WHERE frommessagetype = %(frommessagetype)s AND fromeditype = %(fromeditype)s AND active=%(booll)s AND alt=%(alt)s AND (frompartner_id IS NULL OR frompartner_id=%(frompartner)s OR frompartner_id in (SELECT to_partner_id FROM partnergroup WHERE from_partner_id=%(frompartner)s )) AND (topartner_id IS NULL OR topartner_id=%(topartner)s OR topartner_id in (SELECT to_partner_id FROM partnergroup WHERE from_partner_id=%(topartner)s )) ORDER BY alt DESC, CASE WHEN frompartner_id IS NULL THEN 1 ELSE 0 END, frompartner_id , CASE WHEN topartner_id IS NULL THEN 1 ELSE 0 END, topartner_id ''', { 'frommessagetype': inn.ta_info['messagetype'], 'fromeditype': inn.ta_info['editype'], 'alt': inn.ta_info['alt'], 'frompartner': inn.ta_info['frompartner'], 'topartner': inn.ta_info['topartner'], 'booll': True }): break #escape if found; we need only the first - ORDER BY in the query else: #no translation record is found raise botslib.TranslationNotFoundError( _(u'Editype "$editype", messagetype "$messagetype", frompartner "$frompartner", topartner "$topartner", alt "$alt"' ), editype=inn.ta_info['editype'], messagetype=inn.ta_info['messagetype'], frompartner=inn.ta_info['frompartner'], topartner=inn.ta_info['topartner'], alt=inn.ta_info['alt']) ta_tomes = ta_frommes.copyta( status=endstatus) #copy SPLITUP to TRANSLATED ta tofilename = str(ta_tomes.idta) tscript = row2['tscript'] tomessage = outmessage.outmessage_init( messagetype=row2['tomessagetype'], editype=row2['toeditype'], filename=tofilename, reference=unique('messagecounter'), statust=OK, divtext=tscript) #make outmessage object #copy ta_info botsglobal.logger.debug( u'script "%s" translates messagetype "%s" to messagetype "%s".', tscript, inn.ta_info['messagetype'], tomessage.ta_info['messagetype']) translationscript, scriptfilename = botslib.botsimport( 'mappings', inn.ta_info['editype'] + '.' + tscript) #get the mapping-script doalttranslation = botslib.runscript(translationscript, scriptfilename, 'main', inn=inn, out=tomessage) botsglobal.logger.debug(u'script "%s" finished.', tscript) if 'topartner' not in tomessage.ta_info: #tomessage does not contain values from ta...... tomessage.ta_info['topartner'] = inn.ta_info[ 'topartner'] if tomessage.ta_info[ 'statust'] == DONE: #if indicated in user script the message should be discarded botsglobal.logger.debug( u'No output file because mapping script explicitly indicated this.' ) tomessage.ta_info['filename'] = '' tomessage.ta_info['status'] = DISCARD else: botsglobal.logger.debug( u'Start writing output file editype "%s" messagetype "%s".', tomessage.ta_info['editype'], tomessage.ta_info['messagetype']) tomessage.writeall( ) #write tomessage (result of translation). #problem is that not all values ta_tomes are know to to_message.... #~ print 'tomessage.ta_info',tomessage.ta_info ta_tomes.update( **tomessage.ta_info ) #update outmessage transaction with ta_info; #check the value received from the mappingscript to see if another traanslation needs to be done (chained translation) if doalttranslation is None: del tomessage break #break out of while loop; do no other translation elif isinstance(doalttranslation, dict): #some extended cases; a dict is returned that contains 'instructions' if 'type' not in doalttranslation: raise botslib.BotsError( "Mapping script returned dict. This dict does not have a 'type', like in eg: {'type:'out_as_inn', 'alt':'alt-value'}." ) if doalttranslation['type'] == u'out_as_inn': if 'alt' not in doalttranslation: raise botslib.BotsError( "Mapping script returned dict, type 'out_as_inn'. This dict does not have a 'alt'-value, like in eg: {'type:'out_as_inn', 'alt':'alt-value'}." ) inn = tomessage if isinstance(inn, outmessage.fixed): inn.root.stripnode() inn.ta_info['alt'] = doalttranslation[ 'alt'] #get the alt-value for the next chainded translation inn.ta_info.pop('statust') else: del tomessage inn.ta_info[ 'alt'] = doalttranslation #get the alt-value for the next chainded translation #end of while-loop # #~ print inn.ta_info ta_frommes.update( statust=DONE, **inn.ta_info ) #update db. inn.ta_info could be changed by script. Is this useful? del inn #exceptions file_in-level except: #~ edifile.handleconfirm(ta_fromfile,error=True) #only useful if errors are reported in acknowledgement (eg x12 997). Not used now. txt = botslib.txtexc() ta_parsedfile.failure() ta_parsedfile.update(statust=ERROR, errortext=txt) botsglobal.logger.debug( u'error in translating input file "%s":\n%s', row['filename'], txt) else: edifile.handleconfirm(ta_fromfile, error=False) ta_fromfile.update(statust=DONE) ta_parsedfile.update(statust=DONE, **edifile.confirminfo) botsglobal.logger.debug(u'translated input file "%s".', row['filename']) del edifile
def generalinit(configdir): #Set Configdir #Configdir MUST be importable. So configdir is relative to PYTHONPATH. Try several options for this import. try: #configdir outside bots-directory: import configdir.settings.py importnameforsettings = os.path.normpath( os.path.join(configdir, 'settings')).replace(os.sep, '.') settings = botslib.botsbaseimport(importnameforsettings) except ImportError: #configdir is in bots directory: import bots.configdir.settings.py try: importnameforsettings = os.path.normpath( os.path.join('bots', configdir, 'settings')).replace(os.sep, '.') settings = botslib.botsbaseimport(importnameforsettings) except ImportError: #set pythonpath to config directory first if not os.path.exists(configdir): #check if configdir exists. raise botslib.BotsError(_( u'In initilisation: path to configuration does not exists: "$path".' ), path=configdir) addtopythonpath = os.path.abspath(os.path.dirname(configdir)) #~ print 'add pythonpath for usersys',addtopythonpath moduletoimport = os.path.basename(configdir) sys.path.append(addtopythonpath) importnameforsettings = os.path.normpath( os.path.join(moduletoimport, 'settings')).replace(os.sep, '.') settings = botslib.botsbaseimport(importnameforsettings) #settings are accessed using botsglobal botsglobal.settings = settings #Find pathname configdir using imported settings.py. configdirectory = os.path.abspath(os.path.dirname(settings.__file__)) #Read configuration-file bots.ini. botsglobal.ini = BotsConfig() cfgfile = open(os.path.join(configdirectory, 'bots.ini'), 'r') botsglobal.ini.readfp(cfgfile) cfgfile.close() #Set usersys. #usersys MUST be importable. So usersys is relative to PYTHONPATH. Try several options for this import. usersys = botsglobal.ini.get('directories', 'usersys', 'usersys') try: #usersys outside bots-directory: import usersys importnameforusersys = os.path.normpath(usersys).replace(os.sep, '.') importedusersys = botslib.botsbaseimport(importnameforusersys) except ImportError: #usersys is in bots directory: import bots.usersys try: importnameforusersys = os.path.normpath( os.path.join('bots', usersys)).replace(os.sep, '.') importedusersys = botslib.botsbaseimport(importnameforusersys) except ImportError: #set pythonpath to usersys directory first if not os.path.exists(usersys): #check if configdir exists. raise botslib.BotsError(_( u'In initilisation: path to configuration does not exists: "$path".' ), path=usersys) addtopythonpath = os.path.abspath(os.path.dirname(usersys)) #???? moduletoimport = os.path.basename(usersys) #~ print 'add pythonpath for usersys',addtopythonpath sys.path.append(addtopythonpath) importnameforusersys = os.path.normpath(usersys).replace( os.sep, '.') importedusersys = botslib.botsbaseimport(importnameforusersys) #set directory settings in bots.ini************************************************************ botsglobal.ini.set('directories', 'botspath', botsglobal.settings.PROJECT_PATH) botsglobal.ini.set('directories', 'config', configdirectory) botsglobal.ini.set('directories', 'usersysabs', os.path.abspath( os.path.dirname(importedusersys.__file__)) ) #???Find pathname usersys using imported usersys botsglobal.usersysimportpath = importnameforusersys botssys = botsglobal.ini.get('directories', 'botssys', 'botssys') botsglobal.ini.set('directories', 'botssys', botslib.join(botssys)) botsglobal.ini.set('directories', 'data', botslib.join(botssys, 'data')) botslib.dirshouldbethere(botsglobal.ini.get('directories', 'data')) botsglobal.ini.set('directories', 'logging', botslib.join(botssys, 'logging')) botslib.dirshouldbethere(botsglobal.ini.get('directories', 'logging')) botsglobal.ini.set( 'directories', 'templates', botslib.join(botsglobal.ini.get('directories', 'usersysabs'), 'grammars/template/templates')) botsglobal.ini.set( 'directories', 'templateshtml', botslib.join(botsglobal.ini.get('directories', 'usersysabs'), 'grammars/templatehtml/templates')) #set values in setting.py********************************************************************** if botsglobal.ini.get( 'webserver', 'environment', 'development' ) == 'development': #values in bots.ini are also used in setting up cherrypy settings.DEBUG = True else: settings.DEBUG = False settings.TEMPLATE_DEBUG = settings.DEBUG #set paths in settings.py: #~ settings.FILE_UPLOAD_TEMP_DIR = os.path.join(settings.PROJECT_PATH, 'botssys/pluginsuploaded') #start initializing bots charsets initbotscharsets() #set environment for django to start*************************************************************************************************** os.environ['DJANGO_SETTINGS_MODULE'] = importnameforsettings initbotscharsets() botslib.settimeout(botsglobal.ini.getint('settings', 'globaltimeout', 10)) #
def _translate_one_file(row, routedict, endstatus, userscript, scriptname): ''' - read, lex, parse, make tree of nodes. - split up files into messages (using 'nextmessage' of grammar) - get mappingscript, start mappingscript. - write the results of translation (no enveloping yet) ''' try: ta_fromfile = botslib.OldTransaction(row['idta']) ta_parsed = ta_fromfile.copyta(status=PARSED) if row['filesize'] > botsglobal.ini.getint( 'settings', 'maxfilesizeincoming', 5000000): ta_parsed.update(filesize=row['filesize']) raise botslib.FileTooLargeError( _(u'File size of %(filesize)s is too big; option "maxfilesizeincoming" in bots.ini is %(maxfilesizeincoming)s.' ), { 'filesize': row['filesize'], 'maxfilesizeincoming': botsglobal.ini.getint('settings', 'maxfilesizeincoming', 5000000) }) botsglobal.logger.debug( _(u'Start translating file "%(filename)s" editype "%(editype)s" messagetype "%(messagetype)s".' ), row) #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=row['frompartner'], topartner=row['topartner'], filename=row['filename'], messagetype=row['messagetype'], testindicator=row['testindicator'], editype=row['editype'], charset=row['charset'], alt=row['alt'], fromchannel=row['fromchannel'], idroute=routedict['idroute'], command=routedict['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') #edifile.ta_info contains info: QUERIES, charset etc for inn_splitup in edifile.nextmessage( ): #splitup messages in parsed edifile try: ta_splitup = ta_parsed.copyta( status=SPLITUP, **inn_splitup.ta_info) #copy PARSED to SPLITUP ta #inn_splitup.ta_info: parameters from inmessage.parse_edi_file(), syntax-information and parse-information inn_splitup.ta_info[ 'idta_fromfile'] = ta_fromfile.idta #for confirmations in userscript; used to give idta of 'confirming message' inn_splitup.ta_info[ 'idta'] = ta_splitup.idta #for confirmations in userscript; used to give idta of 'confirming message' number_of_loops_with_same_alt = 0 while 1: #continue as long as there are (alt-)translations #lookup the translation************************ 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']) if not tscript: #no translation found in translate table; check if can find translation via user script if userscript and hasattr(userscript, 'gettranslation'): tscript, toeditype, tomessagetype = botslib.runscript( userscript, scriptname, 'gettranslation', idroute=routedict['idroute'], message=inn_splitup) if not tscript: raise botslib.TranslationNotFoundError( _(u'Translation not found for editype "%(editype)s", messagetype "%(messagetype)s", frompartner "%(frompartner)s", topartner "%(topartner)s", alt "%(alt)s".' ), inn_splitup.ta_info) inn_splitup.ta_info[ 'divtext'] = tscript #ifor reporting used mapping script to database (for display in GUI). #initialize new out-object************************* ta_translated = ta_splitup.copyta( status=endstatus ) #make ta for translated message (new out-ta) filename_translated = unicode(ta_translated.idta) out_translated = outmessage.outmessage_init( editype=toeditype, messagetype=tomessagetype, filename=filename_translated, reference=unique('messagecounter'), statust=OK, divtext=tscript) #make outmessage object #run mapping script************************ 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) #get the 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 ta...... 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 ta...... 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 handle_out_message(out_translated, ta_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) 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 handle_out_message(out_translated, ta_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 if botsglobal.ini.getboolean('settings', 'oldmessageerrors', False): raise txt = botslib.txtexc() ta_splitup.update( statust=ERROR, errortext=txt, **inn_splitup.ta_info ) #update db. inn_splitup.ta_info could be changed by mappingscript. Is this useful? ta_splitup.deletechildren() else: ta_splitup.update( statust=DONE, **inn_splitup.ta_info ) #update db. inn_splitup.ta_info could be changed by mappingscript. Is this useful? #exceptions file_in-level except botslib.GotoException: #edi-file is OK, file is passed-through after parsing. ta_parsed.update(statust=DONE, filesize=row['filesize'], **edifile.ta_info) #update with info from eg queries ta_parsed.copyta(status=MERGED, statust=OK) #original file goes straight to MERGED edifile.handleconfirm(ta_fromfile, error=False) botsglobal.logger.debug( _(u'Parse & passthrough for input file "%(filename)s".'), row) except botslib.FileTooLargeError as msg: ta_parsed.update(statust=ERROR, errortext=unicode(msg)) ta_parsed.deletechildren() botsglobal.logger.debug( u'Error in translating input file "%(filename)s":\n%(msg)s', { 'filename': row['filename'], 'msg': msg }) except: txt = botslib.txtexc() ta_parsed.update(statust=ERROR, errortext=txt, **edifile.ta_info) ta_parsed.deletechildren() 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: edifile.handleconfirm(ta_fromfile, error=False) ta_parsed.update(statust=DONE, filesize=row['filesize'], **edifile.ta_info) botsglobal.logger.debug(_(u'Translated input file "%(filename)s".'), row) finally: ta_fromfile.update(statust=DONE)
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