Merge branch 'feature/#10' into feature/user
kairos03/2018-1-d.cloud#10
Showing
9 changed files
with
109 additions
and
44 deletions
... | @@ -23,7 +23,6 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ... | @@ -23,7 +23,6 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
23 | SECRET_KEY = '534f6m=i@*)=q3kuwlge1m3c+@^cabr3ttcx*omv^+dorydjfr' | 23 | SECRET_KEY = '534f6m=i@*)=q3kuwlge1m3c+@^cabr3ttcx*omv^+dorydjfr' |
24 | 24 | ||
25 | # SECURITY WARNING: don't run with debug turned on in production! | 25 | # SECURITY WARNING: don't run with debug turned on in production! |
26 | -# TODO | ||
27 | DEBUG = True | 26 | DEBUG = True |
28 | 27 | ||
29 | ALLOWED_HOSTS = [] | 28 | ALLOWED_HOSTS = [] |
... | @@ -107,7 +106,7 @@ AUTH_PASSWORD_VALIDATORS = [ | ... | @@ -107,7 +106,7 @@ AUTH_PASSWORD_VALIDATORS = [ |
107 | # Internationalization | 106 | # Internationalization |
108 | # https://docs.djangoproject.com/en/2.0/topics/i18n/ | 107 | # https://docs.djangoproject.com/en/2.0/topics/i18n/ |
109 | 108 | ||
110 | -LANGUAGE_CODE = 'en-us' | 109 | +LANGUAGE_CODE = 'ko_kr' |
111 | 110 | ||
112 | TIME_ZONE = 'UTC' | 111 | TIME_ZONE = 'UTC' |
113 | 112 | ... | ... |
... | @@ -2,11 +2,11 @@ from django.contrib import admin | ... | @@ -2,11 +2,11 @@ from django.contrib import admin |
2 | from django.conf.urls import url, include | 2 | from django.conf.urls import url, include |
3 | from django.contrib.auth import views | 3 | from django.contrib.auth import views |
4 | 4 | ||
5 | - | ||
6 | urlpatterns = [ | 5 | urlpatterns = [ |
7 | url(r'^admin/', admin.site.urls), | 6 | url(r'^admin/', admin.site.urls), |
8 | url(r'^accounts/login/$', views.login, name='login'), | 7 | url(r'^accounts/login/$', views.login, name='login'), |
9 | url(r'^accounts/logout/$', views.logout, name='logout', kwargs={'next_page': '/'}), | 8 | url(r'^accounts/logout/$', views.logout, name='logout', kwargs={'next_page': '/'}), |
10 | url(r'^restapi/', include('restful.urls')), | 9 | url(r'^restapi/', include('restful.urls')), |
11 | url(r'^', include('website.urls')), | 10 | url(r'^', include('website.urls')), |
12 | -] | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
11 | +] | ||
12 | + | ... | ... |
dcloud/rest_mig.sh
0 → 100755
1 | from django.db import models | 1 | from django.db import models |
2 | 2 | ||
3 | - | ||
4 | # Create your models here. | 3 | # Create your models here. |
5 | class File(models.Model): | 4 | class File(models.Model): |
6 | created = models.DateTimeField(auto_now_add=True) | 5 | created = models.DateTimeField(auto_now_add=True) |
7 | modified = models.DateTimeField(auto_now=True) | 6 | modified = models.DateTimeField(auto_now=True) |
8 | title = models.CharField(max_length=100) | 7 | title = models.CharField(max_length=100) |
9 | # file_name = models.CharField(max_length=100, primary_key=True) | 8 | # file_name = models.CharField(max_length=100, primary_key=True) |
9 | + | ||
10 | object_key = models.CharField(max_length=1025) | 10 | object_key = models.CharField(max_length=1025) |
11 | - size = models.IntegerField() | ||
12 | # owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE) | 11 | # owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE) |
13 | 12 | ||
14 | class Meta: | 13 | class Meta: |
15 | - ordering = ('title',) | 14 | + ordering = ('pk',) |
16 | - | ||
17 | - | ... | ... |
dcloud/restful/s3_interface.py
0 → 100644
1 | +import boto3 | ||
2 | +import json | ||
3 | + | ||
4 | +S3 = boto3.client('s3') | ||
5 | +BUCKET = '2018-dcloud' | ||
6 | + | ||
7 | + | ||
8 | +def list_path(bucket, user, path): | ||
9 | + | ||
10 | + files = [] | ||
11 | + # get list | ||
12 | + objects = S3.list_objects(Bucket=bucket, Prefix='{}/{}'.format(user, path), Delimiter='/') | ||
13 | + | ||
14 | + # get sub directorys | ||
15 | + common_prefixes = objects.get('CommonPrefixes') | ||
16 | + if common_prefixes: | ||
17 | + for obj in common_prefixes: | ||
18 | + files.append({'type':'diretory', 'name':obj.get('Prefix').split('/')[-2]}) | ||
19 | + | ||
20 | + # get files | ||
21 | + contents = objects.get('Contents') | ||
22 | + if contents: | ||
23 | + for obj in contents: | ||
24 | + file = obj.get('Key').split('/')[-1] | ||
25 | + if file != '': | ||
26 | + files.append({'type':'file', 'name':file}) | ||
27 | + | ||
28 | + return {'files':files} | ||
29 | + | ||
30 | +# print(list_path(BUCKET, 'test1', '')) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -3,30 +3,8 @@ from rest_framework import serializers | ... | @@ -3,30 +3,8 @@ from rest_framework import serializers |
3 | from restful.models import File | 3 | from restful.models import File |
4 | 4 | ||
5 | 5 | ||
6 | -class FileSerializer(serializers.Serializer): | 6 | +class FileSerializer(serializers.ModelSerializer): |
7 | - pk = serializers.IntegerField(read_only=True) | ||
8 | - created = serializers.DateTimeField(read_only=True) | ||
9 | - modified = serializers.DateTimeField(read_only=True) | ||
10 | - title = serializers.CharField(max_length=100) | ||
11 | - object_key = serializers.CharField(max_length=1025) | ||
12 | - size = serializers.IntegerField() | ||
13 | 7 | ||
14 | - | 8 | + class Meta: |
15 | - def create(self, validated_data): | 9 | + model = File |
16 | - """ | 10 | + fields = ('created', 'updated', 'object_key') |
17 | - Create and Return new `File` instance. Using validated_data. | ||
18 | - """ | ||
19 | - return File.objects.create(**validated_data) | ||
20 | - | ||
21 | - | ||
22 | - def update(self, instance, validated_data): | ||
23 | - """ | ||
24 | - Update and Return existing `File` instance. Using validated_data. | ||
25 | - """ | ||
26 | - instance.title = validated_data.get('title', instance.title) | ||
27 | - instance.object_key = validated_data.get('object_key', instance.object_key) | ||
28 | - instance.size = validated_data.get('size', instance.size) | ||
29 | - instance.language = validated_data.get('language', instance.language) | ||
30 | - instance.style = validated_data.get('style', instance.style) | ||
31 | - instance.save() | ||
32 | - return instance | ... | ... |
1 | -from django.test import TestCase | 1 | +from rest_framework.test import APITestCase |
2 | +from django.urls import reverse | ||
3 | +from rest_framework import status | ||
4 | +from restful.models import File | ||
2 | 5 | ||
3 | -# Create your tests here. | 6 | + |
7 | +class FileListTestCase(APITestCase): | ||
8 | + | ||
9 | + def setUp(self): | ||
10 | + self.tearDown() | ||
11 | + | ||
12 | + def tearDown(self): | ||
13 | + pass | ||
14 | + | ||
15 | + def test_upload(self): | ||
16 | + url = reverse('file-list') | ||
17 | + data = {'object_key': 'test_object_key'} | ||
18 | + response = self.client.post(url, data) | ||
19 | + self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||
20 | + self.assertEqual(File.objects.count(), 1) | ||
21 | + | ||
22 | + def test_list(self): | ||
23 | + url = reverse('file-list') | ||
24 | + response = self.client.get(url) | ||
25 | + self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
26 | + | ||
27 | + | ||
28 | +class FileDetailTestCase(APITestCase): | ||
29 | + | ||
30 | + def setUp(self): | ||
31 | + self.tearDown() | ||
32 | + File.objects.create(object_key='test_object') | ||
33 | + | ||
34 | + def tearDown(self): | ||
35 | + File.objects.all().delete() | ||
36 | + | ||
37 | + def test_delete(self): | ||
38 | + url = reverse('file-detail', kwargs={'pk' : 1 }) | ||
39 | + response = self.client.delete(url) | ||
40 | + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) | ||
41 | + | ||
42 | + def test_update(self): | ||
43 | + url = reverse('file-detail', kwargs={'pk' : 1 }) | ||
44 | + response = self.client.put(url, {"object_key":"test_update"}) | ||
45 | + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) | ||
46 | + | ||
47 | + def test_retrieve(self): | ||
48 | + url = reverse('file-detail', kwargs={'pk' : 1 }) | ||
49 | + response = self.client.get(url) | ||
50 | + self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
51 | + | ||
52 | + | ||
53 | + | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | from django.conf.urls import url | 1 | from django.conf.urls import url |
2 | +from django.shortcuts import redirect | ||
2 | from rest_framework.urlpatterns import format_suffix_patterns | 3 | from rest_framework.urlpatterns import format_suffix_patterns |
3 | from restful import views | 4 | from restful import views |
4 | 5 | ||
5 | urlpatterns = [ | 6 | urlpatterns = [ |
6 | - url(r'^files/$', views.FileList.as_view()), | 7 | + url(r'^files/(?P<path>([a-zA-z0-9가-힣._-]*/)*)$', views.FileList.as_view(), name='file-list'), |
7 | url(r'^files/(?P<pk>[0-9]+)/$', views.FileDetail.as_view()), | 8 | url(r'^files/(?P<pk>[0-9]+)/$', views.FileDetail.as_view()), |
8 | ] | 9 | ] |
9 | 10 | ... | ... |
... | @@ -3,6 +3,7 @@ from django.contrib.auth.decorators import login_required | ... | @@ -3,6 +3,7 @@ from django.contrib.auth.decorators import login_required |
3 | from rest_framework.views import APIView | 3 | from rest_framework.views import APIView |
4 | from rest_framework.response import Response | 4 | from rest_framework.response import Response |
5 | from rest_framework import status | 5 | from rest_framework import status |
6 | +from restful import s3_interface | ||
6 | 7 | ||
7 | from restful.models import File | 8 | from restful.models import File |
8 | from restful.serializers import FileSerializer | 9 | from restful.serializers import FileSerializer |
... | @@ -12,10 +13,14 @@ class FileList(APIView): | ... | @@ -12,10 +13,14 @@ class FileList(APIView): |
12 | List all file, or create a new snippet. | 13 | List all file, or create a new snippet. |
13 | """ | 14 | """ |
14 | 15 | ||
15 | - def get(self, request, format=None): | 16 | + def get(self, request, path='/', format=None): |
16 | - file = File.objects.all() | 17 | + # file = File.objects.all() |
17 | - serializer = FileSerializer(file, many=True) | 18 | + # serializer = FileSerializer(file, many=True) |
18 | - return Response(serializer.data) | 19 | + # print(serializer.data) |
20 | + # return Response(serializer.data) | ||
21 | + data = s3_interface.list_path(s3_interface.BUCKET, 'test1', path) | ||
22 | + return Response(data) | ||
23 | + | ||
19 | 24 | ||
20 | def post(self, request, format=None): | 25 | def post(self, request, format=None): |
21 | serializer = FileSerializer(data=request.data) | 26 | serializer = FileSerializer(data=request.data) |
... | @@ -38,14 +43,14 @@ class FileDetail(APIView): | ... | @@ -38,14 +43,14 @@ class FileDetail(APIView): |
38 | def get(self, request, pk, format=None): | 43 | def get(self, request, pk, format=None): |
39 | file = self.get_object(pk) | 44 | file = self.get_object(pk) |
40 | serializer = FileSerializer(file) | 45 | serializer = FileSerializer(file) |
41 | - return Response(serializer.data) | 46 | + return Response(serializer.data, status=status.HTTP_200_OK) |
42 | 47 | ||
43 | def put(self, request, pk, format=None): | 48 | def put(self, request, pk, format=None): |
44 | file = self.get_object(pk) | 49 | file = self.get_object(pk) |
45 | serializer = FileSerializer(file, data=request.data) | 50 | serializer = FileSerializer(file, data=request.data) |
46 | if serializer.is_valid(): | 51 | if serializer.is_valid(): |
47 | serializer.save() | 52 | serializer.save() |
48 | - return Response(serializer.data) | 53 | + return Response(serializer.data, status=status.HTTP_204_NO_CONTENT) |
49 | return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) | 54 | return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
50 | 55 | ||
51 | def delete(self, request, pk, format=None): | 56 | def delete(self, request, pk, format=None): | ... | ... |
-
Please register or login to post a comment