Explorar el Código

add endpoint for previews

Guénaël Muller hace 6 años
padre
commit
d27feca166

+ 34 - 0
tracim/models/context_models.py Ver fichero

@@ -53,6 +53,29 @@ class WorkspaceAndContentRevisionPath(object):
53 53
         self.workspace_id = workspace_id
54 54
 
55 55
 
56
+class ContentPreviewSizedPath(object):
57
+    """
58
+    Paths params with workspace id and content_id, width, heigth
59
+    """
60
+    def __init__(self, workspace_id: int, content_id: int, width: int, height: int) -> None:  # nopep8
61
+        self.content_id = content_id
62
+        self.workspace_id = workspace_id
63
+        self.width = width
64
+        self.height = height
65
+
66
+
67
+class RevisionPreviewSizedPath(object):
68
+    """
69
+    Paths params with workspace id and content_id, revision_id width, heigth
70
+    """
71
+    def __init__(self, workspace_id: int, content_id: int, revision_id: int, width: int, height: int) -> None:  # nopep8
72
+        self.content_id = content_id
73
+        self.revision_id = revision_id
74
+        self.workspace_id = workspace_id
75
+        self.width = width
76
+        self.height = height
77
+
78
+
56 79
 class CommentPath(object):
57 80
     """
58 81
     Paths params with workspace id and content_id and comment_id model
@@ -68,6 +91,17 @@ class CommentPath(object):
68 91
         self.comment_id = comment_id
69 92
 
70 93
 
94
+class PageQuery(object):
95
+    """
96
+    Page query model
97
+    """
98
+    def __init__(
99
+            self,
100
+            page: int = 0
101
+    ):
102
+        self.page = page
103
+
104
+
71 105
 class ContentFilter(object):
72 106
     """
73 107
     Content filter model

+ 141 - 6
tracim/views/contents_api/file_controller.py Ver fichero

@@ -20,6 +20,9 @@ from tracim.extensions import hapic
20 20
 from tracim.lib.core.content import ContentApi
21 21
 from tracim.views.controllers import Controller
22 22
 from tracim.views.core_api.schemas import FileContentSchema
23
+from tracim.views.core_api.schemas import ContentPreviewSizedPathSchema
24
+from tracim.views.core_api.schemas import RevisionPreviewSizedPathSchema
25
+from tracim.views.core_api.schemas import PageQuerySchema
23 26
 from tracim.views.core_api.schemas import WorkspaceAndContentRevisionIdPathSchema  # nopep8
24 27
 from tracim.views.core_api.schemas import FileRevisionSchema
25 28
 from tracim.views.core_api.schemas import SetContentStatusSchema
@@ -126,45 +129,177 @@ class FileController(Controller):
126 129
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
127 130
     @require_workspace_role(UserRoleInWorkspace.READER)
128 131
     @require_content_types([file_type])
132
+    @hapic.input_query(PageQuerySchema())
133
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
129 134
     @hapic.output_file([])
130 135
     def preview_pdf(self, context, request: TracimRequest, hapic_data=None):
131
-        raise NotImplemented()
136
+        app_config = request.registry.settings['CFG']
137
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
138
+        api = ContentApi(
139
+            current_user=request.current_user,
140
+            session=request.dbsession,
141
+            config=app_config,
142
+        )
143
+        content = api.get_one(
144
+            hapic_data.path.content_id,
145
+            content_type=ContentType.Any
146
+        )
147
+        file_path = api.get_one_revision_filepath(content.revision_id)
148
+        if hapic_data.query.page >= preview_manager.get_page_nb(file_path):
149
+            raise Exception('page {page} of content {content_id} does not exist'.format(
150
+                page=hapic_data.query.page,
151
+                content_id=content.content_id),
152
+            )
153
+        pdf_preview_path = preview_manager.get_pdf_preview(file_path, page=hapic_data.query.page)  # nopep8
154
+        return FileResponse(pdf_preview_path)
132 155
 
133 156
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
134 157
     @require_workspace_role(UserRoleInWorkspace.READER)
135 158
     @require_content_types([file_type])
159
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
136 160
     @hapic.output_file([])
137 161
     def preview_pdf_full(self, context, request: TracimRequest, hapic_data=None):
138
-        raise NotImplemented()
162
+        app_config = request.registry.settings['CFG']
163
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
164
+        api = ContentApi(
165
+            current_user=request.current_user,
166
+            session=request.dbsession,
167
+            config=app_config,
168
+        )
169
+        content = api.get_one(
170
+            hapic_data.path.content_id,
171
+            content_type=ContentType.Any
172
+        )
173
+        file_path = api.get_one_revision_filepath(content.revision_id)
174
+        pdf_preview_path = preview_manager.get_pdf_preview(file_path)
175
+        return FileResponse(pdf_preview_path)
139 176
 
140 177
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
141 178
     @require_workspace_role(UserRoleInWorkspace.READER)
142 179
     @require_content_types([file_type])
180
+    @hapic.input_path(WorkspaceAndContentRevisionIdPathSchema())
181
+    @hapic.input_query(PageQuerySchema())
143 182
     @hapic.output_file([])
144 183
     def preview_pdf_revision(self, context, request: TracimRequest, hapic_data=None):
145
-        raise NotImplemented()
184
+        app_config = request.registry.settings['CFG']
185
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
186
+        api = ContentApi(
187
+            current_user=request.current_user,
188
+            session=request.dbsession,
189
+            config=app_config,
190
+        )
191
+        content = api.get_one(
192
+            hapic_data.path.content_id,
193
+            content_type=ContentType.Any
194
+        )
195
+        revision = api.get_one_revision(
196
+            revision_id=hapic_data.path.revision_id,
197
+            content=content
198
+        )
199
+        file_path = api.get_one_revision_filepath(revision.revision_id)
200
+        if hapic_data.query.page >= preview_manager.get_page_nb(file_path):
201
+            raise Exception('page {page} of content {content_id} does not exist'.format(
202
+                page=hapic_data.query.page,
203
+                content_id=content.content_id),
204
+            )
205
+        pdf_preview_path = preview_manager.get_pdf_preview(file_path, page=hapic_data.query.page)  # nopep8
206
+        return FileResponse(pdf_preview_path)
146 207
 
147 208
     # jpg
148 209
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
149 210
     @require_workspace_role(UserRoleInWorkspace.READER)
150 211
     @require_content_types([file_type])
212
+    @hapic.input_path(WorkspaceAndContentIdPathSchema())
213
+    @hapic.input_query(PageQuerySchema())
151 214
     @hapic.output_file([])
152 215
     def preview_jpg(self, context, request: TracimRequest, hapic_data=None):
153
-        raise NotImplemented()
216
+        app_config = request.registry.settings['CFG']
217
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
218
+        api = ContentApi(
219
+            current_user=request.current_user,
220
+            session=request.dbsession,
221
+            config=app_config,
222
+        )
223
+        content = api.get_one(
224
+            hapic_data.path.content_id,
225
+            content_type=ContentType.Any
226
+        )
227
+        file_path = api.get_one_revision_filepath(content.revision_id)
228
+        if hapic_data.query.page >= preview_manager.get_page_nb(file_path):
229
+            raise Exception('page {page} of content {content_id} does not exist'.format(
230
+                page=hapic_data.query.page,
231
+                content_id=content.content_id),
232
+            )
233
+        jpg_preview_path = preview_manager.get_jpeg_preview(file_path, page=hapic_data.query.page)  # nopep8
234
+        return FileResponse(jpg_preview_path)
154 235
 
155 236
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
156 237
     @require_workspace_role(UserRoleInWorkspace.READER)
157 238
     @require_content_types([file_type])
239
+    @hapic.input_query(PageQuerySchema())
240
+    @hapic.input_path(ContentPreviewSizedPathSchema())
158 241
     @hapic.output_file([])
159 242
     def sized_preview_jpg(self, context, request: TracimRequest, hapic_data=None):
160
-        raise NotImplemented()
243
+        app_config = request.registry.settings['CFG']
244
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
245
+        api = ContentApi(
246
+            current_user=request.current_user,
247
+            session=request.dbsession,
248
+            config=app_config,
249
+        )
250
+        content = api.get_one(
251
+            hapic_data.path.content_id,
252
+            content_type=ContentType.Any
253
+        )
254
+        file_path = api.get_one_revision_filepath(content.revision_id)
255
+        if hapic_data.query.page >= preview_manager.get_page_nb(file_path):
256
+            raise Exception('page {page} of content {content_id} does not exist'.format(
257
+                page=hapic_data.query.page,
258
+                content_id=content.content_id),
259
+            )
260
+        jpg_preview_path = preview_manager.get_jpeg_preview(
261
+            file_path,
262
+            page=hapic_data.query.page,
263
+            width=hapic_data.path.width,
264
+            height=hapic_data.path.height,
265
+        )
266
+        return FileResponse(jpg_preview_path)
161 267
 
162 268
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
163 269
     @require_workspace_role(UserRoleInWorkspace.READER)
164 270
     @require_content_types([file_type])
271
+    @hapic.input_path(RevisionPreviewSizedPathSchema())
272
+    @hapic.input_query(PageQuerySchema())
165 273
     @hapic.output_file([])
166 274
     def sized_preview_jpg_revision(self, context, request: TracimRequest, hapic_data=None):
167
-        raise NotImplemented()
275
+        app_config = request.registry.settings['CFG']
276
+        preview_manager = PreviewManager(app_config.PREVIEW_CACHE_DIR, create_folder=True)  # nopep8
277
+        api = ContentApi(
278
+            current_user=request.current_user,
279
+            session=request.dbsession,
280
+            config=app_config,
281
+        )
282
+        content = api.get_one(
283
+            hapic_data.path.content_id,
284
+            content_type=ContentType.Any
285
+        )
286
+        revision = api.get_one_revision(
287
+            revision_id=hapic_data.path.revision_id,
288
+            content=content
289
+        )
290
+        file_path = api.get_one_revision_filepath(revision.revision_id)
291
+        if hapic_data.query.page >= preview_manager.get_page_nb(file_path):
292
+            raise Exception('page {page} of content {content_id} does not exist'.format(
293
+                page=hapic_data.query.page,
294
+                content_id=content.content_id),
295
+            )
296
+        jpg_preview_path = preview_manager.get_jpeg_preview(
297
+            file_path,
298
+            page=hapic_data.query.page,
299
+            width=hapic_data.path.width,
300
+            height=hapic_data.path.height,
301
+        )
302
+        return FileResponse(jpg_preview_path)
168 303
 
169 304
     @hapic.with_api_doc(tags=[FILE_ENDPOINTS_TAG])
170 305
     @require_workspace_role(UserRoleInWorkspace.READER)

+ 41 - 1
tracim/views/core_api/schemas.py Ver fichero

@@ -1,7 +1,7 @@
1 1
 # coding=utf-8
2 2
 import marshmallow
3 3
 from marshmallow import post_load
4
-from marshmallow.validate import OneOf
4
+from marshmallow.validate import OneOf, Range
5 5
 
6 6
 from tracim.lib.utils.utils import DATETIME_FORMAT
7 7
 from tracim.models.auth import Profile
@@ -10,6 +10,9 @@ from tracim.models.contents import open_status
10 10
 from tracim.models.contents import ContentTypeLegacy as ContentType
11 11
 from tracim.models.contents import ContentStatusLegacy as ContentStatus
12 12
 from tracim.models.context_models import ContentCreation
13
+from tracim.models.context_models import ContentPreviewSizedPath
14
+from tracim.models.context_models import RevisionPreviewSizedPath
15
+from tracim.models.context_models import PageQuery
13 16
 from tracim.models.context_models import WorkspaceAndContentRevisionPath
14 17
 from tracim.models.context_models import CommentCreation
15 18
 from tracim.models.context_models import TextBasedContentUpdate
@@ -90,6 +93,7 @@ class WorkspaceIdPathSchema(marshmallow.Schema):
90 93
 class ContentIdPathSchema(marshmallow.Schema):
91 94
     content_id = marshmallow.fields.Int(example=6, required=True)
92 95
 
96
+
93 97
 class RevisionIdPathSchema(marshmallow.Schema):
94 98
     revision_id = marshmallow.fields.Int(example=6, required=True)
95 99
 
@@ -103,6 +107,11 @@ class WorkspaceAndContentIdPathSchema(
103 107
         return WorkspaceAndContentPath(**data)
104 108
 
105 109
 
110
+class WidthAndHeightPathSchema(marshmallow.Schema):
111
+    width = marshmallow.fields.Int(example=256)
112
+    height = marshmallow.fields.Int(example=256)
113
+
114
+
106 115
 class WorkspaceAndContentRevisionIdPathSchema(
107 116
     WorkspaceIdPathSchema,
108 117
     ContentIdPathSchema,
@@ -113,6 +122,24 @@ class WorkspaceAndContentRevisionIdPathSchema(
113 122
         return WorkspaceAndContentRevisionPath(**data)
114 123
 
115 124
 
125
+class ContentPreviewSizedPathSchema(
126
+    WorkspaceAndContentIdPathSchema,
127
+    WidthAndHeightPathSchema
128
+):
129
+    @post_load
130
+    def make_path_object(self, data):
131
+        return ContentPreviewSizedPath(**data)
132
+
133
+
134
+class RevisionPreviewSizedPathSchema(
135
+    WorkspaceAndContentRevisionIdPathSchema,
136
+    WidthAndHeightPathSchema
137
+):
138
+    @post_load
139
+    def make_path_object(self, data):
140
+        return RevisionPreviewSizedPath(**data)
141
+
142
+
116 143
 class CommentsPathSchema(WorkspaceAndContentIdPathSchema):
117 144
     comment_id = marshmallow.fields.Int(
118 145
         example=6,
@@ -124,6 +151,19 @@ class CommentsPathSchema(WorkspaceAndContentIdPathSchema):
124 151
         return CommentPath(**data)
125 152
 
126 153
 
154
+class PageQuerySchema(marshmallow.Schema):
155
+    page = marshmallow.fields.Int(
156
+        example=2,
157
+        default=0,
158
+        description='allow to show a specific page of a pdf file',
159
+        validate=Range(min=0, error="Value must be positive or 0"),
160
+    )
161
+
162
+    @post_load
163
+    def make_page_query(self, data):
164
+        return PageQuery(**data)
165
+
166
+
127 167
 class FilterContentQuerySchema(marshmallow.Schema):
128 168
     parent_id = marshmallow.fields.Int(
129 169
         example=2,