김재형

Merge branch 'develop'

1 -import mimetypes
2 -import json
3 -import os
4 -from datetime import datetime, timedelta
5 -
6 -import boto3
7 -from botocore.client import Config
8 -
9 -from django.core import serializers
10 -from django.views.decorators.csrf import csrf_exempt
11 -from rest_framework import viewsets
12 -from rest_framework import permissions
13 -from rest_framework.response import Response
14 -from rest_framework.decorators import action
15 -from rest_framework.permissions import IsAuthenticated, AllowAny
16 -
17 -from .models import Item, SharedItem, User
18 -from .serializers import UserSerializer, GroupSerializer, ItemSerializer
19 -from rest_framework import status
20 -from annoying.functions import get_object_or_None
21 -from django.conf import settings
22 -import jwt
23 -from django.http import HttpResponse, JsonResponse
24 -from khudrive.settings import AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, \
25 - AWS_STORAGE_BUCKET_NAME, AWS_ENDPOINT_URL
26 -
27 -
28 -class UserViewSet(viewsets.ModelViewSet):
29 - """
30 - API endpoint that allows users to be viewed or edited.
31 - """
32 - queryset = User.objects.all().order_by('-date_joined')
33 - serializer_class = UserSerializer
34 - permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
35 - # IsOwnerOrReadOnly
36 - ]
37 - permission_classes_by_action = {'get': [permissions.AllowAny],
38 - 'destroy': [permissions.AllowAny]}
39 -
40 - @csrf_exempt
41 - @action(detail=False, methods=['POST'], permission_classes=[permissions.AllowAny], url_path='signup',
42 - url_name='singup')
43 - def signup(self, request):
44 - user_id = request.POST.get('user_id', '')
45 - name = request.POST.get('name', '')
46 - password = request.POST.get('password', '')
47 - user = get_object_or_None(User, user_id=user_id)
48 - if user == None:
49 - user = User(user_id=user_id, name=name, password=password, total_size=100000, current_size=0)
50 - user.save()
51 - root = Item(is_folder=True, name="root", file_type="folder", path="", user_id=user.int_id, size=0,
52 - status=True)
53 - root.save()
54 - user.root_folder = root.item_id
55 - user.save()
56 - return Response({
57 - 'message': 'user created',
58 - 'int_id': user.int_id,
59 - 'user_id': user.user_id,
60 - 'name': user.name,
61 - 'root_folder': root.item_id,
62 - 'total_size': user.total_size,
63 - 'current_size': user.current_size,
64 - 'created_time': user.created_time
65 - },
66 - status=status.HTTP_200_OK,
67 - )
68 - else:
69 - return Response({'message': 'user is already exist.'}, status=status.HTTP_204_NO_CONTENT)
70 -
71 - @csrf_exempt
72 - @action(methods=['post'], detail=False, permission_classes=[permissions.AllowAny],
73 - url_path='login', url_name='login')
74 - def login(self, request):
75 - if not request.data:
76 - return Response({'Error': "Please provide user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
77 - user_id = request.POST['user_id']
78 - password = request.POST['password']
79 - try:
80 - user = User.objects.get(user_id=user_id, password=password)
81 - except User.DoesNotExist:
82 - return Response({'Error': "Invalid user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
83 - if user:
84 - payload1 = {
85 - 'int_id': user.int_id,
86 - 'user_id': user.user_id,
87 - 'exp': datetime.utcnow() + timedelta(seconds=300)
88 - }
89 - payload2 = {
90 - 'int_id': user.int_id,
91 - 'user_id': user.user_id,
92 - 'exp': datetime.utcnow() + timedelta(days=5)
93 - }
94 - access = jwt.encode(payload1, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
95 - refresh = jwt.encode(payload2, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
96 - exp = jwt.decode(access, settings.SECRET_KEY, algorithm='HS256')['exp']
97 - token = {'access': access,
98 - 'refresh': refresh,
99 - 'exp': exp,
100 - 'user': {
101 - 'int_id': user.int_id,
102 - 'user_id': user.user_id,
103 - 'name': user.name,
104 - 'total_size': user.total_size,
105 - 'current_size': user.current_size,
106 - 'root_folder': user.root_folder
107 - }}
108 - return JsonResponse(
109 - token,
110 - status=status.HTTP_200_OK,
111 - )
112 - else:
113 - return JsonResponse(
114 - {'Error': "Invalid credentials"},
115 - status=status.HTTP_400_BAD_REQUEST,
116 - )
117 - return JsonResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
118 -
119 - def get(self, request, pk):
120 - user = User.objects.filter(int_id=pk)
121 - data = serializers.serialize("json", user)
122 - json_data = json.loads(data)
123 - res = json_data[0]['fields']
124 - res['id'] = json_data[0]['pk']
125 - return Response({'data': res}, status=status.HTTP_200_OK)
126 -
127 - def get_permissions(self):
128 - try:
129 - # return permission_classes depending on `action`
130 - return [permission() for permission in self.permission_classes_by_action[self.action]]
131 - except KeyError:
132 - # action is not set return default permission_classes
133 - return [permission() for permission in self.permission_classes]
134 -
135 -
136 -class ItemViewSet(viewsets.ViewSet):
137 - queryset = Item.objects.all()
138 - serializer_class = ItemSerializer
139 - permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
140 - # IsOwnerOrReadOnly
141 - ]
142 - permission_classes_by_action = {'get': [permissions.AllowAny],
143 - 'destroy': [permissions.AllowAny]}
144 -
145 - # url: items/search
146 - @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search')
147 - def search(self, request):
148 - if request.method == 'GET':
149 - keyword = request.GET.get('keyword', '')
150 - # user_id = request.GET.get('user_id', '')
151 - item_list = Item.objects.filter(name__icontains=keyword)
152 -
153 - data = serializers.serialize("json", item_list)
154 - json_data = json.loads(data)
155 - res = []
156 - for i in json_data:
157 - t = i['fields']
158 - t['id'] = i['pk']
159 - res.append(t)
160 - return Response({'data': {'list': res}}, status=status.HTTP_200_OK)
161 -
162 - """
163 - # url: items/11/
164 - # 마지막 slash도 써주어야함
165 - def get(self, request, pk):
166 - #print(pk)
167 - s3 = boto3.client('s3')
168 - s3_bucket = AWS_STORAGE_BUCKET_NAME
169 -
170 - #파일 객체 생성
171 - object_name = request.GET.get('name', '')
172 -
173 - presigned_url = s3.generate_presigned_url(
174 - 'get_object',
175 - Params={'Bucket': s3_bucket,
176 - 'Key': object_name},
177 - ExpiresIn = 3600
178 - )
179 -
180 - return Response({'message': presigned_url}, status=status.HTTP_200_OK)
181 - """
182 -
183 - # url: items/11/
184 - # 마지막 slash도 써주어야함
185 - def get(self, request, pk):
186 - s3 = boto3.client(
187 - 's3',
188 - region_name=AWS_REGION,
189 - aws_access_key_id=AWS_ACCESS_KEY_ID,
190 - aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
191 - aws_session_token=AWS_SESSION_TOKEN,
192 - endpoint_url=AWS_ENDPOINT_URL or None,
193 - config=Config(s3={'addressing_style': 'path'})
194 - )
195 - s3_bucket = AWS_STORAGE_BUCKET_NAME
196 -
197 - item = Item.objects.filter(item_id=pk)
198 - object_name = item.get().name
199 - data = serializers.serialize("json", item)
200 - json_data = json.loads(data)
201 -
202 - presigned_url = s3.generate_presigned_url(
203 - 'get_object',
204 - Params={'Bucket': s3_bucket,
205 - 'Key': object_name},
206 - ExpiresIn=3600
207 - )
208 -
209 - res = json_data[0]['fields']
210 - res['id'] = json_data[0]['pk']
211 - res['signed_url'] = presigned_url
212 - return Response({'data': res}, status=status.HTTP_200_OK)
213 -
214 - # url: items/11/
215 - # 마지막 slash도 써주어야함
216 - def destroy(self, request, pk):
217 - if request.method == 'DELETE':
218 - item = get_object_or_None(Item, item_id=pk)
219 - if item != None:
220 - if item.is_folder == True: # 폴더는 삭제 안되도록 처리
221 - return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
222 - item.is_deleted = True
223 - item.save()
224 - # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록!
225 - return Response({'message': 'destroy complete'}, status=status.HTTP_200_OK)
226 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
227 -
228 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='restore', url_name='restore')
229 - def restore(self, request, pk):
230 - if request.method == 'POST':
231 - item = get_object_or_None(Item, item_id=pk)
232 - if item != None:
233 - item.is_deleted = False
234 - item.save()
235 - return Response({'message': 'restore complete'}, status=status.HTTP_200_OK)
236 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
237 -
238 - @action(methods=['DELETE'], detail=True, permission_classes=[AllowAny], url_path='delete', url_name='delete')
239 - def delete(self, request, pk):
240 - if request.method == 'DELETE':
241 - item = get_object_or_None(Item, item_id=pk)
242 - if item != None:
243 - if item.is_folder == True: # 폴더는 삭제 안되도록 처리
244 - return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
245 - item.delete()
246 - return Response({'message': 'delete permanently complete'}, status=status.HTTP_200_OK)
247 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
248 -
249 -
250 - # url: items/11/move
251 - # 마지막 slash도 써주어야함
252 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move')
253 - def move(self, request, pk):
254 - if request.method == 'POST':
255 - parent_id = request.POST.get('parent', '')
256 - name = request.POST.get('name','')
257 - child = get_object_or_None(Item, item_id=pk)
258 -
259 - if child == None:
260 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
261 -
262 - if parent_id != '':
263 - parent = get_object_or_None(Item, item_id=parent_id)
264 -
265 - if parent == None:
266 - return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
267 - if parent.is_folder == False:
268 - return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
269 -
270 - if parent != None and parent.is_folder == True:
271 - child.parent = parent_id
272 - else:
273 - parent_id = child.parent
274 -
275 - if name != '':
276 - child.name = name;
277 -
278 - child.save()
279 - child = Item.objects.filter(item_id = pk)
280 - child_data = serializers.serialize("json", child)
281 - json_child = json.loads(child_data)
282 - res = json_child[0]['fields']
283 - res['id'] = pk
284 - parent = Item.objects.filter(item_id = parent_id)
285 - parent_data = serializers.serialize("json", parent)
286 - json_parent = json.loads(parent_data)[0]['fields']
287 - res['parentInfo'] = json_parent
288 -
289 - return Response({'data': res}, status=status.HTTP_200_OK)
290 -
291 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy')
292 - def copy(self, request, pk):
293 - if request.method == 'POST':
294 - parent_id = request.POST.get('parent', '')
295 - parent = get_object_or_None(Item, item_id=parent_id)
296 - if parent != None and parent.is_folder == True:
297 - child = get_object_or_None(Item, item_id=pk)
298 - if child == None:
299 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
300 - if child.is_folder == True:
301 - return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT)
302 - copiedName = child.name + "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M'))
303 - copiedItem = Item(is_folder=False, name=copiedName, path=child.path, parent=parent_id,
304 - user_id=child.user_id, size=child.size, status=child.status)
305 - copiedItem.save()
306 -
307 - copiedItem = Item.objects.filter(name=copiedName)
308 - copied_data = serializers.serialize("json", copiedItem)
309 - json_data = json.loads(copied_data)
310 - res = json_data[0]['fields']
311 - res['id'] = json_data[0]['pk']
312 - parent = Item.objects.filter(item_id=parent_id)
313 - parent_data = serializers.serialize("json", parent)
314 - json_parent = json.loads(parent_data)[0]['fields']
315 - res['parentInfo'] = json_parent
316 - return Response({'data': res}, status=status.HTTP_200_OK)
317 - if parent == None:
318 - return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
319 - if parent.is_folder == False:
320 - return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
321 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
322 -
323 - def get_permissions(self):
324 - try:
325 - # return permission_classes depending on `action`
326 - return [permission() for permission in self.permission_classes_by_action[self.action]]
327 - except KeyError:
328 - # action is not set return default permission_classes
329 - return [permission() for permission in self.permission_classes]
330 -
331 - # url: items/{key}/children/
332 - @action(methods=['GET', 'POST'], detail=True, permission_classes=[AllowAny],
333 - url_path='children', url_name='children')
334 - def children(self, request, pk):
335 - if request.method == 'GET':
336 - children = Item.objects.filter(parent=pk, is_deleted=False, status=True)
337 - children_data = serializers.serialize("json", children)
338 - json_children = json.loads(children_data)
339 - parent = Item.objects.filter(item_id=pk) # item
340 - parent_data = serializers.serialize("json", parent)
341 - json_parent = json.loads(parent_data)[0]['fields']
342 - res = json_parent
343 - res['id'] = pk
344 - children_list = []
345 - for i in json_children:
346 - t = i['fields']
347 - t['id'] = i['pk']
348 - children_list.append(t)
349 - res['list'] = children_list
350 - return Response({'data': res}, status=status.HTTP_200_OK)
351 - if request.method == 'POST':
352 - name = request.POST.get('name', '')
353 - user_id = request.GET.get('user_id', '')
354 - item = Item(is_folder=True, name=name, file_type="folder", path="", parent=pk, user_id=user_id, size=0,
355 - status=True)
356 - item.save()
357 - item = Item.objects.filter(item_id=item.item_id)
358 - item_data = serializers.serialize("json", item)
359 - json_item = json.loads(item_data)
360 - res = json_item[0]['fields']
361 - res['id'] = json_item[0]['pk']
362 - res['inside_folder_list'] = []
363 - res['inside_file_list'] = []
364 - return Response({'data': res}, status=status.HTTP_200_OK)
365 -
366 - @action(methods=['GET'], detail=False, permission_classes=[AllowAny],
367 - url_path='trash', url_name='trash')
368 - def trash(self, request):
369 - if request.method == 'GET':
370 - children = Item.objects.filter(is_deleted = True)
371 - children_data = serializers.serialize("json", children)
372 - json_children = json.loads(children_data)
373 - res = {}
374 - children_list = []
375 - for i in json_children:
376 - t = i['fields']
377 - t['id'] = i['pk']
378 - children_list.append(t)
379 - res['list'] = children_list
380 - return Response({'data': res}, status=status.HTTP_200_OK)
381 -
382 - # url: /upload/
383 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
384 - url_path='upload', url_name='upload')
385 - def upload(self, request, pk):
386 - if request.method == 'POST':
387 - s3 = boto3.client(
388 - 's3',
389 - region_name=AWS_REGION,
390 - aws_access_key_id=AWS_ACCESS_KEY_ID,
391 - aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
392 - aws_session_token=AWS_SESSION_TOKEN,
393 - endpoint_url=AWS_ENDPOINT_URL or None,
394 - config=Config(s3={'addressing_style': 'path'})
395 - )
396 - s3_bucket = AWS_STORAGE_BUCKET_NAME
397 -
398 - # 파일 객체 생성
399 - file_name = request.POST.get('name', '')
400 - file_size = request.POST.get('size', '')
401 - file_parent = pk
402 - file_type = mimetypes.guess_type(file_name)[0]
403 - upload_item = Item(name=file_name, size=file_size, user_id=1, file_type=file_type, parent=file_parent)
404 - upload_item.save()
405 -
406 - date_long = datetime.utcnow().strftime('%Y%m%dT000000Z')
407 -
408 - presigned_post = s3.generate_presigned_post(
409 - s3_bucket,
410 - file_name,
411 - {
412 - "acl": "private",
413 - "Content-Type": file_type,
414 - "Content-Disposition": "attachment",
415 - 'region': AWS_REGION,
416 - 'x-amz-algorithm': 'AWS4-HMAC-SHA256',
417 - 'x-amz-date': date_long
418 - },
419 - [
420 - {"acl": "private"},
421 - {"Content-Type": file_type},
422 - {"Content-Disposition": "attachment"},
423 - {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
424 - {'x-amz-date': date_long}
425 - ],
426 - 3600
427 - )
428 -
429 - item = Item.objects.filter(item_id=upload_item.item_id)
430 - item_data = serializers.serialize("json", item)
431 - json_item = json.loads(item_data)
432 - res = json_item[0]['fields']
433 - res['id'] = json_item[0]['pk']
434 -
435 - data = {
436 - "signed_url": presigned_post,
437 - 'url': '%s/%s' % (presigned_post["url"], file_name),
438 - 'item': res
439 - }
440 -
441 - return Response(data, status=status.HTTP_200_OK)
442 -
443 - # url: /status/
444 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
445 - url_path='status', url_name='status')
446 - def status(self, request, *args, **kwargs):
447 - if request.method == 'POST':
448 - pk = request.POST.get('item_id', '')
449 - queryset = Item.objects.filter(item_id=pk)
450 - for cand in queryset:
451 - cand.status = True
452 - cand.save()
453 - return Response({'Message': 'File Upload Successful'}, status=status.HTTP_200_OK)
454 - return Response({'Error': 'No such item found in queryset'}, status=status.HTTP_400_BAD_REQUEST)
455 -
456 -
457 -class SharedItemViewSet(viewsets.ModelViewSet):
458 - queryset = SharedItem.objects.all()
459 - # serializer_class = SharedItemSerializer
460 - permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
461 - # IsOwnerOrReadOnly
462 - ]
463 -
464 - # url: http://localhost:8000/items/1/share/
465 - # 마지막 slash도 써주어야함
466 - @csrf_exempt
467 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='share', url_name='share')
468 - def share(self, request, pk):
469 - if request.method == 'POST':
470 - password = request.POST.get('password', '')
471 - expires = request.POST.get('expires', '')
472 -
473 - sharedfile = get_object_or_None(SharedItem, item_id=pk)
474 - if sharedfile != None:
475 - # 서버는 정상이나 이미 공유객체로 등록된 파일임
476 - return Response({'message': 'This file is already shared'}, status=status.HTTP_200_OK)
477 - sharedfile = SharedItem(item_id=pk, password=password, expires=expires)
478 - sharedfile.save()
479 - sharedfile = SharedItem.objects.get(item_id=pk)
480 -
481 - # sf = serializers.serialize("json", sharedfile)
482 - item = Item.objects.filter(item_id=pk)
483 - item_json = serializers.serialize("json", item)
484 -
485 - json_data = json.loads(item_json)
486 - print(json_data)
487 - res = json_data[0]['fields']
488 - res['id'] = json_data[0]['pk']
489 - return Response({"shared": sharedfile.created_time, 'data': res}, status=status.HTTP_200_OK)
490 -
491 -
492 -item = ItemViewSet.as_view({
493 - 'delete': 'destroy',
494 -})
...\ No newline at end of file ...\ No newline at end of file
1 +import mimetypes
2 +import json
3 +import os
4 +from datetime import datetime, timedelta
5 +
6 +import boto3
7 +from botocore.client import Config
8 +
9 +from django.core import serializers
10 +from django.views.decorators.csrf import csrf_exempt
11 +from rest_framework import viewsets
12 +from rest_framework import permissions
13 +from rest_framework.response import Response
14 +from rest_framework.decorators import action
15 +from rest_framework.permissions import IsAuthenticated, AllowAny
16 +
17 +from .models import Item, SharedItem, User
18 +from .serializers import UserSerializer, GroupSerializer, ItemSerializer
19 +from rest_framework import status
20 +from annoying.functions import get_object_or_None
21 +from django.conf import settings
22 +import jwt
23 +from django.http import HttpResponse, JsonResponse
24 +from khudrive.settings import AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, \
25 + AWS_STORAGE_BUCKET_NAME, AWS_ENDPOINT_URL
26 +
27 +
28 +class UserViewSet(viewsets.ModelViewSet):
29 + """
30 + API endpoint that allows users to be viewed or edited.
31 + """
32 + queryset = User.objects.all().order_by('-date_joined')
33 + serializer_class = UserSerializer
34 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
35 + # IsOwnerOrReadOnly
36 + ]
37 + permission_classes_by_action = {'get': [permissions.AllowAny],
38 + 'destroy': [permissions.AllowAny]}
39 +
40 + @csrf_exempt
41 + @action(detail=False, methods=['POST'], permission_classes=[permissions.AllowAny], url_path='signup',
42 + url_name='singup')
43 + def signup(self, request):
44 + user_id = request.POST.get('user_id', '')
45 + name = request.POST.get('name', '')
46 + password = request.POST.get('password', '')
47 + user = get_object_or_None(User, user_id=user_id)
48 + if user == None:
49 + user = User(user_id=user_id, name=name, password=password, total_size=100000, current_size=0)
50 + user.save()
51 + root = Item(is_folder=True, name="root", file_type="folder", path="", user_id=user.int_id, size=0,
52 + status=True)
53 + root.save()
54 + user.root_folder = root.item_id
55 + user.save()
56 + return Response({
57 + 'message': 'user created',
58 + 'int_id': user.int_id,
59 + 'user_id': user.user_id,
60 + 'name': user.name,
61 + 'root_folder': root.item_id,
62 + 'total_size': user.total_size,
63 + 'current_size': user.current_size,
64 + 'created_time': user.created_time
65 + },
66 + status=status.HTTP_200_OK,
67 + )
68 + else:
69 + return Response({'message': 'user is already exist.'}, status=status.HTTP_204_NO_CONTENT)
70 +
71 + @csrf_exempt
72 + @action(methods=['post'], detail=False, permission_classes=[permissions.AllowAny],
73 + url_path='login', url_name='login')
74 + def login(self, request):
75 + if not request.data:
76 + return Response({'Error': "Please provide user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
77 + user_id = request.POST['user_id']
78 + password = request.POST['password']
79 + try:
80 + user = User.objects.get(user_id=user_id, password=password)
81 + except User.DoesNotExist:
82 + return Response({'Error': "Invalid user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
83 + if user:
84 + payload1 = {
85 + 'int_id': user.int_id,
86 + 'user_id': user.user_id,
87 + 'exp': datetime.utcnow() + timedelta(seconds=300)
88 + }
89 + payload2 = {
90 + 'int_id': user.int_id,
91 + 'user_id': user.user_id,
92 + 'exp': datetime.utcnow() + timedelta(days=5)
93 + }
94 + access = jwt.encode(payload1, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
95 + refresh = jwt.encode(payload2, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
96 + exp = jwt.decode(access, settings.SECRET_KEY, algorithm='HS256')['exp']
97 + token = {'access': access,
98 + 'refresh': refresh,
99 + 'exp': exp,
100 + 'user': {
101 + 'int_id': user.int_id,
102 + 'user_id': user.user_id,
103 + 'name': user.name,
104 + 'total_size': user.total_size,
105 + 'current_size': user.current_size,
106 + 'root_folder': user.root_folder
107 + }}
108 + return JsonResponse(
109 + token,
110 + status=status.HTTP_200_OK,
111 + )
112 + else:
113 + return JsonResponse(
114 + {'Error': "Invalid credentials"},
115 + status=status.HTTP_400_BAD_REQUEST,
116 + )
117 + return JsonResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
118 +
119 + def get(self, request, pk):
120 + user = User.objects.filter(int_id=pk)
121 + data = serializers.serialize("json", user)
122 + json_data = json.loads(data)
123 + res = json_data[0]['fields']
124 + res['id'] = json_data[0]['pk']
125 + return Response({'data': res}, status=status.HTTP_200_OK)
126 +
127 + def get_permissions(self):
128 + try:
129 + # return permission_classes depending on `action`
130 + return [permission() for permission in self.permission_classes_by_action[self.action]]
131 + except KeyError:
132 + # action is not set return default permission_classes
133 + return [permission() for permission in self.permission_classes]
134 +
135 +
136 +class ItemViewSet(viewsets.ViewSet):
137 + queryset = Item.objects.all()
138 + serializer_class = ItemSerializer
139 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
140 + # IsOwnerOrReadOnly
141 + ]
142 + permission_classes_by_action = {'get': [permissions.AllowAny],
143 + 'destroy': [permissions.AllowAny]}
144 +
145 + # url: items/search
146 + @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search')
147 + def search(self, request):
148 + if request.method == 'GET':
149 + keyword = request.GET.get('keyword', '')
150 + # user_id = request.GET.get('user_id', '')
151 + item_list = Item.objects.filter(name__icontains=keyword)
152 +
153 + data = serializers.serialize("json", item_list)
154 + json_data = json.loads(data)
155 + res = []
156 + for i in json_data:
157 + t = i['fields']
158 + t['id'] = i['pk']
159 + res.append(t)
160 + return Response({'data': {'list': res}}, status=status.HTTP_200_OK)
161 +
162 + """
163 + # url: items/11/
164 + # 마지막 slash도 써주어야함
165 + def get(self, request, pk):
166 + #print(pk)
167 + s3 = boto3.client('s3')
168 + s3_bucket = AWS_STORAGE_BUCKET_NAME
169 +
170 + #파일 객체 생성
171 + object_name = request.GET.get('name', '')
172 +
173 + presigned_url = s3.generate_presigned_url(
174 + 'get_object',
175 + Params={'Bucket': s3_bucket,
176 + 'Key': object_name},
177 + ExpiresIn = 3600
178 + )
179 +
180 + return Response({'message': presigned_url}, status=status.HTTP_200_OK)
181 + """
182 +
183 + # url: items/11/
184 + # 마지막 slash도 써주어야함
185 + def get(self, request, pk):
186 + s3 = boto3.client(
187 + 's3',
188 + region_name=AWS_REGION,
189 + aws_access_key_id=AWS_ACCESS_KEY_ID,
190 + aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
191 + aws_session_token=AWS_SESSION_TOKEN,
192 + endpoint_url=AWS_ENDPOINT_URL or None,
193 + config=Config(s3={'addressing_style': 'path'})
194 + )
195 + s3_bucket = AWS_STORAGE_BUCKET_NAME
196 +
197 + item = Item.objects.filter(item_id=pk)
198 + object_name = str(item.get().item_id)
199 + data = serializers.serialize("json", item)
200 + json_data = json.loads(data)
201 +
202 + presigned_url = s3.generate_presigned_url(
203 + 'get_object',
204 + Params={'Bucket': s3_bucket,
205 + 'Key': object_name},
206 + ExpiresIn=3600
207 + )
208 +
209 + res = json_data[0]['fields']
210 + res['id'] = json_data[0]['pk']
211 + res['signed_url'] = presigned_url
212 + return Response({'data': res}, status=status.HTTP_200_OK)
213 +
214 + # url: items/11/
215 + # 마지막 slash도 써주어야함
216 + def destroy(self, request, pk):
217 + if request.method == 'DELETE':
218 + item = get_object_or_None(Item, item_id=pk)
219 + if item != None:
220 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
221 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
222 + item.is_deleted = True
223 + item.save()
224 + # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록!
225 + return Response({'message': 'destroy complete'}, status=status.HTTP_200_OK)
226 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
227 +
228 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='restore', url_name='restore')
229 + def restore(self, request, pk):
230 + if request.method == 'POST':
231 + item = get_object_or_None(Item, item_id=pk)
232 + if item != None:
233 + item.is_deleted = False
234 + item.save()
235 + return Response({'message': 'restore complete'}, status=status.HTTP_200_OK)
236 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
237 +
238 + @action(methods=['DELETE'], detail=True, permission_classes=[AllowAny], url_path='delete', url_name='delete')
239 + def delete(self, request, pk):
240 + if request.method == 'DELETE':
241 + item = get_object_or_None(Item, item_id=pk)
242 + if item != None:
243 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
244 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
245 + item.delete()
246 + return Response({'message': 'delete permanently complete'}, status=status.HTTP_200_OK)
247 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
248 +
249 +
250 + # url: items/11/move
251 + # 마지막 slash도 써주어야함
252 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move')
253 + def move(self, request, pk):
254 + if request.method == 'POST':
255 + parent_id = request.POST.get('parent', '')
256 + name = request.POST.get('name','')
257 + child = get_object_or_None(Item, item_id=pk)
258 +
259 + if child == None:
260 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
261 +
262 + if parent_id != '':
263 + parent = get_object_or_None(Item, item_id=parent_id)
264 +
265 + if parent == None:
266 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
267 + if parent.is_folder == False:
268 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
269 +
270 + if parent != None and parent.is_folder == True:
271 + child.parent = parent_id
272 + else:
273 + parent_id = child.parent
274 +
275 + if name != '':
276 + child.name = name;
277 +
278 + child.save()
279 + child = Item.objects.filter(item_id = pk)
280 + child_data = serializers.serialize("json", child)
281 + json_child = json.loads(child_data)
282 + res = json_child[0]['fields']
283 + res['id'] = pk
284 + parent = Item.objects.filter(item_id = parent_id)
285 + parent_data = serializers.serialize("json", parent)
286 + json_parent = json.loads(parent_data)[0]['fields']
287 + res['parentInfo'] = json_parent
288 +
289 + return Response({'data': res}, status=status.HTTP_200_OK)
290 +
291 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy')
292 + def copy(self, request, pk):
293 + if request.method == 'POST':
294 + parent_id = request.POST.get('parent', '')
295 + parent = get_object_or_None(Item, item_id=parent_id)
296 + if parent != None and parent.is_folder == True:
297 + child = get_object_or_None(Item, item_id=pk)
298 + if child == None:
299 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
300 + if child.is_folder == True:
301 + return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT)
302 + name = child.name.split(".")
303 + copiedName = name[0]+ "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M'))+"." + name[-1]
304 + copiedItem = Item(is_folder=False, name=copiedName, path=child.path, parent=parent_id,
305 + user_id=child.user_id, size=child.size, status=child.status)
306 + copiedItem.save()
307 +
308 + copiedItem = Item.objects.filter(name=copiedName)
309 + copied_data = serializers.serialize("json", copiedItem)
310 + json_data = json.loads(copied_data)
311 + res = json_data[0]['fields']
312 + res['id'] = json_data[0]['pk']
313 + parent = Item.objects.filter(item_id=parent_id)
314 + parent_data = serializers.serialize("json", parent)
315 + json_parent = json.loads(parent_data)[0]['fields']
316 + res['parentInfo'] = json_parent
317 + return Response({'data': res}, status=status.HTTP_200_OK)
318 + if parent == None:
319 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
320 + if parent.is_folder == False:
321 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
322 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
323 +
324 + def get_permissions(self):
325 + try:
326 + # return permission_classes depending on `action`
327 + return [permission() for permission in self.permission_classes_by_action[self.action]]
328 + except KeyError:
329 + # action is not set return default permission_classes
330 + return [permission() for permission in self.permission_classes]
331 +
332 + # url: items/{key}/children/
333 + @action(methods=['GET', 'POST'], detail=True, permission_classes=[AllowAny],
334 + url_path='children', url_name='children')
335 + def children(self, request, pk):
336 + if request.method == 'GET':
337 + children = Item.objects.filter(parent=pk, is_deleted=False, status=True)
338 + children_data = serializers.serialize("json", children)
339 + json_children = json.loads(children_data)
340 + parent = Item.objects.filter(item_id=pk) # item
341 + parent_data = serializers.serialize("json", parent)
342 + json_parent = json.loads(parent_data)[0]['fields']
343 + res = json_parent
344 + res['id'] = pk
345 + children_list = []
346 + for i in json_children:
347 + t = i['fields']
348 + t['id'] = i['pk']
349 + children_list.append(t)
350 + res['list'] = children_list
351 + return Response({'data': res}, status=status.HTTP_200_OK)
352 + if request.method == 'POST':
353 + name = request.POST.get('name', '')
354 + user_id = request.GET.get('user_id', '')
355 + item = Item(is_folder=True, name=name, file_type="folder", path="", parent=pk, user_id=user_id, size=0,
356 + status=True)
357 + item.save()
358 + item = Item.objects.filter(item_id=item.item_id)
359 + item_data = serializers.serialize("json", item)
360 + json_item = json.loads(item_data)
361 + res = json_item[0]['fields']
362 + res['id'] = json_item[0]['pk']
363 + res['inside_folder_list'] = []
364 + res['inside_file_list'] = []
365 + return Response({'data': res}, status=status.HTTP_200_OK)
366 +
367 + @action(methods=['GET'], detail=False, permission_classes=[AllowAny],
368 + url_path='trash', url_name='trash')
369 + def trash(self, request):
370 + if request.method == 'GET':
371 + children = Item.objects.filter(is_deleted = True)
372 + children_data = serializers.serialize("json", children)
373 + json_children = json.loads(children_data)
374 + res = {}
375 + children_list = []
376 + for i in json_children:
377 + t = i['fields']
378 + t['id'] = i['pk']
379 + children_list.append(t)
380 + res['list'] = children_list
381 + return Response({'data': res}, status=status.HTTP_200_OK)
382 +
383 + # url: /upload/
384 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
385 + url_path='upload', url_name='upload')
386 + def upload(self, request, pk):
387 + if request.method == 'POST':
388 + s3 = boto3.client(
389 + 's3',
390 + region_name=AWS_REGION,
391 + aws_access_key_id=AWS_ACCESS_KEY_ID,
392 + aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
393 + aws_session_token=AWS_SESSION_TOKEN,
394 + endpoint_url=AWS_ENDPOINT_URL or None,
395 + config=Config(s3={'addressing_style': 'path'})
396 + )
397 + s3_bucket = AWS_STORAGE_BUCKET_NAME
398 +
399 + # 파일 객체 생성
400 + file_name = request.POST.get('name', '')
401 + file_size = request.POST.get('size', '')
402 + file_parent = pk
403 + file_type = mimetypes.guess_type(file_name)[0]
404 + upload_item = Item(name=file_name, size=file_size, user_id=1, file_type=file_type, parent=file_parent)
405 + upload_item.save()
406 +
407 + file_id = str(upload_item.item_id)
408 +
409 + date_long = datetime.utcnow().strftime('%Y%m%dT000000Z')
410 +
411 + presigned_post = s3.generate_presigned_post(
412 + s3_bucket,
413 + file_id,
414 + {
415 + "acl": "private",
416 + "Content-Type": file_type,
417 + "Content-Disposition": "attachment",
418 + 'region': AWS_REGION,
419 + 'x-amz-algorithm': 'AWS4-HMAC-SHA256',
420 + 'x-amz-date': date_long
421 + },
422 + [
423 + {"acl": "private"},
424 + {"Content-Type": file_type},
425 + {"Content-Disposition": "attachment"},
426 + {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
427 + {'x-amz-date': date_long}
428 + ],
429 + 3600
430 + )
431 +
432 + item = Item.objects.filter(item_id=upload_item.item_id)
433 + item_data = serializers.serialize("json", item)
434 + json_item = json.loads(item_data)
435 + res = json_item[0]['fields']
436 + res['id'] = json_item[0]['pk']
437 +
438 + data = {
439 + "signed_url": presigned_post,
440 + 'url': '%s/%s' % (presigned_post["url"], file_id),
441 + 'item': res
442 + }
443 +
444 + return Response(data, status=status.HTTP_200_OK)
445 +
446 + # url: /status/
447 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
448 + url_path='status', url_name='status')
449 + def status(self, request, *args, **kwargs):
450 + if request.method == 'POST':
451 + pk = request.POST.get('item_id', '')
452 + queryset = Item.objects.filter(item_id=pk)
453 + for cand in queryset:
454 + cand.status = True
455 + cand.save()
456 + return Response({'Message': 'File Upload Successful'}, status=status.HTTP_200_OK)
457 + return Response({'Error': 'No such item found in queryset'}, status=status.HTTP_400_BAD_REQUEST)
458 +
459 +
460 +class SharedItemViewSet(viewsets.ModelViewSet):
461 + queryset = SharedItem.objects.all()
462 + # serializer_class = SharedItemSerializer
463 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
464 + # IsOwnerOrReadOnly
465 + ]
466 +
467 + # url: http://localhost:8000/items/1/share/
468 + # 마지막 slash도 써주어야함
469 + @csrf_exempt
470 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='share', url_name='share')
471 + def share(self, request, pk):
472 + if request.method == 'POST':
473 + password = request.POST.get('password', '')
474 + expires = request.POST.get('expires', '')
475 +
476 + sharedfile = get_object_or_None(SharedItem, item_id=pk)
477 + if sharedfile != None:
478 + # 서버는 정상이나 이미 공유객체로 등록된 파일임
479 + return Response({'message': 'This file is already shared'}, status=status.HTTP_200_OK)
480 + sharedfile = SharedItem(item_id=pk, password=password, expires=expires)
481 + sharedfile.save()
482 +
483 + # sf = serializers.serialize("json", sharedfile)
484 + item = Item.objects.filter(item_id=pk)
485 + item_json = serializers.serialize("json", item)
486 +
487 + json_data = json.loads(item_json)
488 + print(json_data)
489 + res = json_data[0]['fields']
490 + res['id'] = json_data[0]['pk']
491 + return Response({"shared": sharedfile.pk, 'data': res}, status=status.HTTP_200_OK)
492 +
493 +
494 +item = ItemViewSet.as_view({
495 + 'delete': 'destroy',
496 +})
......