assets: add basic API to upload an asset from wcs (#22391)
This commit is contained in:
parent
d782655ff4
commit
e375bf09e8
|
@ -0,0 +1,64 @@
|
|||
# combo - content management system
|
||||
# Copyright (C) 2019 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import base64
|
||||
|
||||
from django.core.files import File
|
||||
from django.utils.six import BytesIO
|
||||
|
||||
from rest_framework import serializers, permissions, status
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.response import Response
|
||||
|
||||
from .models import Asset
|
||||
|
||||
|
||||
class FileSerializer(serializers.Serializer):
|
||||
content = serializers.CharField(required=True, allow_blank=False)
|
||||
content_type = serializers.CharField(required=False, allow_null=True)
|
||||
filename = serializers.CharField(required=False, allow_null=True)
|
||||
|
||||
def validate_content(self, value):
|
||||
try:
|
||||
return base64.decodestring(value.encode('ascii'))
|
||||
except Exception as e:
|
||||
raise serializers.ValidationError('content must be base64 (%r)' % e)
|
||||
|
||||
|
||||
class AssetSerializer(serializers.Serializer):
|
||||
asset = FileSerializer(required=True)
|
||||
|
||||
|
||||
class Set(GenericAPIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = AssetSerializer
|
||||
|
||||
def post(self, request, key, *args, **kwargs):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
if not serializer.is_valid():
|
||||
response = {'err': 1, 'err_desc': serializer.errors}
|
||||
return Response(response, status.HTTP_400_BAD_REQUEST)
|
||||
data = serializer.validated_data
|
||||
|
||||
asset, created = Asset.objects.get_or_create(key=key)
|
||||
asset.asset = File(
|
||||
BytesIO(data['asset']['content']),
|
||||
name=data['asset'].get('filename'))
|
||||
asset.save()
|
||||
response = {'err': 0}
|
||||
return Response(response)
|
||||
|
||||
view_set = Set.as_view()
|
|
@ -19,6 +19,7 @@ from django.conf.urls import url, include
|
|||
from combo.urls_utils import decorated_includes, manager_required
|
||||
|
||||
from . import views
|
||||
from . import api_views
|
||||
|
||||
assets_manager_urls = [
|
||||
url(r'^$', views.assets, name='combo-manager-assets'),
|
||||
|
@ -35,4 +36,7 @@ urlpatterns = [
|
|||
url(r'^assets/(?P<key>[\w_:-]+)$', views.serve_asset),
|
||||
url(r'^manage/assets/', decorated_includes(manager_required,
|
||||
include(assets_manager_urls))),
|
||||
|
||||
url('^api/assets/set/(?P<key>[\w_:-]+)/$', api_views.view_set,
|
||||
name='api-assets-set'),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import base64
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
import pytest
|
||||
|
||||
from combo.apps.assets.models import Asset
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
def test_asset_set_api(app, john_doe):
|
||||
app.authorization = ('Basic', (john_doe.username, john_doe.username))
|
||||
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={
|
||||
'asset': {
|
||||
'content': base64.encodestring(b'plop').decode('ascii'),
|
||||
'content_type': 'text/plain',
|
||||
'filename': 'plop.txt',
|
||||
}
|
||||
})
|
||||
assert Asset.objects.get(key='plop').asset.read() == b'plop'
|
||||
|
||||
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={
|
||||
'asset': {
|
||||
'content': base64.encodestring(b'plop2').decode('ascii'),
|
||||
'content_type': 'text/plain',
|
||||
'filename': 'plop.txt',
|
||||
}
|
||||
})
|
||||
assert Asset.objects.get(key='plop').asset.read() == b'plop2'
|
||||
|
||||
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={}, status=400)
|
||||
assert resp.json.get('err') == 1
|
||||
|
||||
for invalid_value in (None, 'not base 64', u'éléphant'):
|
||||
resp = app.post_json(reverse('api-assets-set', kwargs={'key': 'plop'}), params={
|
||||
'asset': {
|
||||
'content': invalid_value,
|
||||
'content_type': 'text/plain',
|
||||
'filename': 'plop.txt',
|
||||
}
|
||||
}, status=400)
|
||||
assert resp.json.get('err') == 1
|
Loading…
Reference in New Issue