Fixing created datetime for timeline entries
parent
b60922422d
commit
aff9a7d637
|
@ -61,7 +61,7 @@ class BulkCreator(object):
|
||||||
bulk_creator = BulkCreator()
|
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(obj, Model), "obj must be a instance of Model"
|
||||||
assert isinstance(instance, Model), "instance 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)
|
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,
|
event_type=event_type_key,
|
||||||
project=instance.project,
|
project=instance.project,
|
||||||
data=impl(instance, extra_data=extra_data),
|
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 = bulk_creator.created,
|
created=created_datetime,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,23 +116,20 @@ def generate_timeline(initial_date, final_date, project_id):
|
||||||
|
|
||||||
#Memberships
|
#Memberships
|
||||||
for membership in project.memberships.exclude(user=None).exclude(user=project.owner):
|
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", membership.created_at)
|
||||||
_push_to_timelines(project, membership.user, membership, "create")
|
|
||||||
|
|
||||||
for project in projects.iterator():
|
for project in projects.iterator():
|
||||||
bulk_creator.created = project.created_date
|
|
||||||
print("Project:", bulk_creator.created)
|
print("Project:", bulk_creator.created)
|
||||||
extra_data = {
|
extra_data = {
|
||||||
"values_diff": {},
|
"values_diff": {},
|
||||||
"user": extract_user_info(project.owner),
|
"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
|
del extra_data
|
||||||
|
|
||||||
for historyEntry in history_entries.iterator():
|
for historyEntry in history_entries.iterator():
|
||||||
print("History entry:", historyEntry.created_at)
|
print("History entry:", historyEntry.created_at)
|
||||||
try:
|
try:
|
||||||
bulk_creator.created = historyEntry.created_at
|
|
||||||
on_new_history_entry(None, historyEntry, None)
|
on_new_history_entry(None, historyEntry, None)
|
||||||
except ObjectDoesNotExist as e:
|
except ObjectDoesNotExist as e:
|
||||||
print("Ignoring")
|
print("Ignoring")
|
||||||
|
|
|
@ -53,7 +53,7 @@ class BulkCreator(object):
|
||||||
bulk_creator = BulkCreator()
|
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(obj, Model), "obj must be a instance of Model"
|
||||||
assert isinstance(instance, Model), "instance 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)
|
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,
|
project=None,
|
||||||
data=impl(instance, extra_data=extra_data),
|
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 = 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 api wasn't a HistoryResourceMixin so we can't interate on the HistoryEntries in this case
|
||||||
users = User.objects.order_by("date_joined")
|
users = User.objects.order_by("date_joined")
|
||||||
for user in users.iterator():
|
for user in users.iterator():
|
||||||
bulk_creator.created = user.date_joined
|
|
||||||
print("User:", user.date_joined)
|
print("User:", user.date_joined)
|
||||||
extra_data = {
|
extra_data = {
|
||||||
"values_diff": {},
|
"values_diff": {},
|
||||||
"user": extract_user_info(user),
|
"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
|
del extra_data
|
||||||
|
|
||||||
bulk_creator.flush()
|
bulk_creator.flush()
|
||||||
|
|
|
@ -50,7 +50,7 @@ def build_project_namespace(project:object):
|
||||||
return "{0}:{1}".format("project", project.id)
|
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(obj, Model), "obj must be a instance of Model"
|
||||||
assert isinstance(instance, Model), "instance must be a instance of Model"
|
assert isinstance(instance, Model), "instance must be a instance of Model"
|
||||||
from .models import Timeline
|
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,
|
event_type=event_type_key,
|
||||||
project=project,
|
project=project,
|
||||||
data=impl(instance, extra_data=extra_data),
|
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:
|
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
|
@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):
|
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):
|
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:
|
else:
|
||||||
raise Exception("Invalid objects parameter")
|
raise Exception("Invalid objects parameter")
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from taiga.projects.history import services as history_services
|
from taiga.projects.history import services as history_services
|
||||||
from taiga.projects.models import Project
|
from taiga.projects.models import Project
|
||||||
|
@ -33,15 +34,15 @@ def _push_to_timeline(*args, **kwargs):
|
||||||
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:
|
if project is not None:
|
||||||
# Project timeline
|
# Project timeline
|
||||||
_push_to_timeline(project, obj, event_type,
|
_push_to_timeline(project, obj, event_type, created_datetime,
|
||||||
namespace=build_project_namespace(project),
|
namespace=build_project_namespace(project),
|
||||||
extra_data=extra_data)
|
extra_data=extra_data)
|
||||||
|
|
||||||
# User timeline
|
# User timeline
|
||||||
_push_to_timeline(user, obj, event_type,
|
_push_to_timeline(user, obj, event_type, created_datetime,
|
||||||
namespace=build_user_namespace(user),
|
namespace=build_user_namespace(user),
|
||||||
extra_data=extra_data)
|
extra_data=extra_data)
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ def _push_to_timelines(project, user, obj, event_type, extra_data={}):
|
||||||
related_people |= team
|
related_people |= team
|
||||||
related_people = related_people.distinct()
|
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),
|
namespace=build_user_namespace(user),
|
||||||
extra_data=extra_data)
|
extra_data=extra_data)
|
||||||
|
|
||||||
|
@ -103,7 +104,8 @@ def on_new_history_entry(sender, instance, created, **kwargs):
|
||||||
if instance.delete_comment_date:
|
if instance.delete_comment_date:
|
||||||
extra_data["comment_deleted"] = True
|
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):
|
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
|
# If the user is the project owner we don't do anything because that info will
|
||||||
# be shown in created project timeline entry
|
# be shown in created project timeline entry
|
||||||
if not instance.pk and instance.user and instance.user != instance.project.owner:
|
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
|
#Updating existing membership
|
||||||
elif instance.pk:
|
elif instance.pk:
|
||||||
prev_instance = sender.objects.get(pk=instance.pk)
|
prev_instance = sender.objects.get(pk=instance.pk)
|
||||||
if instance.user != prev_instance.user:
|
if instance.user != prev_instance.user:
|
||||||
|
created_datetime = timezone.now()
|
||||||
# The new member
|
# 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 we are updating the old user is removed from project
|
||||||
if prev_instance.user:
|
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):
|
def delete_membership_push_to_timeline(sender, instance, **kwargs):
|
||||||
if instance.user:
|
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):
|
def create_user_push_to_timeline(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
project = None
|
project = None
|
||||||
user = instance
|
user = instance
|
||||||
_push_to_timelines(project, user, user, "create")
|
_push_to_timelines(project, user, user, "create", created_datetime=user.date_joined)
|
||||||
|
|
|
@ -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.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.filter(object_id=user1.id).count() == 2
|
||||||
assert Timeline.objects.order_by("-id")[0].data == id(task)
|
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.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)
|
||||||
service._add_to_object_timeline(user1, task2, "test")
|
service._add_to_object_timeline(user1, task2, "test", task2.created_date)
|
||||||
service._add_to_object_timeline(user1, task3, "test")
|
service._add_to_object_timeline(user1, task3, "test", task3.created_date)
|
||||||
service._add_to_object_timeline(user1, task4, "test")
|
service._add_to_object_timeline(user1, task4, "test", task4.created_date)
|
||||||
service._add_to_object_timeline(user2, task1, "test")
|
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=user1.id).count() == 5
|
||||||
assert Timeline.objects.filter(object_id=user2.id).count() == 2
|
assert Timeline.objects.filter(object_id=user2.id).count() == 2
|
||||||
|
@ -71,7 +71,7 @@ def test_filter_timeline_no_privileges():
|
||||||
task1= factories.TaskFactory()
|
task1= factories.TaskFactory()
|
||||||
|
|
||||||
service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x)))
|
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 = Timeline.objects.exclude(event_type="users.user.create")
|
||||||
timeline = service.filter_timeline_for_user(timeline, user2)
|
timeline = service.filter_timeline_for_user(timeline, user2)
|
||||||
assert timeline.count() == 0
|
assert timeline.count() == 0
|
||||||
|
@ -86,8 +86,8 @@ def test_filter_timeline_public_project():
|
||||||
task2= factories.TaskFactory.create(project=project)
|
task2= factories.TaskFactory.create(project=project)
|
||||||
|
|
||||||
service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x)))
|
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)
|
||||||
service._add_to_object_timeline(user1, task2, "test")
|
service._add_to_object_timeline(user1, task2, "test", task2.created_date)
|
||||||
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
||||||
timeline = service.filter_timeline_for_user(timeline, user2)
|
timeline = service.filter_timeline_for_user(timeline, user2)
|
||||||
assert timeline.count() == 1
|
assert timeline.count() == 1
|
||||||
|
@ -102,8 +102,8 @@ def test_filter_timeline_private_project_anon_permissions():
|
||||||
task2= factories.TaskFactory.create(project=project)
|
task2= factories.TaskFactory.create(project=project)
|
||||||
|
|
||||||
service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x)))
|
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)
|
||||||
service._add_to_object_timeline(user1, task2, "test")
|
service._add_to_object_timeline(user1, task2, "test", task2.created_date)
|
||||||
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
||||||
timeline = service.filter_timeline_for_user(timeline, user2)
|
timeline = service.filter_timeline_for_user(timeline, user2)
|
||||||
assert timeline.count() == 1
|
assert timeline.count() == 1
|
||||||
|
@ -121,8 +121,8 @@ def test_filter_timeline_private_project_member_permissions():
|
||||||
task2= factories.TaskFactory.create(project=project)
|
task2= factories.TaskFactory.create(project=project)
|
||||||
|
|
||||||
service.register_timeline_implementation("tasks.task", "test", lambda x, extra_data=None: str(id(x)))
|
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)
|
||||||
service._add_to_object_timeline(user1, task2, "test")
|
service._add_to_object_timeline(user1, task2, "test", task2.created_date)
|
||||||
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
timeline = Timeline.objects.exclude(event_type="users.user.create")
|
||||||
timeline = service.filter_timeline_for_user(timeline, user2)
|
timeline = service.filter_timeline_for_user(timeline, user2)
|
||||||
assert timeline.count() == 3
|
assert timeline.count() == 3
|
||||||
|
|
|
@ -31,12 +31,12 @@ def test_push_to_timeline_many_objects():
|
||||||
with patch("taiga.timeline.service._add_to_object_timeline") as mock:
|
with patch("taiga.timeline.service._add_to_object_timeline") as mock:
|
||||||
users = [User(), User(), User()]
|
users = [User(), User(), User()]
|
||||||
project = Project()
|
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.call_count == 3
|
||||||
assert mock.mock_calls == [
|
assert mock.mock_calls == [
|
||||||
call(users[0], project, "test", "default", {}),
|
call(users[0], project, "test", project.created_date, "default", {}),
|
||||||
call(users[1], project, "test", "default", {}),
|
call(users[1], project, "test", project.created_date, "default", {}),
|
||||||
call(users[2], project, "test", "default", {}),
|
call(users[2], project, "test", project.created_date, "default", {}),
|
||||||
]
|
]
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
service.push_to_timeline(None, project, "test")
|
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:
|
with patch("taiga.timeline.service._add_to_object_timeline") as mock:
|
||||||
users = [User(), User(), User()]
|
users = [User(), User(), User()]
|
||||||
project = Project()
|
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.call_count == 3
|
||||||
assert mock.mock_calls == [
|
assert mock.mock_calls == [
|
||||||
call(users[0], project, "test", "default", {}),
|
call(users[0], project, "test", project.created_date, "default", {}),
|
||||||
call(users[1], project, "test", "default", {}),
|
call(users[1], project, "test", project.created_date, "default", {}),
|
||||||
call(users[2], project, "test", "default", {}),
|
call(users[2], project, "test", project.created_date, "default", {}),
|
||||||
]
|
]
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
service.push_to_timeline(None, project, "test")
|
service.push_to_timeline(None, project, "test")
|
||||||
|
|
Loading…
Reference in New Issue