From 7304f18d39c3142ae6960e0657857935398351ff Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Mon, 10 May 2021 18:09:04 +0200 Subject: [PATCH 01/65] global: add config option to make userprofiles read-only --- invenio_userprofiles/config.py | 3 +++ .../templates/invenio_userprofiles/settings/_macros.html | 4 ++-- .../templates/invenio_userprofiles/settings/profile.html | 7 +++++-- .../invenio_userprofiles/settings/_macros.html | 4 ++-- .../invenio_userprofiles/settings/profile.html | 9 ++++++--- invenio_userprofiles/views.py | 6 +++++- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/invenio_userprofiles/config.py b/invenio_userprofiles/config.py index b5f6920..fc947c9 100644 --- a/invenio_userprofiles/config.py +++ b/invenio_userprofiles/config.py @@ -28,3 +28,6 @@ USERPROFILES_SETTINGS_TEMPLATE = None """Settings base templates for user profile module.""" + +USERPROFILES_READ_ONLY = False +"""Make the user profiles read-only.""" diff --git a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html index 75ca0bf..bbf20a3 100644 --- a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html +++ b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html @@ -7,11 +7,11 @@ under the terms of the MIT License; see LICENSE file for more details. #} -{% macro render_field(field, icon="", placeholder='', autofocus=False) %} +{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True) %}
{{ field.label }} {%- set extras = dict(autofocus="") if autofocus else dict() %} - {{field(class_="form-control", placeholder=placeholder, **extras)}} + {{field(class_="form-control", disabled=not enabled, placeholder=placeholder, **extras)}} {%- if icon %} {%- endif %} diff --git a/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html index f2424f1..9fea583 100644 --- a/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html @@ -24,17 +24,20 @@ {%- endif %} {%- set form = profile_form %} +{%- set read_only = config.USERPROFILES_READ_ONLY %}
{%- for field in form %} {%- if field.widget.input_type == 'hidden' %} {{ field() }} -{%- else %} -{{ render_field(field, autofocus=True, placeholder=field.label.text) }} +{%- elif not read_only or "repeat" not in field.id %} +{{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} {%- endif %} {%- endfor %} +{%- if not read_only %}
{{ _('Cancel') }}
+{%- endif %}
{%- endblock settings_form %} diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html index 1334a49..0545314 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html @@ -7,11 +7,11 @@ under the terms of the MIT License; see LICENSE file for more details. #} -{% macro render_field(field, icon="", placeholder='', autofocus=False) %} +{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True) %}
{{ field.label }} {%- set extras = dict(autofocus="") if autofocus else dict() %} - {{field(class_="form-control", placeholder=placeholder, **extras)}} + {{field(class_="form-control", disabled=not enabled, placeholder=placeholder, **extras)}} {%- if icon %} {%- endif %} diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html index d172101..277c6b4 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html @@ -24,17 +24,20 @@ {%- endif %} {%- set form = profile_form %} -
+{%- set read_only = config.USERPROFILES_READ_ONLY %} + {%- for field in form %} {%- if field.widget.input_type == 'hidden' %} {{ field() }} - {%- else %} - {{ render_field(field, autofocus=True, placeholder=field.label.text) }} + {%- elif not read_only or "repeat" not in field.id %} + {{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} {%- endif %} {%- endfor %} + {%- if not read_only %}
{{ _('Cancel') }}
+ {%- endif %}
{%- endblock settings_form %} diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 919ab67..06cec3b 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -95,8 +95,9 @@ def profile(): profile_form = profile_form_factory() # Process forms + is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) form = request.form.get('submit', None) - if form == 'profile': + if form == 'profile' and not is_read_only: handle_profile_form(profile_form) elif form == 'verification': handle_verification_form(verification_form) @@ -136,6 +137,9 @@ def handle_verification_form(form): def handle_profile_form(form): """Handle profile update form.""" + if current_app.config.get("USERPROFILES_READ_ONLY", False): + return + form.process(formdata=request.form) if form.validate_on_submit(): From bc4942c7a812b50154d150c4d9118218f4aaf3ee Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Mon, 10 May 2021 18:12:44 +0200 Subject: [PATCH 02/65] setup: bump requirements --- setup.py | 8 +++++--- tests/conftest.py | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index edb93bd..43df721 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,8 @@ history = open('CHANGES.rst').read() tests_require = [ - 'pytest-invenio>=1.4.0', + 'pytest-invenio>=1.4.2', + 'SQLAlchemy-Continuum>=1.2.1', ] extras_require = { @@ -26,7 +27,7 @@ 'invenio-admin>=1.2.0', ], 'docs': [ - 'Sphinx>=1.4.2,<3.0.0', + 'Sphinx>=3.0.0,<3.4.2', 'invenio-mail>=1.0.0', ], 'mysql': [ @@ -53,12 +54,13 @@ ] install_requires = [ + 'Flask>=1.1.0,<2.0.0', 'Flask-Breadcrumbs>=0.5.0', 'Flask-Mail>=0.9.1', 'Flask-Menu>=0.5.0', 'Flask-WTF>=0.14.3', 'invenio-accounts>=1.2.1', - 'invenio-base>=1.2.2', + 'invenio-base>=1.2.4', 'invenio-i18n>=1.2.0', 'invenio-theme>=1.3.4', ] diff --git a/tests/conftest.py b/tests/conftest.py index 0962f14..bc7f7c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -46,6 +46,7 @@ def base_app(): TESTING=True, WTF_CSRF_ENABLED=False, ) + Babel(base_app) Mail(base_app) Menu(base_app) From 2cb88fe838ea7a8f59d96f4a171ba6e46629940c Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Tue, 11 May 2021 19:46:19 +0200 Subject: [PATCH 03/65] tests: fix tests and modernize fixtures --- setup.py | 6 +++--- tests/conftest.py | 22 +++++++++++++++------- tests/test_invenio_userprofile.py | 6 ++++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/setup.py b/setup.py index 43df721..b180e6c 100644 --- a/setup.py +++ b/setup.py @@ -31,13 +31,13 @@ 'invenio-mail>=1.0.0', ], 'mysql': [ - 'invenio-db[mysql]>=1.0.5', + 'invenio-db[mysql]>=1.0.9', ], 'postgresql': [ - 'invenio-db[postgresql]>=1.0.5', + 'invenio-db[postgresql]>=1.0.9', ], 'sqlite': [ - 'invenio-db>=1.0.5', + 'invenio-db>=1.0.9', ], 'tests': tests_require, } diff --git a/tests/conftest.py b/tests/conftest.py index bc7f7c9..e4ef8ea 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,13 +29,11 @@ from invenio_userprofiles.views import blueprint_ui_init -@pytest.yield_fixture() -def base_app(): - """Flask application fixture.""" - instance_path = tempfile.mkdtemp() - base_app = Flask(__name__, instance_path=instance_path) - - base_app.config.update( +@pytest.fixture(scope='module') +def app_config(app_config): + """Override pytest-invenio app_config fixture.""" + app_config.update( + ACCOUNTS_LOCAL_LOGIN_ENABLED=True, ACCOUNTS_USE_CELERY=False, LOGIN_DISABLED=False, SECRET_KEY='testing_key', @@ -47,6 +45,16 @@ def base_app(): WTF_CSRF_ENABLED=False, ) + return app_config + + +@pytest.yield_fixture() +def base_app(app_config): + """Flask application fixture.""" + instance_path = tempfile.mkdtemp() + base_app = Flask(__name__, instance_path=instance_path) + base_app.config.update(app_config) + Babel(base_app) Mail(base_app) Menu(base_app) diff --git a/tests/test_invenio_userprofile.py b/tests/test_invenio_userprofile.py index e7a3155..ed6209c 100644 --- a/tests/test_invenio_userprofile.py +++ b/tests/test_invenio_userprofile.py @@ -31,7 +31,8 @@ def test_init(): """Test extension initialization.""" app = Flask('testapp') app.config.update( - ACCOUNTS_USE_CELERY=False + ACCOUNTS_USE_CELERY=False, + SECRET_KEY="test_key", ) Babel(app) Mail(app) @@ -43,7 +44,8 @@ def test_init(): app = Flask('testapp') app.config.update( - ACCOUNTS_USE_CELERY=False + ACCOUNTS_USE_CELERY=False, + SECRET_KEY="test_key", ) Babel(app) Mail(app) From 11730449546f369a3c6503f5e57e6e7bdb097e48 Mon Sep 17 00:00:00 2001 From: Nicola Tarocco Date: Mon, 17 May 2021 18:06:21 +0200 Subject: [PATCH 04/65] release: v1.2.2 --- CHANGES.rst | 6 +++++- invenio_userprofiles/version.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 050d602..1f8d3e4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,7 +8,11 @@ Changes ======= -Version 1.2.0 (released 2020-12-17) +Version 1.2.2 (released 2021-05-17) + +- Add config option to make user profiles form read-only + +Version 1.2.1 (released 2020-12-17) - Add theme dependent icons. diff --git a/invenio_userprofiles/version.py b/invenio_userprofiles/version.py index 7356ff3..75e21f1 100644 --- a/invenio_userprofiles/version.py +++ b/invenio_userprofiles/version.py @@ -14,4 +14,4 @@ from __future__ import absolute_import, print_function -__version__ = '1.2.1' +__version__ = '1.2.2' From f662b7bcd2feb8be459696974ede4b1a7a3fade1 Mon Sep 17 00:00:00 2001 From: mb-wali Date: Tue, 8 Jun 2021 16:15:23 +0200 Subject: [PATCH 05/65] i18n: adds german translations --- AUTHORS.rst | 1 + .../translations/de/LC_MESSAGES/messages.po | 136 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 invenio_userprofiles/translations/de/LC_MESSAGES/messages.po diff --git a/AUTHORS.rst b/AUTHORS.rst index 60255e4..fd1634e 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -24,3 +24,4 @@ Contributors - Sebastian Witowski - Tibor Simko - Vaibhav Gupta +- Mojib Wali diff --git a/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po new file mode 100644 index 0000000..39fb54f --- /dev/null +++ b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po @@ -0,0 +1,136 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2020 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2020. +# +# Translators: +# Alizee Pace , 2016 +# Tibor Simko , 2016 +# Mojib Wali , 2021 +# Chriz Uniba , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 1.2.0a3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2020-07-20 15:31+0300\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Chriz Uniba , 2021\n" +"Language-Team: German (https://www.transifex.com/inveniosoftware/teams/23537/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.8.0\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/admin.py:45 invenio_userprofiles/forms.py:48 +msgid "Username" +msgstr "Benutzername" + +#: invenio_userprofiles/admin.py:52 +msgid "User Management" +msgstr "Benutzerverwaltung" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:50 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Erforderlich. %(username_rules)s" + +#: invenio_userprofiles/forms.py:52 +msgid "Username not provided." +msgstr "Benutzername nicht angegeben." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:57 +msgid "Full name" +msgstr "Vollständiger Name" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:73 +msgid "Username already exists." +msgstr "Benutzername existiert bereits." + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:83 +msgid "Email address" +msgstr "E-Mail-Adresse" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:95 +msgid "Re-enter email address" +msgstr "E-Mail-Adresse erneut eingeben" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:97 +msgid "Please re-enter your email address." +msgstr "Bitte geben Sie Ihre E-Mail-Adresse erneut ein." + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:102 +msgid "Email addresses do not match." +msgstr "Die E-Mail-Adressen stimmen nicht überein." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:111 +msgid "Resend verification email" +msgstr "Verifizierungs-E-Mail erneut senden" + +#: invenio_userprofiles/validators.py:20 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"Der Benutzername muss mit einem Buchstaben beginnen, mindestens drei Zeichen" +" lang sein und darf nur alphanumerische Zeichen, Bindestriche und " +"Unterstriche enthalten." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:82 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:12 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:12 +#: invenio_userprofiles/views.py:85 +msgid "Profile" +msgstr "Profil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:130 +msgid "Verification email sent." +msgstr "Verifizierungs-E-Mail gesendet." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:157 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"Das Profil wurde aktualisiert. Wir haben eine Bestätigungs-E-Mail an " +"%(email)s gesendet. Bitte überprüfen Sie diese." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:163 +msgid "Profile was updated." +msgstr "Das Profil wurde aktualisiert." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:17 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:17 +msgid "You have not yet verified your email address." +msgstr "Sie haben Ihre E-Mail-Adresse noch nicht verifiziert." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:25 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:25 +msgid "Cancel" +msgstr "Abbrechen" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:26 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:26 +msgid "Update profile" +msgstr "Profil aktualisieren" From c0933ec64ba1a6925f631f79d9a6a2cf581563a4 Mon Sep 17 00:00:00 2001 From: Zacharias Zacharodimos Date: Mon, 12 Jul 2021 10:43:50 +0200 Subject: [PATCH 06/65] release: v1.2.3 --- CHANGES.rst | 4 ++++ invenio_userprofiles/version.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1f8d3e4..0e7590d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 1.2.3 (released 2021-07-12) + +- Adds german translations + Version 1.2.2 (released 2021-05-17) - Add config option to make user profiles form read-only diff --git a/invenio_userprofiles/version.py b/invenio_userprofiles/version.py index 75e21f1..8471658 100644 --- a/invenio_userprofiles/version.py +++ b/invenio_userprofiles/version.py @@ -14,4 +14,4 @@ from __future__ import absolute_import, print_function -__version__ = '1.2.2' +__version__ = '1.2.3' From cbd661377823382e641d2a5c2b36e82fd2058b43 Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Fri, 8 Oct 2021 15:20:14 +0200 Subject: [PATCH 07/65] global: make ready for flask 2 * remove pinning of flask * apparently there are cases where current_user is None, which caused the check for 'current_user.is_anonymous' to fail --- AUTHORS.rst | 1 + invenio_userprofiles/api.py | 3 ++- setup.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index fd1634e..d8ebc19 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -25,3 +25,4 @@ Contributors - Tibor Simko - Vaibhav Gupta - Mojib Wali +- Maximilian Moser diff --git a/invenio_userprofiles/api.py b/invenio_userprofiles/api.py index 742d22f..42823be 100644 --- a/invenio_userprofiles/api.py +++ b/invenio_userprofiles/api.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2021 TU Wien. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -26,7 +27,7 @@ def _get_current_userprofile(): :returns: The :class:`invenio_userprofiles.models.UserProfile` instance. """ - if current_user.is_anonymous: + if not current_user or current_user.is_anonymous: return AnonymousUserProfile() profile = getattr( diff --git a/setup.py b/setup.py index b180e6c..a7d8c59 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2021 TU Wien. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -54,7 +55,6 @@ ] install_requires = [ - 'Flask>=1.1.0,<2.0.0', 'Flask-Breadcrumbs>=0.5.0', 'Flask-Mail>=0.9.1', 'Flask-Menu>=0.5.0', From f06fb33505966b652c8f1a4d4e3298c678dac30a Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Mon, 18 Oct 2021 16:51:15 +0200 Subject: [PATCH 08/65] release: v1.2.4 --- CHANGES.rst | 4 ++++ invenio_userprofiles/version.py | 2 +- setup.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0e7590d..187ec27 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 1.2.4 (released 2021-10-18) + +- Unpin Flask 2 + Version 1.2.3 (released 2021-07-12) - Adds german translations diff --git a/invenio_userprofiles/version.py b/invenio_userprofiles/version.py index 8471658..ea158d9 100644 --- a/invenio_userprofiles/version.py +++ b/invenio_userprofiles/version.py @@ -14,4 +14,4 @@ from __future__ import absolute_import, print_function -__version__ = '1.2.3' +__version__ = '1.2.4' diff --git a/setup.py b/setup.py index a7d8c59..71ca9e4 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,7 @@ 'Flask-Menu>=0.5.0', 'Flask-WTF>=0.14.3', 'invenio-accounts>=1.2.1', - 'invenio-base>=1.2.4', + 'invenio-base>=1.2.5', 'invenio-i18n>=1.2.0', 'invenio-theme>=1.3.4', ] From c6ec0f9737b34c28bbc4dbb8dba1fe109b9e7b89 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 15:07:12 +0200 Subject: [PATCH 09/65] forms: fix flask-login compatibility issue --- invenio_userprofiles/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 7367b00..3e6fb5b 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -79,7 +79,7 @@ def validate_username(form, field): # We are handling a user editing their profile AND a # the username already exists. is_same_user = \ - current_user.id == user_profile.user_id + current_user.get_id() == str(user_profile.user_id) if not is_same_user: # Username already taken by another user. raise ValidationError(msg) From 0326259e60ecae8dd6f6203d4212f5d24a809855 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 15:41:36 +0200 Subject: [PATCH 10/65] github: reduce test matrix size --- .github/workflows/tests.yml | 44 ++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b6f419a..8aad324 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,27 +20,51 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.6, 3.7, 3.8] + python-version: [3.7, 3.8, 3.9] requirements-level: [min, pypi] - db-service: [postgresql9, postgresql11, mysql5, mysql8] + db-service: [postgresql10, postgresql14, mysql5, mysql8] exclude: + - python-version: 3.7 + requirements-level: pypi + - python-version: 3.8 requirements-level: min - - db-service: postgresql11 - python-version: 3.6 + - python-version: 3.9 + requirements-level: min - - db-service: mysql8 - python-version: 3.6 + - python-version: 3.7 + requirements-level: min + db-service: postgresql14 + + - python-version: 3.7 + requirements-level: min + db-service: mysql8 + + - python-version: 3.8 + requirements-level: pypi + db-service: postgresql10 + + - python-version: 3.8 + requirements-level: pypi + db-service: mysql5 + + - python-version: 3.9 + requirements-level: pypi + db-service: postgresql10 + + - python-version: 3.9 + requirements-level: pypi + db-service: mysql5 include: - - db-service: postgresql9 - DB: postgresql9 + - db-service: postgresql10 + DB: postgresql10 EXTRAS: "all,postgresql" - - db-service: postgresql11 - DB: postgresql9 + - db-service: postgresql14 + DB: postgresql10 EXTRAS: "all,postgresql" - db-service: mysql5 From 8cab89e423f2c9fcc62094b101ef49a55dd592f7 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 15:07:31 +0200 Subject: [PATCH 11/65] installation: refactor dependencies --- run-tests.sh | 2 +- setup.py | 26 +++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/run-tests.sh b/run-tests.sh index e4b8210..78a811c 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -23,8 +23,8 @@ function cleanup() { trap cleanup EXIT python -m check_manifest --ignore ".*-requirements.txt" -sphinx-build -qnNW docs docs/_build/html eval "$(docker-services-cli up --db ${DB:-postgresql} --env)" python -m pytest +sphinx-build -qnN docs docs/_build/html tests_exit_code=$? exit "$tests_exit_code" diff --git a/setup.py b/setup.py index 71ca9e4..8ead9c5 100644 --- a/setup.py +++ b/setup.py @@ -19,8 +19,7 @@ history = open('CHANGES.rst').read() tests_require = [ - 'pytest-invenio>=1.4.2', - 'SQLAlchemy-Continuum>=1.2.1', + 'pytest-invenio>=1.4.7', ] extras_require = { @@ -28,17 +27,16 @@ 'invenio-admin>=1.2.0', ], 'docs': [ - 'Sphinx>=3.0.0,<3.4.2', - 'invenio-mail>=1.0.0', + 'Sphinx>=4.2.0,<5', ], 'mysql': [ - 'invenio-db[mysql]>=1.0.9', + 'invenio-db[mysql,versioning]>=1.0.14', ], 'postgresql': [ - 'invenio-db[postgresql]>=1.0.9', + 'invenio-db[postgresql,versioning]>=1.0.14', ], 'sqlite': [ - 'invenio-db>=1.0.9', + 'invenio-db[versioning]>=1.0.14', ], 'tests': tests_require, } @@ -50,19 +48,13 @@ extras_require['all'].extend(reqs) setup_requires = [ - 'pytest-runner>=2.6.2', - 'Babel>=1.3', + 'Babel>=2.8', ] install_requires = [ - 'Flask-Breadcrumbs>=0.5.0', - 'Flask-Mail>=0.9.1', - 'Flask-Menu>=0.5.0', - 'Flask-WTF>=0.14.3', - 'invenio-accounts>=1.2.1', - 'invenio-base>=1.2.5', - 'invenio-i18n>=1.2.0', - 'invenio-theme>=1.3.4', + 'Flask-WTF>=0.15.1', + 'invenio-accounts>=1.4.4', + 'invenio-mail>=1.0.2', ] packages = find_packages() From 1d20071db993e31b5730d2b0750a282c9cb41d98 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 15:47:53 +0200 Subject: [PATCH 12/65] tests: add min dependency constraints for tests --- .github/workflows/tests.yml | 2 +- constraints-min.txt | 3 +++ constraints-pypi.txt | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 constraints-min.txt create mode 100644 constraints-pypi.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8aad324..8aea43f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -100,7 +100,7 @@ jobs: - name: Install dependencies run: | - pip install -r .${{matrix.requirements-level}}-${{ matrix.python-version }}-requirements.txt + pip install -r .${{matrix.requirements-level}}-${{ matrix.python-version }}-requirements.txt -c constraints-${{matrix.requirements-level}}.txt pip install .[${{ matrix.EXTRAS }}] pip freeze docker --version diff --git a/constraints-min.txt b/constraints-min.txt new file mode 100644 index 0000000..068ea4e --- /dev/null +++ b/constraints-min.txt @@ -0,0 +1,3 @@ +Flask>=1.1.4,<2.0.0 +Werkzeug>=1.0,<2.0.0 +markupsafe>=0.23,<1.0 diff --git a/constraints-pypi.txt b/constraints-pypi.txt new file mode 100644 index 0000000..8e3d1c6 --- /dev/null +++ b/constraints-pypi.txt @@ -0,0 +1 @@ +# Empty on purpose From c98e516428ce05f858581c18e9f58be1351cdb62 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 16:03:26 +0200 Subject: [PATCH 13/65] global: remove __future__ imports --- docs/conf.py | 2 -- invenio_userprofiles/__init__.py | 2 -- invenio_userprofiles/admin.py | 2 -- invenio_userprofiles/api.py | 2 -- invenio_userprofiles/ext.py | 2 -- invenio_userprofiles/forms.py | 2 -- invenio_userprofiles/models.py | 2 -- invenio_userprofiles/validators.py | 2 -- invenio_userprofiles/views.py | 2 -- tests/conftest.py | 2 -- tests/helpers.py | 2 -- tests/test_forms.py | 2 -- tests/test_invenio_userprofile.py | 2 -- tests/test_models.py | 2 -- tests/test_validators.py | 2 -- tests/test_views.py | 2 -- 16 files changed, 32 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2c2004d..43d37fa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,8 +8,6 @@ """Sphinx configuration.""" -from __future__ import print_function - import os import sys diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 496660d..af00856 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -8,8 +8,6 @@ """User profiles module for Invenio.""" -from __future__ import absolute_import, print_function - from .api import current_userprofile from .ext import InvenioUserProfiles from .models import AnonymousUserProfile, UserProfile diff --git a/invenio_userprofiles/admin.py b/invenio_userprofiles/admin.py index a4f3b2a..d768f7b 100644 --- a/invenio_userprofiles/admin.py +++ b/invenio_userprofiles/admin.py @@ -8,8 +8,6 @@ """Admin views for invenio-userprofiles.""" -from __future__ import absolute_import, print_function - from flask_admin.contrib.sqla import ModelView from .models import UserProfile diff --git a/invenio_userprofiles/api.py b/invenio_userprofiles/api.py index 42823be..e2047ad 100644 --- a/invenio_userprofiles/api.py +++ b/invenio_userprofiles/api.py @@ -9,8 +9,6 @@ """API for user profiles.""" -from __future__ import absolute_import, print_function - from flask import g from flask_security import current_user from werkzeug.local import LocalProxy diff --git a/invenio_userprofiles/ext.py b/invenio_userprofiles/ext.py index 7913efe..1825ae4 100644 --- a/invenio_userprofiles/ext.py +++ b/invenio_userprofiles/ext.py @@ -8,8 +8,6 @@ """User profiles module for Invenio.""" -from __future__ import absolute_import, print_function - from . import config from .api import current_userprofile diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 3e6fb5b..69cb78b 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -8,8 +8,6 @@ """Forms for user profiles.""" -from __future__ import absolute_import, print_function - from flask_babelex import lazy_gettext as _ from flask_login import current_user from flask_security.forms import email_required, email_validator, \ diff --git a/invenio_userprofiles/models.py b/invenio_userprofiles/models.py index df1e695..8a88efc 100644 --- a/invenio_userprofiles/models.py +++ b/invenio_userprofiles/models.py @@ -8,8 +8,6 @@ """Database models for user profiles.""" -from __future__ import absolute_import, print_function - from invenio_accounts.models import User from invenio_db import db from sqlalchemy import event diff --git a/invenio_userprofiles/validators.py b/invenio_userprofiles/validators.py index d79dd29..5206789 100644 --- a/invenio_userprofiles/validators.py +++ b/invenio_userprofiles/validators.py @@ -8,8 +8,6 @@ """Validators for user profiles.""" -from __future__ import absolute_import, print_function - import re from flask_babelex import lazy_gettext as _ diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 06cec3b..eb3b549 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -8,8 +8,6 @@ """Invenio module that adds userprofiles to the platform.""" -from __future__ import absolute_import, print_function - from flask import Blueprint, current_app, flash, render_template, request from flask_babelex import lazy_gettext as _ from flask_breadcrumbs import register_breadcrumb diff --git a/tests/conftest.py b/tests/conftest.py index e4ef8ea..994466b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,8 +8,6 @@ """Pytest configuration.""" -from __future__ import absolute_import, print_function - import os import shutil import tempfile diff --git a/tests/helpers.py b/tests/helpers.py index 4e7b427..762ea94 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -8,8 +8,6 @@ """Helper functions for tests.""" -from __future__ import absolute_import, print_function - from flask import url_for diff --git a/tests/test_forms.py b/tests/test_forms.py index 630a310..ad32c01 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -8,8 +8,6 @@ """Tests for user profile forms.""" -from __future__ import absolute_import, print_function - from invenio_userprofiles.forms import _update_with_csrf_disabled, \ confirm_register_form_factory, register_form_factory diff --git a/tests/test_invenio_userprofile.py b/tests/test_invenio_userprofile.py index ed6209c..8d73a0b 100644 --- a/tests/test_invenio_userprofile.py +++ b/tests/test_invenio_userprofile.py @@ -8,8 +8,6 @@ """Module tests.""" -from __future__ import absolute_import, print_function - import pytest from flask import Flask from flask_babelex import Babel diff --git a/tests/test_models.py b/tests/test_models.py index 21e77a5..f06ba48 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -8,8 +8,6 @@ """Tests for user profile models.""" -from __future__ import absolute_import, print_function - import pytest from invenio_accounts.models import User from invenio_db import db diff --git a/tests/test_validators.py b/tests/test_validators.py index 9f06827..5a1a10a 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -8,8 +8,6 @@ """Tests for user profile validators.""" -from __future__ import absolute_import, print_function - import pytest from invenio_userprofiles.validators import validate_username diff --git a/tests/test_views.py b/tests/test_views.py index 5ab9d67..03bfe9e 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -8,8 +8,6 @@ """Tests for user profile views.""" -from __future__ import absolute_import, print_function - from flask import url_for from flask_security import url_for_security from helpers import login, sign_up From acfcc58511467550dedda0bd4611088b0b55b9ac Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 16:01:46 +0200 Subject: [PATCH 14/65] global: move from setup.py to setup.cfg --- .github/workflows/pypi-release.yml | 2 +- .github/workflows/tests.yml | 8 +- docs/conf.py | 9 +-- invenio_userprofiles/__init__.py | 3 +- invenio_userprofiles/version.py | 17 ---- pyproject.toml | 3 + setup.cfg | 60 +++++++++++++- setup.py | 121 +---------------------------- 8 files changed, 72 insertions(+), 151 deletions(-) delete mode 100644 invenio_userprofiles/version.py create mode 100644 pyproject.toml diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index a67f72a..6f16cea 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -20,7 +20,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel + pip install setuptools wheel babel - name: Build package # Remove `compile_catalog` if the package has no translations. run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8aea43f..16080d4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -61,19 +61,19 @@ jobs: include: - db-service: postgresql10 DB: postgresql10 - EXTRAS: "all,postgresql" + EXTRAS: "tests" - db-service: postgresql14 DB: postgresql10 - EXTRAS: "all,postgresql" + EXTRAS: "tests" - db-service: mysql5 DB: mysql5 - EXTRAS: "all,mysql" + EXTRAS: "tests" - db-service: mysql8 DB: mysql8 - EXTRAS: "all,mysql" + EXTRAS: "tests" env: DB: ${{ matrix.DB }} diff --git a/docs/conf.py b/docs/conf.py index 43d37fa..7abd286 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,8 @@ import sphinx.environment +from invenio_userprofiles import __version__ + # Plug example application into module path sys.path.append('examples') @@ -61,12 +63,7 @@ # The short X.Y version. # Get the version string. Cannot be done with import! -g = {} -with open(os.path.join(os.path.dirname(__file__), '..', - 'invenio_userprofiles', 'version.py'), - 'rt') as fp: - exec(fp.read(), g) - version = g['__version__'] +version = __version__ # The full version, including alpha/beta/rc tags. release = version diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index af00856..5cb56b9 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -11,7 +11,8 @@ from .api import current_userprofile from .ext import InvenioUserProfiles from .models import AnonymousUserProfile, UserProfile -from .version import __version__ + +__version__ = '1.2.4' __all__ = ('__version__', 'InvenioUserProfiles', 'AnonymousUserProfile', 'UserProfile', 'current_userprofile') diff --git a/invenio_userprofiles/version.py b/invenio_userprofiles/version.py deleted file mode 100644 index ea158d9..0000000 --- a/invenio_userprofiles/version.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of Invenio. -# Copyright (C) 2015-2018 CERN. -# -# Invenio is free software; you can redistribute it and/or modify it -# under the terms of the MIT License; see LICENSE file for more details. - -"""Version information for Invenio-UserProfiles. - -This file is imported by ``invenio_userprofiles.__init__``, -and parsed by ``setup.py``. -""" - -from __future__ import absolute_import, print_function - -__version__ = '1.2.4' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ec4e1ea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel", "babel>2.8"] +build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg index 343c89d..0bdbfb0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,14 +1,68 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. -# Copyright (C) 2015-2018 CERN. +# Copyright (C) 2015-2022 CERN. +# Copyright (C) 2021 TU Wien. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. +[metadata] +name = invenio-userprofiles +version = attr: invenio_userprofiles.__version__ +description = User profiles module for Invenio. +long_description = file: README.rst, CHANGES.rst +keywords = invenio profile account user +license = MIT +author = CERN +author_email = info@inveniosoftware.org +platforms = any +url = https://github.com/inveniosoftware/invenio-userprofiles +classifiers = + Development Status :: 5 - Production/Stable -[aliases] -test = pytest +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +zip_safe = False +install_requires = + Flask-WTF>=0.15.1 + invenio-accounts>=1.4.4 + invenio-mail>=1.0.2 + +[options.extras_require] +tests = + pytest-invenio~=1.4.7 + invenio-admin>=1.3.2 + invenio-db[mysql,postgresql,versioning]>=1.0.14 + Sphinx>=4.2.0,<5 +admin = + # empty for backward compatibility +postgresql = + # empty for backward compatibility +mysql = + # empty for backward compatibility +sqlite = + # empty for backward compatibility + +[options.entry_points] +invenio_admin.views = + invenio_userprofiles_view = invenio_userprofiles.admin:user_profile_adminview +invenio_base.api_apps = + invenio_userprofiles = invenio_userprofiles:InvenioUserProfiles +invenio_base.api_blueprints = + invenio_userprofiles = invenio_userprofiles.views:blueprint_api_init +invenio_base.apps = + invenio_userprofiles = invenio_userprofiles:InvenioUserProfiles +invenio_base.blueprints = + invenio_userprofiles = invenio_userprofiles.views:blueprint_ui_init +invenio_db.alembic = + invenio_userprofiles = invenio_userprofiles:alembic +invenio_db.models = + invenio_userprofiles = invenio_userprofiles.models +invenio_i18n.translations = + messages = invenio_userprofiles [build_sphinx] source-dir = docs/ diff --git a/setup.py b/setup.py index 8ead9c5..275700f 100644 --- a/setup.py +++ b/setup.py @@ -9,123 +9,6 @@ """User profiles module for Invenio.""" -import os -import sys +from setuptools import setup -from setuptools import find_packages, setup -from setuptools.command.test import test as TestCommand - -readme = open('README.rst').read() -history = open('CHANGES.rst').read() - -tests_require = [ - 'pytest-invenio>=1.4.7', -] - -extras_require = { - 'admin': [ - 'invenio-admin>=1.2.0', - ], - 'docs': [ - 'Sphinx>=4.2.0,<5', - ], - 'mysql': [ - 'invenio-db[mysql,versioning]>=1.0.14', - ], - 'postgresql': [ - 'invenio-db[postgresql,versioning]>=1.0.14', - ], - 'sqlite': [ - 'invenio-db[versioning]>=1.0.14', - ], - 'tests': tests_require, -} - -extras_require['all'] = [] -for name, reqs in extras_require.items(): - if name in ('mysql', 'postgresql', 'sqlite'): - continue - extras_require['all'].extend(reqs) - -setup_requires = [ - 'Babel>=2.8', -] - -install_requires = [ - 'Flask-WTF>=0.15.1', - 'invenio-accounts>=1.4.4', - 'invenio-mail>=1.0.2', -] - -packages = find_packages() - - -# Get the version string. Cannot be done with import! -g = {} -with open(os.path.join('invenio_userprofiles', 'version.py'), 'rt') as fp: - exec(fp.read(), g) - version = g['__version__'] - -setup( - name='invenio-userprofiles', - version=version, - description=__doc__, - long_description=readme + '\n\n' + history, - keywords='invenio profile account user', - license='MIT', - author='CERN', - author_email='info@inveniosoftware.org', - url='https://github.com/inveniosoftware/invenio-userprofiles', - packages=packages, - zip_safe=False, - include_package_data=True, - platforms='any', - entry_points={ - 'invenio_admin.views': [ - 'invenio_userprofiles_view = ' - 'invenio_userprofiles.admin:user_profile_adminview', - ], - 'invenio_base.api_apps': [ - 'invenio_userprofiles = invenio_userprofiles:InvenioUserProfiles', - ], - 'invenio_base.api_blueprints': [ - 'invenio_userprofiles' - ' = invenio_userprofiles.views:blueprint_api_init', - ], - 'invenio_base.apps': [ - 'invenio_userprofiles = invenio_userprofiles:InvenioUserProfiles', - ], - 'invenio_base.blueprints': [ - 'invenio_userprofiles' - ' = invenio_userprofiles.views:blueprint_ui_init', - ], - 'invenio_db.alembic': [ - 'invenio_userprofiles = invenio_userprofiles:alembic', - ], - 'invenio_db.models': [ - 'invenio_userprofiles = invenio_userprofiles.models', - ], - 'invenio_i18n.translations': [ - 'messages = invenio_userprofiles', - ], - }, - extras_require=extras_require, - install_requires=install_requires, - setup_requires=setup_requires, - tests_require=tests_require, - classifiers=[ - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: Implementation :: CPython', - 'Development Status :: 5 - Production/Stable', - ], -) +setup() From 3c16f3ae1cfbd918f6eade5599690670ac603284 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Wed, 6 Apr 2022 16:17:26 +0200 Subject: [PATCH 15/65] global: fix werkzeug compatibility --- invenio_userprofiles/__init__.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 5cb56b9..0df5074 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -8,6 +8,22 @@ """User profiles module for Invenio.""" +# Monkey patch Werkzeug 2.1 +# Flask-Login uses the safe_str_cmp method which has been removed in Werkzeug +# 2.1. Flask-Login v0.6.0 (yet to be released at the time of writing) fixes the +# issue. Once we depend on Flask-Login v0.6.0 as the minimal version in +# Flask-Security-Invenio/Invenio-Accounts we can remove this patch again. +try: + # Werkzeug <2.1 + from werkzeug import security + security.safe_str_cmp +except AttributeError: + # Werkzeug >=2.1 + import hmac + + from werkzeug import security + security.safe_str_cmp = hmac.compare_digest + from .api import current_userprofile from .ext import InvenioUserProfiles from .models import AnonymousUserProfile, UserProfile From fec620a5837022d9d0c74be8379dd68aa5a1eeb6 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 7 Apr 2022 16:19:11 +0200 Subject: [PATCH 16/65] babel: fix extensions removed from jinja2 v3.x * The two extensions removed are now built into Jinja directly since v2.9. --- babel.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/babel.ini b/babel.ini index e021ca1..57923d9 100644 --- a/babel.ini +++ b/babel.ini @@ -15,7 +15,6 @@ encoding = utf-8 [jinja2: **/templates/**.html] encoding = utf-8 -extensions = jinja2.ext.autoescape, jinja2.ext.with_ # Extraction from JavaScript files From 735896de8ad1d111c115c5aee3bf014d61a9bdf6 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 00:45:08 +0200 Subject: [PATCH 17/65] admin: remove admin interface * All data is moved to accounts user table, so there's no more data to display here. --- invenio_userprofiles/admin.py | 51 ----------------------------------- invenio_userprofiles/api.py | 2 +- setup.cfg | 2 -- tests/test_admin.py | 45 ------------------------------- 4 files changed, 1 insertion(+), 99 deletions(-) delete mode 100644 invenio_userprofiles/admin.py delete mode 100644 tests/test_admin.py diff --git a/invenio_userprofiles/admin.py b/invenio_userprofiles/admin.py deleted file mode 100644 index d768f7b..0000000 --- a/invenio_userprofiles/admin.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of Invenio. -# Copyright (C) 2016-2018 CERN. -# -# Invenio is free software; you can redistribute it and/or modify it -# under the terms of the MIT License; see LICENSE file for more details. - -"""Admin views for invenio-userprofiles.""" - -from flask_admin.contrib.sqla import ModelView - -from .models import UserProfile - - -def _(x): - """Identity.""" - return x - - -class UserProfileView(ModelView): - """Userprofiles view. Links User ID to user/full/display name.""" - - can_view_details = True - can_create = False - can_delete = False - - column_list = ( - 'user_id', - '_displayname', - 'full_name', - ) - - column_searchable_list = \ - column_filters = \ - column_details_list = \ - columns_sortable_list = \ - column_list - - form_columns = ('username', 'full_name') - - column_labels = { - '_displayname': _('Username'), - } - - -user_profile_adminview = { - 'model': UserProfile, - 'modelview': UserProfileView, - 'category': _('User Management'), -} diff --git a/invenio_userprofiles/api.py b/invenio_userprofiles/api.py index e2047ad..edbd47e 100644 --- a/invenio_userprofiles/api.py +++ b/invenio_userprofiles/api.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. -# Copyright (C) 2015-2018 CERN. +# Copyright (C) 2015-2022 CERN. # Copyright (C) 2021 TU Wien. # # Invenio is free software; you can redistribute it and/or modify it diff --git a/setup.cfg b/setup.cfg index 0bdbfb0..b4e7651 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,8 +47,6 @@ sqlite = # empty for backward compatibility [options.entry_points] -invenio_admin.views = - invenio_userprofiles_view = invenio_userprofiles.admin:user_profile_adminview invenio_base.api_apps = invenio_userprofiles = invenio_userprofiles:InvenioUserProfiles invenio_base.api_blueprints = diff --git a/tests/test_admin.py b/tests/test_admin.py deleted file mode 100644 index de47410..0000000 --- a/tests/test_admin.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of Invenio. -# Copyright (C) 2016-2018 CERN. -# -# Invenio is free software; you can redistribute it and/or modify it -# under the terms of the MIT License; see LICENSE file for more details. - -from flask import Flask, url_for -from flask_admin import Admin -from invenio_admin import InvenioAdmin -from invenio_db import db - -from invenio_userprofiles import InvenioUserProfiles -from invenio_userprofiles.admin import UserProfileView, user_profile_adminview - - -def test_admin(app): - """Test flask-admin interace.""" - InvenioUserProfiles(app) - - assert isinstance(user_profile_adminview, dict) - - assert 'model' in user_profile_adminview - assert 'modelview' in user_profile_adminview - - admin = Admin(app, name="Test") - - user_model = user_profile_adminview.pop('model') - user_view = user_profile_adminview.pop('modelview') - admin.add_view(user_view(user_model, db.session, - **user_profile_adminview)) - - with app.test_request_context(): - request_url = url_for('userprofile.index_view') - - with app.app_context(): - with app.test_client() as client: - res = client.get( - request_url, - follow_redirects=True - ) - assert res.status_code == 200 - assert b'Username' in (res.get_data()) - assert b'Full Name' in (res.get_data()) From 915491ac5375374aa4df2346f42747c47f003987 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 00:46:03 +0200 Subject: [PATCH 18/65] templates: fix rendering for profile fields * Fixes how profile fields are rendered together with email/password field in the registration form. --- .../semantic-ui/invenio_userprofiles/register_user.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/register_user.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/register_user.html index ba0424a..3847c69 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/register_user.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/register_user.html @@ -13,7 +13,9 @@ {% block registration_form_fields %} {%- with form = register_user_form %} -{{ render_field(form.profile, icon="lock icon", errormsg=False) }} +{% for field in form.profile %} +{{ render_field(field, errormsg=field.short_name in form.errors.profile) }} +{% endfor %} {%- endwith %} {{ super() }} {% endblock %} From 5f0bf5b6689604d244f50c65f0dab676bf2da4d2 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 00:47:50 +0200 Subject: [PATCH 19/65] global: rely on accounts profile field * Changes views and code to rely on the new profile field in accounts rather than having a separate database model here. --- constraints-min.txt | 7 +- invenio_userprofiles/__init__.py | 11 +- .../alembic/41157f1933d6_remove_table.py | 47 ++++++ invenio_userprofiles/api.py | 21 +-- invenio_userprofiles/forms.py | 108 +++++++++----- invenio_userprofiles/models.py | 140 ++++++++---------- invenio_userprofiles/views.py | 34 ++--- setup.cfg | 7 +- tests/conftest.py | 3 +- tests/test_models.py | 96 +----------- tests/test_views.py | 38 ++--- 11 files changed, 236 insertions(+), 276 deletions(-) create mode 100644 invenio_userprofiles/alembic/41157f1933d6_remove_table.py diff --git a/constraints-min.txt b/constraints-min.txt index 068ea4e..32f6b27 100644 --- a/constraints-min.txt +++ b/constraints-min.txt @@ -1,3 +1,4 @@ -Flask>=1.1.4,<2.0.0 -Werkzeug>=1.0,<2.0.0 -markupsafe>=0.23,<1.0 +# Dependency coming Flask-Security via Invenio-Accounts 2.0 +Flask-WTF>=1.0.0,<1.1.0 +Flask>=2.0.0,<2.1.0 +Werkzeug>=2.0,<2.1.0 diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 0df5074..d779262 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -26,9 +26,14 @@ from .api import current_userprofile from .ext import InvenioUserProfiles -from .models import AnonymousUserProfile, UserProfile +from .models import UserProfile, UserProfileProxy __version__ = '1.2.4' -__all__ = ('__version__', 'InvenioUserProfiles', 'AnonymousUserProfile', - 'UserProfile', 'current_userprofile') +__all__ = ( + '__version__', + 'current_userprofile', + 'InvenioUserProfiles', + 'UserProfile', + 'UserProfileProxy', +) diff --git a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py new file mode 100644 index 0000000..0908bca --- /dev/null +++ b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py @@ -0,0 +1,47 @@ +# +# This file is part of Invenio. +# Copyright (C) 2016-2018 CERN. +# +# Invenio is free software; you can redistribute it and/or modify it +# under the terms of the MIT License; see LICENSE file for more details. + +"""Remove table.""" + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '41157f1933d6' +down_revision = 'c25ef2c50ffa' +branch_labels = () +depends_on = None + + +def upgrade(): + """Upgrade database.""" + op.drop_table('userprofiles_userprofile') + + +def downgrade(): + """Downgrade database.""" + op.create_table( + 'userprofiles_userprofile', + sa.Column( + 'user_id', sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column( + 'username', sa.VARCHAR(length=255), autoincrement=False, + nullable=True), + sa.Column( + 'displayname', sa.VARCHAR(length=255), autoincrement=False, + nullable=True), + sa.Column( + 'full_name', sa.VARCHAR(length=255), autoincrement=False, + nullable=False), + sa.ForeignKeyConstraint( + ['user_id'], ['accounts_user.id'], + name='fk_userprofiles_userprofile_user_id_accounts_user'), + sa.PrimaryKeyConstraint('user_id', name='pk_userprofiles_userprofile'), + sa.UniqueConstraint( + 'username', + name='uq_userprofiles_userprofile_username') + ) diff --git a/invenio_userprofiles/api.py b/invenio_userprofiles/api.py index edbd47e..e850641 100644 --- a/invenio_userprofiles/api.py +++ b/invenio_userprofiles/api.py @@ -9,11 +9,12 @@ """API for user profiles.""" -from flask import g +from warnings import warn + from flask_security import current_user from werkzeug.local import LocalProxy -from .models import AnonymousUserProfile, UserProfile +from .models import UserProfileProxy def _get_current_userprofile(): @@ -25,17 +26,11 @@ def _get_current_userprofile(): :returns: The :class:`invenio_userprofiles.models.UserProfile` instance. """ - if not current_user or current_user.is_anonymous: - return AnonymousUserProfile() - - profile = getattr( - g, 'userprofile', UserProfile.get_by_userid(current_user.get_id())) - - if profile is None: - profile = UserProfile(user_id=int(current_user.get_id())) - g.userprofile = profile - - return profile + warn( + "current_userprofile is deprecated, use current_user instead", + DeprecationWarning + ) + return UserProfileProxy(current_user) current_userprofile = LocalProxy(lambda: _get_current_userprofile()) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 69cb78b..9e7e491 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -8,18 +8,17 @@ """Forms for user profiles.""" +from flask import current_app from flask_babelex import lazy_gettext as _ from flask_login import current_user from flask_security.forms import email_required, email_validator, \ unique_user_email from flask_wtf import FlaskForm -from sqlalchemy.orm.exc import NoResultFound from wtforms import FormField, StringField, SubmitField -from wtforms.validators import DataRequired, EqualTo, StopValidation, \ +from wtforms.validators import DataRequired, EqualTo, Length, StopValidation, \ ValidationError -from .api import current_userprofile -from .models import UserProfile +from .models import UserProfileProxy from .validators import USERNAME_RULES, validate_username @@ -41,48 +40,75 @@ def current_user_email(form, field): class ProfileForm(FlaskForm): """Form for editing user profile.""" + profile_proxy_cls = UserProfileProxy + username = StringField( # NOTE: Form field label _('Username'), # NOTE: Form field help text description=_('Required. %(username_rules)s', username_rules=USERNAME_RULES), - validators=[DataRequired(message=_('Username not provided.'))], + validators=[ + Length(max=50), + DataRequired(message=_('Username not provided.')) + ], filters=[strip_filter], ) full_name = StringField( # NOTE: Form label _('Full name'), + validators=[Length(max=255)], filters=[strip_filter], ) - def validate_username(form, field): + affiliations = StringField( + # NOTE: Form label + _('Affiliations'), + validators=[Length(max=255)], + filters=[strip_filter], ) + + def validate_username(self, field): """Wrap username validator for WTForms.""" try: validate_username(field.data) except ValueError as e: raise ValidationError(e) - try: - # Check if username is already taken (if the username is *not* - # found a NoResultFound exception is raised). - user_profile = UserProfile.get_by_username(field.data) - # NOTE: Form validation error. - msg = _('Username already exists.') + # Check if username is already taken. + datastore = current_app.extensions['security'].datastore + user = datastore.find_user(username=field.data) + if user is None: + return - if current_userprofile.is_anonymous: - # We are handling a new sign up (i.e. anonymous user) AND a - # the username already exists. Fail. + # NOTE: Form validation error. + msg = _('Username is not available.') + + if current_user.is_anonymous: + # We are handling a new sign up (i.e. anonymous user) AND a + # the username already exists. Fail. + raise ValidationError(msg) + else: + # We are handling a user editing their profile AND a + # the username already exists. + is_same_user = \ + current_user.get_id() == str(user.id) + if not is_same_user: + # Username already taken by another user. raise ValidationError(msg) - else: - # We are handling a user editing their profile AND a - # the username already exists. - is_same_user = \ - current_user.get_id() == str(user_profile.user_id) - if not is_same_user: - # Username already taken by another user. - raise ValidationError(msg) - except NoResultFound: - return + + def process(self, formdata=None, obj=None, data=None, extra_filters=None, + **kwargs): + """Build a proxy around the object.""" + if obj is not None: + obj = self.profile_proxy_cls(obj) + super().process( + formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, + **kwargs + ) + + def populate_obj(self, user): + """Populates the obj.""" + user = self.profile_proxy_cls(user) + super().populate_obj(user) class EmailProfileForm(ProfileForm): @@ -140,6 +166,13 @@ class RegisterForm(Form): profile = FormField(CsrfDisabledProfileForm, separator='.') + def to_dict(self): + profile_data = self.profile.data + data = super().to_dict() + data['username'] = profile_data.pop('username') + data['user_profile'] = profile_data + return data + return RegisterForm @@ -162,25 +195,20 @@ class ConfirmRegisterForm(Form): profile = FormField(CsrfDisabledProfileForm, separator='.') + def to_dict(self): + profile_data = self.profile.data + data = super().to_dict() + data['username'] = profile_data.pop('username') + data['user_profile'] = profile_data + return data + return ConfirmRegisterForm def _update_with_csrf_disabled(d=None): - """Update the input dict with CSRF disabled depending on WTF-Form version. - - From Flask-WTF 0.14.0, `csrf_enabled` param has been deprecated in favor of - `meta={csrf: True/False}`. - """ + """Update the input dict with CSRF disabled.""" if d is None: d = {} - - import flask_wtf - from pkg_resources import parse_version - supports_meta = parse_version(flask_wtf.__version__) >= parse_version( - "0.14.0") - if supports_meta: - d.setdefault('meta', {}) - d['meta'].update({'csrf': False}) - else: - d['csrf_enabled'] = False + d.setdefault('meta', {}) + d['meta'].update({'csrf': False}) return d diff --git a/invenio_userprofiles/models.py b/invenio_userprofiles/models.py index 8a88efc..e7ad41a 100644 --- a/invenio_userprofiles/models.py +++ b/invenio_userprofiles/models.py @@ -8,15 +8,10 @@ """Database models for user profiles.""" -from invenio_accounts.models import User -from invenio_db import db -from sqlalchemy import event -from sqlalchemy.ext.hybrid import hybrid_property +from flask import current_app -from .validators import validate_username - -class AnonymousUserProfile(): +class AnonymousUserProfile: """Anonymous user profile.""" @property @@ -25,52 +20,51 @@ def is_anonymous(self): return True -class UserProfile(db.Model): - """User profile model. - - Stores a username, display name (case sensitive version of username) and a - full name for a user. - """ - - __tablename__ = 'userprofiles_userprofile' - - user_id = db.Column( - db.Integer, - db.ForeignKey(User.id), - primary_key=True - ) - """Foreign key to :class:`~invenio_accounts.models.User`.""" - - user = db.relationship( - User, backref=db.backref( - 'profile', uselist=False, cascade='all, delete-orphan') - ) - """User relationship.""" - - _username = db.Column('username', db.String(255), unique=True) - """Lower-case version of username to assert uniqueness.""" - - _displayname = db.Column('displayname', db.String(255)) - """Case preserving version of username.""" - - full_name = db.Column(db.String(255), nullable=False, default='') - """Full name of person.""" - - @hybrid_property - def username(self): - """Get username.""" - return self._displayname - - @username.setter - def username(self, username): - """Set username. - - .. note:: The username will be converted to lowercase. The display name - will contain the original version. - """ - validate_username(username) - self._username = username.lower() - self._displayname = username +class UserProfileProxy: + """Proxy for a user that allows mapping the form to the user object.""" + + _profile_attrs = ['full_name', 'affiliations'] + _preferences_attrs = ['email_visibility', 'visibility'] + _read_only_attrs = ['email_repeat'] + _aliases = {'email_repeat': 'email', 'user_id': 'id'} + + def __init__(self, user): + """.""" + super().__setattr__('_user', user) + + def __getattr__(self, attr): + """.""" + if attr in self._profile_attrs: + return self._user.user_profile.get(attr, None) + elif attr in self._preferences_attrs: + return self._user.preferences.get(attr, None) + else: + attr = self._aliases.get(attr, attr) + return getattr(self._user, attr) + + def __setattr__(self, attr, value): + """.""" + if attr == 'email': + if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ + self._user.email != value: + self._user.email = value + self._user.confirmed_at = None + elif attr in self._profile_attrs: + self._user.user_profile = {**self._user.user_profile, attr: value} + elif attr in self._preferences_attrs: + self._user.preferences = {**self._user.preferences, attr: value} + elif attr not in self._read_only_attrs: + setattr(self._user, attr, value) + + def __hasattr__(self, attr): + """.""" + if attr in self._profile_attrs: + return attr in self._user.user_profile + elif attr in self._preferences_attrs: + return attr in self._user.preferences[attr] + else: + attr = self._aliases.get(attr, attr) + hasattr(self._user, attr) @classmethod def get_by_username(cls, username): @@ -78,9 +72,11 @@ def get_by_username(cls, username): :param username: A username to query for (case insensitive). """ - return cls.query.filter( - UserProfile._username == username.lower() - ).one() + # Kept for backward compatibility + user = current_app.extensions['security'].datastore.find_user( + _username=username.lower() + ) + return cls(user) if user else None @classmethod def get_by_userid(cls, user_id): @@ -90,28 +86,12 @@ def get_by_userid(cls, user_id): :returns: A :class:`~invenio_userprofiles.models.UserProfile` instance or ``None``. """ - return cls.query.filter_by(user_id=user_id).one_or_none() + # Kept for backward compatibility + user = current_app.extensions['security'].datastore.find_user( + id=user_id + ) + return cls(user) if user else None - @property - def is_anonymous(self): - """Return whether this UserProfile is anonymous.""" - return False - - -@event.listens_for(User, 'init') -def on_user_init(target, args, kwargs): - """Provide hook on :class:`~invenio_accounts.models.User` initialization. - - Automatically convert a dict to a - :class:`~.UserProfile` instance. This is needed - during e.g. user registration where Flask-Security will initialize a - user model with all the form data (which when Invenio-UserProfiles is - enabled includes a ``profile`` key). This will make the user creation fail - unless we convert the profile dict into a :class:`~.UserProfile` instance. - """ - profile = kwargs.pop('profile', None) - if profile is not None and not isinstance(profile, UserProfile): - profile = UserProfile(**profile) - if kwargs.get('id'): - profile.user_id = kwargs['id'] - kwargs['profile'] = profile + +# Backward compatibility +UserProfile = UserProfileProxy diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index eb3b549..80a9670 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -8,6 +8,8 @@ """Invenio module that adds userprofiles to the platform.""" +from warnings import warn + from flask import Blueprint, current_app, flash, render_template, request from flask_babelex import lazy_gettext as _ from flask_breadcrumbs import register_breadcrumb @@ -18,10 +20,9 @@ from invenio_theme.proxies import current_theme_icons from speaklater import make_lazy_string -from .api import current_userprofile from .forms import EmailProfileForm, ProfileForm, VerificationForm, \ confirm_register_form_factory, register_form_factory -from .models import UserProfile +from .models import UserProfileProxy blueprint = Blueprint( 'invenio_userprofiles', @@ -71,7 +72,11 @@ def init_api(state): @blueprint.app_template_filter() def userprofile(value): """Retrieve user profile for a given user id.""" - return UserProfile.get_by_userid(int(value)) + warn( + "userprofile template filter is deprecated.", + DeprecationWarning + ) + return UserProfileProxy.get_by_userid(int(value)) @blueprint.route('/', methods=['GET', 'POST']) @@ -111,15 +116,12 @@ def profile_form_factory(): if current_app.config['USERPROFILES_EMAIL_ENABLED']: return EmailProfileForm( formdata=None, - username=current_userprofile.username, - full_name=current_userprofile.full_name, - email=current_user.email, - email_repeat=current_user.email, + obj=current_user, prefix='profile', ) else: return ProfileForm( formdata=None, - obj=current_userprofile, + obj=current_user, prefix='profile', ) @@ -143,19 +145,13 @@ def handle_profile_form(form): if form.validate_on_submit(): email_changed = False with db.session.begin_nested(): - # Update profile. - current_userprofile.username = form.username.data - current_userprofile.full_name = form.full_name.data - db.session.add(current_userprofile) - - # Update email if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ - form.email.data != current_user.email: - current_user.email = form.email.data - current_user.confirmed_at = None - db.session.add(current_user) + form.email.data != current_user.email: email_changed = True - db.session.commit() + form.populate_obj(current_user) + + db.session.add(current_user) + current_app.extensions['security'].datastore.commit() if email_changed: send_confirmation_instructions(current_user) diff --git a/setup.cfg b/setup.cfg index b4e7651..9f60e5e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,14 +27,11 @@ packages = find: python_requires = >=3.6 zip_safe = False install_requires = - Flask-WTF>=0.15.1 - invenio-accounts>=1.4.4 - invenio-mail>=1.0.2 + invenio-accounts>=2.0.0.dev8 [options.extras_require] tests = pytest-invenio~=1.4.7 - invenio-admin>=1.3.2 invenio-db[mysql,postgresql,versioning]>=1.0.14 Sphinx>=4.2.0,<5 admin = @@ -57,8 +54,6 @@ invenio_base.blueprints = invenio_userprofiles = invenio_userprofiles.views:blueprint_ui_init invenio_db.alembic = invenio_userprofiles = invenio_userprofiles:alembic -invenio_db.models = - invenio_userprofiles = invenio_userprofiles.models invenio_i18n.translations = messages = invenio_userprofiles diff --git a/tests/conftest.py b/tests/conftest.py index 994466b..992f374 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,6 +39,7 @@ def app_config(app_config): 'sqlite://'), TEST_USER_EMAIL='test_user@example.com', TEST_USER_PASSWORD='test_password', + TEST_USER_USERNAME='test', TESTING=True, WTF_CSRF_ENABLED=False, ) @@ -46,7 +47,7 @@ def app_config(app_config): return app_config -@pytest.yield_fixture() +@pytest.fixture() def base_app(app_config): """Flask application fixture.""" instance_path = tempfile.mkdtemp() diff --git a/tests/test_models.py b/tests/test_models.py index f06ba48..9583724 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -19,7 +19,7 @@ def test_userprofiles(app): """Test UserProfile model.""" - profile = UserProfile() + profile = UserProfile(User()) # Check the username validator works on the model profile.username = test_usernames['valid'] @@ -35,39 +35,14 @@ def test_userprofiles(app): assert profile.last_name == 'User' -def test_profile_updating(base_app): - base_app.config.update(USERPROFILES_EXTEND_SECURITY_FORMS=True) - InvenioUserProfiles(base_app) - app = base_app - - with app.app_context(): - user = User(email='lollorosso', password='test_password') - db.session.add(user) - db.session.commit() - - assert user.profile is None - - profile = UserProfile( - username='Test_User', - full_name='Test T. User' - ) - user.profile = profile - user.profile.username = 'Different_Name' - assert user.profile.username == 'Different_Name' - assert profile.username == 'Different_Name' - - def test_case_insensitive_username(app): """Test case-insensitive uniqueness.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@example.org') - u2 = User(email='test2@example.org') - db.session.add(u1, u2) - profile1 = UserProfile(user=u1, username="INFO") - profile2 = UserProfile(user=u2, username="info") - db.session.add(profile1) - db.session.add(profile2) + u1 = User(email='test@example.org', username="INFO") + db.session.add(u1) + u2 = User(email='test2@example.org', username="info") + db.session.add(u2) pytest.raises(IntegrityError, db.session.commit) @@ -75,9 +50,8 @@ def test_case_preserving_username(app): """Test that username preserves the case.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@example.org') + u1 = User(email='test@example.org', username="InFo") db.session.add(u1) - db.session.add(UserProfile(user=u1, username="InFo")) db.session.commit() profile = UserProfile.get_by_username('info') assert profile.username == 'InFo' @@ -87,10 +61,8 @@ def test_delete_cascade(app): """Test that deletion of user, also removes profile.""" with app.app_context(): with db.session.begin_nested(): - u = User(email='test@example.org') + u = User(email='test@example.org', username="InFo") db.session.add(u) - p = UserProfile(user=u, username="InFo") - db.session.add(p) db.session.commit() assert UserProfile.get_by_userid(u.id) is not None @@ -98,57 +70,3 @@ def test_delete_cascade(app): db.session.commit() assert UserProfile.get_by_userid(u.id) is None - - -def test_create_profile(app): - """Test that userprofile can be patched using UserAccount constructor.""" - with app.app_context(): - user = User( - email='test@example.org', - ) - db.session.add(user) - db.session.commit() - - user_id = user.id - patch_user = User( - id=user_id, - email='updated_test@example.org', - profile={'full_name': 'updated_full_name'} - ) - db.session.merge(patch_user) - db.session.commit() - - patch_user = User( - id=user_id, - profile={'username': 'test_username'} - ) - db.session.merge(patch_user) - db.session.commit() - - user = User.query.filter(User.id == user_id).one() - assert user.profile.full_name == 'updated_full_name' - assert user.email == 'updated_test@example.org' - assert user.profile.username == 'test_username' - - -def test_create_profile_with_null(app): - """Test that creation with empty profile.""" - with app.app_context(): - user = User( - email='test@example.org', - ) - db.session.add(user) - db.session.commit() - - assert user.profile is None - user_id = user.id - - user = User( - id=user_id, - profile=None, - ) - db.session.merge(user) - db.session.commit() - - user = User.query.get(user_id) - assert user.profile is None diff --git a/tests/test_views.py b/tests/test_views.py index 03bfe9e..6c8c6ac 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -47,13 +47,15 @@ def test_profile_in_registration(base_app): 'password': 'test_password', 'profile.username': 'TestUser', 'profile.full_name': 'Test C. User', + 'profile.affiliations': 'Test Org', } resp = client.post(register_url, data=data, follow_redirects=True) with app.test_request_context(): user = User.query.filter_by(email='test_user@example.com').one() - assert user.profile.username == 'TestUser' - assert user.profile.full_name == 'Test C. User' + assert user.username == 'TestUser' + assert user.user_profile['full_name'] == 'Test C. User' + assert user.user_profile['affiliations'] == 'Test Org' with app.test_client() as client: resp = client.get(register_url) @@ -68,18 +70,6 @@ def test_profile_in_registration(base_app): assert 'profile.username' in resp.get_data(as_text=True) -def test_template_filter(app): - """Test template filter.""" - with app.app_context(): - user = User(email='test@example.com', password='test_password') - db.session.add(user) - db.session.commit() - user.profile = UserProfile(username='test_username', full_name='name') - db.session.commit() - - assert userprofile(user.profile.user_id) == user.profile - - def test_profile_view_not_accessible_without_login(app): """Test the user can't access profile settings page without logging in.""" with app.test_request_context(): @@ -107,18 +97,19 @@ def test_profile_view(app): # Valid submission should work resp = client.post(profile_url, data=prefix('profile', dict( username=test_usernames['valid'], - full_name='Valid Name', ))) + full_name='Valid Name', affiliations='Aff'))) assert resp.status_code == 200 data = resp.get_data(as_text=True) assert test_usernames['valid'] in data assert 'Valid' in data assert 'Name' in data + assert 'Aff' in data # Invalid submission should not save data resp = client.post(profile_url, data=prefix('profile', dict( username=test_usernames['invalid_characters'], - full_name='Valid Name', ))) + full_name='Valid Name', affiliations='Aff'))) assert resp.status_code == 200 assert test_usernames['invalid_characters'] in \ @@ -131,19 +122,20 @@ def test_profile_view(app): # Whitespace should be trimmed client.post(profile_url, data=prefix('profile', dict( username='{0} '.format(test_usernames['valid']), - full_name='Valid Name ', ))) + full_name='Valid Name ', affiliations=' Aff '))) resp = client.get(profile_url) assert resp.status_code == 200 data = resp.get_data(as_text=True) assert test_usernames['valid'] in data assert 'Valid Name ' not in data + assert ' Aff ' not in data def test_profile_name_exists(app): """Test the profile view.""" app.config['USERPROFILES_EMAIL_ENABLED'] = False - error_msg = 'Username already exists.' + error_msg = 'Username is not available.' with app.app_context(): profile_url = url_for('invenio_userprofiles.profile') @@ -156,7 +148,7 @@ def test_profile_name_exists(app): login(app, client, email=email1, password=password1) assert client.get(profile_url).status_code == 200 resp = client.post(profile_url, data=prefix('profile', dict( - username='existingname', full_name='Valid Name',))) + username='existingname', full_name='Valid Name', affiliations=''))) assert error_msg not in resp.get_data(as_text=True) # Create another user and try setting username to same as above user. @@ -167,7 +159,7 @@ def test_profile_name_exists(app): assert resp.status_code == 200 resp = client.post(profile_url, data=prefix('profile', dict( - username='existingname', full_name='Another name', + username='existingname', full_name='Another name', affiliations='' ))) assert resp.status_code == 200 assert error_msg in resp.get_data(as_text=True) @@ -189,7 +181,7 @@ def test_profile_case_change(app): assert resp.status_code == 200 data = prefix('profile', dict( - username='valid', full_name='Another name', )) + username='valid', full_name='Another name', affiliations='')) # Set the name first time resp = client.post(profile_url, data=data) @@ -203,7 +195,7 @@ def test_profile_case_change(app): # Change case of the username data = prefix('profile', dict( - username='Valid', full_name='Another name', )) + username='Valid', full_name='Another name', affiliations='')) resp = client.post(profile_url, data=data) assert resp.status_code == 200 @@ -258,6 +250,7 @@ def test_change_email(app): data = prefix('profile', dict( username='test', full_name='Test User', + affiliations='', email=app.config['TEST_USER_EMAIL'], email_repeat=app.config['TEST_USER_EMAIL'], )) @@ -301,6 +294,7 @@ def test_change_email_whitespace(app): data = prefix('profile', dict( username='test', full_name='Test User', + affiliations='', email=app.config['TEST_USER_EMAIL'], email_repeat=app.config['TEST_USER_EMAIL'], )) From 0586c29ad7cb6f80bf18842dfa73b28f6472c7d8 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 11:41:01 +0200 Subject: [PATCH 20/65] release: v2.0.0.dev1 --- CHANGES.rst | 5 +++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 187ec27..5d3bf3a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,11 @@ Changes ======= +Version 2.0.0.dev1 (released 2022-04-21) + +- Changes the profile backend to use the new Invenio-Accounts 2.0 profile + field instead of a separate database table. + Version 1.2.4 (released 2021-10-18) - Unpin Flask 2 diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index d779262..557343c 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '1.2.4' +__version__ = '2.0.0.dev1' __all__ = ( '__version__', From 23c2bfe0f0219cd34b3671e9e4545c967c23461c Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 17:26:09 +0200 Subject: [PATCH 21/65] views: add support for setting preferences * Adds basic support for setting visibility preferences. --- invenio_userprofiles/forms.py | 48 ++++++++- .../settings/profile.html | 101 +++++++++++++----- invenio_userprofiles/views.py | 27 ++++- 3 files changed, 146 insertions(+), 30 deletions(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 9e7e491..98448d6 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -14,7 +14,7 @@ from flask_security.forms import email_required, email_validator, \ unique_user_email from flask_wtf import FlaskForm -from wtforms import FormField, StringField, SubmitField +from wtforms import FormField, RadioField, StringField, SubmitField from wtforms.validators import DataRequired, EqualTo, Length, StopValidation, \ ValidationError @@ -176,6 +176,52 @@ def to_dict(self): return RegisterForm +class PreferencesForm(FlaskForm): + """Form for editing user profile.""" + + profile_proxy_cls = UserProfileProxy + + visibility = RadioField( + _('Profile visibility'), + choices=[ + ('public', _('Public')), + ('restricted', _('Hidden')), + ], + description=_( + "Public profiles can be found by other users via searches on " + "username, full name and affiliation. Hidden profiles cannot be" + " found by other users." + ) + ) + + email_visibility = RadioField( + _('Email visibility'), + choices=[ + ('public', _('Public')), + ('restricted', _('Hidden')), + ], + description=_( + "Public email visibility enables your profile to be found by " + "your email address." + ) + ) + + def process(self, formdata=None, obj=None, data=None, extra_filters=None, + **kwargs): + """Build a proxy around the object.""" + if obj is not None: + obj = self.profile_proxy_cls(obj) + super().process( + formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, + **kwargs + ) + + def populate_obj(self, user): + """Populates the obj.""" + user = self.profile_proxy_cls(user) + super().populate_obj(user) + + def confirm_register_form_factory(Form): """Factory for creating a confirm register form.""" class CsrfDisabledProfileForm(ProfileForm): diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html index 277c6b4..130a8b0 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html @@ -13,31 +13,80 @@ {% set panel_title = _("Profile") %} {% set panel_icon = "user icon" %} -{%- block settings_form %} -{%- if security.confirmable and not current_user.confirmed_at %} -
- {{ verification_form.csrf_token }} -
- {{ _("You have not yet verified your email address.") }} {{ verification_form.send_verification_email(class_="compact ui small basic button") }} +{%- block settings_content scoped %} +
+
+ + {%- block settings_content_title scoped %} + {%- if panel_icon %} + + {%- block settings_content_title_icon scoped %} + + {%- endblock %} + + {%- endif %} + {{ panel_title|default("") }} + {%- endblock %} + +
+ + {%- block settings_body scoped %} +
+ {%- block settings_form %} + {%- if security.confirmable and not current_user.confirmed_at %} + + {{ verification_form.csrf_token }} +
+ {{ _("You have not yet verified your email address.") }} {{ verification_form.send_verification_email(class_="compact ui small basic button") }} +
+ + + {%- endif %} + {%- set form = profile_form %} + {%- set read_only = config.USERPROFILES_READ_ONLY %} +
+ {%- for field in form %} + {%- if field.widget.input_type == 'hidden' %} + {{ field() }} + {%- elif not read_only or "repeat" not in field.id %} + {{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} + {%- endif %} + {%- endfor %} + {%- if not read_only %} +
+ {{ _('Cancel') }} + +
+ {%- endif %} +
+ {%- endblock settings_form %} +
+ {%- endblock settings_body %} + +
+ +
+
+ + {{ _("Preferences") }}
- - -{%- endif %} -{%- set form = profile_form %} -{%- set read_only = config.USERPROFILES_READ_ONLY %} -
- {%- for field in form %} - {%- if field.widget.input_type == 'hidden' %} - {{ field() }} - {%- elif not read_only or "repeat" not in field.id %} - {{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} - {%- endif %} - {%- endfor %} - {%- if not read_only %} -
- {{ _('Cancel') }} - +
+ {%- set form = preferences_form %} + {%- set read_only = config.USERPROFILES_READ_ONLY %} + + {%- for field in form %} + {%- if field.widget.input_type == 'hidden' %} + {{ field() }} + {%- else %} + {{ render_field(field, placeholder=field.label.text) }} + {%- endif %} + {%- endfor %} + {%- if not read_only %} +
+ {{ _('Cancel') }} + +
+ {%- endif %} +
- {%- endif %} - -{%- endblock settings_form %} +{% endblock %} diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 80a9670..8363914 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -20,8 +20,8 @@ from invenio_theme.proxies import current_theme_icons from speaklater import make_lazy_string -from .forms import EmailProfileForm, ProfileForm, VerificationForm, \ - confirm_register_form_factory, register_form_factory +from .forms import EmailProfileForm, PreferencesForm, ProfileForm, \ + VerificationForm, confirm_register_form_factory, register_form_factory from .models import UserProfileProxy blueprint = Blueprint( @@ -96,6 +96,8 @@ def profile(): # Create forms verification_form = VerificationForm(formdata=None, prefix="verification") profile_form = profile_form_factory() + preferences_form = PreferencesForm( + formdata=None, obj=current_user, prefix="preferences") # Process forms is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) @@ -104,11 +106,15 @@ def profile(): handle_profile_form(profile_form) elif form == 'verification': handle_verification_form(verification_form) + elif form == 'preferences' and not is_read_only: + handle_preferences_form(preferences_form) return render_template( current_app.config['USERPROFILES_PROFILE_TEMPLATE'], profile_form=profile_form, - verification_form=verification_form,) + verification_form=verification_form, + preferences_form=preferences_form + ) def profile_form_factory(): @@ -163,3 +169,18 @@ def handle_profile_form(form): else: # NOTE: Flash message after successful update of profile. flash(_('Profile was updated.'), category='success') + + +def handle_preferences_form(form): + """Handle preferences form.""" + if current_app.config.get("USERPROFILES_READ_ONLY", False): + return + + form.process(formdata=request.form) + + if form.validate_on_submit(): + form.populate_obj(current_user) + db.session.add(current_user) + current_app.extensions['security'].datastore.commit() + # NOTE: Flash message after successful update of profile. + flash(_('Preferences were updated.'), category='success') From b5dc576e84a4668cd8ea9722f63753a26599599b Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Thu, 21 Apr 2022 17:40:24 +0200 Subject: [PATCH 22/65] release: v2.0.0.dev2 --- invenio_userprofiles/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 557343c..6a3f07f 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.0.dev1' +__version__ = '2.0.0.dev2' __all__ = ( '__version__', From e387d8f8e53a7995e67ff064fa4556fae0f707d6 Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Mon, 25 Apr 2022 16:33:32 +0200 Subject: [PATCH 23/65] tests: support email-validator 1.2.0 and reserved domains --- tests/conftest.py | 2 +- tests/helpers.py | 6 ++++-- tests/test_models.py | 8 ++++---- tests/test_views.py | 16 ++++++++-------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 992f374..ce62381 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,7 +37,7 @@ def app_config(app_config): SECRET_KEY='testing_key', SQLALCHEMY_DATABASE_URI=os.getenv('SQLALCHEMY_DATABASE_URI', 'sqlite://'), - TEST_USER_EMAIL='test_user@example.com', + TEST_USER_EMAIL='test_user@test.org', TEST_USER_PASSWORD='test_password', TEST_USER_USERNAME='test', TESTING=True, diff --git a/tests/helpers.py b/tests/helpers.py index 762ea94..4d3a56a 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -16,10 +16,11 @@ def sign_up(app, client, email=None, password=None): with app.test_request_context(): register_url = url_for('security.register') - client.post(register_url, data=dict( + res = client.post(register_url, data=dict( email=email or app.config['TEST_USER_EMAIL'], password=password or app.config['TEST_USER_PASSWORD'], ), environ_base={'REMOTE_ADDR': '127.0.0.1'}) + assert res.status_code == 302 # redirect after signedup def login(app, client, email=None, password=None): @@ -27,7 +28,8 @@ def login(app, client, email=None, password=None): with app.test_request_context(): login_url = url_for('security.login') - client.post(login_url, data=dict( + res = client.post(login_url, data=dict( email=email or app.config['TEST_USER_EMAIL'], password=password or app.config['TEST_USER_PASSWORD'], )) + assert res.status_code == 302 # redirect after login diff --git a/tests/test_models.py b/tests/test_models.py index 9583724..d17a5c1 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -39,9 +39,9 @@ def test_case_insensitive_username(app): """Test case-insensitive uniqueness.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@example.org', username="INFO") + u1 = User(email='test@test.org', username="INFO") db.session.add(u1) - u2 = User(email='test2@example.org', username="info") + u2 = User(email='test2@test.org', username="info") db.session.add(u2) pytest.raises(IntegrityError, db.session.commit) @@ -50,7 +50,7 @@ def test_case_preserving_username(app): """Test that username preserves the case.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@example.org', username="InFo") + u1 = User(email='test@test.org', username="InFo") db.session.add(u1) db.session.commit() profile = UserProfile.get_by_username('info') @@ -61,7 +61,7 @@ def test_delete_cascade(app): """Test that deletion of user, also removes profile.""" with app.app_context(): with db.session.begin_nested(): - u = User(email='test@example.org', username="InFo") + u = User(email='test@test.org', username="InFo") db.session.add(u) db.session.commit() diff --git a/tests/test_views.py b/tests/test_views.py index 6c8c6ac..23fe195 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -43,7 +43,7 @@ def test_profile_in_registration(base_app): assert 'profile.full_name' in resp.get_data(as_text=True) data = { - 'email': 'test_user@example.com', + 'email': 'test_user@test.org', 'password': 'test_password', 'profile.username': 'TestUser', 'profile.full_name': 'Test C. User', @@ -52,7 +52,7 @@ def test_profile_in_registration(base_app): resp = client.post(register_url, data=data, follow_redirects=True) with app.test_request_context(): - user = User.query.filter_by(email='test_user@example.com').one() + user = User.query.filter_by(email='test_user@test.org').one() assert user.username == 'TestUser' assert user.user_profile['full_name'] == 'Test C. User' assert user.user_profile['affiliations'] == 'Test Org' @@ -60,7 +60,7 @@ def test_profile_in_registration(base_app): with app.test_client() as client: resp = client.get(register_url) data = { - 'email': 'newuser@example.com', + 'email': 'newuser@test.org', 'password': 'test_password', 'profile.username': 'TestUser', 'profile.full_name': 'Same Username', @@ -141,7 +141,7 @@ def test_profile_name_exists(app): profile_url = url_for('invenio_userprofiles.profile') # Create an existing user - email1 = 'exiting@example.org' + email1 = 'exiting@test.org' password1 = '123456' with app.test_client() as client: sign_up(app, client, email=email1, password=password1) @@ -234,7 +234,7 @@ def test_change_email(app): profile_url = url_for('invenio_userprofiles.profile') # Create an existing user - email1 = 'exiting@example.org' + email1 = 'exiting@test.org' password1 = '123456' with app.test_client() as client: sign_up(app, client, email=email1, password=password1) @@ -258,7 +258,7 @@ def test_change_email(app): # Test existing email of another user. data['profile-email_repeat'] = data['profile-email'] = email1 resp = client.post(profile_url, data=data) - assert 'exiting@example.org is already associated with an account.' \ + assert 'exiting@test.org is already associated with an account.' \ in resp.get_data(as_text=True) # Test empty email @@ -272,8 +272,8 @@ def test_change_email(app): assert "Invalid email address" in resp.get_data(as_text=True) # Test different emails - data['profile-email_repeat'] = 'typo@example.org' - data['profile-email'] = 'new@example.org' + data['profile-email_repeat'] = 'typo@test.org' + data['profile-email'] = 'new@test.org' resp = client.post(profile_url, data=data) assert 'Email addresses do not match.' in resp.get_data(as_text=True) From 145d22754749bcca5a45087f7f9ce972f65eca4d Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Mon, 25 Apr 2022 14:44:26 +0200 Subject: [PATCH 24/65] views: mark user as changed on update --- invenio_userprofiles/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 8363914..9793855 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -150,14 +150,15 @@ def handle_profile_form(form): if form.validate_on_submit(): email_changed = False + datastore = current_app.extensions['security'].datastore with db.session.begin_nested(): if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ form.email.data != current_user.email: email_changed = True form.populate_obj(current_user) - db.session.add(current_user) - current_app.extensions['security'].datastore.commit() + datastore.mark_changed(id(db.session), uid=current_user.id) + datastore.commit() if email_changed: send_confirmation_instructions(current_user) From 0997f0b86957a619a5de4ae2038e7d2279b52962 Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Tue, 26 Apr 2022 12:18:09 +0200 Subject: [PATCH 25/65] dependencies: bump invenio-accounts --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 9f60e5e..553beed 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,7 @@ packages = find: python_requires = >=3.6 zip_safe = False install_requires = - invenio-accounts>=2.0.0.dev8 + invenio-accounts>=2.0.0.dev10 [options.extras_require] tests = From 69cbe381a35aca98d398a9673af351b672d41b70 Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Tue, 26 Apr 2022 12:28:36 +0200 Subject: [PATCH 26/65] release: v2.0.0.dev3 --- invenio_userprofiles/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 6a3f07f..17fab68 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.0.dev2' +__version__ = '2.0.0.dev3' __all__ = ( '__version__', From a6b1a0cbb24ce0a2cc955785622f2a7b7d908dff Mon Sep 17 00:00:00 2001 From: David Eckhard Date: Tue, 3 May 2022 14:18:36 +0200 Subject: [PATCH 27/65] alembic: migrate data to invenio-accounts user table --- .../alembic/41157f1933d6_remove_table.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py index 0908bca..a62c79c 100644 --- a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py +++ b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py @@ -1,12 +1,15 @@ # # This file is part of Invenio. # Copyright (C) 2016-2018 CERN. +# Copyright (C) 2022 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. """Remove table.""" +import json + import sqlalchemy as sa from alembic import op @@ -19,6 +22,32 @@ def upgrade(): """Upgrade database.""" + # Migrate username and full_name to invenio_accounts table. + connection = op.get_bind() + results = connection.execute( + "SELECT user_id, username, displayname, full_name " + "FROM userprofiles_userprofile;" + ).all() + + for r in results: + user_id, username, displayname, full_name = r + profile_data = { + "full_name": full_name, + } + query = ( + "UPDATE accounts_user SET " + " username = '{username}', " + " displayname = '{displayname}', " + " profile = '{profile_data_string}' " + "WHERE accounts_user.id = {user_id};".format( + username=username, + displayname=displayname, + profile_data_string=json.dumps(profile_data), + user_id=user_id, + ) + ) + op.execute(query) + op.drop_table('userprofiles_userprofile') From 62846701f0132a08fecd7a68ece62e5c200e387d Mon Sep 17 00:00:00 2001 From: David Eckhard Date: Wed, 4 May 2022 09:32:08 +0200 Subject: [PATCH 28/65] alembic: add preferences to migration script --- .../alembic/41157f1933d6_remove_table.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py index a62c79c..844ec4f 100644 --- a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py +++ b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py @@ -34,15 +34,22 @@ def upgrade(): profile_data = { "full_name": full_name, } + preferences = { + "visibility": "restricted", + "email_visibility": "restricted" + } + query = ( "UPDATE accounts_user SET " " username = '{username}', " " displayname = '{displayname}', " - " profile = '{profile_data_string}' " + " profile = '{profile_data_string}', " + " preferences = '{preferences}' " "WHERE accounts_user.id = {user_id};".format( username=username, displayname=displayname, profile_data_string=json.dumps(profile_data), + preferences=json.dumps(preferences), user_id=user_id, ) ) From 4fdb87365c07b12385cbb4d8ded53c3dfae07a90 Mon Sep 17 00:00:00 2001 From: Lars Holm Nielsen Date: Mon, 23 May 2022 12:51:29 +0200 Subject: [PATCH 29/65] release: v2.0.0 --- CHANGES.rst | 4 +++- invenio_userprofiles/__init__.py | 2 +- setup.cfg | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5d3bf3a..0d8d691 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,11 +8,13 @@ Changes ======= -Version 2.0.0.dev1 (released 2022-04-21) +Version 2.0.0 (released 2022-05-23) - Changes the profile backend to use the new Invenio-Accounts 2.0 profile field instead of a separate database table. +- Adds support for allowing users to change their visibility settings. + Version 1.2.4 (released 2021-10-18) - Unpin Flask 2 diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 17fab68..80a0014 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.0.dev3' +__version__ = '2.0.0' __all__ = ( '__version__', diff --git a/setup.cfg b/setup.cfg index 553beed..525fb46 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,7 @@ packages = find: python_requires = >=3.6 zip_safe = False install_requires = - invenio-accounts>=2.0.0.dev10 + invenio-accounts>=2.0.0 [options.extras_require] tests = From 5c205a6d8041c4381c71f2f0c4b184649594cfb1 Mon Sep 17 00:00:00 2001 From: Mojib Wali <44528277+mb-wali@users.noreply.github.com> Date: Fri, 27 May 2022 09:12:20 +0200 Subject: [PATCH 30/65] i18n: extract messages (#138) --- .gitignore | 1 - MANIFEST.in | 2 +- .../translations/messages.pot | 169 ++++++++++++++++++ setup.cfg | 1 + 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 invenio_userprofiles/translations/messages.pot diff --git a/.gitignore b/.gitignore index 1a3474f..f32b3b9 100644 --- a/.gitignore +++ b/.gitignore @@ -48,7 +48,6 @@ coverage.xml # Translations *.mo -*.pot # Django stuff: *.log diff --git a/MANIFEST.in b/MANIFEST.in index 413a61e..2be7a19 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -24,6 +24,6 @@ recursive-include docs Makefile recursive-include examples *.py *.sh *.html *.txt recursive-include invenio_userprofiles *.html recursive-include invenio_userprofiles *.mo -recursive-include invenio_userprofiles *.po *.pot +recursive-include invenio_userprofiles *.po *.pot *.mo recursive-include invenio_userprofiles *.py recursive-include tests *.py diff --git a/invenio_userprofiles/translations/messages.pot b/invenio_userprofiles/translations/messages.pot new file mode 100644 index 0000000..41c702d --- /dev/null +++ b/invenio_userprofiles/translations/messages.pot @@ -0,0 +1,169 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.0\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-05-27 09:02+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.1\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:47 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:49 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:53 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:59 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:65 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:83 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:131 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:133 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:138 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:147 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:185 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:187 invenio_userprofiles/forms.py:200 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:188 invenio_userprofiles/forms.py:201 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "" +"Public profiles can be found by other users via searches on username, " +"full name and affiliation. Hidden profiles cannot be found by other " +"users." +msgstr "" + +#: invenio_userprofiles/forms.py:198 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:87 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:92 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:141 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:166 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. " +"Please check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:172 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:86 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:87 +msgid "Update preferences" +msgstr "" + diff --git a/setup.cfg b/setup.cfg index 525fb46..ba5d6a6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,6 +67,7 @@ universal = 1 [compile_catalog] directory = invenio_userprofiles/translations/ +use-fuzzy = True [extract_messages] copyright_holder = CERN From 8a69383bfc8d6a941b73ba3208ed9f7b08491fcf Mon Sep 17 00:00:00 2001 From: Mojib Wali <44528277+mb-wali@users.noreply.github.com> Date: Fri, 3 Jun 2022 09:11:02 +0200 Subject: [PATCH 31/65] i18n: add german translations (#140) Co-authored-by: mojib --- .../translations/de/LC_MESSAGES/messages.po | 136 ++++++++++++------ 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po index 39fb54f..10e47b2 100644 --- a/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po @@ -1,112 +1,148 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2020 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2020. +# FIRST AUTHOR , 2022. # # Translators: -# Alizee Pace , 2016 # Tibor Simko , 2016 -# Mojib Wali , 2021 -# Chriz Uniba , 2021 +# Alexander Gruber , 2022 +# Mojib Wali , 2022 +# Hermann Schranzhofer , 2022 +# chriz_uniba , 2022 # +#, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.2.0a3\n" +"Project-Id-Version: invenio-userprofiles 2.0.0\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2020-07-20 15:31+0300\n" +"POT-Creation-Date: 2022-05-27 09:02+0200\n" "PO-Revision-Date: 2016-08-18 14:14+0000\n" -"Last-Translator: Chriz Uniba , 2021\n" +"Last-Translator: chriz_uniba , 2022\n" "Language-Team: German (https://www.transifex.com/inveniosoftware/teams/23537/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.8.0\n" +"Generated-By: Babel 2.10.1\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. NOTE: Form field label -#: invenio_userprofiles/admin.py:45 invenio_userprofiles/forms.py:48 +#: invenio_userprofiles/forms.py:47 msgid "Username" -msgstr "Benutzername" - -#: invenio_userprofiles/admin.py:52 -msgid "User Management" -msgstr "Benutzerverwaltung" +msgstr "Kontoname" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:50 +#: invenio_userprofiles/forms.py:49 #, python-format msgid "Required. %(username_rules)s" msgstr "Erforderlich. %(username_rules)s" -#: invenio_userprofiles/forms.py:52 +#: invenio_userprofiles/forms.py:53 msgid "Username not provided." -msgstr "Benutzername nicht angegeben." +msgstr "Kontoname nicht angegeben." #. NOTE: Form label -#: invenio_userprofiles/forms.py:57 +#: invenio_userprofiles/forms.py:59 msgid "Full name" msgstr "Vollständiger Name" +#. NOTE: Form label +#: invenio_userprofiles/forms.py:65 +msgid "Affiliations" +msgstr "Zugehörigkeiten" + #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:73 -msgid "Username already exists." -msgstr "Benutzername existiert bereits." +#: invenio_userprofiles/forms.py:83 +msgid "Username is not available." +msgstr "Der Kontoname ist nicht verfügbar." #. NOTE: Form field label -#: invenio_userprofiles/forms.py:83 +#: invenio_userprofiles/forms.py:119 msgid "Email address" msgstr "E-Mail-Adresse" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:131 msgid "Re-enter email address" msgstr "E-Mail-Adresse erneut eingeben" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:97 +#: invenio_userprofiles/forms.py:133 msgid "Please re-enter your email address." msgstr "Bitte geben Sie Ihre E-Mail-Adresse erneut ein." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:102 +#: invenio_userprofiles/forms.py:138 msgid "Email addresses do not match." msgstr "Die E-Mail-Adressen stimmen nicht überein." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:111 +#: invenio_userprofiles/forms.py:147 msgid "Resend verification email" msgstr "Verifizierungs-E-Mail erneut senden" -#: invenio_userprofiles/validators.py:20 +#: invenio_userprofiles/forms.py:185 +msgid "Profile visibility" +msgstr "Sichtbarkeit des Profils" + +#: invenio_userprofiles/forms.py:187 invenio_userprofiles/forms.py:200 +msgid "Public" +msgstr "Öffentlich" + +#: invenio_userprofiles/forms.py:188 invenio_userprofiles/forms.py:201 +msgid "Hidden" +msgstr "Verborgen" + +#: invenio_userprofiles/forms.py:190 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"\"Öffentliche\" Profile können über die Suche anhand des Kontonamens, " +"vollständigen Namens und der Zugehörigkeit von anderen gefunden werden. " +"\"Verborgene\" Profile können von anderen nicht gefunden werden." + +#: invenio_userprofiles/forms.py:198 +msgid "Email visibility" +msgstr "Sichtbarkeit der E-Mail" + +#: invenio_userprofiles/forms.py:203 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" +"Die Wahl \"öffentlich\" ermöglicht es, dass Ihr Profil über Ihre E-Mail " +"Adresse gefunden wird." + +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." msgstr "" -"Der Benutzername muss mit einem Buchstaben beginnen, mindestens drei Zeichen" -" lang sein und darf nur alphanumerische Zeichen, Bindestriche und " +"Der Kontoname muss mit einem Buchstaben beginnen, mindestens drei Zeichen " +"lang sein und darf nur alphanumerische Zeichen, Bindestriche und " "Unterstriche enthalten." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:82 +#: invenio_userprofiles/views.py:87 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profil" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:12 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:12 -#: invenio_userprofiles/views.py:85 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:92 msgid "Profile" msgstr "Profil" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:130 +#: invenio_userprofiles/views.py:141 msgid "Verification email sent." msgstr "Verifizierungs-E-Mail gesendet." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:157 +#: invenio_userprofiles/views.py:166 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -116,21 +152,35 @@ msgstr "" "%(email)s gesendet. Bitte überprüfen Sie diese." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:163 +#: invenio_userprofiles/views.py:172 msgid "Profile was updated." msgstr "Das Profil wurde aktualisiert." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:17 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:17 +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +msgid "Preferences were updated." +msgstr "Die Einstellungen wurden aktualisiert." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." msgstr "Sie haben Ihre E-Mail-Adresse noch nicht verifiziert." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:25 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:25 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:86 msgid "Cancel" msgstr "Abbrechen" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:26 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:26 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" msgstr "Profil aktualisieren" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "Einstellungen" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:87 +msgid "Update preferences" +msgstr "Einstellungen aktualisieren" From d07241d61228c47e47025a269ba9a031efc0fa11 Mon Sep 17 00:00:00 2001 From: Manuel Alejandro Date: Wed, 8 Jun 2022 16:33:02 +0200 Subject: [PATCH 32/65] alembic: added migration dependency --- invenio_userprofiles/alembic/41157f1933d6_remove_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py index 844ec4f..f6364b7 100644 --- a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py +++ b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py @@ -17,7 +17,7 @@ revision = '41157f1933d6' down_revision = 'c25ef2c50ffa' branch_labels = () -depends_on = None +depends_on = 'eb9743315a9d' # invenio-accounts: add_userprofile def upgrade(): From 97648d2d716155e232808fc70a7113c8c6519945 Mon Sep 17 00:00:00 2001 From: Alex Ioannidis Date: Fri, 10 Jun 2022 10:27:35 +0200 Subject: [PATCH 33/65] release: v2.0.1 --- CHANGES.rst | 6 +++++- invenio_userprofiles/__init__.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0d8d691..f198d6e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,6 @@ .. This file is part of Invenio. - Copyright (C) 2015-2018 CERN. + Copyright (C) 2015-2022 CERN. Invenio is free software; you can redistribute it and/or modify it under the terms of the MIT License; see LICENSE file for more details. @@ -8,6 +8,10 @@ Changes ======= +Version 2.0.1 (released 2022-06-10) + +- Fixes the Alembic recipe dependency for removing the userprofiles table. + Version 2.0.0 (released 2022-05-23) - Changes the profile backend to use the new Invenio-Accounts 2.0 profile diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 80a0014..2075920 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.0' +__version__ = '2.0.1' __all__ = ( '__version__', From 407fc7f21553011bd570a57fab6c4ea8bd53c375 Mon Sep 17 00:00:00 2001 From: pablo Date: Tue, 28 Jun 2022 16:16:16 +0200 Subject: [PATCH 34/65] Profile settings: style radio fields removing bullet points * closes: inveniosoftware/invenio-app-rdm#1764 --- .../templates/invenio_userprofiles/settings/_macros.html | 4 ++-- .../semantic-ui/invenio_userprofiles/settings/_macros.html | 4 ++-- .../semantic-ui/invenio_userprofiles/settings/profile.html | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html index bbf20a3..8754b50 100644 --- a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html +++ b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html @@ -7,11 +7,11 @@ under the terms of the MIT License; see LICENSE file for more details. #} -{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True) %} +{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True, field_class="form-control") %}
{{ field.label }} {%- set extras = dict(autofocus="") if autofocus else dict() %} - {{field(class_="form-control", disabled=not enabled, placeholder=placeholder, **extras)}} + {{field(class_=field_class, disabled=not enabled, placeholder=placeholder, **extras)}} {%- if icon %} {%- endif %} diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html index 0545314..dcd4410 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/_macros.html @@ -7,11 +7,11 @@ under the terms of the MIT License; see LICENSE file for more details. #} -{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True) %} +{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True, field_class="form-control") %}
{{ field.label }} {%- set extras = dict(autofocus="") if autofocus else dict() %} - {{field(class_="form-control", disabled=not enabled, placeholder=placeholder, **extras)}} + {{field(class_=field_class, disabled=not enabled, placeholder=placeholder, **extras)}} {%- if icon %} {%- endif %} diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html index 130a8b0..9143686 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html @@ -78,7 +78,7 @@ {%- if field.widget.input_type == 'hidden' %} {{ field() }} {%- else %} - {{ render_field(field, placeholder=field.label.text) }} + {{ render_field(field, placeholder=field.label.text, field_class="form-control no-dots-list pl-0") }} {%- endif %} {%- endfor %} {%- if not read_only %} From d05fbc8535be92cb07dbac12e1f16c2c4b3a8bc9 Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Fri, 1 Jul 2022 14:59:02 +0200 Subject: [PATCH 35/65] release: v2.0.2 --- CHANGES.rst | 4 ++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index f198d6e..d90bcaa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 2.0.2 (released 2022-07-01) + +- Style radio buttons and remove dotted bullet points in settings page. + Version 2.0.1 (released 2022-06-10) - Fixes the Alembic recipe dependency for removing the userprofiles table. diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 2075920..145052a 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -28,7 +28,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.1' +__version__ = '2.0.2' __all__ = ( '__version__', From 2cdf2e549aeff104070802f61680f23995b78c09 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:55:45 +0200 Subject: [PATCH 36/65] migrate to use black as opinionated auto formater --- .editorconfig | 10 - docs/conf.py | 206 +++++++-------- invenio_userprofiles/__init__.py | 14 +- .../alembic/41157f1933d6_remove_table.py | 42 ++-- ...71634726ec7e_create_userprofiles_branch.py | 6 +- ...c25ef2c50ffa_create_userprofiles_tables.py | 27 +- invenio_userprofiles/api.py | 2 +- invenio_userprofiles/config.py | 4 +- invenio_userprofiles/ext.py | 42 ++-- invenio_userprofiles/forms.py | 108 ++++---- invenio_userprofiles/models.py | 24 +- invenio_userprofiles/validators.py | 7 +- invenio_userprofiles/views.py | 104 ++++---- pytest.ini | 11 - setup.cfg | 9 + tests/conftest.py | 21 +- tests/helpers.py | 31 ++- tests/test_api.py | 7 +- tests/test_forms.py | 60 +++-- tests/test_invenio_userprofile.py | 21 +- tests/test_models.py | 26 +- tests/test_validators.py | 16 +- tests/test_views.py | 234 +++++++++++------- 23 files changed, 557 insertions(+), 475 deletions(-) delete mode 100644 pytest.ini diff --git a/.editorconfig b/.editorconfig index 15c4c39..8db4643 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,16 +15,6 @@ insert_final_newline = true trim_trailing_whitespace = true charset = utf-8 -# Python files -[*.py] -indent_size = 4 -# isort plugin configuration -known_first_party = invenio_userprofiles -known_third_party = invenio_accounts, invenio_db, invenio_i18n -multi_line_output = 2 -default_section = THIRDPARTY -skip = .eggs - # RST files (used by sphinx) [*.rst] indent_size = 4 diff --git a/docs/conf.py b/docs/conf.py index 7abd286..6e1f173 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,45 +16,45 @@ from invenio_userprofiles import __version__ # Plug example application into module path -sys.path.append('examples') +sys.path.append("examples") # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Do not warn on external images. -suppress_warnings = ['image.nonlocal_uri'] +suppress_warnings = ["image.nonlocal_uri"] # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', + "sphinx.ext.autodoc", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Invenio-UserProfiles' -copyright = u'2015, CERN' -author = u'CERN' +project = "Invenio-UserProfiles" +copyright = "2015, CERN" +author = "CERN" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -77,9 +77,9 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -87,46 +87,46 @@ # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- -html_theme = 'alabaster' +html_theme = "alabaster" html_theme_options = { - 'description': 'User profiles module for Invenio.', - 'github_user': 'inveniosoftware', - 'github_repo': 'invenio-userprofiles', - 'github_button': False, - 'github_banner': True, - 'show_powered_by': False, - 'extra_nav_links': { - 'invenio-userprofiles@GitHub': 'https://github.com/inveniosoftware/invenio-userprofiles', - 'invenio-userprofiles@PyPI': 'https://pypi.python.org/pypi/invenio-userprofiles/', - } + "description": "User profiles module for Invenio.", + "github_user": "inveniosoftware", + "github_repo": "invenio-userprofiles", + "github_button": False, + "github_banner": True, + "show_powered_by": False, + "extra_nav_links": { + "invenio-userprofiles@GitHub": "https://github.com/inveniosoftware/invenio-userprofiles", + "invenio-userprofiles@PyPI": "https://pypi.python.org/pypi/invenio-userprofiles/", + }, } # The theme to use for HTML and HTML Help pages. See the documentation for @@ -135,146 +135,148 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', - 'searchbox.html', - 'donate.html', + "**": [ + "about.html", + "navigation.html", + "relations.html", + "searchbox.html", + "donate.html", ] } # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'invenio-userprofiles_namedoc' +htmlhelp_basename = "invenio-userprofiles_namedoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'invenio-userprofiles.tex', u'invenio-userprofiles Documentation', - u'CERN', 'manual'), + ( + master_doc, + "invenio-userprofiles.tex", + "invenio-userprofiles Documentation", + "CERN", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -282,12 +284,17 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'invenio-userprofiles', u'invenio-userprofiles Documentation', - [author], 1) + ( + master_doc, + "invenio-userprofiles", + "invenio-userprofiles Documentation", + [author], + 1, + ) ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -296,29 +303,34 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'invenio-userprofiles', u'Invenio-UserProfiles Documentation', - author, 'invenio-userprofiles', 'User profiles module for Invenio.', - 'Miscellaneous'), + ( + master_doc, + "invenio-userprofiles", + "Invenio-UserProfiles Documentation", + author, + "invenio-userprofiles", + "User profiles module for Invenio.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), - 'invenio_accounts': - ('https://invenio-accounts.readthedocs.io/en/latest/', None) + "python": ("https://docs.python.org/3", None), + "invenio_accounts": ("https://invenio-accounts.readthedocs.io/en/latest/", None), } # Autodoc configuraton. -autoclass_content = 'both' +autoclass_content = "both" diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 145052a..44c43ba 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -16,24 +16,26 @@ try: # Werkzeug <2.1 from werkzeug import security + security.safe_str_cmp except AttributeError: # Werkzeug >=2.1 import hmac from werkzeug import security + security.safe_str_cmp = hmac.compare_digest from .api import current_userprofile from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = '2.0.2' +__version__ = "2.0.2" __all__ = ( - '__version__', - 'current_userprofile', - 'InvenioUserProfiles', - 'UserProfile', - 'UserProfileProxy', + "__version__", + "current_userprofile", + "InvenioUserProfiles", + "UserProfile", + "UserProfileProxy", ) diff --git a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py index f6364b7..5da82db 100644 --- a/invenio_userprofiles/alembic/41157f1933d6_remove_table.py +++ b/invenio_userprofiles/alembic/41157f1933d6_remove_table.py @@ -14,10 +14,10 @@ from alembic import op # revision identifiers, used by Alembic. -revision = '41157f1933d6' -down_revision = 'c25ef2c50ffa' +revision = "41157f1933d6" +down_revision = "c25ef2c50ffa" branch_labels = () -depends_on = 'eb9743315a9d' # invenio-accounts: add_userprofile +depends_on = "eb9743315a9d" # invenio-accounts: add_userprofile def upgrade(): @@ -34,10 +34,7 @@ def upgrade(): profile_data = { "full_name": full_name, } - preferences = { - "visibility": "restricted", - "email_visibility": "restricted" - } + preferences = {"visibility": "restricted", "email_visibility": "restricted"} query = ( "UPDATE accounts_user SET " @@ -55,29 +52,28 @@ def upgrade(): ) op.execute(query) - op.drop_table('userprofiles_userprofile') + op.drop_table("userprofiles_userprofile") def downgrade(): """Downgrade database.""" op.create_table( - 'userprofiles_userprofile', - sa.Column( - 'user_id', sa.INTEGER(), autoincrement=False, nullable=False), + "userprofiles_userprofile", + sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False), sa.Column( - 'username', sa.VARCHAR(length=255), autoincrement=False, - nullable=True), + "username", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), sa.Column( - 'displayname', sa.VARCHAR(length=255), autoincrement=False, - nullable=True), + "displayname", sa.VARCHAR(length=255), autoincrement=False, nullable=True + ), sa.Column( - 'full_name', sa.VARCHAR(length=255), autoincrement=False, - nullable=False), + "full_name", sa.VARCHAR(length=255), autoincrement=False, nullable=False + ), sa.ForeignKeyConstraint( - ['user_id'], ['accounts_user.id'], - name='fk_userprofiles_userprofile_user_id_accounts_user'), - sa.PrimaryKeyConstraint('user_id', name='pk_userprofiles_userprofile'), - sa.UniqueConstraint( - 'username', - name='uq_userprofiles_userprofile_username') + ["user_id"], + ["accounts_user.id"], + name="fk_userprofiles_userprofile_user_id_accounts_user", + ), + sa.PrimaryKeyConstraint("user_id", name="pk_userprofiles_userprofile"), + sa.UniqueConstraint("username", name="uq_userprofiles_userprofile_username"), ) diff --git a/invenio_userprofiles/alembic/71634726ec7e_create_userprofiles_branch.py b/invenio_userprofiles/alembic/71634726ec7e_create_userprofiles_branch.py index 9ddacf2..bf2cea8 100644 --- a/invenio_userprofiles/alembic/71634726ec7e_create_userprofiles_branch.py +++ b/invenio_userprofiles/alembic/71634726ec7e_create_userprofiles_branch.py @@ -12,10 +12,10 @@ from alembic import op # revision identifiers, used by Alembic. -revision = '71634726ec7e' +revision = "71634726ec7e" down_revision = None -branch_labels = (u'invenio_userprofiles',) -depends_on = 'dbdbc1b19cf2' +branch_labels = ("invenio_userprofiles",) +depends_on = "dbdbc1b19cf2" def upgrade(): diff --git a/invenio_userprofiles/alembic/c25ef2c50ffa_create_userprofiles_tables.py b/invenio_userprofiles/alembic/c25ef2c50ffa_create_userprofiles_tables.py index f002c33..f133020 100644 --- a/invenio_userprofiles/alembic/c25ef2c50ffa_create_userprofiles_tables.py +++ b/invenio_userprofiles/alembic/c25ef2c50ffa_create_userprofiles_tables.py @@ -12,26 +12,29 @@ from alembic import op # revision identifiers, used by Alembic. -revision = 'c25ef2c50ffa' -down_revision = '71634726ec7e' +revision = "c25ef2c50ffa" +down_revision = "71634726ec7e" branch_labels = () -depends_on = '9848d0149abd' +depends_on = "9848d0149abd" def upgrade(): """Upgrade database.""" op.create_table( - 'userprofiles_userprofile', - sa.Column('user_id', sa.Integer(), nullable=False), - sa.Column('username', sa.String(length=255), nullable=True), - sa.Column('displayname', sa.String(length=255), nullable=True), - sa.Column('full_name', sa.String(length=255), nullable=False), - sa.ForeignKeyConstraint(['user_id'], [u'accounts_user.id'], ), - sa.PrimaryKeyConstraint('user_id'), - sa.UniqueConstraint('username') + "userprofiles_userprofile", + sa.Column("user_id", sa.Integer(), nullable=False), + sa.Column("username", sa.String(length=255), nullable=True), + sa.Column("displayname", sa.String(length=255), nullable=True), + sa.Column("full_name", sa.String(length=255), nullable=False), + sa.ForeignKeyConstraint( + ["user_id"], + ["accounts_user.id"], + ), + sa.PrimaryKeyConstraint("user_id"), + sa.UniqueConstraint("username"), ) def downgrade(): """Downgrade database.""" - op.drop_table('userprofiles_userprofile') + op.drop_table("userprofiles_userprofile") diff --git a/invenio_userprofiles/api.py b/invenio_userprofiles/api.py index e850641..d4dc3b4 100644 --- a/invenio_userprofiles/api.py +++ b/invenio_userprofiles/api.py @@ -28,7 +28,7 @@ def _get_current_userprofile(): """ warn( "current_userprofile is deprecated, use current_user instead", - DeprecationWarning + DeprecationWarning, ) return UserProfileProxy(current_user) diff --git a/invenio_userprofiles/config.py b/invenio_userprofiles/config.py index fc947c9..fb3e078 100644 --- a/invenio_userprofiles/config.py +++ b/invenio_userprofiles/config.py @@ -17,10 +17,10 @@ USERPROFILES_EXTEND_SECURITY_FORMS = False """Extend the Invenio-Accounts user registration forms.""" -USERPROFILES_PROFILE_TEMPLATE = 'invenio_userprofiles/settings/profile.html' +USERPROFILES_PROFILE_TEMPLATE = "invenio_userprofiles/settings/profile.html" """Default profile template.""" -USERPROFILES_PROFILE_URL = '/account/settings/profile/' +USERPROFILES_PROFILE_URL = "/account/settings/profile/" """Default profile URL endpoint.""" USERPROFILES_BASE_TEMPLATE = None diff --git a/invenio_userprofiles/ext.py b/invenio_userprofiles/ext.py index 1825ae4..bcad821 100644 --- a/invenio_userprofiles/ext.py +++ b/invenio_userprofiles/ext.py @@ -25,40 +25,42 @@ def init_app(self, app): self.init_config(app) # Register current_profile - app.context_processor(lambda: dict( - current_userprofile=current_userprofile)) + app.context_processor(lambda: dict(current_userprofile=current_userprofile)) - app.extensions['invenio-userprofiles'] = self + app.extensions["invenio-userprofiles"] = self def init_config(self, app): """Initialize configuration.""" excludes = [ - 'USERPROFILES_BASE_TEMPLATE', - 'USERPROFILES_SETTINGS_TEMPLATE', + "USERPROFILES_BASE_TEMPLATE", + "USERPROFILES_SETTINGS_TEMPLATE", ] for k in dir(config): - if k.startswith('USERPROFILES_') and k not in excludes: + if k.startswith("USERPROFILES_") and k not in excludes: app.config.setdefault(k, getattr(config, k)) - app.config.setdefault('USERPROFILES', True) + app.config.setdefault("USERPROFILES", True) app.config.setdefault( - 'USERPROFILES_BASE_TEMPLATE', - app.config.get('BASE_TEMPLATE', - 'invenio_userprofiles/base.html')) + "USERPROFILES_BASE_TEMPLATE", + app.config.get("BASE_TEMPLATE", "invenio_userprofiles/base.html"), + ) app.config.setdefault( - 'USERPROFILES_SETTINGS_TEMPLATE', - app.config.get('SETTINGS_TEMPLATE', - 'invenio_userprofiles/settings/base.html')) + "USERPROFILES_SETTINGS_TEMPLATE", + app.config.get( + "SETTINGS_TEMPLATE", "invenio_userprofiles/settings/base.html" + ), + ) - if app.config['USERPROFILES_EXTEND_SECURITY_FORMS']: + if app.config["USERPROFILES_EXTEND_SECURITY_FORMS"]: app.config.setdefault( - 'USERPROFILES_REGISTER_USER_BASE_TEMPLATE', + "USERPROFILES_REGISTER_USER_BASE_TEMPLATE", app.config.get( - 'SECURITY_REGISTER_USER_TEMPLATE', - 'invenio_accounts/register_user.html' - ) + "SECURITY_REGISTER_USER_TEMPLATE", + "invenio_accounts/register_user.html", + ), ) - app.config['SECURITY_REGISTER_USER_TEMPLATE'] = \ - 'invenio_userprofiles/register_user.html' + app.config[ + "SECURITY_REGISTER_USER_TEMPLATE" + ] = "invenio_userprofiles/register_user.html" diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 98448d6..e6e697d 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -11,12 +11,16 @@ from flask import current_app from flask_babelex import lazy_gettext as _ from flask_login import current_user -from flask_security.forms import email_required, email_validator, \ - unique_user_email +from flask_security.forms import email_required, email_validator, unique_user_email from flask_wtf import FlaskForm from wtforms import FormField, RadioField, StringField, SubmitField -from wtforms.validators import DataRequired, EqualTo, Length, StopValidation, \ - ValidationError +from wtforms.validators import ( + DataRequired, + EqualTo, + Length, + StopValidation, + ValidationError, +) from .models import UserProfileProxy from .validators import USERNAME_RULES, validate_username @@ -44,27 +48,26 @@ class ProfileForm(FlaskForm): username = StringField( # NOTE: Form field label - _('Username'), + _("Username"), # NOTE: Form field help text - description=_('Required. %(username_rules)s', - username_rules=USERNAME_RULES), - validators=[ - Length(max=50), - DataRequired(message=_('Username not provided.')) - ], - filters=[strip_filter], ) + description=_("Required. %(username_rules)s", username_rules=USERNAME_RULES), + validators=[Length(max=50), DataRequired(message=_("Username not provided."))], + filters=[strip_filter], + ) full_name = StringField( # NOTE: Form label - _('Full name'), + _("Full name"), validators=[Length(max=255)], - filters=[strip_filter], ) + filters=[strip_filter], + ) affiliations = StringField( # NOTE: Form label - _('Affiliations'), + _("Affiliations"), validators=[Length(max=255)], - filters=[strip_filter], ) + filters=[strip_filter], + ) def validate_username(self, field): """Wrap username validator for WTForms.""" @@ -74,13 +77,13 @@ def validate_username(self, field): raise ValidationError(e) # Check if username is already taken. - datastore = current_app.extensions['security'].datastore + datastore = current_app.extensions["security"].datastore user = datastore.find_user(username=field.data) if user is None: return # NOTE: Form validation error. - msg = _('Username is not available.') + msg = _("Username is not available.") if current_user.is_anonymous: # We are handling a new sign up (i.e. anonymous user) AND a @@ -89,20 +92,17 @@ def validate_username(self, field): else: # We are handling a user editing their profile AND a # the username already exists. - is_same_user = \ - current_user.get_id() == str(user.id) + is_same_user = current_user.get_id() == str(user.id) if not is_same_user: # Username already taken by another user. raise ValidationError(msg) - def process(self, formdata=None, obj=None, data=None, extra_filters=None, - **kwargs): + def process(self, formdata=None, obj=None, data=None, extra_filters=None, **kwargs): """Build a proxy around the object.""" if obj is not None: obj = self.profile_proxy_cls(obj) super().process( - formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, - **kwargs + formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, **kwargs ) def populate_obj(self, user): @@ -116,8 +116,10 @@ class EmailProfileForm(ProfileForm): email = StringField( # NOTE: Form field label - _('Email address'), - filters=[lambda x: x.lower() if x is not None else x, ], + _("Email address"), + filters=[ + lambda x: x.lower() if x is not None else x, + ], validators=[ email_required, current_user_email, @@ -128,15 +130,17 @@ class EmailProfileForm(ProfileForm): email_repeat = StringField( # NOTE: Form field label - _('Re-enter email address'), + _("Re-enter email address"), # NOTE: Form field help text - description=_('Please re-enter your email address.'), - filters=[lambda x: x.lower() if x else x, ], + description=_("Please re-enter your email address."), + filters=[ + lambda x: x.lower() if x else x, + ], validators=[ email_required, # NOTE: Form validation error. - EqualTo('email', message=_('Email addresses do not match.')) - ] + EqualTo("email", message=_("Email addresses do not match.")), + ], ) @@ -144,11 +148,12 @@ class VerificationForm(FlaskForm): """Form to render a button to request email confirmation.""" # NOTE: Form button label - send_verification_email = SubmitField(_('Resend verification email')) + send_verification_email = SubmitField(_("Resend verification email")) def register_form_factory(Form): """Factory for creating an extended user registration form.""" + class CsrfDisabledProfileForm(ProfileForm): """Subclass of ProfileForm to disable CSRF token in the inner form. @@ -164,13 +169,13 @@ def __init__(self, *args, **kwargs): class RegisterForm(Form): """RegisterForm extended with UserProfile details.""" - profile = FormField(CsrfDisabledProfileForm, separator='.') + profile = FormField(CsrfDisabledProfileForm, separator=".") def to_dict(self): profile_data = self.profile.data data = super().to_dict() - data['username'] = profile_data.pop('username') - data['user_profile'] = profile_data + data["username"] = profile_data.pop("username") + data["user_profile"] = profile_data return data return RegisterForm @@ -182,38 +187,36 @@ class PreferencesForm(FlaskForm): profile_proxy_cls = UserProfileProxy visibility = RadioField( - _('Profile visibility'), + _("Profile visibility"), choices=[ - ('public', _('Public')), - ('restricted', _('Hidden')), + ("public", _("Public")), + ("restricted", _("Hidden")), ], description=_( "Public profiles can be found by other users via searches on " "username, full name and affiliation. Hidden profiles cannot be" " found by other users." - ) + ), ) email_visibility = RadioField( - _('Email visibility'), + _("Email visibility"), choices=[ - ('public', _('Public')), - ('restricted', _('Hidden')), + ("public", _("Public")), + ("restricted", _("Hidden")), ], description=_( "Public email visibility enables your profile to be found by " "your email address." - ) + ), ) - def process(self, formdata=None, obj=None, data=None, extra_filters=None, - **kwargs): + def process(self, formdata=None, obj=None, data=None, extra_filters=None, **kwargs): """Build a proxy around the object.""" if obj is not None: obj = self.profile_proxy_cls(obj) super().process( - formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, - **kwargs + formdata=formdata, obj=obj, data=data, extra_filters=extra_filters, **kwargs ) def populate_obj(self, user): @@ -224,6 +227,7 @@ def populate_obj(self, user): def confirm_register_form_factory(Form): """Factory for creating a confirm register form.""" + class CsrfDisabledProfileForm(ProfileForm): """Subclass of ProfileForm to disable CSRF token in the inner form. @@ -239,13 +243,13 @@ def __init__(self, *args, **kwargs): class ConfirmRegisterForm(Form): """RegisterForm extended with UserProfile details.""" - profile = FormField(CsrfDisabledProfileForm, separator='.') + profile = FormField(CsrfDisabledProfileForm, separator=".") def to_dict(self): profile_data = self.profile.data data = super().to_dict() - data['username'] = profile_data.pop('username') - data['user_profile'] = profile_data + data["username"] = profile_data.pop("username") + data["user_profile"] = profile_data return data return ConfirmRegisterForm @@ -255,6 +259,6 @@ def _update_with_csrf_disabled(d=None): """Update the input dict with CSRF disabled.""" if d is None: d = {} - d.setdefault('meta', {}) - d['meta'].update({'csrf': False}) + d.setdefault("meta", {}) + d["meta"].update({"csrf": False}) return d diff --git a/invenio_userprofiles/models.py b/invenio_userprofiles/models.py index e7ad41a..179e450 100644 --- a/invenio_userprofiles/models.py +++ b/invenio_userprofiles/models.py @@ -23,14 +23,14 @@ def is_anonymous(self): class UserProfileProxy: """Proxy for a user that allows mapping the form to the user object.""" - _profile_attrs = ['full_name', 'affiliations'] - _preferences_attrs = ['email_visibility', 'visibility'] - _read_only_attrs = ['email_repeat'] - _aliases = {'email_repeat': 'email', 'user_id': 'id'} + _profile_attrs = ["full_name", "affiliations"] + _preferences_attrs = ["email_visibility", "visibility"] + _read_only_attrs = ["email_repeat"] + _aliases = {"email_repeat": "email", "user_id": "id"} def __init__(self, user): """.""" - super().__setattr__('_user', user) + super().__setattr__("_user", user) def __getattr__(self, attr): """.""" @@ -44,9 +44,11 @@ def __getattr__(self, attr): def __setattr__(self, attr, value): """.""" - if attr == 'email': - if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ - self._user.email != value: + if attr == "email": + if ( + current_app.config["USERPROFILES_EMAIL_ENABLED"] + and self._user.email != value + ): self._user.email = value self._user.confirmed_at = None elif attr in self._profile_attrs: @@ -73,7 +75,7 @@ def get_by_username(cls, username): :param username: A username to query for (case insensitive). """ # Kept for backward compatibility - user = current_app.extensions['security'].datastore.find_user( + user = current_app.extensions["security"].datastore.find_user( _username=username.lower() ) return cls(user) if user else None @@ -87,9 +89,7 @@ def get_by_userid(cls, user_id): or ``None``. """ # Kept for backward compatibility - user = current_app.extensions['security'].datastore.find_user( - id=user_id - ) + user = current_app.extensions["security"].datastore.find_user(id=user_id) return cls(user) if user else None diff --git a/invenio_userprofiles/validators.py b/invenio_userprofiles/validators.py index 5206789..2cff646 100644 --- a/invenio_userprofiles/validators.py +++ b/invenio_userprofiles/validators.py @@ -12,12 +12,13 @@ from flask_babelex import lazy_gettext as _ -username_regex = re.compile('^[a-zA-Z][a-zA-Z0-9-_]{2}[a-zA-Z0-9-_]*$') +username_regex = re.compile("^[a-zA-Z][a-zA-Z0-9-_]{2}[a-zA-Z0-9-_]*$") """Username rules.""" USERNAME_RULES = _( - 'Username must start with a letter, be at least three characters long and' - ' only contain alphanumeric characters, dashes and underscores.') + "Username must start with a letter, be at least three characters long and" + " only contain alphanumeric characters, dashes and underscores." +) """Description of username validation rules. .. note:: Used for both form help text and for form validation error.""" diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 9793855..f4db70f 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -20,36 +20,42 @@ from invenio_theme.proxies import current_theme_icons from speaklater import make_lazy_string -from .forms import EmailProfileForm, PreferencesForm, ProfileForm, \ - VerificationForm, confirm_register_form_factory, register_form_factory +from .forms import ( + EmailProfileForm, + PreferencesForm, + ProfileForm, + VerificationForm, + confirm_register_form_factory, + register_form_factory, +) from .models import UserProfileProxy blueprint = Blueprint( - 'invenio_userprofiles', + "invenio_userprofiles", __name__, - template_folder='templates', + template_folder="templates", ) blueprint_api_init = Blueprint( - 'invenio_userprofiles_api_init', + "invenio_userprofiles_api_init", __name__, - template_folder='templates', + template_folder="templates", ) blueprint_ui_init = Blueprint( - 'invenio_userprofiles_ui_init', + "invenio_userprofiles_ui_init", __name__, ) def init_common(app): """Post initialization.""" - if app.config['USERPROFILES_EXTEND_SECURITY_FORMS']: - security_ext = app.extensions['security'] + if app.config["USERPROFILES_EXTEND_SECURITY_FORMS"]: + security_ext = app.extensions["security"] security_ext.confirm_register_form = confirm_register_form_factory( - security_ext.confirm_register_form) - security_ext.register_form = register_form_factory( - security_ext.register_form) + security_ext.confirm_register_form + ) + security_ext.register_form = register_form_factory(security_ext.register_form) @blueprint_ui_init.record_once @@ -59,8 +65,7 @@ def init_ui(state): init_common(app) # Register blueprint for templates - app.register_blueprint( - blueprint, url_prefix=app.config['USERPROFILES_PROFILE_URL']) + app.register_blueprint(blueprint, url_prefix=app.config["USERPROFILES_PROFILE_URL"]) @blueprint_api_init.record_once @@ -72,63 +77,64 @@ def init_api(state): @blueprint.app_template_filter() def userprofile(value): """Retrieve user profile for a given user id.""" - warn( - "userprofile template filter is deprecated.", - DeprecationWarning - ) + warn("userprofile template filter is deprecated.", DeprecationWarning) return UserProfileProxy.get_by_userid(int(value)) -@blueprint.route('/', methods=['GET', 'POST']) +@blueprint.route("/", methods=["GET", "POST"]) @login_required @register_menu( - blueprint, 'settings.profile', + blueprint, + "settings.profile", # NOTE: Menu item text (icon replaced by a user icon). - _('%(icon)s Profile', icon=make_lazy_string( - lambda: f'')), - order=0 -) -@register_breadcrumb( - blueprint, 'breadcrumbs.settings.profile', _('Profile') + _( + "%(icon)s Profile", + icon=make_lazy_string(lambda: f''), + ), + order=0, ) +@register_breadcrumb(blueprint, "breadcrumbs.settings.profile", _("Profile")) def profile(): """View for editing a profile.""" # Create forms verification_form = VerificationForm(formdata=None, prefix="verification") profile_form = profile_form_factory() preferences_form = PreferencesForm( - formdata=None, obj=current_user, prefix="preferences") + formdata=None, obj=current_user, prefix="preferences" + ) # Process forms is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) - form = request.form.get('submit', None) - if form == 'profile' and not is_read_only: + form = request.form.get("submit", None) + if form == "profile" and not is_read_only: handle_profile_form(profile_form) - elif form == 'verification': + elif form == "verification": handle_verification_form(verification_form) - elif form == 'preferences' and not is_read_only: + elif form == "preferences" and not is_read_only: handle_preferences_form(preferences_form) return render_template( - current_app.config['USERPROFILES_PROFILE_TEMPLATE'], + current_app.config["USERPROFILES_PROFILE_TEMPLATE"], profile_form=profile_form, verification_form=verification_form, - preferences_form=preferences_form + preferences_form=preferences_form, ) def profile_form_factory(): """Create a profile form.""" - if current_app.config['USERPROFILES_EMAIL_ENABLED']: + if current_app.config["USERPROFILES_EMAIL_ENABLED"]: return EmailProfileForm( formdata=None, obj=current_user, - prefix='profile', ) + prefix="profile", + ) else: return ProfileForm( formdata=None, obj=current_user, - prefix='profile', ) + prefix="profile", + ) def handle_verification_form(form): @@ -150,10 +156,12 @@ def handle_profile_form(form): if form.validate_on_submit(): email_changed = False - datastore = current_app.extensions['security'].datastore + datastore = current_app.extensions["security"].datastore with db.session.begin_nested(): - if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ - form.email.data != current_user.email: + if ( + current_app.config["USERPROFILES_EMAIL_ENABLED"] + and form.email.data != current_user.email + ): email_changed = True form.populate_obj(current_user) db.session.add(current_user) @@ -163,13 +171,17 @@ def handle_profile_form(form): if email_changed: send_confirmation_instructions(current_user) # NOTE: Flash message after successful update of profile. - flash(_('Profile was updated. We have sent a verification ' - 'email to %(email)s. Please check it.', - email=current_user.email), - category='success') + flash( + _( + "Profile was updated. We have sent a verification " + "email to %(email)s. Please check it.", + email=current_user.email, + ), + category="success", + ) else: # NOTE: Flash message after successful update of profile. - flash(_('Profile was updated.'), category='success') + flash(_("Profile was updated."), category="success") def handle_preferences_form(form): @@ -182,6 +194,6 @@ def handle_preferences_form(form): if form.validate_on_submit(): form.populate_obj(current_user) db.session.add(current_user) - current_app.extensions['security'].datastore.commit() + current_app.extensions["security"].datastore.commit() # NOTE: Flash message after successful update of profile. - flash(_('Preferences were updated.'), category='success') + flash(_("Preferences were updated."), category="success") diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 11157ba..0000000 --- a/pytest.ini +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of Invenio. -# Copyright (C) 2015-2018 CERN. -# -# Invenio is free software; you can redistribute it and/or modify it -# under the terms of the MIT License; see LICENSE file for more details. - -[pytest] -addopts = --isort --pydocstyle --pycodestyle --doctest-glob="*.rst" --doctest-modules --cov=invenio_userprofiles --cov-report=term-missing -testpaths = tests invenio_userprofiles diff --git a/setup.cfg b/setup.cfg index ba5d6a6..40f58f6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,7 @@ # This file is part of Invenio. # Copyright (C) 2015-2022 CERN. # Copyright (C) 2021 TU Wien. +# Copyright (C) 2022 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -31,6 +32,7 @@ install_requires = [options.extras_require] tests = + pytest-black>=0.3.0,<0.3.10 pytest-invenio~=1.4.7 invenio-db[mysql,postgresql,versioning]>=1.0.14 Sphinx>=4.2.0,<5 @@ -86,3 +88,10 @@ output-dir = invenio_userprofiles/translations/ [pydocstyle] add_ignore = D401 + +[isort] +profile=black + +[tool:pytest] +addopts = --black --isort --pydocstyle --doctest-glob="*.rst" --doctest-modules --cov=invenio_userprofiles --cov-report=term-missing +testpaths = tests invenio_userprofiles diff --git a/tests/conftest.py b/tests/conftest.py index ce62381..883d955 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,26 +20,24 @@ from invenio_accounts import InvenioAccounts from invenio_accounts.views import blueprint as accounts_blueprint from invenio_db import InvenioDB, db -from sqlalchemy_utils.functions import create_database, database_exists, \ - drop_database +from sqlalchemy_utils.functions import create_database, database_exists, drop_database from invenio_userprofiles import InvenioUserProfiles from invenio_userprofiles.views import blueprint_ui_init -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def app_config(app_config): """Override pytest-invenio app_config fixture.""" app_config.update( ACCOUNTS_LOCAL_LOGIN_ENABLED=True, ACCOUNTS_USE_CELERY=False, LOGIN_DISABLED=False, - SECRET_KEY='testing_key', - SQLALCHEMY_DATABASE_URI=os.getenv('SQLALCHEMY_DATABASE_URI', - 'sqlite://'), - TEST_USER_EMAIL='test_user@test.org', - TEST_USER_PASSWORD='test_password', - TEST_USER_USERNAME='test', + SECRET_KEY="testing_key", + SQLALCHEMY_DATABASE_URI=os.getenv("SQLALCHEMY_DATABASE_URI", "sqlite://"), + TEST_USER_EMAIL="test_user@test.org", + TEST_USER_PASSWORD="test_password", + TEST_USER_USERNAME="test", TESTING=True, WTF_CSRF_ENABLED=False, ) @@ -62,8 +60,9 @@ def base_app(app_config): base_app.register_blueprint(accounts_blueprint) with base_app.app_context(): - if str(db.engine.url) != "sqlite://" and \ - not database_exists(str(db.engine.url)): + if str(db.engine.url) != "sqlite://" and not database_exists( + str(db.engine.url) + ): create_database(str(db.engine.url)) db.create_all() diff --git a/tests/helpers.py b/tests/helpers.py index 4d3a56a..2a52ac1 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -14,22 +14,29 @@ def sign_up(app, client, email=None, password=None): """Register a user.""" with app.test_request_context(): - register_url = url_for('security.register') - - res = client.post(register_url, data=dict( - email=email or app.config['TEST_USER_EMAIL'], - password=password or app.config['TEST_USER_PASSWORD'], - ), environ_base={'REMOTE_ADDR': '127.0.0.1'}) + register_url = url_for("security.register") + + res = client.post( + register_url, + data=dict( + email=email or app.config["TEST_USER_EMAIL"], + password=password or app.config["TEST_USER_PASSWORD"], + ), + environ_base={"REMOTE_ADDR": "127.0.0.1"}, + ) assert res.status_code == 302 # redirect after signedup def login(app, client, email=None, password=None): """Log the user in with the test client.""" with app.test_request_context(): - login_url = url_for('security.login') - - res = client.post(login_url, data=dict( - email=email or app.config['TEST_USER_EMAIL'], - password=password or app.config['TEST_USER_PASSWORD'], - )) + login_url = url_for("security.login") + + res = client.post( + login_url, + data=dict( + email=email or app.config["TEST_USER_EMAIL"], + password=password or app.config["TEST_USER_PASSWORD"], + ), + ) assert res.status_code == 302 # redirect after login diff --git a/tests/test_api.py b/tests/test_api.py index b54a7ef..97e275a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,20 +18,19 @@ def test_logged_out_user_has_anonymous_profile(app): """AnonymousUser should have AnonymousUserProfile.""" with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: resp = client.get(profile_url, follow_redirects=True) assert resp.status_code == 200 assert 'name="login_user_form"' in resp.get_data(as_text=True) - assert current_user.is_anonymous and \ - current_userprofile.is_anonymous + assert current_user.is_anonymous and current_userprofile.is_anonymous def test_get_current_userprofile(app): """Test get_current_userprofile.""" with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: # Logged in user should have userprofile diff --git a/tests/test_forms.py b/tests/test_forms.py index ad32c01..664ca0e 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -8,13 +8,16 @@ """Tests for user profile forms.""" -from invenio_userprofiles.forms import _update_with_csrf_disabled, \ - confirm_register_form_factory, register_form_factory +from invenio_userprofiles.forms import ( + _update_with_csrf_disabled, + confirm_register_form_factory, + register_form_factory, +) def test_register_form_factory_no_csrf(app): """Test CSRF token is not in reg. form and not in profile inner form.""" - security = app.extensions['security'] + security = app.extensions["security"] rf = _get_form(app, security.register_form, register_form_factory) _assert_no_csrf_token(rf) @@ -22,64 +25,71 @@ def test_register_form_factory_no_csrf(app): def test_register_form_factory_csrf(app_with_csrf): """Test CSRF token is in reg. form but not in profile inner form.""" - security = app_with_csrf.extensions['security'] - rf = _get_form(app_with_csrf, security.register_form, - register_form_factory) + security = app_with_csrf.extensions["security"] + rf = _get_form(app_with_csrf, security.register_form, register_form_factory) _assert_csrf_token(rf) def test_force_disable_csrf_register_form(app_with_csrf): """Test force disable CSRF for reg. form""" - security = app_with_csrf.extensions['security'] - rf = _get_form(app_with_csrf, security.register_form, - register_form_factory, force_disable_csrf=True) + security = app_with_csrf.extensions["security"] + rf = _get_form( + app_with_csrf, + security.register_form, + register_form_factory, + force_disable_csrf=True, + ) _assert_no_csrf_token(rf) def test_confirm_register_form_factory_no_csrf(app): """Test CSRF token is not in confirm form and not in profil -e inner form.""" - security = app.extensions['security'] - rf = _get_form(app, security.confirm_register_form, - confirm_register_form_factory) + e inner form.""" + security = app.extensions["security"] + rf = _get_form(app, security.confirm_register_form, confirm_register_form_factory) _assert_no_csrf_token(rf) def test_confirm_register_form_factory_csrf(app_with_csrf): """Test CSRF token is in confirm form but not in profile inner form.""" - security = app_with_csrf.extensions['security'] - rf = _get_form(app_with_csrf, security.confirm_register_form, - confirm_register_form_factory) + security = app_with_csrf.extensions["security"] + rf = _get_form( + app_with_csrf, security.confirm_register_form, confirm_register_form_factory + ) _assert_csrf_token(rf) def test_force_disable_csrf_confirm_form(app_with_csrf): """Test force disable CSRF for confirm. form""" - security = app_with_csrf.extensions['security'] - rf = _get_form(app_with_csrf, security.confirm_register_form, - confirm_register_form_factory, force_disable_csrf=True) + security = app_with_csrf.extensions["security"] + rf = _get_form( + app_with_csrf, + security.confirm_register_form, + confirm_register_form_factory, + force_disable_csrf=True, + ) _assert_no_csrf_token(rf) def _assert_csrf_token(form): """Assert that the field `csrf_token` exists in the form.""" - assert 'profile' in form - assert 'csrf_token' not in form.profile - assert 'csrf_token' in form + assert "profile" in form + assert "csrf_token" not in form.profile + assert "csrf_token" in form assert form.csrf_token def _assert_no_csrf_token(form): """Assert that the field `csrf_token` does not exist in the form.""" - assert 'profile' in form - assert 'csrf_token' not in form.profile + assert "profile" in form + assert "csrf_token" not in form.profile # Flask-WTF==0.13.1 adds always `csrf_token` field, but with None value # Flask-WTF>0.14.2 do not `csrf_token` field - assert 'csrf_token' not in form or form.csrf_token.data is None + assert "csrf_token" not in form or form.csrf_token.data is None def _get_form(app, parent_form, factory_method, force_disable_csrf=False): diff --git a/tests/test_invenio_userprofile.py b/tests/test_invenio_userprofile.py index 8d73a0b..89d11de 100644 --- a/tests/test_invenio_userprofile.py +++ b/tests/test_invenio_userprofile.py @@ -22,12 +22,13 @@ def test_version(): """Test version import.""" from invenio_userprofiles import __version__ + assert __version__ def test_init(): """Test extension initialization.""" - app = Flask('testapp') + app = Flask("testapp") app.config.update( ACCOUNTS_USE_CELERY=False, SECRET_KEY="test_key", @@ -38,9 +39,9 @@ def test_init(): InvenioDB(app) InvenioAccounts(app) ext = InvenioUserProfiles(app) - assert 'invenio-userprofiles' in app.extensions + assert "invenio-userprofiles" in app.extensions - app = Flask('testapp') + app = Flask("testapp") app.config.update( ACCOUNTS_USE_CELERY=False, SECRET_KEY="test_key", @@ -51,26 +52,26 @@ def test_init(): InvenioDB(app) InvenioAccounts(app) ext = InvenioUserProfiles() - assert 'invenio-userprofiles' not in app.extensions + assert "invenio-userprofiles" not in app.extensions ext.init_app(app) - assert 'invenio-userprofiles' in app.extensions + assert "invenio-userprofiles" in app.extensions def test_alembic(app): """Test alembic recipes.""" - ext = app.extensions['invenio-db'] + ext = app.extensions["invenio-db"] with app.app_context(): - if db.engine.name == 'sqlite': - raise pytest.skip('Upgrades are not supported on SQLite.') + if db.engine.name == "sqlite": + raise pytest.skip("Upgrades are not supported on SQLite.") assert not ext.alembic.compare_metadata() db.drop_all() ext.alembic.upgrade() assert not ext.alembic.compare_metadata() - ext.alembic.downgrade(target='96e796392533') + ext.alembic.downgrade(target="96e796392533") ext.alembic.upgrade() assert not ext.alembic.compare_metadata() - ext.alembic.downgrade(target='96e796392533') + ext.alembic.downgrade(target="96e796392533") diff --git a/tests/test_models.py b/tests/test_models.py index d17a5c1..38bb07d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -22,26 +22,26 @@ def test_userprofiles(app): profile = UserProfile(User()) # Check the username validator works on the model - profile.username = test_usernames['valid'] + profile.username = test_usernames["valid"] with pytest.raises(ValueError): - profile.username = test_usernames['invalid_characters'] + profile.username = test_usernames["invalid_characters"] with pytest.raises(ValueError): - profile.username = test_usernames['invalid_begins_with_number'] + profile.username = test_usernames["invalid_begins_with_number"] # Test non-validated attributes - profile.first_name = 'Test' - profile.last_name = 'User' - assert profile.first_name == 'Test' - assert profile.last_name == 'User' + profile.first_name = "Test" + profile.last_name = "User" + assert profile.first_name == "Test" + assert profile.last_name == "User" def test_case_insensitive_username(app): """Test case-insensitive uniqueness.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@test.org', username="INFO") + u1 = User(email="test@test.org", username="INFO") db.session.add(u1) - u2 = User(email='test2@test.org', username="info") + u2 = User(email="test2@test.org", username="info") db.session.add(u2) pytest.raises(IntegrityError, db.session.commit) @@ -50,18 +50,18 @@ def test_case_preserving_username(app): """Test that username preserves the case.""" with app.app_context(): with db.session.begin_nested(): - u1 = User(email='test@test.org', username="InFo") + u1 = User(email="test@test.org", username="InFo") db.session.add(u1) db.session.commit() - profile = UserProfile.get_by_username('info') - assert profile.username == 'InFo' + profile = UserProfile.get_by_username("info") + assert profile.username == "InFo" def test_delete_cascade(app): """Test that deletion of user, also removes profile.""" with app.app_context(): with db.session.begin_nested(): - u = User(email='test@test.org', username="InFo") + u = User(email="test@test.org", username="InFo") db.session.add(u) db.session.commit() diff --git a/tests/test_validators.py b/tests/test_validators.py index 5a1a10a..f42e07a 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -13,25 +13,25 @@ from invenio_userprofiles.validators import validate_username test_usernames = { - 'valid': 'Good-Name_9', - 'invalid_begins_with_number': '9CantStartWithNumber', - 'invalid_characters': '_Containsi!!ega!Char acters*', - 'invalid_short': 'ab', + "valid": "Good-Name_9", + "invalid_begins_with_number": "9CantStartWithNumber", + "invalid_characters": "_Containsi!!ega!Char acters*", + "invalid_short": "ab", } def test_validate_username(app): """Test username validator.""" # Goodname can contain letters, numbers and starts with a letter - validate_username(test_usernames['valid']) + validate_username(test_usernames["valid"]) # Can't start with a number with pytest.raises(ValueError): - validate_username(test_usernames['invalid_begins_with_number']) + validate_username(test_usernames["invalid_begins_with_number"]) # Can only contain latin letters and numbers with pytest.raises(ValueError): - validate_username(test_usernames['invalid_characters']) + validate_username(test_usernames["invalid_characters"]) with pytest.raises(ValueError): - validate_username(test_usernames['invalid_short']) + validate_username(test_usernames["invalid_short"]) diff --git a/tests/test_views.py b/tests/test_views.py index 23fe195..245aa8d 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -23,7 +23,7 @@ def prefix(name, data): """Prefix all keys with value.""" data = {"{0}-{1}".format(name, k): v for (k, v) in data.items()} - data['submit'] = name + data["submit"] = name return data @@ -35,45 +35,45 @@ def test_profile_in_registration(base_app): app = base_app with app.test_request_context(): - register_url = url_for_security('register') + register_url = url_for_security("register") with app.test_client() as client: resp = client.get(register_url) - assert 'profile.username' in resp.get_data(as_text=True) - assert 'profile.full_name' in resp.get_data(as_text=True) + assert "profile.username" in resp.get_data(as_text=True) + assert "profile.full_name" in resp.get_data(as_text=True) data = { - 'email': 'test_user@test.org', - 'password': 'test_password', - 'profile.username': 'TestUser', - 'profile.full_name': 'Test C. User', - 'profile.affiliations': 'Test Org', + "email": "test_user@test.org", + "password": "test_password", + "profile.username": "TestUser", + "profile.full_name": "Test C. User", + "profile.affiliations": "Test Org", } resp = client.post(register_url, data=data, follow_redirects=True) with app.test_request_context(): - user = User.query.filter_by(email='test_user@test.org').one() - assert user.username == 'TestUser' - assert user.user_profile['full_name'] == 'Test C. User' - assert user.user_profile['affiliations'] == 'Test Org' + user = User.query.filter_by(email="test_user@test.org").one() + assert user.username == "TestUser" + assert user.user_profile["full_name"] == "Test C. User" + assert user.user_profile["affiliations"] == "Test Org" with app.test_client() as client: resp = client.get(register_url) data = { - 'email': 'newuser@test.org', - 'password': 'test_password', - 'profile.username': 'TestUser', - 'profile.full_name': 'Same Username', + "email": "newuser@test.org", + "password": "test_password", + "profile.username": "TestUser", + "profile.full_name": "Same Username", } resp = client.post(register_url, data=data) assert resp.status_code == 200 - assert 'profile.username' in resp.get_data(as_text=True) + assert "profile.username" in resp.get_data(as_text=True) def test_profile_view_not_accessible_without_login(app): """Test the user can't access profile settings page without logging in.""" with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: resp = client.get(profile_url, follow_redirects=True) @@ -83,9 +83,9 @@ def test_profile_view_not_accessible_without_login(app): def test_profile_view(app): """Test the profile view.""" - app.config['USERPROFILES_EMAIL_ENABLED'] = False + app.config["USERPROFILES_EMAIL_ENABLED"] = False with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: sign_up(app, client) @@ -95,60 +95,88 @@ def test_profile_view(app): assert 'name="profile_form"' in str(resp.data) # Valid submission should work - resp = client.post(profile_url, data=prefix('profile', dict( - username=test_usernames['valid'], - full_name='Valid Name', affiliations='Aff'))) + resp = client.post( + profile_url, + data=prefix( + "profile", + dict( + username=test_usernames["valid"], + full_name="Valid Name", + affiliations="Aff", + ), + ), + ) assert resp.status_code == 200 data = resp.get_data(as_text=True) - assert test_usernames['valid'] in data - assert 'Valid' in data - assert 'Name' in data - assert 'Aff' in data + assert test_usernames["valid"] in data + assert "Valid" in data + assert "Name" in data + assert "Aff" in data # Invalid submission should not save data - resp = client.post(profile_url, data=prefix('profile', dict( - username=test_usernames['invalid_characters'], - full_name='Valid Name', affiliations='Aff'))) + resp = client.post( + profile_url, + data=prefix( + "profile", + dict( + username=test_usernames["invalid_characters"], + full_name="Valid Name", + affiliations="Aff", + ), + ), + ) assert resp.status_code == 200 - assert test_usernames['invalid_characters'] in \ - resp.get_data(as_text=True) + assert test_usernames["invalid_characters"] in resp.get_data(as_text=True) resp = client.get(profile_url) assert resp.status_code == 200 - assert test_usernames['valid'] in resp.get_data(as_text=True) + assert test_usernames["valid"] in resp.get_data(as_text=True) # Whitespace should be trimmed - client.post(profile_url, data=prefix('profile', dict( - username='{0} '.format(test_usernames['valid']), - full_name='Valid Name ', affiliations=' Aff '))) + client.post( + profile_url, + data=prefix( + "profile", + dict( + username="{0} ".format(test_usernames["valid"]), + full_name="Valid Name ", + affiliations=" Aff ", + ), + ), + ) resp = client.get(profile_url) assert resp.status_code == 200 data = resp.get_data(as_text=True) - assert test_usernames['valid'] in data - assert 'Valid Name ' not in data - assert ' Aff ' not in data + assert test_usernames["valid"] in data + assert "Valid Name " not in data + assert " Aff " not in data def test_profile_name_exists(app): """Test the profile view.""" - app.config['USERPROFILES_EMAIL_ENABLED'] = False - error_msg = 'Username is not available.' + app.config["USERPROFILES_EMAIL_ENABLED"] = False + error_msg = "Username is not available." with app.app_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") # Create an existing user - email1 = 'exiting@test.org' - password1 = '123456' + email1 = "exiting@test.org" + password1 = "123456" with app.test_client() as client: sign_up(app, client, email=email1, password=password1) login(app, client, email=email1, password=password1) assert client.get(profile_url).status_code == 200 - resp = client.post(profile_url, data=prefix('profile', dict( - username='existingname', full_name='Valid Name', affiliations=''))) + resp = client.post( + profile_url, + data=prefix( + "profile", + dict(username="existingname", full_name="Valid Name", affiliations=""), + ), + ) assert error_msg not in resp.get_data(as_text=True) # Create another user and try setting username to same as above user. @@ -158,20 +186,26 @@ def test_profile_name_exists(app): resp = client.get(profile_url) assert resp.status_code == 200 - resp = client.post(profile_url, data=prefix('profile', dict( - username='existingname', full_name='Another name', affiliations='' - ))) + resp = client.post( + profile_url, + data=prefix( + "profile", + dict( + username="existingname", full_name="Another name", affiliations="" + ), + ), + ) assert resp.status_code == 200 assert error_msg in resp.get_data(as_text=True) def test_profile_case_change(app): """Test the profile view.""" - app.config['USERPROFILES_EMAIL_ENABLED'] = False - error_msg = 'Username already exists.' + app.config["USERPROFILES_EMAIL_ENABLED"] = False + error_msg = "Username already exists." with app.app_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: # Create a user @@ -180,8 +214,9 @@ def test_profile_case_change(app): resp = client.get(profile_url) assert resp.status_code == 200 - data = prefix('profile', dict( - username='valid', full_name='Another name', affiliations='')) + data = prefix( + "profile", dict(username="valid", full_name="Another name", affiliations="") + ) # Set the name first time resp = client.post(profile_url, data=data) @@ -194,8 +229,9 @@ def test_profile_case_change(app): assert error_msg not in resp.get_data(as_text=True) # Change case of the username - data = prefix('profile', dict( - username='Valid', full_name='Another name', affiliations='')) + data = prefix( + "profile", dict(username="Valid", full_name="Another name", affiliations="") + ) resp = client.post(profile_url, data=data) assert resp.status_code == 200 @@ -204,38 +240,40 @@ def test_profile_case_change(app): def test_send_verification_form(app): """Test send verification form.""" - mail = app.extensions['mail'] + mail = app.extensions["mail"] with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: sign_up(app, client) login(app, client) resp = client.get(profile_url) assert resp.status_code == 200 - assert 'You have not yet verified your email address' in \ - resp.get_data(as_text=True) + assert "You have not yet verified your email address" in resp.get_data( + as_text=True + ) with mail.record_messages() as outbox: assert len(outbox) == 0 - resp = client.post(profile_url, data=prefix('verification', dict( - send_verification_email='Title' - ))) + resp = client.post( + profile_url, + data=prefix("verification", dict(send_verification_email="Title")), + ) assert len(outbox) == 1 def test_change_email(app): """Test send verification form.""" - mail = app.extensions['mail'] - error_msg = 'Username already exists.' + mail = app.extensions["mail"] + error_msg = "Username already exists." with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") # Create an existing user - email1 = 'exiting@test.org' - password1 = '123456' + email1 = "exiting@test.org" + password1 = "123456" with app.test_client() as client: sign_up(app, client, email=email1, password=password1) login(app, client, email=email1, password=password1) @@ -247,43 +285,48 @@ def test_change_email(app): resp = client.get(profile_url) assert resp.status_code == 200 - data = prefix('profile', dict( - username='test', - full_name='Test User', - affiliations='', - email=app.config['TEST_USER_EMAIL'], - email_repeat=app.config['TEST_USER_EMAIL'], - )) + data = prefix( + "profile", + dict( + username="test", + full_name="Test User", + affiliations="", + email=app.config["TEST_USER_EMAIL"], + email_repeat=app.config["TEST_USER_EMAIL"], + ), + ) # Test existing email of another user. - data['profile-email_repeat'] = data['profile-email'] = email1 + data["profile-email_repeat"] = data["profile-email"] = email1 resp = client.post(profile_url, data=data) - assert 'exiting@test.org is already associated with an account.' \ + assert ( + "exiting@test.org is already associated with an account." in resp.get_data(as_text=True) + ) # Test empty email - data['profile-email_repeat'] = data['profile-email'] = '' + data["profile-email_repeat"] = data["profile-email"] = "" resp = client.post(profile_url, data=data) assert "Email not provided" in resp.get_data(as_text=True) # Test not an email - data['profile-email_repeat'] = data['profile-email'] = 'sadfsdfs' + data["profile-email_repeat"] = data["profile-email"] = "sadfsdfs" resp = client.post(profile_url, data=data) assert "Invalid email address" in resp.get_data(as_text=True) # Test different emails - data['profile-email_repeat'] = 'typo@test.org' - data['profile-email'] = 'new@test.org' + data["profile-email_repeat"] = "typo@test.org" + data["profile-email"] = "new@test.org" resp = client.post(profile_url, data=data) - assert 'Email addresses do not match.' in resp.get_data(as_text=True) + assert "Email addresses do not match." in resp.get_data(as_text=True) def test_change_email_whitespace(app): """Test send verification form.""" - mail = app.extensions['mail'] + mail = app.extensions["mail"] with app.test_request_context(): - profile_url = url_for('invenio_userprofiles.profile') + profile_url = url_for("invenio_userprofiles.profile") with app.test_client() as client: sign_up(app, client) @@ -291,18 +334,21 @@ def test_change_email_whitespace(app): resp = client.get(profile_url) assert resp.status_code == 200 - data = prefix('profile', dict( - username='test', - full_name='Test User', - affiliations='', - email=app.config['TEST_USER_EMAIL'], - email_repeat=app.config['TEST_USER_EMAIL'], - )) + data = prefix( + "profile", + dict( + username="test", + full_name="Test User", + affiliations="", + email=app.config["TEST_USER_EMAIL"], + email_repeat=app.config["TEST_USER_EMAIL"], + ), + ) with mail.record_messages() as outbox: assert len(outbox) == 0 - data['profile-email_repeat'] = data['profile-email'] = 'new@ex.org' + data["profile-email_repeat"] = data["profile-email"] = "new@ex.org" resp = client.post(profile_url, data=data) - assert 'Invalid email address' not in resp.get_data(as_text=True) + assert "Invalid email address" not in resp.get_data(as_text=True) # Email was sent for email address confirmation. assert len(outbox) == 1 From 3d4880f8b3a95b788da85d1181049ccdbb3e9fd7 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:55:45 +0200 Subject: [PATCH 37/65] add .git-blame-ignore-revs --- .git-blame-ignore-revs | 1 + MANIFEST.in | 1 + 2 files changed, 2 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..185c445 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +77332a5cb166342b67732be5539e22e9b403851b diff --git a/MANIFEST.in b/MANIFEST.in index 2be7a19..0e6d0fc 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -27,3 +27,4 @@ recursive-include invenio_userprofiles *.mo recursive-include invenio_userprofiles *.po *.pot *.mo recursive-include invenio_userprofiles *.py recursive-include tests *.py +include .git-blame-ignore-revs From fa786db2490482c5c7895093fd86eb9806f09074 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:55:45 +0200 Subject: [PATCH 38/65] fix docs compatibilty problem with Sphinx>=5.0.0 --- docs/conf.py | 3 ++- setup.cfg | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 6e1f173..48b28a9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2022 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -73,7 +74,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: diff --git a/setup.cfg b/setup.cfg index 40f58f6..b935f2b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,7 @@ tests = pytest-black>=0.3.0,<0.3.10 pytest-invenio~=1.4.7 invenio-db[mysql,postgresql,versioning]>=1.0.14 - Sphinx>=4.2.0,<5 + sphinx>=4.5 admin = # empty for backward compatibility postgresql = From 62ab985fb1e1f17f1f0e4bf8f5c60e26d9e862e2 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:55:45 +0200 Subject: [PATCH 39/65] move check_manifest configuration to setup.cfg. concentrate the configuration of all calls in one place --- run-tests.sh | 3 ++- setup.cfg | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index 78a811c..421945d 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -3,6 +3,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2020 CERN. +# Copyright (C) 2022 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -22,7 +23,7 @@ function cleanup() { } trap cleanup EXIT -python -m check_manifest --ignore ".*-requirements.txt" +python -m check_manifest eval "$(docker-services-cli up --db ${DB:-postgresql} --env)" python -m pytest sphinx-build -qnN docs docs/_build/html diff --git a/setup.cfg b/setup.cfg index b935f2b..9c4a262 100644 --- a/setup.cfg +++ b/setup.cfg @@ -92,6 +92,10 @@ add_ignore = D401 [isort] profile=black +[check-manifest] +ignore = + *-requirements.txt + [tool:pytest] addopts = --black --isort --pydocstyle --doctest-glob="*.rst" --doctest-modules --cov=invenio_userprofiles --cov-report=term-missing testpaths = tests invenio_userprofiles From 5c8742fc1f63cb79d5a25823913a227c5ae3d031 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:55:45 +0200 Subject: [PATCH 40/65] increase minimal python version to 3.7 --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 9c4a262..76d387a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,7 @@ classifiers = [options] include_package_data = True packages = find: -python_requires = >=3.6 +python_requires = >=3.7 zip_safe = False install_requires = invenio-accounts>=2.0.0 From f7603995b4d817f62472955f949a62f0154d2ceb Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 15 Jun 2022 23:59:44 +0200 Subject: [PATCH 41/65] global: clean test infrastructure --- .github/workflows/tests.yml | 33 +++++++++++++++------------------ constraints-min.txt | 4 ---- run-tests.sh | 2 +- 3 files changed, 16 insertions(+), 23 deletions(-) delete mode 100644 constraints-min.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 16080d4..cca69f3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,3 +1,12 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Invenio. +# Copyright (C) 2020 CERN. +# Copyright (C) 2022 Graz University of Technology. +# +# Invenio is free software; you can redistribute it and/or modify it +# under the terms of the MIT License; see LICENSE file for more details. + name: CI on: @@ -21,25 +30,16 @@ jobs: strategy: matrix: python-version: [3.7, 3.8, 3.9] - requirements-level: [min, pypi] + requirements-level: [pypi] db-service: [postgresql10, postgresql14, mysql5, mysql8] exclude: - python-version: 3.7 requirements-level: pypi - - - python-version: 3.8 - requirements-level: min - - - python-version: 3.9 - requirements-level: min - - - python-version: 3.7 - requirements-level: min db-service: postgresql14 - python-version: 3.7 - requirements-level: min + requirements-level: pypi db-service: mysql8 - python-version: 3.8 @@ -61,22 +61,19 @@ jobs: include: - db-service: postgresql10 DB: postgresql10 - EXTRAS: "tests" - db-service: postgresql14 DB: postgresql10 - EXTRAS: "tests" - db-service: mysql5 DB: mysql5 - EXTRAS: "tests" - db-service: mysql8 DB: mysql8 - EXTRAS: "tests" env: DB: ${{ matrix.DB }} + EXTRAS: "tests" steps: - name: Checkout @@ -89,8 +86,8 @@ jobs: - name: Generate dependencies run: | - python -m pip install --upgrade pip setuptools py wheel requirements-builder - requirements-builder -e ${{ matrix.EXTRAS }} ${{ matrix.requirements-file }} --level=${{ matrix.requirements-level }} setup.py > .${{ matrix.requirements-level }}-${{ matrix.python-version }}-requirements.txt + pip install wheel requirements-builder + requirements-builder -e "$EXTRAS" ${{ matrix.requirements-file }} --level=${{ matrix.requirements-level }} setup.py > .${{ matrix.requirements-level }}-${{ matrix.python-version }}-requirements.txt - name: Cache pip uses: actions/cache@v2 @@ -101,7 +98,7 @@ jobs: - name: Install dependencies run: | pip install -r .${{matrix.requirements-level}}-${{ matrix.python-version }}-requirements.txt -c constraints-${{matrix.requirements-level}}.txt - pip install .[${{ matrix.EXTRAS }}] + pip install .[$EXTRAS] pip freeze docker --version docker-compose --version diff --git a/constraints-min.txt b/constraints-min.txt deleted file mode 100644 index 32f6b27..0000000 --- a/constraints-min.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Dependency coming Flask-Security via Invenio-Accounts 2.0 -Flask-WTF>=1.0.0,<1.1.0 -Flask>=2.0.0,<2.1.0 -Werkzeug>=2.0,<2.1.0 diff --git a/run-tests.sh b/run-tests.sh index 421945d..6ad4123 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -24,8 +24,8 @@ function cleanup() { trap cleanup EXIT python -m check_manifest +python -m sphinx.cmd.build -qnNW docs docs/_build/html eval "$(docker-services-cli up --db ${DB:-postgresql} --env)" python -m pytest -sphinx-build -qnN docs docs/_build/html tests_exit_code=$? exit "$tests_exit_code" From a26ebae7763c5b0c78c410206ebf3b5e064e21de Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Tue, 28 Jun 2022 22:10:51 +0200 Subject: [PATCH 42/65] fix remove documentation of file that no longer exists --- docs/api.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index e1acf6e..b4aa11c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -13,12 +13,6 @@ Extension .. automodule:: invenio_userprofiles.ext :members: -Admin ------ - -.. automodule:: invenio_userprofiles.admin - :members: - API --- From 0e19b01f6ea7362fe50c9c81f6ef7465c0d3e368 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Tue, 28 Jun 2022 22:17:27 +0200 Subject: [PATCH 43/65] fix sphinx warning of not found reference target --- .git-blame-ignore-revs | 2 +- docs/conf.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 185c445..c63f7da 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1 +1 @@ -77332a5cb166342b67732be5539e22e9b403851b +5cfedd7dd6dde1d00fbcb115cc88aa017f31a52e diff --git a/docs/conf.py b/docs/conf.py index 48b28a9..9dab2af 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,8 @@ "sphinx.ext.viewcode", ] +nitpick_ignore = [("py:attr", "meta")] + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] From 138d945cb5664ae8cbc7c5e038e450b5371d4923 Mon Sep 17 00:00:00 2001 From: Karolina <38131488+kpsherva@users.noreply.github.com> Date: Thu, 7 Jul 2022 16:44:37 +0200 Subject: [PATCH 44/65] global: update git blame ignore --- .git-blame-ignore-revs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index c63f7da..501408d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1 +1 @@ -5cfedd7dd6dde1d00fbcb115cc88aa017f31a52e +2cdf2e549aeff104070802f61680f23995b78c09 From af6e1d289bc7adfe35f5dbe62cf38d36028154ed Mon Sep 17 00:00:00 2001 From: Guillaume Viger Date: Tue, 5 Jul 2022 17:00:58 -0400 Subject: [PATCH 45/65] profile: don't let USERPROFILES_READ_ONLY disable preferences --- .../invenio_userprofiles/settings/profile.html | 3 --- invenio_userprofiles/views.py | 11 ++++------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html index 9143686..06ed9bc 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html @@ -72,7 +72,6 @@
{%- set form = preferences_form %} - {%- set read_only = config.USERPROFILES_READ_ONLY %}
{%- for field in form %} {%- if field.widget.input_type == 'hidden' %} @@ -81,12 +80,10 @@ {{ render_field(field, placeholder=field.label.text, field_class="form-control no-dots-list pl-0") }} {%- endif %} {%- endfor %} - {%- if not read_only %}
{{ _('Cancel') }}
- {%- endif %}
{% endblock %} diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index f4db70f..1344967 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -110,14 +110,14 @@ def profile(): handle_profile_form(profile_form) elif form == "verification": handle_verification_form(verification_form) - elif form == "preferences" and not is_read_only: + elif form == 'preferences': handle_preferences_form(preferences_form) return render_template( - current_app.config["USERPROFILES_PROFILE_TEMPLATE"], - profile_form=profile_form, + current_app.config['USERPROFILES_PROFILE_TEMPLATE'], verification_form=verification_form, - preferences_form=preferences_form, + profile_form=profile_form, + preferences_form=preferences_form ) @@ -186,9 +186,6 @@ def handle_profile_form(form): def handle_preferences_form(form): """Handle preferences form.""" - if current_app.config.get("USERPROFILES_READ_ONLY", False): - return - form.process(formdata=request.form) if form.validate_on_submit(): From c687484f43c85cb71f80dde3eed43b77738a3437 Mon Sep 17 00:00:00 2001 From: Guillaume Viger Date: Wed, 6 Jul 2022 12:20:40 -0400 Subject: [PATCH 46/65] profile: redirect when update successful closes #139 --- invenio_userprofiles/views.py | 110 +++++++++++++++++----------------- tests/test_views.py | 32 +++++----- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 1344967..e538233 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2022 Northwestern University. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -10,7 +11,8 @@ from warnings import warn -from flask import Blueprint, current_app, flash, render_template, request +from flask import Blueprint, current_app, flash, redirect, render_template, \ + request, url_for from flask_babelex import lazy_gettext as _ from flask_breadcrumbs import register_breadcrumb from flask_login import current_user, login_required @@ -103,15 +105,27 @@ def profile(): formdata=None, obj=current_user, prefix="preferences" ) - # Process forms + # Pick form is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) - form = request.form.get("submit", None) - if form == "profile" and not is_read_only: - handle_profile_form(profile_form) - elif form == "verification": - handle_verification_form(verification_form) - elif form == 'preferences': - handle_preferences_form(preferences_form) + form_name = request.form.get('submit', None) + if form_name == 'profile' and not is_read_only: + handle_form = handle_profile_form + form = profile_form + elif form_name == 'verification': + handle_form = handle_verification_form + form = verification_form + elif form_name == 'preferences': + handle_form = handle_preferences_form + form = preferences_form + else: + form = None + + # Process form + if form: + form.process(formdata=request.form) + if form.validate_on_submit(): + handle_form(form) + return redirect(url_for(".profile"), code=303) # this endpoint return render_template( current_app.config['USERPROFILES_PROFILE_TEMPLATE'], @@ -139,58 +153,42 @@ def profile_form_factory(): def handle_verification_form(form): """Handle email sending verification form.""" - form.process(formdata=request.form) - - if form.validate_on_submit(): - send_confirmation_instructions(current_user) - # NOTE: Flash message. - flash(_("Verification email sent."), category="success") + send_confirmation_instructions(current_user) + # NOTE: Flash message. + flash(_("Verification email sent."), category="success") def handle_profile_form(form): """Handle profile update form.""" - if current_app.config.get("USERPROFILES_READ_ONLY", False): - return - - form.process(formdata=request.form) - - if form.validate_on_submit(): - email_changed = False - datastore = current_app.extensions["security"].datastore - with db.session.begin_nested(): - if ( - current_app.config["USERPROFILES_EMAIL_ENABLED"] - and form.email.data != current_user.email - ): - email_changed = True - form.populate_obj(current_user) - db.session.add(current_user) - datastore.mark_changed(id(db.session), uid=current_user.id) - datastore.commit() - - if email_changed: - send_confirmation_instructions(current_user) - # NOTE: Flash message after successful update of profile. - flash( - _( - "Profile was updated. We have sent a verification " - "email to %(email)s. Please check it.", - email=current_user.email, - ), - category="success", - ) - else: - # NOTE: Flash message after successful update of profile. - flash(_("Profile was updated."), category="success") + email_changed = False + datastore = current_app.extensions['security'].datastore + with db.session.begin_nested(): + if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ + form.email.data != current_user.email: + email_changed = True + form.populate_obj(current_user) + db.session.add(current_user) + datastore.mark_changed(id(db.session), uid=current_user.id) + datastore.commit() + + if email_changed: + send_confirmation_instructions(current_user) + # NOTE: Flash message after successful update of profile. + flash( + _('Profile was updated. We have sent a verification ' + 'email to %(email)s. Please check it.', + email=current_user.email), + category='success' + ) + else: + # NOTE: Flash message after successful update of profile. + flash(_('Profile was updated.'), category='success') def handle_preferences_form(form): """Handle preferences form.""" - form.process(formdata=request.form) - - if form.validate_on_submit(): - form.populate_obj(current_user) - db.session.add(current_user) - current_app.extensions["security"].datastore.commit() - # NOTE: Flash message after successful update of profile. - flash(_("Preferences were updated."), category="success") + form.populate_obj(current_user) + db.session.add(current_user) + current_app.extensions['security'].datastore.commit() + # NOTE: Flash message after successful update of profile. + flash(_('Preferences were updated.'), category='success') diff --git a/tests/test_views.py b/tests/test_views.py index 245aa8d..dbd18c3 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2022 Northwestern University. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -12,11 +13,9 @@ from flask_security import url_for_security from helpers import login, sign_up from invenio_accounts.models import User -from invenio_db import db from test_validators import test_usernames from invenio_userprofiles import InvenioUserProfiles -from invenio_userprofiles.models import UserProfile from invenio_userprofiles.views import blueprint_ui_init, userprofile @@ -98,13 +97,14 @@ def test_profile_view(app): resp = client.post( profile_url, data=prefix( - "profile", + 'profile', dict( - username=test_usernames["valid"], - full_name="Valid Name", - affiliations="Aff", - ), + username=test_usernames['valid'], + full_name='Valid Name', + affiliations='Aff', + ) ), + follow_redirects=True ) assert resp.status_code == 200 @@ -124,6 +124,7 @@ def test_profile_view(app): full_name="Valid Name", affiliations="Aff", ), + follow_redirects=True ), ) @@ -138,13 +139,14 @@ def test_profile_view(app): client.post( profile_url, data=prefix( - "profile", + 'profile', dict( - username="{0} ".format(test_usernames["valid"]), - full_name="Valid Name ", - affiliations=" Aff ", - ), + username='{0} '.format(test_usernames['valid']), + full_name='Valid Name ', + affiliations=' Aff ', + ) ), + follow_redirects=True ) resp = client.get(profile_url) @@ -219,12 +221,12 @@ def test_profile_case_change(app): ) # Set the name first time - resp = client.post(profile_url, data=data) + resp = client.post(profile_url, data=data, follow_redirects=True) assert resp.status_code == 200 assert error_msg not in resp.get_data(as_text=True) # Set the name second time - resp = client.post(profile_url, data=data) + resp = client.post(profile_url, data=data, follow_redirects=True) assert resp.status_code == 200 assert error_msg not in resp.get_data(as_text=True) @@ -233,7 +235,7 @@ def test_profile_case_change(app): "profile", dict(username="Valid", full_name="Another name", affiliations="") ) - resp = client.post(profile_url, data=data) + resp = client.post(profile_url, data=data, follow_redirects=True) assert resp.status_code == 200 assert error_msg not in resp.get_data(as_text=True) From 20639bef966a5e2a19e64e2b697707a2cf7833d5 Mon Sep 17 00:00:00 2001 From: Guillaume Viger Date: Thu, 7 Jul 2022 12:53:07 -0400 Subject: [PATCH 47/65] code-styling: adjust for black --- invenio_userprofiles/views.py | 47 +++++++++++++++++++++-------------- tests/test_views.py | 26 +++++++++---------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index e538233..7cff239 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -11,8 +11,15 @@ from warnings import warn -from flask import Blueprint, current_app, flash, redirect, render_template, \ - request, url_for +from flask import ( + Blueprint, + current_app, + flash, + redirect, + render_template, + request, + url_for, +) from flask_babelex import lazy_gettext as _ from flask_breadcrumbs import register_breadcrumb from flask_login import current_user, login_required @@ -107,14 +114,14 @@ def profile(): # Pick form is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) - form_name = request.form.get('submit', None) - if form_name == 'profile' and not is_read_only: + form_name = request.form.get("submit", None) + if form_name == "profile" and not is_read_only: handle_form = handle_profile_form form = profile_form - elif form_name == 'verification': + elif form_name == "verification": handle_form = handle_verification_form form = verification_form - elif form_name == 'preferences': + elif form_name == "preferences": handle_form = handle_preferences_form form = preferences_form else: @@ -128,10 +135,10 @@ def profile(): return redirect(url_for(".profile"), code=303) # this endpoint return render_template( - current_app.config['USERPROFILES_PROFILE_TEMPLATE'], + current_app.config["USERPROFILES_PROFILE_TEMPLATE"], verification_form=verification_form, profile_form=profile_form, - preferences_form=preferences_form + preferences_form=preferences_form, ) @@ -161,10 +168,12 @@ def handle_verification_form(form): def handle_profile_form(form): """Handle profile update form.""" email_changed = False - datastore = current_app.extensions['security'].datastore + datastore = current_app.extensions["security"].datastore with db.session.begin_nested(): - if current_app.config['USERPROFILES_EMAIL_ENABLED'] and \ - form.email.data != current_user.email: + if ( + current_app.config["USERPROFILES_EMAIL_ENABLED"] + and form.email.data != current_user.email + ): email_changed = True form.populate_obj(current_user) db.session.add(current_user) @@ -175,20 +184,22 @@ def handle_profile_form(form): send_confirmation_instructions(current_user) # NOTE: Flash message after successful update of profile. flash( - _('Profile was updated. We have sent a verification ' - 'email to %(email)s. Please check it.', - email=current_user.email), - category='success' + _( + "Profile was updated. We have sent a verification " + "email to %(email)s. Please check it.", + email=current_user.email, + ), + category="success", ) else: # NOTE: Flash message after successful update of profile. - flash(_('Profile was updated.'), category='success') + flash(_("Profile was updated."), category="success") def handle_preferences_form(form): """Handle preferences form.""" form.populate_obj(current_user) db.session.add(current_user) - current_app.extensions['security'].datastore.commit() + current_app.extensions["security"].datastore.commit() # NOTE: Flash message after successful update of profile. - flash(_('Preferences were updated.'), category='success') + flash(_("Preferences were updated."), category="success") diff --git a/tests/test_views.py b/tests/test_views.py index dbd18c3..cf28f2d 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -97,14 +97,14 @@ def test_profile_view(app): resp = client.post( profile_url, data=prefix( - 'profile', + "profile", dict( - username=test_usernames['valid'], - full_name='Valid Name', - affiliations='Aff', - ) + username=test_usernames["valid"], + full_name="Valid Name", + affiliations="Aff", + ), ), - follow_redirects=True + follow_redirects=True, ) assert resp.status_code == 200 @@ -124,8 +124,8 @@ def test_profile_view(app): full_name="Valid Name", affiliations="Aff", ), - follow_redirects=True ), + follow_redirects=True, ) assert resp.status_code == 200 @@ -139,14 +139,14 @@ def test_profile_view(app): client.post( profile_url, data=prefix( - 'profile', + "profile", dict( - username='{0} '.format(test_usernames['valid']), - full_name='Valid Name ', - affiliations=' Aff ', - ) + username="{0} ".format(test_usernames["valid"]), + full_name="Valid Name ", + affiliations=" Aff ", + ), ), - follow_redirects=True + follow_redirects=True, ) resp = client.get(profile_url) From c5b3c078a49d3e6a65e5d6ebdb6e5773dc879140 Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Fri, 8 Jul 2022 13:47:54 +0200 Subject: [PATCH 48/65] release: v2.0.3 --- CHANGES.rst | 5 +++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index d90bcaa..3cdb7a5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,11 @@ Changes ======= +Version 2.0.3 (released 2022-07-08) + +- add redirection on user profile form submit +- allow updating preferences for read only profiles + Version 2.0.2 (released 2022-07-01) - Style radio buttons and remove dotted bullet points in settings page. diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 44c43ba..26deb81 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.0.2" +__version__ = "2.0.3" __all__ = ( "__version__", From 3da7c4da85dcbc026f111d8575105edd16a9e065 Mon Sep 17 00:00:00 2001 From: David Eckhard Date: Tue, 8 Nov 2022 11:44:08 +0100 Subject: [PATCH 49/65] i18n:pulled translations --- .../translations/af/LC_MESSAGES/messages.po | 168 ++++++++++++++++ .../translations/ar/LC_MESSAGES/messages.po | 183 ++++++++++++++++++ .../translations/bg/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/ca/LC_MESSAGES/messages.po | 173 +++++++++++++++++ .../translations/cs/LC_MESSAGES/messages.po | 177 +++++++++++++++++ .../translations/da/LC_MESSAGES/messages.po | 121 ++++++++---- .../translations/de/LC_MESSAGES/messages.po | 54 +++--- .../translations/el/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/es/LC_MESSAGES/messages.po | 166 ++++++++++------ .../translations/et/LC_MESSAGES/messages.po | 181 +++++++++++++++++ .../et_EE/LC_MESSAGES/messages.po | 168 ++++++++++++++++ .../translations/fa/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/fr/LC_MESSAGES/messages.po | 126 ++++++++---- .../translations/gl/LC_MESSAGES/messages.po | 168 ++++++++++++++++ .../translations/hr/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/hu/LC_MESSAGES/messages.po | 182 +++++++++++++++++ .../translations/it/LC_MESSAGES/messages.po | 127 ++++++++---- .../translations/ja/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/ka/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/lt/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/no/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/pl/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/pt/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/ro/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/ru/LC_MESSAGES/messages.po | 172 ++++++++++++++++ .../translations/rw/LC_MESSAGES/messages.po | 168 ++++++++++++++++ .../translations/sk/LC_MESSAGES/messages.po | 177 +++++++++++++++++ .../translations/sv/LC_MESSAGES/messages.po | 181 +++++++++++++++++ .../translations/tr/LC_MESSAGES/messages.po | 116 +++++++---- .../translations/uk/LC_MESSAGES/messages.po | 168 ++++++++++++++++ .../zh_CN/LC_MESSAGES/messages.po | 173 +++++++++++++++++ .../zh_TW/LC_MESSAGES/messages.po | 172 ++++++++++++++++ 32 files changed, 4978 insertions(+), 235 deletions(-) create mode 100644 invenio_userprofiles/translations/af/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ar/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/bg/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ca/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/cs/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/el/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/et/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/et_EE/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/fa/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/gl/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/hr/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/hu/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ja/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ka/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/lt/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/no/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/pl/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/pt/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ro/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/ru/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/rw/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/sk/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/sv/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/uk/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/zh_CN/LC_MESSAGES/messages.po create mode 100644 invenio_userprofiles/translations/zh_TW/LC_MESSAGES/messages.po diff --git a/invenio_userprofiles/translations/af/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/af/LC_MESSAGES/messages.po new file mode 100644 index 0000000..3ff94bf --- /dev/null +++ b/invenio_userprofiles/translations/af/LC_MESSAGES/messages.po @@ -0,0 +1,168 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Language-Team: Afrikaans (https://www.transifex.com/inveniosoftware/teams/23537/af/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: af\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ar/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ar/LC_MESSAGES/messages.po new file mode 100644 index 0000000..705138a --- /dev/null +++ b/invenio_userprofiles/translations/ar/LC_MESSAGES/messages.po @@ -0,0 +1,183 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# Salaheddine Ben Ali , 2022 +# Bessem Aamira , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Bessem Aamira , 2022\n" +"Language-Team: Arabic (https://www.transifex.com/inveniosoftware/teams/23537/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ar\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" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "اسم المستخدم" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "ضروري. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "لم تدخل إسم مستخدم" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "الإسم الكامل" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "الانتماءات" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "إسم المستخدم غير موجود." + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "عنوان البريد الإلكتروني" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "أعد كتابة عنوان البريد الإلكتروني" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "أعد كتابة عنوان بريدك الإلكتروني، من فضلك." + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "عناوين البريد الإلكتروني غير متطابقة." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "أعد إرسال بريد التثبّت" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "رؤية الملف الشخصي" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "عام" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "مخفي" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"الملفات الشخصية العامة يمكن البحث عنها من قبل المستخدمين الآخرين عن طريق اسم" +" المستخدم و الاسم الكامل و الانتماءات. الملفات الخصية الخفية لا يمكن إيجادها" +" من قبل بقية المستخدمين." + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "رؤية عنوان البريد الالكتروني" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" +"تتيح رؤية عنوان البريد الإلكتروني المضمن بالملف الشخصي للعامة إمكانية البحث " +"و ايجاد ملف الحساب الشخصي عبر بريده الإلكتروني. " + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"إسم المستخدم يتكون من ثلاثة حروف على الأقل. يجب ان يبدأ بحرف هجائي. و تستعمل" +" فيه الحروف الهجائية، الأرقم و الشّرطات القصيرة و الطويلة." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)sالملف الشّخصي" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "الملف الشّخصي" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "تمّ إرسال بريد التثبّت." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"وقع تحديث الملف الشّخصي. أرسلنا بريدا للتّثبّت إلى %(email)s. فالرجاء " +"التّأكّد." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "وقع تحديث الملف الشّخصي" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "تم تحيين الإعدادات." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "لم تتثبّت بعد من عنوان بريدك الإلكتروني." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "إلغاء" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "تحديث الملف الشّخصي" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "الإعدادات" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "تحيين الأعدادات" diff --git a/invenio_userprofiles/translations/bg/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/bg/LC_MESSAGES/messages.po new file mode 100644 index 0000000..5ced703 --- /dev/null +++ b/invenio_userprofiles/translations/bg/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Bulgarian (https://www.transifex.com/inveniosoftware/teams/23537/bg/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: bg\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Потребител" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "E-mail адрес" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Отказ" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ca/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ca/LC_MESSAGES/messages.po new file mode 100644 index 0000000..78a130c --- /dev/null +++ b/invenio_userprofiles/translations/ca/LC_MESSAGES/messages.po @@ -0,0 +1,173 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# Ferran Jorba , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Ferran Jorba , 2022\n" +"Language-Team: Catalan (https://www.transifex.com/inveniosoftware/teams/23537/ca/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Nom d'usuari" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Afiliacions" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Adreça de correu electrònic" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Públic" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Cancel·la" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/cs/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/cs/LC_MESSAGES/messages.po new file mode 100644 index 0000000..224f589 --- /dev/null +++ b/invenio_userprofiles/translations/cs/LC_MESSAGES/messages.po @@ -0,0 +1,177 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Jiří Kunčar , 2016 +# Ivan Masár , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Ivan Masár , 2022\n" +"Language-Team: Czech (https://www.transifex.com/inveniosoftware/teams/23537/cs/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: cs\n" +"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Uživatelské jméno" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Vyžadováno. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "Uživatelské jméno nezadáno." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "Celé jméno" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Emailová adresa" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "Emailová adresa pro ověření" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "Prosím, zadejte znova Vaši emailovou adresu." + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "Emailové adresy se neshodují." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "Znovu zaslat ověřovací email." + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Veřejný" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"Uživatelské jménu musí začínat písmenem, být alespoň 3 znaky dlouhé a skládá" +" se pouze z písmen, čísel, pomlček and podtržítek." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "Profil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "Ověřovací email byl odeslán." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"Profil byl aktualizován. Poslali jsme ověřovací e-mail na adresu %(email)s. " +"Prosím, přečtěte si ho." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "Profil byl aktualizován." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "Čekáme na ověření Vaši emailové adresy." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Stornovat" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "Aktualizovat profil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/da/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/da/LC_MESSAGES/messages.po index 4f30fb7..d38b31d 100644 --- a/invenio_userprofiles/translations/da/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/da/LC_MESSAGES/messages.po @@ -1,85 +1,112 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2016 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2016. +# FIRST AUTHOR , 2022. +# +# Translators: +# Alizee Pace , 2016 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.0.0a7.dev20160617\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2016-08-18 16:12+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" "Last-Translator: Alizee Pace , 2016\n" "Language-Team: Danish (https://www.transifex.com/inveniosoftware/teams/23537/da/)\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.3.4\n" +"Generated-By: Babel 2.10.3\n" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: invenio_userprofiles/admin.py:58 -msgid "Display Name" -msgstr "" - -#: invenio_userprofiles/admin.py:64 -msgid "User Management" -msgstr "" - #. NOTE: Form field label -#: invenio_userprofiles/forms.py:60 +#: invenio_userprofiles/forms.py:51 msgid "Username" msgstr "Brugernavn" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:62 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" msgstr "Påkrævet. %(username_rules)s" -#: invenio_userprofiles/forms.py:64 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." msgstr "" #. NOTE: Form label -#: invenio_userprofiles/forms.py:69 +#: invenio_userprofiles/forms.py:60 msgid "Full name" msgstr "Fulde navn" +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:85 -msgid "Username already exists." -msgstr "Brugernavn findes allerede." +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:119 msgid "Email address" msgstr "Email adresse" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:107 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" msgstr "Gentag email adresse" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:109 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." msgstr "Indtast venligst din email adresse igen." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:114 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." msgstr "Email adresserne skal være ens." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:123 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" msgstr "Send bekræftelses email" -#. NOTE: Used for both form help text and for form validation error. -#: invenio_userprofiles/validators.py:36 +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." @@ -88,23 +115,24 @@ msgstr "" "indeholde alfanumeriske tegn, bindestreg og understregningstegn." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:98 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profil" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:29 -#: invenio_userprofiles/views.py:101 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 msgid "Profile" msgstr "" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:146 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." msgstr "Bekræftelses email sendt." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:173 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -112,18 +140,35 @@ msgid "" msgstr "Profil opdateret. Vi har sendt en bekræftelses email til %(email)s." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:179 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." msgstr "Profil opdateret." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:37 +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." msgstr "Du mangler at bekræfte din email adresse." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:52 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" msgstr "Afbryd" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:53 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" msgstr "Opdater profil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po index 10e47b2..e3ebbb0 100644 --- a/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/de/LC_MESSAGES/messages.po @@ -14,46 +14,46 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 2.0.0\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2022-05-27 09:02+0200\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" "PO-Revision-Date: 2016-08-18 14:14+0000\n" "Last-Translator: chriz_uniba , 2022\n" "Language-Team: German (https://www.transifex.com/inveniosoftware/teams/23537/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.1\n" +"Generated-By: Babel 2.10.3\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:47 +#: invenio_userprofiles/forms.py:51 msgid "Username" msgstr "Kontoname" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:49 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" msgstr "Erforderlich. %(username_rules)s" -#: invenio_userprofiles/forms.py:53 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." msgstr "Kontoname nicht angegeben." #. NOTE: Form label -#: invenio_userprofiles/forms.py:59 +#: invenio_userprofiles/forms.py:60 msgid "Full name" msgstr "Vollständiger Name" #. NOTE: Form label -#: invenio_userprofiles/forms.py:65 +#: invenio_userprofiles/forms.py:67 msgid "Affiliations" msgstr "Zugehörigkeiten" #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:83 +#: invenio_userprofiles/forms.py:86 msgid "Username is not available." msgstr "Der Kontoname ist nicht verfügbar." @@ -63,38 +63,38 @@ msgid "Email address" msgstr "E-Mail-Adresse" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:131 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" msgstr "E-Mail-Adresse erneut eingeben" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:133 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." msgstr "Bitte geben Sie Ihre E-Mail-Adresse erneut ein." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:138 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." msgstr "Die E-Mail-Adressen stimmen nicht überein." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:147 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" msgstr "Verifizierungs-E-Mail erneut senden" -#: invenio_userprofiles/forms.py:185 +#: invenio_userprofiles/forms.py:190 msgid "Profile visibility" msgstr "Sichtbarkeit des Profils" -#: invenio_userprofiles/forms.py:187 invenio_userprofiles/forms.py:200 +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 msgid "Public" msgstr "Öffentlich" -#: invenio_userprofiles/forms.py:188 invenio_userprofiles/forms.py:201 +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 msgid "Hidden" msgstr "Verborgen" -#: invenio_userprofiles/forms.py:190 +#: invenio_userprofiles/forms.py:195 msgid "" "Public profiles can be found by other users via searches on username, full " "name and affiliation. Hidden profiles cannot be found by other users." @@ -103,11 +103,11 @@ msgstr "" "vollständigen Namens und der Zugehörigkeit von anderen gefunden werden. " "\"Verborgene\" Profile können von anderen nicht gefunden werden." -#: invenio_userprofiles/forms.py:198 +#: invenio_userprofiles/forms.py:203 msgid "Email visibility" msgstr "Sichtbarkeit der E-Mail" -#: invenio_userprofiles/forms.py:203 +#: invenio_userprofiles/forms.py:208 msgid "" "Public email visibility enables your profile to be found by your email " "address." @@ -125,24 +125,24 @@ msgstr "" "Unterstriche enthalten." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:87 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profil" #: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 #: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 -#: invenio_userprofiles/views.py:92 +#: invenio_userprofiles/views.py:105 msgid "Profile" msgstr "Profil" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:141 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." msgstr "Verifizierungs-E-Mail gesendet." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:166 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -152,12 +152,12 @@ msgstr "" "%(email)s gesendet. Bitte überprüfen Sie diese." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:172 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." msgstr "Das Profil wurde aktualisiert." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:187 +#: invenio_userprofiles/views.py:205 msgid "Preferences were updated." msgstr "Die Einstellungen wurden aktualisiert." @@ -168,7 +168,7 @@ msgstr "Sie haben Ihre E-Mail-Adresse noch nicht verifiziert." #: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 #: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:86 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" msgstr "Abbrechen" @@ -181,6 +181,6 @@ msgstr "Profil aktualisieren" msgid "Preferences" msgstr "Einstellungen" -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:87 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 msgid "Update preferences" msgstr "Einstellungen aktualisieren" diff --git a/invenio_userprofiles/translations/el/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/el/LC_MESSAGES/messages.po new file mode 100644 index 0000000..b0a70f3 --- /dev/null +++ b/invenio_userprofiles/translations/el/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2022\n" +"Language-Team: Greek (https://www.transifex.com/inveniosoftware/teams/23537/el/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: el\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Όνομα" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Affiliations" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Διεύθυνση email" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Ακύρωση" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/es/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/es/LC_MESSAGES/messages.po index 2bf5231..5966f10 100644 --- a/invenio_userprofiles/translations/es/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/es/LC_MESSAGES/messages.po @@ -1,126 +1,184 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2016 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2016. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# Zacharias Zacharodimos , 2022 +# Jesús Martín , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.0.0a7.dev20160617\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2016-08-18 16:12+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Jesús Martín , 2022\n" "Language-Team: Spanish (https://www.transifex.com/inveniosoftware/teams/23537/es/)\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.3.4\n" +"Generated-By: Babel 2.10.3\n" "Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: invenio_userprofiles/admin.py:58 -msgid "Display Name" -msgstr "" - -#: invenio_userprofiles/admin.py:64 -msgid "User Management" -msgstr "" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:60 +#: invenio_userprofiles/forms.py:51 msgid "Username" -msgstr "" +msgstr "Usuario" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:62 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" -msgstr "" +msgstr "Obligatorio. %(username_rules)s" -#: invenio_userprofiles/forms.py:64 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." -msgstr "" +msgstr "Nombre de usuario no proporcionado." #. NOTE: Form label -#: invenio_userprofiles/forms.py:69 +#: invenio_userprofiles/forms.py:60 msgid "Full name" -msgstr "" +msgstr "Nombre completo" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Afiliaciones" #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:85 -msgid "Username already exists." -msgstr "" +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "Nombre de usuario no disponible." #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:119 msgid "Email address" -msgstr "" +msgstr "Dirección de correo" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:107 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" -msgstr "" +msgstr "Vuelva a introducir la dirección de correo" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:109 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." -msgstr "" +msgstr "Por favor, vuelva a introducir su dirección de correo." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:114 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." -msgstr "" +msgstr "Los direcciones de correo no coinciden." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:123 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" +msgstr "Reenviar correo de verificación" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "Visibilidad del perfil" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Publico" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "Oculto" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"Otros usuarios pueden encontrar perfiles públicos a través de búsquedas de " +"nombre de usuario, nombre completo y afiliación. Los perfiles ocultos no " +"pueden ser encontrados por otros usuarios." + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "Visibilidad del correo" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." msgstr "" +"La visibilidad pública del correo permite que pueda encontrarse su perfil a " +"través del mismo." -#. NOTE: Used for both form help text and for form validation error. -#: invenio_userprofiles/validators.py:36 +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." msgstr "" +"El nombre de usuario debe iniciar con una letra y tener al menos tres " +"caracteres. Sólo se admiten caracteres alfanuméricos, guiones y guiones " +"bajos." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:98 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" -msgstr "" +msgstr "%(icon)s Perfil" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:29 -#: invenio_userprofiles/views.py:101 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 msgid "Profile" -msgstr "" +msgstr "Perfil" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:146 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." -msgstr "" +msgstr "Correo de verificación enviado." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:173 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " "check it." msgstr "" +"El perfil ha sido actualizado. Le hemos enviado un correo de verificación a " +"%(email)s. Le rogamos que lo compruebe." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:179 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." -msgstr "" +msgstr "El perfil ha sido actualizado." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "Las preferencias han sido actualizadas." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:37 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." -msgstr "" +msgstr "Todavía no ha verificado su dirección de correo." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:52 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" -msgstr "" +msgstr "Cancelar" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:53 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" -msgstr "" +msgstr "Actualizar perfil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "Preferencias" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "Actualizar preferencias" diff --git a/invenio_userprofiles/translations/et/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/et/LC_MESSAGES/messages.po new file mode 100644 index 0000000..9daf520 --- /dev/null +++ b/invenio_userprofiles/translations/et/LC_MESSAGES/messages.po @@ -0,0 +1,181 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Martin Jantson , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Martin Jantson , 2022\n" +"Language-Team: Estonian (https://www.transifex.com/inveniosoftware/teams/23537/et/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: et\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Kasutajanimi" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Nõutud. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "Puudub kasutajanimi." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "Ees- ja perekonnanimi" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Seosed" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "Kasutajanimi pole saadaval." + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "E-posti aadress" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "Sisestage e-posti aadress uuesti" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "Palun sisestade oma e-posti aadress uuesti" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "Sisestatud e-posti aadressid on erinevad." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "Saada kinnitusmeil uuesti" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "Profiili nähtavus" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Avalik" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "Varjatud" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"Avalikke profiile saavad teised kasutajad otsida kasutajanime, kasutaja " +"täisnime ja seoste järgi. Varjatud profiilid ei ole teistele kasutajatele " +"leitavad." + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "E-posti aadressi nähtavus" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" +"Avalik e-post võimaldab teistel otsida ja leida sinu profiili sinu e-posti " +"aadressi järgi." + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"Kasutajanimi peab algama tähega, olema vähemalt kolm tähemärki pikk ning " +"võib sisaldada ainult tähti, numbreid, mõttekriipse ja allkriipse." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profiil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "Profiil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "Kinnitusmeil on saadetud." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"Profiil on uuendatud. Kinnitusmeil on saadetud aadressile %(email)s, palun " +"kontrolli seda." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "Profiil on uuendatud." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "Sinu eelistused on uuendatud." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "Sa ei ole veel oma e-posti aadressi kinnitanud." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Tühista" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "Uuenda profiili" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "Eelistused" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "Uuenda eelistusi" diff --git a/invenio_userprofiles/translations/et_EE/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/et_EE/LC_MESSAGES/messages.po new file mode 100644 index 0000000..33ce245 --- /dev/null +++ b/invenio_userprofiles/translations/et_EE/LC_MESSAGES/messages.po @@ -0,0 +1,168 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Language-Team: Estonian (Estonia) (https://www.transifex.com/inveniosoftware/teams/23537/et_EE/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: et_EE\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/fa/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/fa/LC_MESSAGES/messages.po new file mode 100644 index 0000000..1618135 --- /dev/null +++ b/invenio_userprofiles/translations/fa/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2022\n" +"Language-Team: Persian (https://www.transifex.com/inveniosoftware/teams/23537/fa/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: fa\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "نام کاربری" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "وابستگی ها" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "نشانی پست الکترونیکی" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "لغو" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/fr/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/fr/LC_MESSAGES/messages.po index c51c54b..1a5f412 100644 --- a/invenio_userprofiles/translations/fr/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/fr/LC_MESSAGES/messages.po @@ -1,85 +1,113 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2016 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2016. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# Alizee Pace , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.0.0a7.dev20160617\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2016-08-18 16:12+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Alizee Pace , 2016\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Alizee Pace , 2022\n" "Language-Team: French (https://www.transifex.com/inveniosoftware/teams/23537/fr/)\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.3.4\n" +"Generated-By: Babel 2.10.3\n" "Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#: invenio_userprofiles/admin.py:58 -msgid "Display Name" -msgstr "Nom Affiché" - -#: invenio_userprofiles/admin.py:64 -msgid "User Management" -msgstr "Gestion des Utilisateurs" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:60 +#: invenio_userprofiles/forms.py:51 msgid "Username" msgstr "Nom d'utilisateur" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:62 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" msgstr "Obligatoire. %(username_rules)s" -#: invenio_userprofiles/forms.py:64 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." msgstr "Vous n'avez pas donné de nom d'utilisateur." #. NOTE: Form label -#: invenio_userprofiles/forms.py:69 +#: invenio_userprofiles/forms.py:60 msgid "Full name" msgstr "Nom complet" +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Affiliations" + #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:85 -msgid "Username already exists." -msgstr "Ce nom d'utilisateur est déjà pris." +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:119 msgid "Email address" msgstr "Adresse email" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:107 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" msgstr "Entrez à nouveau votre adresse email" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:109 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." msgstr "Veuillez entrer à nouveau votre adresse email." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:114 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." msgstr "Les adresses email sont différentes." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:123 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" msgstr "Renvoyer l'email de vérification" -#. NOTE: Used for both form help text and for form validation error. -#: invenio_userprofiles/validators.py:36 +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Public" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." @@ -89,23 +117,24 @@ msgstr "" "tirets ou des tirets bas." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:98 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profil" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:29 -#: invenio_userprofiles/views.py:101 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 msgid "Profile" msgstr "Profil" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:146 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." msgstr "Email de vérification envoyé." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:173 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -115,18 +144,35 @@ msgstr "" "vérification à l'adresse %(email)s. Nous vous prions de le consulter." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:179 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." msgstr "Profil mis à jour." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:37 +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." msgstr "Vous n'avez pas encore vérifié votre adresse email." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:52 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" msgstr "Annuler" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:53 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" msgstr "Mettre à jour le profil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/gl/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/gl/LC_MESSAGES/messages.po new file mode 100644 index 0000000..cf0f611 --- /dev/null +++ b/invenio_userprofiles/translations/gl/LC_MESSAGES/messages.po @@ -0,0 +1,168 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Language-Team: Galician (https://www.transifex.com/inveniosoftware/teams/23537/gl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/hr/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/hr/LC_MESSAGES/messages.po new file mode 100644 index 0000000..d85d76f --- /dev/null +++ b/invenio_userprofiles/translations/hr/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Croatian (https://www.transifex.com/inveniosoftware/teams/23537/hr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Korisničko ime" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Email adresa" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Odustani" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/hu/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/hu/LC_MESSAGES/messages.po new file mode 100644 index 0000000..a6d8869 --- /dev/null +++ b/invenio_userprofiles/translations/hu/LC_MESSAGES/messages.po @@ -0,0 +1,182 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Andrea Dömötör, 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Andrea Dömötör, 2022\n" +"Language-Team: Hungarian (https://www.transifex.com/inveniosoftware/teams/23537/hu/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: hu\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Felhasználónév" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Kötelező. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "Felhasználónév nincs megadva." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "Teljes név" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Affiliációk" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "A felhasználónév nem elérhető." + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Email cím" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "Adja meg újra az email címét" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "Kérjük, adja meg újra az email címét!" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "Az email címek nem egyeznek meg." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "Visszaigazoló email újraküldése" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "Profil láthatósága" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Nyilvános" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "Elrejtve" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"A nyilvános profilok megtalálhatók a keresőben felhasználónév, teljes név és" +" affiliáció alapján. A rejtett profilok nem kereshetők más felhasználók " +"számára." + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "Email láthatósága" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" +"A nyilvánosan látható email lehetővé teszi, hogy email cím alapján " +"megtalálják az ön profilját." + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"A felhasználónévnek egy betűvel kell kezdődnie, legalább három karakter " +"hosszúnak kell lennie, és csak alfanumerikus karaktereket, kötőjeleket és " +"alulvonásokat tartalmazhat." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "Profil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "Elküldtük a visszaigazoló emailt." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"A profilt frissítettük. Küldtünk egy megerősítő emailt a(z) %(email)s címre." +" Kérjük, ellenőrizze!" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "A profilt frissítettük." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "A beállításokat frissítettük." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "Ön még nem erősítette meg az email címét." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Mégsem" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "Profil frissítése" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "Beállítások" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "Frissítési beállítások" diff --git a/invenio_userprofiles/translations/it/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/it/LC_MESSAGES/messages.po index 1090b0c..9634079 100644 --- a/invenio_userprofiles/translations/it/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/it/LC_MESSAGES/messages.po @@ -1,85 +1,114 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2016 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2016. +# FIRST AUTHOR , 2022. +# +# Translators: +# Alizee Pace , 2016 +# Tibor Simko , 2022 +# Zacharias Zacharodimos , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.0.0a7.dev20160617\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2016-08-18 16:12+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Alizee Pace , 2016\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Zacharias Zacharodimos , 2022\n" "Language-Team: Italian (https://www.transifex.com/inveniosoftware/teams/23537/it/)\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.3.4\n" +"Generated-By: Babel 2.10.3\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: invenio_userprofiles/admin.py:58 -msgid "Display Name" -msgstr "Nome pubblico" - -#: invenio_userprofiles/admin.py:64 -msgid "User Management" -msgstr "Gestione degli Utenti" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:60 +#: invenio_userprofiles/forms.py:51 msgid "Username" msgstr "Nome utente" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:62 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" msgstr "Obbligatorio. %(username_rules)s" -#: invenio_userprofiles/forms.py:64 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." msgstr "Non hai scelto un nome utente." #. NOTE: Form label -#: invenio_userprofiles/forms.py:69 +#: invenio_userprofiles/forms.py:60 msgid "Full name" msgstr "Nome e cognome" +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Affiliazioni" + #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:85 -msgid "Username already exists." -msgstr "Il nome utente è già preso." +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:119 msgid "Email address" msgstr "Indirizzo email" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:107 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" msgstr "Conferma l'indirizzo email" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:109 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." msgstr "Conferma l'indirizzo email, per favore." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:114 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." msgstr "Gli indirizzi email sono diversi." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:123 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" msgstr "Rimanda l'email di verifica" -#. NOTE: Used for both form help text and for form validation error. -#: invenio_userprofiles/validators.py:36 +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Publico" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." @@ -89,23 +118,24 @@ msgstr "" "bassi." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:98 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profilo" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:29 -#: invenio_userprofiles/views.py:101 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 msgid "Profile" msgstr "Profilo" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:146 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." msgstr "Email di verifica mandato." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:173 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -115,18 +145,35 @@ msgstr "" "da %(email)s. Controlla la tua posta elettronica." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:179 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." msgstr "Profilo aggiornato." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:37 +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." msgstr "Non hai ancora verificato l'indirizzo email." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:52 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" msgstr "Annulla" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:53 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" msgstr "Aggiorna il profilo" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ja/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ja/LC_MESSAGES/messages.po new file mode 100644 index 0000000..5b1dbac --- /dev/null +++ b/invenio_userprofiles/translations/ja/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Japanese (https://www.transifex.com/inveniosoftware/teams/23537/ja/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "ユーザー名" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Eメイルアドレス" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "キャンセル" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ka/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ka/LC_MESSAGES/messages.po new file mode 100644 index 0000000..892d252 --- /dev/null +++ b/invenio_userprofiles/translations/ka/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Georgian (https://www.transifex.com/inveniosoftware/teams/23537/ka/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ka\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "მომხმარებლის სახელი" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "ელფოსტის მისამართი" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "გაუქმება" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/lt/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/lt/LC_MESSAGES/messages.po new file mode 100644 index 0000000..3735ed6 --- /dev/null +++ b/invenio_userprofiles/translations/lt/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Lithuanian (https://www.transifex.com/inveniosoftware/teams/23537/lt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: lt\n" +"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Vartotojo vardas" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "El.paštas" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Atšaukti" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/no/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/no/LC_MESSAGES/messages.po new file mode 100644 index 0000000..4914986 --- /dev/null +++ b/invenio_userprofiles/translations/no/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Norwegian (https://www.transifex.com/inveniosoftware/teams/23537/no/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: no\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Brukernavn" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "E-postadresse" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Avbryt" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/pl/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/pl/LC_MESSAGES/messages.po new file mode 100644 index 0000000..93617a6 --- /dev/null +++ b/invenio_userprofiles/translations/pl/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Polish (https://www.transifex.com/inveniosoftware/teams/23537/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Nazwa użytkownika" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Adres email" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Anuluj" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/pt/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/pt/LC_MESSAGES/messages.po new file mode 100644 index 0000000..acbc2e7 --- /dev/null +++ b/invenio_userprofiles/translations/pt/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Portuguese (https://www.transifex.com/inveniosoftware/teams/23537/pt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: pt\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Endereço de email" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Cancelar" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ro/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ro/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f5c2de9 --- /dev/null +++ b/invenio_userprofiles/translations/ro/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Romanian (https://www.transifex.com/inveniosoftware/teams/23537/ro/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ro\n" +"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Nume utilizator" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Anulează" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/ru/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/ru/LC_MESSAGES/messages.po new file mode 100644 index 0000000..4e3c508 --- /dev/null +++ b/invenio_userprofiles/translations/ru/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Russian (https://www.transifex.com/inveniosoftware/teams/23537/ru/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: ru\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Пользователь" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Email аддрес" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Отменить" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/rw/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/rw/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f4c51fb --- /dev/null +++ b/invenio_userprofiles/translations/rw/LC_MESSAGES/messages.po @@ -0,0 +1,168 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Language-Team: Kinyarwanda (https://www.transifex.com/inveniosoftware/teams/23537/rw/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: rw\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/sk/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/sk/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f8e3ddb --- /dev/null +++ b/invenio_userprofiles/translations/sk/LC_MESSAGES/messages.po @@ -0,0 +1,177 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2022 +# Ivan Masár , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Ivan Masár , 2022\n" +"Language-Team: Slovak (https://www.transifex.com/inveniosoftware/teams/23537/sk/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: sk\n" +"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Používateľské meno" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Povinné. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "Používateľské meno nebolo zadané." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "Celé meno" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Afiliácie" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "E-mailová adresa" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "Znovu zadajte e-mailovú adresu" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "Prosím, znovu zadajte vašu e-mailovú adresu." + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "E-mailové adresy sa nezhodujú." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "Znovu odoslať overovací e-mail" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Verejný" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"Používateľské meno musí začínať písmenom, mať dĺžku najmenej tri znaky a " +"môže obsahovať len alfanumerické znaky, pomlčky a podčiarknutia." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "Profil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "Overovací e-mail bol odoslaný" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"Profil bol aktualizovaný. Odoslali sme overovací e-mail na adresu %(email)s." +" Prosím, prečítajte si ho." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "Profil bol aktualizovaný." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "Zatiaľ ste nedokončili overenie vašej e-mailovej adresy." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Zrušiť" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "Aktualizovať profil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/sv/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/sv/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f5c7f41 --- /dev/null +++ b/invenio_userprofiles/translations/sv/LC_MESSAGES/messages.po @@ -0,0 +1,181 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# Sam Arbid, 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Sam Arbid, 2022\n" +"Language-Team: Swedish (https://www.transifex.com/inveniosoftware/teams/23537/sv/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: sv\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "Användarnamn" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "Nödvändig. %(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "Användarnamn har inte angetts." + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "Fulla namn" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Tillhörigheter" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "Användarnamn är inte tillgängligt." + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "Epost-adress" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "Upprepa e-mailadress" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "Vänligen ange din e-postadress igen." + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "E-postadresserna matchar inte." + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "Skicka verifieringsemail igen" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "Profilsynlighet" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Offentlig" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "Dold" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" +"Offentliga profiler kan hittas av andra användare via sökningar på " +"användarnamn, fullständigt namn och tillhörighet. Dolda profiler kan inte " +"hittas av andra användare." + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "E-post synlighet" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" +"Offentlig e-postsynlighet gör att din profil kan hittas av din e-postadress." + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" +"Användarnamn måste börja med en bokstav, vara minst tre tecken långt och " +"endast innehålla alfanumeriska tecken, bindestreck och understreck." + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s Profil" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "Profil" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "Verifieringsmail har skickats." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" +"Profilen har uppdaterats. Vi har skickat ett verifieringsmail till " +"%(email)s. Var vänlig kolla upp det." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "Profilen har uppdaterats." + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "Inställningar har uppdaterats." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "Du har inte verifierat din e-postadress ännu." + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "Avbryt" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "Uppdatera profil" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "Inställningar" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "Uppdatera inställningar" diff --git a/invenio_userprofiles/translations/tr/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/tr/LC_MESSAGES/messages.po index ab035af..fa68ab3 100644 --- a/invenio_userprofiles/translations/tr/LC_MESSAGES/messages.po +++ b/invenio_userprofiles/translations/tr/LC_MESSAGES/messages.po @@ -1,83 +1,113 @@ # Translations template for invenio-userprofiles. -# Copyright (C) 2020 CERN +# Copyright (C) 2022 CERN # This file is distributed under the same license as the # invenio-userprofiles project. -# FIRST AUTHOR , 2020. +# FIRST AUTHOR , 2022. # # Translators: # Berat Aldemir , 2020 +# Ben Translation and Interpreting Services , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: invenio-userprofiles 1.2.0a3\n" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" "Report-Msgid-Bugs-To: info@inveniosoftware.org\n" -"POT-Creation-Date: 2020-07-20 15:31+0300\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" "PO-Revision-Date: 2016-08-18 14:14+0000\n" -"Last-Translator: Berat Aldemir , 2020\n" +"Last-Translator: Ben Translation and Interpreting Services , 2022\n" "Language-Team: Turkish (https://www.transifex.com/inveniosoftware/teams/23537/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.8.0\n" +"Generated-By: Babel 2.10.3\n" "Language: tr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. NOTE: Form field label -#: invenio_userprofiles/admin.py:45 invenio_userprofiles/forms.py:48 +#: invenio_userprofiles/forms.py:51 msgid "Username" msgstr "Kullanıcı adı" -#: invenio_userprofiles/admin.py:52 -msgid "User Management" -msgstr "Kullanıcı Yönetimi" - #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:50 +#: invenio_userprofiles/forms.py:53 #, python-format msgid "Required. %(username_rules)s" msgstr "Gerekli. %(username_rules)s" -#: invenio_userprofiles/forms.py:52 +#: invenio_userprofiles/forms.py:54 msgid "Username not provided." msgstr "Kullanıcı adı girilmedi." #. NOTE: Form label -#: invenio_userprofiles/forms.py:57 +#: invenio_userprofiles/forms.py:60 msgid "Full name" msgstr "Tam ad" +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "Bağlı olunan kurumlar/kuruluşlar" + #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:73 -msgid "Username already exists." -msgstr "Kullanıcı adı zaten mevcut." +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:83 +#: invenio_userprofiles/forms.py:119 msgid "Email address" msgstr "E-posta adresi" #. NOTE: Form field label -#: invenio_userprofiles/forms.py:95 +#: invenio_userprofiles/forms.py:133 msgid "Re-enter email address" msgstr "E-posta adresini tekrar girin" #. NOTE: Form field help text -#: invenio_userprofiles/forms.py:97 +#: invenio_userprofiles/forms.py:135 msgid "Please re-enter your email address." msgstr "Lütfen e-posta adresini tekrar girin." #. NOTE: Form validation error. -#: invenio_userprofiles/forms.py:102 +#: invenio_userprofiles/forms.py:142 msgid "Email addresses do not match." msgstr "E-posta adresleri eşleşmiyor." #. NOTE: Form button label -#: invenio_userprofiles/forms.py:111 +#: invenio_userprofiles/forms.py:151 msgid "Resend verification email" msgstr "Doğrulama e-postasını tekrar gönder" -#: invenio_userprofiles/validators.py:20 +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "Herkese açık" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 msgid "" "Username must start with a letter, be at least three characters long and " "only contain alphanumeric characters, dashes and underscores." @@ -86,24 +116,24 @@ msgstr "" "sadece alfanumerik karakterleri, tireleri ve alttan çizgileri içermelidir." #. NOTE: Menu item text (icon replaced by a user icon). -#: invenio_userprofiles/views.py:82 +#: invenio_userprofiles/views.py:101 #, python-format msgid "%(icon)s Profile" msgstr "%(icon)s Profil" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:12 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:12 -#: invenio_userprofiles/views.py:85 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 msgid "Profile" msgstr "Profil" #. NOTE: Flash message. -#: invenio_userprofiles/views.py:130 +#: invenio_userprofiles/views.py:165 msgid "Verification email sent." msgstr "Doğrulama e-postası gönderildi." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:157 +#: invenio_userprofiles/views.py:187 #, python-format msgid "" "Profile was updated. We have sent a verification email to %(email)s. Please " @@ -113,21 +143,35 @@ msgstr "" "Lütfen kontrol edin." #. NOTE: Flash message after successful update of profile. -#: invenio_userprofiles/views.py:163 +#: invenio_userprofiles/views.py:196 msgid "Profile was updated." msgstr "Profil güncellendi." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:17 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:17 +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 msgid "You have not yet verified your email address." msgstr "E-posta adresinizi henüz onaylamadınız." -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:25 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:25 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 msgid "Cancel" msgstr "İptal" -#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:26 -#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:26 +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 msgid "Update profile" msgstr "Profili güncelle" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/uk/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/uk/LC_MESSAGES/messages.po new file mode 100644 index 0000000..6677ed4 --- /dev/null +++ b/invenio_userprofiles/translations/uk/LC_MESSAGES/messages.po @@ -0,0 +1,168 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Language-Team: Ukrainian (https://www.transifex.com/inveniosoftware/teams/23537/uk/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: uk\n" +"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" diff --git a/invenio_userprofiles/translations/zh_CN/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/zh_CN/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f533942 --- /dev/null +++ b/invenio_userprofiles/translations/zh_CN/LC_MESSAGES/messages.po @@ -0,0 +1,173 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# Kalven Richie, 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Kalven Richie, 2022\n" +"Language-Team: Chinese (China) (https://www.transifex.com/inveniosoftware/teams/23537/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "帐号" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "必需的。%(username_rules)s" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "未提供用户名。" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "全称" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "从属关系" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "用户名不可用。" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "电邮" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "重新输入电子邮件地址" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "请重新输入您的电子邮件地址。" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "电子邮件地址不匹配。" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "重新发送验证电子邮件 " + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "概要文件可见性" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "公开" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "隐藏的" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "其他用户可以通过搜索用户名、全名和从属关系找到公共配置文件。其他用户找不到隐藏的配置文件。" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "电子邮件可见性" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "公共电子邮件可见性使您的个人资料可以通过您的电子邮件地址找到。" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "用户名必须以字母开头,长度至少为三个字符,并且只能包含字母数字字符、破折号和下划线。" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "%(icon)s配置文件" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "配置文件" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "已发送验证电子邮件。" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "配置文件已更新。我们已向%(email)s发送验证电子邮件。请检查。" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "配置文件已更新。" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "首选项已更新。" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "您尚未验证您的电子邮件地址。" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "取消" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "更新配置文件" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "首选项" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "更新首选项" diff --git a/invenio_userprofiles/translations/zh_TW/LC_MESSAGES/messages.po b/invenio_userprofiles/translations/zh_TW/LC_MESSAGES/messages.po new file mode 100644 index 0000000..1f1c9f0 --- /dev/null +++ b/invenio_userprofiles/translations/zh_TW/LC_MESSAGES/messages.po @@ -0,0 +1,172 @@ +# Translations template for invenio-userprofiles. +# Copyright (C) 2022 CERN +# This file is distributed under the same license as the +# invenio-userprofiles project. +# FIRST AUTHOR , 2022. +# +# Translators: +# Tibor Simko , 2016 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: invenio-userprofiles 2.0.3\n" +"Report-Msgid-Bugs-To: info@inveniosoftware.org\n" +"POT-Creation-Date: 2022-10-12 09:55+0200\n" +"PO-Revision-Date: 2016-08-18 14:14+0000\n" +"Last-Translator: Tibor Simko , 2016\n" +"Language-Team: Chinese (Taiwan) (https://www.transifex.com/inveniosoftware/teams/23537/zh_TW/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.10.3\n" +"Language: zh_TW\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:51 +msgid "Username" +msgstr "帳號" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:53 +#, python-format +msgid "Required. %(username_rules)s" +msgstr "" + +#: invenio_userprofiles/forms.py:54 +msgid "Username not provided." +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:60 +msgid "Full name" +msgstr "" + +#. NOTE: Form label +#: invenio_userprofiles/forms.py:67 +msgid "Affiliations" +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:86 +msgid "Username is not available." +msgstr "" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:119 +msgid "Email address" +msgstr "電郵" + +#. NOTE: Form field label +#: invenio_userprofiles/forms.py:133 +msgid "Re-enter email address" +msgstr "" + +#. NOTE: Form field help text +#: invenio_userprofiles/forms.py:135 +msgid "Please re-enter your email address." +msgstr "" + +#. NOTE: Form validation error. +#: invenio_userprofiles/forms.py:142 +msgid "Email addresses do not match." +msgstr "" + +#. NOTE: Form button label +#: invenio_userprofiles/forms.py:151 +msgid "Resend verification email" +msgstr "" + +#: invenio_userprofiles/forms.py:190 +msgid "Profile visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:192 invenio_userprofiles/forms.py:205 +msgid "Public" +msgstr "" + +#: invenio_userprofiles/forms.py:193 invenio_userprofiles/forms.py:206 +msgid "Hidden" +msgstr "" + +#: invenio_userprofiles/forms.py:195 +msgid "" +"Public profiles can be found by other users via searches on username, full " +"name and affiliation. Hidden profiles cannot be found by other users." +msgstr "" + +#: invenio_userprofiles/forms.py:203 +msgid "Email visibility" +msgstr "" + +#: invenio_userprofiles/forms.py:208 +msgid "" +"Public email visibility enables your profile to be found by your email " +"address." +msgstr "" + +#: invenio_userprofiles/validators.py:18 +msgid "" +"Username must start with a letter, be at least three characters long and " +"only contain alphanumeric characters, dashes and underscores." +msgstr "" + +#. NOTE: Menu item text (icon replaced by a user icon). +#: invenio_userprofiles/views.py:101 +#, python-format +msgid "%(icon)s Profile" +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:13 +#: invenio_userprofiles/views.py:105 +msgid "Profile" +msgstr "" + +#. NOTE: Flash message. +#: invenio_userprofiles/views.py:165 +msgid "Verification email sent." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:187 +#, python-format +msgid "" +"Profile was updated. We have sent a verification email to %(email)s. Please " +"check it." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:196 +msgid "Profile was updated." +msgstr "" + +#. NOTE: Flash message after successful update of profile. +#: invenio_userprofiles/views.py:205 +msgid "Preferences were updated." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:21 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:40 +msgid "You have not yet verified your email address." +msgstr "" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:38 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:57 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:84 +msgid "Cancel" +msgstr "取消" + +#: invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html:39 +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:58 +msgid "Update profile" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:71 +msgid "Preferences" +msgstr "" + +#: invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html:85 +msgid "Update preferences" +msgstr "" From 3889b117a3adb6d323ef9a81a52e7e6fd9273d8c Mon Sep 17 00:00:00 2001 From: David Eckhard Date: Fri, 18 Nov 2022 14:29:59 +0100 Subject: [PATCH 50/65] tests: add teardown handler --- tests/conftest.py | 22 ++++++++++++++++++++++ tests/test_views.py | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 883d955..992cbee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. +# Copyright (C) 2022 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -66,6 +67,27 @@ def base_app(app_config): create_database(str(db.engine.url)) db.create_all() + # Taken from: https://github.com/inveniosoftware/invenio-accounts/blob/3ecc1a70da3636618fe14ff2ebf754eed9ec75a1/tests/conftest.py#L94-L112 + def delete_user_from_cache(exception): + """Delete user from `flask.g` when the request is tearing down. + + Flask-login==0.6.2 changed the way the user is saved i.e uses `flask.g`. + Flask.g is pointing to the application context which is initialized per + request. That said, `pytest-flask` is pushing an application context on each + test initialization that causes problems as subsequent requests during a test + are detecting the active application request and not popping it when the + sub-request is tearing down. That causes the logged in user to remain cached + for the whole duration of the test. To fix this, we add an explicit teardown + handler that will pop out the logged in user in each request and it will force + the user to be loaded each time. + """ + from flask import g + + if "_login_user" in g: + del g._login_user + + base_app.teardown_request(delete_user_from_cache) + yield base_app with base_app.app_context(): diff --git a/tests/test_views.py b/tests/test_views.py index cf28f2d..ab321b1 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -196,6 +196,7 @@ def test_profile_name_exists(app): username="existingname", full_name="Another name", affiliations="" ), ), + follow_redirects=True, ) assert resp.status_code == 200 assert error_msg in resp.get_data(as_text=True) @@ -300,7 +301,7 @@ def test_change_email(app): # Test existing email of another user. data["profile-email_repeat"] = data["profile-email"] = email1 - resp = client.post(profile_url, data=data) + resp = client.post(profile_url, data=data, follow_redirects=True) assert ( "exiting@test.org is already associated with an account." in resp.get_data(as_text=True) From 480ca6523e0a262342993e56ba48f1779764621f Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Mon, 21 Nov 2022 14:19:04 +0100 Subject: [PATCH 51/65] release: v2.0.4 --- CHANGES.rst | 4 ++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3cdb7a5..31a70a3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 2.0.4 (released 2022-11-21) + +- add translations + Version 2.0.3 (released 2022-07-08) - add redirection on user profile form submit diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 26deb81..cfc02d7 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.0.3" +__version__ = "2.0.4" __all__ = ( "__version__", From 407c81ea03743d63c56802829a6f155b2fee885f Mon Sep 17 00:00:00 2001 From: Nicola Tarocco Date: Tue, 13 Dec 2022 11:11:45 +0100 Subject: [PATCH 52/65] forms: add helper for preferences form * add helper to be able to use the preferences form during signup, as already done for the profile form. Useful when used with hidden forms where user is registered with OAuth. --- invenio_userprofiles/forms.py | 37 ++++++++++++++++++++++++++++++++--- tests/test_forms.py | 21 +++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index e6e697d..93a50d8 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -169,6 +169,8 @@ def __init__(self, *args, **kwargs): class RegisterForm(Form): """RegisterForm extended with UserProfile details.""" + # cannot be called `user_profile`, to avoid naming collision with the + # hybrid property in the model profile = FormField(CsrfDisabledProfileForm, separator=".") def to_dict(self): @@ -226,23 +228,25 @@ def populate_obj(self, user): def confirm_register_form_factory(Form): - """Factory for creating a confirm register form.""" + """Factory for creating a confirm register form with UserProfile fields.""" class CsrfDisabledProfileForm(ProfileForm): """Subclass of ProfileForm to disable CSRF token in the inner form. - This class will always be a inner form field of the parent class + This class will always be an inner form field of the parent class `Form`. The parent will add/remove the CSRF token in the form. """ def __init__(self, *args, **kwargs): """Initialize the object by hardcoding CSRF token to false.""" kwargs = _update_with_csrf_disabled(kwargs) - super(CsrfDisabledProfileForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) class ConfirmRegisterForm(Form): """RegisterForm extended with UserProfile details.""" + # cannot be called `user_profile`, to avoid naming collision with the + # hybrid property in the model profile = FormField(CsrfDisabledProfileForm, separator=".") def to_dict(self): @@ -255,6 +259,33 @@ def to_dict(self): return ConfirmRegisterForm +def confirm_register_form_preferences_factory(Form): + """Factory for creating a confirm register form with UserProfile and Preferences.""" + + class CsrfDisabledPreferencesForm(PreferencesForm): + """Subclass of PreferencesForm to disable CSRF token in the inner form.""" + + def __init__(self, *args, **kwargs): + """Initialize the object by hardcoding CSRF token to false.""" + kwargs = _update_with_csrf_disabled(kwargs) + super().__init__(*args, **kwargs) + + class ConfirmRegisterForm(Form): + """RegisterForm extended with Preferences details.""" + + # cannot be called `preferences`, to avoid naming collision with the + # hybrid property in the model + prefs = FormField(CsrfDisabledPreferencesForm, separator=".") + + def to_dict(self): + preferences_data = self.prefs.data + data = super().to_dict() + data["preferences"] = preferences_data + return data + + return ConfirmRegisterForm + + def _update_with_csrf_disabled(d=None): """Update the input dict with CSRF disabled.""" if d is None: diff --git a/tests/test_forms.py b/tests/test_forms.py index 664ca0e..5292ee9 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -11,6 +11,7 @@ from invenio_userprofiles.forms import ( _update_with_csrf_disabled, confirm_register_form_factory, + confirm_register_form_preferences_factory, register_form_factory, ) @@ -44,14 +45,28 @@ def test_force_disable_csrf_register_form(app_with_csrf): def test_confirm_register_form_factory_no_csrf(app): - """Test CSRF token is not in confirm form and not in profil - e inner form.""" + """Test CSRF token is not in confirm form and not in profile inner form.""" security = app.extensions["security"] rf = _get_form(app, security.confirm_register_form, confirm_register_form_factory) _assert_no_csrf_token(rf) +def test_confirm_register_form_preferences_factory_no_csrf(app): + """Test CSRF token is not in confirm form and not in inner forms.""" + security = app.extensions["security"] + + def factory_profile_preferences(Form): + ProfileForm = confirm_register_form_factory(Form) + return confirm_register_form_preferences_factory(ProfileForm) + + rf = _get_form(app, security.confirm_register_form, factory_profile_preferences) + + _assert_no_csrf_token(rf) + assert "prefs" in rf + assert "csrf_token" not in rf.prefs + + def test_confirm_register_form_factory_csrf(app_with_csrf): """Test CSRF token is in confirm form but not in profile inner form.""" security = app_with_csrf.extensions["security"] @@ -63,7 +78,7 @@ def test_confirm_register_form_factory_csrf(app_with_csrf): def test_force_disable_csrf_confirm_form(app_with_csrf): - """Test force disable CSRF for confirm. form""" + """Test force disable CSRF for confirm form""" security = app_with_csrf.extensions["security"] rf = _get_form( app_with_csrf, From 400ac5082fc918be1ec6dbed197a6a9973a2ca19 Mon Sep 17 00:00:00 2001 From: Zacharias Zacharodimos Date: Wed, 14 Dec 2022 11:07:41 +0100 Subject: [PATCH 53/65] release: v2.0.5 --- CHANGES.rst | 4 ++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 31a70a3..4dd51de 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 2.0.5 (released 2022-12-14) + +- forms: add helper for preferences form + Version 2.0.4 (released 2022-11-21) - add translations diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index cfc02d7..411ccca 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.0.4" +__version__ = "2.0.5" __all__ = ( "__version__", From 18f921c461ce48109200e4ae2f7bf4c65d9cb93d Mon Sep 17 00:00:00 2001 From: Mojib Wali <44528277+mb-wali@users.noreply.github.com> Date: Fri, 10 Feb 2023 09:11:06 +0100 Subject: [PATCH 54/65] ci: adds i18n workflow (#149) * ci: adds i18n workflow test: adds dry extract_messages command * update dependencies * use --output-file instead of --dry-run as it is buggy * move i18n test * Update run-i18n-tests.sh --------- Co-authored-by: mojib Co-authored-by: David Eckhard Co-authored-by: David <72449192+rekt-hard@users.noreply.github.com> --- .github/workflows/i18n-pull.yml | 64 ++++++++++++++++++++++++++++++ .github/workflows/i18n-push.yml | 69 +++++++++++++++++++++++++++++++++ .github/workflows/tests.yml | 3 ++ run-i18n-tests.sh | 12 ++++++ setup.cfg | 4 +- 5 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/i18n-pull.yml create mode 100644 .github/workflows/i18n-push.yml create mode 100755 run-i18n-tests.sh diff --git a/.github/workflows/i18n-pull.yml b/.github/workflows/i18n-pull.yml new file mode 100644 index 0000000..a603f5e --- /dev/null +++ b/.github/workflows/i18n-pull.yml @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2022 Graz University of Technology. +# +# Invenio-userprofiles is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. + +name: i18n:pull translations +on: workflow_dispatch # manually trigger + +jobs: + i18n-pull: + runs-on: ubuntu-20.04 + env: + PYTHON-VERSION: 3.9 + steps: + - name: Checkout + uses: actions/checkout@v2 + + # setup python + - name: Set up Python ${{ env.PYTHON-VERSION }} + uses: actions/setup-python@v2 + with: + python-version: ${{ env.PYTHON-VERSION }} + + # install dependencies + - name: Install dependencies + run: | + pip install -e ".[all]" + + # install transifex client + - name: transifex-client + run: | + pip install transifex-client + + # store token + - name: store token + run: | + touch ~/.transifexrc + echo [https://www.transifex.com] >> ~/.transifexrc + echo api_hostname=https://api.transifex.com >> ~/.transifexrc + echo hostname=https://www.transifex.com >> ~/.transifexrc + echo password=${{ secrets.TRANSIFEX_TOKEN }} >> ~/.transifexrc + echo username=api >> ~/.transifexrc + + # pull all lang + - name: pull translations + run: | + tx pull -a -f + + # remove transifex credential file + - name: remove transifexrc file + uses: JesseTG/rm@v1.0.2 + with: + path: ~/.transifexrc + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + commit-message: i18n:pulled translations + title: i18n:pulled translations + body: i18n:pulled translations + branch: 101-translations-pull # name of branch which PR is created from + delete-branch: true # delete branch once merged,closed # allow from settings diff --git a/.github/workflows/i18n-push.yml b/.github/workflows/i18n-push.yml new file mode 100644 index 0000000..b85cf5e --- /dev/null +++ b/.github/workflows/i18n-push.yml @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2022 Graz University of Technology. +# +# Invenio-userprofiles is free software; you can redistribute it and/or modify +# it under the terms of the MIT License; see LICENSE file for more details. + +name: i18n:push translations +on: workflow_dispatch # manually trigger + +jobs: + i18n-extract: + runs-on: ubuntu-20.04 + env: + PYTHON-VERSION: 3.9 + steps: + - name: Checkout + uses: actions/checkout@v2 + + # setup python + - name: Set up Python ${{ env.PYTHON-VERSION }} + uses: actions/setup-python@v2 + with: + python-version: ${{ env.PYTHON-VERSION }} + + # install dependencies + - name: Install dependencies + run: | + pip install -e ".[all]" + + # install transifex client + - name: transifex-client + run: | + pip install transifex-client + + # store token + - name: store token + run: | + touch ~/.transifexrc + echo [https://www.transifex.com] >> ~/.transifexrc + echo api_hostname=https://api.transifex.com >> ~/.transifexrc + echo hostname=https://www.transifex.com >> ~/.transifexrc + echo password=${{ secrets.TRANSIFEX_TOKEN }} >> ~/.transifexrc + echo username=api >> ~/.transifexrc + + # extract + - name: extract_messages + run: | + python setup.py extract_messages + + # push source + - name: push_messages + run: | + tx push -s + + # remove transifex credential file + - name: remove transifexrc file + uses: JesseTG/rm@v1.0.2 + with: + path: ~/.transifexrc + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + commit-message: i18n:push translations + title: i18n:push translations + body: i18n:push translations + branch: 101-translations-push # name of branch which PR is created from + delete-branch: true # delete branch once merged,closed diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cca69f3..56973e3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -103,6 +103,9 @@ jobs: docker --version docker-compose --version + - name: Run translations test + run: ./run-i18n-tests.sh + - name: Run tests run: | ./run-tests.sh diff --git a/run-i18n-tests.sh b/run-i18n-tests.sh new file mode 100755 index 0000000..be952fa --- /dev/null +++ b/run-i18n-tests.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# -*- coding: utf-8 -*- +# +# Copyright (C) 2023 Graz University of Technology. +# +# Invenio-Userprofiles is free software; you can redistribute it and/or modify it +# under the terms of the MIT License; see LICENSE file for more details. + +# Usage: +# ./run-i18n-tests.sh + +python -m setup extract_messages --output-file /dev/null diff --git a/setup.cfg b/setup.cfg index 76d387a..c4d0ed8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,8 +32,8 @@ install_requires = [options.extras_require] tests = - pytest-black>=0.3.0,<0.3.10 - pytest-invenio~=1.4.7 + pytest-black>=0.3.0 + pytest-invenio>=1.4.7 invenio-db[mysql,postgresql,versioning]>=1.0.14 sphinx>=4.5 admin = From 79227e46572ed5d667ae9f1558a4d4cf0881fae6 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 11 Jan 2023 21:50:28 +0100 Subject: [PATCH 55/65] migrate: flask_babelex replaced by invenio_i18n * removed use of speaklater and replaced by using LazyString from invenio_i18n so from flask-babel --- invenio_userprofiles/forms.py | 2 +- invenio_userprofiles/validators.py | 2 +- invenio_userprofiles/views.py | 6 +++--- tests/conftest.py | 2 +- tests/test_invenio_userprofile.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 93a50d8..909bcb2 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -9,10 +9,10 @@ """Forms for user profiles.""" from flask import current_app -from flask_babelex import lazy_gettext as _ from flask_login import current_user from flask_security.forms import email_required, email_validator, unique_user_email from flask_wtf import FlaskForm +from invenio_i18n import lazy_gettext as _ from wtforms import FormField, RadioField, StringField, SubmitField from wtforms.validators import ( DataRequired, diff --git a/invenio_userprofiles/validators.py b/invenio_userprofiles/validators.py index 2cff646..10e0b2e 100644 --- a/invenio_userprofiles/validators.py +++ b/invenio_userprofiles/validators.py @@ -10,7 +10,7 @@ import re -from flask_babelex import lazy_gettext as _ +from invenio_i18n import lazy_gettext as _ username_regex = re.compile("^[a-zA-Z][a-zA-Z0-9-_]{2}[a-zA-Z0-9-_]*$") """Username rules.""" diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 7cff239..403a1c9 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -20,14 +20,14 @@ request, url_for, ) -from flask_babelex import lazy_gettext as _ from flask_breadcrumbs import register_breadcrumb from flask_login import current_user, login_required from flask_menu import register_menu from flask_security.confirmable import send_confirmation_instructions from invenio_db import db +from invenio_i18n import LazyString +from invenio_i18n import lazy_gettext as _ from invenio_theme.proxies import current_theme_icons -from speaklater import make_lazy_string from .forms import ( EmailProfileForm, @@ -98,7 +98,7 @@ def userprofile(value): # NOTE: Menu item text (icon replaced by a user icon). _( "%(icon)s Profile", - icon=make_lazy_string(lambda: f''), + icon=LazyString(lambda: f''), ), order=0, ) diff --git a/tests/conftest.py b/tests/conftest.py index 992cbee..8f3ad80 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,12 +15,12 @@ import pytest from flask import Flask -from flask_babelex import Babel from flask_mail import Mail from flask_menu import Menu from invenio_accounts import InvenioAccounts from invenio_accounts.views import blueprint as accounts_blueprint from invenio_db import InvenioDB, db +from invenio_i18n import Babel from sqlalchemy_utils.functions import create_database, database_exists, drop_database from invenio_userprofiles import InvenioUserProfiles diff --git a/tests/test_invenio_userprofile.py b/tests/test_invenio_userprofile.py index 89d11de..31caae8 100644 --- a/tests/test_invenio_userprofile.py +++ b/tests/test_invenio_userprofile.py @@ -10,11 +10,11 @@ import pytest from flask import Flask -from flask_babelex import Babel from flask_mail import Mail from flask_menu import Menu from invenio_accounts import InvenioAccounts from invenio_db import InvenioDB, db +from invenio_i18n import Babel from invenio_userprofiles import InvenioUserProfiles From ca99425a599b6be30b751e5925412eb62666da37 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 8 Feb 2023 23:16:01 +0100 Subject: [PATCH 56/65] setup: allow newest pytest-invenio, pytest-black * remove unused import --- tests/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_views.py b/tests/test_views.py index ab321b1..f9c030e 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -16,7 +16,7 @@ from test_validators import test_usernames from invenio_userprofiles import InvenioUserProfiles -from invenio_userprofiles.views import blueprint_ui_init, userprofile +from invenio_userprofiles.views import blueprint_ui_init def prefix(name, data): From 1147ae21114eb4393d519fe8ae83467bc9535661 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Wed, 1 Mar 2023 23:24:42 +0100 Subject: [PATCH 57/65] setup: add invenio-i18n --- setup.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index c4d0ed8..760358c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ # This file is part of Invenio. # Copyright (C) 2015-2022 CERN. # Copyright (C) 2021 TU Wien. -# Copyright (C) 2022 Graz University of Technology. +# Copyright (C) 2022-2023 Graz University of Technology. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -29,6 +29,7 @@ python_requires = >=3.7 zip_safe = False install_requires = invenio-accounts>=2.0.0 + invenio-i18n>=2.0.0 [options.extras_require] tests = From e6fcc5644095728abe76cc9ead336b144d22ee65 Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Thu, 2 Mar 2023 15:32:46 +0100 Subject: [PATCH 58/65] setup: constraint major version of invenio-i18n --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 760358c..7c59e9a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,7 @@ python_requires = >=3.7 zip_safe = False install_requires = invenio-accounts>=2.0.0 - invenio-i18n>=2.0.0 + invenio-i18n>=2.0.0,<3.0.0 [options.extras_require] tests = From 2dc790eb3283089dd3cba4a274bda38fe61fc088 Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Thu, 2 Mar 2023 15:44:58 +0100 Subject: [PATCH 59/65] release: v2.1.0 --- CHANGES.rst | 5 +++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4dd51de..54e7577 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,11 @@ Changes ======= +Version 2.1.0. (released 2023-03-02) + +- remove deprecated flask_babelex imports +- install invenio_i18n explicitly + Version 2.0.5 (released 2022-12-14) - forms: add helper for preferences form diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 411ccca..701d052 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.0.5" +__version__ = "2.1.0" __all__ = ( "__version__", From 7330c330d0186f4f4d8d881e4f87cc2e91cc0c0a Mon Sep 17 00:00:00 2001 From: anikachurilova Date: Tue, 11 Apr 2023 12:34:10 +0200 Subject: [PATCH 60/65] translations: fix string format * closes https://github.com/inveniosoftware/invenio-app-rdm/issues/2162 --- invenio_userprofiles/forms.py | 4 +++- invenio_userprofiles/views.py | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index 909bcb2..d7db58e 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -50,7 +50,9 @@ class ProfileForm(FlaskForm): # NOTE: Form field label _("Username"), # NOTE: Form field help text - description=_("Required. %(username_rules)s", username_rules=USERNAME_RULES), + description=_("Required. {username_rules}").format( + username_rules=USERNAME_RULES + ), validators=[Length(max=50), DataRequired(message=_("Username not provided."))], filters=[strip_filter], ) diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 403a1c9..9659837 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -186,9 +186,8 @@ def handle_profile_form(form): flash( _( "Profile was updated. We have sent a verification " - "email to %(email)s. Please check it.", - email=current_user.email, - ), + "email to {email}. Please check it." + ).format(email=current_user.email), category="success", ) else: From e0133184a158dfea377e00739aedfb69e4297c92 Mon Sep 17 00:00:00 2001 From: Martin Lettry Date: Sat, 18 Mar 2023 12:23:25 +0100 Subject: [PATCH 61/65] preferences: add user preferences locale * closes https://github.com/inveniosoftware/invenio-app-rdm/issues/2069 * add support for preferences.timezone --- invenio_userprofiles/forms.py | 25 ++++++++++++++++++++++++- invenio_userprofiles/models.py | 2 +- tests/conftest.py | 3 ++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/invenio_userprofiles/forms.py b/invenio_userprofiles/forms.py index d7db58e..2028e61 100644 --- a/invenio_userprofiles/forms.py +++ b/invenio_userprofiles/forms.py @@ -8,12 +8,22 @@ """Forms for user profiles.""" +import pytz from flask import current_app from flask_login import current_user from flask_security.forms import email_required, email_validator, unique_user_email from flask_wtf import FlaskForm from invenio_i18n import lazy_gettext as _ -from wtforms import FormField, RadioField, StringField, SubmitField +from invenio_i18n.ext import InvenioI18N +from werkzeug.local import LocalProxy +from wtforms import ( + FormField, + RadioField, + SelectField, + StringField, + SubmitField, + validators, +) from wtforms.validators import ( DataRequired, EqualTo, @@ -215,6 +225,19 @@ class PreferencesForm(FlaskForm): ), ) + locale = LocalProxy( + lambda: SelectField( + _("Preferences locale"), + choices=set(current_app.extensions["invenio-i18n"].get_locales()), + ), + ) + + # timezone = SelectField( + # _("Preferences timezone"), + # choices=pytz.all_timezones, + # validators=[validators.InputRequired()], + # ) + def process(self, formdata=None, obj=None, data=None, extra_filters=None, **kwargs): """Build a proxy around the object.""" if obj is not None: diff --git a/invenio_userprofiles/models.py b/invenio_userprofiles/models.py index 179e450..d8c0951 100644 --- a/invenio_userprofiles/models.py +++ b/invenio_userprofiles/models.py @@ -24,7 +24,7 @@ class UserProfileProxy: """Proxy for a user that allows mapping the form to the user object.""" _profile_attrs = ["full_name", "affiliations"] - _preferences_attrs = ["email_visibility", "visibility"] + _preferences_attrs = ["email_visibility", "visibility", "locale", "timezone"] _read_only_attrs = ["email_repeat"] _aliases = {"email_repeat": "email", "user_id": "id"} diff --git a/tests/conftest.py b/tests/conftest.py index 8f3ad80..65aa48b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,7 +20,7 @@ from invenio_accounts import InvenioAccounts from invenio_accounts.views import blueprint as accounts_blueprint from invenio_db import InvenioDB, db -from invenio_i18n import Babel +from invenio_i18n import Babel, InvenioI18N from sqlalchemy_utils.functions import create_database, database_exists, drop_database from invenio_userprofiles import InvenioUserProfiles @@ -58,6 +58,7 @@ def base_app(app_config): Menu(base_app) InvenioDB(base_app) InvenioAccounts(base_app) + InvenioI18N(base_app) base_app.register_blueprint(accounts_blueprint) with base_app.app_context(): From 75c3708fb7bbf1374bbf245f2cbe40e11b40b5f4 Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Tue, 25 Apr 2023 16:29:15 +0200 Subject: [PATCH 62/65] release: v2.2.0 --- CHANGES.rst | 6 +++++- invenio_userprofiles/__init__.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 54e7577..5fd5ba9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,7 +8,11 @@ Changes ======= -Version 2.1.0. (released 2023-03-02) +Version 2.2.0 (released 2023-04-25) + +- add locale to user profile preferences + +Version 2.1.0 (released 2023-03-02) - remove deprecated flask_babelex imports - install invenio_i18n explicitly diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 701d052..3bbdcb1 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.1.0" +__version__ = "2.2.0" __all__ = ( "__version__", From 4b000c782d1845cd2262ef747c4b1002bf08b343 Mon Sep 17 00:00:00 2001 From: Jenny Bonsak Date: Fri, 5 May 2023 15:27:06 +0200 Subject: [PATCH 63/65] profile: add SUI styling for locale preferences field --- .../invenio_userprofiles/settings/profile.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html index 06ed9bc..6ecdd1b 100644 --- a/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/semantic-ui/invenio_userprofiles/settings/profile.html @@ -74,11 +74,13 @@ {%- set form = preferences_form %}
{%- for field in form %} - {%- if field.widget.input_type == 'hidden' %} - {{ field() }} - {%- else %} - {{ render_field(field, placeholder=field.label.text, field_class="form-control no-dots-list pl-0") }} - {%- endif %} + {%- if field.widget.input_type == 'hidden' %} + {{ field() }} + {%- elif field.type == 'SelectField' %} + {{ render_field(field, field_class="ui dropdown") }} + {%- else %} + {{ render_field(field, placeholder=field.label.text, field_class="form-control no-dots-list pl-0") }} + {%- endif %} {%- endfor %}
{{ _('Cancel') }} From 9339a8cf6a673f7d554c6555afb11335cfcd5a84 Mon Sep 17 00:00:00 2001 From: Karolina Przerwa Date: Fri, 26 May 2023 10:05:11 +0200 Subject: [PATCH 64/65] release: v2.2.1 --- CHANGES.rst | 4 ++++ invenio_userprofiles/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5fd5ba9..6071bcf 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,10 @@ Changes ======= +Version 2.2.1 (released 2023-05-26) + +- fix styling for locale preferences field + Version 2.2.0 (released 2023-04-25) - add locale to user profile preferences diff --git a/invenio_userprofiles/__init__.py b/invenio_userprofiles/__init__.py index 3bbdcb1..5ed33cd 100644 --- a/invenio_userprofiles/__init__.py +++ b/invenio_userprofiles/__init__.py @@ -30,7 +30,7 @@ from .ext import InvenioUserProfiles from .models import UserProfile, UserProfileProxy -__version__ = "2.2.0" +__version__ = "2.2.1" __all__ = ( "__version__", From 28ba2f3db741ebcf632d8fc6015365881ae686d2 Mon Sep 17 00:00:00 2001 From: Lauren-D Date: Thu, 14 Oct 2021 15:20:50 +0200 Subject: [PATCH 65/65] users: make user profiles read-only Co-Authored-by: Lauren-D --- .gitignore | 3 + invenio_userprofiles/config.py | 9 +++ .../settings/_macros.html | 29 ++++++++- .../settings/profile.html | 32 ++++++---- invenio_userprofiles/views.py | 61 +++++++++---------- 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index f32b3b9..6a62ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,6 @@ target/ # Example generated examples/static/ examples/instance/ + +# VSCode +.vscode \ No newline at end of file diff --git a/invenio_userprofiles/config.py b/invenio_userprofiles/config.py index fb3e078..e6e4cbc 100644 --- a/invenio_userprofiles/config.py +++ b/invenio_userprofiles/config.py @@ -29,5 +29,14 @@ USERPROFILES_SETTINGS_TEMPLATE = None """Settings base templates for user profile module.""" +USERPROFILES_DEFAULT_COUNTRY = None +"""Default country marc21 code for the user profile.""" + +USERPROFILES_COUNTRIES = lambda: [('ch', 'Switzerland')] +"""Function to return the list of label, value for contries.""" + +USERPROFILES_READONLY_FIELDS = lambda: [] +"""Function to return readonly fields.""" + USERPROFILES_READ_ONLY = False """Make the user profiles read-only.""" diff --git a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html index 8754b50..2760626 100644 --- a/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html +++ b/invenio_userprofiles/templates/invenio_userprofiles/settings/_macros.html @@ -7,11 +7,13 @@ under the terms of the MIT License; see LICENSE file for more details. #} -{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True, field_class="form-control") %} +{% macro render_field(field, icon="", placeholder='', autofocus=False, enabled=True) %}
{{ field.label }} {%- set extras = dict(autofocus="") if autofocus else dict() %} - {{field(class_=field_class, disabled=not enabled, placeholder=placeholder, **extras)}} + {{field(class_="form-control", disabled=not enabled, placeholder=placeholder, **extras)}} + + {%- if icon %} {%- endif %} @@ -28,3 +30,26 @@ {%- endif %}
{% endmacro %} + +{% macro render_checkbox_field(field, icon="", autofocus=False, enabled=True) %} +
+ {%- set extras = dict(autofocus="") if autofocus else dict() %} + {{field(class_="form-check-input", type="checkbox", disabled=not enabled, **extras)}} + {{ field.label }} + + {%- if icon %} + + {%- endif %} + {%- if field.description %} +
{{ field.description }}
+ {%- endif %} + {%- if field.errors %} + + {%- endif %} +
+{% endmacro %} diff --git a/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html b/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html index 9fea583..6c3c904 100644 --- a/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html +++ b/invenio_userprofiles/templates/invenio_userprofiles/settings/profile.html @@ -26,18 +26,24 @@ {%- set form = profile_form %} {%- set read_only = config.USERPROFILES_READ_ONLY %} -{%- for field in form %} -{%- if field.widget.input_type == 'hidden' %} -{{ field() }} -{%- elif not read_only or "repeat" not in field.id %} -{{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} -{%- endif %} -{%- endfor %} -{%- if not read_only %} -
- {{ _('Cancel') }} - -
-{%- endif %} + {%- for field in form %} + {%- if field.widget.input_type == 'hidden' %} + {{ field() }} + {%- else %} + {% if field.type == "BooleanField" %} + {{ render_checkbox_field(field, autofocus=True, enabled=not read_only) }} + {%- else %} + {{ render_field(field, autofocus=True, enabled=not read_only, placeholder=field.label.text) }} + {%- endif %} + + {%- endif %} + {%- endfor %} + {%- if not read_only %} +
+ {{ _('Cancel') }} + +
+ {%- endif %} {%- endblock settings_form %} diff --git a/invenio_userprofiles/views.py b/invenio_userprofiles/views.py index 9659837..074245e 100644 --- a/invenio_userprofiles/views.py +++ b/invenio_userprofiles/views.py @@ -112,27 +112,13 @@ def profile(): formdata=None, obj=current_user, prefix="preferences" ) - # Pick form + # Process forms is_read_only = current_app.config.get("USERPROFILES_READ_ONLY", False) - form_name = request.form.get("submit", None) - if form_name == "profile" and not is_read_only: - handle_form = handle_profile_form - form = profile_form - elif form_name == "verification": - handle_form = handle_verification_form - form = verification_form - elif form_name == "preferences": - handle_form = handle_preferences_form - form = preferences_form - else: - form = None - - # Process form - if form: - form.process(formdata=request.form) - if form.validate_on_submit(): - handle_form(form) - return redirect(url_for(".profile"), code=303) # this endpoint + form = request.form.get('submit', None) + if form == 'profile' and not is_read_only: + handle_profile_form(profile_form) + elif form == 'verification': + handle_verification_form(verification_form) return render_template( current_app.config["USERPROFILES_PROFILE_TEMPLATE"], @@ -167,18 +153,29 @@ def handle_verification_form(form): def handle_profile_form(form): """Handle profile update form.""" - email_changed = False - datastore = current_app.extensions["security"].datastore - with db.session.begin_nested(): - if ( - current_app.config["USERPROFILES_EMAIL_ENABLED"] - and form.email.data != current_user.email - ): - email_changed = True - form.populate_obj(current_user) - db.session.add(current_user) - datastore.mark_changed(id(db.session), uid=current_user.id) - datastore.commit() + if current_app.config.get("USERPROFILES_READ_ONLY", False): + return + + form.process(formdata=request.form) + if form.validate_on_submit(): + email_changed = False + with db.session.begin_nested(): + # Update profile. + current_userprofile.username = form.username.data + current_userprofile.last_name=form.last_name.data, + current_userprofile.first_name=form.first_name.data, + current_userprofile.gender=form.gender.data, + current_userprofile.birth_date=form.birth_date.data, + current_userprofile.street=form.street.data, + current_userprofile.postal_code=form.postal_code.data, + current_userprofile.city=form.city.data, + current_userprofile.country=form.country.data, + current_userprofile.home_phone=form.home_phone.data, + current_userprofile.business_phone=form.business_phone.data, + current_userprofile.mobile_phone=form.mobile_phone.data, + current_userprofile.other_phone=form.other_phone.data, + current_userprofile.keep_history=form.keep_history.data + db.session.add(current_userprofile) if email_changed: send_confirmation_instructions(current_user)