0001-assets-add-basic-API-to-upload-an-asset-from-wcs-223.patch
combo/apps/assets/api_views.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2019 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import base64 |
|
18 | ||
19 |
from django.core.files import File |
|
20 |
from django.utils.six import BytesIO |
|
21 | ||
22 |
from rest_framework import serializers, permissions, status |
|
23 |
from rest_framework.generics import GenericAPIView |
|
24 |
from rest_framework.response import Response |
|
25 | ||
26 |
from .models import Asset |
|
27 | ||
28 | ||
29 |
class FileSerializer(serializers.Serializer): |
|
30 |
content = serializers.CharField(required=True, allow_blank=False) |
|
31 |
content_type = serializers.CharField(required=False, allow_null=True) |
|
32 |
filename = serializers.CharField(required=False, allow_null=True) |
|
33 | ||
34 | ||
35 |
class AssetSerializer(serializers.Serializer): |
|
36 |
asset = FileSerializer(required=True) |
|
37 | ||
38 | ||
39 |
class Set(GenericAPIView): |
|
40 |
permission_classes = (permissions.IsAuthenticated,) |
|
41 |
serializer_class = AssetSerializer |
|
42 | ||
43 |
def post(self, request, key, *args, **kwargs): |
|
44 |
serializer = self.get_serializer(data=request.data) |
|
45 |
if not serializer.is_valid(): |
|
46 |
response = {'err': 1, 'err_desc': serializer.errors} |
|
47 |
return Response(response, status.HTTP_400_BAD_REQUEST) |
|
48 |
data = serializer.validated_data |
|
49 | ||
50 |
asset, created = Asset.objects.get_or_create(key=key) |
|
51 |
asset.asset = File( |
|
52 |
BytesIO(base64.decodestring(data['asset']['content'].encode('ascii'))), |
|
53 |
name=data['asset'].get('filename')) |
|
54 |
asset.save() |
|
55 |
response = {'err': 0} |
|
56 |
return Response(response) |
|
57 | ||
58 |
view_set = Set.as_view() |
combo/apps/assets/urls.py | ||
---|---|---|
19 | 19 |
from combo.urls_utils import decorated_includes, manager_required |
20 | 20 | |
21 | 21 |
from . import views |
22 |
from . import api_views |
|
22 | 23 | |
23 | 24 |
assets_manager_urls = [ |
24 | 25 |
url(r'^$', views.assets, name='combo-manager-assets'), |
... | ... | |
35 | 36 |
url(r'^assets/(?P<key>[\w_:-]+)$', views.serve_asset), |
36 | 37 |
url(r'^manage/assets/', decorated_includes(manager_required, |
37 | 38 |
include(assets_manager_urls))), |
39 | ||
40 |
url('^api/assets/set/(?P<key>[\w_:-]+)/$', api_views.view_set, |
|
41 |
name='api-assets-set'), |
|
38 | 42 |
] |
tests/test_assets.py | ||
---|---|---|
1 |
import base64 |
|
2 | ||
3 |
from django.core.urlresolvers import reverse |
|
4 | ||
5 |
import pytest |
|
6 | ||
7 |
from combo.apps.assets.models import Asset |
|
8 | ||
9 |
pytestmark = pytest.mark.django_db |
|
10 | ||
11 |
def test_asset_set_api(app, john_doe): |
|
12 |
app.authorization = ('Basic', (john_doe.username, john_doe.username)) |
|
13 |
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={ |
|
14 |
'asset': { |
|
15 |
'content': base64.encodestring(b'plop').decode('ascii'), |
|
16 |
'content_type': 'text/plain', |
|
17 |
'filename': 'plop.txt', |
|
18 |
} |
|
19 |
}) |
|
20 |
assert Asset.objects.get(key='plop').asset.read() == b'plop' |
|
21 | ||
22 |
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={ |
|
23 |
'asset': { |
|
24 |
'content': base64.encodestring(b'plop2').decode('ascii'), |
|
25 |
'content_type': 'text/plain', |
|
26 |
'filename': 'plop.txt', |
|
27 |
} |
|
28 |
}) |
|
29 |
assert Asset.objects.get(key='plop').asset.read() == b'plop2' |
|
0 |
- |