コード例 #1
0
ファイル: proj_macro.py プロジェクト: jstnlth/rapuma
class Macro(object):
    def __init__(self, pid, cType, gid=None):
        """Do the primary initialization for this class."""

        self.pid = pid
        self.gid = gid
        self.cType = cType
        self.user = UserConfig()
        self.userConfig = self.user.userConfig
        self.projHome = os.path.join(os.path.expanduser(self.userConfig["Resources"]["projects"]), self.pid)
        self.local = ProjLocal(pid, gid, cType)

        #        import pdb; pdb.set_trace()

        self.proj_config = Config(pid)
        self.proj_config.getProjectConfig()
        self.projectConfig = self.proj_config.projectConfig
        self.layoutConfig = self.proj_config.layoutConfig
        self.tools = Tools()
        self.log = ProjLog(pid)
        # Create config placeholders
        self.layoutConfig = None
        self.illustrationConfig = None
        self.macroConfig = self.tools.loadConfig(self.local.macroConfFile, self.local.macroConfXmlFile)

        # Log messages for this module
        self.errorCodes = {
            "3010": ["ERR", "No macro package is registered for the [<<1>>] component type."],
            "3020": ["ERR", "Cannot update! No macro package is registered for the [<<1>>] component type."],
            "3050": ["ERR", "Macro package file not found: [<<1>>]"],
            "3100": [
                "ERR",
                "Macro package: [<<1>>] already exists in the project. I am not allowed to copy over an existing package.",
            ],
            "3200": ["ERR", "Failed to install macro package: [<<1>>]"],
            "3300": ["MSG", "Installed macro package: [<<1>>], Reinitialized [<<2>>]"],
            "3310": ["ERR", "Failed to copy [<<1>>] to folder [<<2>>]."],
            "3400": ["MSG", "Removed macro package configuration settings for: [<<1>>] from the macro.conf file."],
            "3500": ["MSG", "Removed macro package [<<1>>] folder and all files contained."],
            "3600": ["MSG", "Updated component type [<<1>>] with macro package [<<2>>]"],
            "3650": ["ERR", "Failed to updated macro package [<<1>>]"],
        }

    ###############################################################################
    ###################### Macro Package Handling Functions #######################
    ###############################################################################
    ######################## Error Code Block Series = 3000 #######################
    ###############################################################################

    def createMacroFiles(self, macPackId):
        """Create all the necessary macro file names with their assigned paths."""

        self.projMacPackFolder = os.path.join(self.local.projMacPackFolder, macPackId)

        texFileIds = {
            "preStyTexExtFile": "preSty-ext.tex",
            "macSettingsFile": "settings.tex",
            "extTexFile": "extension.tex",
            "grpExtTexFile": self.gid + "-extension.tex",
            "": "",
            "": "",
            "": "",
            "": "",
            "": "",
        }
        styFileIds = {
            "glbExtStyFile": "extension.sty",
            "grpExtStyFile": self.gid + "-extension.sty",
            "": "",
            "": "",
            "": "",
            "": "",
            "": "",
        }

        # <file>
        # <name>TeX lccode Definition File</name>
        # <description>The TeX file that contains lccode definitions and is linked with the hypenation exclusions file.</description>
        # <fileID>lccodeTexFile</fileID>
        # <fileName>[self:gid]-lccode.tex</fileName>
        # <filePath>[self:projGidFolder]</filePath>
        # <depends></depends>
        # <relies></relies>
        # <note>This file is located in the component group folder to allow more segregated processing.</note>
        # </file>
        # <file>
        # <name>TeX Group Hyphenation Exclusions File</name>
        # <description>The file that contains the hypenation words exclusions list for the current group that TeX will use to render the text.</description>
        # <fileID>grpHyphExcTexFile</fileID>
        # <fileName>[self:gid]-hyphenation.tex</fileName>
        # <filePath>[self:projGidFolder]</filePath>
        # <depends></depends>
        # <relies></relies>
        # <note>This file is located in the component group folder to allow more segregated processing.</note>
        # </file>

    def getMacPackIdFromFileName(self, fileName):
        """Return the macPack ID based on the file name"""

        # File name less ext is the ID
        parts = len(fileName.split("."))
        return ".".join(fileName.split(".")[: parts - 1])

    def getMacPackIdFromSource(self, source):
        """Return the macPack ID based on the complete path and file name."""

        # Get the file name from the path
        fileName = self.tools.fName(source)
        # Return the ID
        return self.getMacPackIdFromFileName(fileName)

    def addMacPack(self, source):
        """Add a macro package to the project. It will not work if
        the same package is already present. Remove must be used
        to get rid of the existing one first."""

        #        import pdb; pdb.set_trace()

        macPackId = self.getMacPackIdFromSource(source)
        confXml = os.path.join(self.local.projMacroFolder, macPackId, macPackId + ".xml")
        if not os.path.isfile(source):
            self.log.writeToLog(self.errorCodes["3050"], [source])

        # Do not add/install if there seems to be a macro package there already
        if self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"] and os.path.exists(
            self.local.macroConfFile
        ):
            self.log.writeToLog(self.errorCodes["3100"], [macPackId])
            return False

        # Set the projectConf to the new/same package
        self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"] = macPackId
        self.tools.writeConfFile(self.projectConfig)

        # If we got this far, install the a fresh copy of the macPack
        self.installMacPackOnly(source)
        # Move the style files and custom TeX files out of the macPack
        self.moveMacStyles(macPackId)
        self.moveMacTex(macPackId)

        # Create a fresh macro.conf file if it dosn't exist
        if not os.path.isfile(self.local.macroConfFile):
            self.macroConfig = self.tools.initNewConfig(self.local.macroConfFile, self.local.macroConfXmlFile)
        # Inject information from this particular macro package
        mInfo = self.tools.getXMLSettings(confXml)
        self.macroConfig["Macros"][macPackId] = mInfo.dict()

        # Save the settings now
        self.tools.writeConfFile(self.macroConfig)

        self.log.writeToLog(self.errorCodes["3300"], [macPackId, self.local.macroConfFileName])

        return True

    def moveMacStyles(self, macPackId):
        """Move the default macro package styles out of the freshly installed
        project macro package folder to the project Style folder."""

        #        import pdb; pdb.set_trace()

        # Collect the style files to copy
        for f in self.getMacStyExtFiles(macPackId):
            source = os.path.join(os.path.join(self.local.projMacroFolder, macPackId, f))
            target = os.path.join(self.local.projStyleFolder, f)
            self.tools.makedirs(self.local.projStyleFolder)
            # Do not overwrite existing files unless force is used
            if not os.path.exists(target):
                shutil.copy(source, target)
                # Look for default and set to read-only
                defaultStyFile = os.path.join(self.local.projStyleFolder, macPackId + ".sty")
                if target == defaultStyFile:
                    self.tools.makeReadOnly(defaultStyFile)
            # Remove the source to avoid confusion
            if os.path.exists(target):
                os.remove(source)
            else:
                self.log.writeToLog(self.errorCodes["3310"], [source, self.local.projStyleFolder])

    def getMacStyExtFiles(self, macPackId):
        """Return a list of macro package style extention files."""

        sFiles = []
        macPackFiles = os.listdir(os.path.join(self.local.projMacroFolder, macPackId))
        for f in macPackFiles:
            if f.split(".")[1].lower() == "sty":
                sFiles.append(f)
        return sFiles

    def moveMacTex(self, macPackId):
        """Move the custom macro package TeX out of the freshly installed
        project macro package folder to the project TeX folder."""

        # Collect the TeX extention files to copy
        for f in self.getMacTexExtFiles(macPackId):
            source = os.path.join(os.path.join(self.local.projMacroFolder, macPackId, f))
            target = os.path.join(self.local.projTexFolder, f)
            self.tools.makedirs(self.local.projTexFolder)
            # Do not overwrite existing files
            if not os.path.exists(target):
                shutil.copy(source, target)
            # Remove the source to avoid confusion
            if os.path.exists(target):
                os.remove(source)
            else:
                self.log.writeToLog(self.errorCodes["3310"], [source, self.local.projTexFolder])

    def getMacTexExtFiles(self, macPackId):
        """Return a list of macro package TeX extention files."""

        tFiles = []
        macPackFiles = os.listdir(os.path.join(self.local.projMacroFolder, macPackId))
        for f in macPackFiles:
            if f.find("ext.tex") > 0:
                tFiles.append(f)
        return tFiles

    def removeMacPack(self):
        """Remove the macro package from a component type"""

        #        import pdb; pdb.set_trace()

        if self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"] != "":
            macPackId = self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"]
        else:
            self.log.writeToLog(self.errorCodes["3010"], [self.cType])
        # Aquire target to delete
        target = os.path.join(self.local.projMacroFolder, macPackId)

        # Remove the macPack settings from the config file if it is there
        try:
            del self.macroConfig["Macros"][macPackId]
            # Save the settings now
            self.tools.writeConfFile(self.macroConfig)
            self.log.writeToLog(self.errorCodes["3400"], [macPackId])
        except:
            pass

        # Now remove the macro folder (with all its contents)
        if os.path.exists(target):
            shutil.rmtree(target)
            self.log.writeToLog(self.errorCodes["3500"], [macPackId])

        # Remove any style files associated with the macro
        styTarget = os.path.join(self.local.projStyleFolder, macPackId + ".sty")
        self.tools.makeExecutable(styTarget)
        self.tools.removeFile(styTarget)

        # Remove the reference for this macro package from the component type
        # that uses it. Normally that would probably be just be one of them.
        self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"] = ""
        self.tools.writeConfFile(self.projectConfig)

    def updateMacPack(self, source):
        """Update a macro package with the latest version but do not 
        touch the config file."""

        # Do not update if no macro package is registered in the projectConfig
        if not self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"]:
            self.log.writeToLog(self.errorCodes["3020"], [self.cType.capitalize()])
            return False

        macPackId = self.getMacPackIdFromSource(source)
        confXml = os.path.join(self.local.projMacroFolder, macPackId, macPackId + ".xml")
        oldMacPackId = self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"]
        oldMacDir = os.path.join(self.local.projMacroFolder, oldMacPackId)
        newMacDir = os.path.join(self.local.projMacroFolder, macPackId)

        # Install the new macPack (but use the old settings)
        if self.installMacPackOnly(source):
            # The current macro system must have a "master" style file.
            # This is a version of the ParaText style file. Because
            # an update might include an update to the style file,
            # we need to copy that from the macro folder to the Style
            # folder. We will do that now. The name of the file should
            # be the macPackId + ".sty", in theory.
            srcStyleFile = os.path.join(self.local.projMacroFolder, macPackId, macPackId + ".sty")
            oldStyleFile = os.path.join(self.local.projStyleFolder, oldMacPackId + ".sty")
            newStyleFile = os.path.join(self.local.projStyleFolder, macPackId + ".sty")
            # Unlock the old one so it can be deleted.
            self.tools.makeExecutable(oldStyleFile)
            self.tools.removeFile(oldStyleFile)
            # Now copy in the new one.
            shutil.copy(srcStyleFile, newStyleFile)
            # The style file should never be edited by the user, relock it
            self.tools.makeReadOnly(newStyleFile)
            # Update exsisting extention file names. We never want to loose
            # any settings that the user may have added to the extention
            # files so we will rename the existing files to have the
            # new ID otherwise the system will not find them at render time.
            oldStyExtFile = os.path.join(self.local.projStyleFolder, oldMacPackId + "_ext.sty")
            oldTexExtFile = os.path.join(self.local.projTexFolder, oldMacPackId + "_ext.tex")
            oldTexPreStyExtFile = os.path.join(self.local.projTexFolder, oldMacPackId + "_preSty-ext.tex")
            newStyExtFile = os.path.join(self.local.projStyleFolder, macPackId + "_ext.sty")
            newTexExtFile = os.path.join(self.local.projTexFolder, macPackId + "_ext.tex")
            newTexPreStyExtFile = os.path.join(self.local.projTexFolder, macPackId + "_preSty-ext.tex")
            # By default, we protect any existing versions
            if os.path.exists(newStyExtFile):
                os.remove(oldStyExtFile)
            else:
                self.tools.renameFile(oldStyExtFile, newStyExtFile)
            if os.path.exists(newTexExtFile):
                os.remove(oldTexExtFile)
            else:
                self.tools.renameFile(oldTexExtFile, newTexExtFile)
            if os.path.exists(newTexPreStyExtFile):
                os.remove(oldTexPreStyExtFile)
            else:
                self.tools.renameFile(oldTexPreStyExtFile, newTexPreStyExtFile)
            # Remove un-needed sty and tex files from the newMacDir to
            # avoid confusion. The ext files never are updated because
            # they could contain custom project code that we don't want
            # to loose in an update.
            for f in self.getMacStyExtFiles(macPackId):
                source = os.path.join(newMacDir, f)
                if os.path.exists(source):
                    os.remove(source)
            for f in self.getMacTexExtFiles(macPackId):
                source = os.path.join(newMacDir, f)
                if os.path.exists(source):
                    os.remove(source)
            # Remove the old macPack folder
            shutil.rmtree(oldMacDir)
            # Merge new settings into old section (change name to new ID)
            # When updating, we are assuming the new macro is in the same
            # family as the old one. As such, settings should be almost
            # identical, but in case new settings are being added, we will
            # merge them in now.
            oldConfSettings = self.macroConfig["Macros"][oldMacPackId]
            newConfSettings = self.tools.getXMLSettings(confXml)
            # Now merge
            newConfSettings.merge(oldConfSettings)
            # Inject the new section
            #            self.tools.buildConfSection(self.macroConfig, macPackId)
            self.macroConfig["Macros"][macPackId] = newConfSettings.dict()
            # Delete the old section
            del self.macroConfig["Macros"][oldMacPackId]
            # Save the changes
            self.tools.writeConfFile(self.macroConfig)

            # Assuming everything went well we will change the macPackID on the cType
            self.projectConfig["CompTypes"][self.cType.capitalize()]["macroPackage"] = macPackId
            self.tools.writeConfFile(self.projectConfig)
            # Report success
            self.log.writeToLog(self.errorCodes["3600"], [self.cType.capitalize(), macPackId])
            return True
        # But if the install fails everything stays the same and we report
        else:
            self.log.writeToLog(self.errorCodes["3650"], [macPackId])
            return False

    def installMacPackOnly(self, source):
        """Install the new macro package but only that."""

        #        import pdb; pdb.set_trace()

        if self.tools.pkgExtract(source, self.local.projMacroFolder, self.local.macroConfXmlFile):
            return True
        else:
            self.log.writeToLog(self.errorCodes["3200"], [self.tools.fName(source)])
            return False
コード例 #2
0
ファイル: proj_macro.py プロジェクト: sillsdev/rapuma
class Macro (object) :

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

        self.pid                            = pid
        self.gid                            = gid
        self.cType                          = cType
        self.user                           = UserConfig()
        self.userConfig                     = self.user.userConfig
        self.projHome                       = os.path.join(os.path.expanduser(os.environ['RAPUMA_PROJECTS']), self.pid)
        self.local                          = ProjLocal(pid, gid, cType)


#        import pdb; pdb.set_trace()


        self.proj_config                    = Config(pid)
        self.proj_config.getProjectConfig()
        self.projectConfig                  = self.proj_config.projectConfig
        self.layoutConfig                   = self.proj_config.layoutConfig
        self.tools                          = Tools()
        self.log                            = ProjLog(pid)
        # Create config placeholders
        self.layoutConfig                   = None
        self.illustrationConfig             = None
        self.macroConfig                    = self.tools.loadConfig(self.local.macroConfFile, self.local.macroConfXmlFile)

        # Log messages for this module
        self.errorCodes     = {
            '3010' : ['ERR', 'No macro package is registered for the [<<1>>] component type.'],
            '3020' : ['ERR', 'Cannot update! No macro package is registered for the [<<1>>] component type.'],
            '3050' : ['ERR', 'Macro package file not found: [<<1>>]'],
            '3100' : ['ERR', 'Macro package: [<<1>>] already exists in the project. I am not allowed to copy over an existing package.'],
            '3200' : ['ERR', 'Failed to install macro package: [<<1>>]'],
            '3300' : ['MSG', 'Installed macro package: [<<1>>], Reinitialized [<<2>>]'],
            '3310' : ['ERR', 'Failed to copy [<<1>>] to folder [<<2>>].'],
            '3400' : ['MSG', 'Removed macro package configuration settings for: [<<1>>] from the macro.conf file.'],
            '3500' : ['MSG', 'Removed macro package [<<1>>] folder and all files contained.'],
            '3600' : ['MSG', 'Updated component type [<<1>>] with macro package [<<2>>]'],
            '3650' : ['ERR', 'Failed to updated macro package [<<1>>]']
        }

###############################################################################
###################### Macro Package Handling Functions #######################
###############################################################################
######################## Error Code Block Series = 3000 #######################
###############################################################################

    def createMacroFiles (self, macPackId) :
        '''Create all the necessary macro file names with their assigned paths.'''

        self.projMacPackFolder = os.path.join(self.local.projMacPackFolder, macPackId)

        texFileIds = {'preStyTexExtFile':'preSty-ext.tex', 'macSettingsFile':'settings.tex', 
                        'extTexFile':'extension.tex', 'grpExtTexFile': self.gid + '-extension.tex', 
                        '':'', '':'', '':'', '':'', '':'', }
        styFileIds = {'glbExtStyFile':'extension.sty', 'grpExtStyFile': self.gid + '-extension.sty', 
                        '':'', '':'', '':'', '':'', '':''}


    def getMacPackIdFromFileName (self, fileName) :
        '''Return the macPack ID based on the file name'''

        # File name less ext is the ID
        parts = len(fileName.split('.'))
        return '.'.join(fileName.split('.')[:parts-1])
    
    
    def getMacPackIdFromSource (self, source) :
        '''Return the macPack ID based on the complete path and file name.'''

        # Get the file name from the path
        fileName = self.tools.fName(source)
        # Return the ID
        return self.getMacPackIdFromFileName(fileName)


    def addMacPack (self, source) :
        '''Add a macro package to the project. It will not work if
        the same package is already present. Remove must be used
        to get rid of the existing one first.'''

#        import pdb; pdb.set_trace()

        macPackId = self.getMacPackIdFromSource(source)
        confXml = os.path.join(self.local.projMacroFolder, macPackId, macPackId + '.xml')
        if not os.path.isfile(source) :
            self.log.writeToLog(self.errorCodes['3050'], [source])

        # Do not add/install if there seems to be a macro package there already
        if self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] and os.path.exists(self.local.macroConfFile) :
            self.log.writeToLog(self.errorCodes['3100'], [macPackId])
            return False

        # Set the projectConf to the new/same package
        self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] = macPackId
        self.tools.writeConfFile(self.projectConfig)

        # If we got this far, install the a fresh copy of the macPack
        self.installMacPackOnly(source)
        # Move the style files and custom TeX files out of the macPack
        self.moveMacStyles(macPackId)
        self.moveMacTex(macPackId)

        # Create a fresh macro.conf file if it dosn't exist
        if not os.path.isfile(self.local.macroConfFile) :
            self.macroConfig = self.tools.initNewConfig(self.local.macroConfFile, self.local.macroConfXmlFile)
        # Inject information from this particular macro package
        mInfo = self.tools.getXMLSettings(confXml)
        self.macroConfig['Macros'][macPackId] = mInfo.dict()

        # Save the settings now
        self.tools.writeConfFile(self.macroConfig)

        self.log.writeToLog(self.errorCodes['3300'], [macPackId, self.local.macroConfFileName])
        
        return True


    def moveMacStyles (self, macPackId) :
        '''Move the default macro package styles out of the freshly installed
        project macro package folder to the project Style folder.'''


#        import pdb; pdb.set_trace()

        # Collect the style files to copy
        for f in self.getMacStyExtFiles(macPackId) :
            source = os.path.join(os.path.join(self.local.projMacroFolder, macPackId, f))
            target = os.path.join(self.local.projStyleFolder, f)
            self.tools.makedirs(self.local.projStyleFolder)
            # Do not overwrite existing files unless force is used
            if not os.path.exists(target) :
                shutil.copy(source, target)
                # Look for default and set to read-only
                defaultStyFile = os.path.join(self.local.projStyleFolder, macPackId + '.sty')
                if target == defaultStyFile :
                    self.tools.makeReadOnly(defaultStyFile)
            # Remove the source to avoid confusion
            if os.path.exists(target) :
                os.remove(source)
            else :
                self.log.writeToLog(self.errorCodes['3310'], [source,self.local.projStyleFolder])


    def getMacStyExtFiles (self, macPackId) :
        '''Return a list of macro package style extention files.'''

        sFiles = []
        macPackFiles = os.listdir(os.path.join(self.local.projMacroFolder, macPackId))
        for f in macPackFiles :
            if f.split('.')[1].lower() == 'sty' :
                sFiles.append(f)
        return sFiles


    def moveMacTex (self, macPackId) :
        '''Move the custom macro package TeX out of the freshly installed
        project macro package folder to the project TeX folder.'''

        # Collect the TeX extention files to copy
        for f in self.getMacTexExtFiles(macPackId) :
            source = os.path.join(os.path.join(self.local.projMacroFolder, macPackId, f))
            target = os.path.join(self.local.projTexFolder, f)
            self.tools.makedirs(self.local.projTexFolder)
            # Do not overwrite existing files
            if not os.path.exists(target) :
                shutil.copy(source, target)
            # Remove the source to avoid confusion
            if os.path.exists(target) :
                os.remove(source)
            else :
                self.log.writeToLog(self.errorCodes['3310'], [source,self.local.projTexFolder])


    def getMacTexExtFiles (self, macPackId) :
        '''Return a list of macro package TeX extention files.'''

        tFiles = []
        macPackFiles = os.listdir(os.path.join(self.local.projMacroFolder, macPackId))
        for f in macPackFiles :
            if f.find('ext.tex') > 0 :
                tFiles.append(f)
        return tFiles


    def removeMacPack (self) :
        '''Remove the macro package from a component type'''

#        import pdb; pdb.set_trace()

        if self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] != '' :
            macPackId = self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage']
        else :
            self.log.writeToLog(self.errorCodes['3010'], [self.cType])
        # Aquire target to delete
        target = os.path.join(self.local.projMacroFolder, macPackId)

        # Remove the macPack settings from the config file if it is there
        try :
            del self.macroConfig['Macros'][macPackId]
            # Save the settings now
            self.tools.writeConfFile(self.macroConfig)
            self.log.writeToLog(self.errorCodes['3400'], [macPackId])
        except :
            pass

        # Now remove the macro folder (with all its contents)
        if os.path.exists(target) :
            shutil.rmtree(target)
            self.log.writeToLog(self.errorCodes['3500'], [macPackId])

        # Remove any style files associated with the macro
        styTarget = os.path.join(self.local.projStyleFolder, macPackId + '.sty')
        self.tools.makeExecutable(styTarget)
        self.tools.removeFile(styTarget)

        # Remove the reference for this macro package from the component type
        # that uses it. Normally that would probably be just be one of them.
        self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] = ''
        self.tools.writeConfFile(self.projectConfig)


    def updateMacPack (self, source) :
        '''Update a macro package with the latest version but do not 
        touch the config file.'''


        # Do not update if no macro package is registered in the projectConfig
        if not self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] :
            self.log.writeToLog(self.errorCodes['3020'], [self.cType.capitalize()])
            return False

        macPackId = self.getMacPackIdFromSource(source)
        confXml = os.path.join(self.local.projMacroFolder, macPackId, macPackId + '.xml')
        oldMacPackId = self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage']
        oldMacDir = os.path.join(self.local.projMacroFolder, oldMacPackId)
        newMacDir = os.path.join(self.local.projMacroFolder, macPackId)

        # Install the new macPack (but use the old settings)
        if self.installMacPackOnly(source) :
            # The current macro system must have a "master" style file.
            # This is a version of the ParaText style file. Because
            # an update might include an update to the style file,
            # we need to copy that from the macro folder to the Style
            # folder. We will do that now. The name of the file should
            # be the macPackId + ".sty", in theory.
            srcStyleFile = os.path.join(self.local.projMacroFolder, macPackId, macPackId + '.sty')
            oldStyleFile = os.path.join(self.local.projStyleFolder, oldMacPackId + '.sty')
            newStyleFile = os.path.join(self.local.projStyleFolder, macPackId + '.sty')
            # Unlock the old one so it can be deleted.
            self.tools.makeExecutable(oldStyleFile)
            self.tools.removeFile(oldStyleFile)
            # Now copy in the new one.
            shutil.copy(srcStyleFile, newStyleFile)
            # The style file should never be edited by the user, relock it
            self.tools.makeReadOnly(newStyleFile)
            # Update exsisting extention file names. We never want to loose 
            # any settings that the user may have added to the extention
            # files so we will rename the existing files to have the
            # new ID otherwise the system will not find them at render time.
            oldStyExtFile           = os.path.join(self.local.projStyleFolder, oldMacPackId + '_ext.sty')
            oldTexExtFile           = os.path.join(self.local.projTexFolder, oldMacPackId + '_ext.tex')
            oldTexPreStyExtFile     = os.path.join(self.local.projTexFolder, oldMacPackId + '_preSty-ext.tex')
            newStyExtFile           = os.path.join(self.local.projStyleFolder, macPackId + '_ext.sty')
            newTexExtFile           = os.path.join(self.local.projTexFolder, macPackId + '_ext.tex')
            newTexPreStyExtFile     = os.path.join(self.local.projTexFolder, macPackId + '_preSty-ext.tex')
            # By default, we protect any existing versions
            if os.path.exists(newStyExtFile) :
                os.remove(oldStyExtFile)
            else :
                self.tools.renameFile(oldStyExtFile, newStyExtFile)
            if os.path.exists(newTexExtFile) :
                os.remove(oldTexExtFile)
            else :
                self.tools.renameFile(oldTexExtFile, newTexExtFile)
            if os.path.exists(newTexPreStyExtFile) :
                os.remove(oldTexPreStyExtFile)
            else :
                self.tools.renameFile(oldTexPreStyExtFile, newTexPreStyExtFile)
            # Remove un-needed sty and tex files from the newMacDir to
            # avoid confusion. The ext files never are updated because
            # they could contain custom project code that we don't want
            # to loose in an update.
            for f in self.getMacStyExtFiles(macPackId) :
                source = os.path.join(newMacDir, f)
                if os.path.exists(source) :
                    os.remove(source)
            for f in self.getMacTexExtFiles(macPackId) :
                source = os.path.join(newMacDir, f)
                if os.path.exists(source) :
                    os.remove(source)
            # Remove the old macPack folder
            shutil.rmtree(oldMacDir)
            # Merge new settings into old section (change name to new ID)
            # When updating, we are assuming the new macro is in the same
            # family as the old one. As such, settings should be almost
            # identical, but in case new settings are being added, we will
            # merge them in now.
            oldConfSettings = self.macroConfig['Macros'][oldMacPackId]
            newConfSettings = self.tools.getXMLSettings(confXml)
            # Now merge
            newConfSettings.merge(oldConfSettings)
            # Inject the new section
#            self.tools.buildConfSection(self.macroConfig, macPackId)
            self.macroConfig['Macros'][macPackId] = newConfSettings.dict()
            # Delete the old section
            del self.macroConfig['Macros'][oldMacPackId]
            # Save the changes
            self.tools.writeConfFile(self.macroConfig)

            # Assuming everything went well we will change the macPackID on the cType
            self.projectConfig['CompTypes'][self.cType.capitalize()]['macroPackage'] = macPackId
            self.tools.writeConfFile(self.projectConfig)
            # Report success
            self.log.writeToLog(self.errorCodes['3600'], [self.cType.capitalize(), macPackId])
            return True
        # But if the install fails everything stays the same and we report
        else :
            self.log.writeToLog(self.errorCodes['3650'], [macPackId])
            return False


    def installMacPackOnly (self, source) :
        '''Install the new macro package but only that.'''

#        import pdb; pdb.set_trace()

        if self.tools.pkgExtract(source, self.local.projMacroFolder, self.local.macroConfXmlFile) :
            return True
        else :
            self.log.writeToLog(self.errorCodes['3200'], [self.tools.fName(source)])
            return False
コード例 #3
0
ファイル: proj_font.py プロジェクト: jstnlth/rapuma
class ProjFont (object) :

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

        self.pid                            = pid
        self.tools                          = Tools()
        self.user                           = UserConfig()
        self.log                            = ProjLog(pid)
        self.userConfig                     = self.user.userConfig
        self.proj_config                    = Config(pid)
        self.proj_config.getProjectConfig()
        self.projectConfig                  = self.proj_config.projectConfig
        self.proj_config.getFontConfig()
        self.fontConfig                     = self.proj_config.fontConfig
        self.local                          = ProjLocal(pid, self.projectConfig)

        # Load all font settings for use in this module
        if self.fontConfig :
            for k, v in self.fontConfig['GeneralSettings'].iteritems() :
                setattr(self, k, v)

        # Log messages for this module
        self.errorCodes     = {
            'FONT-000' : ['MSG', 'Font module messages'],
            'FONT-005' : ['MSG', 'FONT-005 - Unassigned error message ID.'],
            'FONT-015' : ['MSG', 'FONT-015 - Unassigned error message ID.'],
            'FONT-020' : ['ERR', 'Failed to find font setting in ParaTExt project (.ssf file). A primary font must be set before this component can be successfully rendered.'],
            'FONT-025' : ['ERR', 'No source editor was found for this project. Please enter this setting before continuing.'],
            'FONT-042' : ['MSG', 'The [<<1>>] font setup information was added to project config'],
            'FONT-050' : ['ERR', 'Halt! [<<1>>] not found. - font.copyInFont()'],
            'FONT-070' : ['LOG', 'Copied the [<<1>>] font file into the project. - proj_font.copyInFont()'],
            'FONT-100' : ['ERR', 'This function has not been implemented yet!.  - proj_font.setGlyphMap()'],

            '0010' : ['LOG', 'Wrote out new font configuration (font.__init__())'],

            '1220' : ['ERR', 'The Font bundle file [<<1>>] could not be found. Process halted.'],
            '1235' : ['MSG', 'Font [<<1>>] has been installed into the project.'],
            '1237' : ['MSG', 'Font [<<1>>] has been updated.'],
            '1240' : ['ERR', 'Font bundle file [<<1>>] not found.'],
            '1241' : ['ERR', 'Font bundle [<<1>>] not found.'],
            '1245' : ['LOG', '<<1>> font setup information added to project config'],
            '1250' : ['ERR', 'The [<<1>>] font is apparently part of this project. Please remove before trying to re-add this font.'],
            '1260' : ['MSG', 'The <<1>> font bundle has been copied into the project font folder.'],
            '1262' : ['LOG', 'The <<1>> font bundle already exsits in the font folder.'],
            '1265' : ['ERR', 'Failed to extract the [<<1>>] font bundle into the project. Font install process failed.'],
            '1267' : ['LOG', 'The <<1>> font bundle has been copied into the project font folder.'],
            '1280' : ['MSG', 'Failed to install the font: [<<1>>] into the project.'],
            '1370' : ['LOG', 'Removed [<<1>>] font name from project component type: [<<2>>].'],
            '1380' : ['MSG', 'Removed the [<<1>>] font from the project.'],
            '1382' : ['MSG', 'Force switch was set (-f). This process has completely removed the [<<1>>] font and settings from the project. - proj_font.removeFont()'],
            '1390' : ['LOG', 'Removed the [<<1>>] font package.'],
            '1395' : ['MSG', 'Could not remove the [<<1>>] font package. It may be used by another group. Use force (-f) to remove the package from the font folder.']

        }


###############################################################################
############################ Project Level Functions ##########################
###############################################################################
######################## Error Code Block Series = 1000 #######################
###############################################################################


    def setGlyphMap (self, cType, font) :
        '''If needed, set the glyph map used for this component type font.'''

        self.log.writeToLog('FONT-100')


    def getFontIdFromFileName (self, fileName) :
        '''Return the font ID based on the file name'''

        # File name less ext is the font ID
        parts = len(fileName.split('.'))
        return '.'.join(fileName.split('.')[:parts-1])
    
    
    def getFontIdFromSource (self, source) :
        '''Return the font ID based on the complete path and file name.'''

        # Get the file name from the path
        fileName = self.tools.fName(source)
        # Return the font ID
        return self.getFontIdFromFileName(fileName)


    def recordFont (self, fontId, cType=None) :
        '''Check for the exsitance of the specified font in the font folder.
        Then extract the meta data into the appropreate configurations.'''

#        import pdb; pdb.set_trace()

        # Set vars do initial checks
        metaDataSource = os.path.join(self.local.projFontFolder, fontId, fontId + '.xml')
        if not os.path.isfile(metaDataSource) :
            self.log.writeToLog(self.errorCodes['1240'], [fontId + '.xml', 'proj_font.recordFont():1240'])
        
        # Build the Fonts section in the config (if needed)
        self.tools.buildConfSection(self.fontConfig, 'Fonts')

        # (Re)Inject the font info into the macPack config file.
        fInfo = self.tools.getXMLSettings(metaDataSource)
        self.fontConfig['Fonts'][fontId] = fInfo.dict()

        # Save the settings now
        self.tools.writeConfFile(self.fontConfig)
        
        # If a component type was specified, record that as well
        if cType :
            self.projectConfig['CompTypes'][cType.capitalize()]['fontName'] = fontId
            self.tools.writeConfFile(self.projectConfig)
        
        return True


    def copyInFont (self, source) :
        '''Copy a font into a project. The font is bundled with other 
        necessary components in a .zip file. If the font folder is
        already there we assume there is a font there and we do not 
        proceed. The user will be prompted to remove the old one first.'''

        fontId = self.getFontIdFromSource(source)
        confXml = os.path.join(self.local.projFontFolder, fontId, fontId + '.xml')
        if not os.path.isfile(source) :
            self.log.writeToLog(self.errorCodes['1220'], [source])

        # Install new copy
        if self.tools.pkgExtract(source, self.local.projFontFolder, confXml) :
            self.log.writeToLog(self.errorCodes['1260'], [self.tools.fName(source)])
            return True
        else :
            self.log.writeToLog(self.errorCodes['1265'], [fontId])
            return False


    def addFont (self, source, cType=None) :
        '''It is a three step process to install a font. This will both
        copy in a font and record it in one call. Do not try to 
        install a substitute font. Path is assumed to exsist and contains
        the file name too.'''

#        import pdb; pdb.set_trace()

        fontId = self.getFontIdFromSource(source)
        # Check for existance, never copy over
        if self.isFont(fontId) :
            self.log.writeToLog(self.errorCodes['1250'], [fontId])
        # Now install and record
        if self.copyInFont(source) and self.recordFont(fontId, cType) :
            self.log.writeToLog(self.errorCodes['1235'], [fontId])
            return True
        else :
            self.log.writeToLog(self.errorCodes['1280'], [fontId])
            return False


    def updateFontPack (self, source, cType=None) :
        '''Update a font package but do not change any of the existing
        settings. If there are setting issues (changes) it would be
        best to remove, then reinstall. A potential confusion point
        is that updating a font normally means changing the ID. Then
        updating actually becomes just installing a font.'''

#        import pdb; pdb.set_trace()

        # Get the font ID
        fontId      = self.getFontIdFromSource(source)
        # Be sure the font is in the project
        if self.isFont(fontId) :
            # Remove old copy
            if os.path.exists(os.path.join(self.local.projFontFolder, fontId)) :
                shutil.rmtree(os.path.join(self.local.projFontFolder, fontId))
            # Bring in a fresh copy
            if self.copyInFont(source) :
                # If a component type was specified, record that as well
                if cType :
                    self.projectConfig['CompTypes'][cType.capitalize()]['fontName'] = fontId
                    self.tools.writeConfFile(self.projectConfig)
                self.log.writeToLog(self.errorCodes['1237'], [fontId])
                return True


    def removeFontSettings (self, fontId) :
        '''Remove the font settings from the project.'''

#        import pdb; pdb.set_trace()
        if self.fontConfig.has_key('Fonts') :
            if self.fontConfig['Fonts'].has_key(fontId) :
                del self.fontConfig['Fonts'][fontId]
                # Write out the new settings files
                self.tools.writeConfFile(self.fontConfig)
                self.log.writeToLog(self.errorCodes['1380'], [fontId])
            # Check to see if this font is listed in any of the cTypes
            # If so, remove it.
            found = 0
            for cType in self.projectConfig['CompTypes'].keys() :
                # It might be possible that the cType has no font settings, so we check
                if self.projectConfig['CompTypes'][cType.capitalize()].has_key('fontName') :
                    if self.projectConfig['CompTypes'][cType.capitalize()]['fontName'] == fontId :
                        self.projectConfig['CompTypes'][cType.capitalize()]['fontName'] = ''
                        self.log.writeToLog(self.errorCodes['1370'], [fontId, cType])
                        found +=1
            if found > 0 :
                self.tools.writeConfFile(self.projectConfig)

            return True


    def removeFontPack (self, fontId) :
        '''Remove a font from a component type which will virtually disconnect 
        it from the calling component type. However, if the force switch is set,
        then remove the font, regardless as to if it is used by another component
        or not. This is useful for purging a font from a project but should be
        used with care.'''

        # Purge the font files and folder
        fontDir = os.path.join(self.local.projFontFolder, fontId)
        if os.path.exists(fontDir) :
            shutil.rmtree(fontDir)
            self.log.writeToLog(self.errorCodes['1390'], [fontId])

        if self.removeFontSettings(fontId) :
            return True


###############################################################################
############################ Font Settings Functions ##########################
###############################################################################
######################## Error Code Block Series = 2000 #######################
###############################################################################

    def isFont (self, fontId) :
        '''Return if it is varified that this font is part of the project.'''
        
        # First do a cusory check to see if at least the font folder is there
        fontDir = os.path.join(self.local.projFontFolder, fontId)
        if not os.path.exists(fontDir) :
            return False
            
        # If the above passed, check in the font config to see if it is listed
        if not self.fontConfig['Fonts'].has_key(fontId) :
            return False
        
        # If the two tests above passed it is probably there
        return True