Merge pull request #739 from taigaio/Improving-asynch-timeline-generation

Improving asynch timeline generation
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-05-31 13:19:50 +02:00
commit 90cf09e30a
4 changed files with 35 additions and 53 deletions

View File

@ -32,9 +32,9 @@ class TimelineAppConfig(AppConfig):
signals.post_save.connect(handlers.on_new_history_entry,
sender=apps.get_model("history", "HistoryEntry"),
dispatch_uid="timeline")
signals.pre_save.connect(handlers.create_membership_push_to_timeline,
signals.post_save.connect(handlers.create_membership_push_to_timeline,
sender=apps.get_model("projects", "Membership"))
signals.post_delete.connect(handlers.delete_membership_push_to_timeline,
signals.pre_delete.connect(handlers.delete_membership_push_to_timeline,
sender=apps.get_model("projects", "Membership"))
signals.post_save.connect(handlers.create_user_push_to_timeline,
sender=get_user_model())

View File

@ -17,6 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.apps import apps
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.db.models import Model
from django.db.models import Q
@ -89,10 +90,27 @@ def _push_to_timeline(objects, instance:object, event_type:str, created_datetime
@app.task
def push_to_timelines(project, user, obj, event_type, created_datetime, extra_data={}):
if project is not None:
def push_to_timelines(project_id, user_id, obj_app_label, obj_model_name, obj_id, event_type, created_datetime, extra_data={}):
ObjModel = apps.get_model(obj_app_label, obj_model_name)
try:
obj = ObjModel.objects.get(id=obj_id)
except ObjModel.DoesNotExist:
return
try:
user = get_user_model().objects.get(id=user_id)
except get_user_model().DoesNotExist:
return
if project_id is not None:
# Actions related with a project
projectModel = apps.get_model("projects", "Project")
try:
project = projectModel.objects.get(id=project_id)
except projectModel.DoesNotExist:
return
## Project timeline
_push_to_timeline(project, obj, event_type, created_datetime,
namespace=build_project_namespace(project),

View File

@ -18,6 +18,7 @@
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.utils.translation import ugettext as _
@ -29,11 +30,14 @@ from taiga.timeline.service import (push_to_timelines,
extract_user_info)
def _push_to_timelines(*args, **kwargs):
def _push_to_timelines(project, user, obj, event_type, created_datetime, extra_data={}):
project_id = None if project is None else project.id
ct = ContentType.objects.get_for_model(obj)
if settings.CELERY_ENABLED:
push_to_timelines.delay(*args, **kwargs)
push_to_timelines.delay(project_id, user.id, ct.app_label, ct.model, obj.id, event_type, created_datetime, extra_data=extra_data)
else:
push_to_timelines(*args, **kwargs)
push_to_timelines(project_id, user.id, ct.app_label, ct.model, obj.id, event_type, created_datetime, extra_data=extra_data)
def _clean_description_fields(values_diff):
@ -89,7 +93,7 @@ def on_new_history_entry(sender, instance, created, **kwargs):
_push_to_timelines(project, user, obj, event_type, created_datetime, extra_data=extra_data)
def create_membership_push_to_timeline(sender, instance, **kwargs):
def create_membership_push_to_timeline(sender, instance, created, **kwargs):
"""
Creating new membership with associated user. If the user is the project owner we don't
do anything because that info will be shown in created project timeline entry
@ -99,29 +103,10 @@ def create_membership_push_to_timeline(sender, instance, **kwargs):
"""
# We shown in created project timeline entry
if not instance.pk and instance.user and instance.user != instance.project.owner:
if created and instance.user and instance.user != instance.project.owner:
created_datetime = instance.created_at
_push_to_timelines(instance.project, instance.user, instance, "create", created_datetime)
# Updating existing membership
elif instance.pk:
try:
prev_instance = sender.objects.get(pk=instance.pk)
if instance.user != prev_instance.user:
created_datetime = timezone.now()
# The new member
_push_to_timelines(instance.project, instance.user, instance, "create", created_datetime)
# If we are updating the old user is removed from project
if prev_instance.user:
_push_to_timelines(instance.project,
prev_instance.user,
prev_instance,
"delete",
created_datetime)
except sender.DoesNotExist:
# This happens with some tests, when a membership is created with a concrete id
pass
def delete_membership_push_to_timeline(sender, instance, **kwargs):
if instance.user:

View File

@ -351,29 +351,6 @@ def test_update_wiki_page_timeline():
assert user_watcher_timeline[0].data["values_diff"]["slug"][1] == "test wiki page timeline updated"
def test_update_membership_timeline():
user_1 = factories.UserFactory.create()
user_2 = factories.UserFactory.create()
membership = factories.MembershipFactory.create(user=user_1)
membership.user = user_2
membership.save()
project_timeline = service.get_project_timeline(membership.project)
user_1_timeline = service.get_user_timeline(user_1)
user_2_timeline = service.get_user_timeline(user_2)
assert project_timeline[0].event_type == "projects.membership.delete"
assert project_timeline[0].data["project"]["id"] == membership.project.id
assert project_timeline[0].data["user"]["id"] == user_1.id
assert project_timeline[1].event_type == "projects.membership.create"
assert project_timeline[1].data["project"]["id"] == membership.project.id
assert project_timeline[1].data["user"]["id"] == user_2.id
assert user_1_timeline[0].event_type == "projects.membership.delete"
assert user_1_timeline[0].data["project"]["id"] == membership.project.id
assert user_1_timeline[0].data["user"]["id"] == user_1.id
assert user_2_timeline[0].event_type == "projects.membership.create"
assert user_2_timeline[0].data["project"]["id"] == membership.project.id
assert user_2_timeline[0].data["user"]["id"] == user_2.id
def test_delete_project_timeline():
project = factories.ProjectFactory.create(name="test project timeline")
user_watcher= factories.UserFactory()
@ -534,9 +511,11 @@ def test_timeline_error_use_member_ids_instead_of_memberships_ids():
history_services.take_snapshot(user_story, user=member_user)
user_timeline = service.get_profile_timeline(member_user)
assert len(user_timeline) == 2
assert len(user_timeline) == 3
assert user_timeline[0].event_type == "userstories.userstory.create"
assert user_timeline[1].event_type == "users.user.create"
assert user_timeline[1].event_type == "projects.membership.create"
assert user_timeline[2].event_type == "users.user.create"
external_user_timeline = service.get_profile_timeline(external_user)
assert len(external_user_timeline) == 1