User settings by project
parent
8bfdf596dc
commit
9389b65157
|
@ -309,6 +309,7 @@ INSTALLED_APPS = [
|
|||
"taiga.projects.issues",
|
||||
"taiga.projects.wiki",
|
||||
"taiga.projects.contact",
|
||||
"taiga.projects.settings",
|
||||
"taiga.searches",
|
||||
"taiga.timeline",
|
||||
"taiga.mdrender",
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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 taiga.base import response
|
||||
from taiga.base.api import ModelCrudViewSet, ReadOnlyListViewSet
|
||||
|
||||
from taiga.projects.settings.choices import HOMEPAGE_CHOICES
|
||||
from taiga.projects.models import Project
|
||||
|
||||
from . import models
|
||||
from . import permissions
|
||||
from . import serializers
|
||||
from . import services
|
||||
|
||||
|
||||
class UserProjectSettingsViewSet(ModelCrudViewSet):
|
||||
serializer_class = serializers.UserProjectSettingsSerializer
|
||||
permission_classes = (permissions.UserProjectSettingsPermission,)
|
||||
|
||||
def _build_user_project_settings(self):
|
||||
projects = Project.objects.filter(
|
||||
Q(owner=self.request.user) |
|
||||
Q(memberships__user=self.request.user)
|
||||
).distinct()
|
||||
|
||||
for project in projects:
|
||||
services.create_user_project_settings_if_not_exists(
|
||||
project, self.request.user)
|
||||
|
||||
def get_queryset(self):
|
||||
if self.request.user.is_anonymous():
|
||||
return models.UserProjectSettings.objects.none()
|
||||
|
||||
self._build_user_project_settings()
|
||||
|
||||
return models.UserProjectSettings.objects.filter(user=self.request.user)\
|
||||
.filter(
|
||||
Q(project__owner=self.request.user) |
|
||||
Q(project__memberships__user=self.request.user)
|
||||
).distinct()
|
||||
|
||||
|
||||
class SectionsViewSet(ReadOnlyListViewSet):
|
||||
def list(self, request, *args, **kwargs):
|
||||
return response.Response(HOMEPAGE_CHOICES)
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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/>.
|
||||
|
||||
import enum
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class Section(enum.IntEnum):
|
||||
timeline = 1
|
||||
search = 2
|
||||
backlog = 3
|
||||
kanban = 4
|
||||
issues = 5
|
||||
wiki = 6
|
||||
team = 7
|
||||
meetup = 8
|
||||
admin = 9
|
||||
|
||||
|
||||
HOMEPAGE_CHOICES = (
|
||||
(Section.timeline, _("Timeline")),
|
||||
(Section.search, _("Search")),
|
||||
(Section.backlog, _("Backlog")),
|
||||
(Section.kanban, _("Kanban")),
|
||||
(Section.issues, _("Issues")),
|
||||
(Section.wiki, _("TeamWiki")),
|
||||
(Section.team, _("Team")),
|
||||
(Section.meetup, _("Meet Up")),
|
||||
(Section.admin, _("Admin")),
|
||||
)
|
|
@ -0,0 +1,49 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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.conf import settings
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from .choices import HOMEPAGE_CHOICES, Section
|
||||
|
||||
|
||||
class UserProjectSettings(models.Model):
|
||||
"""
|
||||
This class represents a persistence for
|
||||
project user notifications preference.
|
||||
"""
|
||||
project = models.ForeignKey("projects.Project", related_name="user_project_settings")
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="user_project_settings")
|
||||
homepage = models.SmallIntegerField(choices=HOMEPAGE_CHOICES,
|
||||
default=Section.timeline)
|
||||
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
modified_at = models.DateTimeField()
|
||||
_importing = None
|
||||
|
||||
class Meta:
|
||||
unique_together = ("project", "user",)
|
||||
ordering = ["created_at"]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self._importing or not self.modified_date:
|
||||
self.modified_at = timezone.now()
|
||||
|
||||
return super().save(*args, **kwargs)
|
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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 taiga.base.api.permissions import (TaigaResourcePermission, IsAuthenticated)
|
||||
|
||||
|
||||
class UserProjectSettingsPermission(TaigaResourcePermission):
|
||||
retrieve_perms = IsAuthenticated()
|
||||
create_perms = IsAuthenticated()
|
||||
update_perms = IsAuthenticated()
|
||||
partial_update_perms = IsAuthenticated()
|
||||
destroy_perms = IsAuthenticated()
|
||||
list_perms = IsAuthenticated()
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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 taiga.base.api import serializers
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class UserProjectSettingsSerializer(serializers.ModelSerializer):
|
||||
project_name = serializers.SerializerMethodField("get_project_name")
|
||||
|
||||
class Meta:
|
||||
model = models.UserProjectSettings
|
||||
fields = ('id', 'project', 'project_name', 'homepage')
|
||||
|
||||
def get_project_name(self, obj):
|
||||
return obj.project.name
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
||||
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
||||
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
||||
# 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 django.db import IntegrityError
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from taiga.base import exceptions as exc
|
||||
from taiga.projects.settings.choices import Section
|
||||
|
||||
|
||||
def user_project_settings_exists(project, user) -> bool:
|
||||
"""
|
||||
Check if policy exists for specified project
|
||||
and user.
|
||||
"""
|
||||
model_cls = apps.get_model("settings", "UserProjectSettings")
|
||||
qs = model_cls.objects.filter(project=project,
|
||||
user=user)
|
||||
return qs.exists()
|
||||
|
||||
|
||||
def create_user_project_settings(project, user, homepage=Section.timeline):
|
||||
"""
|
||||
Given a project and user, create notification policy for it.
|
||||
"""
|
||||
model_cls = apps.get_model("settings", "UserProjectSettings")
|
||||
try:
|
||||
return model_cls.objects.create(project=project,
|
||||
user=user,
|
||||
homepage=homepage)
|
||||
except IntegrityError as e:
|
||||
raise exc.IntegrityError(
|
||||
_("Notify exists for specified user and project")) from e
|
||||
|
||||
|
||||
def create_user_project_settings_if_not_exists(project, user,
|
||||
homepage=Section.timeline):
|
||||
"""
|
||||
Given a project and user, create notification policy for it.
|
||||
"""
|
||||
model_cls = apps.get_model("settings", "UserProjectSettings")
|
||||
try:
|
||||
result = model_cls.objects.get_or_create(
|
||||
project=project,
|
||||
user=user,
|
||||
defaults={"homepage": homepage}
|
||||
)
|
||||
return result[0]
|
||||
except IntegrityError as e:
|
||||
raise exc.IntegrityError(
|
||||
_("Notify exists for specified user and project")) from e
|
|
@ -49,6 +49,13 @@ from taiga.projects.notifications.api import NotifyPolicyViewSet
|
|||
router.register(r"notify-policies", NotifyPolicyViewSet, base_name="notifications")
|
||||
|
||||
|
||||
# Project settings
|
||||
from taiga.projects.settings.api import UserProjectSettingsViewSet, SectionsViewSet
|
||||
|
||||
router.register(r"user-project-settings", UserProjectSettingsViewSet, base_name="user-project-settings")
|
||||
router.register(r"sections", SectionsViewSet, base_name="sections")
|
||||
|
||||
|
||||
# Projects & Selectors
|
||||
from taiga.projects.api import ProjectViewSet
|
||||
from taiga.projects.api import ProjectFansViewSet
|
||||
|
|
Loading…
Reference in New Issue