Browse Source

add simple get last active content endpoint

Guénaël Muller 6 years ago
parent
commit
818d966648

+ 20 - 19
tracim/lib/core/content.py View File

789
 
789
 
790
         return resultset.all()
790
         return resultset.all()
791
 
791
 
792
-    def get_last_active(self, parent_id: int, content_type: str, workspace: Workspace=None, limit=10) -> typing.List[Content]:
792
+    def get_last_active(self, parent_id: typing.Optional[int], content_type: str, workspace: Workspace=None, limit=10, offset=1) -> typing.List[Content]:
793
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
793
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
794
         assert content_type is not None# DYN_REMOVE
794
         assert content_type is not None# DYN_REMOVE
795
         assert isinstance(content_type, str) # DYN_REMOVE
795
         assert isinstance(content_type, str) # DYN_REMOVE
805
         if parent_id:
805
         if parent_id:
806
             resultset = resultset.filter(Content.parent_id==parent_id)
806
             resultset = resultset.filter(Content.parent_id==parent_id)
807
 
807
 
808
-        result = []
809
-        for item in resultset:
810
-            new_item = None
811
-            if ContentType.Comment == item.type:
812
-                new_item = item.parent
813
-            else:
814
-                new_item = item
808
+        resultset = resultset.slice(start=offset, stop=limit)
809
+        # result = []
810
+        # for item in resultset:
811
+        #     new_item = None
812
+        #     if ContentType.Comment == item.type:
813
+        #         new_item = item.parent
814
+        #     else:
815
+        #         new_item = item
816
+        #
817
+        #     # INFO - D.A. - 2015-05-20
818
+        #     # We do not want to show only one item if the last 10 items are
819
+        #     # comments about one thread for example
820
+        #     if new_item not in result:
821
+        #         result.append(new_item)
822
+        #
823
+        #     if len(result) >= limit:
824
+        #         break
815
 
825
 
816
-            # INFO - D.A. - 2015-05-20
817
-            # We do not want to show only one item if the last 10 items are
818
-            # comments about one thread for example
819
-            if new_item not in result:
820
-                result.append(new_item)
821
-
822
-            if len(result) >= limit:
823
-                break
824
-
825
-        return result
826
+        return resultset.all()
826
 
827
 
827
-    def get_last_unread(self, parent_id: int, content_type: str,
828
+    def get_last_unread(self, parent_id: typing.Optional[int], content_type: str,
828
                         workspace: Workspace=None, limit=10) -> typing.List[Content]:
829
                         workspace: Workspace=None, limit=10) -> typing.List[Content]:
829
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
830
         assert parent_id is None or isinstance(parent_id, int) # DYN_REMOVE
830
         assert content_type is not None# DYN_REMOVE
831
         assert content_type is not None# DYN_REMOVE

+ 17 - 0
tracim/models/context_models.py View File

64
     """
64
     """
65
     def __init__(
65
     def __init__(
66
             self,
66
             self,
67
+            workspace_id: int = None,
67
             parent_id: int = None,
68
             parent_id: int = None,
68
             show_archived: int = 0,
69
             show_archived: int = 0,
69
             show_deleted: int = 0,
70
             show_deleted: int = 0,
70
             show_active: int = 1,
71
             show_active: int = 1,
72
+            nb_elem: typing.Optional[int] = None,
73
+            offset: typing.Optional[int] = None,
71
     ) -> None:
74
     ) -> None:
75
+        # 0 is same as None here
76
+        if parent_id == 0:
77
+            parent_id = None
78
+        if workspace_id == 0:
79
+            workspace_id = None
80
+        if offset == 0:
81
+            offset = None
82
+        if nb_elem == 0:
83
+            nb_elem = None
84
+
72
         self.parent_id = parent_id
85
         self.parent_id = parent_id
86
+        self.workspace_id = workspace_id
73
         self.show_archived = bool(show_archived)
87
         self.show_archived = bool(show_archived)
74
         self.show_deleted = bool(show_deleted)
88
         self.show_deleted = bool(show_deleted)
75
         self.show_active = bool(show_active)
89
         self.show_active = bool(show_active)
90
+        self.nb_elem = nb_elem
91
+        self.offset = offset
92
+        self.content_type = ContentType.Any
76
 
93
 
77
 
94
 
78
 class ContentCreation(object):
95
 class ContentCreation(object):

+ 29 - 0
tracim/views/core_api/schemas.py View File

167
     @post_load
167
     @post_load
168
     def make_content_filter(self, data):
168
     def make_content_filter(self, data):
169
         return ContentFilter(**data)
169
         return ContentFilter(**data)
170
+
171
+
172
+class PaginationSchema(marshmallow.Schema):
173
+    nb_elem = marshmallow.fields.Int(
174
+        example=2,
175
+        default=0,
176
+        description='if 0 or not set, return all elements, else return only '
177
+                    'the first nb_elem (according to offset)',
178
+        validate=Range(min=0, error="Value must be positive or 0"),
179
+    )
180
+    offset = marshmallow.fields.Int(
181
+        example=5,
182
+        default=0,
183
+        description='if 0 or not set, do not set offset, else set offset for'
184
+                    'query',
185
+        validate=Range(min=0, error="Value must be positive or 0"),
186
+    )
187
+
188
+
189
+class ExtendedFilterQuerySchema(FilterContentQuerySchema, PaginationSchema):
190
+    workspace_id = marshmallow.fields.Int(
191
+        example=2,
192
+        default=0,
193
+        description='allow to filter items in a workspace.'
194
+                    ' If not set,'
195
+                    'then return contents from all known workspace',
196
+        validate=Range(min=0, error="Value must be positive or 0"),
197
+    )
198
+
170
 ###
199
 ###
171
 
200
 
172
 
201
 

+ 43 - 5
tracim/views/core_api/user_controller.py View File

1
 from pyramid.config import Configurator
1
 from pyramid.config import Configurator
2
-from sqlalchemy.orm.exc import NoResultFound
3
 
2
 
3
+from tracim.lib.core.content import ContentApi
4
 from tracim.lib.utils.authorization import require_same_user_or_profile
4
 from tracim.lib.utils.authorization import require_same_user_or_profile
5
 from tracim.models import Group
5
 from tracim.models import Group
6
 from tracim.models.context_models import WorkspaceInContext
6
 from tracim.models.context_models import WorkspaceInContext
12
 
12
 
13
 from tracim import hapic, TracimRequest
13
 from tracim import hapic, TracimRequest
14
 
14
 
15
-from tracim.exceptions import NotAuthenticated
16
-from tracim.exceptions import InsufficientUserProfile
17
-from tracim.exceptions import UserDoesNotExist
18
 from tracim.lib.core.workspace import WorkspaceApi
15
 from tracim.lib.core.workspace import WorkspaceApi
19
 from tracim.views.controllers import Controller
16
 from tracim.views.controllers import Controller
20
 from tracim.views.core_api.schemas import UserIdPathSchema
17
 from tracim.views.core_api.schemas import UserIdPathSchema
18
+from tracim.views.core_api.schemas import ContentDigestSchema
19
+from tracim.views.core_api.schemas import ExtendedFilterQuerySchema
21
 from tracim.views.core_api.schemas import WorkspaceDigestSchema
20
 from tracim.views.core_api.schemas import WorkspaceDigestSchema
21
+from tracim.models.contents import ContentTypeLegacy as ContentType
22
 
22
 
23
 USER_ENDPOINTS_TAG = 'Users'
23
 USER_ENDPOINTS_TAG = 'Users'
24
 
24
 
46
             for workspace in workspaces
46
             for workspace in workspaces
47
         ]
47
         ]
48
 
48
 
49
+    @hapic.with_api_doc(tags=[USER_ENDPOINTS_TAG])
50
+    @require_same_user_or_profile(Group.TIM_ADMIN)
51
+    @hapic.input_path(UserIdPathSchema())
52
+    @hapic.input_query(ExtendedFilterQuerySchema())
53
+    @hapic.output_body(ContentDigestSchema(many=True))
54
+    def last_active_content(self, context, request: TracimRequest, hapic_data=None):  # nopep8
55
+        """
56
+        Get last_active_content for user
57
+        """
58
+        app_config = request.registry.settings['CFG']
59
+        api = ContentApi(
60
+            current_user=request.current_user,  # User
61
+            session=request.dbsession,
62
+            config=app_config,
63
+        )
64
+        wapi = WorkspaceApi(
65
+            current_user=request.current_user,  # User
66
+            session=request.dbsession,
67
+            config=app_config,
68
+        )
69
+        workspace = None
70
+        if 'workspace_id' in hapic_data.body:
71
+            workspace = wapi.get_one(hapic_data.body.workspace_id)
72
+        last_actives = api.get_last_active(
73
+            parent_id=hapic_data.body.parent_id,
74
+            content_type=hapic_data.body.content_type,
75
+            workspace=workspace,
76
+            offset=None,
77
+            limit=None,
78
+        )
79
+        return [
80
+            api.get_content_in_context(content) for content in last_actives
81
+        ]
82
+
49
     def bind(self, configurator: Configurator) -> None:
83
     def bind(self, configurator: Configurator) -> None:
50
         """
84
         """
51
         Create all routes and views using pyramid configurator
85
         Create all routes and views using pyramid configurator
52
         for this controller
86
         for this controller
53
         """
87
         """
54
 
88
 
55
-        # Applications
89
+        # user worskpace
56
         configurator.add_route('user_workspace', '/users/{user_id}/workspaces', request_method='GET')  # nopep8
90
         configurator.add_route('user_workspace', '/users/{user_id}/workspaces', request_method='GET')  # nopep8
57
         configurator.add_view(self.user_workspace, route_name='user_workspace')
91
         configurator.add_view(self.user_workspace, route_name='user_workspace')
92
+
93
+        # last active content for user
94
+        configurator.add_route('last_active_content', '/users/{user_id}/contents/actives', request_method='GET')  # nopep8
95
+        configurator.add_view(self.last_active_content, route_name='last_active_content')  # nopep8