윤창목

models: status default, views: upload;status;get-presigned_url, settings:AWS con…

…figuration(secret), urls added
...@@ -27,3 +27,4 @@ npm-debug.log* ...@@ -27,3 +27,4 @@ npm-debug.log*
27 yarn-debug.log* 27 yarn-debug.log*
28 yarn-error.log* 28 yarn-error.log*
29 .idea 29 .idea
30 +secrets.json
......
...@@ -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 ]
......