コード例 #1
0
ファイル: proj_script.py プロジェクト: jstnlth/rapuma
class ProjScript (object) :

    def __init__(self, pid, gid) :
        '''Do the primary initialization for this class.'''

        self.pid                        = pid
        self.gid                        = gid
        self.tools                      = Tools()
        self.local                      = ProjLocal(pid)
        self.user                       = UserConfig()
        self.userConfig                 = self.user.userConfig
        self.proj_config                = Config(pid, gid)
        self.proj_config.getProjectConfig()
        self.projectConfig              = self.proj_config.projectConfig
        self.cType                      = self.projectConfig['Groups'][gid]['cType']
        self.Ctype                      = self.cType.capitalize()
        self.log                        = ProjLog(pid)



        # Log messages for this module
        self.errorCodes     = {

            '0000' : ['MSG', 'Placeholder message'],

            '1010' : ['MSG', 'Script install process for [<<1>>] Succeeded.'],
            '1020' : ['ERR', 'Script install process for [<<1>>] failed.'],
            '1030' : ['ERR', 'Script type [<<1>>] not supported.'],
            '1040' : ['ERR', 'Script install cannot proceed for [<<1>>] because this script already exists in the project. You must remove it first before you can add another script.'],

            '2010' : ['MSG', 'Script remove process for [<<1>>] Succeeded.'],
            '2020' : ['ERR', 'Script remove process for [<<1>>] failed.'],

            '4210' : ['MSG', 'Processes completed successfully on: [<<1>>] by [<<2>>]'],
            '4220' : ['ERR', 'Processes for [<<1>>] failed. Script [<<2>>] returned this error: [<<3>>]'],
            '4260' : ['ERR', 'Installed the default component preprocessing script. Editing will be required for it to work with your project.'],
            '4265' : ['LOG', 'Component preprocessing script is already installed.'],
            '4310' : ['ERR', 'Script is an unrecognized type: [<<1>>] Cannot continue with installation.']


        }

###############################################################################
############################# Script Add Functions ############################
###############################################################################
######################## Error Code Block Series = 1000 #######################
###############################################################################


    def addScriptFiles (self, path, scriptType) :
        '''Import/add processing script files for a group that are found
        in the given path. Assumes valid path. Will fail if a copy
        doesn't succeed. If the file is already there, give a warning and
        will not copy.'''

#        import pdb; pdb.set_trace()

        source = path
        fileName = self.tools.fName(path)
        target = os.path.join(self.local.projScriptFolder, fileName)
        
        # Do an initial check to see if the script is already there
        # Never copy over the top of an existing script
        if os.path.isfile(target) :
            self.log.writeToLog(self.errorCodes['1040'], [fileName])
        # Make script folder if needed
        if not os.path.isdir(self.local.projScriptFolder) :
            os.makedirs(self.local.projScriptFolder)
        # Copy in the script
        if self.scriptInstall(source, target) :
            # Record the script file name
            if scriptType == 'preprocess' :
                self.projectConfig['Groups'][self.gid]['preprocessScript'] = fileName
            elif scriptType == 'postprocess' :
                self.projectConfig['Groups'][self.gid]['postprocessScript'] = fileName
            else :
                self.log.writeToLog(self.errorCodes['1030'], [scriptType])

            self.tools.writeConfFile(self.projectConfig)
            self.log.writeToLog(self.errorCodes['1010'], [fileName])
            return True
        else :
            self.log.writeToLog(self.errorCodes['1020'], [fileName])


###############################################################################
############################ Script Remove Functions ##########################
###############################################################################
######################## Error Code Block Series = 2000 #######################
###############################################################################


    def removeScriptFiles (self, scriptType) :
        '''Remove processing script files for a group.'''

        if scriptType == 'preprocess' :
            fileName = self.projectConfig['Groups'][self.gid]['preprocessScript']
        elif scriptType == 'postprocess' :
            fileName = self.projectConfig['Groups'][self.gid]['postprocessScript']
        else :
            self.log.writeToLog(self.errorCodes['1030'], [scriptType])

        target = os.path.join(self.local.projScriptFolder, fileName)
        # Remove the script (if it's not there, we don't care)
        try :
            os.remove(target)
        except :
            pass
        if not os.path.isfile(target) :
            if scriptType == 'preprocess' :
                self.projectConfig['Groups'][self.gid]['preprocessScript'] = ''
            elif scriptType == 'postprocess' :
                self.projectConfig['Groups'][self.gid]['postprocessScript'] = ''
            else :
                self.log.writeToLog(self.errorCodes['1030'], [scriptType])
            self.tools.writeConfFile(self.projectConfig)
            self.log.writeToLog(self.errorCodes['2010'], [fileName])
            return True
        else :
            self.log.writeToLog(self.errorCodes['2020'], [fileName])


###############################################################################
########################## General Script Functions ###########################
###############################################################################
######################## Error Code Block Series = 4000 #######################
###############################################################################


    def runProcessScript (self, target, scriptFile) :
        '''Run a text processing script on a component. This assumes the 
        component and the script are valid and the component lock is turned 
        off. If not, you cannot expect any good to come of this.'''

        # subprocess will fail if permissions are not set on the
        # script we want to run. The correct permission should have
        # been set when we did the installation.
        err = subprocess.call([scriptFile, target])
        if err == 0 :
            self.log.writeToLog(self.errorCodes['4210'], [self.tools.fName(target), self.tools.fName(scriptFile)])
        else :
            self.log.writeToLog(self.errorCodes['4220'], [self.tools.fName(target), self.tools.fName(scriptFile), str(err)])
            return False

        return True


    def scriptInstall (self, source, target) :
        '''Install a script. A script can be a collection of items in
        a zip file or a single .py script file.'''

        scriptTargetFolder, fileName = os.path.split(target)
        if self.tools.isExecutable(source) :
            if not shutil.copy(source, target) :
                self.tools.makeExecutable(target)
                return True
        elif self.tools.fName(source).split('.')[1].lower() == 'zip' :
            myZip = zipfile.ZipFile(source, 'r')
            for f in myZip.namelist() :
                data = myZip.read(f, source)
                # Pretty sure zip represents directory separator char as "/" regardless of OS
                myPath = os.path.join(scriptTargetFolder, f.split("/")[-1])
                try :
                    myFile = open(myPath, "wb")
                    myFile.write(data)
                    myFile.close()
                except :
                    pass
            myZip.close()
            return True
        else :
            self.log.writeToLog(self.errorCodes['4310'], [self.tools.fName(source)])
コード例 #2
0
ファイル: proj_process.py プロジェクト: sillsdev/rapuma
class ProjProcess (object) :

    def __init__(self, pid, gid = None, projectConfig = None) :
        '''Intitate the whole class and create the object.'''

        self.pid                    = pid
        self.tools                  = Tools()
        self.user                   = UserConfig()
        self.userConfig             = self.user.userConfig
        if projectConfig :
            self.projectConfig      = projectConfig
        else :
            self.proj_config        = Config(self.pid)
            self.proj_config.getProjectConfig()
            self.projectConfig      = self.proj_config.projectConfig
        self.local                  = ProjLocal(pid, gid, self.projectConfig)
        self.log                    = ProjLog(pid)

        # Log messages for this module
        self.errorCodes     = {
            '0000' : ['MSG', 'Placeholder message'],
            'XPRT-000' : ['MSG', 'Messages for export issues (probably only in project.py)'],
            'XPRT-005' : ['MSG', 'Unassigned error message ID.'],
            'XPRT-010' : ['ERR', 'Export file name could not be formed with available configuration information.'],
            'XPRT-020' : ['ERR', 'Unable to export: [<<1>>].'],
            'XPRT-030' : ['MSG', 'Files exported to [<<1>>].'],
            'XPRT-040' : ['MSG', 'Beginning export, please wait...'],
            'XPRT-050' : ['MSG', 'Unassigned error message ID.'],

            '1210' : ['MSG', 'Processes completed successfully on: [<<1>>] by [<<2>>]'],
            '1220' : ['ERR', 'Processes for [<<1>>] failed. Script [<<2>>] returned this error: [<<3>>]'],
            '1240' : ['MSG', 'Component group preprocessing [<<1>>] for group [<<2>>].'],
            '1260' : ['ERR', 'Installed the default component preprocessing script. Editing will be required for it to work with your project.'],
            '1265' : ['LOG', 'Component preprocessing script is already installed.'],

        }


###############################################################################
############################### Export Functions ##############################
###############################################################################
####################### Error Code Block Series = 0200 ########################
###############################################################################

# FIXME: This needs to be rewritten

    #def export (self, cType, cName, path = None, script = None, bundle = False, force = False) :
        #'''Facilitate the exporting of project text. It is assumed that the
        #text is clean and ready to go and if any extraneous publishing info
        #has been injected into the text, it will be removed by an appropreate
        #post-process that can be applied by this function. No validation
        #will be initiated by this function.'''
        
        ## FIXME - Todo: add post processing script feature

        ## Probably need to create the component object now
        #self.createComponent(cName)

        ## Figure out target path
        #if path :
            #path = self.tools.resolvePath(path)
        #else :
            #parentFolder = os.path.dirname(self.local.projHome)
            #path = os.path.join(parentFolder, 'Export')

        ## Make target folder if needed
        #if not os.path.isdir(path) :
            #os.makedirs(path)

        ## Start a list for one or more files we will process
        #fList = []

        ## Will need the stylesheet for copy
        #projSty = self.projectConfig['Managers'][cType + '_Style']['mainStyleFile']
        #projSty = os.path.join(self.local.projStyleFolder, projSty)
        ## Process as list of components

        #self.log.writeToLog('XPRT-040')
        #for cid in self.components[cName].getSubcomponentList(cName) :
            #cidCName = self.components[cName].getRapumaCName(cid)
            #ptName = PT_Tools(self).formPTName(cName, cid)
            ## Test, no name = no success
            #if not ptName :
                #self.log.writeToLog('XPRT-010')
                #self.tools.dieNow()

            #target = os.path.join(path, ptName)
            #source = os.path.join(self.local.projComponentFolder, cidCName, cid + '.' + cType)
            ## If shutil.copy() spits anything back its bad news
            #if shutil.copy(source, target) :
                #self.log.writeToLog('XPRT-020', [self.tools.fName(target)])
            #else :
                #fList.append(target)

        ## Start the main process here
        #if bundle :
            #archFile = os.path.join(path, cName + '_' + self.tools.ymd() + '.zip')
            ## Hopefully, this is a one time operation but if force is not True,
            ## we will expand the file name so nothing is lost.
            #if not force :
                #if os.path.isfile(archFile) :
                    #archFile = os.path.join(path, cName + '_' + self.tools.fullFileTimeStamp() + '.zip')

            #myzip = zipfile.ZipFile(archFile, 'w', zipfile.ZIP_DEFLATED)
            #for f in fList :
                ## Create a string object from the contents of the file
                #strObj = StringIO.StringIO()
                #for l in open(f, "rb") :
                    #strObj.write(l)
                ## Write out string object to zip
                #myzip.writestr(self.tools.fName(f), strObj.getvalue())
                #strObj.close()
            ## Close out the zip and report
            #myzip.close()
            ## Clean out the folder
            #for f in fList :
                #os.remove(f)
            #self.log.writeToLog('XPRT-030', [self.tools.fName(archFile)])
        #else :
            #self.log.writeToLog('XPRT-030', [path])

        #return True


###############################################################################
########################## Text Processing Functions ##########################
###############################################################################
######################## Error Code Block Series = 1200 #######################
###############################################################################

    def turnOnOffPreprocess (self, gid, onOff) :
        '''Turn on or off preprocessing on incoming component text.'''

        self.projectConfig['Groups'][gid]['usePreprocessScript'] = onOff
        self.tools.writeConfFile(self.projectConfig)
        self.log.writeToLog(self.errorCodes['1240'], [str(onOff), gid])


    def checkForPreprocessScript (self, gid) :
        '''Check to see if a preprocess script is installed. If not, install the
        default script and give a warning that the script is not complete.'''

        # First make sure the Scripts folder is there
        if not os.path.isdir(self.local.projScriptFolder) :
            os.makedirs(self.local.projScriptFolder)

        # Check and copy if needed
        if not os.path.isfile(self.local.groupPreprocessFile) :
            shutil.copy(self.local.rpmPreprocessFile, self.local.groupPreprocessFile)
            self.tools.makeExecutable(self.local.groupPreprocessFile)
            self.log.writeToLog(self.errorCodes['1260'])
        else :
            self.log.writeToLog(self.errorCodes['1265'])


    def runProcessScript (self, target, scriptFile) :
        '''Run a text processing script on a component. This assumes the 
        component and the script are valid and the component lock is turned 
        off. If not, you cannot expect any good to come of this.'''

        # subprocess will fail if permissions are not set on the
        # script we want to run. The correct permission should have
        # been set when we did the installation.
        err = subprocess.call([scriptFile, target])
        if err == 0 :
            self.log.writeToLog(self.errorCodes['1210'], [self.tools.fName(target), self.tools.fName(scriptFile)])
        else :
            self.log.writeToLog(self.errorCodes['1220'], [self.tools.fName(target), self.tools.fName(scriptFile), str(err)])
            return False

        return True


    def scriptInstall (self, source, target) :
        '''Install a script. A script can be a collection of items in
        a zip file or a single .py script file.'''

        scriptTargetFolder, fileName = os.path.split(target)
        if self.tools.isExecutable(source) :
            shutil.copy(source, target)
            self.tools.makeExecutable(target)
        elif self.tools.fName(source).split('.')[1].lower() == 'zip' :
            myZip = zipfile.ZipFile(source, 'r')
            for f in myZip.namelist() :
                data = myZip.read(f, source)
                # Pretty sure zip represents directory separator char as "/" regardless of OS
                myPath = os.path.join(scriptTargetFolder, f.split("/")[-1])
                try :
                    myFile = open(myPath, "wb")
                    myFile.write(data)
                    myFile.close()
                except :
                    pass
            myZip.close()
            return True
        else :
            self.tools.dieNow('Script is an unrecognized type: ' + self.tools.fName(source) + ' Cannot continue with installation.')


    def installPostProcess (self, cType, script, force = None) :
        '''Install a post process script into the main components processing
        folder for a specified component type. This script will be run on 
        every file of that type that is imported into the project. Some
        projects will have their own specially developed post process
        script. Use the "script" var to specify a process (which should be
        bundled in a system compatable way). If "script" is not specified
        we will copy in a default script that the user can modify. This is
        currently limited to Python scripts only which do in-place processes
        on the target files. The script needs to have the same name as the
        zip file it is bundled in, except the extention is .py instead of
        the bundle .zip extention.'''

        # Define some internal vars
        Ctype               = cType.capitalize()
        oldScript           = ''
        scriptName          = os.path.split(script)[1]
        scriptSourceFolder  = os.path.split(script)[0]
        scriptTarget        = os.path.join(self.local.projScriptFolder, self.tools.fName(script).split('.')[0] + '.py')
        if scriptName in self.projectConfig['CompTypes'][Ctype]['postprocessScripts'] :
            oldScript = scriptName

        # First check for prexsisting script record
        if not force :
            if oldScript :
                self.log.writeToLog('POST-080', [oldScript])
                return False

        # In case this is a new project we may need to install a component
        # type and make a process (components) folder
        if not self.components[cType] :
            self.tools.addComponentType(self.projectConfig, self.local, cType)

        # Make the target folder if needed
        if not os.path.isdir(self.local.projScriptFolder) :
            os.makedirs(self.local.projScriptFolder)

        # First check to see if there already is a script file, return if there is
        if os.path.isfile(scriptTarget) and not force :
            self.log.writeToLog('POST-082', [self.tools.fName(scriptTarget)])
            return False

        # No script found, we can proceed
        if not os.path.isfile(scriptTarget) :
            self.scriptInstall(script, scriptTarget)
            if not os.path.isfile(scriptTarget) :
                self.tools.dieNow('Failed to install script!: ' + self.tools.fName(scriptTarget))
            self.log.writeToLog('POST-110', [self.tools.fName(scriptTarget)])
        elif force :
            self.scriptInstall(script, scriptTarget)
            if not os.path.isfile(scriptTarget) :
                self.tools.dieNow('Failed to install script!: ' + self.tools.fName(scriptTarget))
            self.log.writeToLog('POST-115', [self.tools.fName(scriptTarget)])

        # Record the script with the cType post process scripts list
        scriptList = self.projectConfig['CompTypes'][Ctype]['postprocessScripts']
        if self.tools.fName(scriptTarget) not in scriptList :
            self.projectConfig['CompTypes'][Ctype]['postprocessScripts'] = self.tools.addToList(scriptList, self.tools.fName(scriptTarget))
            self.tools.writeConfFile(self.projectConfig)

        return True


    def removePostProcess (self, cType) :
        '''Remove (actually disconnect) a preprocess script from a

        component type. This will not actually remove the script. That
        would need to be done manually. Rather, this will remove the
        script name entry from the component type so the process cannot
        be accessed for this specific component type.'''

        Ctype = cType.capitalize()
        # Get old setting
        old = self.projectConfig['CompTypes'][Ctype]['postprocessScripts']
        # Reset the field to ''
        if old != '' :
            self.projectConfig['CompTypes'][Ctype]['postprocessScripts'] = ''
            self.tools.writeConfFile(self.projectConfig)
            self.log.writeToLog('POST-130', [old,Ctype])

        else :
            self.log.writeToLog('POST-135', [cType.capitalize()])

        return True