def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.a_or_an = "an" if app_or_project == "app" else "a" self.paths_to_remove = [] self.verbosity = options["verbosity"] self.validate_name(name) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = os.path.join(os.getcwd(), name) try: os.makedirs(top_dir) except FileExistsError: raise CommandError("'%s' already exists" % top_dir) except OSError as e: raise CommandError(e) else: top_dir = os.path.abspath(os.path.expanduser(target)) if app_or_project == "app": self.validate_name(os.path.basename(top_dir), "directory") if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options["extensions"])) extra_files = [] excluded_directories = [".git", "__pycache__"] for file in options["files"]: extra_files.extend(map(lambda x: x.strip(), file.split(","))) if exclude := options.get("exclude"): for directory in exclude: excluded_directories.append(directory.strip())
def handle(self, **options): self.verbosity = 2 self.storage = staticfiles_storage extensions = options.get('extensions') or ['html'] self.symlinks = options.get('symlinks') self.post_process = options['post_process'] # self.post_processed_files = [] self.extensions = handle_extensions(extensions) template_dirs = list(get_app_template_dirs('templates')) for config in settings.TEMPLATES: # only support vanilla Django templates if config['BACKEND'] != 'django.template.backends.django.DjangoTemplates': continue template_dirs += list(config['DIRS']) # find all template files all_files = [] for template_dir in template_dirs: for dirpath, dirnames, filenames in os.walk(template_dir, topdown=True, followlinks=self.symlinks): for filename in filenames: filepath = os.path.join(dirpath, filename) file_ext = os.path.splitext(filename)[1] if file_ext not in self.extensions: continue all_files.append(filepath) all_apps = [] for fp in all_files: with io.open(fp, 'r', encoding=settings.FILE_CHARSET) as template_file: src_data = template_file.read() for t in Lexer(src_data, None).tokenize(): if t.token_type == TOKEN_BLOCK: imatch = SYSTEMJS_TAG_RE.match(t.contents) if imatch: all_apps.append(imatch.group('app')) bundled_files = OrderedDict() storage = FileSystemStorage(settings.STATIC_ROOT, base_url=settings.STATIC_URL) for app in all_apps: rel_path = System.bundle(app, force=True) bundled_files[rel_path] = (storage, rel_path) if self.post_process and hasattr(self.storage, 'post_process'): processor = self.storage.post_process(bundled_files, dry_run=False) for original_path, processed_path, processed in processor: if isinstance(processed, Exception): # pragma: no cover self.stderr.write("Post-processing '%s' failed!" % original_path) # Add a blank line before the traceback, otherwise it's # too easy to miss the relevant part of the error message. self.stderr.write("") raise processed if processed: # pragma: no cover self.log("Post-processed '%s' as '%s'" % (original_path, processed_path), level=1) else: self.log("Skipped post-processing '%s'" % original_path) # pragma: no cover
def handle_noargs(self, *args, **options): global template_dirs # TODO: find a more elegant solution for this global template_exts template_dirs = options.get('template_dirs') template_exts = handle_extensions(options.get('template_exts')) return super(Command, self).handle_noargs(*args, **options)
def handle(self, *args, **options): self.domain = options['domain'] self.verbosity = options['verbosity'] self.ignore_patterns = [] self.purge = options['purge'] self.symlinks = options['symlinks'] extensions = options['extensions'] if self.domain == 'djangojs': exts = extensions if extensions else ['js'] else: exts = extensions if extensions else ['html', 'txt', 'py'] self.extensions = handle_extensions(exts) self.locale_paths = [] self.default_locale_path = None self.string_collection = SourceStringCollection() # Create an extractor for Python files, to reuse for all files self.python_extractor = Extractor() # Support `t()` and `ut()` calls made on the Django module. self.python_extractor.register_functions( 'transifex.native.django.t', 'transifex.native.django.ut', 'transifex.native.django.lazyt') self.stats = {'processed_files': 0, 'strings': []} # Search all related files and collect translatable strings, # storing them in `self.string_collection` self.collect_strings() # Push the strings to the CDS self.push_strings()
def get_command(cls, app_name, domain): assert domain in ('django', 'djangojs') check_programs('xgettext', 'msguniq', 'msgmerge', 'msgattrib') co = cls() co.domain = domain co.extensions = handle_extensions(GETTEXT_EXTENSIONS[domain]) co._update_locale_paths(app_name) return co
def handle(self, *args, **options): self.domain = options['domain'] self.verbosity = options['verbosity'] self.ignore_patterns = [] self.path = options['path'] self.files = set(options['files'] or []) exts = MIGRATE_EXTENSIONS self.extensions = handle_extensions(exts) self.stats = { 'processed_files': 0, 'migrations': [], 'saved': [], 'errors': [], } # Create a reusable migrator for templates code self.django_migration_builder = DjangoTagMigrationBuilder() self.gettext_migration_builder = GettextMigrationBuilder( methods=GettextMethods(**GETTEXT_FUNCTIONS), import_statement=T_IMPORT, ) # -- Text mode: simply transform the given text and exit text = options['text'] if text: migrate_text(text, self._migrate_text) return # -- File mode: read all files based on the given options and migrate # each of them self.executor = MigrationExecutor( options, file_migrator_func=self._migrate_file, ) # Show an intro message self.executor.show_intro() # If specific files are defined, use those if self.files: dirpath = os.getcwd() files = [ TranslatableFile(dirpath, filename) for filename in self.files ] # Else search the file path for supported files else: files = self._find_files(self.path, 'migrate') # Execute the migration self.executor.migrate_files(files)
def _prepare_extensions(self, options): """ Подготовка расширений файлов """ self.extensions = tuple(handle_extensions(options['extensions'])) if self.verbosity >= 2: self.stdout.write( f'Rendering {self.app_or_project} template files with extensions: {", ".join(self.extensions)}\n' ) self.stdout.write( f'Rendering {self.app_or_project} template files with filenames: {", ".join(self.extra_files)}\n' )
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.a_or_an = 'an' if app_or_project == 'app' else 'a' self.paths_to_remove = [] self.verbosity = options['verbosity'] self.validate_name(name) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = os.path.join(os.getcwd(), name) try: os.makedirs(top_dir) except FileExistsError: raise CommandError("'%s' already exists" % top_dir) except OSError as e: raise CommandError(e) else: if app_or_project == 'app': self.validate_name(os.path.basename(target), 'directory') top_dir = os.path.abspath(os.path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options['extensions'])) extra_files = [] for file in options['files']: extra_files.extend(map(lambda x: x.strip(), file.split(','))) if self.verbosity >= 2: self.stdout.write( 'Rendering %s template files with extensions: %s' % (app_or_project, ', '.join(extensions))) self.stdout.write( 'Rendering %s template files with filenames: %s' % (app_or_project, ', '.join(extra_files))) base_name = '%s_name' % app_or_project base_subdir = '%s_template' % app_or_project base_directory = '%s_directory' % app_or_project camel_case_name = 'camel_case_%s_name' % app_or_project camel_case_value = ''.join(x for x in name.title() if x != '_') context = Context( { **options, base_name: name, base_directory: top_dir, camel_case_name: camel_case_value, 'docs_version': get_docs_version(), 'django_version': django.__version__, }, autoescape=False) # Setup a stub settings environment for template rendering if not settings.configured: settings.configure() django.setup() template_dir = self.handle_template(options['template'], base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = os.path.join(top_dir, relative_dir) os.makedirs(target_dir, exist_ok=True) for dirname in dirs[:]: if dirname.startswith('.') or dirname == '__pycache__': dirs.remove(dirname) for filename in files: if filename.endswith(('.pyo', '.pyc', '.py.class')): # Ignore some files as they cause various breakages. continue old_path = os.path.join(root, filename) new_path = os.path.join(top_dir, relative_dir, filename.replace(base_name, name)) for old_suffix, new_suffix in self.rewrite_template_suffixes: if new_path.endswith(old_suffix): new_path = new_path[:-len(old_suffix)] + new_suffix break # Only rewrite once if os.path.exists(new_path): raise CommandError( "%s already exists. Overlaying %s %s into an existing " "directory won't replace conflicting files." % ( new_path, self.a_or_an, app_or_project, )) # Only render the Python files, as we don't want to # accidentally render Django templates files if new_path.endswith(extensions) or filename in extra_files: with open(old_path, encoding='utf-8') as template_file: content = template_file.read() template = Engine().from_string(content) content = template.render(context) with open(new_path, 'w', encoding='utf-8') as new_file: new_file.write(content) else: shutil.copyfile(old_path, new_path) if self.verbosity >= 2: self.stdout.write('Creating %s' % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write('Cleaning up temporary files.') for path_to_remove in self.paths_to_remove: if os.path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove)
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = int(options.get("verbosity")) self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) except OSError as e: if e.errno == errno.EEXIST: message = "'%s' already exists" % top_dir else: message = e raise CommandError(message) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options.get("extensions"), ignored=())) extra_files = [] for file in options.get("files"): extra_files.extend(map(lambda x: x.strip(), file.split(","))) if self.verbosity >= 2: self.stdout.write( "Rendering %s template files with " "extensions: %s\n" % (app_or_project, ", ".join(extensions)) ) self.stdout.write( "Rendering %s template files with " "filenames: %s\n" % (app_or_project, ", ".join(extra_files)) ) base_name = "%s_name" % app_or_project base_subdir = "%s_template" % app_or_project base_directory = "%s_directory" % app_or_project if django.VERSION[-2] != "final": docs_version = "dev" else: docs_version = "%d.%d" % django.VERSION[:2] context = Context( dict(options, **{base_name: name, base_directory: top_dir, "docs_version": docs_version}), autoescape=False ) # Setup a stub settings environment for template rendering from django.conf import settings if not settings.configured: settings.configure() template_dir = self.handle_template(options.get("template"), base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for dirname in dirs[:]: if dirname.startswith(".") or dirname == "__pycache__": dirs.remove(dirname) for filename in files: if filename.endswith((".pyo", ".pyc", ".py.class")): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) if path.exists(new_path): raise CommandError( "%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path ) # Only render the Python files, as we don't want to # accidentally render Django templates files with open(old_path, "rb") as template_file: content = template_file.read() if filename.endswith(extensions) or filename in extra_files: content = content.decode("utf-8") template = Template(content) content = template.render(context) content = content.encode("utf-8") with open(new_path, "wb") as new_file: new_file.write(content) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE, ) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove, onerror=rmtree_errorhandler)
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = options["verbosity"] self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded top_dir = self.get_top_dir(target, name) extensions = tuple(handle_extensions(options["extensions"])) extra_files = ["csrftoken.js"] for file in options["files"]: extra_files.extend(map(lambda x: x.strip(), file.split(","))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ", ".join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ", ".join(extra_files))) base_name = "%s_name" % app_or_project base_subdir = "%s_template" % app_or_project base_directory = "%s_directory" % app_or_project context = Context( dict( options, **{ base_name: name, base_directory: top_dir, "docs_version": get_docs_version(), "django_version": django.__version__, }), autoescape=False, ) # Setup a stub settings environment for template rendering from django.conf import settings if not settings.configured: settings.configure() template_dir = self.handle_template(options["template"], base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for dirname in dirs[:]: if dirname.startswith(".") or dirname == "__pycache__": dirs.remove(dirname) # 处理多版本差异,将只对指定版本初始化 if "run_ver" in options and os.path.basename(root) == "sites": if dirname != options["run_ver"]: dirs.remove(dirname) for filename in files: if filename.endswith((".pyo", ".pyc", ".py.class")): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) if path.exists(new_path): raise CommandError("%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path) # Only render the Python files, as we don't want to # accidentally render Django templates files with open(old_path, "rb") as template_file: content = template_file.read() if filename.endswith(extensions) or filename in extra_files: content = content.decode("utf-8") template = Engine().from_string(content) content = template.render(context) content = content.encode("utf-8") with open(new_path, "wb") as new_file: new_file.write(content) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE, ) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove)
def find_translatable_files(start_path=settings.BASE_DIR, ignore=(), extensions=()): """Returns list of the paths to the files with translatable strings. :param start_path: path from which start search; :param ignore: ignore patterns; :param extensions: allowed file extensions; """ # copy pasted with minimal changes from: # line: 457, file: django.core.management.commands.makemessages # define allowed for search file extensions extensions = handle_extensions(extensions) # define ignore patterns _ignore = consts.DEFAULT_TRANSLATION_IGNORE_PATTERNS + list(ignore) ignore_patterns = [os.path.normcase(p) for p in _ignore] # define directory suffixes dir_suffixes = {'%s*' % path_sep for path_sep in {'/', os.sep}} # define normalized ignore patterns that do not ends with dir suffix normalized_ignore_patterns = [] for p in ignore_patterns: for dir_suffix in dir_suffixes: if p.endswith(dir_suffix): # if pattern ends with dir suffix just truncate it normalized_ignore_patterns.append(p[:-len(dir_suffix)]) break else: normalized_ignore_patterns.append(p) # build ignored roots ignored_roots = [os.path.normpath(p) for p in consts.TRANSLATION_IGNORE_ROOTS if p] # define list for storing paths to the files with translatable stings result_files = [] for dirpath, dirnames, filenames in os.walk(start_path, topdown=True): for dirname in dirnames[:]: # relative path to the dirname _path = os.path.normpath(os.path.join(dirpath, dirname)) # absolute path to the dirname _root = os.path.join(os.path.abspath(dirpath), dirname) # remove directories which are match ignore patterns if is_ignored_path_pattern(_path, normalized_ignore_patterns) \ or _root in ignored_roots: dirnames.remove(dirname) elif dirname == 'locale': dirnames.remove(dirname) for filename in filenames: file_path = os.path.normpath(os.path.join(dirpath, filename)) file_ext = os.path.splitext(filename)[1] if not is_ignored_path_pattern(file_path, set(ignore_patterns)) \ or file_ext in extensions: result_files.append(os.path.join(dirpath, filename)) return sorted(result_files)
else: message = e raise CommandError(message) ======= except FileExistsError: raise CommandError("'%s' already exists" % top_dir) except OSError as e: raise CommandError(e) >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options['extensions'])) extra_files = [] for file in options['files']: extra_files.extend(map(lambda x: x.strip(), file.split(','))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ', '.join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ', '.join(extra_files))) base_name = '%s_name' % app_or_project base_subdir = '%s_template' % app_or_project base_directory = '%s_directory' % app_or_project camel_case_name = 'camel_case_%s_name' % app_or_project
def handle(self, *args, **options): locale = options["locale"] exclude = options["exclude"] self.domain = options["domain"] self.verbosity = options["verbosity"] process_all = options["all"] extensions = options["extensions"] self.symlinks = options["symlinks"] ignore_patterns = options["ignore_patterns"] if options["use_default_ignore_patterns"]: ignore_patterns += ["CVS", ".*", "*~", "*.pyc"] self.ignore_patterns = list(set(ignore_patterns)) # Avoid messing with mutable class variables if options["no_wrap"]: self.msgmerge_options = self.msgmerge_options[:] + ["--no-wrap"] self.msguniq_options = self.msguniq_options[:] + ["--no-wrap"] self.msgattrib_options = self.msgattrib_options[:] + ["--no-wrap"] self.xgettext_options = self.xgettext_options[:] + ["--no-wrap"] if options["no_location"]: self.msgmerge_options = self.msgmerge_options[:] + [ "--no-location" ] self.msguniq_options = self.msguniq_options[:] + ["--no-location"] self.msgattrib_options = self.msgattrib_options[:] + [ "--no-location" ] self.xgettext_options = self.xgettext_options[:] + [ "--no-location" ] if options["add_location"]: if self.gettext_version < (0, 19): raise CommandError( "The --add-location option requires gettext 0.19 or later. " "You have %s." % ".".join(str(x) for x in self.gettext_version)) arg_add_location = "--add-location=%s" % options["add_location"] self.msgmerge_options = self.msgmerge_options[:] + [ arg_add_location ] self.msguniq_options = self.msguniq_options[:] + [arg_add_location] self.msgattrib_options = self.msgattrib_options[:] + [ arg_add_location ] self.xgettext_options = self.xgettext_options[:] + [ arg_add_location ] self.no_obsolete = options["no_obsolete"] self.keep_pot = options["keep_pot"] if self.domain not in ("django", "djangojs"): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == "djangojs": exts = extensions or ["js"] else: exts = extensions or ["html", "txt", "py"] self.extensions = handle_extensions(exts) if (not locale and not exclude and not process_all) or self.domain is None: raise CommandError("Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1])) if self.verbosity > 1: self.stdout.write("examining files with the extensions: %s" % get_text_list(list(self.extensions), "and")) self.invoked_for_django = False self.locale_paths = [] self.default_locale_path = None if os.path.isdir(os.path.join("conf", "locale")): self.locale_paths = [ os.path.abspath(os.path.join("conf", "locale")) ] self.default_locale_path = self.locale_paths[0] self.invoked_for_django = True else: if self.settings_available: self.locale_paths.extend(settings.LOCALE_PATHS) # Allow to run makemessages inside an app dir if os.path.isdir("locale"): self.locale_paths.append(os.path.abspath("locale")) if self.locale_paths: self.default_locale_path = self.locale_paths[0] os.makedirs(self.default_locale_path, exist_ok=True) # Build locale list looks_like_locale = re.compile(r"[a-z]{2}") locale_dirs = filter(os.path.isdir, glob.glob("%s/*" % self.default_locale_path)) all_locales = [ lang_code for lang_code in map(os.path.basename, locale_dirs) if looks_like_locale.match(lang_code) ] # Account for excluded locales if process_all: locales = all_locales else: locales = locale or all_locales locales = set(locales).difference(exclude) if locales: check_programs("msguniq", "msgmerge", "msgattrib") check_programs("xgettext") try: potfiles = self.build_potfiles() # Build po files for each selected locale for locale in locales: if "-" in locale: self.stdout.write( "invalid locale %s, did you mean %s?" % ( locale, locale.replace("-", "_"), ), ) continue if self.verbosity > 0: self.stdout.write("processing locale %s" % locale) for potfile in potfiles: self.write_po_file(potfile, locale) finally: if not self.keep_pot: self.remove_potfiles()
def handle_noargs(self, *args, **options): locale = options.get('locale') self.domain = options.get('domain') self.verbosity = int(options.get('verbosity')) process_all = options.get('all') extensions = options.get('extensions') self.symlinks = options.get('symlinks') ignore_patterns = options.get('ignore_patterns') if options.get('use_default_ignore_patterns'): ignore_patterns += ['CVS', '.*', '*~', '*.pyc'] self.ignore_patterns = list(set(ignore_patterns)) self.wrap = '--no-wrap' if options.get('no_wrap') else '' self.location = '--no-location' if options.get('no_location') else '' self.no_obsolete = options.get('no_obsolete') self.keep_pot = options.get('keep_pot') if self.domain not in ('django', 'djangojs'): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == 'djangojs': exts = extensions if extensions else ['js'] else: exts = extensions if extensions else ['html', 'txt'] self.extensions = handle_extensions(exts) if (locale is None and not process_all) or self.domain is None: raise CommandError("Type '%s help %s' for usage information." % ( os.path.basename(sys.argv[0]), sys.argv[1])) if self.verbosity > 1: self.stdout.write('examining files with the extensions: %s\n' % get_text_list(list(self.extensions), 'and')) # Need to ensure that the i18n framework is enabled from django.conf import settings if settings.configured: settings.USE_I18N = True else: settings.configure(USE_I18N = True) self.invoked_for_django = False if os.path.isdir(os.path.join('conf', 'locale')): localedir = os.path.abspath(os.path.join('conf', 'locale')) self.invoked_for_django = True # Ignoring all contrib apps self.ignore_patterns += ['contrib/*'] elif os.path.isdir('locale'): localedir = os.path.abspath('locale') else: raise CommandError("This script should be run from the Django Git " "tree or your project or app tree. If you did indeed run it " "from the Git checkout or your project or application, " "maybe you are just missing the conf/locale (in the django " "tree) or locale (for project and application) directory? It " "is not created automatically, you have to create it by hand " "if you want to enable i18n for your project or application.") check_programs('xgettext') potfile = self.build_pot_file(localedir) # Build po files for each selected locale locales = [] if locale is not None: locales += locale.split(',') if not isinstance(locale, list) else locale elif process_all: locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir)) locales = [os.path.basename(l) for l in locale_dirs] if locales: check_programs('msguniq', 'msgmerge', 'msgattrib') try: for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) self.write_po_file(potfile, locale) finally: if not self.keep_pot and os.path.exists(potfile): os.unlink(potfile)
from __future__ import unicode_literals
def handle(self, **options): self.symlinks = options.get('symlinks') extensions = options.get('extensions') or ['html'] self.extensions = handle_extensions(extensions)
def handle(self, **options): self.verbosity = options['verbosity'] app_name, target = options.pop('name'), options.pop('directory') extensions = tuple(handle_extensions(options['extensions'])) extra_files = [] for file in options['files']: extra_files.extend(map(lambda x: x.strip(), file.split(','))) self._validate_name(app_name) self.paths_to_remove = [] top_dir = self._expand_target_dir(app_name, target) camel_case_app_name = ''.join(x for x in app_name.title() if x != '_') context = Context(dict(options, **{ 'app_name': app_name, 'camel_case_app_name': camel_case_app_name, 'base_directory': top_dir, 'unicode_literals': '' if six.PY3 else '# -*- coding: utf-8 -*-\n' 'from __future__ import unicode_literals\n\n', }), autoescape=False) # Setup a stub settings environment for template rendering if not settings.configured: settings.configure() django.setup() template_dir = self.handle_template(options['template'], 'module_template') prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace('module_name', app_name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for filename in files: old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace('module_name', app_name)) for old_suffix, new_suffix in self.rewrite_template_suffixes: if new_path.endswith(old_suffix): new_path = new_path[:-len(old_suffix)] + new_suffix break # Only rewrite once if path.exists(new_path): raise CommandError( "{} already exists, overlaying a project or app into an existing " "directory won't replace conflicting files".format(new_path)) if new_path.endswith(extensions) or filename in extra_files: with io.open(old_path, 'r', encoding='utf-8') as template_file: content = template_file.read() template = Engine().from_string(content) content = template.render(context) with io.open(new_path, 'w', encoding='utf-8') as new_file: new_file.write(content) else: shutil.copyfile(old_path, new_path) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove) if self.verbosity >= 1: self.stdout.write("{} module created\n" .format(camel_case_app_name)) self.stdout.write( "To enable the module you need to add '{}.apps.{}Config' " "to the INSTALLED_APPS setting".format(app_name, camel_case_app_name)) self.stdout.write('and run ./manage.py migrate after that\n')
def handle(self, *args, **options): locale = options.get("locale") exclude = options.get("exclude") self.domain = options.get("domain") self.verbosity = options.get("verbosity") process_all = options.get("all") extensions = options.get("extensions") self.symlinks = options.get("symlinks") # Need to ensure that the i18n framework is enabled if settings.configured: settings.USE_I18N = True else: settings.configure(USE_I18N=True) ignore_patterns = options.get("ignore_patterns") if options.get("use_default_ignore_patterns"): ignore_patterns += ["CVS", ".*", "*~", "*.pyc"] self.ignore_patterns = list(set(ignore_patterns)) # Avoid messing with mutable class variables if options.get("no_wrap"): self.msgmerge_options = self.msgmerge_options[:] + ["--no-wrap"] self.msguniq_options = self.msguniq_options[:] + ["--no-wrap"] self.msgattrib_options = self.msgattrib_options[:] + ["--no-wrap"] self.xgettext_options = self.xgettext_options[:] + ["--no-wrap"] if options.get("no_location"): self.msgmerge_options = self.msgmerge_options[:] + ["--no-location"] self.msguniq_options = self.msguniq_options[:] + ["--no-location"] self.msgattrib_options = self.msgattrib_options[:] + ["--no-location"] self.xgettext_options = self.xgettext_options[:] + ["--no-location"] self.no_obsolete = options.get("no_obsolete") self.keep_pot = options.get("keep_pot") if self.domain not in ("django", "djangojs"): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == "djangojs": exts = extensions if extensions else ["js"] else: exts = extensions if extensions else ["html", "txt", "py"] self.extensions = handle_extensions(exts) if (locale is None and not exclude and not process_all) or self.domain is None: raise CommandError( "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1]) ) if self.verbosity > 1: self.stdout.write("examining files with the extensions: %s\n" % get_text_list(list(self.extensions), "and")) self.invoked_for_django = False self.locale_paths = [] self.default_locale_path = None if os.path.isdir(os.path.join("conf", "locale")): self.locale_paths = [os.path.abspath(os.path.join("conf", "locale"))] self.default_locale_path = self.locale_paths[0] self.invoked_for_django = True else: self.locale_paths.extend(list(settings.LOCALE_PATHS)) # Allow to run makemessages inside an app dir if os.path.isdir("locale"): self.locale_paths.append(os.path.abspath("locale")) if self.locale_paths: self.default_locale_path = self.locale_paths[0] if not os.path.exists(self.default_locale_path): os.makedirs(self.default_locale_path) # Build locale list locale_dirs = filter(os.path.isdir, glob.glob("%s/*" % self.default_locale_path)) all_locales = map(os.path.basename, locale_dirs) # Account for excluded locales if process_all: locales = all_locales else: locales = locale or all_locales locales = set(locales) - set(exclude) if locales: check_programs("msguniq", "msgmerge", "msgattrib") check_programs("xgettext") try: potfiles = self.build_potfiles() # Build po files for each selected locale for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) for potfile in potfiles: self.write_po_file(potfile, locale) finally: if not self.keep_pot: self.remove_potfiles()
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = options["verbosity"] self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) except FileExistsError: raise CommandError("'%s' already exists" % top_dir) except OSError as e: raise CommandError(e) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options["extensions"])) extra_files = [] for file in options["files"]: extra_files.extend(map(lambda x: x.strip(), file.split(","))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ", ".join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ", ".join(extra_files))) base_name = "%s_name" % app_or_project base_subdir = "%s_template" % app_or_project base_directory = "%s_directory" % app_or_project camel_case_name = "camel_case_%s_name" % app_or_project camel_case_value = "".join(x for x in name.title() if x != "_") context = Context( dict( options, **{ base_name: name, base_directory: top_dir, camel_case_name: camel_case_value, "docs_version": get_docs_version(), "django_version": django.__version__, }), autoescape=False, ) # Setup a stub settings environment for template rendering if not settings.configured: settings.configure() django.setup() template_dir = self.handle_template(options["template"], base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for dirname in dirs[:]: if dirname.startswith(".") or dirname == "__pycache__": dirs.remove(dirname) for filename in files: if filename.endswith((".pyo", ".pyc", ".py.class")): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) for old_suffix, new_suffix in self.rewrite_template_suffixes: if new_path.endswith(old_suffix): new_path = new_path[:-len(old_suffix)] + new_suffix break # Only rewrite once if path.exists(new_path): raise CommandError("%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path) # Only render the Python files, as we don't want to # accidentally render Django templates files if new_path.endswith(extensions) or filename in extra_files: with open(old_path, "r", encoding="utf-8") as template_file: content = template_file.read() template = Engine().from_string(content) content = template.render(context) with open(new_path, "w", encoding="utf-8") as new_file: new_file.write(content) else: shutil.copyfile(old_path, new_path) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE, ) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove)
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = options['verbosity'] self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) except OSError as e: if e.errno == errno.EEXIST: message = "'%s' already exists" % top_dir else: message = e raise CommandError(message) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple(handle_extensions(options['extensions'])) extra_files = [] for file in options['files']: extra_files.extend(map(lambda x: x.strip(), file.split(','))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ', '.join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ', '.join(extra_files))) base_name = '%s_name' % app_or_project base_subdir = '%s_template' % app_or_project base_directory = '%s_directory' % app_or_project camel_case_name = 'camel_case_%s_name' % app_or_project camel_case_value = ''.join(x for x in name.title() if x != '_') context = Context(dict(options, **{ base_name: name, base_directory: top_dir, camel_case_name: camel_case_value, 'docs_version': get_docs_version(), 'django_version': django.__version__, 'unicode_literals': '' if six.PY3 else 'from __future__ import unicode_literals\n\n', }), autoescape=False) # Setup a stub settings environment for template rendering from django.conf import settings if not settings.configured: settings.configure() template_dir = self.handle_template(options['template'], base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for dirname in dirs[:]: if dirname.startswith('.') or dirname == '__pycache__': dirs.remove(dirname) for filename in files: if filename.endswith(('.pyo', '.pyc', '.py.class')): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) for old_suffix, new_suffix in self.rewrite_template_suffixes: if new_path.endswith(old_suffix): new_path = new_path[:-len(old_suffix)] + new_suffix break # Only rewrite once if path.exists(new_path): raise CommandError("%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path) # Only render the Python files, as we don't want to # accidentally render Django templates files with open(old_path, 'rb') as template_file: content = template_file.read() if new_path.endswith(extensions) or filename in extra_files: content = content.decode('utf-8') template = Engine().from_string(content) content = template.render(context) content = content.encode('utf-8') with open(new_path, 'wb') as new_file: new_file.write(content) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove)
def handle(self, *args, **options): locale = options['locale'] exclude = options['exclude'] self.domain = options['domain'] self.verbosity = options['verbosity'] process_all = options['all'] extensions = options['extensions'] self.symlinks = options['symlinks'] ignore_patterns = options['ignore_patterns'] if options['use_default_ignore_patterns']: ignore_patterns += ['CVS', '.*', '*~', '*.pyc'] self.ignore_patterns = list(set(ignore_patterns)) # Avoid messing with mutable class variables if options['no_wrap']: self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap'] self.msguniq_options = self.msguniq_options[:] + ['--no-wrap'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap'] self.xgettext_options = self.xgettext_options[:] + ['--no-wrap'] if options['no_location']: self.msgmerge_options = self.msgmerge_options[:] + ['--no-location'] self.msguniq_options = self.msguniq_options[:] + ['--no-location'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-location'] self.xgettext_options = self.xgettext_options[:] + ['--no-location'] if options['add_location']: if self.gettext_version < (0, 19): raise CommandError( "The --add-location option requires gettext 0.19 or later. " "You have %s." % '.'.join(str(x) for x in self.gettext_version) ) arg_add_location = "--add-location=%s" % options['add_location'] self.msgmerge_options = self.msgmerge_options[:] + [arg_add_location] self.msguniq_options = self.msguniq_options[:] + [arg_add_location] self.msgattrib_options = self.msgattrib_options[:] + [arg_add_location] self.xgettext_options = self.xgettext_options[:] + [arg_add_location] self.no_obsolete = options['no_obsolete'] self.keep_pot = options['keep_pot'] if self.domain not in ('django', 'djangojs'): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == 'djangojs': exts = extensions or ['js'] else: exts = extensions or ['html', 'txt', 'py'] self.extensions = handle_extensions(exts) if (locale is None and not exclude and not process_all) or self.domain is None: raise CommandError( "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1]) ) if self.verbosity > 1: self.stdout.write( 'examining files with the extensions: %s\n' % get_text_list(list(self.extensions), 'and') ) self.invoked_for_django = False self.locale_paths = [] self.default_locale_path = None if os.path.isdir(os.path.join('conf', 'locale')): self.locale_paths = [os.path.abspath(os.path.join('conf', 'locale'))] self.default_locale_path = self.locale_paths[0] self.invoked_for_django = True else: if self.settings_available: self.locale_paths.extend(settings.LOCALE_PATHS) # Allow to run makemessages inside an app dir if os.path.isdir('locale'): self.locale_paths.append(os.path.abspath('locale')) if self.locale_paths: self.default_locale_path = self.locale_paths[0] os.makedirs(self.default_locale_path, exist_ok=True) # Build locale list looks_like_locale = re.compile(r'[a-z]{2}') locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % self.default_locale_path)) all_locales = [ lang_code for lang_code in map(os.path.basename, locale_dirs) if looks_like_locale.match(lang_code) ] # Account for excluded locales if process_all: locales = all_locales else: locales = locale or all_locales locales = set(locales).difference(exclude) if locales: check_programs('msguniq', 'msgmerge', 'msgattrib') check_programs('xgettext') try: potfiles = self.build_potfiles() # Build po files for each selected locale for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) for potfile in potfiles: self.write_po_file(potfile, locale) finally: if not self.keep_pot: self.remove_potfiles()
def handle(self, *args, **options): locale = options['locale'] exclude = options['exclude'] self.domain = options['domain'] self.verbosity = options['verbosity'] process_all = options['all'] extensions = options['extensions'] self.symlinks = options['symlinks'] ignore_patterns = options['ignore_patterns'] if options['use_default_ignore_patterns']: ignore_patterns += ['CVS', '.*', '*~', '*.pyc'] self.ignore_patterns = list(set(ignore_patterns)) # Avoid messing with mutable class variables if options['no_wrap']: self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap'] self.msguniq_options = self.msguniq_options[:] + ['--no-wrap'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap'] self.xgettext_options = self.xgettext_options[:] + ['--no-wrap'] if options['no_location']: self.msgmerge_options = self.msgmerge_options[:] + ['--no-location'] self.msguniq_options = self.msguniq_options[:] + ['--no-location'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-location'] self.xgettext_options = self.xgettext_options[:] + ['--no-location'] if options['add_location']: if self.gettext_version < (0, 19): raise CommandError( "The --add-location option requires gettext 0.19 or later. " "You have %s." % '.'.join(str(x) for x in self.gettext_version) ) arg_add_location = "--add-location=%s" % options['add_location'] self.msgmerge_options = self.msgmerge_options[:] + [arg_add_location] self.msguniq_options = self.msguniq_options[:] + [arg_add_location] self.msgattrib_options = self.msgattrib_options[:] + [arg_add_location] self.xgettext_options = self.xgettext_options[:] + [arg_add_location] self.no_obsolete = options['no_obsolete'] self.keep_pot = options['keep_pot'] if self.domain not in ('django', 'djangojs'): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == 'djangojs': exts = extensions or ['js'] else: exts = extensions or ['html', 'txt', 'py'] self.extensions = handle_extensions(exts) if (locale is None and not exclude and not process_all) or self.domain is None: raise CommandError( "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1]) ) if self.verbosity > 1: self.stdout.write( 'examining files with the extensions: %s\n' % get_text_list(list(self.extensions), 'and') ) self.invoked_for_django = False self.locale_paths = [] self.default_locale_path = None if os.path.isdir(os.path.join('conf', 'locale')): self.locale_paths = [os.path.abspath(os.path.join('conf', 'locale'))] self.default_locale_path = self.locale_paths[0] self.invoked_for_django = True else: if self.settings_available: self.locale_paths.extend(settings.LOCALE_PATHS) # Allow to run makemessages inside an app dir if os.path.isdir('locale'): self.locale_paths.append(os.path.abspath('locale')) if self.locale_paths: self.default_locale_path = self.locale_paths[0] if not os.path.exists(self.default_locale_path): os.makedirs(self.default_locale_path) # Build locale list looks_like_locale = re.compile(r'[a-z]{2}') locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % self.default_locale_path)) all_locales = [ lang_code for lang_code in map(os.path.basename, locale_dirs) if looks_like_locale.match(lang_code) ] # Account for excluded locales if process_all: locales = all_locales else: locales = locale or all_locales locales = set(locales).difference(exclude) if locales: check_programs('msguniq', 'msgmerge', 'msgattrib') check_programs('xgettext') try: potfiles = self.build_potfiles() # Build po files for each selected locale for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) for potfile in potfiles: self.write_po_file(potfile, locale) finally: if not self.keep_pot: self.remove_potfiles()
def handle_noargs(self, *args, **options): locale = options.get("locale") self.domain = options.get("domain") self.verbosity = int(options.get("verbosity")) process_all = options.get("all") extensions = options.get("extensions") self.symlinks = options.get("symlinks") ignore_patterns = options.get("ignore_patterns") if options.get("use_default_ignore_patterns"): ignore_patterns += ["CVS", ".*", "*~", "*.pyc"] self.ignore_patterns = list(set(ignore_patterns)) self.wrap = "--no-wrap" if options.get("no_wrap") else "" self.location = "--no-location" if options.get("no_location") else "" self.no_obsolete = options.get("no_obsolete") self.keep_pot = options.get("keep_pot") if self.domain not in ("django", "djangojs"): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == "djangojs": exts = extensions if extensions else ["js"] else: exts = extensions if extensions else ["html", "txt"] self.extensions = handle_extensions(exts) if (locale is None and not process_all) or self.domain is None: raise CommandError( "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1]) ) if self.verbosity > 1: self.stdout.write("examining files with the extensions: %s\n" % get_text_list(list(self.extensions), "and")) # Need to ensure that the i18n framework is enabled from django.conf import settings if settings.configured: settings.USE_I18N = True else: settings.configure(USE_I18N=True) self.invoked_for_django = False if os.path.isdir(os.path.join("conf", "locale")): localedir = os.path.abspath(os.path.join("conf", "locale")) self.invoked_for_django = True # Ignoring all contrib apps self.ignore_patterns += ["contrib/*"] elif os.path.isdir("locale"): localedir = os.path.abspath("locale") else: raise CommandError( "This script should be run from the Django Git " "tree or your project or app tree. If you did indeed run it " "from the Git checkout or your project or application, " "maybe you are just missing the conf/locale (in the django " "tree) or locale (for project and application) directory? It " "is not created automatically, you have to create it by hand " "if you want to enable i18n for your project or application." ) check_programs("xgettext") # We require gettext version 0.15 or newer. output, errors, status = popen_wrapper(["xgettext", "--version"]) if status != STATUS_OK: raise CommandError( "Error running xgettext. Note that Django " "internationalization requires GNU gettext 0.15 or newer." ) match = re.search(r"(?P<major>\d+)\.(?P<minor>\d+)", output) if match: xversion = (int(match.group("major")), int(match.group("minor"))) if xversion < (0, 15): raise CommandError( "Django internationalization requires GNU " "gettext 0.15 or newer. You are using version %s, please " "upgrade your gettext toolset." % match.group() ) potfile = self.build_pot_file(localedir) # Build po files for each selected locale locales = [] if locale is not None: locales += locale.split(",") if not isinstance(locale, list) else locale elif process_all: locale_dirs = filter(os.path.isdir, glob.glob("%s/*" % localedir)) locales = [os.path.basename(l) for l in locale_dirs] if locales: check_programs("msguniq", "msgmerge", "msgattrib") try: for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) self.write_po_file(potfile, locale) finally: if not self.keep_pot and os.path.exists(potfile): os.unlink(potfile)
def handle(self, app_or_project, name, target=None, override=False, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = int(options.get('verbosity')) self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) except OSError as e: if e.errno == errno.EEXIST: if not override: raise CommandError("'%s' already exists" % top_dir) else: raise CommandError(e) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple( handle_extensions(options.get('extensions'), ignored=())) extra_files = [] for file in options.get('files'): extra_files.extend(map(lambda x: x.strip(), file.split(','))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ', '.join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ', '.join(extra_files))) base_name = '%s_name' % app_or_project base_subdir = '%s_template' % app_or_project base_directory = '%s_directory' % app_or_project if django.VERSION[-2] != 'final': docs_version = 'dev' else: docs_version = '%d.%d' % django.VERSION[:2] base_context = dict(options, **{ base_name: name, base_directory: top_dir, 'docs_version': docs_version, }) # Setup a stub settings environment for template rendering from django.conf import settings if not settings.configured: settings.configure(DEBUG=True, TEMPLATE_DEBUG=True) template_dir = self.handle_template(options.get('template'), base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) global_context = {} # Try to find context.yaml file in the current directory or # parent directory(ies) globals_file = os.path.join(root, 'globals.yaml') while True: globals_file = os.path.normpath(globals_file) if os.path.exists(globals_file): # Read context with open(globals_file, 'rb') as f: globals_content = f.read() global_context = yaml.safe_load(globals_content) break elif not os.path.dirname(globals_file): break else: globals_file = os.path.join( os.path.dirname(globals_file), '..', os.path.basename(globals_file)) for dirname in dirs[:]: if dirname.startswith('.') or dirname == '__pycache__': dirs.remove(dirname) for filename in files: if (filename.endswith(('.pyo', '.pyc', '.py.class')) or filename in ('globals.yaml',)): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) if path.exists(new_path) and not override: raise CommandError("%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path) with open(old_path, 'rb') as template_file: content = template_file.read() # Only get front matter from matching extensions if filename.endswith(extensions) or filename in extra_files: content = content.decode('utf-8') content, extra_context = self.extract_front_matter(content) context = dict(base_context.items() + global_context.items() + extra_context.items()) else: context = dict(base_context.items() + global_context.items()) # Process context out = self.preprocess_file(filename, context) if out is False: # If False is explicity returned we will not # output this file continue elif isinstance(out, dict): context = out # Only render matching extensions if filename.endswith(extensions) or filename in extra_files: if self.verbosity >= 2: self.stdout.write("Rendering %s\n" % old_path) try: template = Template(content) content = template.render(Context(context, autoescape=False)) except Exception: self.stdout.write("Rendering failed %s\n" % old_path) raise content = content.encode('utf-8') if relative_dir: dir_path = os.path.dirname(new_path) if not path.exists(dir_path): mkdirp(dir_path) with open(new_path, 'wb') as new_file: new_file.write(content) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove, onerror=rmtree_errorhandler)
def handle(self, app_or_project, name, target=None, **options): self.app_or_project = app_or_project self.paths_to_remove = [] self.verbosity = int(options.get('verbosity')) self.validate_name(name, app_or_project) # if some directory is given, make sure it's nicely expanded if target is None: top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) except OSError as e: if e.errno == errno.EEXIST: message = "'%s' already exists" % top_dir else: message = e raise CommandError(message) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): raise CommandError("Destination directory '%s' does not " "exist, please create it first." % top_dir) extensions = tuple( handle_extensions(options.get('extensions'), ignored=())) extra_files = [] for file in options.get('files'): extra_files.extend(map(lambda x: x.strip(), file.split(','))) if self.verbosity >= 2: self.stdout.write("Rendering %s template files with " "extensions: %s\n" % (app_or_project, ', '.join(extensions))) self.stdout.write("Rendering %s template files with " "filenames: %s\n" % (app_or_project, ', '.join(extra_files))) base_name = '%s_name' % app_or_project base_subdir = '%s_template' % app_or_project base_directory = '%s_directory' % app_or_project if django.VERSION[-2] != 'final': docs_version = 'dev' else: docs_version = '%d.%d' % django.VERSION[:2] context = Context(dict( options, **{ base_name: name, base_directory: top_dir, 'docs_version': docs_version, }), autoescape=False) # Setup a stub settings environment for template rendering from django.conf import settings if not settings.configured: settings.configure() template_dir = self.handle_template(options.get('template'), base_subdir) prefix_length = len(template_dir) + 1 for root, dirs, files in os.walk(template_dir): path_rest = root[prefix_length:] relative_dir = path_rest.replace(base_name, name) if relative_dir: target_dir = path.join(top_dir, relative_dir) if not path.exists(target_dir): os.mkdir(target_dir) for dirname in dirs[:]: if dirname.startswith('.') or dirname == '__pycache__': dirs.remove(dirname) for filename in files: if filename.endswith(('.pyo', '.pyc', '.py.class')): # Ignore some files as they cause various breakages. continue old_path = path.join(root, filename) new_path = path.join(top_dir, relative_dir, filename.replace(base_name, name)) if path.exists(new_path): raise CommandError("%s already exists, overlaying a " "project or app into an existing " "directory won't replace conflicting " "files" % new_path) # Only render the Python files, as we don't want to # accidentally render Django templates files with open(old_path, 'rb') as template_file: content = template_file.read() if filename.endswith(extensions) or filename in extra_files: content = content.decode('utf-8') template = Template(content) content = template.render(context) content = content.encode('utf-8') with open(new_path, 'wb') as new_file: new_file.write(content) if self.verbosity >= 2: self.stdout.write("Creating %s\n" % new_path) try: shutil.copymode(old_path, new_path) self.make_writeable(new_path) except OSError: self.stderr.write( "Notice: Couldn't set permission bits on %s. You're " "probably using an uncommon filesystem setup. No " "problem." % new_path, self.style.NOTICE) if self.paths_to_remove: if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove, onerror=rmtree_errorhandler)
def handle(self, *args, **options): locale = options.get('locale') exclude = options.get('exclude') self.domain = options.get('domain') self.verbosity = options.get('verbosity') process_all = options.get('all') extensions = options.get('extensions') self.symlinks = options.get('symlinks') # Need to ensure that the i18n framework is enabled if settings.configured: settings.USE_I18N = True else: settings.configure(USE_I18N=True) ignore_patterns = options.get('ignore_patterns') if options.get('use_default_ignore_patterns'): ignore_patterns += ['CVS', '.*', '*~', '*.pyc'] self.ignore_patterns = list(set(ignore_patterns)) # Avoid messing with mutable class variables if options.get('no_wrap'): self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap'] self.msguniq_options = self.msguniq_options[:] + ['--no-wrap'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap'] self.xgettext_options = self.xgettext_options[:] + ['--no-wrap'] if options.get('no_location'): self.msgmerge_options = self.msgmerge_options[:] + ['--no-location'] self.msguniq_options = self.msguniq_options[:] + ['--no-location'] self.msgattrib_options = self.msgattrib_options[:] + ['--no-location'] self.xgettext_options = self.xgettext_options[:] + ['--no-location'] self.no_obsolete = options.get('no_obsolete') self.keep_pot = options.get('keep_pot') if self.domain not in ('django', 'djangojs'): raise CommandError("currently makemessages only supports domains " "'django' and 'djangojs'") if self.domain == 'djangojs': exts = extensions if extensions else ['js'] else: exts = extensions if extensions else ['html', 'txt', 'py'] self.extensions = handle_extensions(exts) if (locale is None and not exclude and not process_all) or self.domain is None: raise CommandError("Type '%s help %s' for usage information." % ( os.path.basename(sys.argv[0]), sys.argv[1])) if self.verbosity > 1: self.stdout.write('examining files with the extensions: %s\n' % get_text_list(list(self.extensions), 'and')) self.invoked_for_django = False self.locale_paths = [] self.default_locale_path = None if os.path.isdir(os.path.join('conf', 'locale')): self.locale_paths = [os.path.abspath(os.path.join('conf', 'locale'))] self.default_locale_path = self.locale_paths[0] self.invoked_for_django = True else: self.locale_paths.extend(settings.LOCALE_PATHS) # Allow to run makemessages inside an app dir if os.path.isdir('locale'): self.locale_paths.append(os.path.abspath('locale')) if self.locale_paths: self.default_locale_path = self.locale_paths[0] if not os.path.exists(self.default_locale_path): os.makedirs(self.default_locale_path) # Build locale list locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % self.default_locale_path)) all_locales = map(os.path.basename, locale_dirs) # Account for excluded locales if process_all: locales = all_locales else: locales = locale or all_locales locales = set(locales) - set(exclude) if locales: check_programs('msguniq', 'msgmerge', 'msgattrib') check_programs('xgettext') try: potfiles = self.build_potfiles() # Build po files for each selected locale for locale in locales: if self.verbosity > 0: self.stdout.write("processing locale %s\n" % locale) for potfile in potfiles: self.write_po_file(potfile, locale) finally: if not self.keep_pot: self.remove_potfiles()
import cgi