ProjectPyramid/Project.py

changeset 3
76c45d31d462
parent 2
e691c51ab655
child 5
455dc39cd212
--- a/ProjectPyramid/Project.py	Tue Aug 28 17:15:21 2012 +0200
+++ b/ProjectPyramid/Project.py	Tue Aug 28 19:51:52 2012 +0200
@@ -9,6 +9,7 @@
 
 import os
 import configparser
+import re
 
 from PyQt4.QtCore import QObject, QFileInfo, QProcess, QTimer, QUrl
 from PyQt4.QtGui import QMenu, QDialog, QInputDialog, QDesktopServices
@@ -263,23 +264,25 @@
             self.__formsBrowser.addHookMethodAndMenuEntry("newForm", 
                 self.newForm, self.trUtf8("New template..."))
             
-##            self.__e5project.projectLanguageAddedByCode.connect(
-##                self.__projectLanguageAdded)
-##            self.__translationsBrowser = \
-##                e5App().getObject("ProjectBrowser").getProjectBrowser("translations")
-##            self.__translationsBrowser.addHookMethodAndMenuEntry("extractMessages", 
-##                self.extractMessages, self.trUtf8("Extract messages"))
-##            self.__translationsBrowser.addHookMethodAndMenuEntry("releaseAll", 
-##                self.compileCatalogs, self.trUtf8("Compile all catalogs"))
-##            self.__translationsBrowser.addHookMethodAndMenuEntry("releaseSelected", 
-##                self.compileSelectedCatalogs, 
-##                self.trUtf8("Compile selected catalogs"))
-##            self.__translationsBrowser.addHookMethodAndMenuEntry("generateAll", 
-##                self.updateCatalogs, self.trUtf8("Update all catalogs"))
-##            self.__translationsBrowser.addHookMethodAndMenuEntry("generateSelected", 
-##                self.updateSelectedCatalogs, self.trUtf8("Update selected catalogs"))
-            
-            self.__hooksInstalled = True
+            if self.__e5project.getProjectLanguage() == "Python2":
+                # Babel and lingua are not yet available for Python 3
+                self.__e5project.projectLanguageAddedByCode.connect(
+                    self.__projectLanguageAdded)
+                self.__translationsBrowser = \
+                    e5App().getObject("ProjectBrowser").getProjectBrowser("translations")
+                self.__translationsBrowser.addHookMethodAndMenuEntry("extractMessages", 
+                    self.extractMessages, self.trUtf8("Extract Messages"))
+                self.__translationsBrowser.addHookMethodAndMenuEntry("releaseAll", 
+                    self.compileCatalogs, self.trUtf8("Compile All Catalogs"))
+                self.__translationsBrowser.addHookMethodAndMenuEntry("releaseSelected", 
+                    self.compileSelectedCatalogs, 
+                    self.trUtf8("Compile Selected Catalogs"))
+                self.__translationsBrowser.addHookMethodAndMenuEntry("generateAll", 
+                    self.updateCatalogs, self.trUtf8("Update All Catalogs"))
+                self.__translationsBrowser.addHookMethodAndMenuEntry("generateSelected", 
+                    self.updateSelectedCatalogs, self.trUtf8("Update Selected Catalogs"))
+                
+                self.__hooksInstalled = True
     
     def projectClosedHooks(self):
         """
@@ -289,16 +292,16 @@
             self.__formsBrowser.removeHookMethod("newForm")
             self.__formsBrowser = None
             
-##            self.__e5project.projectLanguageAddedByCode.disconnect(
-##                self.__projectLanguageAdded)
-##            self.__translationsBrowser.removeHookMethod("extractMessages")
-##            self.__translationsBrowser.removeHookMethod("releaseAll")
-##            self.__translationsBrowser.removeHookMethod("releaseSelected")
-##            self.__translationsBrowser.removeHookMethod("generateAll")
-##            self.__translationsBrowser.removeHookMethod("generateSelected")
-##            self.__translationsBrowser = None
-            
-            self.__hooksInstalled = False
+            self.__e5project.projectLanguageAddedByCode.disconnect(
+                self.__projectLanguageAdded)
+            self.__translationsBrowser.removeHookMethod("extractMessages")
+            self.__translationsBrowser.removeHookMethod("releaseAll")
+            self.__translationsBrowser.removeHookMethod("releaseSelected")
+            self.__translationsBrowser.removeHookMethod("generateAll")
+            self.__translationsBrowser.removeHookMethod("generateSelected")
+            self.__translationsBrowser = None
+        
+        self.__hooksInstalled = False
     
     def newForm(self, path):
         """
@@ -576,10 +579,13 @@
         if self.__currentProject is None:
             self.__e5project.pdata["TRANSLATIONPATTERN"] = []
         else:
-            # TODO: adjust this to the Pyramid docu
+            config = configparser.ConfigParser()
+            config.read(os.path.join(self.__projectPath(), "setup.cfg"))
+            outputDir = config.get("init_catalog", "output_dir")
+            domain = config.get("init_catalog", "domain")
             self.__e5project.pdata["TRANSLATIONPATTERN"] = [
-                os.path.join(project, project.lower(), "i18n", "%language%", 
-                    "LC_MESSAGES", "%s.po" % project.lower())
+                os.path.join(project, outputDir, "%language%", 
+                    "LC_MESSAGES", "{0}.po".format(domain))
             ]
     
     def __project(self):
@@ -794,3 +800,289 @@
         """
         page = self.__plugin.getPreferences("PyramidDocUrl")
         self.__ui.launchHelpViewer(page)
+    
+    ##################################################################
+    ## slots below implement translation functions
+    ##################################################################
+    
+    def __getLocale(self, filename):
+        """
+        Private method to extract the locale out of a file name.
+        
+        @param filename name of the file used for extraction (string)
+        @return extracted locale (string) or None
+        """
+        if self.__e5project.pdata["TRANSLATIONPATTERN"]:
+            pattern = self.__e5project.pdata["TRANSLATIONPATTERN"][0]\
+                .replace("%language%", "(.*?)")
+            match = re.search(pattern, filename)
+            if match is not None:
+                loc = match.group(1)
+                return loc
+            else:
+                loc = None
+        else:
+            loc = None
+        
+        return loc
+    
+    def __normalizeList(self, filenames):
+        """
+        Private method to normalize a list of file names.
+        
+        @param filenames list of file names to normalize (list of string)
+        @return normalized file names (list of string)
+        """
+        nfilenames = []
+        for filename in filenames:
+            if filename.endswith(".mo"):
+                filename = filename.replace(".mo", ".po")
+            if filename not in nfilenames:
+                nfilenames.append(filename)
+        
+        return nfilenames
+    
+    def __projectFilteredList(self, filenames):
+        """
+        Private method to filter a list of file names by Pyramid project.
+        
+        @param filenames list of file names to be filtered (list of string)
+        @return file names belonging to the current site (list of string)
+        """
+        project = self.__project()
+        nfilenames = []
+        for filename in filenames:
+            if filename.startswith(project + os.sep):
+                nfilenames.append(filename)
+        
+        return nfilenames
+    
+    def extractMessages(self):
+        """
+        Public method to extract the messages catalog template file.
+        """
+        title = self.trUtf8("Extract messages")
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        cmd = self.getPythonCommand()
+        args = []
+        args.append("setup.py")
+        args.append("extract_messages")
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessages extracted successfully."))
+        res = dia.startProcess(cmd, args, projectPath)
+        if res:
+            dia.exec_()
+            
+            config = configparser.ConfigParser()
+            config.read(os.path.join(projectPath, "setup.cfg"))
+            potFile = config.get("extract_messages", "output_file")
+            if potFile:
+                self.__e5project.appendFile(os.path.join(projectPath, potFile))
+            else:
+                try:
+                    lowerProject = self.__project().lower()
+                except PyramidNoProjectSelectedException:
+                    E5MessageBox.warning(self.__ui,
+                        title,
+                        self.trUtf8('No current Pyramid project selected or no Pyramid'
+                                    ' project created yet. Aborting...'))
+                    return
+                
+                self.__e5project.appendFile(os.path.join(
+                    projectPath, lowerProject, "locale", "%s.pot" % lowerProject))
+    
+    def __projectLanguageAdded(self, code):
+        """
+        Private slot handling the addition of a new language.
+        
+        @param code language code of the new language (string)
+        """
+        title = self.trUtf8("Initializing message catalog for '%1'").arg(code)
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        cmd = self.getPythonCommand()
+        args = []
+        args.append("setup.py")
+        args.append("init_catalog")
+        args.append("-l")
+        args.append(code)
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessage catalog initialized successfully."))
+        res = dia.startProcess(cmd, args, projectPath)
+        if res:
+            dia.exec_()
+            
+            langFile = self.__e4project.pdata["TRANSLATIONPATTERN"][0]\
+                .replace("%language%", code)
+            self.__e5project.appendFile(langFile)
+    
+    def compileCatalogs(self, filenames):
+        """
+        Public method to compile the message catalogs.
+        
+        @param filenames list of filenames (not used)
+        """
+        title = self.trUtf8("Compiling message catalogs")
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        cmd = self.getPythonCommand()
+        args = []
+        args.append("setup.py")
+        args.append("compile_catalog")
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessage catalogs compiled successfully."))
+        res = dia.startProcess(cmd, args, projectPath)
+        if res:
+            dia.exec_()
+        
+            for entry in os.walk(projectPath):
+                for fileName in entry[2]:
+                    fullName = os.path.join(entry[0], fileName)
+                    if fullName.endswith('.mo'):
+                        self.__e5project.appendFile(fullName)
+    
+    def compileSelectedCatalogs(self, filenames):
+        """
+        Public method to update the message catalogs.
+        
+        @param filenames list of file names (list of string)
+        """
+        title = self.trUtf8("Compiling message catalogs")
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        argsLists = []
+        
+        for filename in self.__normalizeList(self.__projectFilteredList(filenames)):
+            locale = self.__getLocale(filename)
+            if locale:
+                args = []
+                args.append(self.getPythonCommand())
+                args.append("setup.py")
+                args.append("compile_catalog")
+                args.append("-l")
+                args.append(locale)
+                argsLists.append(args)
+        
+        if len(argsLists) == 0:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No locales detected. Aborting...'))
+            return
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessage catalogs compiled successfully."))
+        res = dia.startBatchProcesses(argsLists, projectPath)
+        if res:
+            dia.exec_()
+            
+            for entry in os.walk(self.__sitePath()):
+                for fileName in entry[2]:
+                    fullName = os.path.join(entry[0], fileName)
+                    if fullName.endswith('.mo'):
+                        self.__e5project.appendFile(fullName)
+    
+    def updateCatalogs(self, filenames):
+        """
+        Public method to update the message catalogs.
+        
+        @param filenames list of filenames (not used)
+        """
+        title = self.trUtf8("Updating message catalogs")
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        cmd = self.getPythonCommand()
+        args = []
+        args.append("setup.py")
+        args.append("update_catalog")
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessage catalogs updated successfully."))
+        res = dia.startProcess(cmd, args, projectPath)
+        if res:
+            dia.exec_()
+    
+    def updateSelectedCatalogs(self, filenames):
+        """
+        Public method to update the message catalogs.
+        
+        @param filenames list of filenames
+        """
+        title = self.trUtf8("Updating message catalogs")
+        try:
+            projectPath = self.__projectPath()
+        except PyramidNoProjectSelectedException:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No current Pyramid project selected or no Pyramid project'
+                            ' created yet. Aborting...'))
+            return
+        
+        argsLists = []
+        
+        for filename in self.__normalizeList(self.__projectFilteredList(filenames)):
+            locale = self.__getLocale(filename)
+            if locale:
+                args = []
+                args.append(self.getPythonCommand())
+                args.append("setup.py")
+                args.append("update_catalog")
+                args.append("-l")
+                args.append(locale)
+                argsLists.append(args)
+        
+        if len(argsLists) == 0:
+            E5MessageBox.warning(self.__ui,
+                title,
+                self.trUtf8('No locales detected. Aborting...'))
+            return
+        
+        dia = PyramidDialog(title, 
+            msgSuccess = \
+                self.trUtf8("\nMessage catalogs updated successfully."))
+        res = dia.startBatchProcesses(argsLists, projectPath)
+        if res:
+            dia.exec_()

eric ide

mercurial