diff --git a/Changelog.md b/Changelog.md index ca6dfea1..a419effb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,35 @@ # Changelog for lgr-django +## 3.0.0 (2020-12-04) +### New features +- Add MSR-4 validating repertoire +- Add RZ-LGR validating repertoires +- Add RZ-LGR in built in LGRs list +- Allow collision tool to check collisions with existing set of TLDs downloaded from IANA +- Add a new basic mode: + - new simplified interface + - validate labels against RZ-LGR + - allow checking for collisions as well +- Add language autocompletion from IANA language registry +- Stop support for python 2.7 +### Improvements +- Update symetry report to consider contextual rules +- Update Django to version 2.2.1 +- Update dependencies versions +- Handle internationalized email addresses +- Add translation to validation report +- Cache scripts and repertoires +- Improve memory consumption +- Display IDNA error as user friendly strings +- Correctly validate rule in LGR edition tool +### Fixes +- Fix memory leak +- Fix error handling in label validation + +## 2.0.1 (2019-08-01) +### Improvements +- Mark out-of-script codepoints as warnings instead of errors (Fixes icann/lgr-core#15). + ## 2.0.0 (2018-09-06) ### New features - Support of Python 3. Compatibility with python2 is preserved for this release. diff --git a/Makefile b/Makefile index ef8d2f85..6e4f7657 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,10 @@ MO_FILES= \ src/lgr_tools/locale/ar/LC_MESSAGES/django.mo \ src/lgr_tools/locale/en/LC_MESSAGES/django.mo \ src/lgr_tools/locale/fr/LC_MESSAGES/django.mo \ + src/lgr_basic/locale/ar/LC_MESSAGES/django.mo \ + src/lgr_basic/locale/en/LC_MESSAGES/django.mo \ + src/lgr_basic/locale/fr/LC_MESSAGES/django.mo \ + PO_FILES= \ src/lgr_web/locale/ar/LC_MESSAGES/django.po \ @@ -36,12 +40,16 @@ PO_FILES= \ src/lgr_tools/locale/ar/LC_MESSAGES/django.po \ src/lgr_tools/locale/en/LC_MESSAGES/django.po \ src/lgr_tools/locale/fr/LC_MESSAGES/django.po \ + src/lgr_basic/locale/ar/LC_MESSAGES/django.po \ + src/lgr_basic/locale/en/LC_MESSAGES/django.po \ + src/lgr_basic/locale/fr/LC_MESSAGES/django.po \ + all: messages messages: $(MO_FILES) -update: update-lgrweb update-lgreditor update-lgrvalidator update-lgrtools +update: update-lgrweb update-lgreditor update-lgrvalidator update-lgrtools update-lgrbasic update-lgrweb: cd src/lgr_web && $(MAKEMESSAGES) $(LANGUAGES) $(MKMSG_OPTIONS) @@ -55,6 +63,10 @@ update-lgrvalidator: update-lgrtools: cd src/lgr_tools && $(MAKEMESSAGES) $(LANGUAGES) $(MKMSG_OPTIONS) +update-lgrbasic: + cd src/lgr_basic && $(MAKEMESSAGES) $(LANGUAGES) $(MKMSG_OPTIONS) + + src/lgr_web/locale/%/LC_MESSAGES/django.po: cd `echo "$@" | sed -e 's#\/locale/.*##'` && django-admin.py makemessages $(LANGUAGES) $(MKMSG_OPTIONS) @@ -67,5 +79,8 @@ src/lgr_validator/locale/%/LC_MESSAGES/django.po: src/lgr_tools/locale/%/LC_MESSAGES/django.po: cd `echo "$@" | sed -e 's#\/locale/.*##'` && django-admin.py makemessages $(LANGUAGES) $(MKMSG_OPTIONS) +src/lgr_basic/locale/%/LC_MESSAGES/django.po: + cd `echo "$@" | sed -e 's#\/locale/.*##'` && django-admin.py makemessages $(LANGUAGES) $(MKMSG_OPTIONS) + $(MO_FILES): $(PO_FILES) cd `echo "$@" | sed -e 's#\/locale/.*##'` && $(COMPILEMESSAGES) diff --git a/README.md b/README.md index 17c95964..4ca84369 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ The following modules are reusable Django apps that can be included in other Dja * `lgr_validator` contains the code related the label validation module. * `lgr_tools` contains the code related to all utilities: testing LGR and label sets, LGR comparisons, etc. * `lgr_renderer` contains the code and templates used to generate the static exports of the LGR (HTML only for now). +* `lgr_basic` contains the code related to the simple LGR interface. ## Acknowledgment This toolset was implemented by Viagenie (Audric Schiltknecht, Julien Bernard, -David Drouin and Marc Blanchet) and Wil Tan on an ICANN contract. +David Drouin, Vincent Gonzalez and Marc Blanchet) and Wil Tan on an ICANN contract. ## License @@ -53,7 +54,7 @@ THE POSSIBILITY OF SUCH DAMAGE. ### Pre-requisites * Operating system: Tested on Linux and Mac OS X -* Python 2.7, >= 3.4 +* Python >=3.6 * [LibXML2](http://www.xmlsoft.org/) [MIT License] used by the lxml Python bindings * [ICU4C](http://site.icu-project.org/) [ICU License] * Python modules (listed in `etc/requirements.txt`, or dependencies thereof) @@ -183,6 +184,7 @@ Some notes for developers * `src/lgr_validator/templates` contains validator-specific templates * `src/lgr_tools/templates` contains tool-specific templates * `src/lgr_renderer/templates` contains renderers (HTML output) templates +* `src/lgr_basic/templates` contains simple interface (HTML output) templates #### Static Assets (CSS, Javascript, Images) diff --git a/bin/bootstrap b/bin/bootstrap index 1694ccac..7e6539fa 100755 --- a/bin/bootstrap +++ b/bin/bootstrap @@ -5,7 +5,7 @@ DSITE="src/lgr_web" if [ ! -e venv ]; then echo "==> Creating virtualenv" - virtualenv venv || exit 3 + virtualenv -p python3 venv || exit 3 fi # activate virtualenv diff --git a/etc/requirements.txt b/etc/requirements.txt index bc3a9309..9dbabe5a 100644 --- a/etc/requirements.txt +++ b/etc/requirements.txt @@ -1,14 +1,17 @@ # Core stuff -Django==1.8.4 -django-widget-tweaks==1.4.1 -django-multiupload==0.5.2 -celery[redis]==3.1.23 -django-redis-cache==1.7.1 +Django==2.2.1 +django-widget-tweaks==1.4.3 +#django-multiupload==0.5.2 +-e git+https://github.com/Chive/django-multiupload.git@ba52e161a68ce19062c3655e89544c2d377990a0#egg=django-multiupload +celery[redis]==4.3.0 +django-redis-cache==2.0.0 +django-autocomplete-light==3.5.1 +vine==1.3.0 # LGR/Unicode modules -picu==1.0 +picu==1.1 munidata==2.0.0 -lgr-core==2.0.0 +lgr-core==3.0.0 # Natural sorting implementation -natsort==5.0.3 +natsort==6.0.0 diff --git a/setup.py b/setup.py index be98a9eb..9834a23b 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='lgr-django', - version='2.0.0', + version='3.0.0', author='Viagenie and Wil Tan', author_email='support@viagenie.ca', packages=find_packages('src'), @@ -19,15 +19,18 @@ 'Framework :: Django :: 1.8', 'Operating System :: OS Independent', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], install_requires=[ # Core stuff 'Django', 'django-widget-tweaks', + 'django-multiupload', + 'django-redis-cache', + 'django-autocomplete-light', 'celery', # LGR/Unicode modules 'lgr-core', diff --git a/src/lgr_basic/__init__.py b/src/lgr_basic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/lgr_basic/forms.py b/src/lgr_basic/forms.py new file mode 100644 index 00000000..9db1ff25 --- /dev/null +++ b/src/lgr_basic/forms.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +from django import forms +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ + +from lgr.tools.utils import parse_label_input +from lgr_editor.api import LGRInfo +from lgr_editor.forms.fields import ROOT_ZONES +from lgr_editor.lgr_exceptions import lgr_exception_to_text +from lgr_editor.repertoires import get_by_name +from lgr_editor.unidb import get_db_by_version +from lgr_tools.forms import UAEmailField + + +class ValidateLabelSimpleForm(forms.Form): + rz_lgr = forms.ChoiceField(label='', required=True, choices=ROOT_ZONES, initial=ROOT_ZONES[-1][0]) + labels = forms.CharField(label='', required=False, + widget=forms.TextInput(attrs={'name': '', + 'class': 'form-label form-control', + 'onkeyup': 'buttonValidateEnabled()', + 'placeholder': _('Label')})) + labels_file = forms.FileField(label='', help_text=_('File must be encoded in UTF-8 and using UNIX line ending.'), + required=False) + email = UAEmailField(label='', required=False, + widget=forms.TextInput(attrs={'id': 'email-task', + 'placeholder': _('Email address for tasks results')}), + help_text=_("As the computing may be very long, we will warn by e-mail once the result can " + "be downloaded.")) + collisions = forms.BooleanField(label='', widget=forms.CheckboxInput(attrs={'id': 'check-for-collision'}), + required=False) + + def clean(self): + cleaned_data = super(ValidateLabelSimpleForm, self).clean() + if (self.cleaned_data.get('collisions') and len(cleaned_data.get('labels', [])) > 1) or self.cleaned_data.get( + 'labels_file'): + if not self.cleaned_data.get('email'): + self.add_error('email', _('E-mail is mandatory to get the tasks results')) + + if 'labels' not in self.errors and not cleaned_data.get('labels') and not cleaned_data.get('labels_file'): + self.add_error('labels', _('Required')) + self.add_error('labels_file', _('Required')) + + if cleaned_data.get('labels') and cleaned_data.get('labels_file'): + # should not happen + self.add_error('labels', _('Unknown error, please report')) + self.add_error('labels_file', _('Unknown error, please report')) + + return cleaned_data + + def clean_labels(self): + rz_lgr = self.cleaned_data['rz_lgr'] + lgr_info = LGRInfo(rz_lgr, lgr=get_by_name(rz_lgr, with_unidb=True)) + udata = get_db_by_version(lgr_info.lgr.metadata.unicode_version) + + value = self.cleaned_data['labels'] + labels = list() + for label in set(value.split(';')): + if not label: + continue + try: + labels.append(parse_label_input(label, idna_decoder=udata.idna_decode_label)) + except ValueError as e: + raise ValidationError(lgr_exception_to_text(e)) + return labels diff --git a/src/lgr_basic/locale/ar/LC_MESSAGES/django.mo b/src/lgr_basic/locale/ar/LC_MESSAGES/django.mo new file mode 100644 index 00000000..74dbaf67 Binary files /dev/null and b/src/lgr_basic/locale/ar/LC_MESSAGES/django.mo differ diff --git a/src/lgr_basic/locale/ar/LC_MESSAGES/django.po b/src/lgr_basic/locale/ar/LC_MESSAGES/django.po new file mode 100644 index 00000000..85e5aa8a --- /dev/null +++ b/src/lgr_basic/locale/ar/LC_MESSAGES/django.po @@ -0,0 +1,174 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#: forms.py:21 +msgid "Label" +msgstr "" + +#: forms.py:22 +msgid "File must be encoded in UTF-8 and using UNIX line ending." +msgstr "" + +#: forms.py:26 +msgid "Email address for tasks results" +msgstr "" + +#: forms.py:27 +msgid "" +"As the computing may be very long, we will warn by e-mail once the result " +"can be downloaded." +msgstr "" + +#: forms.py:37 +msgid "E-mail is mandatory to get the tasks results" +msgstr "" + +#: forms.py:40 forms.py:41 +msgid "Required" +msgstr "" + +#: forms.py:45 forms.py:46 +msgid "Unknown error, please report" +msgstr "" + +#: templates/basic_mode.html:8 templates/basic_mode.html:39 +msgid "LGR Tool" +msgstr "" + +#: templates/basic_mode.html:38 templates/basic_mode.html:39 +msgid "Go to home screen" +msgstr "" + +#: templates/basic_mode.html:43 +msgid "Advanced mode" +msgstr "" + +#: templates/basic_mode.html:47 templates/basic_mode.html:253 +msgid "Display all label forms" +msgstr "" + +#: templates/basic_mode.html:48 +msgid "Label forms" +msgstr "" + +#: templates/basic_mode.html:53 +msgid "About LGR Toolset" +msgstr "" + +#: templates/basic_mode.html:54 templates/basic_mode.html:235 +msgid "About" +msgstr "" + +#: templates/basic_mode.html:74 +msgid "" +"The server was unable to complete the request, most likely because too many " +"resources were required to compute the query. If you check for collision, " +"the result may be still processing and will be sent to your email. Please " +"wait before submitting again." +msgstr "" + +#: templates/basic_mode.html:82 +msgid "A server error occurred." +msgstr "" + +#: templates/basic_mode.html:82 +msgid "code:" +msgstr "" + +#: templates/basic_mode.html:82 +msgid "Please contact the administrator before submitting again." +msgstr "" + +#: templates/basic_mode.html:88 +msgid "Validate label(s) against" +msgstr "" + +#: templates/basic_mode.html:93 +msgid "View LGR as" +msgstr "" + +#: templates/basic_mode.html:106 +msgid "Manually input label(s)" +msgstr "" + +#: templates/basic_mode.html:117 +msgid "Upload a list of labels" +msgstr "" + +#: templates/basic_mode.html:136 +msgid "Check for collision with existing TLDs" +msgstr "" + +#: templates/basic_mode.html:150 +#, python-format +msgid "" +"Your request was sent successfully, the collision and validation tasks " +"processing can take minutes, even hours.
The result will be sent to " +"%(email)s. Do not resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:162 +#, python-format +msgid "" +"Your request was sent successfully, the validation task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:174 +#, python-format +msgid "" +"Your request was sent successfully, the collision task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:184 +msgid "Validate" +msgstr "" + +#: templates/basic_mode.html:197 +msgid "Your saved results" +msgstr "" + +#: templates/basic_mode.html:198 +msgid "The following files contains your tools computation results." +msgstr "" + +#: templates/basic_mode.html:201 +msgid "Note that these files could be cleaned up regularly." +msgstr "" + +#: templates/basic_mode.html:206 +#, python-format +msgid "Download %(file)s" +msgstr "" + +#: templates/basic_mode.html:241 +msgid "Close" +msgstr "" + +#: views.py:83 +msgid "" +"Input label generates too many variants to compute them all quickly. You " +"need to enter your email address and will receive a notification once " +"process is done" +msgstr "" diff --git a/src/lgr_basic/locale/en/LC_MESSAGES/django.mo b/src/lgr_basic/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 00000000..6c5906d1 Binary files /dev/null and b/src/lgr_basic/locale/en/LC_MESSAGES/django.mo differ diff --git a/src/lgr_basic/locale/en/LC_MESSAGES/django.po b/src/lgr_basic/locale/en/LC_MESSAGES/django.po new file mode 100644 index 00000000..abd935e6 --- /dev/null +++ b/src/lgr_basic/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,172 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:21 +msgid "Label" +msgstr "" + +#: forms.py:22 +msgid "File must be encoded in UTF-8 and using UNIX line ending." +msgstr "" + +#: forms.py:26 +msgid "Email address for tasks results" +msgstr "" + +#: forms.py:27 +msgid "" +"As the computing may be very long, we will warn by e-mail once the result " +"can be downloaded." +msgstr "" + +#: forms.py:37 +msgid "E-mail is mandatory to get the tasks results" +msgstr "" + +#: forms.py:40 forms.py:41 +msgid "Required" +msgstr "" + +#: forms.py:45 forms.py:46 +msgid "Unknown error, please report" +msgstr "" + +#: templates/basic_mode.html:8 templates/basic_mode.html:39 +msgid "LGR Tool" +msgstr "" + +#: templates/basic_mode.html:38 templates/basic_mode.html:39 +msgid "Go to home screen" +msgstr "" + +#: templates/basic_mode.html:43 +msgid "Advanced mode" +msgstr "" + +#: templates/basic_mode.html:47 templates/basic_mode.html:253 +msgid "Display all label forms" +msgstr "" + +#: templates/basic_mode.html:48 +msgid "Label forms" +msgstr "" + +#: templates/basic_mode.html:53 +msgid "About LGR Toolset" +msgstr "" + +#: templates/basic_mode.html:54 templates/basic_mode.html:235 +msgid "About" +msgstr "" + +#: templates/basic_mode.html:74 +msgid "" +"The server was unable to complete the request, most likely because too many " +"resources were required to compute the query. If you check for collision, " +"the result may be still processing and will be sent to your email. Please " +"wait before submitting again." +msgstr "" + +#: templates/basic_mode.html:82 +msgid "A server error occurred." +msgstr "" + +#: templates/basic_mode.html:82 +msgid "code:" +msgstr "" + +#: templates/basic_mode.html:82 +msgid "Please contact the administrator before submitting again." +msgstr "" + +#: templates/basic_mode.html:88 +msgid "Validate label(s) against" +msgstr "" + +#: templates/basic_mode.html:93 +msgid "View LGR as" +msgstr "" + +#: templates/basic_mode.html:106 +msgid "Manually input label(s)" +msgstr "" + +#: templates/basic_mode.html:117 +msgid "Upload a list of labels" +msgstr "" + +#: templates/basic_mode.html:136 +msgid "Check for collision with existing TLDs" +msgstr "" + +#: templates/basic_mode.html:150 +#, python-format +msgid "" +"Your request was sent successfully, the collision and validation tasks " +"processing can take minutes, even hours.
The result will be sent to " +"%(email)s. Do not resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:162 +#, python-format +msgid "" +"Your request was sent successfully, the validation task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:174 +#, python-format +msgid "" +"Your request was sent successfully, the collision task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" + +#: templates/basic_mode.html:184 +msgid "Validate" +msgstr "" + +#: templates/basic_mode.html:197 +msgid "Your saved results" +msgstr "" + +#: templates/basic_mode.html:198 +msgid "The following files contains your tools computation results." +msgstr "" + +#: templates/basic_mode.html:201 +msgid "Note that these files could be cleaned up regularly." +msgstr "" + +#: templates/basic_mode.html:206 +#, python-format +msgid "Download %(file)s" +msgstr "" + +#: templates/basic_mode.html:241 +msgid "Close" +msgstr "" + +#: views.py:83 +msgid "" +"Input label generates too many variants to compute them all quickly. You " +"need to enter your email address and will receive a notification once " +"process is done" +msgstr "" diff --git a/src/lgr_basic/locale/fr/LC_MESSAGES/django.mo b/src/lgr_basic/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 00000000..885977d5 Binary files /dev/null and b/src/lgr_basic/locale/fr/LC_MESSAGES/django.mo differ diff --git a/src/lgr_basic/locale/fr/LC_MESSAGES/django.po b/src/lgr_basic/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 00000000..ba45c625 --- /dev/null +++ b/src/lgr_basic/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,1100 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" +"PO-Revision-Date: 2020-06-04 13:41-0400\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.3\n" + +#: forms.py:21 +msgid "Label" +msgstr "Label" + +#: forms.py:22 +msgid "File must be encoded in UTF-8 and using UNIX line ending." +msgstr "" +"Le fichier doit être encodé en UTF-8, et utiliser des retours à la ligne " +"UNIX." + +#: forms.py:26 +msgid "Email address for tasks results" +msgstr "Adresse e-mail utilisée pour recevoir le résultats des tâches" + +#: forms.py:27 +msgid "" +"As the computing may be very long, we will warn by e-mail once the result " +"can be downloaded." +msgstr "" +"Le temps de calcul peut être très long, vous serez averti par e-mail lorsque " +"le résultat pourra être téléchargé. Fournissez une adresse e-mail valide " +"s'il vous plaît." + +#: forms.py:37 +msgid "E-mail is mandatory to get the tasks results" +msgstr "" +"L'adresse e-mail est obligatoire pour recevoir les résultats des tâches" + +#: forms.py:40 forms.py:41 +msgid "Required" +msgstr "Requis" + +#: forms.py:45 forms.py:46 +msgid "Unknown error, please report" +msgstr "Erreur inconnue, reportez l'erreur s'il vous plait" + +#: templates/basic_mode.html:8 templates/basic_mode.html:39 +msgid "LGR Tool" +msgstr "Outil de gestion de LGR" + +#: templates/basic_mode.html:38 templates/basic_mode.html:39 +msgid "Go to home screen" +msgstr "Retourner à l'écran d'accueil" + +#: templates/basic_mode.html:43 +msgid "Advanced mode" +msgstr "Mode avancé" + +#: templates/basic_mode.html:47 templates/basic_mode.html:253 +msgid "Display all label forms" +msgstr "Afficher toutes les formes d'un label" + +#: templates/basic_mode.html:48 +msgid "Label forms" +msgstr "Formes" + +#: templates/basic_mode.html:53 +msgid "About LGR Toolset" +msgstr "À propos de l'application LGR" + +#: templates/basic_mode.html:54 templates/basic_mode.html:235 +msgid "About" +msgstr "À propos" + +#: templates/basic_mode.html:74 +msgid "" +"The server was unable to complete the request, most likely because too many " +"resources were required to compute the query. If you check for collision, " +"the result may be still processing and will be sent to your email. Please " +"wait before submitting again." +msgstr "" +"Le serveur n'a pas pu compléter la requête, probablement parce que trop de " +"ressources sont nécessaires pour calculer la requête. Si vous vérifiez une " +"collision, le résultat peut être toujours en cours de traitement et vous " +"sera envoyé par mail. Merci de patienter avant de soumettre à nouveau." + +#: templates/basic_mode.html:82 +msgid "A server error occurred." +msgstr "Une erreur de serveur s'est produite." + +#: templates/basic_mode.html:82 +msgid "code:" +msgstr "code :" + +#: templates/basic_mode.html:82 +msgid "Please contact the administrator before submitting again." +msgstr "" +"Veuillez contacter l'administrateur avant de soumettre votre requête à " +"nouveau." + +#: templates/basic_mode.html:88 +msgid "Validate label(s) against" +msgstr "Valider le(s) label(s) avec" + +#: templates/basic_mode.html:93 +msgid "View LGR as" +msgstr "Voir la LGR en" + +#: templates/basic_mode.html:106 +msgid "Manually input label(s)" +msgstr "Entrer le(s) label(s) manuellement" + +#: templates/basic_mode.html:117 +msgid "Upload a list of labels" +msgstr "Télécharger une liste de labels" + +#: templates/basic_mode.html:136 +msgid "Check for collision with existing TLDs" +msgstr "Vérifier les collisions avec la liste de TLDs" + +#: templates/basic_mode.html:150 +#, python-format +msgid "" +"Your request was sent successfully, the collision and validation tasks " +"processing can take minutes, even hours.
The result will be sent to " +"%(email)s. Do not resubmit until you receive the report." +msgstr "" +"Votre requête a bien été envoyée, le calcul des collision et la tâche de " +"validation peuvent prendre plusieurs minutes, voire plusieurs heures.
Le " +"résultat sera envoyé à %(email)s. Ne renvoyez pas de requête tant que vous " +"n'avez pas reçu le rapport." + +#: templates/basic_mode.html:162 +#, python-format +msgid "" +"Your request was sent successfully, the validation task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" +"Votre requête a bien été envoyée, la tâche de validation peut prendre " +"plusieurs minutes, voire plusieurs heures.
Le résultat sera envoyé à " +"%(email)s. Ne renvoyez pas de requête tant que vous n'avez pas reçu le " +"rapport." + +#: templates/basic_mode.html:174 +#, python-format +msgid "" +"Your request was sent successfully, the collision task processing can take " +"minutes, even hours.
The result will be sent to %(email)s. Do not " +"resubmit until you receive the report." +msgstr "" +"Votre requête a bien été envoyée, le calcul des collisions peut prendre " +"plusieurs minutes, voire plusieurs heures.
Le résultat sera envoyé à " +"%(email)s. Ne renvoyez pas de requête tant que vous n'avez pas reçu le " +"rapport." + +#: templates/basic_mode.html:184 +msgid "Validate" +msgstr "Valider" + +#: templates/basic_mode.html:197 +msgid "Your saved results" +msgstr "Vos résultats sauvegardés" + +#: templates/basic_mode.html:198 +msgid "The following files contains your tools computation results." +msgstr "" +"Ces fichiers contiennent les résultats des calculs fournis par les outils." + +#: templates/basic_mode.html:201 +msgid "Note that these files could be cleaned up regularly." +msgstr "" +"Veuillez noter que ces fichiers pourraient être régulièrement supprimés." + +#: templates/basic_mode.html:206 +#, python-format +msgid "Download %(file)s" +msgstr "Télécharger %(file)s" + +#: templates/basic_mode.html:241 +msgid "Close" +msgstr "Fermer" + +#: views.py:83 +msgid "" +"Input label generates too many variants to compute them all quickly. You " +"need to enter your email address and will receive a notification once " +"process is done" +msgstr "" +"Le label entré peut générer trop de variantes pour rapidement toutes les " +"calculer. Vous devez rentrer votre adresse e-mail et recevrez une " +"notification une fois que le processus est terminé" + +#, python-format +#~ msgid "" +#~ "Your request was sent successfully, the collision and validation tasks " +#~ "processing can take minutes, even hours.
Both results will be sent to " +#~ "%(email)s in two separate emails. Do not resubmit until you receive both " +#~ "reports." +#~ msgstr "" +#~ "Votre requête a bien été envoyée, les tâches de collision et de " +#~ "validation peuvent prendre plusieurs minutes, voire plusieurs heures.
" +#~ "Les deux résultats seront envoyés à %(email)s en deux e-mails distincts. " +#~ "Ne renvoyez pas de requête tant que vous n'avez pas reçu les deux " +#~ "rapports." + +#~ msgid "Collision task result will be sent to " +#~ msgstr "Le résultat du calcul de collisions sera envoyé à " + +#~ msgid "When" +#~ msgstr "When" + +#~ msgid "Not-When" +#~ msgstr "Not When" + +#~ msgid "Tags" +#~ msgstr "Tags" + +#~ msgid "space-separated tags" +#~ msgstr "liste de tags séparés par des espaces" + +#~ msgid "Code point" +#~ msgstr "Code point" + +#~ msgid "Override repertoire" +#~ msgstr "Ignorer le répertoire" + +#~ msgid "Code points" +#~ msgstr "Code points" + +#~ msgid "Disabled code points" +#~ msgstr "Code points indisponibles" + +#~ msgid "First code point" +#~ msgstr "Premier code point" + +#~ msgid "Last code point" +#~ msgstr "Dernier code point" + +#~ msgid "" +#~ "Last code point (%(last_cp)s) must not be smaller than the first code " +#~ "point (%(first_cp)s)" +#~ msgstr "" +#~ "Le dernier code point (%(last_cp)s) ne peut être plus petit que le " +#~ "premier code point (%(first_cp)s)" + +#~ msgid "Validating repertoire" +#~ msgstr "Répertoire de validation" + +#~ msgid "Script" +#~ msgstr "Script" + +#~ msgid "Manual import" +#~ msgstr "Importation manuelle" + +#~ msgid "Select a file" +#~ msgstr "Sélectionner un fichier" + +#~ msgid "File type" +#~ msgstr "Type de fichier" + +#~ msgid "Name" +#~ msgstr "Nom" + +#~ msgid "Code points will be limited to the selected repertoire" +#~ msgstr "Les code points seront limités au répertoire sélectionné" + +#~ msgid "Select file(s)" +#~ msgstr "Sélectionner un/des fichier(s)" + +#~ msgid "LGR set name" +#~ msgstr "Nom du set LGR" + +#~ msgid "" +#~ "Enter a valid LGR set name. This value may contain only letters, numbers " +#~ "and ./-/_ characters." +#~ msgstr "" +#~ "Entrer un nom de LGR valide. Cette valeur ne peut que contenir des " +#~ "lettres, nombres et les caractères ./-/_." + +#~ msgid "The name of the set" +#~ msgstr "Nom du set" + +#~ msgid "Unicode version" +#~ msgstr "Version d'Unicode" + +#~ msgid "The unicode version used" +#~ msgstr "Version d'Unicode" + +#~ msgid "Version" +#~ msgstr "Version" + +#~ msgid "Version comment" +#~ msgstr "Commentaire de version" + +#~ msgid "Date" +#~ msgstr "Date" + +#~ msgid "Scope" +#~ msgstr "Portée" + +#~ msgid "Scope type" +#~ msgstr "Type de la portée" + +#~ msgid "Validity start" +#~ msgstr "Début de la validité" + +#~ msgid "Description" +#~ msgstr "Description" + +#~ msgid "Description type" +#~ msgstr "Type de la description" + +#~ msgid "Built-in" +#~ msgstr "Fournis" + +#~ msgid "My LGRs" +#~ msgstr "Mes LGRs" + +#~ msgid "Language" +#~ msgstr "Langage" + +#~ msgid "Input code point %(codepoint)s is not in the LGR" +#~ msgstr "Le code point %(codepoint)s n'est pas dans la LGR" + +#~ msgid "Input code point %(codepoint)s is not in the reference repertoire" +#~ msgstr "" +#~ "Le code point %(codepoint)s n'est pas dans le répertoire de référence" + +#~ msgid "" +#~ "Variant %(variant_codepoint)s already exists for code point %(codepoint)s" +#~ msgstr "" +#~ "La variante %(variant_codepoint)s existe déjà pour le code point " +#~ "%(codepoint)s" + +#~ msgid "Range %(first_cp)s - %(last_cp)s already exists in the LGR" +#~ msgstr "L'ensemble %(first_cp)s - %(last_cp)s existe déjà dans la LGR" + +#~ msgid "Input code point %(codepoint)s already exists in the LGR" +#~ msgstr "Le code point %(codepoint)s existe déjà dans la LGR" + +#~ msgid "Input code point %(codepoint)s is not in LGR script" +#~ msgstr "Le code point %(codepoint)s n'est pas dans le script de la LGR" + +#~ msgid "" +#~ "Input code point %(codepoint)s is not a PVALID/CONTEXTO/CONTEXTJ code " +#~ "point per IDNA2008" +#~ msgstr "" +#~ "Le code point %(codepoint)s n'est pas un code point PVALID/CONTEXTO/" +#~ "CONTEXTJ d'après IDNA2008" + +#~ msgid "Code point %(codepoint)s has invalid context rule %(rule)s" +#~ msgstr "" +#~ "Le code point %(codepoint)s a une règle contextuelle invalide %(rule)s" + +#~ msgid "Range %(first_cp)s - %(last_cp)s has invalid context rule" +#~ msgstr "" +#~ "L'ensemble %(first_cp)s - %(last_cp)s a une règle contextuelle invalide" + +#~ msgid "" +#~ "Variant %(variant_codepoint)s of code point %(codepoint)shas invalid " +#~ "context rule" +#~ msgstr "" +#~ "La variante %(variant_codepoint)s du code point %(codepoint)s a une règle " +#~ "contextuelle invalide" + +#~ msgid "Duplicate reference for code point %(codepoint)s" +#~ msgstr "Référence dupliquée pour le code point %(codepoint)s" + +#~ msgid "Unspecified exception for input code point %(codepoint)s" +#~ msgstr "Exception non-spécifiée pour le code point d'entrée %(codepoint)s" + +#~ msgid "Sequence cannot have a tag" +#~ msgstr "Les séquences ne peuvent pas avoir de tag" + +#~ msgid "Invalid language" +#~ msgstr "Langage invalide" + +#~ msgid "Invalid date value" +#~ msgstr "Date invalide" + +#~ msgid "Invalid Unicode version" +#~ msgstr "Version d'unicode invalide" + +#~ msgid "Invalid LGR XML file" +#~ msgstr "Fichier XML de LGR invalide" + +#~ msgid "Reference %(ref_id)s is not defined" +#~ msgstr "La référence %(ref_id)s n'est pas définie" + +#~ msgid "Reference %(ref_id)s already exists" +#~ msgstr "La référence %(ref_id)s existe déjà" + +#~ msgid "Invalid reference id %(ref_id)s " +#~ msgstr "Identifiant de référence invalide %(ref_id)s " + +#~ msgid "Rule \"%(rule_name)s\" cannot be processed (%(message)s)" +#~ msgstr "La règle \"%(rule_name)s\" ne peut pas être traitée (%(message)s)" + +#~ msgid "Input parameter has invalid format" +#~ msgstr "Le paramètre d'entrée a un format invalide" + +#~ msgid "A general exception occurred in the LGR API" +#~ msgstr "Une exception s'est produite dans l'API LGR" + +#~ msgid "LGR is not valid (%(args)s)" +#~ msgstr "La LGR n'est pas valide (%(args)s)" + +#~ msgid "Label %(label)s is not valid in the LGR (%(message)s)" +#~ msgstr "Label %(label)s n'est pas valide dans la LGR (%(message)s)" + +#~ msgid "Input label file contains collision(s)" +#~ msgstr "Le fichier d'entrée des labels contient une/des collision(s)" + +#~ msgid "The LGR contains a variant that do not have symmetric relations" +#~ msgstr "La LGR contient des variantes ne respectant pas la symmétrie" + +#~ msgid "The LGR does not contain a valid language (%(message)s)" +#~ msgstr "La LGR ne contient pas de langues valides (%(message)s)" + +#~ msgid "Cannot generate cross-script variant for LGR without (%(message)s)" +#~ msgstr "" +#~ "Impossible de générer les variantes cross-script pour la LGR sans " +#~ "(%(message)s)" + +#~ msgid "An unknown exception occurred in the LGR API" +#~ msgstr "Une exception inconnue s'est produite dans l'API LGR" + +#~ msgid "References" +#~ msgstr "Références" + +#~ msgid "Meta data" +#~ msgstr "Métadonnées" + +#~ msgid "Rules" +#~ msgstr "Règles" + +#~ msgid "Embedded LGRs" +#~ msgstr "LGR embarquées" + +#~ msgid "Sets:" +#~ msgstr "Sets:" + +#~ msgid "%(lgr_name)s" +#~ msgstr "%(lgr_name)s" + +#~ msgid "Cancel" +#~ msgstr "Annuler" + +#~ msgid "Save" +#~ msgstr "Sauvegarder" + +#~ msgid "Edit" +#~ msgstr "Modifier" + +#~ msgid "" +#~ "\n" +#~ " This application provides a convenient interface for browsing\n" +#~ " and editing LGR’s " +#~ "conforming to the\n" +#~ " Representing Label Generation Rulesets using XML\n" +#~ " specification.\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "Cette application fournit une interface adaptée à la navigation et la " +#~ "modification de LGR " +#~ "conformes à la spécification Representing Label Generation Rulesets " +#~ "using XML.\n" +#~ " " + +#~ msgid "Supported Unicode versions:" +#~ msgstr "Versions d'Unicode supportées:" + +#~ msgid "" +#~ "This toolset was implemented by Viagénie and Wil Tan on an ICANN contract." +#~ msgstr "" +#~ "Cette application a été implémentée par Viagénie et Wil Tan sous contrat ICANN." + +#~ msgid "Next" +#~ msgstr "Suivant" + +#~ msgid "" +#~ "Code points added. Click here if " +#~ "you are not redirected automatically." +#~ msgstr "" +#~ "Code point ajouté. Cliquez ici si " +#~ "vous n'êtes pas redirigé automatiquement." + +#~ msgid "Populate variants" +#~ msgstr "Peupler les variantes" + +#~ msgid "Expand range(s)" +#~ msgstr "Convertir tous les ensembles" + +#~ msgid "Add code point(s)" +#~ msgstr "Ajouter un/des code point(s)" + +#~ msgid "Character Name" +#~ msgstr "Nom du caractère" + +#~ msgid "Comments" +#~ msgstr "Commentaires" + +#~ msgid "Action" +#~ msgstr "Action" + +#~ msgid "Add Rule" +#~ msgstr "Ajouter une règle" + +#~ msgid "There is no rule in the current LGR" +#~ msgstr "Il n'y a pas de règles dans la LGR courante" + +#~ msgid "" +#~ "\n" +#~ "

This rule will be added to " +#~ " codepoint(s)

\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "

Cette règle va être ajoutée à " +#~ " code point(s)

\n" +#~ " " + +#~ msgid "Add Tags" +#~ msgstr "Ajouter des Tags" + +#~ msgid "" +#~ "\n" +#~ "

These tags will be added to codepoint(s)

\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "

Ces tags vont être ajoutées à code point(s)

\n" +#~ " " + +#~ msgid "Code point range" +#~ msgstr "Ensemble de Code points" + +#~ msgid "Code point from script" +#~ msgstr "Code point depuis un script" + +#~ msgid "Import from file" +#~ msgstr "Importer depuis un fichier" + +#~ msgid "Add Code Point" +#~ msgstr "Ajouter un Code Point" + +#~ msgid "Variant(s)" +#~ msgstr "Variante(s)" + +#~ msgid "See code point" +#~ msgstr "Voir le code point" + +#~ msgid "Expand range" +#~ msgstr "Convertir l'ensemble" + +#~ msgid "➡ Select code point(s) to apply batch action..." +#~ msgstr "" +#~ "➡ Sélectionner les code points sur lesquels appliquer une action par " +#~ "lots..." + +#~ msgid "Add WLE" +#~ msgstr "Ajouter une WLE" + +#~ msgid "➡ Apply batch action..." +#~ msgstr "➡ Appliquer action par lots..." + +#~ msgid "Code point appeared in Unicode version: %(age)s" +#~ msgstr "Le code point est apparu dans Unicode version : %(age)s" + +#~ msgid "Add variant" +#~ msgstr "Ajouter une variante" + +#~ msgid "Type" +#~ msgstr "Type" + +#~ msgid "Not When" +#~ msgstr "Not When" + +#~ msgid "Code point is not in LGR" +#~ msgstr "Le code point n'est pas dans la LGR" + +#~ msgid "Are you sure you want delete this variant?" +#~ msgstr "Êtes-vous sûr(e) de vouloir supprimer cette variante ?" + +#~ msgid "Delete variant" +#~ msgstr "Supprimer la variante" + +#~ msgid "Edit references" +#~ msgstr "Modifier les références" + +#~ msgid "Range characters do not have variants." +#~ msgstr "Les ensembles de caractères n'ont pas de variantes." + +#~ msgid "Code point has not variant" +#~ msgstr "Le code point n'a pas de variante" + +#~ msgid "Save variants, tags, context rules and comment" +#~ msgstr "" +#~ "Sauvegarder les variantes, tags, règles contextuelles et commentaires" + +#~ msgid "No references associated with code point." +#~ msgstr "Aucune référence associée au code point." + +#~ msgid "Are you sure you want delete this code point?" +#~ msgstr "Êtes-vous sûr(e) de vouloir supprimer ce code point ?" + +#~ msgid "Delete code point" +#~ msgstr "Supprimer le code point" + +#~ msgid "Edit References for " +#~ msgstr "Modifier les références pour " + +#~ msgctxt "button title" +#~ msgid "Delete reference" +#~ msgstr "Supprimer la référence" + +#~ msgid "Add an existing reference" +#~ msgstr "Ajouter un référence existante" + +#~ msgid "Add" +#~ msgstr "Ajouter" + +#~ msgid "Create a new reference" +#~ msgstr "Créer une nouvelle référence" + +#~ msgid "Error when adding reference" +#~ msgstr "Erreur lors de l'ajout d'une référence" + +#~ msgid "Reference ID (optional)" +#~ msgstr "Id de référence (optionnel)" + +#~ msgid "URL (optional)" +#~ msgstr "URL (optionnelle)" + +#~ msgid "New reference" +#~ msgstr "Nouvelle référence" + +#~ msgid "Save changes" +#~ msgstr "Sauvegarder les changements" + +#~ msgid "List of LGRs in the set" +#~ msgstr "Liste des LGR dans le set" + +#~ msgid "Import existing LGR" +#~ msgstr "Importer une LGR existante" + +#~ msgid "" +#~ "To import LGR set, select the XML files composing the LGR set. The set " +#~ "will automatically be created." +#~ msgstr "" +#~ "Pour importer un set LGR, sélectionner les fichiers XML le set LGR. Le " +#~ "set sera créé automatiquement." + +#~ msgid "" +#~ " Import function " +#~ "will only perfom some basic checking (example: XML validity). Once the " +#~ "LGR has been imported, you need to use the Validate LGR " +#~ "button to do a complete check. " +#~ msgstr "" +#~ " La fonction " +#~ "d'importation effectue uniquement quelques tests de base (par exemple, la " +#~ "validité du XML). Une fois la LGR importée, vous devez utiliser le bouton " +#~ "Valider la LGR pour effectuer un test complet. " + +#~ msgid "These LGRs are already imported. Click on one to access it." +#~ msgstr "Les LGRs suivantes sont déjà importées. Cliquer pour y accéder." + +#~ msgid "Import" +#~ msgstr "Importer" + +#~ msgid "" +#~ " " +#~ "Note that importing large LGR files may take significant time to load on " +#~ "your browser." +#~ msgstr "" +#~ " " +#~ "L’importation de gros fichiers LGR peut être lente à charger dans le " +#~ "navigateur." + +#~ msgid "Cannot import LGR file(s):" +#~ msgstr "Impossible d'importer le(s) fichier(s) LGR :" + +#~ msgid "Code point sequence" +#~ msgstr "Séquence de code points" + +#~ msgid "U-label" +#~ msgstr "U-Label" + +#~ msgid "A-label" +#~ msgstr "A-Label" + +#~ msgid "There was an error saving; please see error(s) below" +#~ msgstr "" +#~ "Il y a eu une erreur lors de la sauvegarde, merci de regarder ci-dessous" + +#~ msgid "Create a new LGR" +#~ msgstr "Créer une nouvelle LGR" + +#~ msgid "These LGRs are already created. Click on one to access it." +#~ msgstr "Les LGRs suivantes sont déjà créées. Cliquez pour y accéder." + +#~ msgid "Create" +#~ msgstr "Créer" + +#~ msgid "Existing references" +#~ msgstr "Références existantes" + +#~ msgid "Reference id" +#~ msgstr "Identifiant de référence" + +#~ msgid "URL" +#~ msgstr "URL" + +#~ msgid "Delete reference" +#~ msgstr "Supprimer la référence" + +#~ msgid "Are you sure you want delete this reference?" +#~ msgstr "Êtes-vous sûr(e) de vouloir supprimer cette référence ?" + +#~ msgid "Classes" +#~ msgstr "Classes" + +#~ msgid "The LGR has no class" +#~ msgstr "La LGR n'a pas de classes" + +#~ msgid "The LGR has no rule" +#~ msgstr "La LGR n'a pas de règles" + +#~ msgid "Actions" +#~ msgstr "Actions" + +#~ msgid "The LGR has no action" +#~ msgstr "La LGR n'a pas d'actions" + +#~ msgid "New class" +#~ msgstr "Nouvelle classe" + +#~ msgid "New rule" +#~ msgstr "Nouvelle règle" + +#~ msgid "New action" +#~ msgstr "Nouvelle action" + +#~ msgid "Existing tags" +#~ msgstr "Tags existants" + +#~ msgid "Tag name" +#~ msgstr "Nom du tag" + +#~ msgid "Associated code points" +#~ msgstr "Code points associés" + +#~ msgid "View all (%(nb_cp)s)" +#~ msgstr "Voir tout (%(nb_cp)s)" + +#~ msgid "Delete Tag" +#~ msgstr "Supprimer le tag" + +#~ msgid "Are you sure you want delete tag %(tag)s?" +#~ msgstr "Êtes-vous sûr(e) de vouloir supprimer ce tag %(tag)s ?" + +#~ msgid "" +#~ "To create a new tag:\n" +#~ " Add it to a code point first to find it back in this list" +#~ msgstr "" +#~ "Pour créer un nouveau tag:\n" +#~ " Ajouter le tag à un code point afin de le retrouver dans " +#~ "cette list" + +#~ msgid "Erroneous conditional code points" +#~ msgstr "Erreur dans les code points conditionels" + +#~ msgid "" +#~ "Code point %(cp)s has invalid %(rule_type)s rule %(rule)s for variant " +#~ "%(variant)s" +#~ msgstr "" +#~ "Le code point %(cp)s a la règle %(rule_type)s %(rule)s invalide pour les " +#~ "variantes %(variant)s" + +#~ msgid "Conditional variants OK" +#~ msgstr "Variantes conditionnelles OK" + +#~ msgid "Missing code points or rules" +#~ msgstr "Code points ou règles manquants" + +#~ msgid "Code point %(cp)s:" +#~ msgstr "Code point %(cp)s:" + +#~ msgid "Variant %(variant)s is not in repertoire" +#~ msgstr "La variante %(variant)s n'est pas dans le répertoire" + +#~ msgid "%(variant)s has not original code point in its variants" +#~ msgstr "%(variant)s n'a pas le code point original dans ses variantes" + +#~ msgid "" +#~ "%(variant)s has not symmetric %(rule_type)s rule %(rule)s on its " +#~ "symmetric variants" +#~ msgstr "" +#~ "%(variant)s n'a pas la règle %(rule_type)s %(rule)s dans ses variantes " +#~ "symmétriques" + +#~ msgid "Symmetry OK" +#~ msgstr "Symétrie OK" + +#~ msgid "Missing variants" +#~ msgstr "Variantes manquantes" + +#~ msgid "Code point %(cp)s is missing variant %(variant)s" +#~ msgstr "Le code point %(cp)s n'a pas la variante %(variant)s" + +#~ msgid "Transitivity OK" +#~ msgstr "Transitivité OK" + +#~ msgid "XML is valid and complies with RNG." +#~ msgstr "XML valide et conforme au RNG." + +#~ msgid "Invalid XML for lgr: %(res)s" +#~ msgstr "Fichier XML invalide pour la LGR: %(res)s" + +#~ msgid "General stats" +#~ msgstr "Statistiques générales" + +#~ msgid "Number of code points: %(nbr)s" +#~ msgstr "Nombre de code points: %(nbr)s" + +#~ msgid "Number of ranges: %(nbr)s" +#~ msgstr "Nombre d'intervalles: %(nbr)s" + +#~ msgid "Largest range: %(largest)s (length: %(largest_len)s)" +#~ msgstr "Plus grand intervalle: %(largest)s (longueur: %(largest_len)s)" + +#~ msgid "Number of sequences: %(nbr)s" +#~ msgstr "Nombre de séquences: %(nbr)s" + +#~ msgid "Largest sequence: %(largest)s (length: %(largest_len)s)" +#~ msgstr "Plus grande séquence: %(largest)s (longueur: %(largest_len)s)" + +#~ msgid "Variants" +#~ msgstr "Variante(s)" + +#~ msgid "Total number of variant mappings: %(nbr)s" +#~ msgstr "Nombre total de variantes mappées: %(nbr)s" + +#~ msgid "Average number of variants per code point: %(nbr)s" +#~ msgstr "Nombre moyen de variantes par code point: %(nbr)s" + +#~ msgid "Largest variant set: %(largest_set)s" +#~ msgstr "Plus grand ensemble de variantes: %(largest_set)s" + +#~ msgid "Variants per type:" +#~ msgstr "Variantes par type:" + +#~ msgid "Number of variants for type %(variant_type)s: %(number)s" +#~ msgstr "Nombre de variantes pour le type %(variant_type)s: %(number)s" + +#~ msgid "Number of code points for tag %(tag_name)s: %(number)s" +#~ msgstr "Nombre de code points pour le tag %(tag_name)s: %(number)s" + +#~ msgid "Number of defined rules: %(nbr)s" +#~ msgstr "Nombre de règles définies: %(nbr)s" + +#~ msgid "Unicode version %(version)s" +#~ msgstr "Version d'Unicode %(version)s" + +#~ msgid "Validating repertoire '%(repertoire)s'" +#~ msgstr "Répertoire de validation '%(repertoire)s'" + +#~ msgid "" +#~ "Target Unicode version %(version)s differs from UnicodeDatabase " +#~ "%(database)s" +#~ msgstr "" +#~ "La version Unicode cible %(version)s diffère de UnicodeDatabase " +#~ "%(database)s" + +#~ msgid "Invalid characters" +#~ msgstr "Caractères invalides" + +#~ msgid "Invalid character %(cp)s:" +#~ msgstr "Caractère invalide %(cp)s:" + +#~ msgid "Error: %(err)s" +#~ msgstr "Erreur: %(err)s" + +#~ msgid "Variant: %(variant|render_char)s" +#~ msgstr "Variante: %(variant|render_char)s" + +#~ msgid "LGR rebuild OK" +#~ msgstr "Reconstruction de la LGR OK" + +#~ msgid "" +#~ "The LGR you have tried to create already exists in your working session. " +#~ "Please use a new name." +#~ msgstr "" +#~ "La LGR que vous essayez de créer existe déjà dans votre session de " +#~ "travail. Merci d'utiliser un nouveau nom." + +#~ msgid "" +#~ "The LGR you have tried to import already exists in your working session. " +#~ "Please rename it before importing it." +#~ msgstr "" +#~ "La LGR que vous essayez d'importer existe déjà dans votre session de " +#~ "travail. Merci de renommer le fichier avant de l'importer." + +#~ msgid "" +#~ "The LGR you have tried to import already exists in your set. Please " +#~ "rename it before importing it." +#~ msgstr "" +#~ "La LGR que vous essayez d'importer existe déjà dans votre ensemble. Merci " +#~ "de renommer le fichier avant de l'importer." + +#~ msgid "The LGR set name already exists. Please use another name." +#~ msgstr "Ce nom de set LGR existe déjà. Merci d'utiliser un autre nom." + +#~ msgid "Testing XML validity using RNG" +#~ msgstr "Validation du XML par le RNG" + +#~ msgid "Testing symmetry" +#~ msgstr "Test de la symmétrie" + +#~ msgid "Testing transitivity" +#~ msgstr "Test de la transitivité" + +#~ msgid "Testing conditional variants" +#~ msgstr "Test des variantes conditionnelles" + +#~ msgid "Generate stats" +#~ msgstr "Génération des statistiques" + +#~ msgid "Rebuilding LGR" +#~ msgstr "Reconstruction de la LGR" + +#~ msgid "New code point %s added" +#~ msgstr "Nouveau code point ajouté %s" + +#~ msgid "Rule" +#~ msgstr "Règle" + +#~ msgid "Tag(s)" +#~ msgstr "Tag(s)" + +#~ msgid "rule" +#~ msgstr "règle" + +#~ msgid "tag(s)" +#~ msgstr "tag(s)" + +#~ msgid "%(operation)s successfully added to %(nb_cp)s code point(s)" +#~ msgstr "%(operation)s ajouté(s) avec succès à %(nb_cp)s code point(s)" + +#~ msgid "" +#~ "%(nb_cp)s code points were not updated to avoid invalid %(operation)s" +#~ msgstr "" +#~ "%(nb_cp)s code points n'ont pas été mis à jour pour éviter des " +#~ "%(operation)s invalides" + +#~ msgid "Automatically added codepoint %s from out-of-repertoire variant" +#~ msgstr "" +#~ "Code point %s automatiquement ajouté depuis une variante hors-répertoire" + +#~ msgid "New variant %s added" +#~ msgstr "Nouvelle variante %s ajoutée" + +#~ msgid "Code point edited" +#~ msgstr "Code point modifié" + +#~ msgid "Variants populated" +#~ msgstr "Les variantes ont été peuplées" + +#~ msgid "References updated successfully" +#~ msgstr "Les références ont été correctement mises à jour" + +#~ msgid "" +#~ "Variant %(var_codepoint)s for code point %(codepoint)s with when=%(when)s " +#~ "and not-when=%(not_when)s could not be found" +#~ msgstr "" +#~ "La variante %(var_codepoint)s du code point %(codepoint)s avec when=" +#~ "%(when)s et not-when=%(not_when)s n'a pas été trouvée" + +#~ msgid "Code point %s has been deleted" +#~ msgstr "Le code point %s a été supprimé" + +#~ msgid "Variant %(var_cp)s with when='%(when)s' and not-when='%(not_when)s'" +#~ msgstr "" +#~ "La variante %(var_cp)s avec when='%(when)s' and not-when='%(not_when)s'" + +#~ msgid "%(var_msg_prefix)s has been deleted" +#~ msgstr "%(var_msg_prefix)s a été supprimée" + +#~ msgid "%(var_msg_prefix)s could not be deleted because it was not found" +#~ msgstr "" +#~ "%(var_msg_prefix)s n'a pas pu être supprimée car elle n'a pas été trouvée" + +#~ msgid "New reference created" +#~ msgstr "Nouvelle référence créée" + +#~ msgid "" +#~ "References to tag %(tag)s have been removed from the repertoire. Do not " +#~ "forget to update any WLE that might reference it." +#~ msgstr "" +#~ "Les références au %(tag)s ont été supprimées du répertoire. N'oubliez pas " +#~ "de mettre à jour les WLE qui pourraient les utiliser." + +#~ msgid "No body specified" +#~ msgstr "Aucun contenu spécifié" + +#~ msgid "Class \"%s\" does not exist" +#~ msgstr "La classe \"%s\" n'existe pas" + +#~ msgid "Class \"%s\" deleted." +#~ msgstr "Classe \"%s\" supprimée." + +#~ msgid "No class element found" +#~ msgstr "Aucune classe trouvée" + +#~ msgid "Name attribute must be present" +#~ msgstr "L'attribut name est obligatoire" + +#~ msgid "" +#~ "Encountered XML syntax error: %s (line number may be wrong, try " +#~ "subtracting one from the reported line number)" +#~ msgstr "" +#~ "Erreur de syntaxe XML : %s (le numéro de ligne peut-être incorrect, " +#~ "essayer de soustraire un au numéro reporté)" + +#~ msgid "Your XML is not valid" +#~ msgstr "Votre XML n'est pas valide" + +#~ msgid "Class \"%s\" already exists" +#~ msgstr "La classe \"%s\" existe déjà" + +#~ msgid "Class \"%s\" saved." +#~ msgstr "Classe \"%s\" sauvegardée." + +#~ msgid "Rule \"%s\" does not exist" +#~ msgstr "La règle \"%s\" n'existe pas" + +#~ msgid "Rule \"%s\" deleted." +#~ msgstr "Règle \"%s\" supprimée." + +#~ msgid "No rule element found" +#~ msgstr "Aucune règle trouvée" + +#~ msgid "Rule \"%s\" already exists" +#~ msgstr "La règle \"%s\" existe déjà" + +#~ msgid "Rule \"%s\" saved." +#~ msgstr "Règle \"%s\" sauvegardée." + +#~ msgid "Action \"%s\" does not exist" +#~ msgstr "Action \"%s\" n'existe pas" + +#~ msgid "Action \"%s\" deleted." +#~ msgstr "Action \"%s\" supprimée." + +#~ msgid "No action element found" +#~ msgstr "Aucune action trouvée" + +#~ msgid "Action saved." +#~ msgstr "Action sauvée." + +#~ msgid "%d code points added" +#~ msgstr "%d code points ont été ajoutés" + +#~ msgid "No code point in input file" +#~ msgstr "Le fichier d'entrée ne contient aucun code point" + +#~ msgid "Meta data saved" +#~ msgstr "Metadonnées sauvegardées" + +#, fuzzy +#~| msgid "Description" +#~ msgid "%(description)s" +#~ msgstr "Description" + +#~ msgid " with Unicode version {}" +#~ msgstr " avec la version d'Unicode {}" + +#~ msgid " and validating repertoire '{}'" +#~ msgstr " et le repertoire de validation '{}'" + +#~ msgid " " +#~ msgstr " " diff --git a/src/lgr_basic/templates/basic_mode.html b/src/lgr_basic/templates/basic_mode.html new file mode 100644 index 00000000..f83318d9 --- /dev/null +++ b/src/lgr_basic/templates/basic_mode.html @@ -0,0 +1,549 @@ + +{% load i18n static %} +{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} + + + + + {% block html_title %}{% trans 'LGR Tool' %}{% endblock %} + + + + + + + + + {% block html_head_more %}{% endblock %} + + +
+
+
+
+
+ {% block navbar %} + + {% endblock navbar %} + + {% block messages %} + {% include "_msgs.html" %} + {% endblock messages %} + + {% block container %} +
+
+
+
+ {% csrf_token %} + + + + + + +
+ +
+ {% include "lgr_editor/_form_field.html" with field=form.rz_lgr %} + + {% trans 'View LGR as' %} + XML | + HTML + +
+
+ +
+ +
+
+ + + {% trans 'Manually input label(s)' %} + + + {% include "lgr_editor/_form_field.html" with field=form.labels_file %} +
+
+ + +
+ +
+
+
+ {% include "lgr_editor/_form_field.html" with field=form.labels %} +
+
+ +
+
+
+
+
+
+ +
+
+
+
+ {% include "lgr_editor/_form_field.html" with field=form.email %} +
+
+ {% if validation_to and collision_to %} +
+
+
+ {% blocktrans trimmed with email=collision_to %} + Your request was sent successfully, the collision and validation tasks processing can take minutes, even hours.
+ The result will be sent to {{ email }}. Do not resubmit until you receive the report. + {% endblocktrans %} +
+
+
+ {% else %} + {% if validation_to %} +
+
+
+ {% blocktrans trimmed with email=validation_to %} + Your request was sent successfully, the validation task processing can take minutes, even hours.
+ The result will be sent to {{ email }}. Do not resubmit until you receive the report. + {% endblocktrans %} +
+
+
+ {% endif %} + {% if collision_to %} +
+
+
+ {% blocktrans trimmed with email=collision_to %} + Your request was sent successfully, the collision task processing can take minutes, even hours.
+ The result will be sent to {{ email }}. Do not resubmit until you receive the report. + {% endblocktrans %} +
+
+
+ {% endif %} + {% endif %} + + +
+ +
+ {% for result in results %} + {% include "lgr_validator/_validated_results.html" with result=result lgr_id=lgr_id index=forloop.counter only %} + {% endfor %} +
+ + {% if storage %} +
+ {% trans 'Your saved results' %} +

{% trans 'The following files contains your tools computation results.' %}

+ + + {% trans 'Note that these files could be cleaned up regularly.' %} + + +
+ {% endif %} +
+
+ + {% block footer %} +
+
+

©

+ {% include "_languages.html" %} +
    +
+
+ {% endblock %} + +
+ {% endblock container %} + + + + + + + + + + + + + {% block html_body_more %}{% endblock %} + + + + + + + diff --git a/src/lgr_basic/urls.py b/src/lgr_basic/urls.py new file mode 100644 index 00000000..3ee5eeac --- /dev/null +++ b/src/lgr_basic/urls.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.conf.urls import url + +from lgr_basic.views import BasicModeView + +LGR_SLUG_FORMAT = r'(?P[\w\_\-\.]+)' + +urlpatterns = [ + url(r'^$', BasicModeView.as_view(), name='lgr_basic_mode') +] diff --git a/src/lgr_basic/views.py b/src/lgr_basic/views.py new file mode 100644 index 00000000..a3397095 --- /dev/null +++ b/src/lgr_basic/views.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import six +from django.conf import settings +from django.contrib import messages +from django.shortcuts import redirect +from django.utils.translation import ugettext as _ +from django.views.generic import FormView + +from lgr.exceptions import LGRException +from lgr.tools.utils import download_file, read_labels +from lgr.utils import cp_to_ulabel +from lgr_editor.api import LabelInfo, session_get_storage, LGRInfo, session_list_storage +from lgr_editor.lgr_exceptions import lgr_exception_to_text +from lgr_editor.repertoires import get_by_name +from lgr_tools.tasks import annotate_task, basic_collision_task +from lgr_validator.views import evaluate_label_from_info, NeedAsyncProcess +from lgr_web.views import ADVANCED_INTERFACE_SESSION_KEY +from .forms import ValidateLabelSimpleForm + + +class BasicModeView(FormView): + form_class = ValidateLabelSimpleForm + template_name = 'basic_mode.html' + + def get(self, request, *args, **kwargs): + # we want to stay in basic mode + request.session[ADVANCED_INTERFACE_SESSION_KEY] = False + return super(BasicModeView, self).get(request, *args, **kwargs) + + def form_valid(self, form): + ctx = {} + results = [] + + email_address = form.cleaned_data['email'] + labels_cp = form.cleaned_data['labels'] + labels_file = form.cleaned_data.get('labels_file') + rz_lgr = form.cleaned_data['rz_lgr'] + ctx['lgr_id'] = rz_lgr # needed to download results as csv + collisions = form.cleaned_data['collisions'] + tlds = None + tld_json = {} + if collisions: + tlds = download_file(settings.ICANN_TLDS)[1].read().lower() + tld_json = LabelInfo.from_form('TLDs', tlds).to_dict() + lgr_info = LGRInfo(rz_lgr, lgr=get_by_name(rz_lgr, with_unidb=True)) + lgr_info.update_xml() + lgr_json = lgr_info.to_dict() + storage_path = session_get_storage(self.request) + + if labels_file: + labels_json = LabelInfo.from_form(labels_file.name, labels_file.read()).to_dict() + # data will be sent by email instead of on the ui + ctx['validation_to'] = email_address + if collisions: + basic_collision_task.delay(lgr_json, labels_json, tld_json, email_address, storage_path, True) + ctx['collision_to'] = email_address + else: + annotate_task.delay(lgr_json, labels_json, email_address, storage_path) + + else: + labels_json = LabelInfo.from_list('labels', [cp_to_ulabel(l) for l in labels_cp]).to_dict() + check_collisions = None + if collisions: + if len(labels_cp) == 1: + # if only one label include collisions directly in result + data = tlds.decode('utf-8') + check_collisions = [l[0] for l in read_labels(six.StringIO(data))] + else: + basic_collision_task.delay(lgr_json, labels_json, tld_json, email_address, storage_path, + False) + ctx['collision_to'] = email_address + + for label_cplist in labels_cp: + try: + results.append(evaluate_label_from_info(self.request, lgr_info, label_cplist, None, email_address, + check_collisions=check_collisions)) + except UnicodeError as ex: + messages.add_message(self.request, messages.ERROR, lgr_exception_to_text(ex)) + except NeedAsyncProcess: + messages.add_message(self.request, messages.INFO, + _('Input label generates too many variants to compute them all quickly. ' + 'You need to enter your email address and will receive a notification once ' + 'process is done')) + ctx['email_required'] = True + except LGRException as ex: + messages.add_message(self.request, messages.ERROR, lgr_exception_to_text(ex)) + # redirect to myself to refresh display + return redirect('lgr_basic_mode') + + return self.render_to_response(self.get_context_data(results=results, **ctx)) + + def get_context_data(self, **kwargs): + ctx = super(BasicModeView, self).get_context_data(**kwargs) + if 'results' in kwargs: + ctx['results'] = kwargs.pop('results') + ctx['storage'] = session_list_storage(self.request) + ctx.update(kwargs) + return ctx diff --git a/src/lgr_editor/api.py b/src/lgr_editor/api.py index 8a7e88db..d58b5b19 100644 --- a/src/lgr_editor/api.py +++ b/src/lgr_editor/api.py @@ -24,7 +24,7 @@ from .utils import (LGR_CACHE_TIMEOUT, LGR_OBJECT_CACHE_KEY, clean_repertoire_cache, - make_lgr_session_key) + make_lgr_session_key, list_root_zones) from .exceptions import LGRValidationException from .repertoires import get_by_name from . import unidb @@ -45,9 +45,17 @@ def __init__(self, name, lgr=None, xml=None, validating_repertoire=None, lgr_set self.lgr_set = lgr_set self.set_labels_info = set_labels_info # List of labels defined for the LGR set, optional - def update_xml(self, pretty_print=False): + def update_xml(self, pretty_print=False, validate=False): # if something was changed in `lgr`, calling this will re-generate the xml - self.xml = serialize_lgr_xml(self.lgr, pretty_print=pretty_print) + new_xml = serialize_lgr_xml(self.lgr, pretty_print=pretty_print) + if validate: + parser = XMLParser(six.BytesIO(new_xml), self.name) + + validation_result = parser.validate_document(settings.LGR_RNG_FILE) + if validation_result is not None: + raise LGRValidationException(validation_result) + + self.xml = new_xml @classmethod def create(cls, name, unicode_version, validating_repertoire_name): @@ -205,6 +213,14 @@ def from_form(cls, name, label_input): return cls(name, labels, b64data) + @classmethod + def from_list(cls, name, labels): + data = '\n'.join(labels) + labels = six.StringIO(data) + b64data = base64.b64encode(data.encode('utf-8')).decode('utf-8') + + return cls(name, labels, b64data) + def to_dict(self): return { 'name': self.name, @@ -298,6 +314,7 @@ def session_open_lgr(request, lgr_id, lgr_xml, def session_select_lgr(request, lgr_id, lgr_set_id=None): """ Find the LGR identified by `lgr_id` in the session. + Can also retrieve a root zone LGR. :param request: Django request object :param lgr_id: a slug identifying the LGR @@ -306,6 +323,10 @@ def session_select_lgr(request, lgr_id, lgr_set_id=None): """ known_lgrs = request.session.get(LGRS_SESSION_KEY, {}) + # handle RZ LGR selection + if lgr_id not in known_lgrs and lgr_id in list_root_zones(): + return LGRInfo(lgr_id, lgr=get_by_name(lgr_id, with_unidb=True)) + if lgr_set_id: if lgr_set_id not in known_lgrs: raise Http404 diff --git a/src/lgr_editor/forms/codepoints.py b/src/lgr_editor/forms/codepoints.py index a2e8972e..247b49be 100644 --- a/src/lgr_editor/forms/codepoints.py +++ b/src/lgr_editor/forms/codepoints.py @@ -132,13 +132,13 @@ def clean(self): cleaned_data = super(EditCodepointsForm, self).clean() if self.post and 'add-rules' in self.post: if cleaned_data['when'] and cleaned_data['not_when']: - self.add_error('when', 'Cannot add when and not-when rules simultaneously') - self.add_error('not_when', 'Cannot add when and not-when rules simultaneously') + self.add_error('when', _('Cannot add when and not-when rules simultaneously')) + self.add_error('not_when', _('Cannot add when and not-when rules simultaneously')) elif not cleaned_data.get('when') and not cleaned_data.get('not_when'): - self.add_error('when', 'Please provide at least one value') - self.add_error('not_when', 'Please provide at least one value') + self.add_error('when', _('Please provide at least one value')) + self.add_error('not_when', _('Please provide at least one value')) if self.post and 'add-tags' in self.post and not cleaned_data.get('tags'): - self.add_error('tags', 'Please provide at least one value') + self.add_error('tags', _('Please provide at least one value')) return cleaned_data diff --git a/src/lgr_editor/forms/fields.py b/src/lgr_editor/forms/fields.py index cc634d42..a2ca06ea 100644 --- a/src/lgr_editor/forms/fields.py +++ b/src/lgr_editor/forms/fields.py @@ -1,11 +1,15 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import re from django.conf import settings -from lgr_editor.utils import list_validating_repertoires - +from lgr_editor.utils import list_validating_repertoires, list_root_zones, parse_language_registry UNICODE_VERSIONS = tuple((v, v) for v in settings.SUPPORTED_UNICODE_VERSIONS) DEFAULT_UNICODE_VERSION = settings.SUPPORTED_UNICODE_VERSIONS[0] VALIDATING_REPERTOIRES = tuple((v, v) for v in list_validating_repertoires()) DEFAULT_VALIDATING_REPERTOIRE = '' + +ROOT_ZONES = tuple((v, re.sub(r'lgr-([1-9]+)-.*', r'RZ-LGR version \1', v)) for v in sorted(list_root_zones())) + +IANA_LANG_REGISTRY = parse_language_registry() diff --git a/src/lgr_editor/forms/importer.py b/src/lgr_editor/forms/importer.py index 4458ab38..7f7a126e 100644 --- a/src/lgr_editor/forms/importer.py +++ b/src/lgr_editor/forms/importer.py @@ -38,5 +38,4 @@ class ImportLGRForm(forms.Form): 'This value may contain only letters, numbers ' 'and ./-/_ characters.'), 'invalid'), ], - help_text=_('The name of the set'), - ) + help_text=_('The name of the set')) diff --git a/src/lgr_editor/forms/labels.py b/src/lgr_editor/forms/labels.py index b8ed9e89..831ab9ce 100644 --- a/src/lgr_editor/forms/labels.py +++ b/src/lgr_editor/forms/labels.py @@ -3,11 +3,10 @@ from django import forms from django.utils.translation import ugettext_lazy as _ -from django.utils.six import text_type - -from lgr_editor import unidb from lgr.tools.utils import parse_label_input +from lgr_editor import unidb +from lgr_editor.lgr_exceptions import lgr_exception_to_text class LabelFormsForm(forms.Form): @@ -29,7 +28,7 @@ def clean(self): try: value = parse_label_input(label, idna_decoder=udata.idna_decode_label) except ValueError as e: - self.add_error('label', text_type(e)) + self.add_error('label', lgr_exception_to_text(e)) else: self.cleaned_data['label'] = value return self.cleaned_data diff --git a/src/lgr_editor/forms/metadata.py b/src/lgr_editor/forms/metadata.py index 3fcc7f87..e433ace1 100644 --- a/src/lgr_editor/forms/metadata.py +++ b/src/lgr_editor/forms/metadata.py @@ -3,15 +3,16 @@ from datetime import date -from django.utils import six +from dal import autocomplete from django import forms from django.forms.formsets import formset_factory +from django.utils import six from django.utils.translation import ugettext_lazy as _ +from .fields import UNICODE_VERSIONS, DEFAULT_UNICODE_VERSION, VALIDATING_REPERTOIRES, DEFAULT_VALIDATING_REPERTOIRE, \ + IANA_LANG_REGISTRY from .utils import BaseDisableableFormSet -from .fields import UNICODE_VERSIONS, DEFAULT_UNICODE_VERSION, VALIDATING_REPERTOIRES, DEFAULT_VALIDATING_REPERTOIRE - def DateInputPlaceHolder(placeholder=''): """ @@ -28,6 +29,7 @@ def TextInputPlaceHolder(placeholder): """ return forms.TextInput(attrs={'placeholder': placeholder}) + DESCRIPTION_CONTENT_TYPES = ( ('', ''), ('text/plain', 'text/plain'), @@ -39,11 +41,14 @@ class MetadataForm(forms.Form): version = forms.CharField(label=_("Version"), max_length=255, required=False) version_comment = forms.CharField(label=_("Version comment"), required=False) date = forms.DateField(label=_("Date"), widget=DateInputPlaceHolder(date.today().isoformat()), required=False) - scope = forms.CharField(label=_("Scope"), max_length=255, required=False, widget=TextInputPlaceHolder('example')) # XXX: we may need to support multiple scope elements - scope_type = forms.CharField(label=_("Scope type"), max_length=255, required=False, widget=TextInputPlaceHolder('domain')) + scope = forms.CharField(label=_("Scope"), max_length=255, required=False, widget=TextInputPlaceHolder( + 'example')) # XXX: we may need to support multiple scope elements + scope_type = forms.CharField(label=_("Scope type"), max_length=255, required=False, + widget=TextInputPlaceHolder('domain')) validity_start = forms.DateField(label=_("Validity start"), widget=DateInputPlaceHolder(), required=False) validity_end = forms.DateField(label=_("Validity end"), widget=DateInputPlaceHolder(), required=False) - unicode_version = forms.ChoiceField(label=_("Unicode version"), choices=UNICODE_VERSIONS, initial=DEFAULT_UNICODE_VERSION, required=False) + unicode_version = forms.ChoiceField(label=_("Unicode version"), choices=UNICODE_VERSIONS, + initial=DEFAULT_UNICODE_VERSION, required=False) description = forms.CharField(label=_("Description"), widget=forms.Textarea, required=False) description_type = forms.ChoiceField(label=_("Description type"), choices=DESCRIPTION_CONTENT_TYPES, required=False) @@ -72,7 +77,9 @@ def __init__(self, *args, **kwargs): class LanguageForm(forms.Form): # validate using language_tags function - language = forms.CharField(label=_("Language"), max_length=50, required=False) # https://tools.ietf.org/html/rfc5646#section-4.4 + language = autocomplete.Select2ListChoiceField(label=_("Language"), choice_list=[''] + sorted(IANA_LANG_REGISTRY), + widget=autocomplete.ListSelect2(url='language-autocomplete'), + initial='', required=False) LanguageFormSet = formset_factory(LanguageForm, diff --git a/src/lgr_editor/forms/references.py b/src/lgr_editor/forms/references.py index ad3361c3..3450bf25 100644 --- a/src/lgr_editor/forms/references.py +++ b/src/lgr_editor/forms/references.py @@ -5,6 +5,7 @@ from django import forms from django.forms.formsets import formset_factory +from django.utils.translation import ugettext_lazy as _ from lgr.metadata import ReferenceManager from .utils import BaseDisableableFormSet, ReadOnlyTextInput @@ -29,7 +30,7 @@ def __init__(self, *args, **kwargs): def clean(self): cleaned_data = super(ReferenceForm, self).clean() if cleaned_data['ref_id'] and not re.match(ReferenceManager.REFERENCE_REGEX, str(cleaned_data['ref_id'])): - self.add_error('ref_id', 'Invalid format') + self.add_error('ref_id', _('Invalid format')) return cleaned_data diff --git a/src/lgr_editor/lgr_exceptions.py b/src/lgr_editor/lgr_exceptions.py index dfee98f4..612f1a70 100644 --- a/src/lgr_editor/lgr_exceptions.py +++ b/src/lgr_editor/lgr_exceptions.py @@ -3,10 +3,13 @@ lgr_exceptions.py - Map LGR exception to user terms. """ from __future__ import unicode_literals + +from django.utils.translation import ugettext from django.utils.translation import ugettext_lazy as _ import lgr.exceptions from lgr.utils import format_cp +from picu.exceptions import IDNAException from .exceptions import LGRValidationException @@ -28,14 +31,14 @@ def lgr_exception_to_text(exception): elif isinstance(exception, lgr.exceptions.NotInRepertoire): message = _('Input code point %(codepoint)s is not in ' 'the reference repertoire') % { - 'codepoint': format_cp(exception.cp) - } + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.VariantAlreadyExists): message = _('Variant %(variant_codepoint)s already exists for ' 'code point %(codepoint)s') % { - 'variant_codepoint': format_cp(exception.variant), - 'codepoint': format_cp(exception.cp) - } + 'variant_codepoint': format_cp(exception.variant), + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.RangeAlreadyExists): message = _('Range %(first_cp)s - %(last_cp)s already exists in the LGR') % { 'first_cp': format_cp(exception.first_cp), @@ -44,8 +47,8 @@ def lgr_exception_to_text(exception): elif isinstance(exception, lgr.exceptions.CharAlreadyExists): message = _('Input code point %(codepoint)s already exists ' 'in the LGR') % { - 'codepoint': format_cp(exception.cp) - } + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.CharNotInScript): message = _('Input code point %(codepoint)s is not in LGR script') % { 'codepoint': format_cp(exception.cp) @@ -53,8 +56,8 @@ def lgr_exception_to_text(exception): elif isinstance(exception, lgr.exceptions.CharInvalidIdnaProperty): message = _('Input code point %(codepoint)s is not a ' 'PVALID/CONTEXTO/CONTEXTJ code point per IDNA2008') % { - 'codepoint': format_cp(exception.cp) - } + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.CharInvalidContextRule): message = _('Code point %(codepoint)s has invalid context rule %(rule)s') % { 'codepoint': format_cp(exception.cp), @@ -68,9 +71,9 @@ def lgr_exception_to_text(exception): elif isinstance(exception, lgr.exceptions.VariantInvalidContextRule): message = _('Variant %(variant_codepoint)s of code point %(codepoint)s' 'has invalid context rule') % { - 'variant_codepoint': format_cp(exception.variant), - 'codepoint': format_cp(exception.cp) - } + 'variant_codepoint': format_cp(exception.variant), + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.DuplicateReference): message = _('Duplicate reference for code point %(codepoint)s') % { 'codepoint': format_cp(exception.cp) @@ -78,8 +81,8 @@ def lgr_exception_to_text(exception): elif isinstance(exception, lgr.exceptions.CharLGRException): message = _('Unspecified exception for input code point ' '%(codepoint)s') % { - 'codepoint': format_cp(exception.cp) - } + 'codepoint': format_cp(exception.cp) + } elif isinstance(exception, lgr.exceptions.LGRFormatException): reason = exception.reason if reason == lgr.exceptions.LGRFormatException.LGRFormatReason.SEQUENCE_NO_TAG: @@ -127,8 +130,79 @@ def lgr_exception_to_text(exception): 'relations') elif isinstance(exception, lgr.exceptions.MissingLanguage): message = _('The LGR does not contain a valid language (%(message)s)' % {'message': exception.message}) + elif isinstance(exception, lgr.exceptions.LGRCrossScriptMissingDataException): + message = _('Cannot generate cross-script variant for LGR without (%(message)s)' % { + 'message': exception.missing_part + }) elif isinstance(exception, lgr.exceptions.LGRException): message = _('An unknown exception occurred in the LGR API') + elif isinstance(exception, IDNAException): + messages = [] + for error in exception.error_labels: + if error == 'UIDNA_ERROR_EMPTY_LABEL': + messages.append(ugettext('Label is empty')) + elif error == 'UIDNA_ERROR_LABEL_TOO_LONG': + messages.append(ugettext('%(label)s is invalid due to its length being longer than 63 bytes.') % { + 'label': exception.obj + }) + # elif error == 'UIDNA_ERROR_DOMAIN_NAME_TOO_LONG': + elif error == 'UIDNA_ERROR_LEADING_HYPHEN': + messages.append(ugettext('%(label)s is invalid due to hypen restrictions in the RFC5891 as it starts ' + 'with a hyphen-minus.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_TRAILING_HYPHEN': + messages.append(ugettext('%(label)s is invalid due to hyphen restrictions in the RFC5891 as it ends ' + 'with a hyphen-minus.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_HYPHEN_3_4': + messages.append(ugettext('%(label)s is invalid due to hyphen restrictions in the RFC5891 as it ' + 'contains hyphen-minus in the third and fourth positions.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_LEADING_COMBINING_MARK': + messages.append(ugettext('%(label)s is invalid due to leading combining marks restriction in the ' + 'RFC5891.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_DISALLOWED': + messages.append(ugettext('%(label)s is invalid as it contains disallowed characters.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_PUNYCODE': + messages.append(ugettext('%(label)s is invalid as it starts with ‘xn--’ but does not contain valid ' + 'Punycode.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_LABEL_HAS_DOT': + messages.append(ugettext('%(label)s is invalid as it contains full stop (dot).' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_INVALID_ACE_LABEL': + messages.append(ugettext('%(label)s is invalid due to invalid Punycode.' % {'label': exception.obj})) + elif error == 'UIDNA_ERROR_BIDI': + messages.append(ugettext('%(label)s is invalid due to the Bidi rule in the RFC5893.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_CONTEXTJ': + messages.append(ugettext('%(label)s is invalid due to the IDNA contextual rule for Zero Width ' + 'Joiner.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_CONTEXTO_PUNCTUATION': + messages.append(ugettext('%(label)s is invalid due to the IDNA contextual rule for punctuation in ' + 'the RFC5892.' % { + 'label': exception.obj + })) + elif error == 'UIDNA_ERROR_CONTEXTO_DIGITS': + messages.append(ugettext('%(label)s is invalid due to the IDNA contextual rule for digits in the ' + 'RFC5892.' % { + 'label': exception.obj + })) + else: + messages.append(exception) + message = '\n'.join(messages) else: message = '%s' % exception diff --git a/src/lgr_editor/locale/ar/LC_MESSAGES/django.mo b/src/lgr_editor/locale/ar/LC_MESSAGES/django.mo index cfa97df1..74dbaf67 100644 Binary files a/src/lgr_editor/locale/ar/LC_MESSAGES/django.mo and b/src/lgr_editor/locale/ar/LC_MESSAGES/django.mo differ diff --git a/src/lgr_editor/locale/ar/LC_MESSAGES/django.po b/src/lgr_editor/locale/ar/LC_MESSAGES/django.po index 6e5c0e27..9ee52dc8 100644 --- a/src/lgr_editor/locale/ar/LC_MESSAGES/django.po +++ b/src/lgr_editor/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-04 16:04+0000\n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,6 +29,7 @@ msgstr "" #: forms/codepoint.py:16 templates/lgr_editor/_editor_base.html:31 #: templates/lgr_editor/codepoint_list.html:40 +#: templates/lgr_editor/validate_lgr/compute_stats.html:71 msgid "Tags" msgstr "" @@ -72,7 +73,7 @@ msgid "" msgstr "" #: forms/codepoints.py:78 forms/importer.py:14 forms/importer.py:27 -#: forms/metadata.py:50 +#: forms/metadata.py:55 msgid "Validating repertoire" msgstr "" @@ -98,6 +99,14 @@ msgstr "" msgid "File type" msgstr "" +#: forms/codepoints.py:135 forms/codepoints.py:136 +msgid "Cannot add when and not-when rules simultaneously" +msgstr "" + +#: forms/codepoints.py:138 forms/codepoints.py:139 forms/codepoints.py:142 +msgid "Please provide at least one value" +msgstr "" + #: forms/importer.py:13 msgid "Name" msgstr "" @@ -124,208 +133,301 @@ msgstr "" msgid "The name of the set" msgstr "" -#: forms/labels.py:14 +#: forms/labels.py:13 msgid "Label" msgstr "" -#: forms/labels.py:15 forms/metadata.py:46 +#: forms/labels.py:14 forms/metadata.py:50 msgid "Unicode version" msgstr "" -#: forms/labels.py:17 +#: forms/labels.py:16 msgid "The unicode version used" msgstr "" -#: forms/metadata.py:39 +#: forms/metadata.py:41 msgid "Version" msgstr "" -#: forms/metadata.py:40 +#: forms/metadata.py:42 msgid "Version comment" msgstr "" -#: forms/metadata.py:41 +#: forms/metadata.py:43 msgid "Date" msgstr "" -#: forms/metadata.py:42 +#: forms/metadata.py:44 msgid "Scope" msgstr "" -#: forms/metadata.py:43 +#: forms/metadata.py:46 msgid "Scope type" msgstr "" -#: forms/metadata.py:44 +#: forms/metadata.py:48 msgid "Validity start" msgstr "" -#: forms/metadata.py:45 +#: forms/metadata.py:49 msgid "Validity end" msgstr "" -#: forms/metadata.py:47 templates/lgr_editor/codepoint_view.html:227 +#: forms/metadata.py:52 templates/lgr_editor/codepoint_view.html:227 #: templates/lgr_editor/references.html:14 #: templates/lgr_editor/references.html:51 msgid "Description" msgstr "" -#: forms/metadata.py:48 +#: forms/metadata.py:53 msgid "Description type" msgstr "" -#: forms/metadata.py:53 +#: forms/metadata.py:58 msgid "Built-in" msgstr "" -#: forms/metadata.py:65 +#: forms/metadata.py:70 msgid "My LGRs" msgstr "" -#: forms/metadata.py:75 +#: forms/metadata.py:80 msgid "Language" msgstr "" -#: lgr_exceptions.py:25 +#: forms/references.py:33 +msgid "Invalid format" +msgstr "" + +#: lgr_exceptions.py:28 #, python-format msgid "Input code point %(codepoint)s is not in the LGR" msgstr "" -#: lgr_exceptions.py:29 +#: lgr_exceptions.py:32 #, python-format msgid "Input code point %(codepoint)s is not in the reference repertoire" msgstr "" -#: lgr_exceptions.py:34 +#: lgr_exceptions.py:37 #, python-format msgid "" "Variant %(variant_codepoint)s already exists for code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:40 +#: lgr_exceptions.py:43 #, python-format msgid "Range %(first_cp)s - %(last_cp)s already exists in the LGR" msgstr "" -#: lgr_exceptions.py:45 +#: lgr_exceptions.py:48 #, python-format msgid "Input code point %(codepoint)s already exists in the LGR" msgstr "" -#: lgr_exceptions.py:50 +#: lgr_exceptions.py:53 #, python-format msgid "Input code point %(codepoint)s is not in LGR script" msgstr "" -#: lgr_exceptions.py:54 +#: lgr_exceptions.py:57 #, python-format msgid "" "Input code point %(codepoint)s is not a PVALID/CONTEXTO/CONTEXTJ code point " "per IDNA2008" msgstr "" -#: lgr_exceptions.py:59 +#: lgr_exceptions.py:62 #, python-format msgid "Code point %(codepoint)s has invalid context rule %(rule)s" msgstr "" -#: lgr_exceptions.py:64 +#: lgr_exceptions.py:67 #, python-format msgid "Range %(first_cp)s - %(last_cp)s has invalid context rule" msgstr "" -#: lgr_exceptions.py:69 +#: lgr_exceptions.py:72 #, python-format msgid "" "Variant %(variant_codepoint)s of code point %(codepoint)shas invalid context " "rule" msgstr "" -#: lgr_exceptions.py:75 +#: lgr_exceptions.py:78 #, python-format msgid "Duplicate reference for code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:79 +#: lgr_exceptions.py:82 #, python-format msgid "Unspecified exception for input code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:86 +#: lgr_exceptions.py:89 msgid "Sequence cannot have a tag" msgstr "" -#: lgr_exceptions.py:88 +#: lgr_exceptions.py:91 msgid "Invalid language" msgstr "" -#: lgr_exceptions.py:90 +#: lgr_exceptions.py:93 msgid "Invalid date value" msgstr "" -#: lgr_exceptions.py:92 +#: lgr_exceptions.py:95 msgid "Invalid Unicode version" msgstr "" -#: lgr_exceptions.py:94 +#: lgr_exceptions.py:97 msgid "Invalid LGR XML file" msgstr "" -#: lgr_exceptions.py:96 +#: lgr_exceptions.py:99 #, python-format msgid "Reference %(ref_id)s is not defined" msgstr "" -#: lgr_exceptions.py:100 +#: lgr_exceptions.py:103 #, python-format msgid "Reference %(ref_id)s already exists" msgstr "" -#: lgr_exceptions.py:104 +#: lgr_exceptions.py:107 #, python-format msgid "Invalid reference id %(ref_id)s " msgstr "" -#: lgr_exceptions.py:108 +#: lgr_exceptions.py:111 #, python-format msgid "Rule \"%(rule_name)s\" cannot be processed (%(message)s)" msgstr "" -#: lgr_exceptions.py:113 +#: lgr_exceptions.py:116 msgid "Input parameter has invalid format" msgstr "" -#: lgr_exceptions.py:115 +#: lgr_exceptions.py:118 msgid "A general exception occurred in the LGR API" msgstr "" -#: lgr_exceptions.py:117 +#: lgr_exceptions.py:120 #, python-format msgid "LGR is not valid (%(args)s)" msgstr "" -#: lgr_exceptions.py:119 +#: lgr_exceptions.py:122 #, python-format msgid "Label %(label)s is not valid in the LGR (%(message)s)" msgstr "" -#: lgr_exceptions.py:124 +#: lgr_exceptions.py:127 msgid "Input label file contains collision(s)" msgstr "" -#: lgr_exceptions.py:126 +#: lgr_exceptions.py:129 msgid "The LGR contains a variant that do not have symmetric relations" msgstr "" -#: lgr_exceptions.py:129 +#: lgr_exceptions.py:132 #, python-format msgid "The LGR does not contain a valid language (%(message)s)" msgstr "" -#: lgr_exceptions.py:131 +#: lgr_exceptions.py:134 +#, python-format +msgid "Cannot generate cross-script variant for LGR without (%(message)s)" +msgstr "" + +#: lgr_exceptions.py:138 msgid "An unknown exception occurred in the LGR API" msgstr "" +#: lgr_exceptions.py:143 +msgid "Label is empty" +msgstr "" + +#: lgr_exceptions.py:145 +#, python-format +msgid "%(label)s is invalid due to its length being longer than 63 bytes." +msgstr "" + +#: lgr_exceptions.py:150 +#, python-format +msgid "" +"%(label)s is invalid due to hypen restrictions in the RFC5891 as it starts " +"with a hyphen-minus." +msgstr "" + +#: lgr_exceptions.py:155 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it ends " +"with a hyphen-minus." +msgstr "" + +#: lgr_exceptions.py:160 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it " +"contains hyphen-minus in the third and fourth positions." +msgstr "" + +#: lgr_exceptions.py:165 +#, python-format +msgid "" +"%(label)s is invalid due to leading combining marks restriction in the " +"RFC5891." +msgstr "" + +#: lgr_exceptions.py:170 +#, python-format +msgid "%(label)s is invalid as it contains disallowed characters." +msgstr "" + +#: lgr_exceptions.py:174 +#, python-format +msgid "" +"%(label)s is invalid as it starts with ‘xn--’ but does not contain valid " +"Punycode." +msgstr "" + +#: lgr_exceptions.py:179 +#, python-format +msgid "%(label)s is invalid as it contains full stop (dot)." +msgstr "" + +#: lgr_exceptions.py:183 +#, python-format +msgid "%(label)s is invalid due to invalid Punycode." +msgstr "" + +#: lgr_exceptions.py:185 +#, python-format +msgid "%(label)s is invalid due to the Bidi rule in the RFC5893." +msgstr "" + +#: lgr_exceptions.py:189 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for Zero Width Joiner." +msgstr "" + +#: lgr_exceptions.py:194 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for punctuation in the " +"RFC5892." +msgstr "" + +#: lgr_exceptions.py:199 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for digits in the " +"RFC5892." +msgstr "" + #: templates/lgr_editor/_editor_base.html:25 #: templates/lgr_editor/codepoint_view.html:54 msgid "References" @@ -337,6 +439,7 @@ msgstr "" #: templates/lgr_editor/_editor_base.html:34 templates/lgr_editor/rules.html:18 #: templates/lgr_editor/rules_edit.html:57 +#: templates/lgr_editor/validate_lgr/compute_stats.html:79 msgid "Rules" msgstr "" @@ -356,7 +459,7 @@ msgstr "" #: templates/lgr_editor/_rule_editor_widgets.html:5 #: templates/lgr_editor/codepoint_view.html:244 -#: templates/lgr_editor/metadata.html:32 +#: templates/lgr_editor/metadata.html:45 #: templates/lgr_editor/rules_edit.html:40 #: templates/lgr_editor/rules_edit.html:71 #: templates/lgr_editor/rules_edit.html:103 @@ -364,7 +467,7 @@ msgid "Cancel" msgstr "" #: templates/lgr_editor/_rule_editor_widgets.html:8 -#: templates/lgr_editor/metadata.html:33 +#: templates/lgr_editor/metadata.html:46 #: templates/lgr_editor/references.html:39 #: templates/lgr_editor/rules_edit.html:43 #: templates/lgr_editor/rules_edit.html:74 @@ -444,7 +547,6 @@ msgid "Action" msgstr "" #: templates/lgr_editor/codepoint_list.html:52 -#: templates/lgr_editor/codepoint_list.html:82 msgid "Add Rule" msgstr "" @@ -464,6 +566,11 @@ msgid "" " " msgstr "" +#: templates/lgr_editor/codepoint_list.html:82 +#: templates/lgr_editor/codepoint_list.html:275 +msgid "Add Tags" +msgstr "" + #: templates/lgr_editor/codepoint_list.html:87 msgid "" "\n" @@ -509,10 +616,6 @@ msgstr "" msgid "Add WLE" msgstr "" -#: templates/lgr_editor/codepoint_list.html:275 -msgid "Add Tags" -msgstr "" - #: templates/lgr_editor/codepoint_list.html:295 msgid "➡ Apply batch action..." msgstr "" @@ -658,23 +761,23 @@ msgstr "" msgid "Cannot import LGR file(s):" msgstr "" -#: templates/lgr_editor/label_forms.html:11 +#: templates/lgr_editor/label_forms.html:10 msgid "Display forms" msgstr "" -#: templates/lgr_editor/label_forms.html:18 +#: templates/lgr_editor/label_forms.html:16 msgid "Code point sequence" msgstr "" -#: templates/lgr_editor/label_forms.html:19 +#: templates/lgr_editor/label_forms.html:17 msgid "U-label" msgstr "" -#: templates/lgr_editor/label_forms.html:20 +#: templates/lgr_editor/label_forms.html:18 msgid "A-label" msgstr "" -#: templates/lgr_editor/metadata.html:11 +#: templates/lgr_editor/metadata.html:23 msgid "There was an error saving; please see error(s) below" msgstr "" @@ -776,215 +879,423 @@ msgid "" " Add it to a code point first to find it back in this list" msgstr "" -#: views.py:114 +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:7 +msgid "Erroneous conditional code points" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:11 +#, python-format +msgid "" +"Code point %(cp)s has invalid %(rule_type)s rule %(rule)s for variant " +"%(variant)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:18 +msgid "Conditional variants OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:7 +msgid "Missing code points or rules" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:11 +#, python-format +msgid "Code point %(cp)s:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:15 +#, python-format +msgid "Variant %(variant)s is not in repertoire" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:19 +#, python-format +msgid "%(variant)s has not original code point in its variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:23 +#, python-format +msgid "" +"%(variant)s has not symmetric %(rule_type)s rule %(rule)s on its symmetric " +"variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:27 +#, python-format +msgid "%(variant)s unknown symmetry problem, please report" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:35 +msgid "Symmetry OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:7 +msgid "Missing variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:11 +#, python-format +msgid "Code point %(cp)s is missing variant %(variant)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:18 +msgid "Transitivity OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:7 +msgid "XML is valid and complies with RNG." +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:9 +#, python-format +msgid "Invalid XML for lgr: %(res)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:6 +msgid "General stats" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:9 +#, python-format +msgid "Number of code points: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:15 +#, python-format +msgid "Number of ranges: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:21 +#, python-format +msgid "Largest range: %(largest)s (length: %(largest_len)s)" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:28 +#, python-format +msgid "Number of sequences: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:34 +#, python-format +msgid "Largest sequence: %(largest)s (length: %(largest_len)s)" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:41 +msgid "Variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:44 +#, python-format +msgid "Total number of variant mappings: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:49 +#, python-format +msgid "Average number of variants per code point: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:54 +#, python-format +msgid "Largest variant set: %(largest_set)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:60 +msgid "Variants per type:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:63 +#, python-format +msgid "Number of variants for type %(variant_type)s: %(number)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:74 +#, python-format +msgid "Number of code points for tag %(tag_name)s: %(number)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:82 +#, python-format +msgid "Number of defined rules: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:6 +#, python-format +msgid "Unicode version %(version)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:8 +#, python-format +msgid "Validating repertoire '%(repertoire)s'" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:13 +#, python-format +msgid "" +"Target Unicode version %(version)s differs from UnicodeDatabase %(database)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:19 +msgid "Possibly erroneous characters" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:23 +#, python-format +msgid "Character %(cp)s:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:29 +#, python-format +msgid "Warning: %(warn)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:36 +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:49 +#, python-format +msgid "Error: %(err)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:43 +#, python-format +msgid "Variant: %(variant|render_char)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:60 +msgid "LGR rebuild OK" +msgstr "" + +#: views.py:115 msgid "" "The LGR you have tried to create already exists in your working session. " "Please use a new name." msgstr "" -#: views.py:148 +#: views.py:149 msgid "" "The LGR you have tried to import already exists in your working session. " "Please rename it before importing it." msgstr "" -#: views.py:154 +#: views.py:155 msgid "" "The LGR you have tried to import already exists in your set. Please rename " "it before importing it." msgstr "" -#: views.py:177 +#: views.py:178 msgid "The LGR set name already exists. Please use another name." msgstr "" -#: views.py:289 +#: views.py:249 +msgid "Testing XML validity using RNG" +msgstr "" + +#: views.py:250 +msgid "Testing symmetry" +msgstr "" + +#: views.py:251 +msgid "Testing transitivity" +msgstr "" + +#: views.py:252 +msgid "Testing conditional variants" +msgstr "" + +#: views.py:253 +msgid "Generate stats" +msgstr "" + +#: views.py:254 +msgid "Rebuilding LGR" +msgstr "" + +#: views.py:302 #, python-format msgid "New code point %s added" msgstr "" -#: views.py:362 +#: views.py:375 msgid "Rule" msgstr "" -#: views.py:362 +#: views.py:375 msgid "Tag(s)" msgstr "" -#: views.py:363 +#: views.py:376 msgid "rule" msgstr "" -#: views.py:363 +#: views.py:376 msgid "tag(s)" msgstr "" -#: views.py:367 +#: views.py:380 #, python-format msgid "%(operation)s successfully added to %(nb_cp)s code point(s)" msgstr "" -#: views.py:372 +#: views.py:385 #, python-format msgid "%(nb_cp)s code points were not updated to avoid invalid %(operation)s" msgstr "" -#: views.py:504 +#: views.py:517 #, python-format -msgid "Automatically added codepoint %s from out-of-repertoire variant" +msgid "Automatically added codepoint %s from out-of-repertoire-var variant" msgstr "" -#: views.py:507 +#: views.py:520 #, python-format msgid "New variant %s added" msgstr "" -#: views.py:580 +#: views.py:593 msgid "Code point edited" msgstr "" -#: views.py:732 +#: views.py:745 msgid "Variants populated" msgstr "" -#: views.py:783 views.py:819 +#: views.py:798 views.py:834 msgid "References updated successfully" msgstr "" -#: views.py:822 +#: views.py:837 #, python-format msgid "" "Variant %(var_codepoint)s for code point %(codepoint)s with when=%(when)s " "and not-when=%(not_when)s could not be found" msgstr "" -#: views.py:858 +#: views.py:873 #, python-format msgid "Code point %s has been deleted" msgstr "" -#: views.py:880 +#: views.py:895 #, python-format msgid "Variant %(var_cp)s with when='%(when)s' and not-when='%(not_when)s'" msgstr "" -#: views.py:886 +#: views.py:901 #, python-format msgid "%(var_msg_prefix)s has been deleted" msgstr "" -#: views.py:889 +#: views.py:904 #, python-format msgid "%(var_msg_prefix)s could not be deleted because it was not found" msgstr "" -#: views.py:919 +#: views.py:934 msgid "New reference created" msgstr "" -#: views.py:1127 +#: views.py:1142 #, python-format msgid "" "References to tag %(tag)s have been removed from the repertoire. Do not " "forget to update any WLE that might reference it." msgstr "" -#: views.py:1195 views.py:1357 views.py:1441 +#: views.py:1210 views.py:1372 views.py:1460 msgid "No body specified" msgstr "" -#: views.py:1204 +#: views.py:1219 #, python-format msgid "Class \"%s\" does not exist" msgstr "" -#: views.py:1208 +#: views.py:1223 #, python-format msgid "Class \"%s\" deleted." msgstr "" -#: views.py:1213 +#: views.py:1228 msgid "No class element found" msgstr "" -#: views.py:1215 views.py:1377 +#: views.py:1230 views.py:1392 msgid "Name attribute must be present" msgstr "" -#: views.py:1219 views.py:1236 views.py:1381 views.py:1398 views.py:1465 -#: views.py:1478 +#: views.py:1234 views.py:1251 views.py:1405 views.py:1417 views.py:1484 +#: views.py:1497 #, python-format msgid "" "Encountered XML syntax error: %s (line number may be wrong, try subtracting " "one from the reported line number)" msgstr "" -#: views.py:1222 views.py:1239 views.py:1384 views.py:1401 views.py:1468 -#: views.py:1481 +#: views.py:1237 views.py:1254 views.py:1408 views.py:1420 views.py:1487 +#: views.py:1500 msgid "Your XML is not valid" msgstr "" -#: views.py:1227 +#: views.py:1242 #, python-format msgid "Class \"%s\" already exists" msgstr "" -#: views.py:1229 +#: views.py:1244 #, python-format msgid "Class \"%s\" saved." msgstr "" -#: views.py:1366 +#: views.py:1381 #, python-format msgid "Rule \"%s\" does not exist" msgstr "" -#: views.py:1370 +#: views.py:1385 #, python-format msgid "Rule \"%s\" deleted." msgstr "" -#: views.py:1375 +#: views.py:1390 msgid "No rule element found" msgstr "" -#: views.py:1389 +#: views.py:1397 #, python-format msgid "Rule \"%s\" already exists" msgstr "" -#: views.py:1391 +#: views.py:1410 #, python-format msgid "Rule \"%s\" saved." msgstr "" -#: views.py:1452 +#: views.py:1471 #, python-format msgid "Action \"%s\" does not exist" msgstr "" -#: views.py:1456 +#: views.py:1475 #, python-format msgid "Action \"%s\" deleted." msgstr "" -#: views.py:1461 +#: views.py:1480 msgid "No action element found" msgstr "" -#: views.py:1471 +#: views.py:1490 msgid "Action saved." msgstr "" -#: views.py:1540 views.py:1628 +#: views.py:1559 views.py:1647 #, python-format msgid "%d code points added" msgstr "" -#: views.py:1597 +#: views.py:1616 msgid "No code point in input file" msgstr "" -#: views.py:1903 +#: views.py:1922 msgid "Meta data saved" msgstr "" diff --git a/src/lgr_editor/locale/en/LC_MESSAGES/django.mo b/src/lgr_editor/locale/en/LC_MESSAGES/django.mo index 8b5f6d89..6c5906d1 100644 Binary files a/src/lgr_editor/locale/en/LC_MESSAGES/django.mo and b/src/lgr_editor/locale/en/LC_MESSAGES/django.mo differ diff --git a/src/lgr_editor/locale/en/LC_MESSAGES/django.po b/src/lgr_editor/locale/en/LC_MESSAGES/django.po index 6ebfb584..1dfaaa63 100644 --- a/src/lgr_editor/locale/en/LC_MESSAGES/django.po +++ b/src/lgr_editor/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-04 16:04+0000\n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -27,6 +27,7 @@ msgstr "" #: forms/codepoint.py:16 templates/lgr_editor/_editor_base.html:31 #: templates/lgr_editor/codepoint_list.html:40 +#: templates/lgr_editor/validate_lgr/compute_stats.html:71 msgid "Tags" msgstr "" @@ -70,7 +71,7 @@ msgid "" msgstr "" #: forms/codepoints.py:78 forms/importer.py:14 forms/importer.py:27 -#: forms/metadata.py:50 +#: forms/metadata.py:55 msgid "Validating repertoire" msgstr "" @@ -96,6 +97,14 @@ msgstr "" msgid "File type" msgstr "" +#: forms/codepoints.py:135 forms/codepoints.py:136 +msgid "Cannot add when and not-when rules simultaneously" +msgstr "" + +#: forms/codepoints.py:138 forms/codepoints.py:139 forms/codepoints.py:142 +msgid "Please provide at least one value" +msgstr "" + #: forms/importer.py:13 msgid "Name" msgstr "" @@ -122,208 +131,301 @@ msgstr "" msgid "The name of the set" msgstr "" -#: forms/labels.py:14 +#: forms/labels.py:13 msgid "Label" msgstr "" -#: forms/labels.py:15 forms/metadata.py:46 +#: forms/labels.py:14 forms/metadata.py:50 msgid "Unicode version" msgstr "" -#: forms/labels.py:17 +#: forms/labels.py:16 msgid "The unicode version used" msgstr "" -#: forms/metadata.py:39 +#: forms/metadata.py:41 msgid "Version" msgstr "" -#: forms/metadata.py:40 +#: forms/metadata.py:42 msgid "Version comment" msgstr "" -#: forms/metadata.py:41 +#: forms/metadata.py:43 msgid "Date" msgstr "" -#: forms/metadata.py:42 +#: forms/metadata.py:44 msgid "Scope" msgstr "" -#: forms/metadata.py:43 +#: forms/metadata.py:46 msgid "Scope type" msgstr "" -#: forms/metadata.py:44 +#: forms/metadata.py:48 msgid "Validity start" msgstr "" -#: forms/metadata.py:45 +#: forms/metadata.py:49 msgid "Validity end" msgstr "" -#: forms/metadata.py:47 templates/lgr_editor/codepoint_view.html:227 +#: forms/metadata.py:52 templates/lgr_editor/codepoint_view.html:227 #: templates/lgr_editor/references.html:14 #: templates/lgr_editor/references.html:51 msgid "Description" msgstr "" -#: forms/metadata.py:48 +#: forms/metadata.py:53 msgid "Description type" msgstr "" -#: forms/metadata.py:53 +#: forms/metadata.py:58 msgid "Built-in" msgstr "" -#: forms/metadata.py:65 +#: forms/metadata.py:70 msgid "My LGRs" msgstr "" -#: forms/metadata.py:75 +#: forms/metadata.py:80 msgid "Language" msgstr "" -#: lgr_exceptions.py:25 +#: forms/references.py:33 +msgid "Invalid format" +msgstr "" + +#: lgr_exceptions.py:28 #, python-format msgid "Input code point %(codepoint)s is not in the LGR" msgstr "" -#: lgr_exceptions.py:29 +#: lgr_exceptions.py:32 #, python-format msgid "Input code point %(codepoint)s is not in the reference repertoire" msgstr "" -#: lgr_exceptions.py:34 +#: lgr_exceptions.py:37 #, python-format msgid "" "Variant %(variant_codepoint)s already exists for code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:40 +#: lgr_exceptions.py:43 #, python-format msgid "Range %(first_cp)s - %(last_cp)s already exists in the LGR" msgstr "" -#: lgr_exceptions.py:45 +#: lgr_exceptions.py:48 #, python-format msgid "Input code point %(codepoint)s already exists in the LGR" msgstr "" -#: lgr_exceptions.py:50 +#: lgr_exceptions.py:53 #, python-format msgid "Input code point %(codepoint)s is not in LGR script" msgstr "" -#: lgr_exceptions.py:54 +#: lgr_exceptions.py:57 #, python-format msgid "" "Input code point %(codepoint)s is not a PVALID/CONTEXTO/CONTEXTJ code point " "per IDNA2008" msgstr "" -#: lgr_exceptions.py:59 +#: lgr_exceptions.py:62 #, python-format msgid "Code point %(codepoint)s has invalid context rule %(rule)s" msgstr "" -#: lgr_exceptions.py:64 +#: lgr_exceptions.py:67 #, python-format msgid "Range %(first_cp)s - %(last_cp)s has invalid context rule" msgstr "" -#: lgr_exceptions.py:69 +#: lgr_exceptions.py:72 #, python-format msgid "" "Variant %(variant_codepoint)s of code point %(codepoint)shas invalid context " "rule" msgstr "" -#: lgr_exceptions.py:75 +#: lgr_exceptions.py:78 #, python-format msgid "Duplicate reference for code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:79 +#: lgr_exceptions.py:82 #, python-format msgid "Unspecified exception for input code point %(codepoint)s" msgstr "" -#: lgr_exceptions.py:86 +#: lgr_exceptions.py:89 msgid "Sequence cannot have a tag" msgstr "" -#: lgr_exceptions.py:88 +#: lgr_exceptions.py:91 msgid "Invalid language" msgstr "" -#: lgr_exceptions.py:90 +#: lgr_exceptions.py:93 msgid "Invalid date value" msgstr "" -#: lgr_exceptions.py:92 +#: lgr_exceptions.py:95 msgid "Invalid Unicode version" msgstr "" -#: lgr_exceptions.py:94 +#: lgr_exceptions.py:97 msgid "Invalid LGR XML file" msgstr "" -#: lgr_exceptions.py:96 +#: lgr_exceptions.py:99 #, python-format msgid "Reference %(ref_id)s is not defined" msgstr "" -#: lgr_exceptions.py:100 +#: lgr_exceptions.py:103 #, python-format msgid "Reference %(ref_id)s already exists" msgstr "" -#: lgr_exceptions.py:104 +#: lgr_exceptions.py:107 #, python-format msgid "Invalid reference id %(ref_id)s " msgstr "" -#: lgr_exceptions.py:108 +#: lgr_exceptions.py:111 #, python-format msgid "Rule \"%(rule_name)s\" cannot be processed (%(message)s)" msgstr "" -#: lgr_exceptions.py:113 +#: lgr_exceptions.py:116 msgid "Input parameter has invalid format" msgstr "" -#: lgr_exceptions.py:115 +#: lgr_exceptions.py:118 msgid "A general exception occurred in the LGR API" msgstr "" -#: lgr_exceptions.py:117 +#: lgr_exceptions.py:120 #, python-format msgid "LGR is not valid (%(args)s)" msgstr "" -#: lgr_exceptions.py:119 +#: lgr_exceptions.py:122 #, python-format msgid "Label %(label)s is not valid in the LGR (%(message)s)" msgstr "" -#: lgr_exceptions.py:124 +#: lgr_exceptions.py:127 msgid "Input label file contains collision(s)" msgstr "" -#: lgr_exceptions.py:126 +#: lgr_exceptions.py:129 msgid "The LGR contains a variant that do not have symmetric relations" msgstr "" -#: lgr_exceptions.py:129 +#: lgr_exceptions.py:132 #, python-format msgid "The LGR does not contain a valid language (%(message)s)" msgstr "" -#: lgr_exceptions.py:131 +#: lgr_exceptions.py:134 +#, python-format +msgid "Cannot generate cross-script variant for LGR without (%(message)s)" +msgstr "" + +#: lgr_exceptions.py:138 msgid "An unknown exception occurred in the LGR API" msgstr "" +#: lgr_exceptions.py:143 +msgid "Label is empty" +msgstr "" + +#: lgr_exceptions.py:145 +#, python-format +msgid "%(label)s is invalid due to its length being longer than 63 bytes." +msgstr "" + +#: lgr_exceptions.py:150 +#, python-format +msgid "" +"%(label)s is invalid due to hypen restrictions in the RFC5891 as it starts " +"with a hyphen-minus." +msgstr "" + +#: lgr_exceptions.py:155 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it ends " +"with a hyphen-minus." +msgstr "" + +#: lgr_exceptions.py:160 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it " +"contains hyphen-minus in the third and fourth positions." +msgstr "" + +#: lgr_exceptions.py:165 +#, python-format +msgid "" +"%(label)s is invalid due to leading combining marks restriction in the " +"RFC5891." +msgstr "" + +#: lgr_exceptions.py:170 +#, python-format +msgid "%(label)s is invalid as it contains disallowed characters." +msgstr "" + +#: lgr_exceptions.py:174 +#, python-format +msgid "" +"%(label)s is invalid as it starts with ‘xn--’ but does not contain valid " +"Punycode." +msgstr "" + +#: lgr_exceptions.py:179 +#, python-format +msgid "%(label)s is invalid as it contains full stop (dot)." +msgstr "" + +#: lgr_exceptions.py:183 +#, python-format +msgid "%(label)s is invalid due to invalid Punycode." +msgstr "" + +#: lgr_exceptions.py:185 +#, python-format +msgid "%(label)s is invalid due to the Bidi rule in the RFC5893." +msgstr "" + +#: lgr_exceptions.py:189 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for Zero Width Joiner." +msgstr "" + +#: lgr_exceptions.py:194 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for punctuation in the " +"RFC5892." +msgstr "" + +#: lgr_exceptions.py:199 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for digits in the " +"RFC5892." +msgstr "" + #: templates/lgr_editor/_editor_base.html:25 #: templates/lgr_editor/codepoint_view.html:54 msgid "References" @@ -335,6 +437,7 @@ msgstr "" #: templates/lgr_editor/_editor_base.html:34 templates/lgr_editor/rules.html:18 #: templates/lgr_editor/rules_edit.html:57 +#: templates/lgr_editor/validate_lgr/compute_stats.html:79 msgid "Rules" msgstr "" @@ -354,7 +457,7 @@ msgstr "" #: templates/lgr_editor/_rule_editor_widgets.html:5 #: templates/lgr_editor/codepoint_view.html:244 -#: templates/lgr_editor/metadata.html:32 +#: templates/lgr_editor/metadata.html:45 #: templates/lgr_editor/rules_edit.html:40 #: templates/lgr_editor/rules_edit.html:71 #: templates/lgr_editor/rules_edit.html:103 @@ -362,7 +465,7 @@ msgid "Cancel" msgstr "" #: templates/lgr_editor/_rule_editor_widgets.html:8 -#: templates/lgr_editor/metadata.html:33 +#: templates/lgr_editor/metadata.html:46 #: templates/lgr_editor/references.html:39 #: templates/lgr_editor/rules_edit.html:43 #: templates/lgr_editor/rules_edit.html:74 @@ -442,7 +545,6 @@ msgid "Action" msgstr "" #: templates/lgr_editor/codepoint_list.html:52 -#: templates/lgr_editor/codepoint_list.html:82 msgid "Add Rule" msgstr "" @@ -462,6 +564,11 @@ msgid "" " " msgstr "" +#: templates/lgr_editor/codepoint_list.html:82 +#: templates/lgr_editor/codepoint_list.html:275 +msgid "Add Tags" +msgstr "" + #: templates/lgr_editor/codepoint_list.html:87 msgid "" "\n" @@ -507,10 +614,6 @@ msgstr "" msgid "Add WLE" msgstr "" -#: templates/lgr_editor/codepoint_list.html:275 -msgid "Add Tags" -msgstr "" - #: templates/lgr_editor/codepoint_list.html:295 msgid "➡ Apply batch action..." msgstr "" @@ -656,23 +759,23 @@ msgstr "" msgid "Cannot import LGR file(s):" msgstr "" -#: templates/lgr_editor/label_forms.html:11 +#: templates/lgr_editor/label_forms.html:10 msgid "Display forms" msgstr "" -#: templates/lgr_editor/label_forms.html:18 +#: templates/lgr_editor/label_forms.html:16 msgid "Code point sequence" msgstr "" -#: templates/lgr_editor/label_forms.html:19 +#: templates/lgr_editor/label_forms.html:17 msgid "U-label" msgstr "" -#: templates/lgr_editor/label_forms.html:20 +#: templates/lgr_editor/label_forms.html:18 msgid "A-label" msgstr "" -#: templates/lgr_editor/metadata.html:11 +#: templates/lgr_editor/metadata.html:23 msgid "There was an error saving; please see error(s) below" msgstr "" @@ -774,215 +877,423 @@ msgid "" " Add it to a code point first to find it back in this list" msgstr "" -#: views.py:114 +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:7 +msgid "Erroneous conditional code points" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:11 +#, python-format +msgid "" +"Code point %(cp)s has invalid %(rule_type)s rule %(rule)s for variant " +"%(variant)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:18 +msgid "Conditional variants OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:7 +msgid "Missing code points or rules" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:11 +#, python-format +msgid "Code point %(cp)s:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:15 +#, python-format +msgid "Variant %(variant)s is not in repertoire" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:19 +#, python-format +msgid "%(variant)s has not original code point in its variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:23 +#, python-format +msgid "" +"%(variant)s has not symmetric %(rule_type)s rule %(rule)s on its symmetric " +"variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:27 +#, python-format +msgid "%(variant)s unknown symmetry problem, please report" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:35 +msgid "Symmetry OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:7 +msgid "Missing variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:11 +#, python-format +msgid "Code point %(cp)s is missing variant %(variant)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:18 +msgid "Transitivity OK" +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:7 +msgid "XML is valid and complies with RNG." +msgstr "" + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:9 +#, python-format +msgid "Invalid XML for lgr: %(res)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:6 +msgid "General stats" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:9 +#, python-format +msgid "Number of code points: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:15 +#, python-format +msgid "Number of ranges: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:21 +#, python-format +msgid "Largest range: %(largest)s (length: %(largest_len)s)" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:28 +#, python-format +msgid "Number of sequences: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:34 +#, python-format +msgid "Largest sequence: %(largest)s (length: %(largest_len)s)" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:41 +msgid "Variants" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:44 +#, python-format +msgid "Total number of variant mappings: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:49 +#, python-format +msgid "Average number of variants per code point: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:54 +#, python-format +msgid "Largest variant set: %(largest_set)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:60 +msgid "Variants per type:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:63 +#, python-format +msgid "Number of variants for type %(variant_type)s: %(number)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:74 +#, python-format +msgid "Number of code points for tag %(tag_name)s: %(number)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:82 +#, python-format +msgid "Number of defined rules: %(nbr)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:6 +#, python-format +msgid "Unicode version %(version)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:8 +#, python-format +msgid "Validating repertoire '%(repertoire)s'" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:13 +#, python-format +msgid "" +"Target Unicode version %(version)s differs from UnicodeDatabase %(database)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:19 +msgid "Possibly erroneous characters" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:23 +#, python-format +msgid "Character %(cp)s:" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:29 +#, python-format +msgid "Warning: %(warn)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:36 +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:49 +#, python-format +msgid "Error: %(err)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:43 +#, python-format +msgid "Variant: %(variant|render_char)s" +msgstr "" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:60 +msgid "LGR rebuild OK" +msgstr "" + +#: views.py:115 msgid "" "The LGR you have tried to create already exists in your working session. " "Please use a new name." msgstr "" -#: views.py:148 +#: views.py:149 msgid "" "The LGR you have tried to import already exists in your working session. " "Please rename it before importing it." msgstr "" -#: views.py:154 +#: views.py:155 msgid "" "The LGR you have tried to import already exists in your set. Please rename " "it before importing it." msgstr "" -#: views.py:177 +#: views.py:178 msgid "The LGR set name already exists. Please use another name." msgstr "" -#: views.py:289 +#: views.py:249 +msgid "Testing XML validity using RNG" +msgstr "" + +#: views.py:250 +msgid "Testing symmetry" +msgstr "" + +#: views.py:251 +msgid "Testing transitivity" +msgstr "" + +#: views.py:252 +msgid "Testing conditional variants" +msgstr "" + +#: views.py:253 +msgid "Generate stats" +msgstr "" + +#: views.py:254 +msgid "Rebuilding LGR" +msgstr "" + +#: views.py:302 #, python-format msgid "New code point %s added" msgstr "" -#: views.py:362 +#: views.py:375 msgid "Rule" msgstr "" -#: views.py:362 +#: views.py:375 msgid "Tag(s)" msgstr "" -#: views.py:363 +#: views.py:376 msgid "rule" msgstr "" -#: views.py:363 +#: views.py:376 msgid "tag(s)" msgstr "" -#: views.py:367 +#: views.py:380 #, python-format msgid "%(operation)s successfully added to %(nb_cp)s code point(s)" msgstr "" -#: views.py:372 +#: views.py:385 #, python-format msgid "%(nb_cp)s code points were not updated to avoid invalid %(operation)s" msgstr "" -#: views.py:504 +#: views.py:517 #, python-format -msgid "Automatically added codepoint %s from out-of-repertoire variant" +msgid "Automatically added codepoint %s from out-of-repertoire-var variant" msgstr "" -#: views.py:507 +#: views.py:520 #, python-format msgid "New variant %s added" msgstr "" -#: views.py:580 +#: views.py:593 msgid "Code point edited" msgstr "" -#: views.py:732 +#: views.py:745 msgid "Variants populated" msgstr "" -#: views.py:783 views.py:819 +#: views.py:798 views.py:834 msgid "References updated successfully" msgstr "" -#: views.py:822 +#: views.py:837 #, python-format msgid "" "Variant %(var_codepoint)s for code point %(codepoint)s with when=%(when)s " "and not-when=%(not_when)s could not be found" msgstr "" -#: views.py:858 +#: views.py:873 #, python-format msgid "Code point %s has been deleted" msgstr "" -#: views.py:880 +#: views.py:895 #, python-format msgid "Variant %(var_cp)s with when='%(when)s' and not-when='%(not_when)s'" msgstr "" -#: views.py:886 +#: views.py:901 #, python-format msgid "%(var_msg_prefix)s has been deleted" msgstr "" -#: views.py:889 +#: views.py:904 #, python-format msgid "%(var_msg_prefix)s could not be deleted because it was not found" msgstr "" -#: views.py:919 +#: views.py:934 msgid "New reference created" msgstr "" -#: views.py:1127 +#: views.py:1142 #, python-format msgid "" "References to tag %(tag)s have been removed from the repertoire. Do not " "forget to update any WLE that might reference it." msgstr "" -#: views.py:1195 views.py:1357 views.py:1441 +#: views.py:1210 views.py:1372 views.py:1460 msgid "No body specified" msgstr "" -#: views.py:1204 +#: views.py:1219 #, python-format msgid "Class \"%s\" does not exist" msgstr "" -#: views.py:1208 +#: views.py:1223 #, python-format msgid "Class \"%s\" deleted." msgstr "" -#: views.py:1213 +#: views.py:1228 msgid "No class element found" msgstr "" -#: views.py:1215 views.py:1377 +#: views.py:1230 views.py:1392 msgid "Name attribute must be present" msgstr "" -#: views.py:1219 views.py:1236 views.py:1381 views.py:1398 views.py:1465 -#: views.py:1478 +#: views.py:1234 views.py:1251 views.py:1405 views.py:1417 views.py:1484 +#: views.py:1497 #, python-format msgid "" "Encountered XML syntax error: %s (line number may be wrong, try subtracting " "one from the reported line number)" msgstr "" -#: views.py:1222 views.py:1239 views.py:1384 views.py:1401 views.py:1468 -#: views.py:1481 +#: views.py:1237 views.py:1254 views.py:1408 views.py:1420 views.py:1487 +#: views.py:1500 msgid "Your XML is not valid" msgstr "" -#: views.py:1227 +#: views.py:1242 #, python-format msgid "Class \"%s\" already exists" msgstr "" -#: views.py:1229 +#: views.py:1244 #, python-format msgid "Class \"%s\" saved." msgstr "" -#: views.py:1366 +#: views.py:1381 #, python-format msgid "Rule \"%s\" does not exist" msgstr "" -#: views.py:1370 +#: views.py:1385 #, python-format msgid "Rule \"%s\" deleted." msgstr "" -#: views.py:1375 +#: views.py:1390 msgid "No rule element found" msgstr "" -#: views.py:1389 +#: views.py:1397 #, python-format msgid "Rule \"%s\" already exists" msgstr "" -#: views.py:1391 +#: views.py:1410 #, python-format msgid "Rule \"%s\" saved." msgstr "" -#: views.py:1452 +#: views.py:1471 #, python-format msgid "Action \"%s\" does not exist" msgstr "" -#: views.py:1456 +#: views.py:1475 #, python-format msgid "Action \"%s\" deleted." msgstr "" -#: views.py:1461 +#: views.py:1480 msgid "No action element found" msgstr "" -#: views.py:1471 +#: views.py:1490 msgid "Action saved." msgstr "" -#: views.py:1540 views.py:1628 +#: views.py:1559 views.py:1647 #, python-format msgid "%d code points added" msgstr "" -#: views.py:1597 +#: views.py:1616 msgid "No code point in input file" msgstr "" -#: views.py:1903 +#: views.py:1922 msgid "Meta data saved" msgstr "" diff --git a/src/lgr_editor/locale/fr/LC_MESSAGES/django.mo b/src/lgr_editor/locale/fr/LC_MESSAGES/django.mo index 907f5a37..76593377 100644 Binary files a/src/lgr_editor/locale/fr/LC_MESSAGES/django.mo and b/src/lgr_editor/locale/fr/LC_MESSAGES/django.mo differ diff --git a/src/lgr_editor/locale/fr/LC_MESSAGES/django.po b/src/lgr_editor/locale/fr/LC_MESSAGES/django.po index c0f71a92..a358716b 100644 --- a/src/lgr_editor/locale/fr/LC_MESSAGES/django.po +++ b/src/lgr_editor/locale/fr/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-04 16:04+0000\n" -"PO-Revision-Date: 2018-09-04 11:47-0400\n" +"POT-Creation-Date: 2020-12-02 03:08+0000\n" +"PO-Revision-Date: 2020-12-01 22:10-0500\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 2.1.1\n" +"X-Generator: Poedit 2.4.1\n" #: forms/codepoint.py:14 templates/lgr_editor/codepoint_view.html:52 msgid "When" @@ -28,6 +28,7 @@ msgstr "Not When" #: forms/codepoint.py:16 templates/lgr_editor/_editor_base.html:31 #: templates/lgr_editor/codepoint_list.html:40 +#: templates/lgr_editor/validate_lgr/compute_stats.html:71 msgid "Tags" msgstr "Tags" @@ -73,7 +74,7 @@ msgstr "" "code point (%(first_cp)s)" #: forms/codepoints.py:78 forms/importer.py:14 forms/importer.py:27 -#: forms/metadata.py:50 +#: forms/metadata.py:55 msgid "Validating repertoire" msgstr "Répertoire de validation" @@ -101,6 +102,14 @@ msgstr "" msgid "File type" msgstr "Type de fichier" +#: forms/codepoints.py:135 forms/codepoints.py:136 +msgid "Cannot add when and not-when rules simultaneously" +msgstr "Impossible d'ajouter when et not-when simultanément" + +#: forms/codepoints.py:138 forms/codepoints.py:139 forms/codepoints.py:142 +msgid "Please provide at least one value" +msgstr "Fournissez au moins une valeur s'il vous plait" + #: forms/importer.py:13 msgid "Name" msgstr "Nom" @@ -129,79 +138,83 @@ msgstr "" msgid "The name of the set" msgstr "Nom du set" -#: forms/labels.py:14 +#: forms/labels.py:13 msgid "Label" msgstr "Label" -#: forms/labels.py:15 forms/metadata.py:46 +#: forms/labels.py:14 forms/metadata.py:50 msgid "Unicode version" msgstr "Version d'Unicode" -#: forms/labels.py:17 +#: forms/labels.py:16 msgid "The unicode version used" msgstr "Version d'Unicode" -#: forms/metadata.py:39 +#: forms/metadata.py:41 msgid "Version" msgstr "Version" -#: forms/metadata.py:40 +#: forms/metadata.py:42 msgid "Version comment" msgstr "Commentaire de version" -#: forms/metadata.py:41 +#: forms/metadata.py:43 msgid "Date" msgstr "Date" -#: forms/metadata.py:42 +#: forms/metadata.py:44 msgid "Scope" msgstr "Portée" -#: forms/metadata.py:43 +#: forms/metadata.py:46 msgid "Scope type" msgstr "Type de la portée" -#: forms/metadata.py:44 +#: forms/metadata.py:48 msgid "Validity start" msgstr "Début de la validité" -#: forms/metadata.py:45 +#: forms/metadata.py:49 msgid "Validity end" msgstr "Fin de la validité" -#: forms/metadata.py:47 templates/lgr_editor/codepoint_view.html:227 +#: forms/metadata.py:52 templates/lgr_editor/codepoint_view.html:227 #: templates/lgr_editor/references.html:14 #: templates/lgr_editor/references.html:51 msgid "Description" msgstr "Description" -#: forms/metadata.py:48 +#: forms/metadata.py:53 msgid "Description type" msgstr "Type de la description" -#: forms/metadata.py:53 +#: forms/metadata.py:58 msgid "Built-in" msgstr "Fournis" -#: forms/metadata.py:65 +#: forms/metadata.py:70 msgid "My LGRs" msgstr "Mes LGRs" -#: forms/metadata.py:75 +#: forms/metadata.py:80 msgid "Language" msgstr "Langage" -#: lgr_exceptions.py:25 +#: forms/references.py:33 +msgid "Invalid format" +msgstr "Format invalide" + +#: lgr_exceptions.py:28 #, python-format msgid "Input code point %(codepoint)s is not in the LGR" msgstr "Le code point %(codepoint)s n'est pas dans la LGR" -#: lgr_exceptions.py:29 +#: lgr_exceptions.py:32 #, python-format msgid "Input code point %(codepoint)s is not in the reference repertoire" msgstr "Le code point %(codepoint)s n'est pas dans le répertoire de référence" -#: lgr_exceptions.py:34 +#: lgr_exceptions.py:37 #, python-format msgid "" "Variant %(variant_codepoint)s already exists for code point %(codepoint)s" @@ -209,22 +222,22 @@ msgstr "" "La variante %(variant_codepoint)s existe déjà pour le code point " "%(codepoint)s" -#: lgr_exceptions.py:40 +#: lgr_exceptions.py:43 #, python-format msgid "Range %(first_cp)s - %(last_cp)s already exists in the LGR" msgstr "L'ensemble %(first_cp)s - %(last_cp)s existe déjà dans la LGR" -#: lgr_exceptions.py:45 +#: lgr_exceptions.py:48 #, python-format msgid "Input code point %(codepoint)s already exists in the LGR" msgstr "Le code point %(codepoint)s existe déjà dans la LGR" -#: lgr_exceptions.py:50 +#: lgr_exceptions.py:53 #, python-format msgid "Input code point %(codepoint)s is not in LGR script" msgstr "Le code point %(codepoint)s n'est pas dans le script de la LGR" -#: lgr_exceptions.py:54 +#: lgr_exceptions.py:57 #, python-format msgid "" "Input code point %(codepoint)s is not a PVALID/CONTEXTO/CONTEXTJ code point " @@ -233,18 +246,18 @@ msgstr "" "Le code point %(codepoint)s n'est pas un code point PVALID/CONTEXTO/CONTEXTJ " "d'après IDNA2008" -#: lgr_exceptions.py:59 +#: lgr_exceptions.py:62 #, python-format msgid "Code point %(codepoint)s has invalid context rule %(rule)s" msgstr "Le code point %(codepoint)s a une règle contextuelle invalide %(rule)s" -#: lgr_exceptions.py:64 +#: lgr_exceptions.py:67 #, python-format msgid "Range %(first_cp)s - %(last_cp)s has invalid context rule" msgstr "" "L'ensemble %(first_cp)s - %(last_cp)s a une règle contextuelle invalide" -#: lgr_exceptions.py:69 +#: lgr_exceptions.py:72 #, python-format msgid "" "Variant %(variant_codepoint)s of code point %(codepoint)shas invalid context " @@ -253,91 +266,202 @@ msgstr "" "La variante %(variant_codepoint)s du code point %(codepoint)s a une règle " "contextuelle invalide" -#: lgr_exceptions.py:75 +#: lgr_exceptions.py:78 #, python-format msgid "Duplicate reference for code point %(codepoint)s" msgstr "Référence dupliquée pour le code point %(codepoint)s" -#: lgr_exceptions.py:79 +#: lgr_exceptions.py:82 #, python-format msgid "Unspecified exception for input code point %(codepoint)s" msgstr "Exception non-spécifiée pour le code point d'entrée %(codepoint)s" -#: lgr_exceptions.py:86 +#: lgr_exceptions.py:89 msgid "Sequence cannot have a tag" msgstr "Les séquences ne peuvent pas avoir de tag" -#: lgr_exceptions.py:88 +#: lgr_exceptions.py:91 msgid "Invalid language" msgstr "Langage invalide" -#: lgr_exceptions.py:90 +#: lgr_exceptions.py:93 msgid "Invalid date value" msgstr "Date invalide" -#: lgr_exceptions.py:92 +#: lgr_exceptions.py:95 msgid "Invalid Unicode version" msgstr "Version d'unicode invalide" -#: lgr_exceptions.py:94 +#: lgr_exceptions.py:97 msgid "Invalid LGR XML file" msgstr "Fichier XML de LGR invalide" -#: lgr_exceptions.py:96 +#: lgr_exceptions.py:99 #, python-format msgid "Reference %(ref_id)s is not defined" msgstr "La référence %(ref_id)s n'est pas définie" -#: lgr_exceptions.py:100 +#: lgr_exceptions.py:103 #, python-format msgid "Reference %(ref_id)s already exists" msgstr "La référence %(ref_id)s existe déjà" -#: lgr_exceptions.py:104 +#: lgr_exceptions.py:107 #, python-format msgid "Invalid reference id %(ref_id)s " msgstr "Identifiant de référence invalide %(ref_id)s " -#: lgr_exceptions.py:108 +#: lgr_exceptions.py:111 #, python-format msgid "Rule \"%(rule_name)s\" cannot be processed (%(message)s)" msgstr "La règle \"%(rule_name)s\" ne peut pas être traitée (%(message)s)" -#: lgr_exceptions.py:113 +#: lgr_exceptions.py:116 msgid "Input parameter has invalid format" msgstr "Le paramètre d'entrée a un format invalide" -#: lgr_exceptions.py:115 +#: lgr_exceptions.py:118 msgid "A general exception occurred in the LGR API" msgstr "Une exception s'est produite dans l'API LGR" -#: lgr_exceptions.py:117 +#: lgr_exceptions.py:120 #, python-format msgid "LGR is not valid (%(args)s)" msgstr "La LGR n'est pas valide (%(args)s)" -#: lgr_exceptions.py:119 +#: lgr_exceptions.py:122 #, python-format msgid "Label %(label)s is not valid in the LGR (%(message)s)" msgstr "Label %(label)s n'est pas valide dans la LGR (%(message)s)" -#: lgr_exceptions.py:124 +#: lgr_exceptions.py:127 msgid "Input label file contains collision(s)" msgstr "Le fichier d'entrée des labels contient une/des collision(s)" -#: lgr_exceptions.py:126 +#: lgr_exceptions.py:129 msgid "The LGR contains a variant that do not have symmetric relations" msgstr "La LGR contient des variantes ne respectant pas la symmétrie" -#: lgr_exceptions.py:129 +#: lgr_exceptions.py:132 #, python-format msgid "The LGR does not contain a valid language (%(message)s)" msgstr "La LGR ne contient pas de langues valides (%(message)s)" -#: lgr_exceptions.py:131 +#: lgr_exceptions.py:134 +#, python-format +msgid "Cannot generate cross-script variant for LGR without (%(message)s)" +msgstr "" +"Impossible de générer les variantes cross-script pour la LGR sans " +"(%(message)s)" + +#: lgr_exceptions.py:138 msgid "An unknown exception occurred in the LGR API" msgstr "Une exception inconnue s'est produite dans l'API LGR" +#: lgr_exceptions.py:143 +msgid "Label is empty" +msgstr "Le label est vide" + +#: lgr_exceptions.py:145 +#, python-format +msgid "%(label)s is invalid due to its length being longer than 63 bytes." +msgstr "" +"le label %(label)s est invalide car sa longueur est supérieure à 63 octets." + +#: lgr_exceptions.py:150 +#, python-format +msgid "" +"%(label)s is invalid due to hypen restrictions in the RFC5891 as it starts " +"with a hyphen-minus." +msgstr "" +"le label %(label)s est invalide en raison des restrictions sur les traits " +"d'union dans la RFC5891 car il débute par le signe moins." + +#: lgr_exceptions.py:155 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it ends " +"with a hyphen-minus." +msgstr "" +"le label %(label)s est invalide en raison des restrictions sur les traits " +"d'union dans la RFC5891 car il termine par le signe moins." + +#: lgr_exceptions.py:160 +#, python-format +msgid "" +"%(label)s is invalid due to hyphen restrictions in the RFC5891 as it " +"contains hyphen-minus in the third and fourth positions." +msgstr "" +"le label %(label)s est invalide en raison des restrictions sur les traits " +"d'union dans la RFC5891 car contient le signe moins à la troisième et " +"quatrième position." + +#: lgr_exceptions.py:165 +#, python-format +msgid "" +"%(label)s is invalid due to leading combining marks restriction in the " +"RFC5891." +msgstr "" +"le label %(label)s est invalide en raison des restrictions sur signes " +"combinatoires de tête dans la RFC5891." + +#: lgr_exceptions.py:170 +#, python-format +msgid "%(label)s is invalid as it contains disallowed characters." +msgstr "" +"le label %(label)s est invalide car il contient des caractères interdits." + +#: lgr_exceptions.py:174 +#, python-format +msgid "" +"%(label)s is invalid as it starts with ‘xn--’ but does not contain valid " +"Punycode." +msgstr "" +"le label %(label)s est invalide car ils débute par 'xn--' et ne contient pas " +"de Punycode valide." + +#: lgr_exceptions.py:179 +#, python-format +msgid "%(label)s is invalid as it contains full stop (dot)." +msgstr "le label %(label)s est invalide car il contient un point final." + +#: lgr_exceptions.py:183 +#, python-format +msgid "%(label)s is invalid due to invalid Punycode." +msgstr "le label %(label)s est invalide en raison de Punycode invalide." + +#: lgr_exceptions.py:185 +#, python-format +msgid "%(label)s is invalid due to the Bidi rule in the RFC5893." +msgstr "" +"le label %(label)s est invalide en raison de la règle Bidi dans la RFC5893." + +#: lgr_exceptions.py:189 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for Zero Width Joiner." +msgstr "" +"le label %(label)s est invalide en raison de la règle IDNA contextuelle pour " +"les liant sans chasse (Zero Width Joiner)." + +#: lgr_exceptions.py:194 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for punctuation in the " +"RFC5892." +msgstr "" +"le label %(label)s est invalide en raison de la règle IDNA contextuelle pour " +"la ponctuation ans la RFC5892." + +#: lgr_exceptions.py:199 +#, python-format +msgid "" +"%(label)s is invalid due to the IDNA contextual rule for digits in the " +"RFC5892." +msgstr "" +"le label %(label)s est invalide en raison de la règle IDNA contextuelle pour " +"les chiffres ans la RFC5892." + #: templates/lgr_editor/_editor_base.html:25 #: templates/lgr_editor/codepoint_view.html:54 msgid "References" @@ -349,6 +473,7 @@ msgstr "Métadonnées" #: templates/lgr_editor/_editor_base.html:34 templates/lgr_editor/rules.html:18 #: templates/lgr_editor/rules_edit.html:57 +#: templates/lgr_editor/validate_lgr/compute_stats.html:79 msgid "Rules" msgstr "Règles" @@ -368,7 +493,7 @@ msgstr "%(lgr_name)s" #: templates/lgr_editor/_rule_editor_widgets.html:5 #: templates/lgr_editor/codepoint_view.html:244 -#: templates/lgr_editor/metadata.html:32 +#: templates/lgr_editor/metadata.html:45 #: templates/lgr_editor/rules_edit.html:40 #: templates/lgr_editor/rules_edit.html:71 #: templates/lgr_editor/rules_edit.html:103 @@ -376,7 +501,7 @@ msgid "Cancel" msgstr "Annuler" #: templates/lgr_editor/_rule_editor_widgets.html:8 -#: templates/lgr_editor/metadata.html:33 +#: templates/lgr_editor/metadata.html:46 #: templates/lgr_editor/references.html:39 #: templates/lgr_editor/rules_edit.html:43 #: templates/lgr_editor/rules_edit.html:74 @@ -467,7 +592,6 @@ msgid "Action" msgstr "Action" #: templates/lgr_editor/codepoint_list.html:52 -#: templates/lgr_editor/codepoint_list.html:82 msgid "Add Rule" msgstr "Ajouter une règle" @@ -491,6 +615,11 @@ msgstr "" " code point(s)

\n" " " +#: templates/lgr_editor/codepoint_list.html:82 +#: templates/lgr_editor/codepoint_list.html:275 +msgid "Add Tags" +msgstr "Ajouter des Tags" + #: templates/lgr_editor/codepoint_list.html:87 msgid "" "\n" @@ -541,10 +670,6 @@ msgstr "" msgid "Add WLE" msgstr "Ajouter une WLE" -#: templates/lgr_editor/codepoint_list.html:275 -msgid "Add Tags" -msgstr "Ajouter des Tags" - #: templates/lgr_editor/codepoint_list.html:295 msgid "➡ Apply batch action..." msgstr "➡ Appliquer action par lots..." @@ -699,23 +824,23 @@ msgstr "" msgid "Cannot import LGR file(s):" msgstr "Impossible d'importer le(s) fichier(s) LGR :" -#: templates/lgr_editor/label_forms.html:11 +#: templates/lgr_editor/label_forms.html:10 msgid "Display forms" msgstr "Afficher les formes" -#: templates/lgr_editor/label_forms.html:18 +#: templates/lgr_editor/label_forms.html:16 msgid "Code point sequence" msgstr "Séquence de code points" -#: templates/lgr_editor/label_forms.html:19 +#: templates/lgr_editor/label_forms.html:17 msgid "U-label" msgstr "U-Label" -#: templates/lgr_editor/label_forms.html:20 +#: templates/lgr_editor/label_forms.html:18 msgid "A-label" msgstr "A-Label" -#: templates/lgr_editor/metadata.html:11 +#: templates/lgr_editor/metadata.html:23 msgid "There was an error saving; please see error(s) below" msgstr "" "Il y a eu une erreur lors de la sauvegarde, merci de regarder ci-dessous" @@ -821,7 +946,197 @@ msgstr "" " Ajouter le tag à un code point afin de le retrouver dans " "cette list" -#: views.py:114 +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:7 +msgid "Erroneous conditional code points" +msgstr "Erreur dans les code points conditionels" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:11 +#, python-format +msgid "" +"Code point %(cp)s has invalid %(rule_type)s rule %(rule)s for variant " +"%(variant)s" +msgstr "" +"Le code point %(cp)s a la règle %(rule_type)s %(rule)s invalide pour les " +"variantes %(variant)s" + +#: templates/lgr_editor/validate_lgr/check_conditional_variants.html:18 +msgid "Conditional variants OK" +msgstr "Variantes conditionnelles OK" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:7 +msgid "Missing code points or rules" +msgstr "Code points ou règles manquants" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:11 +#, python-format +msgid "Code point %(cp)s:" +msgstr "Code point %(cp)s:" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:15 +#, python-format +msgid "Variant %(variant)s is not in repertoire" +msgstr "La variante %(variant)s n'est pas dans le répertoire" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:19 +#, python-format +msgid "%(variant)s has not original code point in its variants" +msgstr "%(variant)s n'a pas le code point original dans ses variantes" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:23 +#, python-format +msgid "" +"%(variant)s has not symmetric %(rule_type)s rule %(rule)s on its symmetric " +"variants" +msgstr "" +"%(variant)s n'a pas la règle %(rule_type)s %(rule)s dans ses variantes " +"symmétriques" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:27 +#, python-format +msgid "%(variant)s unknown symmetry problem, please report" +msgstr "" +"%(variant)s problème de symétrie inconnu, veuillez contacter le support" + +#: templates/lgr_editor/validate_lgr/check_symmetry.html:35 +msgid "Symmetry OK" +msgstr "Symétrie OK" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:7 +msgid "Missing variants" +msgstr "Variantes manquantes" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:11 +#, python-format +msgid "Code point %(cp)s is missing variant %(variant)s" +msgstr "Le code point %(cp)s n'a pas la variante %(variant)s" + +#: templates/lgr_editor/validate_lgr/check_transitivity.html:18 +msgid "Transitivity OK" +msgstr "Transitivité OK" + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:7 +msgid "XML is valid and complies with RNG." +msgstr "XML valide et conforme au RNG." + +#: templates/lgr_editor/validate_lgr/check_xml_validity.html:9 +#, python-format +msgid "Invalid XML for lgr: %(res)s" +msgstr "Fichier XML invalide pour la LGR: %(res)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:6 +msgid "General stats" +msgstr "Statistiques générales" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:9 +#, python-format +msgid "Number of code points: %(nbr)s" +msgstr "Nombre de code points: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:15 +#, python-format +msgid "Number of ranges: %(nbr)s" +msgstr "Nombre d'intervalles: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:21 +#, python-format +msgid "Largest range: %(largest)s (length: %(largest_len)s)" +msgstr "Plus grand intervalle: %(largest)s (longueur: %(largest_len)s)" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:28 +#, python-format +msgid "Number of sequences: %(nbr)s" +msgstr "Nombre de séquences: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:34 +#, python-format +msgid "Largest sequence: %(largest)s (length: %(largest_len)s)" +msgstr "Plus grande séquence: %(largest)s (longueur: %(largest_len)s)" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:41 +msgid "Variants" +msgstr "Variante(s)" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:44 +#, python-format +msgid "Total number of variant mappings: %(nbr)s" +msgstr "Nombre total de variantes mappées: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:49 +#, python-format +msgid "Average number of variants per code point: %(nbr)s" +msgstr "Nombre moyen de variantes par code point: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:54 +#, python-format +msgid "Largest variant set: %(largest_set)s" +msgstr "Plus grand ensemble de variantes: %(largest_set)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:60 +msgid "Variants per type:" +msgstr "Variantes par type:" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:63 +#, python-format +msgid "Number of variants for type %(variant_type)s: %(number)s" +msgstr "Nombre de variantes pour le type %(variant_type)s: %(number)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:74 +#, python-format +msgid "Number of code points for tag %(tag_name)s: %(number)s" +msgstr "Nombre de code points pour le tag %(tag_name)s: %(number)s" + +#: templates/lgr_editor/validate_lgr/compute_stats.html:82 +#, python-format +msgid "Number of defined rules: %(nbr)s" +msgstr "Nombre de règles définies: %(nbr)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:6 +#, python-format +msgid "Unicode version %(version)s" +msgstr "Version d'Unicode %(version)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:8 +#, python-format +msgid "Validating repertoire '%(repertoire)s'" +msgstr "Répertoire de validation '%(repertoire)s'" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:13 +#, python-format +msgid "" +"Target Unicode version %(version)s differs from UnicodeDatabase %(database)s" +msgstr "" +"La version Unicode cible %(version)s diffère de UnicodeDatabase %(database)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:19 +msgid "Possibly erroneous characters" +msgstr "Caractères possiblement erronés" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:23 +#, python-format +msgid "Character %(cp)s:" +msgstr "Caractère %(cp)s:" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:29 +#, python-format +msgid "Warning: %(warn)s" +msgstr "Attention : %(warn)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:36 +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:49 +#, python-format +msgid "Error: %(err)s" +msgstr "Erreur: %(err)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:43 +#, python-format +msgid "Variant: %(variant|render_char)s" +msgstr "Variante: %(variant|render_char)s" + +#: templates/lgr_editor/validate_lgr/rebuild_lgr.html:60 +msgid "LGR rebuild OK" +msgstr "Reconstruction de la LGR OK" + +#: views.py:115 msgid "" "The LGR you have tried to create already exists in your working session. " "Please use a new name." @@ -829,7 +1144,7 @@ msgstr "" "La LGR que vous essayez de créer existe déjà dans votre session de travail. " "Merci d'utiliser un nouveau nom." -#: views.py:148 +#: views.py:149 msgid "" "The LGR you have tried to import already exists in your working session. " "Please rename it before importing it." @@ -837,7 +1152,7 @@ msgstr "" "La LGR que vous essayez d'importer existe déjà dans votre session de " "travail. Merci de renommer le fichier avant de l'importer." -#: views.py:154 +#: views.py:155 msgid "" "The LGR you have tried to import already exists in your set. Please rename " "it before importing it." @@ -845,67 +1160,91 @@ msgstr "" "La LGR que vous essayez d'importer existe déjà dans votre ensemble. Merci de " "renommer le fichier avant de l'importer." -#: views.py:177 +#: views.py:178 msgid "The LGR set name already exists. Please use another name." msgstr "Ce nom de set LGR existe déjà. Merci d'utiliser un autre nom." -#: views.py:289 +#: views.py:249 +msgid "Testing XML validity using RNG" +msgstr "Validation du XML par le RNG" + +#: views.py:250 +msgid "Testing symmetry" +msgstr "Test de la symmétrie" + +#: views.py:251 +msgid "Testing transitivity" +msgstr "Test de la transitivité" + +#: views.py:252 +msgid "Testing conditional variants" +msgstr "Test des variantes conditionnelles" + +#: views.py:253 +msgid "Generate stats" +msgstr "Génération des statistiques" + +#: views.py:254 +msgid "Rebuilding LGR" +msgstr "Reconstruction de la LGR" + +#: views.py:302 #, python-format msgid "New code point %s added" msgstr "Nouveau code point ajouté %s" -#: views.py:362 +#: views.py:375 msgid "Rule" msgstr "Règle" -#: views.py:362 +#: views.py:375 msgid "Tag(s)" msgstr "Tag(s)" -#: views.py:363 +#: views.py:376 msgid "rule" msgstr "règle" -#: views.py:363 +#: views.py:376 msgid "tag(s)" msgstr "tag(s)" -#: views.py:367 +#: views.py:380 #, python-format msgid "%(operation)s successfully added to %(nb_cp)s code point(s)" msgstr "%(operation)s ajouté(s) avec succès à %(nb_cp)s code point(s)" -#: views.py:372 +#: views.py:385 #, python-format msgid "%(nb_cp)s code points were not updated to avoid invalid %(operation)s" msgstr "" "%(nb_cp)s code points n'ont pas été mis à jour pour éviter des %(operation)s " "invalides" -#: views.py:504 +#: views.py:517 #, python-format -msgid "Automatically added codepoint %s from out-of-repertoire variant" +msgid "Automatically added codepoint %s from out-of-repertoire-var variant" msgstr "" "Code point %s automatiquement ajouté depuis une variante hors-répertoire" -#: views.py:507 +#: views.py:520 #, python-format msgid "New variant %s added" msgstr "Nouvelle variante %s ajoutée" -#: views.py:580 +#: views.py:593 msgid "Code point edited" msgstr "Code point modifié" -#: views.py:732 +#: views.py:745 msgid "Variants populated" msgstr "Les variantes ont été peuplées" -#: views.py:783 views.py:819 +#: views.py:798 views.py:834 msgid "References updated successfully" msgstr "Les références ont été correctement mises à jour" -#: views.py:822 +#: views.py:837 #, python-format msgid "" "Variant %(var_codepoint)s for code point %(codepoint)s with when=%(when)s " @@ -914,33 +1253,33 @@ msgstr "" "La variante %(var_codepoint)s du code point %(codepoint)s avec when=" "%(when)s et not-when=%(not_when)s n'a pas été trouvée" -#: views.py:858 +#: views.py:873 #, python-format msgid "Code point %s has been deleted" msgstr "Le code point %s a été supprimé" -#: views.py:880 +#: views.py:895 #, python-format msgid "Variant %(var_cp)s with when='%(when)s' and not-when='%(not_when)s'" msgstr "" "La variante %(var_cp)s avec when='%(when)s' and not-when='%(not_when)s'" -#: views.py:886 +#: views.py:901 #, python-format msgid "%(var_msg_prefix)s has been deleted" msgstr "%(var_msg_prefix)s a été supprimée" -#: views.py:889 +#: views.py:904 #, python-format msgid "%(var_msg_prefix)s could not be deleted because it was not found" msgstr "" "%(var_msg_prefix)s n'a pas pu être supprimée car elle n'a pas été trouvée" -#: views.py:919 +#: views.py:934 msgid "New reference created" msgstr "Nouvelle référence créée" -#: views.py:1127 +#: views.py:1142 #, python-format msgid "" "References to tag %(tag)s have been removed from the repertoire. Do not " @@ -949,30 +1288,30 @@ msgstr "" "Les références au %(tag)s ont été supprimées du répertoire. N'oubliez pas de " "mettre à jour les WLE qui pourraient les utiliser." -#: views.py:1195 views.py:1357 views.py:1441 +#: views.py:1210 views.py:1372 views.py:1460 msgid "No body specified" msgstr "Aucun contenu spécifié" -#: views.py:1204 +#: views.py:1219 #, python-format msgid "Class \"%s\" does not exist" msgstr "La classe \"%s\" n'existe pas" -#: views.py:1208 +#: views.py:1223 #, python-format msgid "Class \"%s\" deleted." msgstr "Classe \"%s\" supprimée." -#: views.py:1213 +#: views.py:1228 msgid "No class element found" msgstr "Aucune classe trouvée" -#: views.py:1215 views.py:1377 +#: views.py:1230 views.py:1392 msgid "Name attribute must be present" msgstr "L'attribut name est obligatoire" -#: views.py:1219 views.py:1236 views.py:1381 views.py:1398 views.py:1465 -#: views.py:1478 +#: views.py:1234 views.py:1251 views.py:1405 views.py:1417 views.py:1484 +#: views.py:1497 #, python-format msgid "" "Encountered XML syntax error: %s (line number may be wrong, try subtracting " @@ -981,72 +1320,86 @@ msgstr "" "Erreur de syntaxe XML : %s (le numéro de ligne peut-être incorrect, essayer " "de soustraire un au numéro reporté)" -#: views.py:1222 views.py:1239 views.py:1384 views.py:1401 views.py:1468 -#: views.py:1481 +#: views.py:1237 views.py:1254 views.py:1408 views.py:1420 views.py:1487 +#: views.py:1500 msgid "Your XML is not valid" msgstr "Votre XML n'est pas valide" -#: views.py:1227 +#: views.py:1242 #, python-format msgid "Class \"%s\" already exists" msgstr "La classe \"%s\" existe déjà" -#: views.py:1229 +#: views.py:1244 #, python-format msgid "Class \"%s\" saved." msgstr "Classe \"%s\" sauvegardée." -#: views.py:1366 +#: views.py:1381 #, python-format msgid "Rule \"%s\" does not exist" msgstr "La règle \"%s\" n'existe pas" -#: views.py:1370 +#: views.py:1385 #, python-format msgid "Rule \"%s\" deleted." msgstr "Règle \"%s\" supprimée." -#: views.py:1375 +#: views.py:1390 msgid "No rule element found" msgstr "Aucune règle trouvée" -#: views.py:1389 +#: views.py:1397 #, python-format msgid "Rule \"%s\" already exists" msgstr "La règle \"%s\" existe déjà" -#: views.py:1391 +#: views.py:1410 #, python-format msgid "Rule \"%s\" saved." msgstr "Règle \"%s\" sauvegardée." -#: views.py:1452 +#: views.py:1471 #, python-format msgid "Action \"%s\" does not exist" msgstr "Action \"%s\" n'existe pas" -#: views.py:1456 +#: views.py:1475 #, python-format msgid "Action \"%s\" deleted." msgstr "Action \"%s\" supprimée." -#: views.py:1461 +#: views.py:1480 msgid "No action element found" msgstr "Aucune action trouvée" -#: views.py:1471 +#: views.py:1490 msgid "Action saved." msgstr "Action sauvée." -#: views.py:1540 views.py:1628 +#: views.py:1559 views.py:1647 #, python-format msgid "%d code points added" msgstr "%d code points ont été ajoutés" -#: views.py:1597 +#: views.py:1616 msgid "No code point in input file" msgstr "Le fichier d'entrée ne contient aucun code point" -#: views.py:1903 +#: views.py:1922 msgid "Meta data saved" msgstr "Metadonnées sauvegardées" + +#, fuzzy +#~| msgid "Description" +#~ msgid "%(description)s" +#~ msgstr "Description" + +#~ msgid " with Unicode version {}" +#~ msgstr " avec la version d'Unicode {}" + +#~ msgid " and validating repertoire '{}'" +#~ msgstr " et le repertoire de validation '{}'" + +#~ msgid " " +#~ msgstr " " diff --git a/src/lgr_editor/repertoires.py b/src/lgr_editor/repertoires.py index 398e7f9e..04abee39 100644 --- a/src/lgr_editor/repertoires.py +++ b/src/lgr_editor/repertoires.py @@ -12,26 +12,45 @@ from lgr.parser.xml_parser import XMLParser from .utils import list_validating_repertoires +from . import unidb + +from django.core.cache import cache logger = logging.getLogger(__name__) -REPERTOIRES = {} -SCRIPTS = {} +REPERTOIRE_CACHE_KEY = 'validating-repertoire' +SCRIPTS_CACHE_KEY = 'scripts' +CACHE_TIMEOUT = 3600*24*30 -def get_by_name(repertoire_name): - if repertoire_name not in REPERTOIRES: - logger.debug("%s parsing file", repertoire_name) +def get_by_name(repertoire_name, with_unidb=False): + repertoire_cache_key = "{}{}".format(REPERTOIRE_CACHE_KEY, repertoire_name) + repertoire = cache.get(repertoire_cache_key) + logger.debug("Get repertoire by name %s", repertoire_name) + if not repertoire: + logger.info("%s parsing file as not in cache", repertoire_name) repertoire_path = os.path.join(settings.REPERTOIRE_STORAGE_LOCATION, '{}.xml'.format(repertoire_name)) parser = XMLParser(repertoire_path, repertoire_name) - doc = parser.parse_document() - doc.expand_ranges() # need to get through all code points - REPERTOIRES[repertoire_name] = doc + if with_unidb: + unicode_version = parser.unicode_version() + parser.unicode_database = unidb.manager.get_db_by_version(unicode_version) + repertoire = parser.parse_document() + repertoire.expand_ranges() # need to get through all code points + cache.set(repertoire_cache_key, repertoire, CACHE_TIMEOUT) + elif with_unidb: + # need to retrieve unicode database as it is not retrieved from cache + unicode_version = repertoire.metadata.unicode_version + repertoire.unicode_database = unidb.manager.get_db_by_version(unicode_version) - return REPERTOIRES[repertoire_name] + return repertoire def get_all_scripts_from_repertoire(unicode_database): - if unicode_database not in SCRIPTS: + # XXX should we add database class name in cache key? + scripts_cache_key = "{}:{}".format(SCRIPTS_CACHE_KEY, unicode_database.get_unicode_version()) + scripts = cache.get(scripts_cache_key) + logger.debug("Get scripts for Unicode %s", unicode_database.get_unicode_version()) + if not scripts: + logger.info("Scripts not in cache") scripts = set() for rep in list_validating_repertoires(): validating_repertoire = get_by_name(rep) @@ -46,6 +65,6 @@ def get_all_scripts_from_repertoire(unicode_database): unicode_database.get_unicode_version(), e) - SCRIPTS[unicode_database] = scripts + cache.set(scripts_cache_key, scripts, CACHE_TIMEOUT) - return SCRIPTS[unicode_database] + return scripts diff --git a/src/lgr_editor/templates/lgr_editor/_form_field.html b/src/lgr_editor/templates/lgr_editor/_form_field.html index 41c479b1..9c61768c 100644 --- a/src/lgr_editor/templates/lgr_editor/_form_field.html +++ b/src/lgr_editor/templates/lgr_editor/_form_field.html @@ -1,8 +1,11 @@ {% load widget_tweaks %}
-
- {{ field|add_class:"form-control" }} +
+ {{ field|add_class:"form-control" }} + {% if field.field.widget.input_type == 'text' %} + + {% endif %} {% if field.errors %} {% for error in field.errors %}{{ error }}{% endfor %} @@ -14,3 +17,8 @@ {% endif %}
+ \ No newline at end of file diff --git a/src/lgr_editor/templates/lgr_editor/codepoint_list.html b/src/lgr_editor/templates/lgr_editor/codepoint_list.html index e7ca933c..b4b6e091 100644 --- a/src/lgr_editor/templates/lgr_editor/codepoint_list.html +++ b/src/lgr_editor/templates/lgr_editor/codepoint_list.html @@ -79,7 +79,7 @@