Ejemplo n.º 1
0
def datemask(value, frommask, tomask):
    ''' value is formatted according as in frommask;
        returned is the value formatted according to tomask.
        example: datemask('12/31/2012','MM/DD/YYYY','YYYYMMDD') returns '20121231'
    '''
    if not value:
        return value
    convdict = collections.defaultdict(list)
    for key, val in zip(frommask, value):
        convdict[key].append(val)
    #convdict contains for example:  {'Y': [u'2', u'0', u'1', u'2'], 'M': [u'1', u'2'], 'D': [u'3', u'1'], '/': [u'/', u'/']}
    terug = ''
    try:
        # alternative implementation: return ''.join([convdict.get(c,[c]).pop(0) for c in tomask])     #very short, but not faster....
        for char in tomask:
            terug += convdict.get(char, [char]).pop(
                0
            )  #for this character, lookup value in convdict (a list). pop(0) this list: get first member of list, and drop it. If char not in convdict as key, use char itself.
    except:
        raise botslib.BotsError(_(
            u'Error in function datamask("$value", "$frommask", "$tomask").'),
                                value=value,
                                frommask=frommask,
                                tomask=tomask)
    return terug
Ejemplo n.º 2
0
 def get(self, section, option, default=''):
     try:
         return ConfigParser.SafeConfigParser.get(self, section, option)
     except:  #if there is no such section,option
         if default == '':
             raise botslib.BotsError(_(
                 u'No entry "$entry" in section "$section" in "bots.ini".'),
                                     entry=option,
                                     section=section)
         return default
Ejemplo n.º 3
0
 def get(self, section, option, default=''):
     if self.has_option(section, option):
         return ConfigParser.RawConfigParser.get(self, section, option)
     elif default == '':
         raise botslib.BotsError(
             u'No entry "%(option)s" in section "%(section)s" in "bots.ini".',
             {
                 'option': option,
                 'section': section
             })
     else:
         return default
Ejemplo n.º 4
0
def dateformat(date):
    ''' for edifact: return right format code for the date. '''
    if not date:
        return None
    if len(date) == 8:
        return '102'
    if len(date) == 12:
        return '203'
    if len(date) == 16:
        return '718'
    raise botslib.BotsError(_(u'No valid edifact date format for "%(date)s".'),
                            {'date': date})
Ejemplo n.º 5
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
Ejemplo n.º 6
0
def generalinit(configdir):
    #Set Configdir
    #Configdir MUST be importable. So configdir is relative to PYTHONPATH. Try several options for this import.
    try:  #configdir outside bots-directory: import configdir.settings.py
        importnameforsettings = os.path.normpath(
            os.path.join(configdir, 'settings')).replace(os.sep, '.')
        settings = botslib.botsbaseimport(importnameforsettings)
    except ImportError:  #configdir is in bots directory: import bots.configdir.settings.py
        try:
            importnameforsettings = os.path.normpath(
                os.path.join('bots', configdir,
                             'settings')).replace(os.sep, '.')
            settings = botslib.botsbaseimport(importnameforsettings)
        except ImportError:  #set pythonpath to config directory first
            if not os.path.exists(configdir):  #check if configdir exists.
                raise botslib.BotsError(_(
                    u'In initilisation: path to configuration does not exists: "$path".'
                ),
                                        path=configdir)
            addtopythonpath = os.path.abspath(os.path.dirname(configdir))
            #~ print 'add pythonpath for usersys',addtopythonpath
            moduletoimport = os.path.basename(configdir)
            sys.path.append(addtopythonpath)
            importnameforsettings = os.path.normpath(
                os.path.join(moduletoimport, 'settings')).replace(os.sep, '.')
            settings = botslib.botsbaseimport(importnameforsettings)
    #settings are accessed using botsglobal
    botsglobal.settings = settings
    #Find pathname configdir using imported settings.py.
    configdirectory = os.path.abspath(os.path.dirname(settings.__file__))

    #Read configuration-file bots.ini.
    botsglobal.ini = BotsConfig()
    cfgfile = open(os.path.join(configdirectory, 'bots.ini'), 'r')
    botsglobal.ini.readfp(cfgfile)
    cfgfile.close()

    #Set usersys.
    #usersys MUST be importable. So usersys is relative to PYTHONPATH. Try several options for this import.
    usersys = botsglobal.ini.get('directories', 'usersys', 'usersys')
    try:  #usersys outside bots-directory: import usersys
        importnameforusersys = os.path.normpath(usersys).replace(os.sep, '.')
        importedusersys = botslib.botsbaseimport(importnameforusersys)
    except ImportError:  #usersys is in bots directory: import bots.usersys
        try:
            importnameforusersys = os.path.normpath(
                os.path.join('bots', usersys)).replace(os.sep, '.')
            importedusersys = botslib.botsbaseimport(importnameforusersys)
        except ImportError:  #set pythonpath to usersys directory first
            if not os.path.exists(usersys):  #check if configdir exists.
                raise botslib.BotsError(_(
                    u'In initilisation: path to configuration does not exists: "$path".'
                ),
                                        path=usersys)
            addtopythonpath = os.path.abspath(os.path.dirname(usersys))  #????
            moduletoimport = os.path.basename(usersys)
            #~ print 'add pythonpath for usersys',addtopythonpath
            sys.path.append(addtopythonpath)
            importnameforusersys = os.path.normpath(usersys).replace(
                os.sep, '.')
            importedusersys = botslib.botsbaseimport(importnameforusersys)

    #set directory settings in bots.ini************************************************************
    botsglobal.ini.set('directories', 'botspath',
                       botsglobal.settings.PROJECT_PATH)
    botsglobal.ini.set('directories', 'config', configdirectory)
    botsglobal.ini.set('directories', 'usersysabs',
                       os.path.abspath(
                           os.path.dirname(importedusersys.__file__))
                       )  #???Find pathname usersys using imported usersys

    botsglobal.usersysimportpath = importnameforusersys
    botssys = botsglobal.ini.get('directories', 'botssys', 'botssys')
    botsglobal.ini.set('directories', 'botssys', botslib.join(botssys))

    botsglobal.ini.set('directories', 'data', botslib.join(botssys, 'data'))
    botslib.dirshouldbethere(botsglobal.ini.get('directories', 'data'))

    botsglobal.ini.set('directories', 'logging',
                       botslib.join(botssys, 'logging'))
    botslib.dirshouldbethere(botsglobal.ini.get('directories', 'logging'))
    botsglobal.ini.set(
        'directories', 'templates',
        botslib.join(botsglobal.ini.get('directories', 'usersysabs'),
                     'grammars/template/templates'))
    botsglobal.ini.set(
        'directories', 'templateshtml',
        botslib.join(botsglobal.ini.get('directories', 'usersysabs'),
                     'grammars/templatehtml/templates'))

    #set values in setting.py**********************************************************************
    if botsglobal.ini.get(
            'webserver', 'environment', 'development'
    ) == 'development':  #values in bots.ini are also used in setting up cherrypy
        settings.DEBUG = True
    else:
        settings.DEBUG = False
    settings.TEMPLATE_DEBUG = settings.DEBUG
    #set paths in settings.py:
    #~ settings.FILE_UPLOAD_TEMP_DIR = os.path.join(settings.PROJECT_PATH, 'botssys/pluginsuploaded')

    #start initializing bots charsets
    initbotscharsets()
    #set environment for django to start***************************************************************************************************
    os.environ['DJANGO_SETTINGS_MODULE'] = importnameforsettings
    initbotscharsets()
    botslib.settimeout(botsglobal.ini.getint('settings', 'globaltimeout',
                                             10))  #
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
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