コード例 #1
0
 def _openoutenvelope(self):
     ''' make an outmessage object; read the grammar.'''
     #self.ta_info contains information from ta: editype, messagetype,testindicator,charset,envelope, contenttype
     self.out = outmessage.outmessage_init(
         **self.ta_info)  #make outmessage object.
     #read grammar for envelopesyntax. Remark: self.ta_info is not updated.
     self.out.messagegrammarread(typeofgrammarfile='envelope')
コード例 #2
0
ファイル: envelope.py プロジェクト: jbellomy/bots.v220
 def _openoutenvelope(self, editype, messagetype_or_envelope):
     ''' make an outmessage object; read the grammar.'''
     #self.ta_info now contains information from ta: editype, messagetype,testindicator,charset,envelope, contenttype
     self.out = outmessage.outmessage_init(
         **
         self.ta_info)  #make outmessage object. Init with self.out.ta_info
     #read grammar for envelopesyntax. Remark: self.ta_info is not updated now
     self.out.outmessagegrammarread(editype, messagetype_or_envelope)
コード例 #3
0
ファイル: envelope.py プロジェクト: jboyleca/bots.v220
 def _openoutenvelope(self, editype, messagetype_or_envelope):
     """ make an outmessage object; read the grammar."""
     # self.ta_info now contains information from ta: editype, messagetype,testindicator,charset,envelope, contenttype
     self.out = outmessage.outmessage_init(**self.ta_info)  # make outmessage object. Init with self.out.ta_info
     # read grammar for envelopesyntax. Remark: self.ta_info is not updated now
     self.out.outmessagegrammarread(editype, messagetype_or_envelope)
コード例 #4
0
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
コード例 #5
0
ファイル: transform.py プロジェクト: alexproca/bots
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.FileTooLarge(_(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 = str(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.FileTooLarge as msg:
        ta_parsed.update(statust=ERROR,errortext=str(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)
コード例 #6
0
ファイル: transform.py プロジェクト: divadrei/bots
def translate(startstatus,endstatus,idroute,rootidta):
    ''' main translation loop.
        get edifiles to be translated, than:
        -   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)
        status: FILEIN--PARSED-<SPLITUP--TRANSLATED
    '''
    try:    #see if there is a userscript that can determine the translation
        userscript,scriptname = botslib.botsimport('mappings','translation')
    except ImportError:       #userscript is not there; other errors like syntax errors are not catched
        userscript = scriptname = None
    #select edifiles to translate
    for rawrow in botslib.query(u'''SELECT idta,frompartner,topartner,filename,messagetype,testindicator,editype,charset,alt,fromchannel,filesize
                                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':rootidta}):
        try:
            row = dict(rawrow)   #convert to real dictionary ()
            ta_fromfile = botslib.OldTransaction(row['idta'])
            ta_parsed = ta_fromfile.copyta(status=PARSED)       #make PARSED ta
            if row['filesize'] > botsglobal.ini.getint('settings','maxfilesizeincoming',5000000):
                ta_parsed.update(filesize=row['filesize'])
                raise botslib.InMessageError(_(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=idroute)
            #if no exception: infile has been lexed and parsed OK.
            #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'
                    post_mapping_mode = False       #if post_mapping: reuse out-object, if no translation is found no error
                    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=idroute,message=inn_splitup)
                            if not tscript:
                                if post_mapping_mode:   #in post-mapping mode, not finding the (partern specific!) script is no problem: translation is done
                                    #there is no post-mapping script found (in other words, default mapping script is enough).
                                    #all OK, handle the generated out-file and continue with next message
                                    botsglobal.logger.debug(_(u'Found no "post-mapping" translation for editype "%(editype)s", messagetype "%(messagetype)s", frompartner "%(frompartner)s", topartner "%(topartner)s", alt "%(alt)s".'),
                                                                inn_splitup.ta_info)
                                    handle_out_message(out_translated,ta_translated)
                                    del out_translated
                                    break   #break out of while loop
                                else:
                                    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).
                        if not post_mapping_mode:
                            #initialize new out-object*************************
                            ta_translated = ta_splitup.copyta(status=endstatus)     #make ta for translated message (new out-ta)
                            filename_translated = str(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)
                            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
                            elif doalttranslation['type'] == u'post_mapping':
                                #do chained  (post)translation: same inn and out-objects.
                                #in other words, the post-translation continue where is 'default' mapping ended.
                                #use case: default mapping (for all partners), partner-specific post-translation
                                #note: this is easier via import defaultmapping in a partner specific mapping. Please use that method!
                                post_mapping_mode = True       #translation is done; reset post_mapping_mode
                                inn_splitup.ta_info['alt'] = doalttranslation['alt']   #get the alt-value for the next chained translation
                                #~ inn_splitup.ta_info.pop('statust')
                            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)
                            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
                    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 (file not OK according to grammar)
        except:
            txt = botslib.txtexc()
            ta_parsed.update(statust=ERROR,errortext=txt)
            ta_parsed.deletechildren()
            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)
コード例 #7
0
ファイル: engine2.py プロジェクト: avkameth/bots.v321
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
コード例 #8
0
ファイル: engine2.py プロジェクト: zhangweiquan/bots
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
コード例 #9
0
ファイル: transform.py プロジェクト: jboyleca/bots.v210
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
コード例 #10
0
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
コード例 #11
0
ファイル: envelope.py プロジェクト: avkameth/bots.v321
 def _openoutenvelope(self):
     ''' make an outmessage object; read the grammar.'''
     #self.ta_info contains information from ta: editype, messagetype,testindicator,charset,envelope, contenttype
     self.out = outmessage.outmessage_init(**self.ta_info)    #make outmessage object.
     #read grammar for envelopesyntax. Remark: self.ta_info is not updated.
     self.out.messagegrammarread(typeofgrammarfile='envelope')
コード例 #12
0
ファイル: xml2botsgrammar.py プロジェクト: divadrei/bots
def start():
    #********command line arguments**************************
    usage = '''
    This is "%(name)s" version %(version)s, part of Bots open source edi translator (http://bots.sourceforge.net).
    Creates a grammar from an xml file.'
    Usage:'
        %(name)s  -c<directory>  <xml_file>  <xml_grammar_file>
    Options:
        -c<directory>      directory for configuration files (default: config).
        <xml_file>         name of the xml file to read
        <xml_grammar_file> name of the grammar file to write
    
    '''%{'name':os.path.basename(sys.argv[0]),'version':botsglobal.version}
    configdir = 'config'
    edifile =''
    grammarfile = ''
    for arg in sys.argv[1:]:
        if arg.startswith('-c'):
            configdir = arg[2:]
            if not configdir:
                print 'Error: configuration directory indicated, but no directory name.'
                sys.exit(1)
        elif arg in ["?", "/?",'-h', '--help'] or arg.startswith('-'):
            print usage
            sys.exit(0)
        else:
            if not edifile:
                edifile = arg
            else:
                grammarfile = arg
    if not edifile or not grammarfile:
        print 'Error: both edifile and grammarfile are required.'
        sys.exit(0)
    #***end handling command line arguments**************************
    botsinit.generalinit(configdir)     #find locating of bots, configfiles, init paths etc.
    process_name = 'xml2botsgrammar'
    botsglobal.logger = botsinit.initenginelogging(process_name)
    atexit.register(logging.shutdown)
    
    #the xml file is parsed as an xmlnocheck message
    editype = 'xmlnocheck'
    messagetype = 'xmlnocheckxxxtemporaryforxml2grammar'
    mpath = []
    #a (temp) xmlnocheck grammar is needed (but needs not actual content. This file is not removed.
    tmpgrammarfile = botslib.join(botsglobal.ini.get('directories','usersysabs'),'grammars',editype,messagetype+'.py')
    filehandler = open(tmpgrammarfile,'w')
    filehandler.close()
    
    #make inmessage object: read the xml file
    inn = inmessage.parse_edi_file(editype=editype,messagetype=messagetype,filename=edifile,remove_empties_from_xml=False)
    #make outmessage object; nothing is 'filled' yet.
    out = outmessage.outmessage_init(editype=editype,messagetype=messagetype,filename='botssys/infile/unitnode/output/inisout03.edi',divtext='',topartner='')    
    
    #***do the mapping***************************************************
    #handle root
    rootmpath = [{'BOTSID':inn.root.record['BOTSID'],'BOTSIDnr':'1'}]
    out.put(*rootmpath)
    map_writefields(out,inn.root,rootmpath)
    #walk tree; write results to out-tree
    for node_instance,mpath in map_treewalker(inn.root,mpath):
        mpath.append({'BOTSID':node_instance.record['BOTSID']})
        if out.get(*mpath) is None:
            out.put(*mpath)
        map_writefields(out,node_instance,mpath)

    #***mapping is done; 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 translator.')
    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
コード例 #13
0
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)
コード例 #14
0
def start():
    #********command line arguments**************************
    usage = '''
    This is "%(name)s" version %(version)s, part of Bots open source edi translator (http://bots.sourceforge.net).
    Creates a grammar from an xml file.'
    Usage:'
        %(name)s  -c<directory>  <xml_file>  <xml_grammar_file>
    Options:
        -c<directory>      directory for configuration files (default: config).
        -a                 all xml elements as records
        <xml_file>         name of the xml file to read
        <xml_grammar_file> name of the grammar file to write
    
    '''%{'name':os.path.basename(sys.argv[0]),'version':botsglobal.version}
    configdir = 'config'
    edifile =''
    botsgrammarfilename = ''
    allrecords = False
    for arg in sys.argv[1:]:
        if arg.startswith('-c'):
            configdir = arg[2:]
            if not configdir:
                print 'Error: configuration directory indicated, but no directory name.'
                sys.exit(1)
        elif arg.startswith('-a'):
            allrecords = True
        elif arg in ["?", "/?",'-h', '--help'] or arg.startswith('-'):
            print usage
            sys.exit(0)
        else:
            if not edifile:
                edifile = arg
            else:
                botsgrammarfilename = arg
    if not edifile or not botsgrammarfilename:
        print 'Error: both edifile and grammarfile are required.'
        sys.exit(0)
    #***end handling command line arguments**************************
    botsinit.generalinit(configdir)     #find locating of bots, configfiles, init paths etc.
    process_name = 'xml2botsgrammar'
    botsglobal.logger = botsinit.initenginelogging(process_name)
    atexit.register(logging.shutdown)

    targetNamespace = ''
    #*******************************************************************
    #***add classes for handling editype xml to inmessage
    #*******************************************************************
    if allrecords:
        #~ editype = 'xmlforgrammar_allrecords'
        inmessage.xmlforgrammar = xmlforgrammar_allrecords
    else:
        #~ editype = 'xmlforgrammar' 
        inmessage.xmlforgrammar = xmlforgrammar
    #make inmessage object: read the xml file
    inn = inmessage.parse_edi_file(editype='xmlforgrammar',messagetype='',filename=edifile)
    inn.checkforerrorlist() #no exception if infile has been lexed and parsed OK else raises an error
    #make outmessage object; nothing is 'filled' yet. In mapping tree is filled; nothing is written to file.
    out = outmessage.outmessage_init(editype='xmlnocheck',messagetype='',filename='',divtext='',topartner='')    
    
    #***mapping: make 'normalised' out-tree suited for writing as a grammar***************************************************
    mpath_root = [OrderedDict({'BOTSID':inn.root.record['BOTSID'],'BOTSIDnr':'1'})] #handle root
    out.put(*mpath_root)
    map_writefields(out,inn.root,mpath_root)
    
    #walk tree; write results to out-tree
    mpath_start = []
    for node_instance,mpath in map_treewalker(inn.root,mpath_start):
        mpath.append(OrderedDict({'BOTSID':node_instance.record['BOTSID']}))
        if out.get(*mpath) is None:     #if node does not exist: write it.
            out.put(*mpath)
        map_writefields(out,node_instance,mpath)
    #***mapping is done 

    #***convert out-tree to grammar
    structure = []
    recorddefs = {}
    tree2grammar(out.root,structure,recorddefs)

    #***write grammar to file
    grammar2file(botsgrammarfilename,structure,recorddefs,targetNamespace)
コード例 #15
0
ファイル: transform.py プロジェクト: avkameth/bots.v220
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