From aff9a7d63704c4e45b5f0c1b5136d46894a1a6d9 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 19 Jun 2015 10:42:03 +0200 Subject: [PATCH] Fixing created datetime for timeline entries --- .../management/commands/rebuild_timeline.py | 13 ++++------ .../rebuild_timeline_for_user_creation.py | 7 +++-- taiga/timeline/service.py | 15 ++++++----- taiga/timeline/signals.py | 25 +++++++++++------- tests/integration/test_timeline.py | 26 +++++++++---------- tests/unit/test_timeline.py | 16 ++++++------ 6 files changed, 52 insertions(+), 50 deletions(-) diff --git a/taiga/timeline/management/commands/rebuild_timeline.py b/taiga/timeline/management/commands/rebuild_timeline.py index 0a234d38..2c462ce0 100644 --- a/taiga/timeline/management/commands/rebuild_timeline.py +++ b/taiga/timeline/management/commands/rebuild_timeline.py @@ -61,7 +61,7 @@ class BulkCreator(object): bulk_creator = BulkCreator() -def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, namespace:str="default", extra_data:dict={}): +def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, created_datetime:object, namespace:str="default", extra_data:dict={}): assert isinstance(obj, Model), "obj must be a instance of Model" assert isinstance(instance, Model), "instance must be a instance of Model" event_type_key = _get_impl_key_from_model(instance.__class__, event_type) @@ -73,8 +73,8 @@ def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, n event_type=event_type_key, project=instance.project, data=impl(instance, extra_data=extra_data), - data_content_type = ContentType.objects.get_for_model(instance.__class__), - created = bulk_creator.created, + data_content_type=ContentType.objects.get_for_model(instance.__class__), + created=created_datetime, )) @@ -116,23 +116,20 @@ def generate_timeline(initial_date, final_date, project_id): #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") + _push_to_timelines(project, membership.user, membership, "create", membership.created_at) for project in projects.iterator(): - bulk_creator.created = project.created_date print("Project:", bulk_creator.created) extra_data = { "values_diff": {}, "user": extract_user_info(project.owner), } - _push_to_timelines(project, project.owner, project, "create", extra_data=extra_data) + _push_to_timelines(project, project.owner, project, "create", project.created_date, extra_data=extra_data) del extra_data for historyEntry in history_entries.iterator(): print("History entry:", historyEntry.created_at) try: - bulk_creator.created = historyEntry.created_at on_new_history_entry(None, historyEntry, None) except ObjectDoesNotExist as e: print("Ignoring") diff --git a/taiga/timeline/management/commands/rebuild_timeline_for_user_creation.py b/taiga/timeline/management/commands/rebuild_timeline_for_user_creation.py index d4f99ed5..2982969a 100644 --- a/taiga/timeline/management/commands/rebuild_timeline_for_user_creation.py +++ b/taiga/timeline/management/commands/rebuild_timeline_for_user_creation.py @@ -53,7 +53,7 @@ class BulkCreator(object): bulk_creator = BulkCreator() -def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, namespace:str="default", extra_data:dict={}): +def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, created_datetime:object, namespace:str="default", extra_data:dict={}): assert isinstance(obj, Model), "obj must be a instance of Model" assert isinstance(instance, Model), "instance must be a instance of Model" event_type_key = _get_impl_key_from_model(instance.__class__, event_type) @@ -66,7 +66,7 @@ def custom_add_to_object_timeline(obj:object, instance:object, event_type:str, n project=None, data=impl(instance, extra_data=extra_data), data_content_type = ContentType.objects.get_for_model(instance.__class__), - created = bulk_creator.created, + created=created_datetime, )) @@ -75,13 +75,12 @@ def generate_timeline(): # Users api wasn't a HistoryResourceMixin so we can't interate on the HistoryEntries in this case users = User.objects.order_by("date_joined") for user in users.iterator(): - bulk_creator.created = user.date_joined print("User:", user.date_joined) extra_data = { "values_diff": {}, "user": extract_user_info(user), } - _push_to_timelines(None, user, user, "create", extra_data=extra_data) + _push_to_timelines(None, user, user, "create", user.date_joined, extra_data=extra_data) del extra_data bulk_creator.flush() diff --git a/taiga/timeline/service.py b/taiga/timeline/service.py index 5317942f..6fde769c 100644 --- a/taiga/timeline/service.py +++ b/taiga/timeline/service.py @@ -50,7 +50,7 @@ def build_project_namespace(project:object): return "{0}:{1}".format("project", project.id) -def _add_to_object_timeline(obj:object, instance:object, event_type:str, namespace:str="default", extra_data:dict={}): +def _add_to_object_timeline(obj:object, instance:object, event_type:str, created_datetime:object, namespace:str="default", extra_data:dict={}): assert isinstance(obj, Model), "obj must be a instance of Model" assert isinstance(instance, Model), "instance must be a instance of Model" from .models import Timeline @@ -67,21 +67,22 @@ def _add_to_object_timeline(obj:object, instance:object, event_type:str, namespa event_type=event_type_key, project=project, data=impl(instance, extra_data=extra_data), - data_content_type = ContentType.objects.get_for_model(instance.__class__), + data_content_type=ContentType.objects.get_for_model(instance.__class__), + created=created_datetime, ) -def _add_to_objects_timeline(objects, instance:object, event_type:str, namespace:str="default", extra_data:dict={}): +def _add_to_objects_timeline(objects, instance:object, event_type:str, created_datetime:object, namespace:str="default", extra_data:dict={}): for obj in objects: - _add_to_object_timeline(obj, instance, event_type, namespace, extra_data) + _add_to_object_timeline(obj, instance, event_type, created_datetime, namespace, extra_data) @app.task -def push_to_timeline(objects, instance:object, event_type:str, namespace:str="default", extra_data:dict={}): +def push_to_timeline(objects, instance:object, event_type:str, created_datetime:object, namespace:str="default", extra_data:dict={}): if isinstance(objects, Model): - _add_to_object_timeline(objects, instance, event_type, namespace, extra_data) + _add_to_object_timeline(objects, instance, event_type, created_datetime, namespace, extra_data) elif isinstance(objects, QuerySet) or isinstance(objects, list): - _add_to_objects_timeline(objects, instance, event_type, namespace, extra_data) + _add_to_objects_timeline(objects, instance, event_type, created_datetime, namespace, extra_data) else: raise Exception("Invalid objects parameter") diff --git a/taiga/timeline/signals.py b/taiga/timeline/signals.py index 03d8b9f5..b0787946 100644 --- a/taiga/timeline/signals.py +++ b/taiga/timeline/signals.py @@ -15,6 +15,7 @@ # along with this program. If not, see . from django.conf import settings +from django.utils import timezone from taiga.projects.history import services as history_services from taiga.projects.models import Project @@ -33,15 +34,15 @@ def _push_to_timeline(*args, **kwargs): push_to_timeline(*args, **kwargs) -def _push_to_timelines(project, user, obj, event_type, extra_data={}): +def _push_to_timelines(project, user, obj, event_type, created_datetime, extra_data={}): if project is not None: # Project timeline - _push_to_timeline(project, obj, event_type, + _push_to_timeline(project, obj, event_type, created_datetime, namespace=build_project_namespace(project), extra_data=extra_data) # User timeline - _push_to_timeline(user, obj, event_type, + _push_to_timeline(user, obj, event_type, created_datetime, namespace=build_user_namespace(user), extra_data=extra_data) @@ -64,7 +65,7 @@ def _push_to_timelines(project, user, obj, event_type, extra_data={}): related_people |= team related_people = related_people.distinct() - _push_to_timeline(related_people, obj, event_type, + _push_to_timeline(related_people, obj, event_type, created_datetime, namespace=build_user_namespace(user), extra_data=extra_data) @@ -103,7 +104,8 @@ def on_new_history_entry(sender, instance, created, **kwargs): if instance.delete_comment_date: extra_data["comment_deleted"] = True - _push_to_timelines(project, user, obj, event_type, extra_data=extra_data) + created_datetime = instance.created_at + _push_to_timelines(project, user, obj, event_type, created_datetime, extra_data=extra_data) def create_membership_push_to_timeline(sender, instance, **kwargs): @@ -111,26 +113,29 @@ def create_membership_push_to_timeline(sender, instance, **kwargs): # If the user is the project owner we don't do anything because that info will # be shown in created project timeline entry if not instance.pk and instance.user and instance.user != instance.project.owner: - _push_to_timelines(instance.project, instance.user, instance, "create") + created_datetime = instance.created_at + _push_to_timelines(instance.project, instance.user, instance, "create", created_datetime) #Updating existing membership elif instance.pk: 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") + _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") + _push_to_timelines(instance.project, prev_instance.user, prev_instance, "delete", created_datetime) def delete_membership_push_to_timeline(sender, instance, **kwargs): if instance.user: - _push_to_timelines(instance.project, instance.user, instance, "delete") + created_datetime = timezone.now() + _push_to_timelines(instance.project, instance.user, instance, "delete", created_datetime) def create_user_push_to_timeline(sender, instance, created, **kwargs): if created: project = None user = instance - _push_to_timelines(project, user, user, "create") + _push_to_timelines(project, user, user, "create", created_datetime=user.date_joined) diff --git a/tests/integration/test_timeline.py b/tests/integration/test_timeline.py index 326a7b85..05c649b7 100644 --- a/tests/integration/test_timeline.py +++ b/tests/integration/test_timeline.py @@ -34,7 +34,7 @@ def test_add_to_object_timeline(): service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task, "test") + service._add_to_object_timeline(user1, task, "test", task.created_date) assert Timeline.objects.filter(object_id=user1.id).count() == 2 assert Timeline.objects.order_by("-id")[0].data == id(task) @@ -53,11 +53,11 @@ def test_get_timeline(): service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task1, "test") - service._add_to_object_timeline(user1, task2, "test") - service._add_to_object_timeline(user1, task3, "test") - service._add_to_object_timeline(user1, task4, "test") - service._add_to_object_timeline(user2, task1, "test") + service._add_to_object_timeline(user1, task1, "test", task1.created_date) + service._add_to_object_timeline(user1, task2, "test", task2.created_date) + service._add_to_object_timeline(user1, task3, "test", task3.created_date) + service._add_to_object_timeline(user1, task4, "test", task4.created_date) + service._add_to_object_timeline(user2, task1, "test", task1.created_date) assert Timeline.objects.filter(object_id=user1.id).count() == 5 assert Timeline.objects.filter(object_id=user2.id).count() == 2 @@ -71,7 +71,7 @@ def test_filter_timeline_no_privileges(): task1= factories.TaskFactory() service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task1, "test") + service._add_to_object_timeline(user1, task1, "test", task1.created_date) timeline = Timeline.objects.exclude(event_type="users.user.create") timeline = service.filter_timeline_for_user(timeline, user2) assert timeline.count() == 0 @@ -86,8 +86,8 @@ def test_filter_timeline_public_project(): task2= factories.TaskFactory.create(project=project) service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task1, "test") - service._add_to_object_timeline(user1, task2, "test") + service._add_to_object_timeline(user1, task1, "test", task1.created_date) + service._add_to_object_timeline(user1, task2, "test", task2.created_date) timeline = Timeline.objects.exclude(event_type="users.user.create") timeline = service.filter_timeline_for_user(timeline, user2) assert timeline.count() == 1 @@ -102,8 +102,8 @@ def test_filter_timeline_private_project_anon_permissions(): task2= factories.TaskFactory.create(project=project) service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task1, "test") - service._add_to_object_timeline(user1, task2, "test") + service._add_to_object_timeline(user1, task1, "test", task1.created_date) + service._add_to_object_timeline(user1, task2, "test", task2.created_date) timeline = Timeline.objects.exclude(event_type="users.user.create") timeline = service.filter_timeline_for_user(timeline, user2) assert timeline.count() == 1 @@ -121,8 +121,8 @@ def test_filter_timeline_private_project_member_permissions(): task2= factories.TaskFactory.create(project=project) service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x))) - service._add_to_object_timeline(user1, task1, "test") - service._add_to_object_timeline(user1, task2, "test") + service._add_to_object_timeline(user1, task1, "test", task1.created_date) + service._add_to_object_timeline(user1, task2, "test", task2.created_date) timeline = Timeline.objects.exclude(event_type="users.user.create") timeline = service.filter_timeline_for_user(timeline, user2) assert timeline.count() == 3 diff --git a/tests/unit/test_timeline.py b/tests/unit/test_timeline.py index c580404e..377e9728 100644 --- a/tests/unit/test_timeline.py +++ b/tests/unit/test_timeline.py @@ -31,12 +31,12 @@ def test_push_to_timeline_many_objects(): with patch("taiga.timeline.service._add_to_object_timeline") as mock: users = [User(), User(), User()] project = Project() - service.push_to_timeline(users, project, "test") + service.push_to_timeline(users, project, "test", project.created_date) assert mock.call_count == 3 assert mock.mock_calls == [ - call(users[0], project, "test", "default", {}), - call(users[1], project, "test", "default", {}), - call(users[2], project, "test", "default", {}), + call(users[0], project, "test", project.created_date, "default", {}), + call(users[1], project, "test", project.created_date, "default", {}), + call(users[2], project, "test", project.created_date, "default", {}), ] with pytest.raises(Exception): service.push_to_timeline(None, project, "test") @@ -46,12 +46,12 @@ def test_add_to_objects_timeline(): with patch("taiga.timeline.service._add_to_object_timeline") as mock: users = [User(), User(), User()] project = Project() - service._add_to_objects_timeline(users, project, "test") + service._add_to_objects_timeline(users, project, "test", project.created_date) assert mock.call_count == 3 assert mock.mock_calls == [ - call(users[0], project, "test", "default", {}), - call(users[1], project, "test", "default", {}), - call(users[2], project, "test", "default", {}), + call(users[0], project, "test", project.created_date, "default", {}), + call(users[1], project, "test", project.created_date, "default", {}), + call(users[2], project, "test", project.created_date, "default", {}), ] with pytest.raises(Exception): service.push_to_timeline(None, project, "test")