Showing
1 changed file
with
494 additions
and
307 deletions
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 | +}) | ... | ... |
-
Please register or login to post a comment