Procházet zdrojové kódy

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

inkhey před 6 roky
rodič
revize
855e9da56d
No account linked to committer's email

+ 9 - 44
backend/tracim_backend/lib/core/content.py Zobrazit soubor

@@ -924,41 +924,6 @@ class ContentApi(object):
924 924
 
925 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 927
     def get_last_unread(self, parent_id: int, content_type: str,
963 928
                         workspace: Workspace=None, limit=10) -> typing.List[Content]:
964 929
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
@@ -989,7 +954,7 @@ class ContentApi(object):
989 954
             self,
990 955
             workspace: Workspace=None,
991 956
             limit: typing.Optional[int]=None,
992
-            before_datetime: typing.Optional[datetime.datetime]= None,
957
+            before_content: typing.Optional[Content]= None,
993 958
             content_ids: typing.Optional[typing.List[int]] = None,
994 959
     ) -> typing.List[Content]:
995 960
         """
@@ -997,7 +962,8 @@ class ContentApi(object):
997 962
         (last modification of content itself or one of this comment)
998 963
         :param workspace: Workspace to check
999 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 967
         :param content_ids: restrict selection to some content ids and
1002 968
         related Comments
1003 969
         :return: list of content
@@ -1021,6 +987,7 @@ class ContentApi(object):
1021 987
 
1022 988
         active_contents = []
1023 989
         too_recent_content = []
990
+        before_content_find = False
1024 991
         for content in resultset:
1025 992
             related_active_content = None
1026 993
             if ContentType.Comment == content.type:
@@ -1028,18 +995,16 @@ class ContentApi(object):
1028 995
             else:
1029 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 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 1001
                     active_contents.append(related_active_content)
1040 1002
                 else:
1041 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 1008
             if limit and len(active_contents) >= limit:
1044 1009
                 break
1045 1010
 

+ 10 - 2
backend/tracim_backend/lib/core/workspace.py Zobrazit soubor

@@ -3,9 +3,11 @@ import typing
3 3
 
4 4
 from sqlalchemy.orm import Query
5 5
 from sqlalchemy.orm import Session
6
+from sqlalchemy.orm.exc import NoResultFound
6 7
 
7 8
 from tracim_backend import CFG
8 9
 from tracim_backend.exceptions import EmptyLabelNotAllowed
10
+from tracim_backend.exceptions import WorkspaceNotFound
9 11
 from tracim_backend.lib.utils.translation import fake_translator as _
10 12
 
11 13
 from tracim_backend.lib.core.userworkspace import RoleApi
@@ -132,10 +134,16 @@ class WorkspaceApi(object):
132 134
         return workspace
133 135
 
134 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 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 149
     def get_one_for_current_user(self, id):

+ 2 - 2
backend/tracim_backend/models/context_models.py Zobrazit soubor

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

Diff nebyl zobrazen, protože je příliš veliký
+ 1806 - 170
backend/tracim_backend/tests/functional/test_user.py


+ 4 - 4
backend/tracim_backend/tests/library/test_content_api.py Zobrazit soubor

@@ -2247,26 +2247,26 @@ class TestContentApi(DefaultTest):
2247 2247
         secondly_created_but_not_commented = api.create(ContentType.Page, workspace, main_folder, 'this is another randomized label content', '', True)  # nopep8
2248 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 2251
         assert len(last_actives) == 2
2252 2252
         # comment is newest than page2
2253 2253
         assert last_actives[0] == firstly_created_but_recently_commented
2254 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 2257
         assert len(last_actives) == 2
2258 2258
         # last updated content is newer than other one despite creation
2259 2259
         # of the other is more recent
2260 2260
         assert last_actives[0] == firstly_created_but_recently_updated
2261 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 2264
         assert len(last_actives) == 2
2265 2265
         # creation order is inverted here as last created is last active
2266 2266
         assert last_actives[0] == secondly_created
2267 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 2270
         assert len(last_actives) == 1
2271 2271
         # folder subcontent modification does not change folder order
2272 2272
         assert last_actives[0] == main_folder

+ 5 - 3
backend/tracim_backend/views/core_api/schemas.py Zobrazit soubor

@@ -360,9 +360,11 @@ class ActiveContentFilterQuerySchema(marshmallow.Schema):
360 360
                     'the first limit elem (according to offset)',
361 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 369
     @post_load
368 370
     def make_content_filter(self, data):

+ 10 - 2
backend/tracim_backend/views/core_api/user_controller.py Zobrazit soubor

@@ -11,6 +11,7 @@ from tracim_backend.lib.core.group import GroupApi
11 11
 from tracim_backend.lib.core.user import UserApi
12 12
 from tracim_backend.lib.core.workspace import WorkspaceApi
13 13
 from tracim_backend.lib.core.content import ContentApi
14
+from tracim_backend.models.contents import ContentTypeLegacy as ContentType
14 15
 from tracim_backend.views.controllers import Controller
15 16
 from tracim_backend.lib.utils.authorization import require_same_user_or_profile
16 17
 from tracim_backend.lib.utils.authorization import require_profile
@@ -265,10 +266,17 @@ class UserController(Controller):
265 266
         workspace = None
266 267
         if hapic_data.path.workspace_id:
267 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 276
         last_actives = api.get_last_active(
269 277
             workspace=workspace,
270 278
             limit=content_filter.limit or None,
271
-            before_datetime=content_filter.before_datetime or None,
279
+            before_content=before_content,
272 280
         )
273 281
         return [
274 282
             api.get_content_in_context(content)
@@ -302,7 +310,7 @@ class UserController(Controller):
302 310
         last_actives = api.get_last_active(
303 311
             workspace=workspace,
304 312
             limit=None,
305
-            before_datetime=None,
313
+            before_content=None,
306 314
             content_ids=hapic_data.query.contents_ids or None
307 315
         )
308 316
         return [