Browse Source

Merge pull request #2 from tracim/fix/fix_read/unread_endpoints

inkhey 6 years ago
parent
commit
855e9da56d
No account linked to committer's email

+ 9 - 44
backend/tracim_backend/lib/core/content.py View File

924
 
924
 
925
         return resultset.all()
925
         return resultset.all()
926
 
926
 
927
-    def get_last_active(self, parent_id: int, content_type: str, workspace: Workspace=None, limit=10) -> typing.List[Content]:
928
-        assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
929
-        assert content_type is not None# DYN_REMOVE
930
-        assert isinstance(content_type, str) # DYN_REMOVE
931
-
932
-        resultset = self._base_query(workspace) \
933
-            .filter(Content.workspace_id == Workspace.workspace_id) \
934
-            .filter(Workspace.is_deleted.is_(False)) \
935
-            .order_by(desc(Content.updated))
936
-
937
-        if content_type!=ContentType.Any:
938
-            resultset = resultset.filter(Content.type==content_type)
939
-
940
-        if parent_id:
941
-            resultset = resultset.filter(Content.parent_id==parent_id)
942
-
943
-        result = []
944
-        for item in resultset:
945
-            new_item = None
946
-            if ContentType.Comment == item.type:
947
-                new_item = item.parent
948
-            else:
949
-                new_item = item
950
-
951
-            # INFO - D.A. - 2015-05-20
952
-            # We do not want to show only one item if the last 10 items are
953
-            # comments about one thread for example
954
-            if new_item not in result:
955
-                result.append(new_item)
956
-
957
-            if len(result) >= limit:
958
-                break
959
-
960
-        return result
961
-
962
     def get_last_unread(self, parent_id: int, content_type: str,
927
     def get_last_unread(self, parent_id: int, content_type: str,
963
                         workspace: Workspace=None, limit=10) -> typing.List[Content]:
928
                         workspace: Workspace=None, limit=10) -> typing.List[Content]:
964
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
929
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
989
             self,
954
             self,
990
             workspace: Workspace=None,
955
             workspace: Workspace=None,
991
             limit: typing.Optional[int]=None,
956
             limit: typing.Optional[int]=None,
992
-            before_datetime: typing.Optional[datetime.datetime]= None,
957
+            before_content: typing.Optional[Content]= None,
993
             content_ids: typing.Optional[typing.List[int]] = None,
958
             content_ids: typing.Optional[typing.List[int]] = None,
994
     ) -> typing.List[Content]:
959
     ) -> typing.List[Content]:
995
         """
960
         """
997
         (last modification of content itself or one of this comment)
962
         (last modification of content itself or one of this comment)
998
         :param workspace: Workspace to check
963
         :param workspace: Workspace to check
999
         :param limit: maximum number of elements to return
964
         :param limit: maximum number of elements to return
1000
-        :param before_datetime: date from where we check older content.
965
+        :param before_content: last_active content are only those updated
966
+         before this content given.
1001
         :param content_ids: restrict selection to some content ids and
967
         :param content_ids: restrict selection to some content ids and
1002
         related Comments
968
         related Comments
1003
         :return: list of content
969
         :return: list of content
1021
 
987
 
1022
         active_contents = []
988
         active_contents = []
1023
         too_recent_content = []
989
         too_recent_content = []
990
+        before_content_find = False
1024
         for content in resultset:
991
         for content in resultset:
1025
             related_active_content = None
992
             related_active_content = None
1026
             if ContentType.Comment == content.type:
993
             if ContentType.Comment == content.type:
1028
             else:
995
             else:
1029
                 related_active_content = content
996
                 related_active_content = content
1030
 
997
 
1031
-            if not before_datetime:
1032
-                before_datetime = datetime.datetime.now()
1033
-            # INFO - D.A. - 2015-05-20
1034
-            # We do not want to show only one item if the last 10 items are
1035
-            # comments about one thread for example
1036
             if related_active_content not in active_contents and related_active_content not in too_recent_content:  # nopep8
998
             if related_active_content not in active_contents and related_active_content not in too_recent_content:  # nopep8
1037
-                # we verify that content is old enough
1038
-                if content.updated < before_datetime:
999
+
1000
+                if not before_content or before_content_find:
1039
                     active_contents.append(related_active_content)
1001
                     active_contents.append(related_active_content)
1040
                 else:
1002
                 else:
1041
                     too_recent_content.append(related_active_content)
1003
                     too_recent_content.append(related_active_content)
1042
 
1004
 
1005
+                if before_content and related_active_content == before_content:
1006
+                    before_content_find = True
1007
+
1043
             if limit and len(active_contents) >= limit:
1008
             if limit and len(active_contents) >= limit:
1044
                 break
1009
                 break
1045
 
1010
 

+ 10 - 2
backend/tracim_backend/lib/core/workspace.py View File

3
 
3
 
4
 from sqlalchemy.orm import Query
4
 from sqlalchemy.orm import Query
5
 from sqlalchemy.orm import Session
5
 from sqlalchemy.orm import Session
6
+from sqlalchemy.orm.exc import NoResultFound
6
 
7
 
7
 from tracim_backend import CFG
8
 from tracim_backend import CFG
8
 from tracim_backend.exceptions import EmptyLabelNotAllowed
9
 from tracim_backend.exceptions import EmptyLabelNotAllowed
10
+from tracim_backend.exceptions import WorkspaceNotFound
9
 from tracim_backend.lib.utils.translation import fake_translator as _
11
 from tracim_backend.lib.utils.translation import fake_translator as _
10
 
12
 
11
 from tracim_backend.lib.core.userworkspace import RoleApi
13
 from tracim_backend.lib.core.userworkspace import RoleApi
132
         return workspace
134
         return workspace
133
 
135
 
134
     def get_one(self, id):
136
     def get_one(self, id):
135
-        return self._base_query().filter(Workspace.workspace_id == id).one()
137
+        try:
138
+            return self._base_query().filter(Workspace.workspace_id == id).one()
139
+        except NoResultFound as exc:
140
+            raise WorkspaceNotFound('workspace {} does not exist or not visible for user'.format(id)) from exc  # nopep8
136
 
141
 
137
     def get_one_by_label(self, label: str) -> Workspace:
142
     def get_one_by_label(self, label: str) -> Workspace:
138
-        return self._base_query().filter(Workspace.label == label).one()
143
+        try:
144
+            return self._base_query().filter(Workspace.label == label).one()
145
+        except NoResultFound as exc:
146
+            raise WorkspaceNotFound('workspace {} does not exist or not visible for user'.format(id)) from exc  # nopep8
139
 
147
 
140
     """
148
     """
141
     def get_one_for_current_user(self, id):
149
     def get_one_for_current_user(self, id):

+ 2 - 2
backend/tracim_backend/models/context_models.py View File

226
     def __init__(
226
     def __init__(
227
             self,
227
             self,
228
             limit: int = None,
228
             limit: int = None,
229
-            before_datetime: datetime = None,
229
+            before_content_id: datetime = None,
230
     ):
230
     ):
231
         self.limit = limit
231
         self.limit = limit
232
-        self.before_datetime = before_datetime
232
+        self.before_content_id = before_content_id
233
 
233
 
234
 
234
 
235
 class ContentIdsQuery(object):
235
 class ContentIdsQuery(object):

File diff suppressed because it is too large
+ 1806 - 170
backend/tracim_backend/tests/functional/test_user.py


+ 4 - 4
backend/tracim_backend/tests/library/test_content_api.py View File

2247
         secondly_created_but_not_commented = api.create(ContentType.Page, workspace, main_folder, 'this is another randomized label content', '', True)  # nopep8
2247
         secondly_created_but_not_commented = api.create(ContentType.Page, workspace, main_folder, 'this is another randomized label content', '', True)  # nopep8
2248
         comments = api.create_comment(workspace, firstly_created_but_recently_commented, 'juste a super comment', True)  # nopep8
2248
         comments = api.create_comment(workspace, firstly_created_but_recently_commented, 'juste a super comment', True)  # nopep8
2249
 
2249
 
2250
-        last_actives = api.get_last_active(workspace=workspace, limit=2, before_datetime=datetime.datetime.now())  # nopep8
2250
+        last_actives = api.get_last_active(workspace=workspace, limit=2)  # nopep8
2251
         assert len(last_actives) == 2
2251
         assert len(last_actives) == 2
2252
         # comment is newest than page2
2252
         # comment is newest than page2
2253
         assert last_actives[0] == firstly_created_but_recently_commented
2253
         assert last_actives[0] == firstly_created_but_recently_commented
2254
         assert last_actives[1] == secondly_created_but_not_commented
2254
         assert last_actives[1] == secondly_created_but_not_commented
2255
 
2255
 
2256
-        last_actives = api.get_last_active(workspace=workspace, limit=2, before_datetime=last_actives[1].get_simple_last_activity_date())  # nopep8
2256
+        last_actives = api.get_last_active(workspace=workspace, limit=2, before_content=last_actives[1])  # nopep8
2257
         assert len(last_actives) == 2
2257
         assert len(last_actives) == 2
2258
         # last updated content is newer than other one despite creation
2258
         # last updated content is newer than other one despite creation
2259
         # of the other is more recent
2259
         # of the other is more recent
2260
         assert last_actives[0] == firstly_created_but_recently_updated
2260
         assert last_actives[0] == firstly_created_but_recently_updated
2261
         assert last_actives[1] == secondly_created_but_not_updated
2261
         assert last_actives[1] == secondly_created_but_not_updated
2262
 
2262
 
2263
-        last_actives = api.get_last_active(workspace=workspace, limit=2, before_datetime=last_actives[1].get_simple_last_activity_date())  # nopep8
2263
+        last_actives = api.get_last_active(workspace=workspace, limit=2, before_content=last_actives[1])  # nopep8
2264
         assert len(last_actives) == 2
2264
         assert len(last_actives) == 2
2265
         # creation order is inverted here as last created is last active
2265
         # creation order is inverted here as last created is last active
2266
         assert last_actives[0] == secondly_created
2266
         assert last_actives[0] == secondly_created
2267
         assert last_actives[1] == firstly_created
2267
         assert last_actives[1] == firstly_created
2268
 
2268
 
2269
-        last_actives = api.get_last_active(workspace=workspace, limit=2, before_datetime=last_actives[1].get_simple_last_activity_date())  # nopep8
2269
+        last_actives = api.get_last_active(workspace=workspace, limit=2, before_content=last_actives[1])  # nopep8
2270
         assert len(last_actives) == 1
2270
         assert len(last_actives) == 1
2271
         # folder subcontent modification does not change folder order
2271
         # folder subcontent modification does not change folder order
2272
         assert last_actives[0] == main_folder
2272
         assert last_actives[0] == main_folder

+ 5 - 3
backend/tracim_backend/views/core_api/schemas.py View File

360
                     'the first limit elem (according to offset)',
360
                     'the first limit elem (according to offset)',
361
         validate=Range(min=0, error="Value must be positive or 0"),
361
         validate=Range(min=0, error="Value must be positive or 0"),
362
     )
362
     )
363
-    before_datetime = marshmallow.fields.DateTime(
364
-        format=DATETIME_FORMAT,
365
-        description='return only content lastly updated before this date',
363
+    before_content_id = marshmallow.fields.Int(
364
+        example=41,
365
+        default=None,
366
+        allow_none=True,
367
+        description='return only content updated before this content',
366
     )
368
     )
367
     @post_load
369
     @post_load
368
     def make_content_filter(self, data):
370
     def make_content_filter(self, data):

+ 10 - 2
backend/tracim_backend/views/core_api/user_controller.py View File

11
 from tracim_backend.lib.core.user import UserApi
11
 from tracim_backend.lib.core.user import UserApi
12
 from tracim_backend.lib.core.workspace import WorkspaceApi
12
 from tracim_backend.lib.core.workspace import WorkspaceApi
13
 from tracim_backend.lib.core.content import ContentApi
13
 from tracim_backend.lib.core.content import ContentApi
14
+from tracim_backend.models.contents import ContentTypeLegacy as ContentType
14
 from tracim_backend.views.controllers import Controller
15
 from tracim_backend.views.controllers import Controller
15
 from tracim_backend.lib.utils.authorization import require_same_user_or_profile
16
 from tracim_backend.lib.utils.authorization import require_same_user_or_profile
16
 from tracim_backend.lib.utils.authorization import require_profile
17
 from tracim_backend.lib.utils.authorization import require_profile
265
         workspace = None
266
         workspace = None
266
         if hapic_data.path.workspace_id:
267
         if hapic_data.path.workspace_id:
267
             workspace = wapi.get_one(hapic_data.path.workspace_id)
268
             workspace = wapi.get_one(hapic_data.path.workspace_id)
269
+        before_content = None
270
+        if content_filter.before_content_id:
271
+            before_content = api.get_one(
272
+                content_id=content_filter.before_content_id,
273
+                workspace=workspace,
274
+                content_type=ContentType.Any
275
+            )
268
         last_actives = api.get_last_active(
276
         last_actives = api.get_last_active(
269
             workspace=workspace,
277
             workspace=workspace,
270
             limit=content_filter.limit or None,
278
             limit=content_filter.limit or None,
271
-            before_datetime=content_filter.before_datetime or None,
279
+            before_content=before_content,
272
         )
280
         )
273
         return [
281
         return [
274
             api.get_content_in_context(content)
282
             api.get_content_in_context(content)
302
         last_actives = api.get_last_active(
310
         last_actives = api.get_last_active(
303
             workspace=workspace,
311
             workspace=workspace,
304
             limit=None,
312
             limit=None,
305
-            before_datetime=None,
313
+            before_content=None,
306
             content_ids=hapic_data.query.contents_ids or None
314
             content_ids=hapic_data.query.contents_ids or None
307
         )
315
         )
308
         return [
316
         return [