def get_resource_files(self, resource): """ Get a dict for all files assigned to a resource. First we calculate the files matching the file expression and then we apply all translation excpetions. The resulting dict will be in this format: { 'en': 'path/foo/en/bar.po', 'de': 'path/foo/de/bar.po', 'es': 'path/exceptions/es.po'} NOTE: All paths are relative to the root of the project """ tr_files = {} if self.config.has_section(resource): try: file_filter = self.config.get(resource, "file_filter") except ConfigParser.NoOptionError: file_filter = "$^" source_lang = self.config.get(resource, "source_lang") source_file = self.get_resource_option(resource, 'source_file') or None expr_re = regex_from_filefilter(file_filter, self.root) expr_rec = re.compile(expr_re) for root, dirs, files in os.walk(self.root): for f in files: f_path = os.path.abspath(os.path.join(root, f)) match = expr_rec.match(f_path) if match: lang = match.group(1) if lang != source_lang: f_path = relpath(f_path, self.root) if f_path != source_file: tr_files.update({lang: f_path}) for (name, value) in self.config.items(resource): if name.startswith("trans."): lang = name.split('.')[1] # delete language which has same file if value in tr_files.values(): keys = [] for k, v in tr_files.iteritems(): if v == value: keys.append(k) if len(keys) == 1: del tr_files[keys[0]] else: raise Exception("Your configuration seems wrong."\ " You have multiple languages pointing to"\ " the same file.") # Add language with correct file tr_files.update({lang: value}) return tr_files return None
def get_resource_files(self, resource): """ Get a dict for all files assigned to a resource. First we calculate the files matching the file expression and then we apply all translation excpetions. The resulting dict will be in this format: { 'en': 'path/foo/en/bar.po', 'de': 'path/foo/de/bar.po', 'es': 'path/exceptions/es.po'} NOTE: All paths are relative to the root of the project """ tr_files = {} if self.config.has_section(resource): try: file_filter = self.config.get(resource, "file_filter") except ConfigParser.NoOptionError: file_filter = "$^" source_lang = self.config.get(resource, "source_lang") source_file = self.get_resource_option(resource, 'source_file') or None expr_re = regex_from_filefilter(file_filter, self.root) expr_rec = re.compile(expr_re) for root, dirs, files in os.walk(self.root): for f in files: f_path = os.path.abspath(os.path.join(root, f)) match = expr_rec.match(f_path) if match: lang = match.group(1) if lang != source_lang: f_path = relpath(f_path, self.root) if f_path != source_file: tr_files.update({lang: f_path}) for (name, value) in self.config.items(resource): if name.startswith("trans."): lang = name.split('.')[1] # delete language which has same file if value in tr_files.values(): keys = [] for k, v in tr_files.iteritems(): if v == value: keys.append(k) if len(keys) == 1: del tr_files[keys[0]] else: raise Exception("Your configuration seems wrong."\ " You have multiple languages pointing to"\ " the same file.") # Add language with correct file tr_files.update({lang:value}) return tr_files return None
def _auto_local(path_to_tx, resource, source_language, expression, execute=False, source_file=None, regex=False): """Auto configure local project.""" # The path everything will be relative to curpath = os.path.abspath(os.curdir) # Force expr to be a valid regex expr (escaped) but keep <lang> intact expr_re = utils.regex_from_filefilter(expression, curpath) expr_rec = re.compile(expr_re) if not execute: logger.info("Only printing the commands which will be run if the " "--execute switch is specified.") # First, let's construct a dictionary of all matching files. # Note: Only the last matching file of a language will be stored. translation_files = {} for root, dirs, files in os.walk(curpath): for f in files: f_path = os.path.abspath(os.path.join(root, f)) match = expr_rec.match(f_path) if match: lang = match.group(1) f_path = os.path.abspath(f_path) if lang == source_language and not source_file: source_file = f_path else: translation_files[lang] = f_path if not source_file: raise Exception("Could not find a source language file. Please run" " set --source manually and then re-run this command or provide" " the source file with the -s flag.") if execute: logger.info("Updating source for resource %s ( %s -> %s )." % (resource, source_language, relpath(source_file, path_to_tx))) _set_source_file(path_to_tx, resource, source_language, relpath(source_file, path_to_tx)) else: logger.info('\ntx set --source -r %(res)s -l %(lang)s %(file)s\n' % { 'res': resource, 'lang': source_language, 'file': relpath(source_file, curpath)}) prj = project.Project(path_to_tx) root_dir = os.path.abspath(path_to_tx) if execute: try: prj.config.get("%s" % resource, "source_file") except ConfigParser.NoSectionError: raise Exception("No resource with slug \"%s\" was found.\nRun 'tx set --auto" "-local -r %s \"expression\"' to do the initial configuration." % resource) # Now let's handle the translation files. if execute: logger.info("Updating file expression for resource %s ( %s )." % (resource, expression)) # Eval file_filter relative to root dir file_filter = relpath(os.path.join(curpath, expression), path_to_tx) prj.config.set("%s" % resource, "file_filter", file_filter) else: for (lang, f_path) in sorted(translation_files.items()): logger.info('tx set -r %(res)s -l %(lang)s %(file)s' % { 'res': resource, 'lang': lang, 'file': relpath(f_path, curpath)}) if execute: prj.save()
def cmd_set(argv, path_to_tx): "Add local or remote files under transifex" parser = set_parser() (options, args) = parser.parse_args(argv) # Implement options/args checks # TODO !!!!!!! if options.local: try: expression = args[0] except IndexError: parser.error("Please specify an expression.") if not options.resource: parser.error("Please specify a resource") if not options.source_language: parser.error("Please specify a source language.") if not '<lang>' in expression: parser.error("The expression you have provided is not valid.") if not utils.valid_slug(options.resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _auto_local(path_to_tx, options.resource, source_language=options.source_language, expression = expression, source_file=options.source_file, execute=options.execute, regex=False) if options.execute: _set_minimum_perc(options.resource, options.minimum_perc, path_to_tx) _set_mode(options.resource, options.mode, path_to_tx) _set_type(options.resource, options.i18n_type, path_to_tx) return if options.remote: try: url = args[0] except IndexError: parser.error("Please specify an remote url") _auto_remote(path_to_tx, url) _set_minimum_perc(options.resource, options.minimum_perc, path_to_tx) _set_mode(options.resource, options.mode, path_to_tx) return if options.is_source: resource = options.resource if not resource: parser.error("You must specify a resource name with the" " -r|--resource flag.") lang = options.language if not lang: parser.error("Please specify a source language.") if len(args) != 1: parser.error("Please specify a file.") if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") file = args[0] # Calculate relative path path_to_file = relpath(file, path_to_tx) _set_source_file(path_to_tx, resource, options.language, path_to_file) elif options.resource or options.language: resource = options.resource lang = options.language if len(args) != 1: parser.error("Please specify a file") # Calculate relative path path_to_file = relpath(args[0], path_to_tx) try: _go_to_dir(path_to_tx) except UnInitializedError, e: utils.logger.error(e) return if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _set_translation(path_to_tx, resource, lang, path_to_file)
if not os.path.exists(path_to_file): raise Exception("tx: File ( %s ) does not exist." % os.path.join(path_to_tx, path_to_file)) # instantiate the project.Project prj = project.Project(path_to_tx) root_dir = os.path.abspath(path_to_tx) if root_dir not in os.path.normpath(os.path.abspath(path_to_file)): raise Exception("File must be under the project root directory.") logger.info("Setting source file for resource %s.%s ( %s -> %s )." % ( proj, res, lang, path_to_file)) path_to_file = relpath(path_to_file, root_dir) prj = project.Project(path_to_tx) # FIXME: Check also if the path to source file already exists. try: try: prj.config.get("%s.%s" % (proj, res), "source_file") except ConfigParser.NoSectionError: prj.config.add_section("%s.%s" % (proj, res)) except ConfigParser.NoOptionError: pass finally: prj.config.set("%s.%s" % (proj, res), "source_file", path_to_file) prj.config.set("%s.%s" % (proj, res), "source_lang",
def cmd_set(argv, path_to_tx): "Add local or remote files under transifex" class EpilogParser(OptionParser): def format_epilog(self, formatter): return self.epilog usage="usage: %prog [tx_options] set [options] [args]" description="This command can be used to create a mapping between files"\ " and projects either using local files or using files from a remote"\ " Transifex server." epilog="\nExamples:\n"\ " To set the source file:\n $ tx set -r project.resource --source -l en <file>\n\n"\ " To set a single translation file:\n $ tx set -r project.resource -l de <file>\n\n"\ " To automatically detect and assign translation files:\n"\ " $ tx set --auto-local -r project.resource 'expr'\n\n"\ " To automatically detect and assign the source files and translations:\n"\ " $ tx set --auto-local -r project.resource 'expr' --source-lang en\n\n"\ " To set a specific file as a source and auto detect translations:\n"\ " $ tx set --auto-local -r project.resource 'expr' --source-lang en"\ " --source-file <file>\n\n"\ " To set a remote release/resource/project:\n"\ " $ tx set --auto-remote <transifex-url>\n" parser = EpilogParser(usage=usage, description=description, epilog=epilog) parser.add_option("--auto-local", action="store_true", dest="local", default=False, help="Used when auto configuring local project.") parser.add_option("--auto-remote", action="store_true", dest="remote", default=False, help="Used when adding remote files from Transifex" " server.") parser.add_option("-r","--resource", action="store", dest="resource", default=None, help="Specify the slug of the resource that you're" " setting up (This must be in the following format:" " `project_slug.resource_slug`).") parser.add_option("--source", action="store_true", dest="is_source", default=False, help="Specify that added file a source file [doesn't" " work with the --auto-* commands].") parser.add_option("-l","--language", action="store", dest="language", default=None, help="Specify which translations you want to pull" " [doesn't work with the --auto-* commands].") group = OptionGroup(parser, "Extended options", "These options can only be" " used with the --auto-local command.") group.add_option("-s","--source-language", action="store", dest="source_language", default=None, help="Specify the source language of a resource" " [requires --auto-local].") group.add_option("-f","--source-file", action="store", dest="source_file", default=None, help="Specify the source file of a resource [requires" " --auto-local].") group.add_option("--execute", action="store_true", dest="execute", default=False, help="Execute commands [requires --auto-local].") parser.add_option_group(group) (options, args) = parser.parse_args(argv) # Implement options/args checks # TODO !!!!!!! # if --auto is true if options.local: try: expression = args[0] except IndexError: parser.error("Please specify an expression.") if not options.resource: parser.error("Please specify a resource") if not options.source_language: parser.error("Please specify a source language.") if not '<lang>' in expression: parser.error("The expression you have provided is not valid.") if not utils.valid_slug(options.resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _auto_local(path_to_tx, options.resource, source_language=options.source_language, expression = expression, source_file=options.source_file, execute=options.execute, nosource=False, regex=False) elif options.remote: try: url = args[0] except IndexError: parser.error("Please specify an remote url") _auto_remote(path_to_tx, url) # if we have --source, we set source elif options.is_source: resource = options.resource if not resource: parser.error("You must specify a resource name with the" " -r|--resource flag.") lang = options.language if not lang: parser.error("Please specify a source language.") if len(args) != 1: parser.error("Please specify a file.") if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") file = args[0] # Calculate relative path path_to_file = relpath(file, path_to_tx) _set_source_file(path_to_tx, resource, options.language, path_to_file) else: resource = options.resource lang = options.language if not resource or not lang: parser.error("You need to specify a resource and a language for the" " translation") if len(args) != 1: parser.error("Please specify a file") # Calculate relative path path_to_file = relpath(args[0], path_to_tx) try: _go_to_dir(path_to_tx) except UnInitializedError, e: utils.ERRMSG(e) return if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _set_translation(path_to_tx, resource, lang, path_to_file)
def _auto_local(path_to_tx, resource, source_language, expression, execute=False, source_file=None, regex=False): """Auto configure local project.""" # The path everything will be relative to curpath = os.path.abspath(os.curdir) # Force expr to be a valid regex expr (escaped) but keep <lang> intact expr_re = utils.regex_from_filefilter(expression, curpath) expr_rec = re.compile(expr_re) if not execute: logger.info("Only printing the commands which will be run if the " "--execute switch is specified.") # First, let's construct a dictionary of all matching files. # Note: Only the last matching file of a language will be stored. translation_files = {} for root, dirs, files in os.walk(curpath): for f in files: f_path = os.path.abspath(os.path.join(root, f)) match = expr_rec.match(f_path) if match: lang = match.group(1) f_path = os.path.abspath(f_path) if lang == source_language and not source_file: source_file = f_path else: translation_files[lang] = f_path if not source_file: raise Exception( "Could not find a source language file. Please run" " set --source manually and then re-run this command or provide" " the source file with the -s flag.") if execute: logger.info( "Updating source for resource %s ( %s -> %s )." % (resource, source_language, relpath(source_file, path_to_tx))) _set_source_file(path_to_tx, resource, source_language, relpath(source_file, path_to_tx)) else: logger.info( '\ntx set --source -r %(res)s -l %(lang)s %(file)s\n' % { 'res': resource, 'lang': source_language, 'file': relpath(source_file, curpath) }) prj = project.Project(path_to_tx) root_dir = os.path.abspath(path_to_tx) if execute: try: prj.config.get("%s" % resource, "source_file") except ConfigParser.NoSectionError: raise Exception( "No resource with slug \"%s\" was found.\nRun 'tx set --auto" "-local -r %s \"expression\"' to do the initial configuration." % resource) # Now let's handle the translation files. if execute: logger.info("Updating file expression for resource %s ( %s )." % (resource, expression)) # Eval file_filter relative to root dir file_filter = relpath(os.path.join(curpath, expression), path_to_tx) prj.config.set("%s" % resource, "file_filter", file_filter) else: for (lang, f_path) in sorted(translation_files.items()): logger.info('tx set -r %(res)s -l %(lang)s %(file)s' % { 'res': resource, 'lang': lang, 'file': relpath(f_path, curpath) }) if execute: prj.save()
def cmd_set(argv, path_to_tx): "Add local or remote files under transifex" parser = set_parser() (options, args) = parser.parse_args(argv) # Implement options/args checks # TODO !!!!!!! if options.local: try: expression = args[0] except IndexError: parser.error("Please specify an expression.") if not options.resource: parser.error("Please specify a resource") if not options.source_language: parser.error("Please specify a source language.") if not '<lang>' in expression: parser.error("The expression you have provided is not valid.") if not utils.valid_slug(options.resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _auto_local(path_to_tx, options.resource, source_language=options.source_language, expression=expression, source_file=options.source_file, execute=options.execute, regex=False) if options.execute: _set_minimum_perc(options.resource, options.minimum_perc, path_to_tx) _set_mode(options.resource, options.mode, path_to_tx) _set_type(options.resource, options.i18n_type, path_to_tx) return if options.remote: try: url = args[0] except IndexError: parser.error("Please specify an remote url") _auto_remote(path_to_tx, url) _set_minimum_perc(options.resource, options.minimum_perc, path_to_tx) _set_mode(options.resource, options.mode, path_to_tx) return if options.is_source: resource = options.resource if not resource: parser.error("You must specify a resource name with the" " -r|--resource flag.") lang = options.language if not lang: parser.error("Please specify a source language.") if len(args) != 1: parser.error("Please specify a file.") if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") file = args[0] # Calculate relative path path_to_file = relpath(file, path_to_tx) _set_source_file(path_to_tx, resource, options.language, path_to_file) elif options.resource or options.language: resource = options.resource lang = options.language if len(args) != 1: parser.error("Please specify a file") # Calculate relative path path_to_file = relpath(args[0], path_to_tx) try: _go_to_dir(path_to_tx) except UnInitializedError, e: utils.logger.error(e) return if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _set_translation(path_to_tx, resource, lang, path_to_file)
if not os.path.exists(path_to_file): raise Exception("tx: File ( %s ) does not exist." % os.path.join(path_to_tx, path_to_file)) # instantiate the project.Project prj = project.Project(path_to_tx) root_dir = os.path.abspath(path_to_tx) if root_dir not in os.path.normpath(os.path.abspath(path_to_file)): raise Exception("File must be under the project root directory.") logger.info("Setting source file for resource %s.%s ( %s -> %s )." % (proj, res, lang, path_to_file)) path_to_file = relpath(path_to_file, root_dir) prj = project.Project(path_to_tx) # FIXME: Check also if the path to source file already exists. try: try: prj.config.get("%s.%s" % (proj, res), "source_file") except ConfigParser.NoSectionError: prj.config.add_section("%s.%s" % (proj, res)) except ConfigParser.NoOptionError: pass finally: prj.config.set("%s.%s" % (proj, res), "source_file", path_to_file) prj.config.set("%s.%s" % (proj, res), "source_lang", lang)
fd.write(r) fd.close() if new_translations: MSG("Pulling new translations for resource %s (source: %s)" % (resource, sfile)) for lang in new_translations: if lang in lang_map.keys(): local_lang = lang_map[lang] else: local_lang = lang remote_lang = lang if file_filter: local_file = relpath( os.path.join(self.root, file_filter.replace('<lang>', local_lang)), os.curdir) else: trans_dir = os.path.join(self.root, ".tx", resource) if not os.path.exists(trans_dir): os.mkdir(trans_dir) local_file = relpath( os.path.join(trans_dir, '%s_translation' % local_lang, os.curdir)) MSG(" -> %s: %s" % (color_text(remote_lang, "RED"), local_file)) r = self.do_url_request('pull_file', url_info, language=remote_lang)
mkdir_p(base_dir) fd = open(local_file, 'wb') fd.write(r) fd.close() if new_translations: MSG("Pulling new translations for resource %s (source: %s)" % (resource, sfile)) for lang in new_translations: if lang in lang_map.keys(): local_lang = lang_map[lang] else: local_lang = lang remote_lang = lang if file_filter: local_file = relpath(os.path.join(self.root, file_filter.replace('<lang>', local_lang)), os.curdir) else: trans_dir = os.path.join(self.root, ".tx", resource) if not os.path.exists(trans_dir): os.mkdir(trans_dir) local_file = relpath(os.path.join(trans_dir, '%s_translation' % local_lang, os.curdir)) MSG(" -> %s: %s" % (color_text(remote_lang, "RED"), local_file)) r = self.do_url_request('pull_file', url_info, language=remote_lang) base_dir = os.path.split(local_file)[0] mkdir_p(base_dir) fd = open(local_file, 'wb') fd.write(r) fd.close()
def cmd_set(argv, path_to_tx): "Add local or remote files under transifex" class EpilogParser(OptionParser): def format_epilog(self, formatter): return self.epilog usage = "usage: %prog [tx_options] set [options] [args]" description="This command can be used to create a mapping between files"\ " and projects either using local files or using files from a remote"\ " Transifex server." epilog="\nExamples:\n"\ " To set the source file:\n $ tx set -r project.resource --source -l en <file>\n\n"\ " To set a single translation file:\n $ tx set -r project.resource -l de <file>\n\n"\ " To automatically detect and assign translation files:\n"\ " $ tx set --auto-local -r project.resource 'expr'\n\n"\ " To automatically detect and assign the source files and translations:\n"\ " $ tx set --auto-local -r project.resource 'expr' --source-lang en\n\n"\ " To set a specific file as a source and auto detect translations:\n"\ " $ tx set --auto-local -r project.resource 'expr' --source-lang en"\ " --source-file <file>\n\n"\ " To set a remote release/resource/project:\n"\ " $ tx set --auto-remote <transifex-url>\n" parser = EpilogParser(usage=usage, description=description, epilog=epilog) parser.add_option("--auto-local", action="store_true", dest="local", default=False, help="Used when auto configuring local project.") parser.add_option("--auto-remote", action="store_true", dest="remote", default=False, help="Used when adding remote files from Transifex" " server.") parser.add_option("-r", "--resource", action="store", dest="resource", default=None, help="Specify the slug of the resource that you're" " setting up (This must be in the following format:" " `project_slug.resource_slug`).") parser.add_option("--source", action="store_true", dest="is_source", default=False, help="Specify that added file a source file [doesn't" " work with the --auto-* commands].") parser.add_option("-l", "--language", action="store", dest="language", default=None, help="Specify which translations you want to pull" " [doesn't work with the --auto-* commands].") group = OptionGroup( parser, "Extended options", "These options can only be" " used with the --auto-local command.") group.add_option("-s", "--source-language", action="store", dest="source_language", default=None, help="Specify the source language of a resource" " [requires --auto-local].") group.add_option("-f", "--source-file", action="store", dest="source_file", default=None, help="Specify the source file of a resource [requires" " --auto-local].") group.add_option("--execute", action="store_true", dest="execute", default=False, help="Execute commands [requires --auto-local].") parser.add_option_group(group) (options, args) = parser.parse_args(argv) # Implement options/args checks # TODO !!!!!!! # if --auto is true if options.local: try: expression = args[0] except IndexError: parser.error("Please specify an expression.") if not options.resource: parser.error("Please specify a resource") if not options.source_language: parser.error("Please specify a source language.") if not '<lang>' in expression: parser.error("The expression you have provided is not valid.") if not utils.valid_slug(options.resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _auto_local(path_to_tx, options.resource, source_language=options.source_language, expression=expression, source_file=options.source_file, execute=options.execute, nosource=False, regex=False) elif options.remote: try: url = args[0] except IndexError: parser.error("Please specify an remote url") _auto_remote(path_to_tx, url) # if we have --source, we set source elif options.is_source: resource = options.resource if not resource: parser.error("You must specify a resource name with the" " -r|--resource flag.") lang = options.language if not lang: parser.error("Please specify a source language.") if len(args) != 1: parser.error("Please specify a file.") if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") file = args[0] # Calculate relative path path_to_file = relpath(file, path_to_tx) _set_source_file(path_to_tx, resource, options.language, path_to_file) else: resource = options.resource lang = options.language if not resource or not lang: parser.error( "You need to specify a resource and a language for the" " translation") if len(args) != 1: parser.error("Please specify a file") # Calculate relative path path_to_file = relpath(args[0], path_to_tx) try: _go_to_dir(path_to_tx) except UnInitializedError, e: utils.ERRMSG(e) return if not utils.valid_slug(resource): parser.error("Invalid resource slug. The format is <project_slug>"\ ".<resource_slug> and the valid characters include [_-\w].") _set_translation(path_to_tx, resource, lang, path_to_file)