models: status default, views: upload;status;get-presigned_url, settings:AWS con…
…figuration(secret), urls added
Showing
5 changed files
with
126 additions
and
10 deletions
... | @@ -14,7 +14,7 @@ class Item(models.Model): | ... | @@ -14,7 +14,7 @@ class Item(models.Model): |
14 | is_deleted = models.BooleanField(default = False) | 14 | is_deleted = models.BooleanField(default = False) |
15 | created_time = models.DateTimeField(auto_now=True) | 15 | created_time = models.DateTimeField(auto_now=True) |
16 | updated_time = models.DateTimeField(null=True) | 16 | updated_time = models.DateTimeField(null=True) |
17 | - status = models.BooleanField() | 17 | + status = models.BooleanField(default=False) |
18 | 18 | ||
19 | #file = models.FileField(upload_to = \path) | 19 | #file = models.FileField(upload_to = \path) |
20 | 20 | ... | ... |
... | @@ -4,6 +4,7 @@ import os | ... | @@ -4,6 +4,7 @@ import os |
4 | from datetime import datetime | 4 | from datetime import datetime |
5 | 5 | ||
6 | import boto3 | 6 | import boto3 |
7 | +from botocore.client import Config | ||
7 | 8 | ||
8 | from django.contrib.auth.models import User | 9 | from django.contrib.auth.models import User |
9 | from django.core import serializers | 10 | from django.core import serializers |
... | @@ -18,6 +19,7 @@ from api.models import Item, SharedItem | ... | @@ -18,6 +19,7 @@ from api.models import Item, SharedItem |
18 | from api.serializers import UserSerializer,GroupSerializer,ItemSerializer | 19 | from api.serializers import UserSerializer,GroupSerializer,ItemSerializer |
19 | from rest_framework import status | 20 | from rest_framework import status |
20 | from annoying.functions import get_object_or_None | 21 | from annoying.functions import get_object_or_None |
22 | +from khudrive.settings import AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, AWS_STORAGE_BUCKET_NAME | ||
21 | 23 | ||
22 | class UserViewSet(viewsets.ModelViewSet): | 24 | class UserViewSet(viewsets.ModelViewSet): |
23 | """ | 25 | """ |
... | @@ -53,12 +55,52 @@ class ItemViewSet(viewsets.ViewSet): | ... | @@ -53,12 +55,52 @@ class ItemViewSet(viewsets.ViewSet): |
53 | t['id'] = i['pk'] | 55 | t['id'] = i['pk'] |
54 | res.append(t) | 56 | res.append(t) |
55 | return Response({'data': {'list' : res}}, status=status.HTTP_200_OK) | 57 | return Response({'data': {'list' : res}}, status=status.HTTP_200_OK) |
58 | + """ | ||
59 | + # url: items/11/ | ||
60 | + # 마지막 slash도 써주어야함 | ||
61 | + def get(self, request, pk): | ||
62 | + #print(pk) | ||
63 | + s3 = boto3.client('s3') | ||
64 | + s3_bucket = AWS_STORAGE_BUCKET_NAME | ||
56 | 65 | ||
66 | + #파일 객체 생성 | ||
67 | + object_name = request.GET.get('name', '') | ||
68 | + | ||
69 | + presigned_url = s3.generate_presigned_url( | ||
70 | + 'get_object', | ||
71 | + Params={'Bucket': s3_bucket, | ||
72 | + 'Key': object_name}, | ||
73 | + ExpiresIn = 3600 | ||
74 | + ) | ||
75 | + | ||
76 | + return Response({'message': presigned_url}, status=status.HTTP_200_OK) | ||
77 | + """ | ||
57 | # url: items/11/ | 78 | # url: items/11/ |
58 | # 마지막 slash도 써주어야함 | 79 | # 마지막 slash도 써주어야함 |
59 | def get(self, request, pk): | 80 | def get(self, request, pk): |
60 | - print(pk) | 81 | + s3 = boto3.client('s3', |
61 | - return Response({'message': "info complete"}, status=status.HTTP_200_OK) | 82 | + aws_access_key_id=AWS_ACCESS_KEY_ID, |
83 | + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, | ||
84 | + aws_session_token=AWS_SESSION_TOKEN, | ||
85 | + config=Config(signature_version='s3v4')) | ||
86 | + s3_bucket = AWS_STORAGE_BUCKET_NAME | ||
87 | + | ||
88 | + item = Item.objects.filter(item_id=pk) | ||
89 | + object_name = item.get().name | ||
90 | + data = serializers.serialize("json", item) | ||
91 | + json_data = json.loads(data) | ||
92 | + | ||
93 | + presigned_url = s3.generate_presigned_url( | ||
94 | + 'get_object', | ||
95 | + Params={'Bucket': s3_bucket, | ||
96 | + 'Key': object_name}, | ||
97 | + ExpiresIn = 3600 | ||
98 | + ) | ||
99 | + | ||
100 | + res = json_data[0]['fields'] | ||
101 | + res['id']=json_data[0]['pk'] | ||
102 | + res['signed_url']=presigned_url | ||
103 | + return Response({'data': res}, status=status.HTTP_200_OK) | ||
62 | 104 | ||
63 | # url: items/11/ | 105 | # url: items/11/ |
64 | # 마지막 slash도 써주어야함 | 106 | # 마지막 slash도 써주어야함 |
... | @@ -149,21 +191,78 @@ class ItemViewSet(viewsets.ViewSet): | ... | @@ -149,21 +191,78 @@ class ItemViewSet(viewsets.ViewSet): |
149 | url_path='children', url_name='children') | 191 | url_path='children', url_name='children') |
150 | def children(self, request, pk, *args, **kwargs): | 192 | def children(self, request, pk, *args, **kwargs): |
151 | if request.method == 'GET': | 193 | if request.method == 'GET': |
152 | - parent_item = Item.objects.get(pk = pk) | 194 | + parent_item = Item.objects.get(item_id = pk) |
153 | try: | 195 | try: |
154 | parent_item = get_object_or_404(Item, pk = pk) | 196 | parent_item = get_object_or_404(Item, pk = pk) |
155 | except parent_item.DoesNotExist: | 197 | except parent_item.DoesNotExist: |
156 | return Response({'Error': 'Folder does not exist.'}) | 198 | return Response({'Error': 'Folder does not exist.'}) |
157 | items = Item.objects.get(parent = parent_item.pk) | 199 | items = Item.objects.get(parent = parent_item.pk) |
158 | - return Response(items) | 200 | + return Response(items, status=status.HTTP_200_OK) |
159 | 201 | ||
160 | if request.method == 'POST': | 202 | if request.method == 'POST': |
161 | data = JSONParser().parse(request) | 203 | data = JSONParser().parse(request) |
162 | serializer = ItemSerializer(data=data) | 204 | serializer = ItemSerializer(data=data) |
163 | if serializer.is_valid(): | 205 | if serializer.is_valid(): |
164 | serializer.save() | 206 | serializer.save() |
165 | - return Response(serializer.data) | 207 | + return Response(serializer.data, status=status.HTTP_200_OK) |
166 | - return Response(serializer.errors) | 208 | + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
209 | + | ||
210 | + # url: /upload/ | ||
211 | + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], | ||
212 | + url_path='upload', url_name='upload') | ||
213 | + def upload(self, request, pk): | ||
214 | + if request.method == 'POST': | ||
215 | + s3 = boto3.client('s3') | ||
216 | + s3_bucket = AWS_STORAGE_BUCKET_NAME | ||
217 | + | ||
218 | + #파일 객체 생성 | ||
219 | + file_name = request.POST.get('name', '') | ||
220 | + file_size = request.POST.get('size', '') | ||
221 | + file_parent = pk | ||
222 | + file_type = mimetypes.guess_type(file_name)[0] | ||
223 | + upload_item = Item(name=file_name, size=file_size, user_id=1, file_type=file_type, parent=file_parent) | ||
224 | + upload_item.save() | ||
225 | + | ||
226 | + date_long = datetime.utcnow().strftime('%Y%m%dT000000Z') | ||
227 | + | ||
228 | + presigned_post = s3.generate_presigned_post( | ||
229 | + s3_bucket, | ||
230 | + file_name, | ||
231 | + { | ||
232 | + "acl": "private", | ||
233 | + "Content-Type": file_type, | ||
234 | + 'region': AWS_REGION, | ||
235 | + 'x-amz-algorithm': 'AWS4-HMAC-SHA256', | ||
236 | + 'x-amz-date': date_long | ||
237 | + }, | ||
238 | + [ | ||
239 | + {"acl": "private"}, | ||
240 | + {"Content-Type": file_type}, | ||
241 | + {'x-amz-algorithm': 'AWS4-HMAC-SHA256'}, | ||
242 | + {'x-amz-date': date_long} | ||
243 | + ], | ||
244 | + 3600 | ||
245 | + ) | ||
246 | + | ||
247 | + data = { | ||
248 | + "signed_url": presigned_post, | ||
249 | + 'url': 'https://%s.s3.amazonaws.com/%s' % (s3_bucket, file_name) | ||
250 | + } | ||
251 | + | ||
252 | + return Response({'presigned_post':presigned_post, 'proc_data':data}, status=status.HTTP_200_OK) | ||
253 | + | ||
254 | + # url: /status/ | ||
255 | + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], | ||
256 | + url_path='status', url_name='status') | ||
257 | + def status(self, request, *args, **kwargs): | ||
258 | + if request.method == 'POST': | ||
259 | + pk = request.POST.get('item_id', '') | ||
260 | + queryset = Item.objects.filter(item_id = pk) | ||
261 | + for cand in queryset: | ||
262 | + cand.status = True | ||
263 | + cand.save() | ||
264 | + return Response({'Message': 'File Upload Successful'}, status=status.HTTP_200_OK) | ||
265 | + return Response({'Error': 'No such item found in queryset'}, status=status.HTTP_400_BAD_REQUEST) | ||
167 | 266 | ||
168 | 267 | ||
169 | 268 | ... | ... |
... | @@ -11,10 +11,17 @@ https://docs.djangoproject.com/en/3.0/ref/settings/ | ... | @@ -11,10 +11,17 @@ https://docs.djangoproject.com/en/3.0/ref/settings/ |
11 | """ | 11 | """ |
12 | 12 | ||
13 | import os | 13 | import os |
14 | +import sys | ||
15 | +import json | ||
14 | 16 | ||
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) | 17 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) |
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 18 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
17 | 19 | ||
20 | +ROOT_DIR = os.path.dirname(BASE_DIR) | ||
21 | +# secrets.json의 경로 | ||
22 | +SECRETS_PATH = os.path.join(ROOT_DIR, 'secrets.json') | ||
23 | +# json파일을 파이썬 객체로 변환 | ||
24 | +secrets = json.loads(open(SECRETS_PATH).read()) | ||
18 | 25 | ||
19 | # Quick-start development settings - unsuitable for production | 26 | # Quick-start development settings - unsuitable for production |
20 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ | 27 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ |
... | @@ -82,8 +89,8 @@ DATABASES = { | ... | @@ -82,8 +89,8 @@ DATABASES = { |
82 | 'default': { | 89 | 'default': { |
83 | 'ENGINE': 'django.db.backends.postgresql', | 90 | 'ENGINE': 'django.db.backends.postgresql', |
84 | 'NAME': 'khuDrive', | 91 | 'NAME': 'khuDrive', |
85 | - 'USER': 'jooheekwon', | 92 | + 'USER': 'root', |
86 | - 'PASSWORD': '', | 93 | + 'PASSWORD': '1234', |
87 | 'HOST': 'localhost', | 94 | 'HOST': 'localhost', |
88 | 'PORT': '', | 95 | 'PORT': '', |
89 | } | 96 | } |
... | @@ -127,3 +134,11 @@ USE_TZ = True | ... | @@ -127,3 +134,11 @@ USE_TZ = True |
127 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ | 134 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ |
128 | 135 | ||
129 | STATIC_URL = '/static/' | 136 | STATIC_URL = '/static/' |
137 | + | ||
138 | + | ||
139 | +#S3 | ||
140 | +DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' | ||
141 | +STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' | ||
142 | + | ||
143 | +for key, value in secrets.items(): | ||
144 | + setattr(sys.modules[__name__], key, value) | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -34,5 +34,6 @@ urlpatterns = [ | ... | @@ -34,5 +34,6 @@ urlpatterns = [ |
34 | url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'), | 34 | url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'), |
35 | url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'), | 35 | url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'), |
36 | url(r'^children/$', views.ItemViewSet.children, name='children'), | 36 | url(r'^children/$', views.ItemViewSet.children, name='children'), |
37 | - | 37 | + url(r'^upload/$', views.ItemViewSet.upload, name='upload'), |
38 | + url(r'^status/$', views.ItemViewSet.status, name='status'), | ||
38 | ] | 39 | ] | ... | ... |
-
Please register or login to post a comment