def compile_messages(): basedirs = [os.path.join('conf', 'locale'), 'locale'] if os.environ.get('DJANGO_SETTINGS_MODULE'): from django.conf import settings basedirs.extend(settings.LOCALE_PATHS) # Gather existing directories. basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs))) if not basedirs: raise CommandError("This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified.") for basedir in basedirs: for dirpath, dirnames, filenames in os.walk(basedir): for f in filenames: if f.endswith('.po'): fn = os.path.join(dirpath, f) if has_bom(fn): raise CommandError("The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM." % fn) pf = os.path.splitext(fn)[0] # Store the names of the .mo and .po files in an environment # variable, rather than doing a string replacement into the # command, so that we can take advantage of shell quoting, to # quote any malicious characters/escaping. # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html if sys.platform == 'win32': # Different shell-variable syntax bits = ['msgfmt', '--check-format', '-o', pf + '.mo', pf + '.po'] else: bits = ['msgfmt', '--check-format', '-o', pf + '.mo', pf + '.po'] pipe = subprocess.Popen(bits, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr = pipe.communicate()[-1] if pipe.returncode != 0: return False, stderr return True, ''
def _compile(stdout, locale, basedir, program): if locale: dirs = [os.path.join(basedir, l, 'LC_MESSAGES') for l in locale] else: dirs = [basedir] for ldir in dirs: for dirpath, dirnames, filenames in os.walk(ldir): for f in filenames: if not f.endswith('.po'): continue stdout.write('processing file %s in %s\n' % (f, dirpath)) fn = os.path.join(dirpath, f) if has_bom(fn): raise CommandError( "The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM." % fn) pf = os.path.splitext(fn)[0] args = [ program, '--check-format', '-o', npath(pf + '.mo'), npath(pf + '.po') ] output, errors, status = popen_wrapper(args) if status: if errors: msg = "Execution of %s failed: %s" % (program, errors) else: msg = "Execution of %s failed" % program raise CommandError(msg)
def form_valid(self, form): try: file_path = os.path.join(self.po_path, self.po_file) file_ = open(file_path, 'w+') file_.write(smart_str(form.cleaned_data['po_content'])) file_.close() domain = 'django.po' if self.po_file.endswith('django.po') \ else 'djangojs.po' uni_django_path = os.path.join(self.po_path, domain) source_files = [] #iterate over the installed applications, locate & concat #the corresponding global django.po or djangojs.po file for app_name in settings.INSTALLED_APPS: local_django = os.path.join(self.po_path, '%s-%s' % (app_name, domain)) if os.path.exists(local_django): source_files.append(local_django) concat_message_files(source_files, uni_django_path) if not has_bom(uni_django_path): compile_message_file(uni_django_path) #reset the cached translation messages so that #we do not need to restart the web server reset_translations(self.language.name) messages.add_message(self.request, messages.SUCCESS, _(('The file %(file)s was succesfuly updated.' \ % { 'file' : self.po_file }))) except: messages.add_message(self.request, messages.ERROR, _(('The file %(file)s could not be saved.' \ % { 'file' : self.po_file }))) #save and continue editing if "_continue" in self.request.POST: return HttpResponseRedirect('../%s' % self.po_file) return super(TranslationMessagesEditView, self).form_valid(form)
def get_context_data(self, **kwargs): context = super(GenerateTranslationMessagesView, self).get_context_data(**kwargs) if hasattr(self, 'error') and self.error: context['error'] = self.error return context #locate the current directory curr_dir = os.curdir domain_dict = {'django' : ['html','txt'], 'djangojs' : []} lang_files = [] #iterate over the installed applications and copy their po files #for this language to the appropriate folder for app_name in settings.INSTALLED_APPS: mod = import_module(app_name) mod_root = os.path.dirname(mod.__file__) if not os.path.exists(os.path.join(mod_root, 'locale')): continue original_path = os.path.join(mod_root, 'locale', to_locale(self.language.name), 'LC_MESSAGES') delete_at_the_end = False if not os.path.exists(original_path): if not app_name.startswith('django.contrib'): try: #try to create language directory for the app os.makedirs(original_path) delete_at_the_end = True except: continue else: continue if not app_name.startswith('django.contrib'): #move original files to a temp file for file_ in list(os.listdir(original_path)): if file_.endswith('.po'): shutil.copy(os.path.join(original_path, file_), os.path.join(original_path, 'original-%s' % file_)) #copy the project-wise files to the appropriate directory if not self.request.GET.get('delete', 0): #replace original file with the yawd version #so that it gets updated for f in list(os.listdir(self.po_path)): if f.startswith('%s-' % app_name) and f.endswith('.po'): shutil.copy(os.path.join(self.po_path, f), os.path.join(original_path, f.replace('%s-' % app_name, ''))) #makemessages excluding the core applications os.chdir(mod_root) for key, value in domain_dict.items(): try: management.call_command('makemessages', domain=key, extensions=value, locale=self.locale, verbosity=0) except management.CommandError: #Django could throw a CommandError if we process #the domainjs and there are no messages to process. pass os.chdir(curr_dir) #iterate over the application po files for file_ in list(os.listdir(original_path)): if not file_.startswith('original-') and file_.endswith('.po'): original_file_path = os.path.join(original_path, file_) file_name = '%s-%s' % (app_name, file_) #copy file copy_path = os.path.join(self.po_path, file_name) if self.request.GET.get('delete', 0) or \ not (app_name.startswith('django.contrib') \ and os.path.exists(copy_path)): shutil.copy(original_file_path, copy_path) os.chmod(copy_path, 0664) #unlink updated file if not app_name.startswith('django.contrib'): os.unlink(original_file_path) lang_files.append(file_name) if not app_name.startswith('django.contrib'): if delete_at_the_end: shutil.rmtree(os.path.join(mod_root, 'locale', to_locale(self.language.name))) else: for file_ in os.listdir(original_path): #put back the original application files if file_.startswith('original-') and file_.endswith('.po'): shutil.move(os.path.join(original_path, file_), os.path.join(original_path, file_.replace('original-',''))) #concat all messages in a single .po file for each domain for domain in domain_dict: file_name = '%s.po' % domain uni_django_path = os.path.join(self.po_path, file_name) if os.path.exists(uni_django_path): os.unlink(uni_django_path) source_files = [os.path.join(self.po_path, f) for f in lang_files \ if f.endswith(file_name)] if source_files: #merge .po files concat_message_files(source_files, uni_django_path) #compile django.po if not has_bom(uni_django_path): compile_message_file(uni_django_path) #reset the cached translation messages so that #we do not need to restart the web server reset_translations(self.language.name) context['lang_files'] = sorted(lang_files) return context