From cd6e301af40b1c5f06d7e881463aceb78858f4e5 Mon Sep 17 00:00:00 2001 From: Clement Verna Date: Jul 24 2017 12:06:23 +0000 Subject: Add the date_modified to projects API This commit add the date_modified timestamp to the projects API, the date_modified timestamp is updated whenever the project's settings, project's group settings or the project's user settings are modified. Fixes #2412 Signed-off-by: Clement Verna Signed-off-by: Pierre-Yves Chibon --- diff --git a/alembic/versions/8a5d68f74beb_add_date_modified_for_project.py b/alembic/versions/8a5d68f74beb_add_date_modified_for_project.py new file mode 100644 index 0000000..aa43da6 --- /dev/null +++ b/alembic/versions/8a5d68f74beb_add_date_modified_for_project.py @@ -0,0 +1,36 @@ +"""Add date_modified for project + +Revision ID: 8a5d68f74beb +Revises: 27a79ff0fb41 +Create Date: 2017-07-18 19:28:09.566997 + +""" +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = '8a5d68f74beb' +down_revision = '27a79ff0fb41' + + +def upgrade(): + ''' Add the column date_modified to the table projects. + ''' + op.add_column( + 'projects', + sa.Column('date_modified', sa.DateTime, nullable=True, + default=sa.func.now()) + ) + op.execute("UPDATE projects SET date_modified=date_created;") + + op.alter_column( + 'projects', + column_name='date_modified', + nullable=False, + exisiting_nullable=True) + + +def downgrade(): + ''' Remove the column date_modified from the table projects. + ''' + op.drop_column('projects', 'date_modified') diff --git a/pagure/api/project.py b/pagure/api/project.py index 7b8ee4f..a63b981 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -333,6 +333,7 @@ def api_projects(): "close_status": [], "custom_keys": [], "date_created": "1427441537", + "date_modified": "1427441537", "description": "A web-based calendar for Fedora", "milestones": {}, "namespace": null, diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index b67068b..b84d6d9 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -976,7 +976,9 @@ def add_user_to_project( if new_user_obj in project.users: access_obj = get_obj_access(session, project, new_user_obj) access_obj.access = access + project.date_modified = datetime.datetime.utcnow() session.add(access_obj) + session.add(project) session.flush() pagure.lib.notify.log( @@ -998,7 +1000,9 @@ def add_user_to_project( user_id=new_user_obj.id, access=access, ) + project.date_modified = datetime.datetime.utcnow() session.add(project_user) + session.add(project) # Make sure we won't have SQLAlchemy error before we continue session.flush() @@ -1067,6 +1071,8 @@ def add_group_to_project( access_obj = get_obj_access(session, project, group_obj) access_obj.access = access session.add(access_obj) + project.date_modified = datetime.datetime.utcnow() + session.add(project) session.flush() pagure.lib.notify.log( @@ -1090,6 +1096,8 @@ def add_group_to_project( ) session.add(project_group) # Make sure we won't have SQLAlchemy error before we continue + project.date_modified = datetime.datetime.utcnow() + session.add(project) session.flush() pagure.lib.notify.log( @@ -1738,6 +1746,7 @@ def update_project_settings(session, repo, settings, user): return 'No settings to change' else: repo.settings = new_settings + repo.date_modified = datetime.datetime.utcnow() session.add(repo) session.flush() diff --git a/pagure/lib/model.py b/pagure/lib/model.py index f37fd95..5191a91 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -371,7 +371,8 @@ class Project(BASE): date_created = sa.Column(sa.DateTime, nullable=False, default=datetime.datetime.utcnow) - + date_modified = sa.Column(sa.DateTime, nullable=False, + default=datetime.datetime.utcnow) parent = relation('Project', remote_side=[id], backref='forks') user = relation('User', foreign_keys=[user_id], remote_side=[User.id], backref='projects') @@ -821,6 +822,7 @@ class Project(BASE): 'parent': self.parent.to_json( public=public, api=api) if self.parent else None, 'date_created': self.date_created.strftime('%s'), + 'date_modified': self.date_modified.strftime('%s'), 'user': self.user.to_json(public=public), 'access_users': self.access_users_json, 'access_groups': self.access_groups_json, diff --git a/tests/test_pagure_flask_api_fork.py b/tests/test_pagure_flask_api_fork.py index 47b1719..1de1c79 100644 --- a/tests/test_pagure_flask_api_fork.py +++ b/tests/test_pagure_flask_api_fork.py @@ -89,7 +89,9 @@ class PagureFlaskApiForktests(tests.Modeltests): data['requests'][0]['date_created'] = '1431414800' data['requests'][0]['updated_on'] = '1431414800' data['requests'][0]['project']['date_created'] = '1431414800' + data['requests'][0]['project']['date_modified'] = '1431414800' data['requests'][0]['repo_from']['date_created'] = '1431414800' + data['requests'][0]['repo_from']['date_modified'] = '1431414800' data['requests'][0]['uid'] = '1431414800' data['requests'][0]['last_updated'] = '1431414800' expected_data = { @@ -131,6 +133,7 @@ class PagureFlaskApiForktests(tests.Modeltests): ], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project #1", "fullname": "test", "id": 1, @@ -165,6 +168,7 @@ class PagureFlaskApiForktests(tests.Modeltests): ], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project #1", "fullname": "test", "id": 1, @@ -201,7 +205,9 @@ class PagureFlaskApiForktests(tests.Modeltests): data2['requests'][0]['date_created'] = '1431414800' data2['requests'][0]['updated_on'] = '1431414800' data2['requests'][0]['project']['date_created'] = '1431414800' + data2['requests'][0]['project']['date_modified'] = '1431414800' data2['requests'][0]['repo_from']['date_created'] = '1431414800' + data2['requests'][0]['repo_from']['date_modified'] = '1431414800' data2['requests'][0]['uid'] = '1431414800' data2['requests'][0]['last_updated'] = '1431414800' self.assertDictEqual(data, data2) @@ -262,7 +268,9 @@ class PagureFlaskApiForktests(tests.Modeltests): data['date_created'] = '1431414800' data['updated_on'] = '1431414800' data['project']['date_created'] = '1431414800' + data['project']['date_modified'] = '1431414800' data['repo_from']['date_created'] = '1431414800' + data['repo_from']['date_modified'] = '1431414800' data['uid'] = '1431414800' data['last_updated'] = '1431414800' expected_data = { @@ -298,6 +306,7 @@ class PagureFlaskApiForktests(tests.Modeltests): ], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project #1", "fullname": "test", "id": 1, @@ -330,6 +339,7 @@ class PagureFlaskApiForktests(tests.Modeltests): "Duplicate"], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project #1", "fullname": "test", "id": 1, @@ -363,7 +373,9 @@ class PagureFlaskApiForktests(tests.Modeltests): data2 = json.loads(output.data) data2['date_created'] = '1431414800' data2['project']['date_created'] = '1431414800' + data2['project']['date_modified'] = '1431414800' data2['repo_from']['date_created'] = '1431414800' + data2['repo_from']['date_modified'] = '1431414800' data2['uid'] = '1431414800' data2['date_created'] = '1431414800' data2['updated_on'] = '1431414800' diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 0747f8a..4191c89 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -243,6 +243,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -276,6 +277,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -367,6 +369,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -395,6 +398,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -417,8 +421,11 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" data['projects'][1]['date_created'] = "1436527638" + data['projects'][1]['date_modified'] = "1436527638" data['projects'][2]['date_created'] = "1436527638" + data['projects'][2]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -450,6 +457,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -484,6 +492,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #2", "fullname": "test2", "id": 2, @@ -518,6 +527,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, @@ -541,8 +551,11 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" data['projects'][1]['date_created'] = "1436527638" + data['projects'][1]['date_modified'] = "1436527638" data['projects'][2]['date_created'] = "1436527638" + data['projects'][2]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -573,6 +586,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -607,6 +621,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #2", "fullname": "test2", "id": 2, @@ -639,6 +654,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, @@ -662,6 +678,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -690,6 +707,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): "Duplicate"], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -712,6 +730,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -741,6 +760,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, @@ -795,6 +815,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['date_created'] = "1436527638" + data['date_modified'] = "1436527638" expected_data ={ "access_groups": { "admin": [], @@ -814,6 +835,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -837,9 +859,9 @@ class PagureFlaskApiProjecttests(tests.Modeltests): output = self.app.get('/api/0/projects?page=1') self.assertEqual(output.status_code, 200) data = json.loads(output.data) - data['projects'][0]['date_created'] = "1436527638" - data['projects'][1]['date_created'] = "1436527638" - data['projects'][2]['date_created'] = "1436527638" + for i in range(3): + data['projects'][i]['date_created'] = "1436527638" + data['projects'][i]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -881,6 +903,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #1", "fullname": "test", "id": 1, @@ -915,6 +938,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project #2", "fullname": "test2", "id": 2, @@ -947,6 +971,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, @@ -975,6 +1000,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" expected_data = { "args": { "fork": None, @@ -1017,6 +1043,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, @@ -1106,6 +1133,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['date_created'] = '1496338274' + data['date_modified'] = '1496338274' expected_output = { "access_groups": { "admin": [], @@ -1128,6 +1156,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests): ], "custom_keys": [], "date_created": "1496338274", + "date_modified": "1496338274", "description": "test project #1", "fullname": "test", "id": 1, diff --git a/tests/test_pagure_flask_api_ui_private_repo.py b/tests/test_pagure_flask_api_ui_private_repo.py index bfed6b4..c218435 100644 --- a/tests/test_pagure_flask_api_ui_private_repo.py +++ b/tests/test_pagure_flask_api_ui_private_repo.py @@ -1021,6 +1021,7 @@ class PagurePrivateRepotest(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" self.assertDictEqual( data, { @@ -1053,6 +1054,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project description", "id": 1, "milestones": {}, @@ -1075,6 +1077,7 @@ class PagurePrivateRepotest(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) data['projects'][0]['date_created'] = "1436527638" + data['projects'][0]['date_modified'] = "1436527638" self.assertDictEqual( data, { @@ -1106,6 +1109,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1436527638", + "date_modified": "1436527638", "description": "test project description", "id": 1, "milestones": {}, @@ -1181,7 +1185,9 @@ class PagurePrivateRepotest(tests.Modeltests): data['requests'][0]['date_created'] = '1431414800' data['requests'][0]['updated_on'] = '1431414800' data['requests'][0]['project']['date_created'] = '1431414800' + data['requests'][0]['project']['date_modified'] = '1431414800' data['requests'][0]['repo_from']['date_created'] = '1431414800' + data['requests'][0]['repo_from']['date_modified'] = '1431414800' data['requests'][0]['uid'] = '1431414800' data['requests'][0]['last_updated'] = '1431414800' self.assertDictEqual( @@ -1223,6 +1229,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project description", "id": 1, "milestones": {}, @@ -1255,6 +1262,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project description", "id": 1, "milestones": {}, @@ -1292,7 +1300,9 @@ class PagurePrivateRepotest(tests.Modeltests): data2['requests'][0]['date_created'] = '1431414800' data2['requests'][0]['updated_on'] = '1431414800' data2['requests'][0]['project']['date_created'] = '1431414800' + data2['requests'][0]['project']['date_modified'] = '1431414800' data2['requests'][0]['repo_from']['date_created'] = '1431414800' + data2['requests'][0]['repo_from']['date_modified'] = '1431414800' data2['requests'][0]['uid'] = '1431414800' data2['requests'][0]['last_updated'] = '1431414800' self.assertDictEqual(data, data2) @@ -1304,7 +1314,9 @@ class PagurePrivateRepotest(tests.Modeltests): data['date_created'] = '1431414800' data['updated_on'] = '1431414800' data['project']['date_created'] = '1431414800' + data['project']['date_modified'] = '1431414800' data['repo_from']['date_created'] = '1431414800' + data['repo_from']['date_modified'] = '1431414800' data['uid'] = '1431414800' data['last_updated'] = '1431414800' self.assertDictEqual( @@ -1339,6 +1351,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project description", "id": 1, "milestones": {}, @@ -1371,6 +1384,7 @@ class PagurePrivateRepotest(tests.Modeltests): "close_status": [], "custom_keys": [], "date_created": "1431414800", + "date_modified": "1431414800", "description": "test project description", "id": 1, "milestones": {}, @@ -1404,7 +1418,9 @@ class PagurePrivateRepotest(tests.Modeltests): data2 = json.loads(output.get_data(as_text=True)) data2['date_created'] = '1431414800' data2['project']['date_created'] = '1431414800' + data2['project']['date_modified'] = '1431414800' data2['repo_from']['date_created'] = '1431414800' + data2['repo_from']['date_modified'] = '1431414800' data2['uid'] = '1431414800' data2['date_created'] = '1431414800' data2['updated_on'] = '1431414800' diff --git a/tests/test_pagure_flask_api_user.py b/tests/test_pagure_flask_api_user.py index ba487b2..572eec7 100644 --- a/tests/test_pagure_flask_api_user.py +++ b/tests/test_pagure_flask_api_user.py @@ -88,8 +88,11 @@ class PagureFlaskApiUSertests(tests.Modeltests): self.assertEqual(output.status_code, 200) data = json.loads(output.data) data['repos'][0]['date_created'] = "1490272832" + data['repos'][0]['date_modified'] = "1490272832" data['repos'][1]['date_created'] = "1490272832" + data['repos'][1]['date_modified'] = "1490272832" data['repos'][2]['date_created'] = "1490272832" + data['repos'][2]['date_modified'] = "1490272832" expected_data = { "forks": [], "repos": [ @@ -113,6 +116,7 @@ class PagureFlaskApiUSertests(tests.Modeltests): ], "custom_keys": [], "date_created": "1490272832", + "date_modified": "1490272832", "description": "test project #1", "fullname": "test", "id": 1, @@ -160,6 +164,7 @@ class PagureFlaskApiUSertests(tests.Modeltests): ], "custom_keys": [], "date_created": "1490272832", + "date_modified": "1490272832", "description": "test project #2", "fullname": "test2", "id": 2, @@ -206,6 +211,7 @@ class PagureFlaskApiUSertests(tests.Modeltests): ], "custom_keys": [], "date_created": "1490272832", + "date_modified": "1490272832", "description": "namespaced test project", "fullname": "somenamespace/test3", "id": 3, diff --git a/tests/test_pagure_lib_git.py b/tests/test_pagure_lib_git.py index 8300527..d226b43 100644 --- a/tests/test_pagure_lib_git.py +++ b/tests/test_pagure_lib_git.py @@ -1850,7 +1850,7 @@ new file mode 100644 index 0000000..60f7480 --- /dev/null +++ b/456 -@@ -0,0 +1,126 @@ +@@ -0,0 +1,128 @@ +{ + "assignee": null, + "branch": "master", @@ -1881,6 +1881,7 @@ index 0000000..60f7480 + "close_status": [], + "custom_keys": [], + "date_created": null, ++ "date_modified": null, + "description": "test project for ticket", + "fullname": "test_ticket_repo", + "id": 1, @@ -1931,6 +1932,7 @@ index 0000000..60f7480 + "close_status": [], + "custom_keys": [], + "date_created": null, ++ "date_modified": null, + "description": "test project for ticket", + "fullname": "test_ticket_repo", + "id": 1, @@ -1998,6 +2000,9 @@ index 0000000..60f7480 elif 'date_created' in row: t = row.split(': ')[0] row = '%s: null,' % t + elif 'date_modified' in row: + t = row.split(': ')[0] + row = '%s: null,' % t elif 'last_updated' in row: t = row.split(': ')[0] row = '%s: null,' % t @@ -2010,7 +2015,7 @@ index 0000000..60f7480 row = '+++ b/456' npatch.append(row) patch = '\n'.join(npatch) - # print patch + print patch self.assertEqual(patch, exp) def test_update_ticket_from_git_no_priority(self):