윤창목

Changed signed_url keys from name to id

1 -import mimetypes 1 +import mimetypes
2 -import json 2 +import json
3 -import os 3 +import os
4 -from datetime import datetime 4 +from datetime import datetime, timedelta
5 - 5 +
6 -import boto3 6 +import boto3
7 -from botocore.client import Config 7 +from botocore.client import Config
8 - 8 +
9 -from django.contrib.auth.models import User 9 +from django.core import serializers
10 -from django.core import serializers 10 +from django.views.decorators.csrf import csrf_exempt
11 -from django.views.decorators.csrf import csrf_exempt 11 +from rest_framework import viewsets
12 -from rest_framework import viewsets 12 +from rest_framework import permissions
13 -from rest_framework import permissions 13 +from rest_framework.response import Response
14 -from rest_framework.response import Response 14 +from rest_framework.decorators import action
15 -from rest_framework.decorators import action 15 +from rest_framework.permissions import IsAuthenticated, AllowAny
16 -from rest_framework.permissions import IsAuthenticated, AllowAny 16 +
17 - 17 +from .models import Item, SharedItem, User
18 -from api.models import Item, SharedItem 18 +from .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 21 +from django.conf import settings
22 -from khudrive.settings import AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, AWS_STORAGE_BUCKET_NAME 22 +import jwt
23 - 23 +from django.http import HttpResponse, JsonResponse
24 -class UserViewSet(viewsets.ModelViewSet): 24 +from khudrive.settings import AWS_SESSION_TOKEN, AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, \
25 - """ 25 + AWS_STORAGE_BUCKET_NAME, AWS_ENDPOINT_URL
26 - API endpoint that allows users to be viewed or edited. 26 +
27 - """ 27 +
28 - queryset = User.objects.all().order_by('-date_joined') 28 +class UserViewSet(viewsets.ModelViewSet):
29 - serializer_class = UserSerializer 29 + """
30 - permission_classes = [permissions.IsAuthenticated] 30 + API endpoint that allows users to be viewed or edited.
31 - 31 + """
32 - 32 + queryset = User.objects.all().order_by('-date_joined')
33 -class ItemViewSet(viewsets.ViewSet): 33 + serializer_class = UserSerializer
34 - 34 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
35 - queryset = Item.objects.all() 35 + # IsOwnerOrReadOnly
36 - serializer_class = ItemSerializer 36 + ]
37 - permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny, 37 + permission_classes_by_action = {'get': [permissions.AllowAny],
38 - #IsOwnerOrReadOnly 38 + 'destroy': [permissions.AllowAny]}
39 - ] 39 +
40 - permission_classes_by_action = {'get': [permissions.AllowAny], 40 + @csrf_exempt
41 - 'destroy': [permissions.AllowAny]} 41 + @action(detail=False, methods=['POST'], permission_classes=[permissions.AllowAny], url_path='signup',
42 - 42 + url_name='singup')
43 - # url: items/search 43 + def signup(self, request):
44 - @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search') 44 + user_id = request.POST.get('user_id', '')
45 - def search(self, request): 45 + name = request.POST.get('name', '')
46 - if request.method == 'GET': 46 + password = request.POST.get('password', '')
47 - keyword = request.GET.get('keyword', '') 47 + user = get_object_or_None(User, user_id=user_id)
48 - item_list = Item.objects.filter(name__icontains = keyword) 48 + if user == None:
49 - 49 + user = User(user_id=user_id, name=name, password=password, total_size=100000, current_size=0)
50 - data = serializers.serialize("json", item_list) 50 + user.save()
51 - json_data = json.loads(data) 51 + root = Item(is_folder=True, name="root", file_type="folder", path="", user_id=user.int_id, size=0,
52 - res = [] 52 + status=True)
53 - for i in json_data: 53 + root.save()
54 - t = i['fields'] 54 + user.root_folder = root.item_id
55 - t['id'] = i['pk'] 55 + user.save()
56 - res.append(t) 56 + return Response({
57 - return Response({'data': {'list' : res}}, status=status.HTTP_200_OK) 57 + 'message': 'user created',
58 - """ 58 + 'int_id': user.int_id,
59 - # url: items/11/ 59 + 'user_id': user.user_id,
60 - # 마지막 slash도 써주어야함 60 + 'name': user.name,
61 - def get(self, request, pk): 61 + 'root_folder': root.item_id,
62 - #print(pk) 62 + 'total_size': user.total_size,
63 - s3 = boto3.client('s3') 63 + 'current_size': user.current_size,
64 - s3_bucket = AWS_STORAGE_BUCKET_NAME 64 + 'created_time': user.created_time
65 - 65 + },
66 - #파일 객체 생성 66 + status=status.HTTP_200_OK,
67 - object_name = request.GET.get('name', '') 67 + )
68 - 68 + else:
69 - presigned_url = s3.generate_presigned_url( 69 + return Response({'message': 'user is already exist.'}, status=status.HTTP_204_NO_CONTENT)
70 - 'get_object', 70 +
71 - Params={'Bucket': s3_bucket, 71 + @csrf_exempt
72 - 'Key': object_name}, 72 + @action(methods=['post'], detail=False, permission_classes=[permissions.AllowAny],
73 - ExpiresIn = 3600 73 + url_path='login', url_name='login')
74 - ) 74 + def login(self, request):
75 - 75 + if not request.data:
76 - return Response({'message': presigned_url}, status=status.HTTP_200_OK) 76 + return Response({'Error': "Please provide user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
77 - """ 77 + user_id = request.POST['user_id']
78 - # url: items/11/ 78 + password = request.POST['password']
79 - # 마지막 slash도 써주어야함 79 + try:
80 - def get(self, request, pk): 80 + user = User.objects.get(user_id=user_id, password=password)
81 - s3 = boto3.client('s3', 81 + except User.DoesNotExist:
82 - aws_access_key_id=AWS_ACCESS_KEY_ID, 82 + return Response({'Error': "Invalid user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
83 - aws_secret_access_key=AWS_SECRET_ACCESS_KEY, 83 + if user:
84 - aws_session_token=AWS_SESSION_TOKEN, 84 + payload1 = {
85 - config=Config(signature_version='s3v4')) 85 + 'int_id': user.int_id,
86 - s3_bucket = AWS_STORAGE_BUCKET_NAME 86 + 'user_id': user.user_id,
87 - 87 + 'exp': datetime.utcnow() + timedelta(seconds=300)
88 - item = Item.objects.filter(item_id=pk) 88 + }
89 - object_name = item.get().name 89 + payload2 = {
90 - data = serializers.serialize("json", item) 90 + 'int_id': user.int_id,
91 - json_data = json.loads(data) 91 + 'user_id': user.user_id,
92 - 92 + 'exp': datetime.utcnow() + timedelta(days=5)
93 - presigned_url = s3.generate_presigned_url( 93 + }
94 - 'get_object', 94 + access = jwt.encode(payload1, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
95 - Params={'Bucket': s3_bucket, 95 + refresh = jwt.encode(payload2, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
96 - 'Key': object_name}, 96 + exp = jwt.decode(access, settings.SECRET_KEY, algorithm='HS256')['exp']
97 - ExpiresIn = 3600 97 + token = {'access': access,
98 - ) 98 + 'refresh': refresh,
99 - 99 + 'exp': exp,
100 - res = json_data[0]['fields'] 100 + 'user': {
101 - res['id']=json_data[0]['pk'] 101 + 'int_id': user.int_id,
102 - res['signed_url']=presigned_url 102 + 'user_id': user.user_id,
103 - return Response({'data': res}, status=status.HTTP_200_OK) 103 + 'name': user.name,
104 - 104 + 'total_size': user.total_size,
105 - # url: items/11/ 105 + 'current_size': user.current_size,
106 - # 마지막 slash도 써주어야함 106 + 'root_folder': user.root_folder
107 - def destroy(self, request, pk): 107 + }}
108 - if request.method == 'DELETE': 108 + return JsonResponse(
109 - print(pk) 109 + token,
110 - item = get_object_or_None(Item, item_id=pk) 110 + status=status.HTTP_200_OK,
111 - if item != None: 111 + )
112 - if item.is_folder == True: # 폴더는 삭제 안되도록 처리 112 + else:
113 - return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK) 113 + return JsonResponse(
114 - item.is_deleted = True 114 + {'Error': "Invalid credentials"},
115 - item.save() 115 + status=status.HTTP_400_BAD_REQUEST,
116 - # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록! 116 + )
117 - return Response({'message': 'delete complete'},status=status.HTTP_200_OK) 117 + return JsonResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
118 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT) 118 +
119 - 119 + def get(self, request, pk):
120 - # url: items/11/move 120 + user = User.objects.filter(int_id=pk)
121 - # 마지막 slash도 써주어야함 121 + data = serializers.serialize("json", user)
122 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move') 122 + json_data = json.loads(data)
123 - def move(self, request, pk): 123 + res = json_data[0]['fields']
124 - if request.method == 'POST': 124 + res['id'] = json_data[0]['pk']
125 - parent_id = request.POST.get('parent', '') 125 + return Response({'data': res}, status=status.HTTP_200_OK)
126 - name = request.POST.get('name','') 126 +
127 - parent = get_object_or_None(Item, item_id=parent_id) 127 + def get_permissions(self):
128 - if parent != None and parent.is_folder == True: 128 + try:
129 - child = get_object_or_None(Item, item_id=pk) 129 + # return permission_classes depending on `action`
130 - if child == None: 130 + return [permission() for permission in self.permission_classes_by_action[self.action]]
131 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT) 131 + except KeyError:
132 - child.parent = parent_id 132 + # action is not set return default permission_classes
133 - child.save() 133 + return [permission() for permission in self.permission_classes]
134 - child = Item.objects.filter(item_id = pk) 134 +
135 - child_data = serializers.serialize("json", child) 135 +
136 - json_child = json.loads(child_data) 136 +class ItemViewSet(viewsets.ViewSet):
137 - res = json_child[0]['fields'] 137 + queryset = Item.objects.all()
138 - res['id'] = pk 138 + serializer_class = ItemSerializer
139 - parent = Item.objects.filter(item_id = parent_id) 139 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
140 - parent_data = serializers.serialize("json", parent) 140 + # IsOwnerOrReadOnly
141 - json_parent = json.loads(parent_data)[0]['fields'] 141 + ]
142 - res['parentInfo'] = json_parent 142 + permission_classes_by_action = {'get': [permissions.AllowAny],
143 - return Response({'data': res}, status=status.HTTP_200_OK) 143 + 'destroy': [permissions.AllowAny]}
144 - if parent == None: 144 +
145 - return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK) 145 + # url: items/search
146 - if parent.is_folder == False: 146 + @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search')
147 - return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK) 147 + def search(self, request):
148 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT) 148 + if request.method == 'GET':
149 - 149 + keyword = request.GET.get('keyword', '')
150 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy') 150 + # user_id = request.GET.get('user_id', '')
151 - def copy(self, request, pk): 151 + item_list = Item.objects.filter(name__icontains=keyword)
152 - if request.method == 'POST': 152 +
153 - parent_id = request.POST.get('parent', '') 153 + data = serializers.serialize("json", item_list)
154 - parent = get_object_or_None(Item, item_id=parent_id) 154 + json_data = json.loads(data)
155 - if parent != None and parent.is_folder == True: 155 + res = []
156 - child = get_object_or_None(Item, item_id=pk) 156 + for i in json_data:
157 - if child == None: 157 + t = i['fields']
158 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT) 158 + t['id'] = i['pk']
159 - if child.is_folder == True: 159 + res.append(t)
160 - return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT) 160 + return Response({'data': {'list': res}}, status=status.HTTP_200_OK)
161 - copiedName = child.name + "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M')) 161 +
162 - copiedItem = Item(is_folder = False, name = copiedName, path =child.path, parent = parent_id, user_id= child.user_id, size=child.size, status=child.status) 162 + """
163 - copiedItem.save() 163 + # url: items/11/
164 - 164 + # 마지막 slash도 써주어야함
165 - copiedItem = Item.objects.filter(name = copiedName) 165 + def get(self, request, pk):
166 - copied_data = serializers.serialize("json", copiedItem) 166 + #print(pk)
167 - json_data = json.loads(copied_data) 167 + s3 = boto3.client('s3')
168 - res = json_data[0]['fields'] 168 + s3_bucket = AWS_STORAGE_BUCKET_NAME
169 - res['id'] = json_data[0]['pk'] 169 +
170 - parent = Item.objects.filter(item_id = parent_id) 170 + #파일 객체 생성
171 - parent_data = serializers.serialize("json", parent) 171 + object_name = request.GET.get('name', '')
172 - json_parent = json.loads(parent_data)[0]['fields'] 172 +
173 - res['parentInfo'] = json_parent 173 + presigned_url = s3.generate_presigned_url(
174 - return Response({'data': res}, status=status.HTTP_200_OK) 174 + 'get_object',
175 - if parent == None: 175 + Params={'Bucket': s3_bucket,
176 - return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK) 176 + 'Key': object_name},
177 - if parent.is_folder == False: 177 + ExpiresIn = 3600
178 - return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK) 178 + )
179 - return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT) 179 +
180 - 180 + return Response({'message': presigned_url}, status=status.HTTP_200_OK)
181 - def get_permissions(self): 181 + """
182 - try: 182 +
183 - # return permission_classes depending on `action` 183 + # url: items/11/
184 - return [permission() for permission in self.permission_classes_by_action[self.action]] 184 + # 마지막 slash도 써주어야함
185 - except KeyError: 185 + def get(self, request, pk):
186 - # action is not set return default permission_classes 186 + s3 = boto3.client(
187 - return [permission() for permission in self.permission_classes] 187 + 's3',
188 - 188 + region_name=AWS_REGION,
189 - #url: items/{key}/children/ 189 + aws_access_key_id=AWS_ACCESS_KEY_ID,
190 - @action(methods=['GET', 'POST'], detail=True, permission_classes=[AllowAny], 190 + aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
191 - url_path='children', url_name='children') 191 + aws_session_token=AWS_SESSION_TOKEN,
192 - def children(self, request, pk, *args, **kwargs): 192 + endpoint_url=AWS_ENDPOINT_URL or None,
193 - if request.method == 'GET': 193 + config=Config(s3={'addressing_style': 'path'})
194 - parent_item = Item.objects.get(item_id = pk) 194 + )
195 - try: 195 + s3_bucket = AWS_STORAGE_BUCKET_NAME
196 - parent_item = get_object_or_404(Item, pk = pk) 196 +
197 - except parent_item.DoesNotExist: 197 + item = Item.objects.filter(item_id=pk)
198 - return Response({'Error': 'Folder does not exist.'}) 198 + object_id = item.get().item_id
199 - items = Item.objects.get(parent = parent_item.pk) 199 + data = serializers.serialize("json", item)
200 - return Response(items, status=status.HTTP_200_OK) 200 + json_data = json.loads(data)
201 - 201 +
202 - if request.method == 'POST': 202 + presigned_url = s3.generate_presigned_url(
203 - data = JSONParser().parse(request) 203 + 'get_object',
204 - serializer = ItemSerializer(data=data) 204 + Params={'Bucket': s3_bucket,
205 - if serializer.is_valid(): 205 + 'Key': object_id},
206 - serializer.save() 206 + ExpiresIn=3600
207 - return Response(serializer.data, status=status.HTTP_200_OK) 207 + )
208 - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 208 +
209 - 209 + res = json_data[0]['fields']
210 - # url: /upload/ 210 + res['id'] = json_data[0]['pk']
211 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], 211 + res['signed_url'] = presigned_url
212 - url_path='upload', url_name='upload') 212 + return Response({'data': res}, status=status.HTTP_200_OK)
213 - def upload(self, request, pk): 213 +
214 - if request.method == 'POST': 214 + # url: items/11/
215 - s3 = boto3.client('s3') 215 + # 마지막 slash도 써주어야함
216 - s3_bucket = AWS_STORAGE_BUCKET_NAME 216 + def destroy(self, request, pk):
217 - 217 + if request.method == 'DELETE':
218 - #파일 객체 생성 218 + item = get_object_or_None(Item, item_id=pk)
219 - file_name = request.POST.get('name', '') 219 + if item != None:
220 - file_size = request.POST.get('size', '') 220 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
221 - file_parent = pk 221 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
222 - file_type = mimetypes.guess_type(file_name)[0] 222 + item.is_deleted = True
223 - upload_item = Item(name=file_name, size=file_size, user_id=1, file_type=file_type, parent=file_parent) 223 + item.save()
224 - upload_item.save() 224 + # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록!
225 - 225 + return Response({'message': 'destroy complete'}, status=status.HTTP_200_OK)
226 - date_long = datetime.utcnow().strftime('%Y%m%dT000000Z') 226 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
227 - 227 +
228 - presigned_post = s3.generate_presigned_post( 228 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='restore', url_name='restore')
229 - s3_bucket, 229 + def restore(self, request, pk):
230 - file_name, 230 + if request.method == 'POST':
231 - { 231 + item = get_object_or_None(Item, item_id=pk)
232 - "acl": "private", 232 + if item != None:
233 - "Content-Type": file_type, 233 + item.is_deleted = False
234 - 'region': AWS_REGION, 234 + item.save()
235 - 'x-amz-algorithm': 'AWS4-HMAC-SHA256', 235 + return Response({'message': 'restore complete'}, status=status.HTTP_200_OK)
236 - 'x-amz-date': date_long 236 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
237 - }, 237 +
238 - [ 238 + @action(methods=['DELETE'], detail=True, permission_classes=[AllowAny], url_path='delete', url_name='delete')
239 - {"acl": "private"}, 239 + def delete(self, request, pk):
240 - {"Content-Type": file_type}, 240 + if request.method == 'DELETE':
241 - {'x-amz-algorithm': 'AWS4-HMAC-SHA256'}, 241 + item = get_object_or_None(Item, item_id=pk)
242 - {'x-amz-date': date_long} 242 + if item != None:
243 - ], 243 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
244 - 3600 244 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
245 - ) 245 + item.delete()
246 - 246 + return Response({'message': 'delete permanently complete'}, status=status.HTTP_200_OK)
247 - data = { 247 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
248 - "signed_url": presigned_post, 248 +
249 - 'url': 'https://%s.s3.amazonaws.com/%s' % (s3_bucket, file_name) 249 +
250 - } 250 + # url: items/11/move
251 - 251 + # 마지막 slash도 써주어야함
252 - return Response({'presigned_post':presigned_post, 'proc_data':data}, status=status.HTTP_200_OK) 252 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move')
253 - 253 + def move(self, request, pk):
254 - # url: /status/ 254 + if request.method == 'POST':
255 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], 255 + parent_id = request.POST.get('parent', '')
256 - url_path='status', url_name='status') 256 + name = request.POST.get('name','')
257 - def status(self, request, *args, **kwargs): 257 + child = get_object_or_None(Item, item_id=pk)
258 - if request.method == 'POST': 258 +
259 - pk = request.POST.get('item_id', '') 259 + if child == None:
260 - queryset = Item.objects.filter(item_id = pk) 260 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
261 - for cand in queryset: 261 +
262 - cand.status = True 262 + if parent_id != '':
263 - cand.save() 263 + parent = get_object_or_None(Item, item_id=parent_id)
264 - return Response({'Message': 'File Upload Successful'}, status=status.HTTP_200_OK) 264 +
265 - return Response({'Error': 'No such item found in queryset'}, status=status.HTTP_400_BAD_REQUEST) 265 + if parent == None:
266 - 266 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
267 - 267 + if parent.is_folder == False:
268 - 268 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
269 - 269 +
270 - 270 + if parent != None and parent.is_folder == True:
271 -class SharedItemViewSet(viewsets.ModelViewSet): 271 + child.parent = parent_id
272 - 272 + else:
273 - queryset = SharedItem.objects.all() 273 + parent_id = child.parent
274 - # serializer_class = SharedItemSerializer 274 +
275 - permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny, 275 + if name != '':
276 - # IsOwnerOrReadOnly 276 + child.name = name;
277 - ] 277 +
278 - # url: http://localhost:8000/items/1/share/ 278 + child.save()
279 - # 마지막 slash도 써주어야함 279 + child = Item.objects.filter(item_id = pk)
280 - @csrf_exempt 280 + child_data = serializers.serialize("json", child)
281 - @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='share', url_name='share') 281 + json_child = json.loads(child_data)
282 - def share(self, request, pk): 282 + res = json_child[0]['fields']
283 - if request.method == 'POST': 283 + res['id'] = pk
284 - password = request.POST.get('password', '') 284 + parent = Item.objects.filter(item_id = parent_id)
285 - expires = request.POST.get('expires', '') 285 + parent_data = serializers.serialize("json", parent)
286 - 286 + json_parent = json.loads(parent_data)[0]['fields']
287 - sharedfile = get_object_or_None(SharedItem, item_id=pk) 287 + res['parentInfo'] = json_parent
288 - if sharedfile != None: 288 +
289 - # 서버는 정상이나 이미 공유객체로 등록된 파일임 289 + return Response({'data': res}, status=status.HTTP_200_OK)
290 - return Response({'message': 'This file is already shared'}, status=status.HTTP_200_OK) 290 +
291 - sharedfile = SharedItem(item_id =pk, password=password, expires = expires) 291 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy')
292 - sharedfile.save() 292 + def copy(self, request, pk):
293 - sharedfile = SharedItem.objects.get(item_id = pk) 293 + if request.method == 'POST':
294 - 294 + parent_id = request.POST.get('parent', '')
295 - # sf = serializers.serialize("json", sharedfile) 295 + parent = get_object_or_None(Item, item_id=parent_id)
296 - item = Item.objects.filter(item_id = pk) 296 + if parent != None and parent.is_folder == True:
297 - item_json = serializers.serialize("json", item) 297 + child = get_object_or_None(Item, item_id=pk)
298 - 298 + if child == None:
299 - json_data = json.loads(item_json) 299 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
300 - print(json_data) 300 + if child.is_folder == True:
301 - res = json_data[0]['fields'] 301 + return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT)
302 - res['id'] = json_data[0]['pk'] 302 + copiedName = child.name + "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M'))
303 - return Response({"shared": sharedfile.created_time , 'data': res}, status=status.HTTP_200_OK) 303 + copiedItem = Item(is_folder=False, name=copiedName, path=child.path, parent=parent_id,
304 - 304 + user_id=child.user_id, size=child.size, status=child.status)
305 -item = ItemViewSet.as_view({ 305 + copiedItem.save()
306 - 'delete': 'destroy', 306 +
307 -}) 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_id,
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_id),
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 +})
......