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 combo.urls_utils import decorated_includes, manager_required
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
from . import api_views
|
||||||
|
|
||||||
assets_manager_urls = [
|
assets_manager_urls = [
|
||||||
url(r'^$', views.assets, name='combo-manager-assets'),
|
url(r'^$', views.assets, name='combo-manager-assets'),
|
||||||
|
@ -35,4 +36,7 @@ urlpatterns = [
|
||||||
url(r'^assets/(?P<key>[\w_:-]+)$', views.serve_asset),
|
url(r'^assets/(?P<key>[\w_:-]+)$', views.serve_asset),
|
||||||
url(r'^manage/assets/', decorated_includes(manager_required,
|
url(r'^manage/assets/', decorated_includes(manager_required,
|
||||||
include(assets_manager_urls))),
|
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