def start(): #********command line arguments************************** edifile ='' grammarfile = '' configdir = 'config' for arg in sys.argv[1:]: if not arg: continue if arg.startswith('-c'): configdir = arg[2:] if not configdir: print ' !!Indicated Bots should use specific .ini file but no file name was given.' showusage() elif arg in ["?", "/?"] or arg.startswith('-'): showusage() else: if not edifile: edifile = arg else: grammarfile = arg if not (edifile and grammarfile): print ' !!Both edifile and grammarfile are required.' showusage() #********end handling command line arguments************************** editype='xmlnocheck' messagetype='xmlnocheckxxxtemporaryforxml2grammar' mpath = [] botsinit.generalinit(configdir) os.chdir(botsglobal.ini.get('directories','botspath')) botsinit.initenginelogging() #the xml file is parsed as an xmlnocheck message....so a (temp) xmlnocheck grammar is needed....without content... this file is not removed.... tmpgrammarfile = botslib.join(botsglobal.ini.get('directories','usersysabs'),'grammars',editype,messagetype+'.py') f = open(tmpgrammarfile,'w') f.close() inn = inmessage.edifromfile(editype=editype,messagetype=messagetype,filename=edifile) #~ inn.root.display() out = outmessage.outmessage_init(editype=editype,messagetype=messagetype,filename='botssys/infile/unitnode/output/inisout03.edi',divtext='',topartner='') #make outmessage object #handle root rootmpath = [{'BOTSID':inn.root.record['BOTSID']}] out.put(*rootmpath) writefields(out,inn.root,rootmpath) #walk tree; write results to out-tree for node,mpath in treewalker(inn.root,mpath): mpath.append({'BOTSID':node.record['BOTSID']}) if out.get(*mpath) is None: out.put(*mpath) writefields(out,node,mpath) #~ out.root.display() #out-tree is finished; represents ' normalised' tree suited for writing as a grammar structure = [] recorddefs = {} tree2grammar(out.root,structure,recorddefs) #~ for key,value in recorddefs.items(): #~ print key,value #~ print '\n' sortedstructurelist = structure2list(structure) recorddefsstring = recorddefs2string(recorddefs,sortedstructurelist) structurestring = structure2string(structure) #write grammar file grammar = open(grammarfile,'wb') grammar.write('#grammar automatically generated by bots open source edi software.') grammar.write('\n') grammar.write('from bots.botsconfig import *') grammar.write('\n\n') grammar.write('syntax = {}') grammar.write('\n\n') grammar.write('structure = [\n%s]\n'%(structurestring)) grammar.write('\n\n') grammar.write('recorddefs = %s'%(recorddefsstring)) grammar.write('\n\n') grammar.close() print 'grammar file is written',grammarfile
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 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 # ~ import gc # ~ gc.disable() 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 # whole edi-file is read, parsed and made into a inmessage-object: 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; del tomessage # ~ gc.collect() if not doalttranslation: break # out of while loop else: inn.ta_info["alt"] = doalttranslation # 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 # ~ gc.collect() # 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 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