commit
e6b25c4e38
|
@ -1,4 +1,5 @@
|
|||
.*.sw*
|
||||
.#*
|
||||
*.log
|
||||
taiga/search
|
||||
settings/local.py
|
||||
|
|
|
@ -17,7 +17,6 @@ notifications:
|
|||
email:
|
||||
recipients:
|
||||
- jespinog@gmail.com
|
||||
- andrei.antoukh@gmail.com
|
||||
- bameda@dbarragan.com
|
||||
on_success: change
|
||||
on_failure: change
|
||||
|
|
|
@ -23,4 +23,5 @@ answer newbie questions, and generally made taiga that much better:
|
|||
- Hector Colina <hcolina@gmail.com>
|
||||
- Julien Palard
|
||||
- Joe Letts
|
||||
- Chris Wilson <chris.wilson@aridhia.com>
|
||||
|
||||
|
|
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,7 +1,22 @@
|
|||
# Changelog #
|
||||
|
||||
|
||||
## 1.7.0 Empetrum Nigrum (unreleased)
|
||||
## 1.8.0 Saracenia Purpurea (2015-06-18)
|
||||
|
||||
### Features
|
||||
- Improve timeline resource.
|
||||
- Add sitemap of taiga-front (the web client).
|
||||
- Search by reference (thanks to [@artlepool](https://github.com/artlepool))
|
||||
- Add call 'by_username' to the API resource User
|
||||
- i18n.
|
||||
- Add deutsch (de) translation.
|
||||
- Add nederlands (nl) translation.
|
||||
|
||||
### Misc
|
||||
- Lots of small and not so small bugfixes.
|
||||
|
||||
|
||||
## 1.7.0 Empetrum Nigrum (2015-05-21)
|
||||
|
||||
### Features
|
||||
- Make Taiga translatable (i18n support).
|
||||
|
|
|
@ -18,3 +18,5 @@ echo "-> Load initial roles"
|
|||
python manage.py loaddata initial_role --traceback
|
||||
echo "-> Generate sample data"
|
||||
python manage.py sample_data --traceback
|
||||
echo "-> Rebuilding timeline"
|
||||
python manage.py rebuild_timeline --purge
|
||||
|
|
|
@ -2,7 +2,7 @@ Django==1.7.8
|
|||
#djangorestframework==2.3.13 # It's not necessary since Taiga 1.7
|
||||
django-picklefield==0.3.1
|
||||
django-sampledatahelper==0.2.2
|
||||
gunicorn==19.1.1
|
||||
gunicorn==19.3.0
|
||||
psycopg2==2.5.4
|
||||
pillow==2.5.3
|
||||
pytz==2014.4
|
||||
|
|
|
@ -78,7 +78,7 @@ LANGUAGES = [
|
|||
#("cs", "Čeština"), # Czech
|
||||
#("cy", "Cymraeg"), # Welsh
|
||||
#("da", "Dansk"), # Danish
|
||||
#("de", "Deutsch"), # German
|
||||
("de", "Deutsch"), # German
|
||||
#("el", "Ελληνικά"), # Greek
|
||||
("en", "English (US)"), # English
|
||||
#("en-au", "English (Australia)"), # Australian English
|
||||
|
@ -122,7 +122,7 @@ LANGUAGES = [
|
|||
#("my", "မြန်မာ"), # Burmese
|
||||
#("nb", "Norsk (bokmål)"), # Norwegian Bokmal
|
||||
#("ne", "नेपाली"), # Nepali
|
||||
#("nl", "Nederlands"), # Dutch
|
||||
("nl", "Nederlands"), # Dutch
|
||||
#("nn", "Norsk (nynorsk)"), # Norwegian Nynorsk
|
||||
#("os", "Ирон æвзаг"), # Ossetic
|
||||
#("pa", "ਪੰਜਾਬੀ"), # Punjabi
|
||||
|
@ -257,6 +257,7 @@ INSTALLED_APPS = [
|
|||
"django.contrib.messages",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.staticfiles",
|
||||
"django.contrib.sitemaps",
|
||||
|
||||
"taiga.base",
|
||||
"taiga.base.api",
|
||||
|
@ -449,9 +450,16 @@ BITBUCKET_VALID_ORIGIN_IPS = ["131.103.20.165", "131.103.20.166"]
|
|||
GITLAB_VALID_ORIGIN_IPS = []
|
||||
|
||||
EXPORTS_TTL = 60 * 60 * 24 # 24 hours
|
||||
|
||||
CELERY_ENABLED = False
|
||||
WEBHOOKS_ENABLED = False
|
||||
|
||||
|
||||
# If is True /front/sitemap.xml show a valid sitemap of taiga-front client
|
||||
FRONT_SITEMAP_ENABLED = False
|
||||
FRONT_SITEMAP_CACHE_TIMEOUT = 24*60*60 # In second
|
||||
|
||||
|
||||
from .sr import *
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ DATABASES = {
|
|||
#REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = {
|
||||
# "anon": "20/min",
|
||||
# "user": "200/min",
|
||||
# "import-mode": "20/sec"
|
||||
# "import-mode": "20/sec",
|
||||
# "import-dump-mode": "1/minute"
|
||||
#}
|
||||
|
||||
# GITHUB SETTINGS
|
||||
|
@ -61,3 +62,8 @@ DATABASES = {
|
|||
#GITHUB_API_URL = "https://api.github.com/"
|
||||
#GITHUB_API_CLIENT_ID = "yourgithubclientid"
|
||||
#GITHUB_API_CLIENT_SECRET = "yourgithubclientsecret"
|
||||
|
||||
# SITEMAP
|
||||
# If is True /front/sitemap.xml show a valid sitemap of taiga-front client
|
||||
#FRONT_SITEMAP_ENABLED = False
|
||||
#FRONT_SITEMAP_CACHE_TIMEOUT = 24*60*60 # In second
|
||||
|
|
|
@ -50,6 +50,6 @@ class PrivateRegisterForNewUserSerializer(BaseRegisterSerializer):
|
|||
|
||||
|
||||
class PrivateRegisterForExistingUserSerializer(serializers.Serializer):
|
||||
username = serializers.CharField(max_length=30)
|
||||
username = serializers.CharField(max_length=255)
|
||||
password = serializers.CharField(min_length=4)
|
||||
token = serializers.CharField(max_length=255, required=True)
|
||||
|
|
|
@ -49,6 +49,9 @@ class I18NJsonField(JsonField):
|
|||
|
||||
def translate_values(self, d):
|
||||
i18n_d = {}
|
||||
if d is None:
|
||||
return d
|
||||
|
||||
for key, value in d.items():
|
||||
if isinstance(value, dict):
|
||||
i18n_d[key] = self.translate_values(value)
|
||||
|
|
|
@ -364,6 +364,26 @@ class TagsFilter(FilterBackend):
|
|||
return super().filter_queryset(request, queryset, view)
|
||||
|
||||
|
||||
class StatusFilter(FilterBackend):
|
||||
def __init__(self, filter_name='status'):
|
||||
self.filter_name = filter_name
|
||||
|
||||
def _get_status_queryparams(self, params):
|
||||
status = params.get(self.filter_name, None)
|
||||
if status is not None:
|
||||
status = set([x.strip() for x in status.split(",")])
|
||||
return list(status)
|
||||
|
||||
return None
|
||||
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
query_status = self._get_status_queryparams(request.QUERY_PARAMS)
|
||||
if query_status:
|
||||
queryset = queryset.filter(status__in=query_status)
|
||||
|
||||
return super().filter_queryset(request, queryset, view)
|
||||
|
||||
|
||||
class QFilter(FilterBackend):
|
||||
def filter_queryset(self, request, queryset, view):
|
||||
q = request.QUERY_PARAMS.get('q', None)
|
||||
|
|
|
@ -25,8 +25,8 @@ COORS_ALLOWED_HEADERS = ["content-type", "x-requested-with",
|
|||
"x-session-id"]
|
||||
COORS_ALLOWED_CREDENTIALS = True
|
||||
COORS_EXPOSE_HEADERS = ["x-pagination-count", "x-paginated", "x-paginated-by",
|
||||
"x-paginated-by", "x-pagination-current", "x-site-host",
|
||||
"x-site-register"]
|
||||
"x-pagination-current", "x-pagination-next", "x-pagination-prev",
|
||||
"x-site-host", "x-site-register"]
|
||||
|
||||
|
||||
class CoorsMiddleware(object):
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
|
||||
.headerContent {
|
||||
text-align: center;
|
||||
color:#b8b8b8 !important;
|
||||
color:#8D8D8D !important;
|
||||
font-family: 'Open Sans', Arial, Helvetica;
|
||||
font-size:14px;
|
||||
margin-bottom:16px;
|
||||
|
@ -379,7 +379,7 @@
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" alink="#699b05" link="#699b05" bgcolor="#FFFFFF" text="#444444">
|
||||
<center>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
||||
<tr>
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
* @style heading 2
|
||||
*/
|
||||
h2{
|
||||
color: #b8b8b8 !important;
|
||||
color: #8D8D8D !important;
|
||||
display:block;
|
||||
font-family: 'Open Sans', Arial;
|
||||
font-size:20px;
|
||||
|
@ -340,7 +340,7 @@
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" alink="#699b05" link="#699b05" bgcolor="#FFFFFF" text="#444444">
|
||||
<center>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
||||
<tr>
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
|
||||
.headerContent {
|
||||
text-align: center;
|
||||
color:#b8b8b8 !important;
|
||||
color:#8D8D8D !important;
|
||||
font-family: 'Open Sans', Arial, Helvetica;
|
||||
font-size:14px;
|
||||
margin-bottom:16px;
|
||||
|
@ -379,7 +379,7 @@
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
|
||||
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" alink="#699b05" link="#699b05" bgcolor="#FFFFFF" text="#444444">
|
||||
<center>
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
||||
<tr>
|
||||
|
|
|
@ -241,7 +241,9 @@ class HistoryExportSerializerMixin(serializers.ModelSerializer):
|
|||
history = serializers.SerializerMethodField("get_history")
|
||||
|
||||
def get_history(self, obj):
|
||||
history_qs = history_service.get_history_queryset_by_model_instance(obj)
|
||||
history_qs = history_service.get_history_queryset_by_model_instance(obj,
|
||||
types=(history_models.HistoryType.change, history_models.HistoryType.create,))
|
||||
|
||||
return HistoryExportSerializer(history_qs, many=True).data
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ from django.template.defaultfilters import slugify
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from taiga.projects.history.services import make_key_from_model_object
|
||||
from taiga.projects.history.services import make_key_from_model_object, take_snapshot
|
||||
from taiga.timeline.service import build_project_namespace
|
||||
from taiga.projects.references import sequences as seq
|
||||
from taiga.projects.references import models as refs
|
||||
|
@ -229,9 +229,13 @@ def store_task(project, data):
|
|||
for task_attachment in data.get("attachments", []):
|
||||
store_attachment(project, serialized.object, task_attachment)
|
||||
|
||||
for history in data.get("history", []):
|
||||
history_entries = data.get("history", [])
|
||||
for history in history_entries:
|
||||
store_history(project, serialized.object, history)
|
||||
|
||||
if not history_entries:
|
||||
take_snapshot(serialized.object, user=serialized.object.owner)
|
||||
|
||||
custom_attributes_values = data.get("custom_attributes_values", None)
|
||||
if custom_attributes_values:
|
||||
custom_attributes = serialized.object.project.taskcustomattributes.all().values('id', 'name')
|
||||
|
@ -319,9 +323,13 @@ def store_wiki_page(project, wiki_page):
|
|||
for attachment in wiki_page.get("attachments", []):
|
||||
store_attachment(project, serialized.object, attachment)
|
||||
|
||||
for history in wiki_page.get("history", []):
|
||||
history_entries = wiki_page.get("history", [])
|
||||
for history in history_entries:
|
||||
store_history(project, serialized.object, history)
|
||||
|
||||
if not history_entries:
|
||||
take_snapshot(serialized.object, user=serialized.object.owner)
|
||||
|
||||
return serialized
|
||||
|
||||
add_errors("wiki_pages", serialized.errors)
|
||||
|
@ -381,9 +389,13 @@ def store_user_story(project, data):
|
|||
for role_point in data.get("role_points", []):
|
||||
store_role_point(project, serialized.object, role_point)
|
||||
|
||||
for history in data.get("history", []):
|
||||
history_entries = data.get("history", [])
|
||||
for history in history_entries:
|
||||
store_history(project, serialized.object, history)
|
||||
|
||||
if not history_entries:
|
||||
take_snapshot(serialized.object, user=serialized.object.owner)
|
||||
|
||||
custom_attributes_values = data.get("custom_attributes_values", None)
|
||||
if custom_attributes_values:
|
||||
custom_attributes = serialized.object.project.userstorycustomattributes.all().values('id', 'name')
|
||||
|
@ -434,9 +446,13 @@ def store_issue(project, data):
|
|||
for attachment in data.get("attachments", []):
|
||||
store_attachment(project, serialized.object, attachment)
|
||||
|
||||
for history in data.get("history", []):
|
||||
history_entries = data.get("history", [])
|
||||
for history in history_entries:
|
||||
store_history(project, serialized.object, history)
|
||||
|
||||
if not history_entries:
|
||||
take_snapshot(serialized.object, user=serialized.object.owner)
|
||||
|
||||
custom_attributes_values = data.get("custom_attributes_values", None)
|
||||
if custom_attributes_values:
|
||||
custom_attributes = serialized.object.project.issuecustomattributes.all().values('id', 'name')
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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_jinja import library
|
||||
from django_sites import get_by_id as get_site_by_id
|
||||
|
||||
|
||||
urls = {
|
||||
"home": "/",
|
||||
|
||||
"login": "/login",
|
||||
"change-password": "/change-password/{0}",
|
||||
"change-email": "/change-email/{0}",
|
||||
"cancel-account": "/cancel-account/{0}",
|
||||
"invitation": "/invitation/{0}",
|
||||
|
||||
"project": "/project/{0}",
|
||||
|
||||
"backlog": "/project/{0}/backlog/",
|
||||
"taskboard": "/project/{0}/taskboard/{1}",
|
||||
"kanban": "/project/{0}/kanban/",
|
||||
"userstory": "/project/{0}/us/{1}",
|
||||
"task": "/project/{0}/task/{1}",
|
||||
|
||||
"issues": "/project/{0}/issues",
|
||||
"issue": "/project/{0}/issue/{1}",
|
||||
|
||||
"wiki": "/project/{0}/wiki/{1}",
|
||||
|
||||
"project-admin": "/project/{0}/admin/project-profile/details",
|
||||
}
|
||||
|
||||
|
||||
@library.global_function(name="resolve_front_url")
|
||||
def resolve(type, *args):
|
||||
site = get_site_by_id("front")
|
||||
url_tmpl = "{scheme}//{domain}{url}"
|
||||
|
||||
scheme = site.scheme and "{0}:".format(site.scheme) or ""
|
||||
url = urls[type].format(*args)
|
||||
return url_tmpl.format(scheme=scheme, domain=site.domain, url=url)
|
|
@ -0,0 +1,60 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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 collections import OrderedDict
|
||||
|
||||
from .generics import GenericSitemap
|
||||
|
||||
from .projects import ProjectsSitemap
|
||||
from .projects import ProjectBacklogsSitemap
|
||||
from .projects import ProjectKanbansSitemap
|
||||
from .projects import ProjectIssuesSitemap
|
||||
from .projects import ProjectTeamsSitemap
|
||||
|
||||
from .milestones import MilestonesSitemap
|
||||
|
||||
from .userstories import UserStoriesSitemap
|
||||
|
||||
from .tasks import TasksSitemap
|
||||
|
||||
from .issues import IssuesSitemap
|
||||
|
||||
from .wiki import WikiPagesSitemap
|
||||
|
||||
from .users import UsersSitemap
|
||||
|
||||
|
||||
sitemaps = OrderedDict([
|
||||
("generics", GenericSitemap),
|
||||
|
||||
("projects", ProjectsSitemap),
|
||||
("project-backlogs", ProjectBacklogsSitemap),
|
||||
("project-kanbans", ProjectKanbansSitemap),
|
||||
("project-issues-list", ProjectIssuesSitemap),
|
||||
("project-teams", ProjectTeamsSitemap),
|
||||
|
||||
("milestones", MilestonesSitemap),
|
||||
|
||||
("userstories", UserStoriesSitemap),
|
||||
|
||||
("tasks", TasksSitemap),
|
||||
|
||||
("issues", IssuesSitemap),
|
||||
|
||||
("wikipages", WikiPagesSitemap),
|
||||
|
||||
("users", UsersSitemap)
|
||||
])
|
|
@ -0,0 +1,45 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.contrib.sitemaps import Sitemap as DjangoSitemap
|
||||
|
||||
|
||||
class Sitemap(DjangoSitemap):
|
||||
def get_urls(self, page=1, site=None, protocol=None):
|
||||
urls = []
|
||||
latest_lastmod = None
|
||||
all_items_lastmod = True # track if all items have a lastmod
|
||||
for item in self.paginator.page(page).object_list:
|
||||
loc = self.__get('location', item)
|
||||
priority = self.__get('priority', item, None)
|
||||
lastmod = self.__get('lastmod', item, None)
|
||||
if all_items_lastmod:
|
||||
all_items_lastmod = lastmod is not None
|
||||
if (all_items_lastmod and
|
||||
(latest_lastmod is None or lastmod > latest_lastmod)):
|
||||
latest_lastmod = lastmod
|
||||
url_info = {
|
||||
'item': item,
|
||||
'location': loc,
|
||||
'lastmod': lastmod,
|
||||
'changefreq': self.__get('changefreq', item, None),
|
||||
'priority': str(priority if priority is not None else ''),
|
||||
}
|
||||
urls.append(url_info)
|
||||
if all_items_lastmod and latest_lastmod:
|
||||
self.latest_lastmod = latest_lastmod
|
||||
|
||||
return urls
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class GenericSitemap(Sitemap):
|
||||
def items(self):
|
||||
return [
|
||||
{"url_key": "home", "changefreq": "monthly", "priority": 0.6},
|
||||
{"url_key": "login", "changefreq": "monthly", "priority": 0.6},
|
||||
{"url_key": "register", "changefreq": "monthly", "priority": 0.6},
|
||||
{"url_key": "forgot-password", "changefreq": "monthly", "priority": 0.6}
|
||||
]
|
||||
|
||||
def location(self, obj):
|
||||
return resolve(obj["url_key"])
|
||||
|
||||
def changefreq(self, obj):
|
||||
return obj.get("changefreq", None)
|
||||
|
||||
def priority(self, obj):
|
||||
return obj.get("priority", None)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class IssuesSitemap(Sitemap):
|
||||
def items(self):
|
||||
issue_model = apps.get_model("issues", "Issue")
|
||||
|
||||
# Get issues of public projects OR private projects if anon user can view them
|
||||
queryset = issue_model.objects.filter(Q(project__is_private=False) |
|
||||
Q(project__is_private=True,
|
||||
project__anon_permissions__contains=["view_issues"]))
|
||||
|
||||
# Project data is needed
|
||||
queryset = queryset.select_related("project")
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("issue", obj.project.slug, obj.ref)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,51 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class MilestonesSitemap(Sitemap):
|
||||
def items(self):
|
||||
milestone_model = apps.get_model("milestones", "Milestone")
|
||||
|
||||
# Get US of public projects OR private projects if anon user can view them and us and tasks
|
||||
queryset = milestone_model.objects.filter(Q(project__is_private=False) |
|
||||
Q(project__is_private=True,
|
||||
project__anon_permissions__contains=["view_milestones",
|
||||
"view_us",
|
||||
"view_tasks"]))
|
||||
|
||||
# Project data is needed
|
||||
queryset = queryset.select_related("project")
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("taskboard", obj.project.slug, obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,154 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class ProjectsSitemap(Sitemap):
|
||||
def items(self):
|
||||
project_model = apps.get_model("projects", "Project")
|
||||
|
||||
# Get public projects OR private projects if anon user can view them
|
||||
queryset = project_model.objects.filter(Q(is_private=False) |
|
||||
Q(is_private=True,
|
||||
anon_permissions__contains=["view_project"]))
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("project", obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
||||
|
||||
|
||||
class ProjectBacklogsSitemap(Sitemap):
|
||||
def items(self):
|
||||
project_model = apps.get_model("projects", "Project")
|
||||
|
||||
# Get public projects OR private projects if anon user can view them and user stories
|
||||
queryset = project_model.objects.filter(Q(is_private=False) |
|
||||
Q(is_private=True,
|
||||
anon_permissions__contains=["view_project",
|
||||
"view_us"]))
|
||||
|
||||
# Exclude projects without backlog enabled
|
||||
queryset = queryset.exclude(is_backlog_activated=False)
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("backlog", obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
||||
|
||||
|
||||
class ProjectKanbansSitemap(Sitemap):
|
||||
def items(self):
|
||||
project_model = apps.get_model("projects", "Project")
|
||||
|
||||
# Get public projects OR private projects if anon user can view them and user stories
|
||||
queryset = project_model.objects.filter(Q(is_private=False) |
|
||||
Q(is_private=True,
|
||||
anon_permissions__contains=["view_project",
|
||||
"view_us"]))
|
||||
|
||||
# Exclude projects without kanban enabled
|
||||
queryset = queryset.exclude(is_kanban_activated=False)
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("kanban", obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
||||
|
||||
|
||||
class ProjectIssuesSitemap(Sitemap):
|
||||
def items(self):
|
||||
project_model = apps.get_model("projects", "Project")
|
||||
|
||||
# Get public projects OR private projects if anon user can view them and issues
|
||||
queryset = project_model.objects.filter(Q(is_private=False) |
|
||||
Q(is_private=True,
|
||||
anon_permissions__contains=["view_project",
|
||||
"view_issues"]))
|
||||
|
||||
# Exclude projects without issues enabled
|
||||
queryset = queryset.exclude(is_issues_activated=False)
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("issues", obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
||||
|
||||
|
||||
class ProjectTeamsSitemap(Sitemap):
|
||||
def items(self):
|
||||
project_model = apps.get_model("projects", "Project")
|
||||
|
||||
# Get public projects OR private projects if anon user can view them
|
||||
queryset = project_model.objects.filter(Q(is_private=False) |
|
||||
Q(is_private=True,
|
||||
anon_permissions__contains=["view_project"]))
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("team", obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class TasksSitemap(Sitemap):
|
||||
def items(self):
|
||||
task_model = apps.get_model("tasks", "Task")
|
||||
|
||||
# Get tasks of public projects OR private projects if anon user can view them
|
||||
queryset = task_model.objects.filter(Q(project__is_private=False) |
|
||||
Q(project__is_private=True,
|
||||
project__anon_permissions__contains=["view_tasks"]))
|
||||
|
||||
# Project data is needed
|
||||
queryset = queryset.select_related("project")
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("task", obj.project.slug, obj.ref)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.4
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class UsersSitemap(Sitemap):
|
||||
def items(self):
|
||||
user_model = apps.get_model("users", "User")
|
||||
|
||||
# Only active users and not system users
|
||||
queryset = user_model.objects.filter(is_active=True,
|
||||
is_system=False)
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("user", obj.username)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return None
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class UserStoriesSitemap(Sitemap):
|
||||
def items(self):
|
||||
us_model = apps.get_model("userstories", "UserStory")
|
||||
|
||||
# Get US of public projects OR private projects if anon user can view them
|
||||
queryset = us_model.objects.filter(Q(project__is_private=False) |
|
||||
Q(project__is_private=True,
|
||||
project__anon_permissions__contains=["view_us"]))
|
||||
|
||||
# Project data is needed
|
||||
queryset = queryset.select_related("project")
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("userstory", obj.project.slug, obj.ref)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,52 @@
|
|||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2015 Taiga Agile LLC <support@taiga.io>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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.db.models import Q
|
||||
from django.apps import apps
|
||||
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
from .base import Sitemap
|
||||
|
||||
|
||||
class WikiPagesSitemap(Sitemap):
|
||||
def items(self):
|
||||
wiki_page_model = apps.get_model("wiki", "WikiPage")
|
||||
|
||||
# Get wiki pages of public projects OR private projects if anon user can view them
|
||||
queryset = wiki_page_model.objects.filter(Q(project__is_private=False) |
|
||||
Q(project__is_private=True,
|
||||
project__anon_permissions__contains=["view_wiki_pages"]))
|
||||
|
||||
# Exclude wiki pages from projects without wiki section enabled
|
||||
queryset = queryset.exclude(project__is_wiki_activated=False)
|
||||
|
||||
# Project data is needed
|
||||
queryset = queryset.select_related("project")
|
||||
|
||||
return queryset
|
||||
|
||||
def location(self, obj):
|
||||
return resolve("wiki", obj.project.slug, obj.slug)
|
||||
|
||||
def lastmod(self, obj):
|
||||
return obj.modified_date
|
||||
|
||||
def changefreq(self, obj):
|
||||
return "daily"
|
||||
|
||||
def priority(self, obj):
|
||||
return 0.6
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright (C) 2015 Andrey Antukh <niwi@niwi.be>
|
||||
# Copyright (C) 2015 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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_jinja import library
|
||||
from django_sites import get_by_id as get_site_by_id
|
||||
|
||||
from taiga.front.urls import urls
|
||||
|
||||
|
||||
register = library.Library()
|
||||
|
||||
|
||||
@register.global_function(name="resolve_front_url")
|
||||
def resolve(type, *args):
|
||||
site = get_site_by_id("front")
|
||||
url_tmpl = "{scheme}//{domain}{url}"
|
||||
|
||||
scheme = site.scheme and "{0}:".format(site.scheme) or ""
|
||||
url = urls[type].format(*args)
|
||||
return url_tmpl.format(scheme=scheme, domain=site.domain, url=url)
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (C) 2015 Andrey Antukh <niwi@niwi.be>
|
||||
# Copyright (C) 2015 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2015 David Barragán <bameda@dbarragan.com>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
|
||||
urls = {
|
||||
"home": "/",
|
||||
"login": "/login",
|
||||
"register": "/register",
|
||||
"forgot-password": "/forgot-password",
|
||||
|
||||
"change-password": "/change-password/{0}", # user.token
|
||||
"change-email": "/change-email/{0}", # user.email_token
|
||||
"cancel-account": "/cancel-account/{0}", # auth.token.get_token_for_user(user)
|
||||
"invitation": "/invitation/{0}", # membership.token
|
||||
|
||||
"user": "/profile/{0}", # user.username
|
||||
|
||||
"project": "/project/{0}", # project.slug
|
||||
|
||||
"backlog": "/project/{0}/backlog/", # project.slug
|
||||
"taskboard": "/project/{0}/taskboard/{1}", # project.slug, milestone.slug
|
||||
"kanban": "/project/{0}/kanban/", # project.slug
|
||||
|
||||
"userstory": "/project/{0}/us/{1}", # project.slug, us.ref
|
||||
"task": "/project/{0}/task/{1}", # project.slug, task.ref
|
||||
|
||||
"issues": "/project/{0}/issues", # project.slug
|
||||
"issue": "/project/{0}/issue/{1}", # project.slug, issue.ref
|
||||
|
||||
"wiki": "/project/{0}/wiki/{1}", # project.slug, wikipage.slug
|
||||
|
||||
"team": "/project/{0}/team/", # project.slug
|
||||
|
||||
"project-admin": "/project/{0}/admin/project-profile/details", # project.slug
|
||||
}
|
||||
|
|
@ -9,8 +9,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"PO-Revision-Date: 2015-05-25 13:58+0000\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+0200\n"
|
||||
"PO-Revision-Date: 2015-06-09 07:47+0000\n"
|
||||
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
|
||||
"Language-Team: Catalan (http://www.transifex.com/projects/p/taiga-back/"
|
||||
"language/ca/)\n"
|
||||
|
@ -441,10 +441,6 @@ msgid ""
|
|||
"%(comment)s</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<h3>Comentari:</h3>\n"
|
||||
" <p>%(comment)s</p>\n"
|
||||
" "
|
||||
|
||||
#: taiga/base/templates/emails/updates-body-text.jinja:6
|
||||
#, python-format
|
||||
|
@ -1082,7 +1078,7 @@ msgstr "Amo"
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr "Projecte"
|
||||
|
||||
|
@ -1126,7 +1122,7 @@ msgstr "Descripció"
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr "Ordre"
|
||||
|
||||
|
@ -1148,7 +1144,7 @@ msgstr ""
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr "Nom"
|
||||
|
||||
|
@ -1371,7 +1367,7 @@ msgstr "referència externa"
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr "slug"
|
||||
|
||||
|
@ -1421,7 +1417,7 @@ msgstr "email"
|
|||
msgid "create at"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr "token"
|
||||
|
||||
|
@ -2107,15 +2103,15 @@ msgstr ""
|
|||
msgid "The version must be an integer"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr "Versió"
|
||||
|
||||
|
@ -2131,43 +2127,43 @@ msgstr "Aquest e-mail ja està en ús"
|
|||
msgid "Invalid role for the project"
|
||||
msgstr "Rol invàlid per al projecte"
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr "Opcions per defecte"
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr "Estatus d'històries d'usuari"
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr "Punts"
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr "Estatus de tasques"
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr "Estatus d'incidéncies"
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr "Tipus d'incidéncies"
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr "Prioritats"
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr "Severitats"
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr "Rols"
|
||||
|
||||
|
@ -2558,7 +2554,7 @@ msgstr ""
|
|||
msgid "Stakeholder"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -2653,57 +2649,57 @@ msgstr "Permissos"
|
|||
msgid "Important dates"
|
||||
msgstr "Dates importants"
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr "Nom d'usuari o email invàlid"
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr "Correu enviat satisfactòriament"
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr "Token invàlid"
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr "Paràmetre de password actual requerit"
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr "Paràmetre de password requerit"
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr "Password invàlid, al menys 6 caràcters requerits"
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr "Password actual invàlid"
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr "Arguments incomplets."
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr "Format d'image invàlid"
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr "Email duplicat"
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr "Email no vàlid"
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr ""
|
||||
"Invàlid. Estás segur que el token es correcte i que no l'has usat abans?"
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr "Invàlid. Estás segur que el token es correcte?"
|
||||
|
||||
|
@ -2761,22 +2757,26 @@ msgid "default language"
|
|||
msgstr "llenguatge per defecte"
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default theme"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr "zona horaria per defecte"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr "coloritza tags"
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr "token de correu"
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr "nova adreça de correu"
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr "permissos"
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+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"
|
||||
|
@ -1051,7 +1051,7 @@ msgstr ""
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ msgstr ""
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1117,7 +1117,7 @@ msgstr ""
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1340,7 +1340,7 @@ msgstr ""
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1390,7 +1390,7 @@ msgstr ""
|
|||
msgid "create at"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2070,15 +2070,15 @@ msgstr ""
|
|||
msgid "The version must be an integer"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2094,43 +2094,43 @@ msgstr ""
|
|||
msgid "Invalid role for the project"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2503,7 +2503,7 @@ msgstr ""
|
|||
msgid "Stakeholder"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -2596,56 +2596,56 @@ msgstr ""
|
|||
msgid "Important dates"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2699,22 +2699,26 @@ msgid "default language"
|
|||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default timezone"
|
||||
msgid "default theme"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"PO-Revision-Date: 2015-05-25 15:50+0000\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+0200\n"
|
||||
"PO-Revision-Date: 2015-06-17 07:24+0000\n"
|
||||
"Last-Translator: David Barragán <bameda@gmail.com>\n"
|
||||
"Language-Team: Spanish (http://www.transifex.com/projects/p/taiga-back/"
|
||||
"language/es/)\n"
|
||||
|
@ -854,7 +854,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"<h1>Feedback</h1>\n"
|
||||
"<p>Taiga ha recivido feedback de %(full_name)s <%(email)s></p>"
|
||||
"<p>Taiga ha recibido feedback de %(full_name)s <%(email)s></p>"
|
||||
|
||||
#: taiga/feedback/templates/emails/feedback_notification-body-html.jinja:9
|
||||
#, python-format
|
||||
|
@ -1220,7 +1220,7 @@ msgstr "Dueño"
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr "Proyecto"
|
||||
|
||||
|
@ -1264,7 +1264,7 @@ msgstr "descripción"
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr "orden"
|
||||
|
||||
|
@ -1286,7 +1286,7 @@ msgstr "Talky"
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr "nombre"
|
||||
|
||||
|
@ -1509,7 +1509,7 @@ msgstr "referencia externa"
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr "slug"
|
||||
|
||||
|
@ -1561,7 +1561,7 @@ msgstr "email"
|
|||
msgid "create at"
|
||||
msgstr "creado el"
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr "token"
|
||||
|
||||
|
@ -2478,15 +2478,15 @@ msgstr "Los observadores tienen usuarios invalidos"
|
|||
msgid "The version must be an integer"
|
||||
msgstr "La versión debe ser un número entero"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr "La versión no es válida"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr "Las version difiere de la actual"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr "versión"
|
||||
|
||||
|
@ -2503,43 +2503,43 @@ msgstr "La dirección de email ya está en uso."
|
|||
msgid "Invalid role for the project"
|
||||
msgstr "Rol inválido para el proyecto"
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr "El número total de sprints debe ser mayor o igual a cero"
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr "Opciones por defecto"
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr "Estados de historia de usuario"
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr "Puntos"
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr "Estado de tareas"
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr "Estados de peticion"
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr "Tipos de petición"
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr "Prioridades"
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr "Gravedades"
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr "Roles"
|
||||
|
||||
|
@ -2964,7 +2964,7 @@ msgstr "Product Owner"
|
|||
msgid "Stakeholder"
|
||||
msgstr "Stakeholder"
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -3059,57 +3059,57 @@ msgstr "Permisos"
|
|||
msgid "Important dates"
|
||||
msgstr "datos importántes"
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr "Nombre de usuario o email no válidos"
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr "¡Correo enviado con éxito!"
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr "token inválido"
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr "La contraseña actual es obligatoria."
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr "La nueva contraseña es obligatoria"
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr "La longitud de la contraseña debe de ser de al menos 6 caracteres"
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr "Contraseña actual inválida"
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr "Argumentos incompletos"
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr "Formato de imagen no válido"
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr "Email duplicado"
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr "Email no válido"
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr ""
|
||||
"Invalido, ¿estás seguro de que el token es correcto y no se ha usado antes?"
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr "Inválido, ¿estás seguro de que el token es correcto?"
|
||||
|
||||
|
@ -3167,22 +3167,26 @@ msgid "default language"
|
|||
msgstr "idioma por defecto"
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default theme"
|
||||
msgstr "tema por defecto"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr "zona horaria por defecto"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr "añade color a las etiquetas"
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr "token de email"
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr "nueva dirección de email"
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr "permisos"
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"PO-Revision-Date: 2015-05-25 15:44+0000\n"
|
||||
"Last-Translator: David Barragán <bameda@gmail.com>\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+0200\n"
|
||||
"PO-Revision-Date: 2015-06-09 07:47+0000\n"
|
||||
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
|
||||
"Language-Team: Finnish (http://www.transifex.com/projects/p/taiga-back/"
|
||||
"language/fi/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -467,9 +467,6 @@ msgid ""
|
|||
"%(comment)s</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<h3>kommentti:</h3>\n"
|
||||
"<p>%(comment)s</p>"
|
||||
|
||||
#: taiga/base/templates/emails/updates-body-text.jinja:6
|
||||
#, python-format
|
||||
|
@ -1210,7 +1207,7 @@ msgstr "omistaja"
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr "projekti"
|
||||
|
||||
|
@ -1254,7 +1251,7 @@ msgstr "kuvaus"
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr "order"
|
||||
|
||||
|
@ -1276,7 +1273,7 @@ msgstr "Talky"
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr "nimi"
|
||||
|
||||
|
@ -1499,7 +1496,7 @@ msgstr "ulkoinen viittaus"
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr "hukka-aika"
|
||||
|
||||
|
@ -1549,7 +1546,7 @@ msgstr "sähköposti"
|
|||
msgid "create at"
|
||||
msgstr "luo täällä"
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr "tunniste"
|
||||
|
||||
|
@ -2475,15 +2472,15 @@ msgstr "Vahdit sisältävät virheellisiä käyttäjiä"
|
|||
msgid "The version must be an integer"
|
||||
msgstr "Versio pitää olla kokonaisluku"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
msgstr "Versio on virheellinen"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr "Versio ei ole sama kuin nykyinen"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr "versio"
|
||||
|
||||
|
@ -2499,43 +2496,43 @@ msgstr "Sähköpostiosoite on jo käytössä"
|
|||
msgid "Invalid role for the project"
|
||||
msgstr "Virheellinen rooli projektille"
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr "Virstapylväitä yhteensä pitää olla vähintään 0."
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr "Oletusoptiot"
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr "Käyttäjätarinatilat"
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr "Pisteet"
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr "Tehtävien tilat"
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr "Pyyntöjen tilat"
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr "pyyntötyypit"
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr "Kiireellisyydet"
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr "Vakavuudet"
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr "Roolit"
|
||||
|
||||
|
@ -2957,7 +2954,7 @@ msgstr "Tuoteomistaja"
|
|||
msgid "Stakeholder"
|
||||
msgstr "Sidosryhmä"
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -3052,58 +3049,58 @@ msgstr "Oikeudet"
|
|||
msgid "Important dates"
|
||||
msgstr "Tärkeät päivämäärät"
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr "Tuntematon käyttäjänimi tai sähköposti"
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr "Sähköposti lähetetty."
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr "Tunniste on virheellinen"
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr "Nykyinen salasanaparametri tarvitaan"
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr "Uusi salasanaparametri tarvitaan"
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr "Salasanan pitää olla vähintään 6 merkkiä pitkä"
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr "Virheellinen nykyinen salasana"
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr "Puutteelliset argumentit"
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr "Väärä kuvaformaatti"
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr "Sähköposti on jo olemassa"
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr "Virheellinen sähköposti"
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr ""
|
||||
"Virheellinen. Oletko varma, että tunniste on oikea ja et ole jo käyttänyt "
|
||||
"sitä?"
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr "Virheellinen, oletko varma että tunniste on oikea?"
|
||||
|
||||
|
@ -3161,22 +3158,26 @@ msgid "default language"
|
|||
msgstr "oletuskieli"
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default theme"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr "oletus aikavyöhyke"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr "väritä avainsanat"
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr "sähköpostitunniste"
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr "uusi sähköpostiosoite"
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr "oikeudet"
|
||||
|
||||
|
|
|
@ -5,16 +5,19 @@
|
|||
# Translators:
|
||||
# Alain Poirier <alain.poirier@net-ng.com>, 2015
|
||||
# David Barragán <bameda@gmail.com>, 2015
|
||||
# Florent B. <me@kxrz.me>, 2015
|
||||
# Louis-Michel Couture <louim_1@hotmail.com>, 2015
|
||||
# Matthieu Durocher <matthieu@technocyclope.com>, 2015
|
||||
# Nlko <nospam1@thomasson.fr>, 2015
|
||||
# Stéphane Mor <stephanemor@gmail.com>, 2015
|
||||
# William Godin <williamgodin@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"PO-Revision-Date: 2015-05-25 13:58+0000\n"
|
||||
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+0200\n"
|
||||
"PO-Revision-Date: 2015-06-12 21:30+0000\n"
|
||||
"Last-Translator: Nlko <nospam1@thomasson.fr>\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/taiga-back/"
|
||||
"language/fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -142,7 +145,7 @@ msgstr ""
|
|||
#: taiga/base/api/fields.py:860
|
||||
#, python-format
|
||||
msgid "\"%s\" value must be a float."
|
||||
msgstr "La valeur de \"%s\" doit être un nombre flottant."
|
||||
msgstr "La valeur de \"%s\" doit être un nombre en virgule flottante."
|
||||
|
||||
#: taiga/base/api/fields.py:881
|
||||
msgid "Enter a number."
|
||||
|
@ -225,7 +228,7 @@ msgstr "Type incorrect. Valeur pk attendue, %s reçu."
|
|||
#: taiga/base/api/relations.py:310
|
||||
#, python-format
|
||||
msgid "Object with %s=%s does not exist."
|
||||
msgstr "L'object pour lequel %s=%s n'existe pas."
|
||||
msgstr "L'objet pour lequel %s=%s n'existe pas."
|
||||
|
||||
#: taiga/base/api/relations.py:346
|
||||
msgid "Invalid hyperlink - No URL match"
|
||||
|
@ -484,7 +487,7 @@ msgstr ""
|
|||
|
||||
#: taiga/export_import/api.py:103
|
||||
msgid "We needed at least one role"
|
||||
msgstr ""
|
||||
msgstr "Veuillez sélectionner au moins un rôle."
|
||||
|
||||
#: taiga/export_import/api.py:197
|
||||
msgid "Needed dump file"
|
||||
|
@ -496,15 +499,16 @@ msgstr "Format de dump invalide"
|
|||
|
||||
#: taiga/export_import/dump_service.py:96
|
||||
msgid "error importing project data"
|
||||
msgstr ""
|
||||
msgstr "Erreur lors de l'importation de données"
|
||||
|
||||
#: taiga/export_import/dump_service.py:109
|
||||
msgid "error importing lists of project attributes"
|
||||
msgstr ""
|
||||
msgstr "erreur lors de l'importation des listes des attributs de projet"
|
||||
|
||||
#: taiga/export_import/dump_service.py:114
|
||||
msgid "error importing default project attributes values"
|
||||
msgstr ""
|
||||
"erreur lors de l'importation des valeurs par défaut des attributs de projet"
|
||||
|
||||
#: taiga/export_import/dump_service.py:124
|
||||
msgid "error importing custom attributes"
|
||||
|
@ -520,7 +524,7 @@ msgstr "Erreur à l'importation des groupes d'utilisateurs"
|
|||
|
||||
#: taiga/export_import/dump_service.py:149
|
||||
msgid "error importing sprints"
|
||||
msgstr ""
|
||||
msgstr "Erreur lors de l'importation des sprints."
|
||||
|
||||
#: taiga/export_import/dump_service.py:154
|
||||
msgid "error importing wiki pages"
|
||||
|
@ -540,11 +544,11 @@ msgstr "erreur à l'importation des histoires utilisateur"
|
|||
|
||||
#: taiga/export_import/dump_service.py:174
|
||||
msgid "error importing tasks"
|
||||
msgstr ""
|
||||
msgstr "Erreur lors de l'importation des tâches."
|
||||
|
||||
#: taiga/export_import/dump_service.py:179
|
||||
msgid "error importing tags"
|
||||
msgstr ""
|
||||
msgstr "erreur lors de l'importation des mots-clés"
|
||||
|
||||
#: taiga/export_import/dump_service.py:183
|
||||
msgid "error importing timelines"
|
||||
|
@ -870,7 +874,7 @@ msgstr ""
|
|||
|
||||
#: taiga/hooks/github/event_hooks.py:169
|
||||
msgid "Issue created from GitHub."
|
||||
msgstr ""
|
||||
msgstr "Suivi de problème créé à partir de GitHub."
|
||||
|
||||
#: taiga/hooks/github/event_hooks.py:178 taiga/hooks/github/event_hooks.py:193
|
||||
msgid "Invalid issue comment information"
|
||||
|
@ -894,6 +898,9 @@ msgid ""
|
|||
"\n"
|
||||
"{message}"
|
||||
msgstr ""
|
||||
"Commentaire provenant de GitHub:\n"
|
||||
"\n"
|
||||
"{message}"
|
||||
|
||||
#: taiga/hooks/gitlab/event_hooks.py:87
|
||||
msgid "Status changed from GitLab commit"
|
||||
|
@ -1106,7 +1113,7 @@ msgstr "propriétaire"
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr "projet"
|
||||
|
||||
|
@ -1150,7 +1157,7 @@ msgstr "description"
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr "ordre"
|
||||
|
||||
|
@ -1172,7 +1179,7 @@ msgstr "Talky"
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr "nom"
|
||||
|
||||
|
@ -1395,7 +1402,7 @@ msgstr "référence externe"
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr "slug"
|
||||
|
||||
|
@ -1443,9 +1450,9 @@ msgstr "email"
|
|||
|
||||
#: taiga/projects/models.py:61
|
||||
msgid "create at"
|
||||
msgstr ""
|
||||
msgstr "Créé le"
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr "jeton"
|
||||
|
||||
|
@ -1800,6 +1807,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Created the sprint \"%(milestone)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] Sprint \"%(milestone)s\" créé\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/milestones/milestone-delete-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -1831,6 +1840,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Deleted the Sprint \"%(milestone)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] Sprint \"%(milestone)s\" Éffacé\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/tasks/task-change-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -1860,6 +1871,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Updated the task #%(ref)s \"%(subject)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] Tâche #%(ref)s \"%(subject)s\" mise à jour\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/tasks/task-create-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -1893,6 +1906,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Created the task #%(ref)s \"%(subject)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] Tâche #%(ref)s \"%(subject)s\" créée\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/tasks/task-delete-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -1924,6 +1939,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Deleted the task #%(ref)s \"%(subject)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] Tâche #%(ref)s \"%(subject)s\" supprimée\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/userstories/userstory-change-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -1953,6 +1970,8 @@ msgid ""
|
|||
"\n"
|
||||
"[%(project)s] Updated the US #%(ref)s \"%(subject)s\"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"[%(project)s] US #%(ref)s \"%(subject)s\" mise à jour\n"
|
||||
|
||||
#: taiga/projects/notifications/templates/emails/userstories/userstory-create-body-html.jinja:4
|
||||
#, python-format
|
||||
|
@ -2131,15 +2150,15 @@ msgstr "La liste des observateurs contient des utilisateurs invalides"
|
|||
msgid "The version must be an integer"
|
||||
msgstr "La version doit être un nombre entier"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
msgstr "La version n'est pas valide"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr "La version ne correspond pas à la version courante"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr "version"
|
||||
|
||||
|
@ -2156,43 +2175,43 @@ msgstr "Adresse email déjà existante"
|
|||
msgid "Invalid role for the project"
|
||||
msgstr "Rôle non valide pour le projet"
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr "Le nombre de jalons doit être supérieur ou égal à zéro"
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr "Options par défaut"
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr "Etats de la User Story"
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr "Points"
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr "Etats des tâches"
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr "Statuts des problèmes"
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr "Types de problèmes"
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr "Priorités"
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr "Sévérités"
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr "Rôles"
|
||||
|
||||
|
@ -2594,7 +2613,7 @@ msgstr "Product Owner"
|
|||
msgid "Stakeholder"
|
||||
msgstr "Participant"
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -2689,58 +2708,58 @@ msgstr "Permissions"
|
|||
msgid "Important dates"
|
||||
msgstr "Dates importantes"
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr "Nom d'utilisateur ou email non valide"
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr "Mail envoyé avec succès!"
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr "Jeton invalide"
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr "Paramètre 'mot de passe actuel' requis"
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr "Paramètre 'nouveau mot de passe' requis"
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr "Le mot de passe doit être d'au moins 6 caractères"
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr "Mot de passe actuel incorrect"
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr "arguments manquants"
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr "format de l'image non valide"
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr "Email dupliquée"
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr "Email non valide"
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr ""
|
||||
"Invalide, êtes-vous sûre que le jeton est correct et qu'il n'a pas déjà été "
|
||||
"utilisé ?"
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr "Invalide, êtes-vous sûre que le jeton est correct ?"
|
||||
|
||||
|
@ -2799,22 +2818,26 @@ msgid "default language"
|
|||
msgstr "langage par défaut"
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default theme"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr "Fuseau horaire par défaut"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr "changer la couleur des tags"
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr "jeton email"
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr "nouvelle adresse email"
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr "permissions"
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,9 +11,9 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: taiga-back\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-05-25 17:31+0200\n"
|
||||
"PO-Revision-Date: 2015-05-25 15:44+0000\n"
|
||||
"Last-Translator: David Barragán <bameda@gmail.com>\n"
|
||||
"POT-Creation-Date: 2015-06-15 12:34+0200\n"
|
||||
"PO-Revision-Date: 2015-06-09 07:47+0000\n"
|
||||
"Last-Translator: Taiga Dev Team <support@taiga.io>\n"
|
||||
"Language-Team: Chinese Traditional (http://www.transifex.com/projects/p/"
|
||||
"taiga-back/language/zh-Hant/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -469,9 +469,6 @@ msgid ""
|
|||
"%(comment)s</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<h3>評論:</h3>\n"
|
||||
"<p>%(comment)s</p>"
|
||||
|
||||
#: taiga/base/templates/emails/updates-body-text.jinja:6
|
||||
#, python-format
|
||||
|
@ -1205,7 +1202,7 @@ msgstr "所有者"
|
|||
#: taiga/projects/models.py:507 taiga/projects/models.py:538
|
||||
#: 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
|
||||
#: taiga/projects/wiki/models.py:66 taiga/users/models.py:196
|
||||
msgid "project"
|
||||
msgstr "專案"
|
||||
|
||||
|
@ -1249,7 +1246,7 @@ msgstr "描述"
|
|||
#: taiga/projects/models.py:391 taiga/projects/models.py:418
|
||||
#: taiga/projects/models.py:453 taiga/projects/models.py:476
|
||||
#: taiga/projects/models.py:501 taiga/projects/models.py:534
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:188
|
||||
#: taiga/projects/wiki/models.py:71 taiga/users/models.py:191
|
||||
msgid "order"
|
||||
msgstr "次序"
|
||||
|
||||
|
@ -1271,7 +1268,7 @@ msgstr "Talky"
|
|||
#: taiga/projects/models.py:414 taiga/projects/models.py:451
|
||||
#: taiga/projects/models.py:474 taiga/projects/models.py:497
|
||||
#: taiga/projects/models.py:532 taiga/projects/models.py:555
|
||||
#: taiga/users/models.py:180 taiga/webhooks/models.py:27
|
||||
#: taiga/users/models.py:183 taiga/webhooks/models.py:27
|
||||
msgid "name"
|
||||
msgstr "姓名"
|
||||
|
||||
|
@ -1494,7 +1491,7 @@ msgstr "外部參考"
|
|||
#: taiga/projects/milestones/models.py:37 taiga/projects/models.py:125
|
||||
#: taiga/projects/models.py:352 taiga/projects/models.py:416
|
||||
#: taiga/projects/models.py:499 taiga/projects/models.py:557
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:182
|
||||
#: taiga/projects/wiki/models.py:30 taiga/users/models.py:185
|
||||
msgid "slug"
|
||||
msgstr "代稱"
|
||||
|
||||
|
@ -1544,7 +1541,7 @@ msgstr "電子郵件"
|
|||
msgid "create at"
|
||||
msgstr "創建於"
|
||||
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:126
|
||||
#: taiga/projects/models.py:63 taiga/users/models.py:128
|
||||
msgid "token"
|
||||
msgstr "代號"
|
||||
|
||||
|
@ -2474,15 +2471,15 @@ msgstr "監督者包含無效使用者"
|
|||
msgid "The version must be an integer"
|
||||
msgstr "版本須為整數值 "
|
||||
|
||||
#: taiga/projects/occ/mixins.py:56
|
||||
msgid "The version is not valid"
|
||||
msgstr "版本無效"
|
||||
#: taiga/projects/occ/mixins.py:58
|
||||
msgid "The version parameter is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/projects/occ/mixins.py:72
|
||||
#: taiga/projects/occ/mixins.py:74
|
||||
msgid "The version doesn't match with the current one"
|
||||
msgstr "版本與目前使用不相符"
|
||||
|
||||
#: taiga/projects/occ/mixins.py:92
|
||||
#: taiga/projects/occ/mixins.py:93
|
||||
msgid "version"
|
||||
msgstr "版本"
|
||||
|
||||
|
@ -2498,43 +2495,43 @@ msgstr "電子郵件已使用"
|
|||
msgid "Invalid role for the project"
|
||||
msgstr "專案無效的角色"
|
||||
|
||||
#: taiga/projects/serializers.py:343
|
||||
#: taiga/projects/serializers.py:340
|
||||
msgid "Total milestones must be major or equal to zero"
|
||||
msgstr "Kanban"
|
||||
|
||||
#: taiga/projects/serializers.py:400
|
||||
#: taiga/projects/serializers.py:402
|
||||
msgid "Default options"
|
||||
msgstr "預設選項"
|
||||
|
||||
#: taiga/projects/serializers.py:401
|
||||
#: taiga/projects/serializers.py:403
|
||||
msgid "User story's statuses"
|
||||
msgstr "使用者故事狀態"
|
||||
|
||||
#: taiga/projects/serializers.py:402
|
||||
#: taiga/projects/serializers.py:404
|
||||
msgid "Points"
|
||||
msgstr "點數"
|
||||
|
||||
#: taiga/projects/serializers.py:403
|
||||
#: taiga/projects/serializers.py:405
|
||||
msgid "Task's statuses"
|
||||
msgstr "任務狀態"
|
||||
|
||||
#: taiga/projects/serializers.py:404
|
||||
#: taiga/projects/serializers.py:406
|
||||
msgid "Issue's statuses"
|
||||
msgstr "問題狀態"
|
||||
|
||||
#: taiga/projects/serializers.py:405
|
||||
#: taiga/projects/serializers.py:407
|
||||
msgid "Issue's types"
|
||||
msgstr "問題類型"
|
||||
|
||||
#: taiga/projects/serializers.py:406
|
||||
#: taiga/projects/serializers.py:408
|
||||
msgid "Priorities"
|
||||
msgstr "優先性"
|
||||
|
||||
#: taiga/projects/serializers.py:407
|
||||
#: taiga/projects/serializers.py:409
|
||||
msgid "Severities"
|
||||
msgstr "嚴重性"
|
||||
|
||||
#: taiga/projects/serializers.py:408
|
||||
#: taiga/projects/serializers.py:410
|
||||
msgid "Roles"
|
||||
msgstr "角色"
|
||||
|
||||
|
@ -2949,7 +2946,7 @@ msgstr "產品所有人"
|
|||
msgid "Stakeholder"
|
||||
msgstr "利害關係人"
|
||||
|
||||
#: taiga/projects/userstories/api.py:173
|
||||
#: taiga/projects/userstories/api.py:174
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Generating the user story [US #{ref} - {subject}](:us:{ref} \"US #{ref} - "
|
||||
|
@ -3043,56 +3040,56 @@ msgstr "許可"
|
|||
msgid "Important dates"
|
||||
msgstr "重要日期"
|
||||
|
||||
#: taiga/users/api.py:112 taiga/users/api.py:119
|
||||
#: taiga/users/api.py:124 taiga/users/api.py:131
|
||||
msgid "Invalid username or email"
|
||||
msgstr "無效使用者或郵件"
|
||||
|
||||
#: taiga/users/api.py:128
|
||||
#: taiga/users/api.py:140
|
||||
msgid "Mail sended successful!"
|
||||
msgstr "成功送出郵件"
|
||||
|
||||
#: taiga/users/api.py:140 taiga/users/api.py:145
|
||||
#: taiga/users/api.py:152 taiga/users/api.py:157
|
||||
msgid "Token is invalid"
|
||||
msgstr "代號無效"
|
||||
|
||||
#: taiga/users/api.py:166
|
||||
#: taiga/users/api.py:178
|
||||
msgid "Current password parameter needed"
|
||||
msgstr "需要目前密碼之參數"
|
||||
|
||||
#: taiga/users/api.py:169
|
||||
#: taiga/users/api.py:181
|
||||
msgid "New password parameter needed"
|
||||
msgstr "需要新密碼參數"
|
||||
|
||||
#: taiga/users/api.py:172
|
||||
#: taiga/users/api.py:184
|
||||
msgid "Invalid password length at least 6 charaters needed"
|
||||
msgstr "無效密碼長度,至少需6個字元"
|
||||
|
||||
#: taiga/users/api.py:175
|
||||
#: taiga/users/api.py:187
|
||||
msgid "Invalid current password"
|
||||
msgstr "無效密碼"
|
||||
|
||||
#: taiga/users/api.py:191
|
||||
#: taiga/users/api.py:203
|
||||
msgid "Incomplete arguments"
|
||||
msgstr "不完整參數"
|
||||
|
||||
#: taiga/users/api.py:196
|
||||
#: taiga/users/api.py:208
|
||||
msgid "Invalid image format"
|
||||
msgstr "無效的圖片檔案"
|
||||
|
||||
#: taiga/users/api.py:249
|
||||
#: taiga/users/api.py:261
|
||||
msgid "Duplicated email"
|
||||
msgstr "複製電子郵件"
|
||||
|
||||
#: taiga/users/api.py:251
|
||||
#: taiga/users/api.py:263
|
||||
msgid "Not valid email"
|
||||
msgstr "非有效電子郵性"
|
||||
|
||||
#: taiga/users/api.py:271 taiga/users/api.py:277
|
||||
#: taiga/users/api.py:283 taiga/users/api.py:289
|
||||
msgid ""
|
||||
"Invalid, are you sure the token is correct and you didn't use it before?"
|
||||
msgstr "無效,請確認代號正確,之前是否曾使用過?"
|
||||
|
||||
#: taiga/users/api.py:304 taiga/users/api.py:312 taiga/users/api.py:315
|
||||
#: taiga/users/api.py:316 taiga/users/api.py:324 taiga/users/api.py:327
|
||||
msgid "Invalid, are you sure the token is correct?"
|
||||
msgstr "無效,請確認代號是否正確?"
|
||||
|
||||
|
@ -3146,22 +3143,26 @@ msgid "default language"
|
|||
msgstr "預設語言 "
|
||||
|
||||
#: taiga/users/models.py:122
|
||||
msgid "default theme"
|
||||
msgstr ""
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
msgid "default timezone"
|
||||
msgstr "預設時區"
|
||||
|
||||
#: taiga/users/models.py:124
|
||||
#: taiga/users/models.py:126
|
||||
msgid "colorize tags"
|
||||
msgstr "顏色標籤"
|
||||
|
||||
#: taiga/users/models.py:129
|
||||
#: taiga/users/models.py:131
|
||||
msgid "email token"
|
||||
msgstr "電子郵件符號 "
|
||||
|
||||
#: taiga/users/models.py:131
|
||||
#: taiga/users/models.py:133
|
||||
msgid "new email address"
|
||||
msgstr "新電子郵件地址"
|
||||
|
||||
#: taiga/users/models.py:185
|
||||
#: taiga/users/models.py:188
|
||||
msgid "permissions"
|
||||
msgstr "許可"
|
||||
|
||||
|
|
|
@ -25,22 +25,22 @@
|
|||
|
||||
from markdown.extensions import Extension
|
||||
from markdown.inlinepatterns import Pattern
|
||||
from markdown.util import etree
|
||||
from markdown.util import etree, AtomicString
|
||||
|
||||
from taiga.users.models import User
|
||||
|
||||
|
||||
class MentionsExtension(Extension):
|
||||
def extendMarkdown(self, md, md_globals):
|
||||
MENTION_RE = r'(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-]+)'
|
||||
MENTION_RE = r'(@)([a-z0-9.-\.]+)'
|
||||
mentionsPattern = MentionsPattern(MENTION_RE)
|
||||
mentionsPattern.md = md
|
||||
md.inlinePatterns.add('mentions', mentionsPattern, '_begin')
|
||||
md.inlinePatterns.add('mentions', mentionsPattern, '_end')
|
||||
|
||||
|
||||
class MentionsPattern(Pattern):
|
||||
def handleMatch(self, m):
|
||||
username = m.group(2)
|
||||
username = m.group(3)
|
||||
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
|
@ -49,10 +49,11 @@ class MentionsPattern(Pattern):
|
|||
|
||||
url = "/profile/{}".format(username)
|
||||
|
||||
link_text = "@{}".format(username)
|
||||
link_text = "@{}".format(username)
|
||||
|
||||
a = etree.Element('a')
|
||||
a.text = link_text
|
||||
a.text = AtomicString(link_text)
|
||||
|
||||
a.set('href', url)
|
||||
a.set('title', user.get_full_name())
|
||||
a.set('class', "mention")
|
||||
|
|
|
@ -28,7 +28,7 @@ from markdown.inlinepatterns import Pattern
|
|||
from markdown.util import etree
|
||||
|
||||
from taiga.projects.references.services import get_instance_by_ref
|
||||
from taiga.front import resolve
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
|
||||
class TaigaReferencesExtension(Extension):
|
||||
|
|
|
@ -21,7 +21,7 @@ import markdown
|
|||
|
||||
from markdown.treeprocessors import Treeprocessor
|
||||
|
||||
from taiga.front import resolve
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
|
||||
|
||||
class TargetBlankLinkExtension(markdown.Extension):
|
||||
|
|
|
@ -21,7 +21,7 @@ from markdown.treeprocessors import Treeprocessor
|
|||
|
||||
from markdown.util import etree
|
||||
|
||||
from taiga.front import resolve
|
||||
from taiga.front.templatetags.functions import resolve
|
||||
from taiga.base.utils.slug import slugify
|
||||
|
||||
import re
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
{% set values_removed = lists_diff(values_from, values_to) %}
|
||||
|
||||
<tr>
|
||||
<td valign="middle" rowspan="2" class="update-row-name">
|
||||
<td valign="middle" class="update-row-name">
|
||||
<h3>{{ verbose_name(obj_class, field_name) }}</h3>
|
||||
</td>
|
||||
<td valign="top" class="update-row-from">
|
||||
|
|
|
@ -37,7 +37,9 @@ class OCCResourceMixin(object):
|
|||
return param_version
|
||||
|
||||
def _validate_param_version(self, param_version, current_version):
|
||||
if param_version is not None:
|
||||
if param_version is None:
|
||||
return False
|
||||
else:
|
||||
if param_version < 0:
|
||||
return False
|
||||
if current_version is not None and param_version > current_version:
|
||||
|
@ -53,7 +55,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 parameter is not valid")})
|
||||
|
||||
if current_version != param_version:
|
||||
diff_versions = current_version - param_version
|
||||
|
@ -71,7 +73,6 @@ class OCCResourceMixin(object):
|
|||
if both_modified:
|
||||
raise exc.WrongArguments({"version": _("The version doesn't match with the current one")})
|
||||
|
||||
if obj.id:
|
||||
obj.version = models.F('version') + 1
|
||||
|
||||
def pre_save(self, obj):
|
||||
|
|
|
@ -98,6 +98,7 @@ class BasicUserStoryStatusSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = models.UserStoryStatus
|
||||
i18n_fields = ("name",)
|
||||
fields = ("name", "color")
|
||||
|
||||
|
||||
|
@ -128,6 +129,7 @@ class BasicTaskStatusSerializerSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = models.TaskStatus
|
||||
i18n_fields = ("name",)
|
||||
fields = ("name", "color")
|
||||
|
||||
|
||||
|
@ -170,6 +172,7 @@ class BasicIssueStatusSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = models.IssueStatus
|
||||
i18n_fields = ("name",)
|
||||
fields = ("name", "color")
|
||||
|
||||
|
||||
|
@ -273,6 +276,7 @@ class ProjectMembershipSerializer(serializers.ModelSerializer):
|
|||
full_name = serializers.CharField(source='user.get_full_name', required=False)
|
||||
username = serializers.CharField(source='user.username', required=False)
|
||||
color = serializers.CharField(source='user.color', required=False)
|
||||
is_active = serializers.BooleanField(source='user.is_active', required=False)
|
||||
photo = serializers.SerializerMethodField("get_photo")
|
||||
|
||||
class Meta:
|
||||
|
@ -305,12 +309,11 @@ class ProjectSerializer(serializers.ModelSerializer):
|
|||
my_permissions = serializers.SerializerMethodField("get_my_permissions")
|
||||
i_am_owner = serializers.SerializerMethodField("get_i_am_owner")
|
||||
tags_colors = TagsColorsField(required=False)
|
||||
users = serializers.SerializerMethodField("get_users")
|
||||
total_closed_milestones = serializers.SerializerMethodField("get_total_closed_milestones")
|
||||
|
||||
class Meta:
|
||||
model = models.Project
|
||||
read_only_fields = ("created_date", "modified_date", "owner")
|
||||
read_only_fields = ("created_date", "modified_date", "owner", "slug")
|
||||
exclude = ("last_us_ref", "last_task_ref", "last_issue_ref",
|
||||
"issues_csv_uuid", "tasks_csv_uuid", "userstories_csv_uuid")
|
||||
|
||||
|
@ -328,9 +331,6 @@ class ProjectSerializer(serializers.ModelSerializer):
|
|||
return is_project_owner(self.context["request"].user, obj)
|
||||
return False
|
||||
|
||||
def get_users(self, obj):
|
||||
return UserSerializer(obj.members.all(), many=True).data
|
||||
|
||||
def get_total_closed_milestones(self, obj):
|
||||
return obj.milestones.filter(closed=True).count()
|
||||
|
||||
|
@ -355,12 +355,14 @@ class ProjectDetailSerializer(ProjectSerializer):
|
|||
issue_types = IssueTypeSerializer(many=True, required=False)
|
||||
priorities = PrioritySerializer(many=True, required=False) # Issues
|
||||
severities = SeveritySerializer(many=True, required=False)
|
||||
|
||||
userstory_custom_attributes = UserStoryCustomAttributeSerializer(source="userstorycustomattributes",
|
||||
many=True, required=False)
|
||||
task_custom_attributes = TaskCustomAttributeSerializer(source="taskcustomattributes",
|
||||
many=True, required=False)
|
||||
issue_custom_attributes = IssueCustomAttributeSerializer(source="issuecustomattributes",
|
||||
many=True, required=False)
|
||||
users = serializers.SerializerMethodField("get_users")
|
||||
|
||||
def get_memberships(self, obj):
|
||||
qs = obj.memberships.filter(user__isnull=False)
|
||||
|
@ -374,11 +376,14 @@ class ProjectDetailSerializer(ProjectSerializer):
|
|||
serializer = ProjectRoleSerializer(obj.roles.all(), many=True)
|
||||
return serializer.data
|
||||
|
||||
def get_users(self, obj):
|
||||
return UserSerializer(obj.members.all(), many=True).data
|
||||
|
||||
|
||||
class ProjectDetailAdminSerializer(ProjectDetailSerializer):
|
||||
class Meta:
|
||||
model = models.Project
|
||||
read_only_fields = ("created_date", "modified_date", "owner")
|
||||
read_only_fields = ("created_date", "modified_date", "owner", "slug")
|
||||
exclude = ("last_us_ref", "last_task_ref", "last_issue_ref")
|
||||
|
||||
|
||||
|
|
|
@ -50,10 +50,11 @@ class UserStoryViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMi
|
|||
list_serializer_class = serializers.UserStorySerializer
|
||||
permission_classes = (permissions.UserStoryPermission,)
|
||||
|
||||
filter_backends = (filters.CanViewUsFilterBackend, filters.TagsFilter,
|
||||
filter_backends = (filters.StatusFilter, filters.CanViewUsFilterBackend, filters.TagsFilter,
|
||||
filters.QFilter, filters.OrderByFilterMixin)
|
||||
retrieve_exclude_filters = (filters.TagsFilter,)
|
||||
filter_fields = ["project", "milestone", "milestone__isnull", "status",
|
||||
|
||||
retrieve_exclude_filters = (filters.StatusFilter, filters.TagsFilter,)
|
||||
filter_fields = ["project", "milestone", "milestone__isnull",
|
||||
"is_archived", "status__is_archived", "assigned_to",
|
||||
"status__is_closed", "watchers", "is_closed"]
|
||||
order_by_fields = ["backlog_order", "sprint_order", "kanban_order"]
|
||||
|
|
|
@ -26,7 +26,7 @@ from taiga.projects.validators import ProjectExistsValidator
|
|||
from taiga.projects.validators import UserStoryStatusExistsValidator
|
||||
from taiga.projects.userstories.validators import UserStoryExistsValidator
|
||||
from taiga.projects.notifications.validators import WatchersValidator
|
||||
from taiga.projects.serializers import UserStoryStatusSerializer
|
||||
from taiga.projects.serializers import BasicUserStoryStatusSerializer
|
||||
from taiga.users.serializers import BasicInfoSerializer as UserBasicInfoSerializer
|
||||
|
||||
from . import models
|
||||
|
@ -53,7 +53,7 @@ class UserStorySerializer(WatchersValidator, serializers.ModelSerializer):
|
|||
origin_issue = serializers.SerializerMethodField("get_origin_issue")
|
||||
blocked_note_html = serializers.SerializerMethodField("get_blocked_note_html")
|
||||
description_html = serializers.SerializerMethodField("get_description_html")
|
||||
status_extra_info = UserStoryStatusSerializer(source="status", required=False, read_only=True)
|
||||
status_extra_info = BasicUserStoryStatusSerializer(source="status", required=False, read_only=True)
|
||||
assigned_to_extra_info = UserBasicInfoSerializer(source="assigned_to", required=False, read_only=True)
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -24,6 +24,7 @@ MAX_RESULTS = getattr(settings, "SEARCHES_MAX_RESULTS", 150)
|
|||
def search_user_stories(project, text):
|
||||
model_cls = apps.get_model("userstories", "UserStory")
|
||||
where_clause = ("to_tsvector(coalesce(userstories_userstory.subject) || ' ' || "
|
||||
"coalesce(userstories_userstory.ref) || ' ' || "
|
||||
"coalesce(userstories_userstory.description)) @@ plainto_tsquery(%s)")
|
||||
|
||||
if text:
|
||||
|
@ -35,8 +36,9 @@ def search_user_stories(project, text):
|
|||
|
||||
def search_tasks(project, text):
|
||||
model_cls = apps.get_model("tasks", "Task")
|
||||
where_clause = ("to_tsvector(coalesce(tasks_task.subject, '') || ' ' || coalesce(tasks_task.description, '')) "
|
||||
"@@ plainto_tsquery(%s)")
|
||||
where_clause = ("to_tsvector(coalesce(tasks_task.subject, '') || ' ' || "
|
||||
"coalesce(tasks_task.ref) || ' ' || "
|
||||
"coalesce(tasks_task.description, '')) @@ plainto_tsquery(%s)")
|
||||
|
||||
if text:
|
||||
return (model_cls.objects.extra(where=[where_clause], params=[text])
|
||||
|
@ -47,8 +49,9 @@ def search_tasks(project, text):
|
|||
|
||||
def search_issues(project, text):
|
||||
model_cls = apps.get_model("issues", "Issue")
|
||||
where_clause = ("to_tsvector(coalesce(issues_issue.subject) || ' ' || coalesce(issues_issue.description)) "
|
||||
"@@ plainto_tsquery(%s)")
|
||||
where_clause = ("to_tsvector(coalesce(issues_issue.subject) || ' ' || "
|
||||
"coalesce(issues_issue.ref) || ' ' || "
|
||||
"coalesce(issues_issue.description)) @@ plainto_tsquery(%s)")
|
||||
|
||||
if text:
|
||||
return (model_cls.objects.extra(where=[where_clause], params=[text])
|
||||
|
|
|
@ -30,7 +30,7 @@ class Command(BaseCommand):
|
|||
removing_timeline_ids = []
|
||||
for t in Timeline.objects.filter(event_type="projects.membership.create").order_by("created"):
|
||||
print(t.created)
|
||||
if t.project.owner.id == t.data["user"]["id"]:
|
||||
if t.project.owner.id == t.data["user"].get("id", None):
|
||||
removing_timeline_ids.append(t.id)
|
||||
|
||||
Timeline.objects.filter(id__in=removing_timeline_ids).delete()
|
||||
|
|
|
@ -41,14 +41,18 @@ from optparse import make_option
|
|||
|
||||
import gc
|
||||
|
||||
|
||||
class BulkCreator(object):
|
||||
def __init__(self):
|
||||
self.timeline_objects = []
|
||||
self.created = None
|
||||
|
||||
def createElement(self, element):
|
||||
def create_element(self, element):
|
||||
self.timeline_objects.append(element)
|
||||
if len(self.timeline_objects) > 1000:
|
||||
self.flush()
|
||||
|
||||
def flush(self):
|
||||
Timeline.objects.bulk_create(self.timeline_objects, batch_size=1000)
|
||||
del self.timeline_objects
|
||||
self.timeline_objects = []
|
||||
|
@ -63,7 +67,7 @@ def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, n
|
|||
event_type_key = _get_impl_key_from_model(instance.__class__, event_type)
|
||||
impl = _timeline_impl_map.get(event_type_key, None)
|
||||
|
||||
bulk_creator.createElement(Timeline(
|
||||
bulk_creator.create_element(Timeline(
|
||||
content_object=obj,
|
||||
namespace=namespace,
|
||||
event_type=event_type_key,
|
||||
|
@ -74,13 +78,15 @@ def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, n
|
|||
))
|
||||
|
||||
|
||||
def generate_timeline(initial_date, final_date):
|
||||
if initial_date or final_date:
|
||||
def generate_timeline(initial_date, final_date, project_id):
|
||||
if initial_date or final_date or project_id:
|
||||
timelines = Timeline.objects.all()
|
||||
if initial_date:
|
||||
timelines = timelines.filter(created__gte=initial_date)
|
||||
if final_date:
|
||||
timelines = timelines.filter(created__lt=final_date)
|
||||
if project_id:
|
||||
timelines = timelines.filter(project__id=project_id)
|
||||
|
||||
timelines.delete()
|
||||
|
||||
|
@ -97,6 +103,22 @@ def generate_timeline(initial_date, final_date):
|
|||
projects = projects.filter(created_date__lt=final_date)
|
||||
history_entries = history_entries.filter(created_at__lt=final_date)
|
||||
|
||||
if project_id:
|
||||
project = Project.objects.get(id=project_id)
|
||||
us_keys = ['userstories.userstory:%s'%(id) for id in project.user_stories.values_list("id", flat=True)]
|
||||
tasks_keys = ['tasks.task:%s'%(id) for id in project.tasks.values_list("id", flat=True)]
|
||||
issue_keys = ['issues.issue:%s'%(id) for id in project.issues.values_list("id", flat=True)]
|
||||
wiki_keys = ['wiki.wikipage:%s'%(id) for id in project.wiki_pages.values_list("id", flat=True)]
|
||||
keys = us_keys + tasks_keys + issue_keys + wiki_keys
|
||||
|
||||
projects = projects.filter(id=project_id)
|
||||
history_entries = history_entries.filter(key__in=keys)
|
||||
|
||||
#Memberships
|
||||
for membership in project.memberships.exclude(user=None).exclude(user=project.owner):
|
||||
bulk_creator.created = membership.created_at
|
||||
_push_to_timelines(project, membership.user, membership, "create")
|
||||
|
||||
for project in projects.iterator():
|
||||
bulk_creator.created = project.created_date
|
||||
print("Project:", bulk_creator.created)
|
||||
|
@ -115,6 +137,8 @@ def generate_timeline(initial_date, final_date):
|
|||
except ObjectDoesNotExist as e:
|
||||
print("Ignoring")
|
||||
|
||||
bulk_creator.flush()
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Regenerate project timeline'
|
||||
|
@ -136,6 +160,12 @@ class Command(BaseCommand):
|
|||
dest='final_date',
|
||||
default=None,
|
||||
help='Final date for timeline generation'),
|
||||
) + (
|
||||
make_option('--project',
|
||||
action='store',
|
||||
dest='project',
|
||||
default=None,
|
||||
help='Selected project id for timeline generation'),
|
||||
)
|
||||
|
||||
|
||||
|
@ -148,4 +178,4 @@ class Command(BaseCommand):
|
|||
if options["purge"] == True:
|
||||
Timeline.objects.all().delete()
|
||||
|
||||
generate_timeline(options["initial_date"], options["final_date"])
|
||||
generate_timeline(options["initial_date"], options["final_date"], options["project"])
|
||||
|
|
|
@ -99,6 +99,10 @@ def on_new_history_entry(sender, instance, created, **kwargs):
|
|||
"comment_html": instance.comment_html,
|
||||
}
|
||||
|
||||
# Detect deleted comment
|
||||
if instance.delete_comment_date:
|
||||
extra_data["comment_deleted"] = True
|
||||
|
||||
_push_to_timelines(project, user, obj, event_type, extra_data=extra_data)
|
||||
|
||||
|
||||
|
|
|
@ -16,12 +16,16 @@
|
|||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
from django.contrib import admin
|
||||
|
||||
from .routers import router
|
||||
from .contrib_routers import router as contrib_router
|
||||
|
||||
|
||||
##############################################
|
||||
# Default
|
||||
##############################################
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^api/v1/', include(router.urls)),
|
||||
url(r'^api/v1/', include(contrib_router.urls)),
|
||||
|
@ -29,6 +33,39 @@ urlpatterns = [
|
|||
url(r'^admin/', include(admin.site.urls)),
|
||||
]
|
||||
|
||||
handler500 = "taiga.base.api.views.api_server_error"
|
||||
|
||||
|
||||
##############################################
|
||||
# Front sitemap
|
||||
##############################################
|
||||
|
||||
if settings.FRONT_SITEMAP_ENABLED:
|
||||
from django.contrib.sitemaps.views import index
|
||||
from django.contrib.sitemaps.views import sitemap
|
||||
from django.views.decorators.cache import cache_page
|
||||
|
||||
from taiga.front.sitemaps import sitemaps
|
||||
|
||||
urlpatterns += [
|
||||
url(r"^front/sitemap\.xml$",
|
||||
cache_page(settings.FRONT_SITEMAP_CACHE_TIMEOUT)(index),
|
||||
{"sitemaps": sitemaps, 'sitemap_url_name': 'front-sitemap'},
|
||||
name="front-sitemap-index"),
|
||||
url(r"^front/sitemap-(?P<section>.+)\.xml$",
|
||||
cache_page(settings.FRONT_SITEMAP_CACHE_TIMEOUT)(sitemap),
|
||||
{"sitemaps": sitemaps},
|
||||
name="front-sitemap")
|
||||
]
|
||||
|
||||
|
||||
##############################################
|
||||
# Static and media files in debug mode
|
||||
##############################################
|
||||
|
||||
if settings.DEBUG:
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
def mediafiles_urlpatterns(prefix):
|
||||
"""
|
||||
Method for serve media files with runserver.
|
||||
|
@ -41,9 +78,6 @@ def mediafiles_urlpatterns(prefix):
|
|||
{'document_root': settings.MEDIA_ROOT})
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
# Hardcoded only for development server
|
||||
urlpatterns += staticfiles_urlpatterns(prefix="/static/")
|
||||
urlpatterns += mediafiles_urlpatterns(prefix="/media/")
|
||||
|
||||
handler500 = "taiga.base.api.views.api_server_error"
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0010_auto_20150414_0936'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='theme',
|
||||
field=models.CharField(null=True, blank=True, max_length=100, default='', verbose_name='default theme'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -118,6 +118,8 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
|
||||
lang = models.CharField(max_length=20, null=True, blank=True, default="",
|
||||
verbose_name=_("default language"))
|
||||
theme = models.CharField(max_length=100, null=True, blank=True, default="",
|
||||
verbose_name=_("default theme"))
|
||||
timezone = models.CharField(max_length=20, null=True, blank=True, default="",
|
||||
verbose_name=_("default timezone"))
|
||||
colorize_tags = models.BooleanField(null=False, blank=True, default=False,
|
||||
|
@ -167,6 +169,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
self.color = ""
|
||||
self.bio = ""
|
||||
self.lang = ""
|
||||
self.theme = ""
|
||||
self.timezone = ""
|
||||
self.colorize_tags = True
|
||||
self.token = None
|
||||
|
|
|
@ -44,7 +44,7 @@ class UserPermission(TaigaResourcePermission):
|
|||
me_perms = IsAuthenticated()
|
||||
remove_avatar_perms = IsAuthenticated()
|
||||
starred_perms = AllowAny()
|
||||
change_email_perms = IsTheSameUser()
|
||||
change_email_perms = AllowAny()
|
||||
contacts_perms = AllowAny()
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
# IMPORTANT: Maintain the UserAdminSerializer Meta up to date
|
||||
# with this info (including there the email)
|
||||
fields = ("id", "username", "full_name", "full_name_display",
|
||||
"color", "bio", "lang", "timezone", "is_active",
|
||||
"color", "bio", "lang", "theme", "timezone", "is_active",
|
||||
"photo", "big_photo", "roles", "projects_with_me")
|
||||
read_only_fields = ("id",)
|
||||
|
||||
|
@ -103,7 +103,7 @@ class UserAdminSerializer(UserSerializer):
|
|||
# IMPORTANT: Maintain the UserSerializer Meta up to date
|
||||
# with this info (including here the email)
|
||||
fields = ("id", "username", "full_name", "full_name_display", "email",
|
||||
"color", "bio", "lang", "timezone", "is_active", "photo",
|
||||
"color", "bio", "lang", "theme", "timezone", "is_active", "photo",
|
||||
"big_photo")
|
||||
read_only_fields = ("id", "email")
|
||||
|
||||
|
|
|
@ -272,6 +272,7 @@ def test_user_action_password_recovery(client, data):
|
|||
def test_user_action_change_email(client, data):
|
||||
url = reverse('users-change-email')
|
||||
|
||||
def after_each_request():
|
||||
data.registered_user.email_token = "test-token"
|
||||
data.registered_user.new_email = "new@email.com"
|
||||
data.registered_user.save()
|
||||
|
@ -283,5 +284,6 @@ def test_user_action_change_email(client, data):
|
|||
]
|
||||
|
||||
patch_data = json.dumps({"email_token": "test-token"})
|
||||
results = helper_test_http_method(client, 'post', url, patch_data, users)
|
||||
assert results == [401, 204, 400]
|
||||
after_each_request()
|
||||
results = helper_test_http_method(client, 'post', url, patch_data, users, after_each_request=after_each_request)
|
||||
assert results == [204, 204, 204]
|
||||
|
|
|
@ -46,3 +46,8 @@ def test_render_and_extract_mentions():
|
|||
user = factories.UserFactory(username="user1", full_name="test")
|
||||
(_, extracted) = render_and_extract(dummy_project, "**@user1**")
|
||||
assert extracted['mentions'] == [user]
|
||||
|
||||
def test_proccessor_valid_email():
|
||||
result = render(dummy_project, "**beta.tester@taiga.io**")
|
||||
expected_result = "<p><strong><a href=\"mailto:beta.tester@taiga.io\" target=\"_blank\">beta.tester@taiga.io</a></strong></p>"
|
||||
assert result == expected_result
|
||||
|
|
|
@ -333,3 +333,26 @@ def test_valid_concurrent_save_for_task_different_fields(client):
|
|||
data = {"version": 1, "description": "test 2"}
|
||||
response = client.patch(url, json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
|
||||
def test_invalid_save_without_version_parameter(client):
|
||||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory.create(owner=user)
|
||||
f.MembershipFactory.create(project=project, user=user, is_owner=True)
|
||||
client.login(user)
|
||||
|
||||
mock_path = "taiga.projects.tasks.api.TaskViewSet.pre_conditions_on_save"
|
||||
with patch(mock_path):
|
||||
url = reverse("tasks-list")
|
||||
data = {"subject": "test",
|
||||
"project": project.id,
|
||||
"status": f.TaskStatusFactory.create(project=project).id}
|
||||
response = client.json.post(url, json.dumps(data))
|
||||
assert response.status_code == 201
|
||||
|
||||
task_id = json.loads(response.content)["id"]
|
||||
url = reverse("tasks-detail", args=(task_id,))
|
||||
data = {"subject": "test 1"}
|
||||
response = client.patch(url, json.dumps(data), content_type="application/json")
|
||||
assert response.status_code == 400
|
||||
|
|
|
@ -93,6 +93,18 @@ def test_validate_requested_email_change(client):
|
|||
assert user.new_email is None
|
||||
assert user.email == "new@email.com"
|
||||
|
||||
def test_validate_requested_email_change_for_anonymous_user(client):
|
||||
user = f.UserFactory.create(email_token="change_email_token", new_email="new@email.com")
|
||||
url = reverse('users-change-email')
|
||||
data = {"email_token": "change_email_token"}
|
||||
|
||||
response = client.post(url, json.dumps(data), content_type="application/json")
|
||||
|
||||
assert response.status_code == 204
|
||||
user = models.User.objects.get(pk=user.id)
|
||||
assert user.email_token is None
|
||||
assert user.new_email is None
|
||||
assert user.email == "new@email.com"
|
||||
|
||||
def test_validate_requested_email_change_without_token(client):
|
||||
user = f.UserFactory.create(email_token="change_email_token", new_email="new@email.com")
|
||||
|
|
|
@ -214,6 +214,25 @@ def test_archived_filter(client):
|
|||
assert len(json.loads(response.content)) == 1
|
||||
|
||||
|
||||
def test_filter_by_multiple_status(client):
|
||||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory.create(owner=user)
|
||||
f.MembershipFactory.create(project=project, user=user, is_owner=True)
|
||||
f.UserStoryFactory.create(project=project)
|
||||
us1 = f.UserStoryFactory.create(project=project)
|
||||
us2 = f.UserStoryFactory.create(project=project)
|
||||
|
||||
client.login(user)
|
||||
|
||||
url = reverse("userstories-list")
|
||||
url = "{}?status={},{}".format(reverse("userstories-list"), us1.status.id, us2.status.id)
|
||||
|
||||
|
||||
data = {}
|
||||
response = client.get(url, data)
|
||||
assert len(json.loads(response.content)) == 2
|
||||
|
||||
|
||||
def test_get_total_points(client):
|
||||
project = f.ProjectFactory.create()
|
||||
|
||||
|
|
Loading…
Reference in New Issue