def update_confirmation(request): data = None if request.method == 'POST': data = request.POST form = UpdateConfirmationPoForm(data=data) up_conf = request.session.get('transhette_update_confirmation') priority = up_conf['priority'] filename = up_conf['filename'] pofile_tmp = pofile(up_conf['po_tmp']) pofile_dest_file = pofile(up_conf['po_dest_file']) if form.is_valid(): priority = up_conf['priority'] merge(pofile_tmp, pofile_dest_file, priority) redirect_to = reverse('transhette.views.home') return HttpResponseRedirect(redirect_to) else: lang = up_conf['lang'] list_lang = find_pos(lang, include_djangos=False, include_transhette=False) lang_index = list_lang.index(up_conf['po_dest_file']) posible_path = _get_path_file(pofile_tmp, filename) news_entries, changes_entries = get_changes(pofile_tmp, pofile_dest_file, priority) return render_to_response('transhette/update_confirmation.html', {'form': form, 'news_entries': news_entries, 'changes_entries': changes_entries, 'po_dest_file': up_conf['po_dest_file'], 'priority': priority, 'posible_path': posible_path, 'lang': lang, 'lang_index': lang_index, 'ADMIN_MEDIA_PREFIX': ADMIN_PREFIX}, context_instance=RequestContext(request))
def list_languages(request): """ Lists the languages for the current project, the gettext catalog files that can be translated and their translation progress """ languages = [] do_django = 'django' in request.GET or get_setting('INCLUDE_DJANGOS') do_transhette = 'transhette' in request.GET or get_setting( 'INCLUDE_TRANSHETTE') has_pos = False for language in settings.LANGUAGES: pos = find_pos(language[0], include_djangos=do_django, include_transhette=do_transhette) has_pos = has_pos or len(pos) languages.append(( language[0], _(language[1]), [(os.path.realpath(l), pofile(l)) for l in pos], )) ADMIN_MEDIA_PREFIX = ADMIN_PREFIX version = transhette.get_version(True) return render_to_response('transhette/languages.html', locals(), context_instance=RequestContext(request))
def search_msg_id_in_other_pos(msg_list, lang, pofile_path): pofile_paths = find_pos( lang, include_djangos=get_setting('INCLUDE_DJANGOS'), include_transhette=get_setting('INCLUDE_TRANSHETTE')) pofiles = [] for path in pofile_paths: pofiles.append(pofile(path)) for msg in msg_list: for p in pofiles: valid_entry = None valid_catalog = p if p.fpath == pofile_path.fpath: is_valid = True break msgid = msg['message'].msgid entry = p.find(msgid) if entry: is_valid = False valid_entry = entry break msg.update({ 'is_valid': is_valid, 'valid_catalog': valid_catalog, 'valid_entry': valid_entry }) return msg_list
def translation_conflicts(request): """ Returns a conflict msgid list. Same msgstr translations from different msgids """ locale_path = os.path.join(settings.BASEDIR, 'locale') po_dict = {} # fill pofile_dict for lang, _lang_name in settings.LANGUAGES: po = pofile(os.path.join(locale_path, lang, 'LC_MESSAGES', 'django.po')) po_dict[lang] = po # reference po file catalog. used to find conflicts main_po = po_dict['es'] msgstr_list = [entry.msgstr for entry in main_po] msgid_list = [entry.msgid for entry in main_po] conflicts = [] for msgstr in msgstr_list: indexes = [] index = -1 try: while True: index = msgstr_list.index(msgstr, index+1) entry = main_po.find(msgid_list[index]) if entry.translated() and not entry.msgid_plural: indexes.append(index) except ValueError: pass if len(indexes) == 0: continue # not present. usually msgstr was a database value elif len(indexes) > 1: # conflict happends. two or more msgid are translated into same msgstr conflict = {} conflict['msgstr'] = msgstr conflict['conflict_list'] = [] for i in indexes: msgid = msgid_list[i] main_entry = main_po.find(msgid) item = { 'msgid': msgid, 'entries': [], 'occurrences': [], } for lang, po in po_dict.items(): entry = po.find(msgid) if entry.translated(): item['entries'].append( {'lang': lang, 'entry': entry}, ) for occurrence in main_entry.occurrences: item['occurrences'].append( {'file': occurrence[0], 'line': occurrence[1]}, ) conflict['conflict_list'].append(item) conflicts.append(conflict) return render_to_response('transhette/translation_conflicts.html', {'conflicts': conflicts, 'ADMIN_MEDIA_PREFIX': ADMIN_PREFIX}, context_instance=RequestContext(request))
def lang_sel(request, langid, idx): """ Selects a file to be translated """ if langid not in [l[0] for l in settings.LANGUAGES]: raise Http404 else: do_django = 'django' in request.GET or get_setting('INCLUDE_DJANGOS') do_transhette = 'transhette' in request.GET or get_setting( 'INCLUDE_TRANSHETTE') request.session['transhette_i18n_lang_code'] = langid request.session['transhette_i18n_lang_name'] = str([ l[1] for l in settings.LANGUAGES if l[0] == langid ][0]).decode('utf-8') file_ = find_pos(langid, include_djangos=do_django, include_transhette=do_transhette)[int(idx)] reload_catalog_in_session(request, file_) # Retain query arguments query_arg = "" if 'query' in request.REQUEST: query_arg = '?query=%s' % request.REQUEST.get('query') if 'page' in request.GET: if query_arg: query_arg = query_arg + '&' else: query_arg = '?' query_arg = query_arg + 'page=%d' % int(request.GET.get('page')) if get_setting('SHOW_NATIVE_LANGUAGE'): native_lang = get_setting('FORCE_NATIVE_LANGUAGE_TO', default=get_language()) request.session['transhette_i18n_native_lang_code'] = native_lang request.session['transhette_i18n_native_lang_name'] = str([ l[1] for l in settings.LANGUAGES if l[0] == native_lang ][0]).decode('utf-8') file_locale_path = file_.split(os.path.sep) file_locale_path[-3] = native_lang native_file_ = os.path.sep.join(file_locale_path) if os.path.isfile(native_file_): native_po = pofile(native_file_) for i in range(len(native_po)): native_po[i].id = i request.session['transhette_i18n_native_pofile'] = native_po try: os.utime(file_, None) request.session['transhette_i18n_write'] = True except OSError: request.session['transhette_i18n_write'] = False return HttpResponseRedirect(reverse('transhette-home') + query_arg)
def _get_files_to_merge(self): # Escribo el archivo que ha mandado el usuario en un archivo temporal temporal_filepath = tempfile.NamedTemporaryFile().name tmp_file = open(temporal_filepath, "w") if self.data_file is None: self.data_file = self.cleaned_data['file'].read() tmp_file.write(self.data_file) tmp_file.flush() po_tmp = polib.pofile(temporal_filepath) if not self.pofile: # Consigo la ruta del archivo con el cual voy a hacer un merge, creo un pofile path_file = _get_path_file(po_tmp, self.cleaned_data['file'].name, self.cleaned_data.get('language', None), self.cleaned_data.get('application', None)) po_dest_file = polib.pofile(path_file) else: po_dest_file = self.pofile return (tmp_file, po_tmp, po_dest_file)
def reload_catalog_in_session(request, file_path=None): """ Reload transhette catalog in session """ if file_path is None: file_path = request.session['transhette_i18n_fn'] po = pofile(file_path) for i in range(len(po)): po[i].id = i request.session['transhette_i18n_fn'] = file_path request.session['transhette_i18n_pofile'] = po request.session['transhette_i18n_mtime'] = os.stat(file_path)[-2]
def update_confirmation(request): data = None if request.method == 'POST': data = request.POST form = UpdateConfirmationPoForm(data=data) up_conf = request.session.get('transhette_update_confirmation') priority = up_conf['priority'] filename = up_conf['filename'] pofile_tmp = pofile(up_conf['po_tmp']) pofile_dest_file = pofile(up_conf['po_dest_file']) if form.is_valid(): priority = up_conf['priority'] merge(pofile_tmp, pofile_dest_file, priority) redirect_to = reverse('transhette.views.home') return HttpResponseRedirect(redirect_to) else: lang = up_conf['lang'] list_lang = find_pos(lang, include_djangos=False, include_transhette=False) lang_index = list_lang.index(up_conf['po_dest_file']) posible_path = _get_path_file(pofile_tmp, filename) news_entries, changes_entries = get_changes(pofile_tmp, pofile_dest_file, priority) return render_to_response('transhette/update_confirmation.html', { 'form': form, 'news_entries': news_entries, 'changes_entries': changes_entries, 'po_dest_file': up_conf['po_dest_file'], 'priority': priority, 'posible_path': posible_path, 'lang': lang, 'lang_index': lang_index, 'ADMIN_MEDIA_PREFIX': ADMIN_PREFIX }, context_instance=RequestContext(request))
def lang_sel(request, langid, idx): """ Selects a file to be translated """ if langid not in [l[0] for l in settings.LANGUAGES]: raise Http404 else: do_django = 'django' in request.GET or get_setting('INCLUDE_DJANGOS') do_transhette = 'transhette' in request.GET or get_setting('INCLUDE_TRANSHETTE') request.session['transhette_i18n_lang_code'] = langid request.session['transhette_i18n_lang_name'] = str([l[1] for l in settings.LANGUAGES if l[0] == langid][0]).decode('utf-8') file_ = find_pos(langid, include_djangos=do_django, include_transhette=do_transhette)[int(idx)] reload_catalog_in_session(request, file_) # Retain query arguments query_arg = "" if 'query' in request.REQUEST: query_arg = '?query=%s' % request.REQUEST.get('query') if 'page' in request.GET: if query_arg: query_arg = query_arg + '&' else: query_arg = '?' query_arg = query_arg + 'page=%d' % int(request.GET.get('page')) if get_setting('SHOW_NATIVE_LANGUAGE'): native_lang = get_setting('FORCE_NATIVE_LANGUAGE_TO', default=get_language()) request.session['transhette_i18n_native_lang_code'] = native_lang request.session['transhette_i18n_native_lang_name'] = str([l[1] for l in settings.LANGUAGES if l[0] == native_lang][0]).decode('utf-8') file_locale_path = file_.split(os.path.sep) file_locale_path[-3] = native_lang native_file_ = os.path.sep.join(file_locale_path) if os.path.isfile(native_file_): native_po = pofile(native_file_) for i in range(len(native_po)): native_po[i].id = i request.session['transhette_i18n_native_pofile'] = native_po try: os.utime(file_, None) request.session['transhette_i18n_write'] = True except OSError: request.session['transhette_i18n_write'] = False return HttpResponseRedirect(reverse('transhette-home') + query_arg)
def set_new_translation(request): """ Post to include a new translation for a msgid """ message = 'SOME ERRORS' if not request.POST: return None else: msgid = request.POST['msgid'] msgstr = request.POST['msgstr'] lang = get_language() pos = find_pos(lang, include_djangos=True, include_transhette=True) if pos: for file_po in pos: candidate = pofile(file_po) poentry = candidate.find(msgid) if poentry: selected_pofile = candidate poentry.msgstr = msgstr po_filename = file_po break format_errors = validate_format(selected_pofile) if not format_errors: try: selected_pofile.metadata[ 'Last-Translator'] = unicodedata.normalize( 'NFKD', u"%s %s <%s>" % (request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') selected_pofile.metadata['X-Translated-Using'] = str( "django-transhette %s" % transhette.get_version(False)) selected_pofile.metadata[ 'PO-Revision-Date'] = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass selected_pofile.save() selected_pofile.save_as_mofile(po_filename.replace('.po', '.mo')) message = 'OK' return render_to_response('transhette/inline_demo_result.html', {'message': message}, context_instance=RequestContext(request))
def list_languages(request): """ Lists the languages for the current project, the gettext catalog files that can be translated and their translation progress """ languages = [] do_django = 'django' in request.GET or get_setting('INCLUDE_DJANGOS') do_transhette = 'transhette' in request.GET or get_setting('INCLUDE_TRANSHETTE') has_pos = False for language in settings.LANGUAGES: pos = find_pos(language[0], include_djangos=do_django, include_transhette=do_transhette) has_pos = has_pos or len(pos) languages.append( (language[0], _(language[1]), [(os.path.realpath(l), pofile(l)) for l in pos], ) ) ADMIN_MEDIA_PREFIX = ADMIN_PREFIX version = transhette.get_version(True) return render_to_response('transhette/languages.html', locals(), context_instance=RequestContext(request))
def set_new_translation(request): """ Post to include a new translation for a msgid """ message='SOME ERRORS' if not request.POST: return None else: msgid = request.POST['msgid'] msgstr = request.POST['msgstr'] lang = get_language() pos = find_pos(lang, include_djangos=True, include_transhette=True) if pos: for file_po in pos: candidate = pofile(file_po) poentry = candidate.find(msgid) if poentry: selected_pofile = candidate poentry.msgstr = msgstr po_filename = file_po break format_errors = validate_format(selected_pofile) if not format_errors: try: selected_pofile.metadata['Last-Translator'] = unicodedata.normalize('NFKD', u"%s %s <%s>" %(request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') selected_pofile.metadata['X-Translated-Using'] = str("django-transhette %s" % transhette.get_version(False)) selected_pofile.metadata['PO-Revision-Date'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass selected_pofile.save() selected_pofile.save_as_mofile(po_filename.replace('.po', '.mo')) message='OK' return render_to_response('transhette/inline_demo_result.html', {'message': message}, context_instance=RequestContext(request))
def search_msg_id_in_other_pos(msg_list, lang, pofile_path): pofile_paths = find_pos(lang, include_djangos=get_setting('INCLUDE_DJANGOS'), include_transhette=get_setting('INCLUDE_TRANSHETTE')) pofiles = [] for path in pofile_paths: pofiles.append(pofile(path)) for msg in msg_list: for p in pofiles: valid_entry = None valid_catalog = p if p.fpath == pofile_path.fpath: is_valid = True break msgid = msg['message'].msgid entry = p.find(msgid) if entry: is_valid = False valid_entry = entry break msg.update({'is_valid': is_valid, 'valid_catalog': valid_catalog, 'valid_entry': valid_entry}) return msg_list
def ajax(request): def fix_nls(in_, out_): """Fixes submitted translations by filtering carriage returns and pairing newlines at the begging and end of the translated string with the original """ if 0 == len(in_) or 0 == len(out_): return out_ if "\r" in out_ and "\r" not in in_: out_=out_.replace("\r", '') if "\n" == in_[0] and "\n" != out_[0]: out_ = "\n" + out_ elif "\n" != in_[0] and "\n" == out_[0]: out_ = out_.lstrip() if "\n" == in_[-1] and "\n" != out_[-1]: out_ = out_ + "\n" elif "\n" != in_[-1] and "\n" == out_[-1]: out_ = out_.rstrip() return out_ catalog = request.GET.get('catalog', None) translation = request.GET.get('translation', None) if not translation: translation = {} for key, value in request.GET.items(): if key.startswith('translation_'): translation[key.replace('translation_', '')]=value msgid = request.GET.get('msgid', None) try: po_file = pofile(catalog) entry = po_file.find(msgid) except: po_file = None entry = None if not catalog or not translation or not msgid\ or not po_file or not entry: raise Http404 saved = False if isinstance(translation, dict): for key, item in translation.items(): entry.msgstr_plural[key] = fix_nls(entry.msgid_plural, item) else: entry.msgstr = fix_nls(entry.msgid, translation) if 'fuzzy' in entry.flags: entry.flags.remove('fuzzy') transhette_i18n_write = request.session.get('transhette_i18n_write', True) format_errors = validate_format(po_file) if transhette_i18n_write and not format_errors: try: po_file.metadata['Last-Translator'] = unicodedata.normalize('NFKD', u"%s %s <%s>" %(request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') po_file.metadata['X-Translated-Using'] = str("django-transhette %s" % transhette.get_version(False)) po_file.metadata['PO-Revision-Date'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass try: po_file.save() po_file.save_as_mofile(po_file.fpath.replace('.po', '.mo')) saved = True except: pass json_dict = simplejson.dumps({'saved': saved, 'translation': translation}) return HttpResponse(json_dict, mimetype='text/javascript')
def merge(po_tmp, po_dest_file, priority): po_tmp = pofile(po_tmp.fpath) priority_merge(po_dest_file, po_tmp, priority)
def home(request): """ Displays a list of messages to be translated """ def fix_nls(in_, out_): """Fixes submitted translations by filtering carriage returns and pairing newlines at the begging and end of the translated string with the original """ if 0 == len(in_) or 0 == len(out_): return out_ if "\r" in out_ and "\r" not in in_: out_=out_.replace("\r", '') if "\n" == in_[0] and "\n" != out_[0]: out_ = "\n" + out_ elif "\n" != in_[0] and "\n" == out_[0]: out_ = out_.lstrip() if "\n" == in_[-1] and "\n" != out_[-1]: out_ = out_ + "\n" elif "\n" != in_[-1] and "\n" == out_[-1]: out_ = out_.rstrip() return out_ version = transhette.get_version(True) if 'transhette_i18n_fn' in request.session: # if another translator has updated catalog... we will reload this reload_if_catalog_updated(request) transhette_i18n_fn = request.session.get('transhette_i18n_fn') transhette_i18n_pofile = request.session.get('transhette_i18n_pofile') transhette_i18n_native_pofile = request.session.get('transhette_i18n_native_pofile') transhette_i18n_lang_code = request.session.get('transhette_i18n_lang_code') transhette_i18n_lang_bidi = (transhette_i18n_lang_code in settings.LANGUAGES_BIDI) transhette_i18n_write = request.session.get('transhette_i18n_write', True) languages = [] for language in settings.LANGUAGES: pos = find_pos(language[0]) position = None lang_frag = '/%s/' for i in xrange(len(pos)): if transhette_i18n_pofile.fpath.replace( lang_frag % transhette_i18n_lang_code, lang_frag % language[0]) == pofile(pos[i]).fpath: position = i if position is not None: languages.append((language[0], _(language[1]), position)) # Retain query arguments query_arg = '' if 'query' in request.REQUEST: query_arg = '?query=%s' % request.REQUEST.get('query') if 'page' in request.GET: if query_arg: query_arg = query_arg + '&' else: query_arg = '?' query_arg = query_arg + 'page=%d' % int(request.GET.get('page')) if 'filter' in request.GET: if request.GET.get('filter') in ['untranslated', 'translated', 'both', 'fuzzy']: filter_ = request.GET.get('filter') request.session['transhette_i18n_filter'] = filter_ return HttpResponseRedirect(reverse('transhette-home')) elif 'transhette_i18n_filter' in request.session: transhette_i18n_filter = request.session.get('transhette_i18n_filter') else: transhette_i18n_filter = 'both' if '_next' in request.POST: rx=re.compile(r'^m_([0-9]+)') rx_plural=re.compile(r'^m_([0-9]+)_([0-9]+)') file_change = False for k in request.POST.keys(): if rx_plural.match(k): id=int(rx_plural.match(k).groups()[0]) idx=int(rx_plural.match(k).groups()[1]) transhette_i18n_pofile[id].msgstr_plural[str(idx)] = fix_nls(transhette_i18n_pofile[id].msgid_plural[idx], request.POST.get(k)) file_change = True elif rx.match(k): id=int(rx.match(k).groups()[0]) transhette_i18n_pofile[id].msgstr = fix_nls(transhette_i18n_pofile[id].msgid, request.POST.get(k)) file_change = True if file_change and 'fuzzy' in transhette_i18n_pofile[id].flags: transhette_i18n_pofile[id].flags.remove('fuzzy') format_errors = validate_format(transhette_i18n_pofile) if file_change and transhette_i18n_write and not format_errors: reload_if_catalog_updated(request, polling=True) try: transhette_i18n_pofile.metadata['Last-Translator'] = unicodedata.normalize('NFKD', u"%s %s <%s>" %(request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') transhette_i18n_pofile.metadata['X-Translated-Using'] = str("django-transhette %s" % transhette.get_version(False)) transhette_i18n_pofile.metadata['PO-Revision-Date'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass try: mo_path = transhette_i18n_fn.replace('.po', '.mo') transhette_i18n_pofile.save() transhette_i18n_pofile.save_as_mofile(mo_path) # Try auto-reloading via the WSGI daemon mode reload mechanism if get_setting('WSGI_AUTO_RELOAD') and\ 'mod_wsgi.process_group' in request.environ and \ request.environ.get('mod_wsgi.process_group', None) and \ 'SCRIPT_FILENAME' in request.environ and \ int(request.environ.get('mod_wsgi.script_reloading', '0')): try: os.utime(request.environ.get('SCRIPT_FILENAME'), None) except OSError: pass except: request.session['transhette_i18n_write'] = False request.session['transhette_i18n_pofile'] = transhette_i18n_pofile request.session['transhette_i18n_native_pofile'] = transhette_i18n_native_pofile return HttpResponseRedirect(reverse('transhette-home') + query_arg) transhette_i18n_lang_name = _(request.session.get('transhette_i18n_lang_name')) transhette_i18n_lang_code = request.session.get('transhette_i18n_lang_code') transhette_i18n_native_lang_name = request.session.get('transhette_i18n_native_lang_name', '') transhette_i18n_native_lang_code = request.session.get('transhette_i18n_native_lang_code', '') if 'query' in request.REQUEST and request.REQUEST.get('query', '').strip(): query = request.REQUEST.get('query').strip() try: rx = re.compile(re.escape(query), re.IGNORECASE) except re.error: rx = None matched_entries = [] if rx: for e in transhette_i18n_pofile: entry_text = smart_unicode(e.msgstr) + smart_unicode(e.msgid) if get_setting('SEARCH_INTO_OCCURRENCES'): entry_text += u''.join([o[0] for o in e.occurrences]) if rx.search(entry_text): matched_entries.append(e) if transhette_i18n_native_pofile: for e in transhette_i18n_native_pofile: entry_text = smart_unicode(e.msgstr) + smart_unicode(e.msgid) if get_setting('SEARCH_INTO_OCCURRENCES'): entry_text += u''.join([o[0] for o in e.occurrences]) if rx.search(entry_text): lang_entry = transhette_i18n_pofile.find(e.msgid) if lang_entry and not lang_entry in matched_entries: matched_entries.append(lang_entry) pofile_to_paginate = matched_entries else: if transhette_i18n_filter == 'both': pofile_to_paginate = transhette_i18n_pofile elif transhette_i18n_filter == 'untranslated': pofile_to_paginate = transhette_i18n_pofile.untranslated_entries() elif transhette_i18n_filter == 'translated': pofile_to_paginate = transhette_i18n_pofile.translated_entries() elif transhette_i18n_filter == 'fuzzy': pofile_to_paginate = transhette_i18n_pofile.fuzzy_entries() if get_setting('SHOW_NATIVE_LANGUAGE') and transhette_i18n_native_pofile: to_paginate = [dict(message=message, native_message=transhette_i18n_native_pofile.find(message.msgid)) \ for message in pofile_to_paginate] else: to_paginate = [dict(message=message) for message in pofile_to_paginate] paginator = Paginator(to_paginate, get_setting('MESSAGES_PER_PAGE')) if 'page' in request.GET and int(request.GET.get('page')) <= paginator.num_pages and int(request.GET.get('page')) > 0: page = int(request.GET.get('page')) else: page = 1 if get_setting('SHOW_NATIVE_LANGUAGE') and transhette_i18n_lang_code != transhette_i18n_native_lang_code: default_column_name = True else: default_column_name = False message_list = paginator.page(page).object_list message_list = search_msg_id_in_other_pos(message_list, transhette_i18n_lang_code, transhette_i18n_pofile) needs_pagination = paginator.num_pages > 1 if needs_pagination: if paginator.num_pages >= 10: page_range = pagination_range(1, paginator.num_pages, page) else: page_range = range(1, 1 + paginator.num_pages) ADMIN_MEDIA_PREFIX = ADMIN_PREFIX ENABLE_TRANSLATION_SUGGESTIONS = get_setting('ENABLE_TRANSLATION_SUGGESTIONS') return render_to_response('transhette/pofile.html', locals(), context_instance=RequestContext(request)) else: return list_languages(request)
def home(request): """ Displays a list of messages to be translated """ def fix_nls(in_, out_): """Fixes submitted translations by filtering carriage returns and pairing newlines at the begging and end of the translated string with the original """ if 0 == len(in_) or 0 == len(out_): return out_ if "\r" in out_ and "\r" not in in_: out_ = out_.replace("\r", '') if "\n" == in_[0] and "\n" != out_[0]: out_ = "\n" + out_ elif "\n" != in_[0] and "\n" == out_[0]: out_ = out_.lstrip() if "\n" == in_[-1] and "\n" != out_[-1]: out_ = out_ + "\n" elif "\n" != in_[-1] and "\n" == out_[-1]: out_ = out_.rstrip() return out_ version = transhette.get_version(True) if 'transhette_i18n_fn' in request.session: # if another translator has updated catalog... we will reload this reload_if_catalog_updated(request) transhette_i18n_fn = request.session.get('transhette_i18n_fn') transhette_i18n_pofile = request.session.get('transhette_i18n_pofile') transhette_i18n_native_pofile = request.session.get( 'transhette_i18n_native_pofile') transhette_i18n_lang_code = request.session.get( 'transhette_i18n_lang_code') transhette_i18n_lang_bidi = (transhette_i18n_lang_code in settings.LANGUAGES_BIDI) transhette_i18n_write = request.session.get('transhette_i18n_write', True) languages = [] for language in settings.LANGUAGES: pos = find_pos(language[0]) position = None lang_frag = '/%s/' for i in xrange(len(pos)): if transhette_i18n_pofile.fpath.replace( lang_frag % transhette_i18n_lang_code, lang_frag % language[0]) == pofile(pos[i]).fpath: position = i if position is not None: languages.append((language[0], _(language[1]), position)) # Retain query arguments query_arg = '' if 'query' in request.REQUEST: query_arg = '?query=%s' % request.REQUEST.get('query') if 'page' in request.GET: if query_arg: query_arg = query_arg + '&' else: query_arg = '?' query_arg = query_arg + 'page=%d' % int(request.GET.get('page')) if 'filter' in request.GET: if request.GET.get('filter') in [ 'untranslated', 'translated', 'both', 'fuzzy' ]: filter_ = request.GET.get('filter') request.session['transhette_i18n_filter'] = filter_ return HttpResponseRedirect(reverse('transhette-home')) elif 'transhette_i18n_filter' in request.session: transhette_i18n_filter = request.session.get( 'transhette_i18n_filter') else: transhette_i18n_filter = 'both' if '_next' in request.POST: rx = re.compile(r'^m_([0-9]+)') rx_plural = re.compile(r'^m_([0-9]+)_([0-9]+)') file_change = False for k in request.POST.keys(): if rx_plural.match(k): id = int(rx_plural.match(k).groups()[0]) idx = int(rx_plural.match(k).groups()[1]) transhette_i18n_pofile[id].msgstr_plural[str( idx)] = fix_nls( transhette_i18n_pofile[id].msgid_plural[idx], request.POST.get(k)) file_change = True elif rx.match(k): id = int(rx.match(k).groups()[0]) transhette_i18n_pofile[id].msgstr = fix_nls( transhette_i18n_pofile[id].msgid, request.POST.get(k)) file_change = True if file_change and 'fuzzy' in transhette_i18n_pofile[id].flags: transhette_i18n_pofile[id].flags.remove('fuzzy') format_errors = validate_format(transhette_i18n_pofile) if file_change and transhette_i18n_write and not format_errors: reload_if_catalog_updated(request, polling=True) try: transhette_i18n_pofile.metadata[ 'Last-Translator'] = unicodedata.normalize( 'NFKD', u"%s %s <%s>" % (request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') transhette_i18n_pofile.metadata[ 'X-Translated-Using'] = str( "django-transhette %s" % transhette.get_version(False)) transhette_i18n_pofile.metadata[ 'PO-Revision-Date'] = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass try: mo_path = transhette_i18n_fn.replace('.po', '.mo') transhette_i18n_pofile.save() transhette_i18n_pofile.save_as_mofile(mo_path) # Try auto-reloading via the WSGI daemon mode reload mechanism if get_setting('WSGI_AUTO_RELOAD') and\ 'mod_wsgi.process_group' in request.environ and \ request.environ.get('mod_wsgi.process_group', None) and \ 'SCRIPT_FILENAME' in request.environ and \ int(request.environ.get('mod_wsgi.script_reloading', '0')): try: os.utime(request.environ.get('SCRIPT_FILENAME'), None) except OSError: pass except: request.session['transhette_i18n_write'] = False request.session[ 'transhette_i18n_pofile'] = transhette_i18n_pofile request.session[ 'transhette_i18n_native_pofile'] = transhette_i18n_native_pofile return HttpResponseRedirect( reverse('transhette-home') + query_arg) transhette_i18n_lang_name = _( request.session.get('transhette_i18n_lang_name')) transhette_i18n_lang_code = request.session.get( 'transhette_i18n_lang_code') transhette_i18n_native_lang_name = request.session.get( 'transhette_i18n_native_lang_name', '') transhette_i18n_native_lang_code = request.session.get( 'transhette_i18n_native_lang_code', '') if 'query' in request.REQUEST and request.REQUEST.get('query', '').strip(): query = request.REQUEST.get('query').strip() try: rx = re.compile(re.escape(query), re.IGNORECASE) except re.error: rx = None matched_entries = [] if rx: for e in transhette_i18n_pofile: entry_text = smart_unicode(e.msgstr) + smart_unicode( e.msgid) if get_setting('SEARCH_INTO_OCCURRENCES'): entry_text += u''.join([o[0] for o in e.occurrences]) if rx.search(entry_text): matched_entries.append(e) if transhette_i18n_native_pofile: for e in transhette_i18n_native_pofile: entry_text = smart_unicode(e.msgstr) + smart_unicode( e.msgid) if get_setting('SEARCH_INTO_OCCURRENCES'): entry_text += u''.join( [o[0] for o in e.occurrences]) if rx.search(entry_text): lang_entry = transhette_i18n_pofile.find(e.msgid) if lang_entry and not lang_entry in matched_entries: matched_entries.append(lang_entry) pofile_to_paginate = matched_entries else: if transhette_i18n_filter == 'both': pofile_to_paginate = transhette_i18n_pofile elif transhette_i18n_filter == 'untranslated': pofile_to_paginate = transhette_i18n_pofile.untranslated_entries( ) elif transhette_i18n_filter == 'translated': pofile_to_paginate = transhette_i18n_pofile.translated_entries( ) elif transhette_i18n_filter == 'fuzzy': pofile_to_paginate = transhette_i18n_pofile.fuzzy_entries() if get_setting( 'SHOW_NATIVE_LANGUAGE') and transhette_i18n_native_pofile: to_paginate = [dict(message=message, native_message=transhette_i18n_native_pofile.find(message.msgid)) \ for message in pofile_to_paginate] else: to_paginate = [ dict(message=message) for message in pofile_to_paginate ] paginator = Paginator(to_paginate, get_setting('MESSAGES_PER_PAGE')) if 'page' in request.GET and int( request.GET.get('page')) <= paginator.num_pages and int( request.GET.get('page')) > 0: page = int(request.GET.get('page')) else: page = 1 if get_setting( 'SHOW_NATIVE_LANGUAGE' ) and transhette_i18n_lang_code != transhette_i18n_native_lang_code: default_column_name = True else: default_column_name = False message_list = paginator.page(page).object_list message_list = search_msg_id_in_other_pos(message_list, transhette_i18n_lang_code, transhette_i18n_pofile) needs_pagination = paginator.num_pages > 1 if needs_pagination: if paginator.num_pages >= 10: page_range = pagination_range(1, paginator.num_pages, page) else: page_range = range(1, 1 + paginator.num_pages) ADMIN_MEDIA_PREFIX = ADMIN_PREFIX ENABLE_TRANSLATION_SUGGESTIONS = get_setting( 'ENABLE_TRANSLATION_SUGGESTIONS') return render_to_response('transhette/pofile.html', locals(), context_instance=RequestContext(request)) else: return list_languages(request)
def ajax(request): def fix_nls(in_, out_): """Fixes submitted translations by filtering carriage returns and pairing newlines at the begging and end of the translated string with the original """ if 0 == len(in_) or 0 == len(out_): return out_ if "\r" in out_ and "\r" not in in_: out_ = out_.replace("\r", '') if "\n" == in_[0] and "\n" != out_[0]: out_ = "\n" + out_ elif "\n" != in_[0] and "\n" == out_[0]: out_ = out_.lstrip() if "\n" == in_[-1] and "\n" != out_[-1]: out_ = out_ + "\n" elif "\n" != in_[-1] and "\n" == out_[-1]: out_ = out_.rstrip() return out_ catalog = request.GET.get('catalog', None) translation = request.GET.get('translation', None) if not translation: translation = {} for key, value in request.GET.items(): if key.startswith('translation_'): translation[key.replace('translation_', '')] = value msgid = request.GET.get('msgid', None) try: po_file = pofile(catalog) entry = po_file.find(msgid) except: po_file = None entry = None if not catalog or not translation or not msgid\ or not po_file or not entry: raise Http404 saved = False if isinstance(translation, dict): for key, item in translation.items(): entry.msgstr_plural[key] = fix_nls(entry.msgid_plural, item) else: entry.msgstr = fix_nls(entry.msgid, translation) if 'fuzzy' in entry.flags: entry.flags.remove('fuzzy') transhette_i18n_write = request.session.get('transhette_i18n_write', True) format_errors = validate_format(po_file) if transhette_i18n_write and not format_errors: try: po_file.metadata['Last-Translator'] = unicodedata.normalize( 'NFKD', u"%s %s <%s>" % (request.user.first_name, request.user.last_name, request.user.email)).encode('ascii', 'ignore') po_file.metadata['X-Translated-Using'] = str( "django-transhette %s" % transhette.get_version(False)) po_file.metadata['PO-Revision-Date'] = datetime.datetime.now( ).strftime('%Y-%m-%d %H:%M%z') except UnicodeDecodeError: pass try: po_file.save() po_file.save_as_mofile(po_file.fpath.replace('.po', '.mo')) saved = True except: pass json_dict = simplejson.dumps({'saved': saved, 'translation': translation}) return HttpResponse(json_dict, mimetype='text/javascript')
def translation_conflicts(request): """ Returns a conflict msgid list. Same msgstr translations from different msgids """ locale_path = os.path.join(settings.BASEDIR, 'locale') po_dict = {} # fill pofile_dict for lang, _lang_name in settings.LANGUAGES: po = pofile(os.path.join(locale_path, lang, 'LC_MESSAGES', 'django.po')) po_dict[lang] = po # reference po file catalog. used to find conflicts main_po = po_dict['es'] msgstr_list = [entry.msgstr for entry in main_po] msgid_list = [entry.msgid for entry in main_po] conflicts = [] for msgstr in msgstr_list: indexes = [] index = -1 try: while True: index = msgstr_list.index(msgstr, index + 1) entry = main_po.find(msgid_list[index]) if entry.translated() and not entry.msgid_plural: indexes.append(index) except ValueError: pass if len(indexes) == 0: continue # not present. usually msgstr was a database value elif len(indexes) > 1: # conflict happends. two or more msgid are translated into same msgstr conflict = {} conflict['msgstr'] = msgstr conflict['conflict_list'] = [] for i in indexes: msgid = msgid_list[i] main_entry = main_po.find(msgid) item = { 'msgid': msgid, 'entries': [], 'occurrences': [], } for lang, po in po_dict.items(): entry = po.find(msgid) if entry.translated(): item['entries'].append({ 'lang': lang, 'entry': entry }, ) for occurrence in main_entry.occurrences: item['occurrences'].append( { 'file': occurrence[0], 'line': occurrence[1] }, ) conflict['conflict_list'].append(item) conflicts.append(conflict) return render_to_response('transhette/translation_conflicts.html', { 'conflicts': conflicts, 'ADMIN_MEDIA_PREFIX': ADMIN_PREFIX }, context_instance=RequestContext(request))