--- 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_()