diff options
author | Sayamindu Dasgupta <sayamindu@gmail.com> | 2010-01-08 22:45:07 (GMT) |
---|---|---|
committer | Sayamindu Dasgupta <sayamindu@gmail.com> | 2010-01-08 22:45:07 (GMT) |
commit | 1790e434a8a1e32132443ad5868598cb3a619c4e (patch) | |
tree | e5f2ef6f7e82a721a0c0466532be62368c529451 /Pootle-2.0.0 | |
parent | 291467c06268c79f4ae7750060f572b6a2ce5f1e (diff) |
Add syntax check via libgettextpo
Diffstat (limited to 'Pootle-2.0.0')
4 files changed, 76 insertions, 13 deletions
diff --git a/Pootle-2.0.0/html/style.css b/Pootle-2.0.0/html/style.css index 7c43572..fda9338 100644 --- a/Pootle-2.0.0/html/style.css +++ b/Pootle-2.0.0/html/style.css @@ -478,6 +478,19 @@ html[dir="rtl"] #nav-main ul li padding: 10px 25px; } +#validate-message +{ + background-image: url('images/error.png'); + background-repeat: no-repeat; + line-height: 3; + background-position: left center; + font-weight: bold; + background-color: #ffe; + border: 1px solid #fc9; + margin-bottom: 2em; + padding: 10px 25px; +} + #site-message .success { color: #3f3; diff --git a/Pootle-2.0.0/local_apps/pootle_app/templates/language/translatepage.html b/Pootle-2.0.0/local_apps/pootle_app/templates/language/translatepage.html index 32da92c..3e87385 100644 --- a/Pootle-2.0.0/local_apps/pootle_app/templates/language/translatepage.html +++ b/Pootle-2.0.0/local_apps/pootle_app/templates/language/translatepage.html @@ -58,6 +58,9 @@ </ul> {% endif %} <div class="translate-form"> + {% if validationerror %} + <div id="validate-message" class="error" dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}">{{ validationerror }}</div> + {% endif %} {% if notice %} <div id="site-message" dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}">{{ notice }}</div> {% else %} diff --git a/Pootle-2.0.0/local_apps/pootle_app/views/language/translate_page.py b/Pootle-2.0.0/local_apps/pootle_app/views/language/translate_page.py index da4d70d..1168335 100644 --- a/Pootle-2.0.0/local_apps/pootle_app/views/language/translate_page.py +++ b/Pootle-2.0.0/local_apps/pootle_app/views/language/translate_page.py @@ -23,6 +23,9 @@ import re import difflib import os +import sys + +import gettextpo from django.conf import settings from django.core.exceptions import PermissionDenied @@ -724,6 +727,7 @@ def handle_suggestions(last_item, request, store, submitsuggests, skips, transla return last_item def handle_submits(last_item, request, store, submits, skips, translations, comments, fuzzies): + validation_error = {} for item in submits: if item in skips or item not in translations: continue @@ -741,9 +745,14 @@ def handle_submits(last_item, request, store, submits, skips, translations, comm if translator_comments: newvalues["translator_comments"] = translator_comments - unit_update.update_translation(store, item, newvalues, request) + try: + unit_update.update_translation(store, item, newvalues, request) + except gettextpo.error: + validation_error = _("Gettext validation error: %s") % (sys.exc_info()[1]) + last_item = item - return last_item + + return last_item, validation_error def process_post(request, store): @@ -801,33 +810,45 @@ def process_post(request, store): prev_last_item = handle_backs(-1, backs) last_item = handle_skips(-1, skips) last_item = handle_suggestions(last_item, request, store, submitsuggests, skips, translations) - last_item = handle_submits(last_item, request, store, submits, skips, translations, comments, fuzzies) - return prev_last_item, last_item + last_item, validation_error = handle_submits(last_item, request, store, submits, skips, translations, comments, fuzzies) + return prev_last_item, last_item, validation_error def process_post_main(store_name, item, request, next_store_item, prev_store_item): store = Store.objects.get(pootle_path=store_name) request.translation_project.indexer # Force initialization of the indexer - prev_item, next_item = process_post(request, store) + prev_item, next_item, validation_error = process_post(request, store) + + if len(validation_error) > 0: + if prev_item > -1: + prev_item = prev_item - 1 + if next_item > -1: + next_item = next_item - 1 search = search_forms.search_from_request(request) if next_item > -1: - return next_store_item(search, store_name, next_item + 1) + ret = next_store_item(search, store_name, next_item + 1) + return ret[0], ret[1], validation_error elif prev_item > -1: - return prev_store_item(search, store_name, prev_item - 1) + ret = prev_store_item(search, store_name, prev_item - 1) + return ret[0], ret[1], validation_error else: - return store, item + return store, item, validation_error def get_position(request, next_store_item, prev_store_item): state = dispatch.TranslatePageState(request.GET) store_name = dispatch.get_store(request) item = state.item + validation_error = {} if request.method == 'POST': if 'new_search' in request.POST: - return next_store_item(search_forms.search_from_request(request), store_name, item) + ret = next_store_item(search_forms.search_from_request(request), store_name, item) + return ret[0], ret[1], validation_error else: return process_post_main(store_name, item, request, next_store_item, prev_store_item) else: - return next_store_item(search_forms.search_from_request(request), store_name, item) + ret = next_store_item(search_forms.search_from_request(request), store_name, item) + return ret[0], ret[1], validation_error + def get_failure_message(request): # We are reviewing a check @@ -843,12 +864,12 @@ def get_failure_message(request): def find_and_display(request, directory, next_store_item, prev_store_item): try: - store, item = get_position(request, next_store_item, prev_store_item) - return view(request, directory, store, item) + store, item, validation_error = get_position(request, next_store_item, prev_store_item) + return view(request, directory, store, item, validation_error = validation_error) except StopIteration: return view(request, directory, None, 0, get_failure_message(request)) -def view(request, directory, store, item, stopped_by=None): +def view(request, directory, store, item, stopped_by=None, validation_error={}): """the page which lets people edit translations""" state = dispatch.TranslatePageState(request.GET) if not check_permission("view", request): @@ -900,6 +921,7 @@ def view(request, directory, store, item, stopped_by=None): # translation form "actionurl": formaction, "notice": notice, + "validationerror": validation_error, # l10n: Heading above the table column with the source language "original_title": _("Original"), # l10n: Heading above the table column with the target language diff --git a/Pootle-2.0.0/local_apps/pootle_store/fields.py b/Pootle-2.0.0/local_apps/pootle_store/fields.py index 76ab93d..91a6a8b 100644 --- a/Pootle-2.0.0/local_apps/pootle_store/fields.py +++ b/Pootle-2.0.0/local_apps/pootle_store/fields.py @@ -26,6 +26,8 @@ import os import shutil import tempfile +import gettextpo + from django.conf import settings from django.core.files import File from django.db.models.fields.files import FieldFile, FileField @@ -40,6 +42,27 @@ from pootle.__version__ import sver as pootle_version x_generator = "Pootle %s" % pootle_version + +def validate_gettext_translation(unit): + ''' + Uses libgettextpo to validate translation. + Raises exception if validation fails + ''' + #TODO: Add plural support + if not isinstance(unit, po.pounit): + # We can only handle po files + return + + pomessage = gettextpo.PoMessage() + pomessage.set_msgid(unit.msgid[0]) + pomessage.set_msgstr(unit.msgstr[0]) + + for tc in ['python-format', 'c-format', 'php-format']: + if unit.hastypecomment(tc): + pomessage.set_format(tc, True) + + pomessage.check_format() + class StatsTuple(object): """Encapsulates stats in the in memory cache, needed since LRUCachingDict is based on a weakref.WeakValueDictionary @@ -171,6 +194,8 @@ class TranslationStoreFile(File): unit.target = newvalues['target'][0] else: unit.target = newvalues['target'] + if not unit.hasplural(): + validate_gettext_translation(unit) if newvalues.has_key('fuzzy'): unit.markfuzzy(newvalues['fuzzy']) if newvalues.has_key('translator_comments'): |