Add gettext to translatable strings

remotes/origin/enhancement/email-actions
David Barragán Merino 2015-03-27 13:31:36 +01:00
parent 2d960c7a5d
commit d3fade9565
48 changed files with 524 additions and 211 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: taiga-back\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-25 20:09+0100\n"
"POT-Creation-Date: 2015-04-06 17:04+0200\n"
"PO-Revision-Date: 2015-03-25 20:09+0100\n"
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
"Language-Team: Taiga Dev Team <support@taiga.io>\n"

View File

@ -17,7 +17,7 @@
from functools import partial
from enum import Enum
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.conf import settings
from rest_framework import serializers

View File

@ -18,6 +18,7 @@ from rest_framework import serializers
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
import re
@ -29,13 +30,13 @@ class BaseRegisterSerializer(serializers.Serializer):
def validate_username(self, attrs, source):
value = attrs[source]
validator = validators.RegexValidator(re.compile('^[\w.-]+$'), "invalid username", "invalid")
validator = validators.RegexValidator(re.compile('^[\w.-]+$'), _("invalid username"), "invalid")
try:
validator(value)
except ValidationError:
raise serializers.ValidationError("Required. 255 characters or fewer. Letters, numbers "
"and /./-/_ characters'")
raise serializers.ValidationError(_("Required. 255 characters or fewer. Letters, numbers "
"and /./-/_ characters'"))
return attrs

View File

@ -91,7 +91,7 @@ def get_membership_by_token(token:str):
membership_model = apps.get_model("projects", "Membership")
qs = membership_model.objects.filter(token=token)
if len(qs) == 0:
raise exc.NotFound("Token not matches any valid invitation.")
raise exc.NotFound(_("Token not matches any valid invitation."))
return qs[0]
@ -119,7 +119,7 @@ def public_register(username:str, password:str, email:str, full_name:str):
try:
user.save()
except IntegrityError:
raise exc.WrongArguments("User is already register.")
raise exc.WrongArguments(_("User is already register."))
send_register_email(user)
user_registered_signal.send(sender=user.__class__, user=user)
@ -143,7 +143,7 @@ def private_register_for_existing_user(token:str, username:str, password:str):
membership.user = user
membership.save(update_fields=["user"])
except IntegrityError:
raise exc.IntegrityError("Membership with user is already exists.")
raise exc.IntegrityError(_("Membership with user is already exists."))
send_register_email(user)
return user

View File

@ -18,6 +18,7 @@ from taiga.base import exceptions as exc
from django.apps import apps
from django.core import signing
from django.utils.translation import ugettext as _
def get_token_for_user(user, scope):
@ -43,13 +44,13 @@ def get_user_for_token(token, scope, max_age=None):
try:
data = signing.loads(token, max_age=max_age)
except signing.BadSignature:
raise exc.NotAuthenticated("Invalid token")
raise exc.NotAuthenticated(_("Invalid token"))
model_cls = apps.get_model("users", "User")
try:
user = model_cls.objects.get(pk=data["user_%s_id" % (scope)])
except (model_cls.DoesNotExist, KeyError):
raise exc.NotAuthenticated("Invalid token")
raise exc.NotAuthenticated(_("Invalid token"))
else:
return user

View File

@ -126,11 +126,11 @@ class GenericAPIView(views.APIView):
"""
deprecated_style = False
if page_size is not None:
warnings.warn('The `page_size` parameter to `paginate_queryset()` '
warnings.warn(_('The `page_size` parameter to `paginate_queryset()` '
'is due to be deprecated. '
'Note that the return style of this method is also '
'changed, and will simply return a page object '
'when called without a `page_size` argument.',
'when called without a `page_size` argument.'),
PendingDeprecationWarning, stacklevel=2)
deprecated_style = True
else:
@ -141,12 +141,10 @@ class GenericAPIView(views.APIView):
return None
if not self.allow_empty:
warnings.warn(
'The `allow_empty` parameter is due to be deprecated. '
warnings.warn(_('The `allow_empty` parameter is due to be deprecated. '
'To use `allow_empty=False` style behavior, You should override '
'`get_queryset()` and explicitly raise a 404 on empty querysets.',
PendingDeprecationWarning, stacklevel=2
)
'`get_queryset()` and explicitly raise a 404 on empty querysets.'),
PendingDeprecationWarning, stacklevel=2)
paginator = self.paginator_class(queryset, page_size,
allow_empty_first_page=self.allow_empty)
@ -191,10 +189,10 @@ class GenericAPIView(views.APIView):
"""
filter_backends = self.filter_backends or []
if not filter_backends and hasattr(self, 'filter_backend'):
raise RuntimeError('The `filter_backend` attribute and `FILTER_BACKEND` setting '
raise RuntimeError(_('The `filter_backend` attribute and `FILTER_BACKEND` setting '
'are due to be deprecated in favor of a `filter_backends` '
'attribute and `DEFAULT_FILTER_BACKENDS` setting, that take '
'a *list* of filter backend classes.')
'a *list* of filter backend classes.'))
return filter_backends
###########################################################
@ -212,8 +210,8 @@ class GenericAPIView(views.APIView):
Otherwise defaults to using `self.paginate_by`.
"""
if queryset is not None:
raise RuntimeError('The `queryset` parameter to `get_paginate_by()` '
'is due to be deprecated.')
raise RuntimeError(_('The `queryset` parameter to `get_paginate_by()` '
'is due to be deprecated.'))
if self.paginate_by_param:
try:
return strict_positive_int(
@ -233,11 +231,9 @@ class GenericAPIView(views.APIView):
if serializer_class is not None:
return serializer_class
assert self.model is not None, \
"'%s' should either include a 'serializer_class' attribute, " \
"or use the 'model' attribute as a shortcut for " \
"automatically generating a serializer class." \
% self.__class__.__name__
assert self.model is not None, _("'%s' should either include a 'serializer_class' attribute, "
"or use the 'model' attribute as a shortcut for "
"automatically generating a serializer class." % self.__class__.__name__)
class DefaultSerializer(self.model_serializer_class):
class Meta:
@ -261,7 +257,7 @@ class GenericAPIView(views.APIView):
if self.model is not None:
return self.model._default_manager.all()
raise ImproperlyConfigured("'%s' must define 'queryset' or 'model'" % self.__class__.__name__)
raise ImproperlyConfigured(_("'%s' must define 'queryset' or 'model'" % self.__class__.__name__))
def get_object(self, queryset=None):
"""
@ -289,18 +285,16 @@ class GenericAPIView(views.APIView):
if lookup is not None:
filter_kwargs = {self.lookup_field: lookup}
elif pk is not None and self.lookup_field == 'pk':
raise RuntimeError('The `pk_url_kwarg` attribute is due to be deprecated. '
'Use the `lookup_field` attribute instead')
raise RuntimeError(_('The `pk_url_kwarg` attribute is due to be deprecated. '
'Use the `lookup_field` attribute instead'))
elif slug is not None and self.lookup_field == 'pk':
raise RuntimeError('The `slug_url_kwarg` attribute is due to be deprecated. '
'Use the `lookup_field` attribute instead')
raise RuntimeError(_('The `slug_url_kwarg` attribute is due to be deprecated. '
'Use the `lookup_field` attribute instead'))
else:
raise ImproperlyConfigured(
'Expected view %s to be called with a URL keyword argument '
raise ImproperlyConfigured(_('Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, self.lookup_field)
)
(self.__class__.__name__, self.lookup_field)))
obj = get_object_or_404(queryset, **filter_kwargs)
return obj

View File

@ -22,6 +22,7 @@ import warnings
from django.core.exceptions import ValidationError
from django.http import Http404
from django.db import transaction as tx
from django.utils.translation import ugettext as _
from taiga.base import response
from rest_framework.settings import api_settings
@ -94,12 +95,10 @@ class ListModelMixin(object):
# Default is to allow empty querysets. This can be altered by setting
# `.allow_empty = False`, to raise 404 errors on empty querysets.
if not self.allow_empty and not self.object_list:
warnings.warn(
'The `allow_empty` parameter is due to be deprecated. '
warnings.warn(_('The `allow_empty` parameter is due to be deprecated. '
'To use `allow_empty=False` style behavior, You should override '
'`get_queryset()` and explicitly raise a 404 on empty querysets.',
PendingDeprecationWarning
)
'`get_queryset()` and explicitly raise a 404 on empty querysets.'),
PendingDeprecationWarning)
class_name = self.__class__.__name__
error_msg = self.empty_error % {'class_name': class_name}
raise Http404(error_msg)

View File

@ -20,6 +20,7 @@ from taiga.base.utils import sequence as sq
from taiga.permissions.service import user_has_perm, is_project_owner
from django.apps import apps
from django.utils.translation import ugettext as _
######################################################################
# Base permissiones definition
@ -57,7 +58,7 @@ class ResourcePermission(object):
elif inspect.isclass(permset) and issubclass(permset, PermissionComponent):
permset = permset()
else:
raise RuntimeError("Invalid permission definition.")
raise RuntimeError(_("Invalid permission definition."))
if self.global_perms:
permset = (self.global_perms & permset)

View File

@ -23,6 +23,7 @@ from django.core.exceptions import PermissionDenied
from django.http import Http404, HttpResponse
from django.utils.datastructures import SortedDict
from django.views.decorators.csrf import csrf_exempt
from django.utils.translation import ugettext as _
from rest_framework import status, exceptions
from rest_framework.compat import smart_text, HttpResponseBase, View
@ -93,10 +94,10 @@ def exception_handler(exc):
headers=headers)
elif isinstance(exc, Http404):
return NotFound({'detail': 'Not found'})
return NotFound({'detail': _('Not found')})
elif isinstance(exc, PermissionDenied):
return Forbidden({'detail': 'Permission denied'})
return Forbidden({'detail': _('Permission denied')})
# Note: Unhandled exceptions will raise a 500 error.
return None
@ -345,11 +346,9 @@ class APIView(View):
Returns the final response object.
"""
# Make the error obvious if a proper response is not returned
assert isinstance(response, HttpResponseBase), (
'Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` '
'to be returned from the view, but received a `%s`'
% type(response)
)
assert isinstance(response, HttpResponseBase), _('Expected a `Response`, `HttpResponse` or '
'`HttpStreamingResponse` to be returned from the view, '
'but received a `%s`' % type(response))
if isinstance(response, Response):
if not getattr(request, 'accepted_renderer', None):
@ -446,6 +445,6 @@ class APIView(View):
def api_server_error(request, *args, **kwargs):
if settings.DEBUG is False and request.META['CONTENT_TYPE'] == "application/json":
return HttpResponse(json.dumps({"error": "Server application error"}),
return HttpResponse(json.dumps({"error": _("Server application error")}),
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return server_error(request, *args, **kwargs)

View File

@ -19,6 +19,7 @@
from functools import update_wrapper
from django.utils.decorators import classonlymethod
from django.utils.translation import ugettext as _
from . import views
from . import mixins
@ -53,12 +54,12 @@ class ViewSetMixin(object):
# sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
raise TypeError(_("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
% (key, cls.__name__)))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r" % (
cls.__name__, key))
raise TypeError(_("%s() received an invalid keyword %r"
% (cls.__name__, key)))
def view(request, *args, **kwargs):
self = cls(**initkwargs)

View File

@ -19,7 +19,7 @@ import logging
from django.apps import apps
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import filters
@ -60,7 +60,7 @@ class QueryParamsFilterMixin(filters.BaseFilterBackend):
try:
queryset = queryset.filter(**query_params)
except ValueError:
raise exc.BadRequest("Error in filter params types.")
raise exc.BadRequest(_("Error in filter params types."))
return queryset
@ -104,10 +104,10 @@ class PermissionBasedFilterBackend(FilterBackend):
try:
project_id = int(request.QUERY_PARAMS["project"])
except:
logger.error("Filtering project diferent value than an integer: {}".format(
logger.error(_("Filtering project diferent value than an integer: {}".format(
request.QUERY_PARAMS["project"]
))
raise exc.BadRequest("'project' must be an integer value.")
)))
raise exc.BadRequest(_("'project' must be an integer value."))
qs = queryset
@ -193,10 +193,10 @@ class CanViewProjectObjFilterBackend(FilterBackend):
try:
project_id = int(request.QUERY_PARAMS["project"])
except:
logger.error("Filtering project diferent value than an integer: {}".format(
logger.error(_("Filtering project diferent value than an integer: {}".format(
request.QUERY_PARAMS["project"]
))
raise exc.BadRequest("'project' must be an integer value.")
)))
raise exc.BadRequest(_("'project' must be an integer value."))
qs = queryset
@ -250,8 +250,9 @@ class MembersFilterBackend(PermissionBasedFilterBackend):
try:
project_id = int(request.QUERY_PARAMS["project"])
except:
logger.error("Filtering project diferent value than an integer: {}".format(request.QUERY_PARAMS["project"]))
raise exc.BadRequest("'project' must be an integer value.")
logger.error(_("Filtering project diferent value than an integer: {}".format(
request.QUERY_PARAMS["project"])))
raise exc.BadRequest(_("'project' must be an integer value."))
if project_id:
Project = apps.get_model('projects', 'Project')

View File

@ -15,6 +15,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext as _
from contextlib import contextmanager
@ -22,7 +24,7 @@ from contextlib import contextmanager
def without_signals(*disablers):
for disabler in disablers:
if not (isinstance(disabler, list) or isinstance(disabler, tuple)) or len(disabler) == 0:
raise ValueError("The parameters must be lists of at least one parameter (the signal)")
raise ValueError(_("The parameters must be lists of at least one parameter (the signal)."))
signal, *ids = disabler
signal.backup_receivers = signal.receivers

View File

@ -19,7 +19,7 @@ import codecs
import uuid
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.db.transaction import atomic
from django.db.models import signals
from django.conf import settings

View File

@ -14,6 +14,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext as _
from taiga.projects.models import Membership
from . import serializers
@ -83,7 +85,7 @@ def dict_to_project(data, owner=None):
project_serialized = service.store_project(data)
if not project_serialized:
raise TaigaImportError('error importing project')
raise TaigaImportError(_('error importing project'))
proj = project_serialized.object
@ -96,12 +98,12 @@ def dict_to_project(data, owner=None):
service.store_choices(proj, data, "severities", serializers.SeverityExportSerializer)
if service.get_errors(clear=False):
raise TaigaImportError('error importing choices')
raise TaigaImportError(_('error importing choices'))
service.store_default_choices(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing default choices')
raise TaigaImportError(_('error importing default choices'))
service.store_custom_attributes(proj, data, "userstorycustomattributes",
serializers.UserStoryCustomAttributeExportSerializer)
@ -111,12 +113,12 @@ def dict_to_project(data, owner=None):
serializers.IssueCustomAttributeExportSerializer)
if service.get_errors(clear=False):
raise TaigaImportError('error importing custom attributes')
raise TaigaImportError(_('error importing custom attributes'))
service.store_roles(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing roles')
raise TaigaImportError(_('error importing roles'))
service.store_memberships(proj, data)
@ -131,37 +133,37 @@ def dict_to_project(data, owner=None):
)
if service.get_errors(clear=False):
raise TaigaImportError('error importing memberships')
raise TaigaImportError(_('error importing memberships'))
store_milestones(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing milestones')
raise TaigaImportError(_('error importing milestones'))
store_wiki_pages(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing wiki pages')
raise TaigaImportError(_('error importing wiki pages'))
store_wiki_links(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing wiki links')
raise TaigaImportError(_('error importing wiki links'))
store_issues(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing issues')
raise TaigaImportError(_('error importing issues'))
store_user_stories(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing user stories')
raise TaigaImportError(_('error importing user stories'))
store_tasks(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing issues')
raise TaigaImportError(_('error importing issues'))
store_tags_colors(proj, data)

View File

@ -18,11 +18,12 @@ import base64
import os
from collections import OrderedDict
from django.contrib.contenttypes.models import ContentType
from django.core.files.base import ContentFile
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext as _
from django.contrib.contenttypes.models import ContentType
from rest_framework import serializers
@ -153,7 +154,7 @@ class ProjectRelatedField(serializers.RelatedField):
kwargs = {self.slug_field: data, "project": self.context['project']}
return self.queryset.get(**kwargs)
except ObjectDoesNotExist:
raise ValidationError("{}=\"{}\" not found in this project".format(self.slug_field, data))
raise ValidationError(_("{}=\"{}\" not found in this project".format(self.slug_field, data)))
class HistoryUserField(JsonField):
@ -458,7 +459,7 @@ class MilestoneExportSerializer(serializers.ModelSerializer):
name = attrs[source]
qs = self.project.milestones.filter(name=name)
if qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs

View File

@ -20,6 +20,7 @@ from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.utils import timezone
from django.conf import settings
from django.utils.translation import ugettext as _
from djmail.template_mail import MagicMailBuilder, InlineCSSTemplateMail
@ -45,8 +46,8 @@ def dump_project(self, user, project):
except Exception:
ctx = {
"user": user,
"error_subject": "Error generating project dump",
"error_message": "Error generating project dump",
"error_subject": _("Error generating project dump"),
"error_message": _("Error generating project dump"),
"project": project
}
email = mbuilder.export_error(user, ctx)
@ -78,8 +79,8 @@ def load_project_dump(user, dump):
except Exception:
ctx = {
"user": user,
"error_subject": "Error loading project dump",
"error_message": "Error loading project dump",
"error_subject": _("Error loading project dump"),
"error_message": _("Error loading project dump"),
}
email = mbuilder.import_error(user, ctx)
email.send()

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base import exceptions as exc
from taiga.base import response

View File

@ -16,7 +16,7 @@
import re
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base import exceptions as exc
from taiga.projects.models import IssueStatus, TaskStatus, UserStoryStatus
@ -27,11 +27,10 @@ from taiga.projects.history.services import take_snapshot
from taiga.projects.notifications.services import send_notifications
from taiga.hooks.event_hooks import BaseEventHook
from taiga.hooks.exceptions import ActionSyntaxException
from taiga.base.utils import json
from .services import get_bitbucket_user
import json
class PushEventHook(BaseEventHook):
def process_event(self):
@ -92,7 +91,7 @@ class PushEventHook(BaseEventHook):
element.save()
snapshot = take_snapshot(element,
comment="Status changed from BitBucket commit",
comment=_("Status changed from BitBucket commit"),
user=get_bitbucket_user(bitbucket_user))
send_notifications(element, history=snapshot)

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.projects.models import IssueStatus, TaskStatus, UserStoryStatus
@ -85,7 +85,7 @@ class PushEventHook(BaseEventHook):
element.save()
snapshot = take_snapshot(element,
comment="Status changed from GitHub commit",
comment=_("Status changed from GitHub commit"),
user=get_github_user(github_user))
send_notifications(element, history=snapshot)
@ -125,7 +125,7 @@ class IssuesEventHook(BaseEventHook):
)
take_snapshot(issue, user=get_github_user(github_user))
snapshot = take_snapshot(issue, comment="Created from GitHub", user=get_github_user(github_user))
snapshot = take_snapshot(issue, comment=_("Created from GitHub"), user=get_github_user(github_user))
send_notifications(issue, history=snapshot)
@ -149,6 +149,6 @@ class IssueCommentEventHook(BaseEventHook):
for item in list(issues) + list(tasks) + list(uss):
snapshot = take_snapshot(item,
comment="From GitHub:\n\n{}".format(comment_message),
comment=_("From GitHub:\n\n{}".format(comment_message)),
user=get_github_user(github_user))
send_notifications(item, history=snapshot)

View File

@ -17,7 +17,7 @@
import re
import os
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.projects.models import IssueStatus, TaskStatus, UserStoryStatus
@ -84,7 +84,7 @@ class PushEventHook(BaseEventHook):
element.save()
snapshot = take_snapshot(element,
comment="Status changed from GitLab commit",
comment=_("Status changed from GitLab commit"),
user=get_gitlab_user(gitlab_user))
send_notifications(element, history=snapshot)
@ -126,5 +126,5 @@ class IssuesEventHook(BaseEventHook):
)
take_snapshot(issue, user=get_gitlab_user(None))
snapshot = take_snapshot(issue, comment="Created from GitLab", user=get_gitlab_user(None))
snapshot = take_snapshot(issue, comment=_("Created from GitLab"), user=get_gitlab_user(None))
send_notifications(issue, history=snapshot)

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: taiga-back\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-25 20:09+0100\n"
"POT-Creation-Date: 2015-04-06 17:04+0200\n"
"PO-Revision-Date: 2015-03-25 20:09+0100\n"
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
"Language-Team: Taiga Dev Team <support@taiga.io>\n"
@ -28,6 +28,15 @@ msgstr ""
msgid "invalid login type"
msgstr ""
#: taiga/auth/serializers.py:33 taiga/users/serializers.py:52
msgid "invalid username"
msgstr ""
#: taiga/auth/serializers.py:38 taiga/users/serializers.py:58
msgid ""
"Required. 255 characters or fewer. Letters, numbers and /./-/_ characters'"
msgstr ""
#: taiga/auth/services.py:75
msgid "Username is already in use."
msgstr ""
@ -36,19 +45,129 @@ msgstr ""
msgid "Email is already in use."
msgstr ""
#: taiga/auth/services.py:94
msgid "Token not matches any valid invitation."
msgstr ""
#: taiga/auth/services.py:122
msgid "User is already register."
msgstr ""
#: taiga/auth/services.py:146
msgid "Membership with user is already exists."
msgstr ""
#: taiga/auth/services.py:172
msgid "Error on creating new user."
msgstr ""
#: taiga/base/api/generics.py:162
#: taiga/auth/tokens.py:47 taiga/auth/tokens.py:54
msgid "Invalid token"
msgstr ""
#: taiga/base/api/generics.py:129
msgid ""
"The `page_size` parameter to `paginate_queryset()` is due to be deprecated. "
"Note that the return style of this method is also changed, and will simply "
"return a page object when called without a `page_size` argument."
msgstr ""
#: taiga/base/api/generics.py:144 taiga/base/api/mixins.py:98
msgid ""
"The `allow_empty` parameter is due to be deprecated. To use "
"`allow_empty=False` style behavior, You should override `get_queryset()` and "
"explicitly raise a 404 on empty querysets."
msgstr ""
#: taiga/base/api/generics.py:160
msgid "Page is not 'last', nor can it be converted to an int."
msgstr ""
#: taiga/base/api/generics.py:166
#: taiga/base/api/generics.py:164
#, python-format
msgid "Invalid page (%(page_number)s): %(message)s"
msgstr ""
#: taiga/base/api/generics.py:192
msgid ""
"The `filter_backend` attribute and `FILTER_BACKEND` setting are due to be "
"deprecated in favor of a `filter_backends` attribute and "
"`DEFAULT_FILTER_BACKENDS` setting, that take a *list* of filter backend "
"classes."
msgstr ""
#: taiga/base/api/generics.py:213
msgid ""
"The `queryset` parameter to `get_paginate_by()` is due to be deprecated."
msgstr ""
#: taiga/base/api/generics.py:234
#, python-format
msgid ""
"'%s' should either include a 'serializer_class' attribute, or use the "
"'model' attribute as a shortcut for automatically generating a serializer "
"class."
msgstr ""
#: taiga/base/api/generics.py:260
#, python-format
msgid "'%s' must define 'queryset' or 'model'"
msgstr ""
#: taiga/base/api/generics.py:288
msgid ""
"The `pk_url_kwarg` attribute is due to be deprecated. Use the `lookup_field` "
"attribute instead"
msgstr ""
#: taiga/base/api/generics.py:291
msgid ""
"The `slug_url_kwarg` attribute is due to be deprecated. Use the "
"`lookup_field` attribute instead"
msgstr ""
#: taiga/base/api/generics.py:294
#, python-format
msgid ""
"Expected view %s to be called with a URL keyword argument named \"%s\". Fix "
"your URL conf, or set the `.lookup_field` attribute on the view correctly."
msgstr ""
#: taiga/base/api/permissions.py:61
msgid "Invalid permission definition."
msgstr ""
#: taiga/base/api/views.py:97
msgid "Not found"
msgstr ""
#: taiga/base/api/views.py:100
msgid "Permission denied"
msgstr ""
#: taiga/base/api/views.py:349
#, python-format
msgid ""
"Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be "
"returned from the view, but received a `%s`"
msgstr ""
#: taiga/base/api/views.py:448
msgid "Server application error"
msgstr ""
#: taiga/base/api/viewsets.py:57
#, python-format
msgid ""
"You tried to pass in the %s method name as a keyword argument to %s(). Don't "
"do that."
msgstr ""
#: taiga/base/api/viewsets.py:61
#, python-format
msgid "%s() received an invalid keyword %r"
msgstr ""
#: taiga/base/connectors/exceptions.py:24
msgid "Connection error."
msgstr ""
@ -81,6 +200,20 @@ msgstr ""
msgid "Precondition error"
msgstr ""
#: taiga/base/filters.py:63
msgid "Error in filter params types."
msgstr ""
#: taiga/base/filters.py:107 taiga/base/filters.py:196
#: taiga/base/filters.py:253
msgid "Filtering project diferent value than an integer: {}"
msgstr ""
#: taiga/base/filters.py:110 taiga/base/filters.py:199
#: taiga/base/filters.py:255
msgid "'project' must be an integer value."
msgstr ""
#: taiga/base/tags.py:25
msgid "tags"
msgstr ""
@ -166,6 +299,10 @@ msgid ""
" "
msgstr ""
#: taiga/base/utils/signals.py:27
msgid "The parameters must be lists of at least one parameter (the signal)."
msgstr ""
#: taiga/export_import/api.py:183
msgid "Needed dump file"
msgstr ""
@ -174,16 +311,80 @@ msgstr ""
msgid "Invalid dump format"
msgstr ""
#: taiga/export_import/serializers.py:377
#: taiga/export_import/dump_service.py:88
msgid "error importing project"
msgstr ""
#: taiga/export_import/dump_service.py:101
msgid "error importing choices"
msgstr ""
#: taiga/export_import/dump_service.py:106
msgid "error importing default choices"
msgstr ""
#: taiga/export_import/dump_service.py:116
msgid "error importing custom attributes"
msgstr ""
#: taiga/export_import/dump_service.py:121
msgid "error importing roles"
msgstr ""
#: taiga/export_import/dump_service.py:136
msgid "error importing memberships"
msgstr ""
#: taiga/export_import/dump_service.py:141
msgid "error importing milestones"
msgstr ""
#: taiga/export_import/dump_service.py:146
msgid "error importing wiki pages"
msgstr ""
#: taiga/export_import/dump_service.py:151
msgid "error importing wiki links"
msgstr ""
#: taiga/export_import/dump_service.py:156
#: taiga/export_import/dump_service.py:166
msgid "error importing issues"
msgstr ""
#: taiga/export_import/dump_service.py:161
msgid "error importing user stories"
msgstr ""
#: taiga/export_import/serializers.py:157
msgid "{}=\"{}\" not found in this project"
msgstr ""
#: taiga/export_import/serializers.py:378
#: taiga/projects/custom_attributes/serializers.py:104
msgid "Invalid content. It must be {\"key\": \"value\",...}"
msgstr ""
#: taiga/export_import/serializers.py:392
#: taiga/export_import/serializers.py:393
#: taiga/projects/custom_attributes/serializers.py:119
msgid "It contain invalid custom fields."
msgstr ""
#: taiga/export_import/serializers.py:462
#: taiga/projects/milestones/serializers.py:63
#: taiga/projects/serializers.py:64 taiga/projects/serializers.py:88
#: taiga/projects/serializers.py:110 taiga/projects/serializers.py:142
msgid "Name duplicated for the project"
msgstr ""
#: taiga/export_import/tasks.py:49 taiga/export_import/tasks.py:50
msgid "Error generating project dump"
msgstr ""
#: taiga/export_import/tasks.py:82 taiga/export_import/tasks.py:83
msgid "Error loading project dump"
msgstr ""
#: taiga/export_import/templates/emails/dump_project-subject.jinja:1
#, python-format
msgid "[%(project)s] Your project dump has been generated"
@ -286,28 +487,55 @@ msgstr ""
msgid "The payload is not a valid application/x-www-form-urlencoded"
msgstr ""
#: taiga/hooks/bitbucket/event_hooks.py:46
#: taiga/hooks/bitbucket/event_hooks.py:45
msgid "The payload is not valid"
msgstr ""
#: taiga/hooks/bitbucket/event_hooks.py:82
#: taiga/hooks/bitbucket/event_hooks.py:81
#: taiga/hooks/github/event_hooks.py:75 taiga/hooks/gitlab/event_hooks.py:74
msgid "The referenced element doesn't exist"
msgstr ""
#: taiga/hooks/bitbucket/event_hooks.py:89
#: taiga/hooks/bitbucket/event_hooks.py:88
#: taiga/hooks/github/event_hooks.py:82 taiga/hooks/gitlab/event_hooks.py:81
msgid "The status doesn't exist"
msgstr ""
#: taiga/hooks/bitbucket/event_hooks.py:94
msgid "Status changed from BitBucket commit"
msgstr ""
#: taiga/hooks/github/event_hooks.py:88
msgid "Status changed from GitHub commit"
msgstr ""
#: taiga/hooks/github/event_hooks.py:113 taiga/hooks/gitlab/event_hooks.py:114
msgid "Invalid issue information"
msgstr ""
#: taiga/hooks/github/event_hooks.py:128
msgid "Created from GitHub"
msgstr ""
#: taiga/hooks/github/event_hooks.py:135 taiga/hooks/github/event_hooks.py:144
msgid "Invalid issue comment information"
msgstr ""
#: taiga/hooks/github/event_hooks.py:152
msgid ""
"From GitHub:\n"
"\n"
"{}"
msgstr ""
#: taiga/hooks/gitlab/event_hooks.py:87
msgid "Status changed from GitLab commit"
msgstr ""
#: taiga/hooks/gitlab/event_hooks.py:129
msgid "Created from GitLab"
msgstr ""
#: taiga/permissions/permissions.py:21 taiga/permissions/permissions.py:31
#: taiga/permissions/permissions.py:52
msgid "View project"
@ -470,6 +698,14 @@ msgstr ""
msgid "Admin roles"
msgstr ""
#: taiga/projects/api.py:189
msgid "Not valid template name"
msgstr ""
#: taiga/projects/api.py:192
msgid "Not valid template description"
msgstr ""
#: taiga/projects/api.py:454 taiga/projects/serializers.py:227
msgid "At least one of the user must be an active admin"
msgstr ""
@ -478,10 +714,19 @@ msgstr ""
msgid "You don't have permisions to see that."
msgstr ""
#: taiga/projects/attachments/api.py:47
msgid "Non partial updates not supported"
msgstr ""
#: taiga/projects/attachments/api.py:62
msgid "Project ID not matches between object and project"
msgstr ""
#: taiga/projects/attachments/models.py:54 taiga/projects/issues/models.py:38
#: taiga/projects/milestones/models.py:39 taiga/projects/models.py:131
#: taiga/projects/tasks/models.py:37 taiga/projects/userstories/models.py:64
#: taiga/projects/wiki/models.py:34 taiga/userstorage/models.py:25
#: taiga/projects/notifications/models.py:57 taiga/projects/tasks/models.py:37
#: taiga/projects/userstories/models.py:64 taiga/projects/wiki/models.py:34
#: taiga/userstorage/models.py:25
msgid "owner"
msgstr ""
@ -492,9 +737,9 @@ msgstr ""
#: taiga/projects/models.py:383 taiga/projects/models.py:412
#: taiga/projects/models.py:445 taiga/projects/models.py:468
#: taiga/projects/models.py:495 taiga/projects/models.py:526
#: taiga/projects/tasks/models.py:41 taiga/projects/userstories/models.py:62
#: taiga/projects/wiki/models.py:28 taiga/projects/wiki/models.py:66
#: taiga/users/models.py:193
#: taiga/projects/notifications/models.py:69 taiga/projects/tasks/models.py:41
#: taiga/projects/userstories/models.py:62 taiga/projects/wiki/models.py:28
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:193
msgid "project"
msgstr ""
@ -542,6 +787,14 @@ msgstr ""
msgid "order"
msgstr ""
#: taiga/projects/choices.py:21
msgid "AppearIn"
msgstr ""
#: taiga/projects/choices.py:22
msgid "Talky"
msgstr ""
#: taiga/projects/custom_attributes/models.py:31
#: taiga/projects/milestones/models.py:34 taiga/projects/models.py:120
#: taiga/projects/models.py:338 taiga/projects/models.py:377
@ -573,6 +826,14 @@ msgstr ""
msgid "Already exists one with the same name."
msgstr ""
#: taiga/projects/history/api.py:70
msgid "Comment already deleted"
msgstr ""
#: taiga/projects/history/api.py:89
msgid "Comment not deleted"
msgstr ""
#: taiga/projects/history/choices.py:27
msgid "Change"
msgstr ""
@ -637,6 +898,7 @@ msgstr ""
#: taiga/projects/history/templates/emails/includes/fields_diff-html.jinja:134
#: taiga/projects/history/templates/emails/includes/fields_diff-html.jinja:145
#: taiga/projects/services/stats.py:124 taiga/projects/services/stats.py:125
msgid "Unassigned"
msgstr ""
@ -783,6 +1045,10 @@ msgstr ""
msgid "disponibility"
msgstr ""
#: taiga/projects/milestones/models.py:75
msgid "The estimated start must be previous to the estimated finish."
msgstr ""
#: taiga/projects/milestones/validators.py:12
msgid "There's no sprint with that id"
msgstr ""
@ -984,14 +1250,27 @@ msgstr ""
msgid "watchers"
msgstr ""
#: taiga/projects/notifications/models.py:57
#: taiga/projects/notifications/models.py:59
msgid "created date time"
msgstr ""
#: taiga/projects/notifications/models.py:59
#: taiga/projects/notifications/models.py:61
msgid "updated date time"
msgstr ""
#: taiga/projects/notifications/models.py:63
msgid "history entries"
msgstr ""
#: taiga/projects/notifications/models.py:66
msgid "notify users"
msgstr ""
#: taiga/projects/notifications/services.py:63
#: taiga/projects/notifications/services.py:77
msgid "Notify exists for specified user and project"
msgstr ""
#: taiga/projects/notifications/templates/emails/wiki/wikipage-change-subject.jinja:1
#, python-format
msgid ""
@ -1013,6 +1292,22 @@ msgid ""
"[%(project)s] Deleted the Wiki Page \"%(page)s\"\n"
msgstr ""
#: taiga/projects/notifications/validators.py:43
msgid "Watchers contains invalid users"
msgstr ""
#: taiga/projects/occ/mixins.py:34
msgid "The version must be an integer"
msgstr ""
#: taiga/projects/occ/mixins.py:55
msgid "The version is not valid"
msgstr ""
#: taiga/projects/occ/mixins.py:71
msgid "The version doesn't match with the current one"
msgstr ""
#: taiga/projects/occ/mixins.py:91
msgid "version"
msgstr ""
@ -1029,6 +1324,10 @@ msgstr ""
msgid "Invalid role for the project"
msgstr ""
#: taiga/projects/serializers.py:313
msgid "Total milestones must be major or equal to zero"
msgstr ""
#: taiga/projects/serializers.py:370
msgid "Default options"
msgstr ""
@ -1065,6 +1364,14 @@ msgstr ""
msgid "Roles"
msgstr ""
#: taiga/projects/services/stats.py:72
msgid "Future sprint"
msgstr ""
#: taiga/projects/services/stats.py:89
msgid "Project End"
msgstr ""
#: taiga/projects/tasks/api.py:57 taiga/projects/tasks/api.py:60
#: taiga/projects/tasks/api.py:63 taiga/projects/tasks/api.py:66
msgid "You don't have permissions for add/modify this task."
@ -1189,15 +1496,15 @@ msgstr ""
msgid "There's no user story with that id"
msgstr ""
#: taiga/projects/validators.py:12
#: taiga/projects/validators.py:28
msgid "There's no project with that id"
msgstr ""
#: taiga/projects/validators.py:21
#: taiga/projects/validators.py:37
msgid "There's no user story status with that id"
msgstr ""
#: taiga/projects/validators.py:30
#: taiga/projects/validators.py:46
msgid "There's no task status with that id"
msgstr ""
@ -1286,12 +1593,12 @@ msgstr ""
msgid "Not valid email"
msgstr ""
#: taiga/users/api.py:246 taiga/users/api.py:252
#: taiga/users/api.py:247 taiga/users/api.py:253
msgid ""
"Invalid, are you sure the token is correct and you didn't use it before?"
msgstr ""
#: taiga/users/api.py:279 taiga/users/api.py:287 taiga/users/api.py:290
#: taiga/users/api.py:280 taiga/users/api.py:288 taiga/users/api.py:291
msgid "Invalid, are you sure the token is correct?"
msgstr ""
@ -1364,23 +1671,18 @@ msgstr ""
msgid "permissions"
msgstr ""
#: taiga/users/serializers.py:52
msgid "invalid username"
msgstr ""
#: taiga/users/serializers.py:53
msgid "invalid"
msgstr ""
#: taiga/users/serializers.py:58
msgid ""
"Required. 255 characters or fewer. Letters, numbers and /./-/_ characters'"
msgstr ""
#: taiga/users/serializers.py:64
msgid "Invalid username. Try with a different one."
msgstr ""
#: taiga/users/services.py:48 taiga/users/services.py:52
msgid "Username or password does not matches user."
msgstr ""
#: taiga/users/templates/emails/change_email-body-html.jinja:4
#, python-format
msgid ""
@ -1507,25 +1809,25 @@ msgid "secret key"
msgstr ""
#: taiga/webhooks/models.py:39
msgid "Status code"
msgid "status code"
msgstr ""
#: taiga/webhooks/models.py:40
msgid "Request data"
msgid "request data"
msgstr ""
#: taiga/webhooks/models.py:41
msgid "Request headers"
msgid "request headers"
msgstr ""
#: taiga/webhooks/models.py:42
msgid "Response data"
msgid "response data"
msgstr ""
#: taiga/webhooks/models.py:43
msgid "Response headers"
msgid "response headers"
msgstr ""
#: taiga/webhooks/models.py:44
msgid "Duration"
msgid "duration"
msgstr ""

View File

@ -18,7 +18,7 @@ import uuid
from django.db.models import signals
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base import filters
from taiga.base import response
@ -186,10 +186,10 @@ class ProjectViewSet(ModelCrudViewSet):
template_description = request.DATA.get('template_description', None)
if not template_name:
raise response.BadRequest("Not valid template name")
raise response.BadRequest(_("Not valid template name"))
if not template_description:
raise response.BadRequest("Not valid template description")
raise response.BadRequest(_("Not valid template description"))
template_slug = slugify_uniquely(template_name, models.ProjectTemplate)

View File

@ -14,24 +14,18 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import os.path as path
import hashlib
import mimetypes
mimetypes.init()
from django.utils.translation import ugettext as _
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
from django import http
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base.api import generics
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.users.models import User
from taiga.projects.notifications.mixins import WatchedResourceMixin
from taiga.projects.history.mixins import HistoryResourceMixin
@ -50,7 +44,7 @@ class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCru
def update(self, *args, **kwargs):
partial = kwargs.get("partial", False)
if not partial:
raise exc.NotSupported("Non partial updates not supported")
raise exc.NotSupported(_("Non partial updates not supported"))
return super().update(*args, **kwargs)
def get_content_type(self):
@ -65,7 +59,7 @@ class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCru
obj.name = path.basename(obj.attached_file.name).lower()
if obj.project_id != obj.content_object.project_id:
raise exc.WrongArguments("Project ID not matches between object and project")
raise exc.WrongArguments(_("Project ID not matches between object and project"))
super().pre_save(obj)

View File

@ -14,7 +14,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
VIDEOCONFERENCES_CHOICES = (
("appear-in", "AppearIn"),
("talky", "Talky"),
("appear-in", _("AppearIn")),
("talky", _("Talky")),
)

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django.utils import timezone
from taiga.base import response
@ -66,7 +67,7 @@ class HistoryViewSet(ReadOnlyListViewSet):
return response.NotFound()
if comment.delete_comment_date or comment.delete_comment_user:
return response.BadRequest({"error": "Comment already deleted"})
return response.BadRequest({"error": _("Comment already deleted")})
comment.delete_comment_date = timezone.now()
comment.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
@ -85,7 +86,7 @@ class HistoryViewSet(ReadOnlyListViewSet):
return response.NotFound()
if not comment.delete_comment_date and not comment.delete_comment_user:
return response.BadRequest({"error": "Comment not deleted"})
return response.BadRequest({"error": _("Comment not deleted")})
comment.delete_comment_date = None
comment.delete_comment_user = None

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.db.models import Q
from django.http import Http404, HttpResponse

View File

@ -72,7 +72,7 @@ class Milestone(WatchedModelMixin, models.Model):
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.estimated_start and self.estimated_finish and self.estimated_start > self.estimated_finish:
raise ValidationError('The estimated start must be previous to the estimated finish.')
raise ValidationError(_('The estimated start must be previous to the estimated finish.'))
def save(self, *args, **kwargs):
if not self._importing or not self.modified_date:

View File

@ -14,15 +14,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
from django.utils.translation import ugettext as _
from rest_framework import serializers
from taiga.base.utils import json
from ..userstories.serializers import UserStorySerializer
from . import models
class MilestoneSerializer(serializers.ModelSerializer):
user_stories = UserStorySerializer(many=True, required=False, read_only=True)
total_points = serializers.SerializerMethodField("get_total_points")
@ -59,6 +60,6 @@ class MilestoneSerializer(serializers.ModelSerializer):
qs = models.Milestone.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs

View File

@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers

View File

@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base import response
from taiga.base import exceptions as exc

View File

@ -18,9 +18,11 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from .choices import NOTIFY_LEVEL_CHOICES
from taiga.projects.history.choices import HISTORY_TYPE_CHOICES
from .choices import NOTIFY_LEVEL_CHOICES
class NotifyPolicy(models.Model):
"""
This class represents a persistence for
@ -52,19 +54,19 @@ class HistoryChangeNotification(models.Model):
"""
key = models.CharField(max_length=255, unique=False, editable=False)
owner = models.ForeignKey("users.User", null=False, blank=False,
verbose_name="owner",related_name="+")
verbose_name=_("owner"), related_name="+")
created_datetime = models.DateTimeField(null=False, blank=False, auto_now_add=True,
verbose_name=_("created date time"))
updated_datetime = models.DateTimeField(null=False, blank=False, auto_now_add=True,
verbose_name=_("updated date time"))
history_entries = models.ManyToManyField("history.HistoryEntry", null=True, blank=True,
verbose_name="history entries",
verbose_name=_("history entries"),
related_name="+")
notify_users = models.ManyToManyField("users.User", null=True, blank=True,
verbose_name="notify users",
verbose_name=_("notify users"),
related_name="+")
project = models.ForeignKey("projects.Project", null=False, blank=False,
verbose_name="project",related_name="+")
verbose_name=_("project"),related_name="+")
history_type = models.SmallIntegerField(choices=HISTORY_TYPE_CHOICES)

View File

@ -22,6 +22,7 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.db import transaction
from django.conf import settings
from django.utils.translation import ugettext as _
from djmail import template_mail
@ -37,6 +38,7 @@ from taiga.users.models import User
from .models import HistoryChangeNotification
def notify_policy_exists(project, user) -> bool:
"""
Check if policy exists for specified project
@ -58,7 +60,7 @@ def create_notify_policy(project, user, level=NotifyLevel.notwatch):
user=user,
notify_level=level)
except IntegrityError as e:
raise exc.IntegrityError("Notify exists for specified user and project") from e
raise exc.IntegrityError(_("Notify exists for specified user and project")) from e
def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.notwatch):
@ -72,7 +74,7 @@ def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.notwatch
defaults={"notify_level": level})
return result[0]
except IntegrityError as e:
raise exc.IntegrityError("Notify exists for specified user and project") from e
raise exc.IntegrityError(_("Notify exists for specified user and project")) from e
def get_notify_policy(project, user):
@ -256,8 +258,7 @@ def send_sync_notifications(notification_id):
obj, _ = get_last_snapshot_for_key(notification.key)
obj_class = get_model_from_key(obj.key)
context = {
"obj_class": obj_class,
context = {"obj_class": obj_class,
"snapshot": obj.snapshot,
"project": notification.project,
"changer": notification.owner,

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers
@ -40,6 +40,6 @@ class WatchersValidator:
# in project members list
result = set(users).difference(set(project.members.all()))
if result:
raise serializers.ValidationError("Watchers contains invalid users")
raise serializers.ValidationError(_("Watchers contains invalid users"))
return attrs

View File

@ -31,7 +31,7 @@ class OCCResourceMixin(object):
try:
param_version = param_version and int(param_version)
except (ValueError, TypeError):
raise exc.WrongArguments({"version": "The version must be an integer"})
raise exc.WrongArguments({"version": _("The version must be an integer")})
return param_version
@ -52,7 +52,7 @@ class OCCResourceMixin(object):
# Extract param version
param_version = self._extract_param_version()
if not self._validate_param_version(param_version, current_version):
raise exc.WrongArguments({"version": "The version is not valid"})
raise exc.WrongArguments({"version": _("The version is not valid")})
if current_version != param_version:
diff_versions = current_version - param_version
@ -68,7 +68,7 @@ class OCCResourceMixin(object):
both_modified = modifying_fields & modified_fields
if both_modified:
raise exc.WrongArguments({"version": "The version doesn't match with the current one"})
raise exc.WrongArguments({"version": _("The version doesn't match with the current one")})
if obj.id:
obj.version = models.F('version') + 1

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base.api.permissions import TaigaResourcePermission
from taiga.base.api.permissions import HasProjectPerm

View File

@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.db.models import Q
from rest_framework import serializers
@ -61,7 +61,7 @@ class PointsSerializer(ModelSerializer):
qs = models.Points.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
@ -85,7 +85,7 @@ class UserStoryStatusSerializer(ModelSerializer):
name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
@ -107,7 +107,7 @@ class TaskStatusSerializer(ModelSerializer):
qs = models.TaskStatus.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
@ -139,7 +139,7 @@ class IssueStatusSerializer(ModelSerializer):
qs = models.IssueStatus.objects.filter(project=attrs["project"], name=attrs[source])
if qs and qs.exists():
raise serializers.ValidationError("Name duplicated for the project")
raise serializers.ValidationError(_("Name duplicated for the project"))
return attrs
@ -310,7 +310,7 @@ class ProjectSerializer(ModelSerializer):
"""
value = attrs[source]
if value is None:
raise serializers.ValidationError("Total milestones must be major or equal to zero")
raise serializers.ValidationError(_("Total milestones must be major or equal to zero"))
return attrs

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext as _
from django.db.models import Q, Count
from django.apps import apps
import datetime
@ -21,6 +22,7 @@ import copy
from taiga.projects.history.models import HistoryEntry
def _get_milestones_stats_for_backlog(project):
"""
Get collection of stats for each millestone of project.
@ -67,7 +69,7 @@ def _get_milestones_stats_for_backlog(project):
current_client_increment += sum(ml.client_increment_points.values())
else:
milestone_name = "Future sprint"
milestone_name = _("Future sprint")
team_increment = current_team_increment + future_team_increment,
client_increment = current_client_increment + future_client_increment,
current_evolution = None
@ -84,7 +86,7 @@ def _get_milestones_stats_for_backlog(project):
evolution = (project.total_story_points - current_evolution
if current_evolution is not None and project.total_story_points else None)
yield {
'name': 'Project End',
'name': _('Project End'),
'optimal': optimal_points,
'evolution': evolution,
'team-increment': team_increment,
@ -119,8 +121,8 @@ def _count_owned_object(user_obj, counting_storage):
else:
counting_storage[0] = {}
counting_storage[0]['count'] = 1
counting_storage[0]['username'] = 'Unassigned'
counting_storage[0]['name'] = 'Unassigned'
counting_storage[0]['username'] = _('Unassigned')
counting_storage[0]['name'] = _('Unassigned')
counting_storage[0]['id'] = 0
counting_storage[0]['color'] = 'black'

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters, response

View File

@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers

View File

@ -14,9 +14,9 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers
from taiga.base.api import serializers
from . import models

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework.permissions import IsAuthenticated

View File

@ -18,7 +18,7 @@ import uuid
from django.apps import apps
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django.conf import settings

View File

@ -21,6 +21,7 @@ This model contains a domain logic for users application.
from django.apps import apps
from django.db.models import Q
from django.conf import settings
from django.utils.translation import ugettext as _
from easy_thumbnails.files import get_thumbnailer
from easy_thumbnails.exceptions import InvalidImageFormatError
@ -44,11 +45,11 @@ def get_and_validate_user(*, username:str, password:str) -> bool:
qs = user_model.objects.filter(Q(username=username) |
Q(email=username))
if len(qs) == 0:
raise exc.WrongArguments("Username or password does not matches user.")
raise exc.WrongArguments(_("Username or password does not matches user."))
user = qs[0]
if not user.check_password(password):
raise exc.WrongArguments("Username or password does not matches user.")
raise exc.WrongArguments(_("Username or password does not matches user."))
return user
@ -80,6 +81,10 @@ def get_big_photo_url(photo):
def get_big_photo_or_gravatar_url(user):
"""Get the user's big photo/gravatar url."""
if user:
return get_big_photo_url(user.photo) if user.photo else get_gravatar_url(user.email, size=settings.DEFAULT_BIG_AVATAR_SIZE)
if not user:
return ""
if user.photo:
return get_big_photo_url(user.photo)
else:
return get_gravatar_url(user.email, size=settings.DEFAULT_BIG_AVATAR_SIZE)

View File

@ -15,7 +15,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from rest_framework import serializers

View File

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext as _
from django.db import IntegrityError
from taiga.base.api import ModelCrudViewSet

View File

@ -36,12 +36,12 @@ class WebhookLog(models.Model):
webhook = models.ForeignKey(Webhook, null=False, blank=False,
related_name="logs")
url = models.URLField(null=False, blank=False, verbose_name=_("URL"))
status = models.IntegerField(null=False, blank=False, verbose_name=_("Status code"))
request_data = JsonField(null=False, blank=False, verbose_name=_("Request data"))
request_headers = JsonField(null=False, blank=False, verbose_name=_("Request headers"), default={})
response_data = models.TextField(null=False, blank=False, verbose_name=_("Response data"))
response_headers = JsonField(null=False, blank=False, verbose_name=_("Response headers"), default={})
duration = models.FloatField(null=False, blank=False, verbose_name=_("Duration"), default=0)
status = models.IntegerField(null=False, blank=False, verbose_name=_("status code"))
request_data = JsonField(null=False, blank=False, verbose_name=_("request data"))
request_headers = JsonField(null=False, blank=False, verbose_name=_("request headers"), default={})
response_data = models.TextField(null=False, blank=False, verbose_name=_("response data"))
response_headers = JsonField(null=False, blank=False, verbose_name=_("response headers"), default={})
duration = models.FloatField(null=False, blank=False, verbose_name=_("duration"), default=0)
created = models.DateTimeField(auto_now_add=True)
class Meta: