권주희

Merge branch 'develop' into 'master'

Develop



See merge request !11
...@@ -26,3 +26,5 @@ __pycache__ ...@@ -26,3 +26,5 @@ __pycache__
26 npm-debug.log* 26 npm-debug.log*
27 yarn-debug.log* 27 yarn-debug.log*
28 yarn-error.log* 28 yarn-error.log*
29 +.idea
30 +secrets.json
......
1 +from django.contrib import admin
2 +
3 +from .models import Item, SharedItem, User
4 +
5 +admin.site.register(Item)
6 +admin.site.register(SharedItem)
7 +admin.site.register(User)
...\ No newline at end of file ...\ No newline at end of file
1 +# Generated by Django 3.0.6 on 2020-06-11 14:54
2 +
3 +from django.db import migrations, models
4 +
5 +
6 +class Migration(migrations.Migration):
7 +
8 + initial = True
9 +
10 + dependencies = [
11 + ]
12 +
13 + operations = [
14 + migrations.CreateModel(
15 + name='Item',
16 + fields=[
17 + ('item_id', models.AutoField(primary_key=True, serialize=False)),
18 + ('is_folder', models.BooleanField(default=False)),
19 + ('name', models.CharField(max_length=50)),
20 + ('file_type', models.CharField(max_length=100, null=True)),
21 + ('path', models.TextField()),
22 + ('parent', models.IntegerField()),
23 + ('user_id', models.IntegerField()),
24 + ('size', models.IntegerField()),
25 + ('is_deleted', models.BooleanField(default=False)),
26 + ('created_time', models.DateTimeField(auto_now=True)),
27 + ('updated_time', models.DateTimeField(null=True)),
28 + ('status', models.BooleanField()),
29 + ],
30 + options={
31 + 'ordering': ['item_id'],
32 + },
33 + ),
34 + migrations.CreateModel(
35 + name='SharedItem',
36 + fields=[
37 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
38 + ('item_id', models.IntegerField()),
39 + ('expires', models.DateTimeField()),
40 + ('password', models.CharField(max_length=20)),
41 + ('created_time', models.DateTimeField(auto_now=True)),
42 + ],
43 + options={
44 + 'ordering': ['item_id'],
45 + },
46 + ),
47 + migrations.CreateModel(
48 + name='User',
49 + fields=[
50 + ('int_id', models.AutoField(primary_key=True, serialize=False)),
51 + ('user_id', models.CharField(max_length=50)),
52 + ('name', models.CharField(max_length=50)),
53 + ('password', models.CharField(max_length=20)),
54 + ('total_size', models.IntegerField()),
55 + ('current_size', models.IntegerField()),
56 + ('created_time', models.DateTimeField(auto_now=True)),
57 + ],
58 + options={
59 + 'ordering': ['int_id'],
60 + },
61 + ),
62 + ]
1 +# Generated by Django 3.0.6 on 2020-06-11 15:29
2 +
3 +from django.db import migrations, models
4 +
5 +
6 +class Migration(migrations.Migration):
7 +
8 + dependencies = [
9 + ('api', '0001_initial'),
10 + ]
11 +
12 + operations = [
13 + migrations.AddField(
14 + model_name='user',
15 + name='root_folder',
16 + field=models.IntegerField(null=True),
17 + ),
18 + migrations.AlterField(
19 + model_name='item',
20 + name='parent',
21 + field=models.IntegerField(null=True),
22 + ),
23 + ]
1 +from django.db import models
2 +
3 +# Create your models here.
4 +class Item(models.Model):
5 + item_id = models.AutoField(primary_key = True)
6 + is_folder = models.BooleanField(default = False)
7 + name = models.CharField(max_length = 50)
8 + file_type = models.CharField(max_length=100, null=True) # signed_url 생성을 위해 file type 세팅
9 + path = models.TextField()
10 + #parent = models.ForeignKey('Item', on_delete=models.CASCADE, null=True) #related_name
11 + parent = models.IntegerField(null=True) # root 폴더의 경우 null임
12 + user_id = models.IntegerField()
13 + size = models.IntegerField()
14 + is_deleted = models.BooleanField(default = False)
15 + created_time = models.DateTimeField(auto_now=True)
16 + updated_time = models.DateTimeField(null=True)
17 + status = models.BooleanField(default=False)
18 +
19 + #file = models.FileField(upload_to = \path)
20 +
21 + class Meta:
22 + ordering = ['item_id']
23 +
24 +
25 +class SharedItem(models.Model):
26 + item_id = models.IntegerField()
27 + #file_id?
28 + expires = models.DateTimeField()
29 + password = models.CharField(max_length = 20)
30 + created_time = models.DateTimeField(auto_now=True)
31 + class Meta:
32 + ordering = ['item_id']
33 +
34 +
35 +class User(models.Model):
36 + int_id = models.AutoField(primary_key = True)
37 + user_id = models.CharField(max_length = 50)
38 + name = models.CharField(max_length = 50)
39 + password = models.CharField(max_length = 20)
40 + root_folder = models.IntegerField(null=True)
41 + total_size = models.IntegerField()
42 + current_size = models.IntegerField()
43 + created_time = models.DateTimeField(auto_now=True)
44 + class Meta:
45 + ordering = ['int_id']
1 +from django.contrib.auth.models import Group
2 +from rest_framework import serializers
3 +from .models import Item, SharedItem,User
4 +
5 +
6 +class UserSerializer(serializers.HyperlinkedModelSerializer):
7 + class Meta:
8 + model = User
9 + fields = '__all__'
10 +
11 +class GroupSerializer(serializers.HyperlinkedModelSerializer):
12 + class Meta:
13 + model = Group
14 + fields = ['url', 'name']
15 +
16 +class ItemSerializer(serializers.ModelSerializer):
17 + class Meta:
18 + model = Item
19 + fields = '__all__'
20 +
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, AWS_STORAGE_BUCKET_NAME
25 +
26 +class UserViewSet(viewsets.ModelViewSet):
27 + """
28 + API endpoint that allows users to be viewed or edited.
29 + """
30 + queryset = User.objects.all().order_by('-date_joined')
31 + serializer_class = UserSerializer
32 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
33 + # IsOwnerOrReadOnly
34 + ]
35 + permission_classes_by_action = {'get': [permissions.AllowAny],
36 + 'destroy': [permissions.AllowAny]}
37 + @csrf_exempt
38 + @action(detail=False, methods=['POST'], permission_classes=[permissions.AllowAny], url_path='signup', url_name='singup')
39 + def signup(self, request):
40 + user_id = request.POST.get('user_id', '')
41 + name = request.POST.get('name', '')
42 + password = request.POST.get('password', '')
43 + user = get_object_or_None(User, user_id=user_id)
44 + if user == None:
45 + user = User(user_id = user_id, name = name, password = password, total_size=100000, current_size = 0)
46 + user.save()
47 + root = Item(is_folder=True, name="root", file_type="folder", path="", user_id=user.int_id, size=0,
48 + status=True)
49 + root.save()
50 + return Response({
51 + 'message': 'user created',
52 + 'int_id': user.int_id,
53 + 'user_id': user.user_id,
54 + 'name': user.name,
55 + 'root_folder':root.item_id,
56 + 'total_size': user.total_size,
57 + 'current_size': user.current_size,
58 + 'created_time': user.created_time
59 + },
60 + status=status.HTTP_200_OK,
61 + )
62 + else:
63 + return Response({'message': 'user is already exist.'}, status=status.HTTP_204_NO_CONTENT)
64 +
65 + @csrf_exempt
66 + @action(methods=['post'], detail=False, permission_classes=[permissions.AllowAny],
67 + url_path='login', url_name='login')
68 + def login(self, request):
69 + if not request.data:
70 + return Response({'Error': "Please provide user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
71 + user_id = request.POST['user_id']
72 + password = request.POST['password']
73 + try:
74 + user = User.objects.get(user_id=user_id, password=password)
75 + except User.DoesNotExist:
76 + return Response({'Error': "Invalid user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
77 + if user:
78 + payload1 = {
79 + 'int_id': user.int_id,
80 + 'user_id': user.user_id,
81 + 'exp': datetime.utcnow() + timedelta(seconds=300)
82 + }
83 + payload2 = {
84 + 'int_id': user.int_id,
85 + 'user_id': user.user_id,
86 + 'exp': datetime.utcnow() + timedelta(days=5)
87 + }
88 + access = jwt.encode(payload1, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
89 + refresh = jwt.encode(payload2, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
90 + exp = jwt.decode(access, settings.SECRET_KEY, algorithm='HS256')['exp']
91 + token = {'access': access,
92 + 'refresh': refresh,
93 + 'exp': exp}
94 + return JsonResponse(
95 + token,
96 + status=status.HTTP_200_OK,
97 + )
98 + else:
99 + return JsonResponse(
100 + {'Error': "Invalid credentials"},
101 + status=status.HTTP_400_BAD_REQUEST,
102 + )
103 + return JsonResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
104 +
105 + def get(self, request, pk):
106 + user = User.objects.filter(int_id=pk)
107 + data = serializers.serialize("json", user)
108 + json_data = json.loads(data)
109 + res = json_data[0]['fields']
110 + res['id']=json_data[0]['pk']
111 + return Response({'data': res}, status=status.HTTP_200_OK)
112 +
113 + def get_permissions(self):
114 + try:
115 + # return permission_classes depending on `action`
116 + return [permission() for permission in self.permission_classes_by_action[self.action]]
117 + except KeyError:
118 + # action is not set return default permission_classes
119 + return [permission() for permission in self.permission_classes]
120 +
121 +
122 +class ItemViewSet(viewsets.ViewSet):
123 +
124 + queryset = Item.objects.all()
125 + serializer_class = ItemSerializer
126 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
127 + #IsOwnerOrReadOnly
128 + ]
129 + permission_classes_by_action = {'get': [permissions.AllowAny],
130 + 'destroy': [permissions.AllowAny]}
131 +
132 + # url: items/search
133 + @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search')
134 + def search(self, request):
135 + if request.method == 'GET':
136 + keyword = request.GET.get('keyword', '')
137 + user_id = request.GET.get('user_id', '')
138 + item_list = Item.objects.filter(name__icontains = keyword, user_id = user_id )
139 +
140 + data = serializers.serialize("json", item_list)
141 + json_data = json.loads(data)
142 + res = []
143 + for i in json_data:
144 + t = i['fields']
145 + t['id'] = i['pk']
146 + res.append(t)
147 + return Response({'data': {'list' : res}}, status=status.HTTP_200_OK)
148 + """
149 + # url: items/11/
150 + # 마지막 slash도 써주어야함
151 + def get(self, request, pk):
152 + #print(pk)
153 + s3 = boto3.client('s3')
154 + s3_bucket = AWS_STORAGE_BUCKET_NAME
155 +
156 + #파일 객체 생성
157 + object_name = request.GET.get('name', '')
158 +
159 + presigned_url = s3.generate_presigned_url(
160 + 'get_object',
161 + Params={'Bucket': s3_bucket,
162 + 'Key': object_name},
163 + ExpiresIn = 3600
164 + )
165 +
166 + return Response({'message': presigned_url}, status=status.HTTP_200_OK)
167 + """
168 + # url: items/11/
169 + # 마지막 slash도 써주어야함
170 + def get(self, request, pk):
171 + s3 = boto3.client('s3',
172 + aws_access_key_id=AWS_ACCESS_KEY_ID,
173 + aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
174 + aws_session_token=AWS_SESSION_TOKEN,
175 + config=Config(signature_version='s3v4'))
176 + s3_bucket = AWS_STORAGE_BUCKET_NAME
177 +
178 + item = Item.objects.filter(item_id=pk)
179 + object_name = item.get().name
180 + data = serializers.serialize("json", item)
181 + json_data = json.loads(data)
182 +
183 + presigned_url = s3.generate_presigned_url(
184 + 'get_object',
185 + Params={'Bucket': s3_bucket,
186 + 'Key': object_name},
187 + ExpiresIn = 3600
188 + )
189 +
190 + res = json_data[0]['fields']
191 + res['id']=json_data[0]['pk']
192 + res['signed_url']=presigned_url
193 + return Response({'data': res}, status=status.HTTP_200_OK)
194 +
195 + # url: items/11/
196 + # 마지막 slash도 써주어야함
197 + def destroy(self, request, pk):
198 + if request.method == 'DELETE':
199 + print(pk)
200 + item = get_object_or_None(Item, item_id=pk)
201 + if item != None:
202 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
203 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
204 + item.is_deleted = True
205 + item.save()
206 + # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록!
207 + return Response({'message': 'delete complete'},status=status.HTTP_200_OK)
208 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
209 +
210 + # url: items/11/move
211 + # 마지막 slash도 써주어야함
212 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move')
213 + def move(self, request, pk):
214 + if request.method == 'POST':
215 + parent_id = request.POST.get('parent', '')
216 + name = request.POST.get('name','')
217 + parent = get_object_or_None(Item, item_id=parent_id)
218 + if parent != None and parent.is_folder == True:
219 + child = get_object_or_None(Item, item_id=pk)
220 + if child == None:
221 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
222 + child.parent = parent_id
223 + child.save()
224 + child = Item.objects.filter(item_id = pk)
225 + child_data = serializers.serialize("json", child)
226 + json_child = json.loads(child_data)
227 + res = json_child[0]['fields']
228 + res['id'] = pk
229 + parent = Item.objects.filter(item_id = parent_id)
230 + parent_data = serializers.serialize("json", parent)
231 + json_parent = json.loads(parent_data)[0]['fields']
232 + res['parentInfo'] = json_parent
233 + return Response({'data': res}, status=status.HTTP_200_OK)
234 + if parent == None:
235 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
236 + if parent.is_folder == False:
237 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
238 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
239 +
240 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy')
241 + def copy(self, request, pk):
242 + if request.method == 'POST':
243 + parent_id = request.POST.get('parent', '')
244 + parent = get_object_or_None(Item, item_id=parent_id)
245 + if parent != None and parent.is_folder == True:
246 + child = get_object_or_None(Item, item_id=pk)
247 + if child == None:
248 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
249 + if child.is_folder == True:
250 + return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT)
251 + copiedName = child.name + "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M'))
252 + copiedItem = Item(is_folder = False, name = copiedName, path =child.path, parent = parent_id, user_id= child.user_id, size=child.size, status=child.status)
253 + copiedItem.save()
254 +
255 + copiedItem = Item.objects.filter(name = copiedName)
256 + copied_data = serializers.serialize("json", copiedItem)
257 + json_data = json.loads(copied_data)
258 + res = json_data[0]['fields']
259 + res['id'] = json_data[0]['pk']
260 + parent = Item.objects.filter(item_id = parent_id)
261 + parent_data = serializers.serialize("json", parent)
262 + json_parent = json.loads(parent_data)[0]['fields']
263 + res['parentInfo'] = json_parent
264 + return Response({'data': res}, status=status.HTTP_200_OK)
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 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
270 +
271 + def get_permissions(self):
272 + try:
273 + # return permission_classes depending on `action`
274 + return [permission() for permission in self.permission_classes_by_action[self.action]]
275 + except KeyError:
276 + # action is not set return default permission_classes
277 + return [permission() for permission in self.permission_classes]
278 +
279 + # url: items/{key}/children/
280 + @action(methods=['GET', 'POST'], detail=True, permission_classes=[AllowAny],
281 + url_path='children', url_name='children')
282 + def children(self, request, pk):
283 + if request.method == 'GET':
284 + children = Item.objects.filter(parent = pk, is_deleted=False)
285 + children_data = serializers.serialize("json", children)
286 + json_children = json.loads(children_data)
287 + parent = Item.objects.filter(item_id=pk) #item
288 + parent_data = serializers.serialize("json", parent)
289 + json_parent = json.loads(parent_data)[0]['fields']
290 + res = json_parent
291 + res['id'] = pk
292 + children_list = []
293 + for i in json_children:
294 + t = i['fields']
295 + t['id'] = i['pk']
296 + children_list.append(t)
297 + res['list'] = children_list
298 + return Response({'data': res}, status=status.HTTP_200_OK)
299 + if request.method == 'POST':
300 + name = request.POST.get('name', '')
301 + user_id = request.GET.get('user_id', '')
302 + item = Item(is_folder=True, name=name, file_type="folder", path="", parent=pk, user_id=user_id, size=0, status=True)
303 + item.save()
304 + item = Item.objects.filter(item_id = item.item_id)
305 + item_data = serializers.serialize("json", item)
306 + json_item = json.loads(item_data)
307 + res = json_item[0]['fields']
308 + res['id']=json_item[0]['pk']
309 + res['inside_folder_list'] = []
310 + res['inside_file_list'] = []
311 + return Response({'data': res}, status=status.HTTP_200_OK)
312 +
313 + # url: /upload/
314 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
315 + url_path='upload', url_name='upload')
316 + def upload(self, request, pk):
317 + if request.method == 'POST':
318 + s3 = boto3.client('s3')
319 + s3_bucket = AWS_STORAGE_BUCKET_NAME
320 +
321 + #파일 객체 생성
322 + file_name = request.POST.get('name', '')
323 + file_size = request.POST.get('size', '')
324 + file_parent = pk
325 + file_type = mimetypes.guess_type(file_name)[0]
326 + upload_item = Item(name=file_name, size=file_size, user_id=1, file_type=file_type, parent=file_parent)
327 + upload_item.save()
328 +
329 + date_long = datetime.utcnow().strftime('%Y%m%dT000000Z')
330 +
331 + presigned_post = s3.generate_presigned_post(
332 + s3_bucket,
333 + file_name,
334 + {
335 + "acl": "private",
336 + "Content-Type": file_type,
337 + 'region': AWS_REGION,
338 + 'x-amz-algorithm': 'AWS4-HMAC-SHA256',
339 + 'x-amz-date': date_long
340 + },
341 + [
342 + {"acl": "private"},
343 + {"Content-Type": file_type},
344 + {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
345 + {'x-amz-date': date_long}
346 + ],
347 + 3600
348 + )
349 +
350 + data = {
351 + "signed_url": presigned_post,
352 + 'url': 'https://%s.s3.amazonaws.com/%s' % (s3_bucket, file_name)
353 + }
354 +
355 + return Response({'presigned_post':presigned_post, 'proc_data':data}, status=status.HTTP_200_OK)
356 +
357 + # url: /status/
358 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny],
359 + url_path='status', url_name='status')
360 + def status(self, request, *args, **kwargs):
361 + if request.method == 'POST':
362 + pk = request.POST.get('item_id', '')
363 + queryset = Item.objects.filter(item_id = pk)
364 + for cand in queryset:
365 + cand.status = True
366 + cand.save()
367 + return Response({'Message': 'File Upload Successful'}, status=status.HTTP_200_OK)
368 + return Response({'Error': 'No such item found in queryset'}, status=status.HTTP_400_BAD_REQUEST)
369 +
370 +
371 +class SharedItemViewSet(viewsets.ModelViewSet):
372 +
373 + queryset = SharedItem.objects.all()
374 + # serializer_class = SharedItemSerializer
375 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
376 + # IsOwnerOrReadOnly
377 + ]
378 + # url: http://localhost:8000/items/1/share/
379 + # 마지막 slash도 써주어야함
380 + @csrf_exempt
381 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='share', url_name='share')
382 + def share(self, request, pk):
383 + if request.method == 'POST':
384 + password = request.POST.get('password', '')
385 + expires = request.POST.get('expires', '')
386 +
387 + sharedfile = get_object_or_None(SharedItem, item_id=pk)
388 + if sharedfile != None:
389 + # 서버는 정상이나 이미 공유객체로 등록된 파일임
390 + return Response({'message': 'This file is already shared'}, status=status.HTTP_200_OK)
391 + sharedfile = SharedItem(item_id =pk, password=password, expires = expires)
392 + sharedfile.save()
393 + sharedfile = SharedItem.objects.get(item_id = pk)
394 +
395 + # sf = serializers.serialize("json", sharedfile)
396 + item = Item.objects.filter(item_id = pk)
397 + item_json = serializers.serialize("json", item)
398 +
399 + json_data = json.loads(item_json)
400 + print(json_data)
401 + res = json_data[0]['fields']
402 + res['id'] = json_data[0]['pk']
403 + return Response({"shared": sharedfile.created_time , 'data': res}, status=status.HTTP_200_OK)
404 +
405 +item = ItemViewSet.as_view({
406 + 'delete': 'destroy',
407 +})
1 -from django.contrib import admin
2 -
3 -# Register your models here.
1 -from django.db import models
2 -
3 -# Create your models here.
1 -from django.shortcuts import render
2 -
3 -# Create your views here.
1 """ 1 """
2 Django settings for khudrive project. 2 Django settings for khudrive project.
3 3
4 -Generated by 'django-admin startproject' using Django 3.0.6. 4 +Generated by 'django-admin startproject' using Django 3.0.7.
5 5
6 For more information on this file, see 6 For more information on this file, see
7 https://docs.djangoproject.com/en/3.0/topics/settings/ 7 https://docs.djangoproject.com/en/3.0/topics/settings/
...@@ -11,16 +11,23 @@ https://docs.djangoproject.com/en/3.0/ref/settings/ ...@@ -11,16 +11,23 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
11 """ 11 """
12 12
13 import os 13 import os
14 +import sys
15 +import json
14 16
15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 17 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 18 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 19
20 +ROOT_DIR = os.path.dirname(BASE_DIR)
21 +# secrets.json의 경로
22 +SECRETS_PATH = os.path.join(ROOT_DIR, 'secrets.json')
23 +# json파일을 파이썬 객체로 변환
24 +secrets = json.loads(open(SECRETS_PATH).read())
18 25
19 # Quick-start development settings - unsuitable for production 26 # Quick-start development settings - unsuitable for production
20 # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ 27 # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
21 28
22 # SECURITY WARNING: keep the secret key used in production secret! 29 # SECURITY WARNING: keep the secret key used in production secret!
23 -SECRET_KEY = '3b=a99pdbz*48$9$kh@h3tkb*9w-m3vtf8ngyymdzwpl5$emwn' 30 +SECRET_KEY = ')i0_(*4t7k3=rcqp*_i0u((9zbk8q(2(3tk(%$woji-e-37=o*'
24 31
25 # SECURITY WARNING: don't run with debug turned on in production! 32 # SECURITY WARNING: don't run with debug turned on in production!
26 DEBUG = True 33 DEBUG = True
...@@ -38,6 +45,7 @@ INSTALLED_APPS = [ ...@@ -38,6 +45,7 @@ INSTALLED_APPS = [
38 'django.contrib.messages', 45 'django.contrib.messages',
39 'django.contrib.staticfiles', 46 'django.contrib.staticfiles',
40 'rest_framework', 47 'rest_framework',
48 + 'api.apps.ApiConfig',
41 ] 49 ]
42 50
43 MIDDLEWARE = [ 51 MIDDLEWARE = [
...@@ -73,11 +81,18 @@ WSGI_APPLICATION = 'khudrive.wsgi.application' ...@@ -73,11 +81,18 @@ WSGI_APPLICATION = 'khudrive.wsgi.application'
73 81
74 # Database 82 # Database
75 # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 83 # https://docs.djangoproject.com/en/3.0/ref/settings/#databases
76 -
77 DATABASES = { 84 DATABASES = {
85 + # 'default': {
86 + # 'ENGINE': 'django.db.backends.sqlite3',
87 + # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
88 + # }
78 'default': { 89 'default': {
79 - 'ENGINE': 'django.db.backends.sqlite3', 90 + 'ENGINE': 'django.db.backends.postgresql',
80 - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 91 + 'NAME': 'khuDrive',
92 + 'USER': 'root',
93 + 'PASSWORD': '1234',
94 + 'HOST': 'localhost',
95 + 'PORT': '',
81 } 96 }
82 } 97 }
83 98
...@@ -119,3 +134,11 @@ USE_TZ = True ...@@ -119,3 +134,11 @@ USE_TZ = True
119 # https://docs.djangoproject.com/en/3.0/howto/static-files/ 134 # https://docs.djangoproject.com/en/3.0/howto/static-files/
120 135
121 STATIC_URL = '/static/' 136 STATIC_URL = '/static/'
137 +
138 +
139 +#S3
140 +DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
141 +STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
142 +
143 +for key, value in secrets.items():
144 + setattr(sys.modules[__name__], key, value)
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -13,9 +13,29 @@ Including another URLconf ...@@ -13,9 +13,29 @@ Including another URLconf
13 1. Import the include() function: from django.urls import include, path 13 1. Import the include() function: from django.urls import include, path
14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 """ 15 """
16 +from django.urls import include, path
17 +from rest_framework import routers
16 from django.contrib import admin 18 from django.contrib import admin
17 -from django.urls import path 19 +from api import views
20 +from django.conf.urls import url
18 21
22 +router = routers.DefaultRouter()
23 +router.register(r'users', views.UserViewSet)
24 +router.register(r'items', views.ItemViewSet)
25 +router.register(r'items', views.SharedItemViewSet)
26 +
27 +# Wire up our API using automatic URL routing.
28 +# Additionally, we include login URLs for the browsable API.
19 urlpatterns = [ 29 urlpatterns = [
20 path('admin/', admin.site.urls), 30 path('admin/', admin.site.urls),
31 + path('', include(router.urls)),
32 + url(r'^search/$', views.ItemViewSet.search, name='search'),
33 + url(r'^<int:pk>/share/$', views.SharedItemViewSet.share, name='share'),
34 + url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'),
35 + url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'),
36 + url(r'^<int:pk>/children/$', views.ItemViewSet.children, name='children'),
37 + url(r'^signup/$', views.UserViewSet.signup, name='signup'),
38 + url(r'^login/$', views.UserViewSet.login, name='login'),
39 + url(r'^upload/$', views.ItemViewSet.upload, name='upload'),
40 + url(r'^status/$', views.ItemViewSet.status, name='status'),
21 ] 41 ]
......