diff --git a/.gitignore b/.gitignore index 82e7cd3a..90842d0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .env +/env +env #VS Code .vscode/ settings.json diff --git a/Digital_Fortress_Backend/settings/base.py b/Digital_Fortress_Backend/dev_settings.py similarity index 59% rename from Digital_Fortress_Backend/settings/base.py rename to Digital_Fortress_Backend/dev_settings.py index 43580d69..df32d71b 100644 --- a/Digital_Fortress_Backend/settings/base.py +++ b/Digital_Fortress_Backend/dev_settings.py @@ -1,15 +1,39 @@ +""" +Django settings for Digital_Fortress_Backend project. + +Generated by 'django-admin startproject' using Django 2.2.1. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + import os from decouple import config, Csv from datetime import timedelta from rest_framework.settings import api_settings -BASE_DIR = os.path.dirname(os.path.dirname( - os.path.dirname(os.path.abspath(__file__)))) +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = config('SECRET_KEY') +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = config('DEBUG', cast=bool) + +ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY') + +# Application definition + INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', @@ -55,6 +79,30 @@ WSGI_APPLICATION = 'Digital_Fortress_Backend.wsgi.application' +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + +# DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.postgresql_psycopg2', +# 'NAME': config('DB_NAME'), +# 'USER': config('DB_USER'), +# 'PASSWORD': config('DB_PASSWORD'), +# 'HOST': config('DB_HOST'), +# 'PORT': config('DB_PORT'), +# } +# } + +# Password validation +# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators + AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', @@ -91,6 +139,9 @@ 'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT, } +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Asia/Kolkata' @@ -101,7 +152,18 @@ USE_TZ = True -PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = os.path.join(BASE_DIR, 'static/') + +CORS_ORIGIN_ALLOW_ALL = True +CORS_ALLOW_CREDENTIALS = True +CORS_ORIGIN_WHITELIST = [ + 'http://localhost:3030', +] +CORS_ORIGIN_REGEX_WHITELIST = [ + 'http://localhost:3030', +] diff --git a/Digital_Fortress_Backend/settings.py b/Digital_Fortress_Backend/settings.py new file mode 100644 index 00000000..7c4ec0e8 --- /dev/null +++ b/Digital_Fortress_Backend/settings.py @@ -0,0 +1,187 @@ +""" +Django settings for Digital_Fortress_Backend project. + +Generated by 'django-admin startproject' using Django 2.2.1. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + +import os +from decouple import config, Csv +from datetime import timedelta +from rest_framework.settings import api_settings + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = config('SECRET_KEY') + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = config('DEBUG',default=False, cast=bool) + +ALLOWED_HOSTS = ["*"] +#ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) + +GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY') + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'Quiz', + 'corsheaders', + 'rest_framework', + 'knox', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'Digital_Fortress_Backend.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'Digital_Fortress_Backend.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +if DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } + } +else : + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': config('DB_NAME'), + 'USER': config('DB_USER'), + 'PASSWORD': config('DB_PASSWORD'), + 'HOST': 'localhost', + 'PORT': '', + } + } + +# Password validation +# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', + ], + 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'knox.auth.TokenAuthentication', + ] +} + +REST_KNOX = { + 'SECURE_HASH_ALGORITHM': 'cryptography.hazmat.primitives.hashes.SHA512', + 'AUTH_TOKEN_CHARACTER_LENGTH': 64, + 'TOKEN_TTL': timedelta(hours=72), + 'USER_SERIALIZER': 'knox.serializers.UserSerializer', + 'TOKEN_LIMIT_PER_USER': None, + 'AUTO_REFRESH': False, + 'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT, +} + +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Kolkata' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') + +MEDIA_URL='/media/' +MEDIA_ROOT=os.path.join(BASE_DIR,'media') + +#CORS_ALLOW_CREDENTIALS = True + +CORS_ORIGIN_ALLOW_ALL = True + +#CORS_ALLOW_CREDENTIALS = True + +''' +CSRF_TRUSTED_ORIGINS = ['dfapi.weblikate.com','localhost:8000','localhost:5000','digitalfortress-frontend.vercel.app'] +''' +CSRF_COOKIE_DOMAIN= 'dfapi.weblikate.com' +''' +CORS_ORIGIN_WHITELIST = [ + 'localhost:8000','localhost:5000','dfapi.weblikate.com','digitalfortress-frontend.vercel.app' +] +''' +''' +CORS_ORIGIN_REGEX_WHITELIST = [ + 'http://localhost:8000','http://localhost:5000','https://dfapi.weblikate.com', +] +''' diff --git a/Digital_Fortress_Backend/settings/__init__.py b/Digital_Fortress_Backend/settings/__init__.py deleted file mode 100644 index 9b5ed21c..00000000 --- a/Digital_Fortress_Backend/settings/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .base import * diff --git a/Digital_Fortress_Backend/settings/development.py b/Digital_Fortress_Backend/settings/development.py deleted file mode 100644 index 1ba4fc27..00000000 --- a/Digital_Fortress_Backend/settings/development.py +++ /dev/null @@ -1,13 +0,0 @@ -from .base import * -from decouple import config, Csv - -DEBUG = True - -ALLOWED_HOSTS = ['127.0.0.1', ] - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } -} diff --git a/Digital_Fortress_Backend/settings/production.py b/Digital_Fortress_Backend/settings/production.py deleted file mode 100644 index 19e49f3c..00000000 --- a/Digital_Fortress_Backend/settings/production.py +++ /dev/null @@ -1,19 +0,0 @@ -from .base import * -from decouple import config, Csv - -DEBUG = False - -ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': config('DB_NAME'), - 'USER': config('DB_USER'), - 'PASSWORD': config('DB_PASSWORD'), - 'HOST': config('DB_HOST'), - 'PORT': config('DB_PORT'), - } -} - -STATIC_ROOT = os.path.join(BASE_DIR, 'static') diff --git a/Digital_Fortress_Backend/urls.py b/Digital_Fortress_Backend/urls.py index 25636b44..4f71e99d 100644 --- a/Digital_Fortress_Backend/urls.py +++ b/Digital_Fortress_Backend/urls.py @@ -15,8 +15,11 @@ """ from django.contrib import admin from django.urls import path, include - +from django.conf.urls.static import static +from django.conf import settings urlpatterns = [ path('admin/', admin.site.urls), path('quiz/', include('Quiz.urls')) -] +]+ static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) + + diff --git a/Quiz/admin.py b/Quiz/admin.py index 62048a7f..8ddfd1e5 100644 --- a/Quiz/admin.py +++ b/Quiz/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin # Register your models here. -from .models import Round, Clue, Player, Location +from .models import Round, Clue, Player, Location, duration from django.conf import settings @@ -42,3 +42,4 @@ def clear_all_values(self, req, queryset): admin.site.register(Round) admin.site.register(Player, PlayerAdmin) admin.site.register(Location, LocationAdmin) +admin.site.register(duration) diff --git a/Quiz/migrations/0004_duration.py b/Quiz/migrations/0004_duration.py new file mode 100644 index 00000000..e5be2721 --- /dev/null +++ b/Quiz/migrations/0004_duration.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.4 on 2020-01-24 10:42 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('Quiz', '0003_auto_20191222_2004'), + ] + + operations = [ + migrations.CreateModel( + name='duration', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.DateTimeField(default=datetime.datetime.now)), + ('end_time', models.DateTimeField(default=datetime.datetime.now)), + ], + ), + ] diff --git a/Quiz/migrations/0005_player_first_name.py b/Quiz/migrations/0005_player_first_name.py new file mode 100644 index 00000000..b41ec599 --- /dev/null +++ b/Quiz/migrations/0005_player_first_name.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2020-01-24 11:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('Quiz', '0004_duration'), + ] + + operations = [ + migrations.AddField( + model_name='player', + name='first_name', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/Quiz/migrations/0006_remove_player_first_name.py b/Quiz/migrations/0006_remove_player_first_name.py new file mode 100644 index 00000000..be744f8c --- /dev/null +++ b/Quiz/migrations/0006_remove_player_first_name.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.4 on 2020-01-24 13:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('Quiz', '0005_player_first_name'), + ] + + operations = [ + migrations.RemoveField( + model_name='player', + name='first_name', + ), + ] diff --git a/Quiz/migrations/0007_player_first_name.py b/Quiz/migrations/0007_player_first_name.py new file mode 100644 index 00000000..71f51c9f --- /dev/null +++ b/Quiz/migrations/0007_player_first_name.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2020-01-24 13:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('Quiz', '0006_remove_player_first_name'), + ] + + operations = [ + migrations.AddField( + model_name='player', + name='first_name', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/Quiz/models.py b/Quiz/models.py index f4c51834..8e5c55c7 100644 --- a/Quiz/models.py +++ b/Quiz/models.py @@ -1,5 +1,5 @@ from django.db import models - +from datetime import datetime # Create your models here. @@ -17,7 +17,9 @@ def __str__(self): class Round(models.Model): round_number = models.IntegerField(default=1) question = models.CharField(max_length=750) + audio=models.FileField(upload_to='media/audios',blank=True) answer = models.CharField(max_length=200) + image=models.ImageField(upload_to='media/images',blank=True) def __str__(self): return str(self.round_number) @@ -41,6 +43,8 @@ def checkAnswer(self, answer): class Clue(models.Model): question = models.CharField(max_length=750) + audio=models.FileField(upload_to='media/audios',blank=True) + image=models.ImageField(upload_to='media/images',blank=True) answer = models.CharField(max_length=200) location = models.ForeignKey( Location, on_delete=models.CASCADE, blank=True, null=True) @@ -73,6 +77,7 @@ def getPosition(self): class Player(models.Model): name = models.CharField(max_length=200, blank=True) + first_name = models.CharField(max_length=200, blank=True) email = models.EmailField(max_length=254) imageLink = models.CharField(max_length=200) score = models.IntegerField(default=0) @@ -101,3 +106,11 @@ def checkClue(self, value): if value == int(hint): return 1 return 0 + +class duration(models.Model): + start_time = models.DateTimeField(default=datetime.now) + end_time = models.DateTimeField(default=datetime.now) + + def __str__(self): + return "Duration" + \ No newline at end of file diff --git a/Quiz/serializers.py b/Quiz/serializers.py index 9d523760..fffa3d87 100644 --- a/Quiz/serializers.py +++ b/Quiz/serializers.py @@ -7,24 +7,25 @@ class CreateUserSerializer(serializers.ModelSerializer): email = serializers.CharField() username = serializers.CharField() + first_name = serializers.CharField() class Meta: model = User - fields = ('email', 'username') + fields = ('email', 'username', 'first_name') def create(self, data): user = User.objects.create_user(username=data['username'], - email=data['email']) + email=data['email'],first_name=data['first_name']) return user class PlayerSerializer(serializers.ModelSerializer): class Meta: model = Player - fields = ('name', 'email', 'imageLink', 'score', 'roundNo') + fields = ('name', 'first_name', 'email', 'imageLink', 'score', 'roundNo') class RoundSerializer(serializers.ModelSerializer): class Meta: model = Round - fields = ('question', 'round_number') + fields = ('question', 'round_number','audio','image') diff --git a/Quiz/urls.py b/Quiz/urls.py index 81084aaa..63e3599b 100644 --- a/Quiz/urls.py +++ b/Quiz/urls.py @@ -1,6 +1,6 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from .views import LeaderBoard, getClue, getRound, putClue, checkRound, leaderboard, Login, Register +from .views import LeaderBoard, getClue, getRound, putClue, checkRound, leaderboard, Login, Register,getuserscore from knox.views import LogoutView urlpatterns = [ path('leaderboard', leaderboard.as_view(), name='leaderboard'), @@ -11,5 +11,6 @@ path('checkClue', putClue.as_view(), name="checkClue"), path('auth/login', Login.as_view(), name="login"), path('auth/register', Register.as_view(), name="register"), - path('auth/logout', LogoutView.as_view(), name="logout") + path('auth/logout', LogoutView.as_view(), name="logout"), + path('user',getuserscore.as_view(),name="user") ] diff --git a/Quiz/views.py b/Quiz/views.py index 3cea496a..228aae13 100644 --- a/Quiz/views.py +++ b/Quiz/views.py @@ -9,7 +9,7 @@ from rest_framework.decorators import permission_classes, APIView from rest_framework.permissions import AllowAny, IsAuthenticated from django.http import HttpResponse, JsonResponse -from .models import Round, Player, Clue +from .models import Round, Player, Clue, duration import datetime import requests as r import time @@ -20,10 +20,17 @@ import urllib from .serializers import CreateUserSerializer, RoundSerializer, PlayerSerializer from decouple import config - - +from decimal import Decimal +from decouple import config # Create your views here. +def check_duration(): + tm = timezone.now() + obj = duration.objects.all().first() + if tm > obj.start_time and tm < obj.end_time: + return False + else: + return True def LeaderBoard(request): if request.GET.get("password") == config('DOWNLOAD', cast=str): @@ -31,7 +38,7 @@ def LeaderBoard(request): response["Content-Disposition"] = 'attachment; filename="leaderboards.csv"' writer = csv.writer(response) for player in Player.objects.order_by("-score", "submit_time"): - writer.writerow([player.name, player.email, player.score]) + writer.writerow([player.first_name, player.email, player.score]) return response else: return HttpResponse("You are not authorized to see this page!") @@ -48,7 +55,8 @@ def verifyGoogleToken(token): return { "email": idinfo['email'], - "username": idinfo['name'], + "username": idinfo['email'], + "first_name": idinfo['name'], "image": idinfo['picture'], "status": 200 } @@ -68,16 +76,46 @@ def verifyFacebookToken(accesstoken, expiration_time, userID): idInfo = r.get(url=url, params=parameters).json() return { "email": idInfo['email'], - "username": idInfo['name'], + "username": idInfo['email'], + "first_name": idInfo['name'], "image": idInfo['picture']['data']['url'], 'status': 200 } +def verifyGithubToken(accessCode): + try: + tokenurl= "https://github.com/login/oauth/access_token" + params = { + "client_id": config('GITHUB_CLIENT_ID'), + "client_secret":config('GITHUB_CLIENT_SECRET'), + "code": accessCode, + "redirect_uri":"http://localhost:5000/" + } + headers = { + "Accept":"application/json" + } + accesscode= r.post(url=tokenurl,params=params,headers=headers).json() + + userurl = "https://api.github.com/user" + headers = { + "Authorization" : "Bearer {}".format(accesscode['access_token']) + } + userinfo=r.get(url=userurl, headers=headers).json() + + return { + "email":userinfo['email'], + "username":userinfo['email'], + "first_name":userinfo['name'], + "image":userinfo['avatar_url'], + "status":200 + } + except ValueError: + return {"status": 404, "message": "Your Token has expired. Please login/register again!"} def centrePoint(roundNo): clues = Clue.objects.filter(round=roundNo) - x = 0.0 - y = 0.0 + x = Decimal(0.0) + y = Decimal(0.0) count = 0 for clue in clues: pos = clue.getPosition() @@ -85,8 +123,8 @@ def centrePoint(roundNo): y += pos[1] count += 1 centre = [] - centre.append(x/count) - centre.append(y/count) + centre.append(x/Decimal(count)) + centre.append(y/Decimal(count)) return centre @@ -107,7 +145,7 @@ def get(self, request, format=None): for player in p: player.rank = current_rank players_array.append({ - "name": player.name, + "name": player.first_name, "rank": player.rank, "score": player.score, "image": player.imageLink, @@ -124,8 +162,7 @@ def post(self, request, *args, **kwargs): if request.data.get('type') == '1': res = verifyGoogleToken(request.data.get('accesstoken')) else: - res = verifyFacebookToken(request.data.get('accesstoken'), request.data.get('expiration_time'), request.data.get( - 'userID')) + res = verifyGithubToken(request.data.get('accesscode')) if res['status'] == 404: return Response({ "status": 404, @@ -137,7 +174,7 @@ def post(self, request, *args, **kwargs): serializer.is_valid(raise_exception=True) user = serializer.save() player = Player.objects.create( - name=res['username'], email=res['email'], imageLink=res['image']) + name=res['username'],first_name=res['first_name'], email=res['email'], imageLink=res['image']) return Response({ "user": serializer.data, "token": AuthToken.objects.create(user)[1], @@ -155,8 +192,7 @@ def post(self, request, *args, **kwargs): if request.data.get('type') == '1': res = verifyGoogleToken(request.data.get('accesstoken')) else: - res = verifyFacebookToken(request.data.get('accesstoken'), request.data.get('expiration_time'), request.data.get( - 'userID')) + res = verifyGithubToken(request.data.get('accesscode')) if res['status'] == 404: return Response({ "status": 404, @@ -165,8 +201,8 @@ def post(self, request, *args, **kwargs): else: if verifyUser(res['email']) == True: print(res) - user = User.objects.get(username=res['username']) - player = Player.objects.get(name=res['username']) + user = User.objects.get(email=res['email']) + player = Player.objects.get(email=res['email']) serializer = self.get_serializer(player) return Response({ "user": serializer.data, @@ -183,6 +219,8 @@ def post(self, request, *args, **kwargs): @permission_classes([IsAuthenticated, ]) class getRound(APIView): def get(self, request, format=None): + if check_duration(): + return Response({"start_time":duration.objects.all().first().start_time ,"end_time":duration.objects.all().first().end_time , "status": 410, "detail": 1}) player = Player.objects.get(name=request.user.username) try: curr_round = Round.objects.get(round_number=player.roundNo) @@ -197,6 +235,8 @@ def get(self, request, format=None): @permission_classes([IsAuthenticated]) class checkRound(APIView): def post(self, request, *args, **kwargs): + if check_duration(): + return Response({"start_time":duration.objects.all().first().start_time ,"end_time":duration.objects.all().first().end_time , "status": 410, "detail": 1}) try: player = Player.objects.get(name=request.user.username) round = Round.objects.get( @@ -213,10 +253,25 @@ def post(self, request, *args, **kwargs): except (Player.DoesNotExist, Round.DoesNotExist): return Response({"status": 404, "detail": 1}) - +@permission_classes([IsAuthenticated]) +class getuserscore(APIView): + def get(self,request): + ps= Player.objects.order_by("-score", "submit_time") + current_rank = 1 + try: + player= Player.objects.get(name=request.user.username) + for p in ps: + if p.first_name == player.first_name: + return Response({"status":200,"score":player.score,"rank":current_rank,"name":player.first_name,"email":player.email}) + else: + current_rank += 1 + except (Player.DoesNotExist): + return Response({"status":404, "message":"user not found"}) @permission_classes([IsAuthenticated]) class getClue(APIView): def get(self, request, format=None): + if check_duration(): + return Response({"start_time":duration.objects.all().first().start_time ,"end_time":duration.objects.all().first().end_time , "status": 410, "detail": 1}) try: player = Player.objects.get(name=request.user.username) round = Round.objects.get(round_number=(player.roundNo)) @@ -242,6 +297,8 @@ def get(self, request, format=None): @permission_classes([IsAuthenticated]) class putClue(APIView): def post(self, request, *args, **kwargs): + if check_duration(): + return Response({"start_time":duration.objects.all().first().start_time ,"end_time":duration.objects.all().first().end_time , "status": 410, "detail": 1}) try: player = Player.objects.get(name=request.user.username) try: diff --git a/README.md b/README.md index b4a75eff..77186331 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ +# DigitalFortress Backend This is the backend repository built on Django framework and utilises Django Rest Framework for a REST API. -**How to run:** +## How to run during development** -1. First, install the requiremnents by running the command **pip install -r requirements.txt** -2. Then, apply the migrations using **python manange.py migrate** -3. Run the server using **python manage.py runserver** +1. First, install the requiremnents by running the command `pip install -r requirements.txt` +2. Then, apply the migrations using `python manange.py migrate` +3. Run the server using `python manage.py runserver --settings=Digital_Fortress_Backend.dev_settings` -**Status Codes:** +### Status Codes: 200 : Success @@ -18,9 +19,11 @@ This is the backend repository built on Django framework and utilises Django Res 403 : Wrong Clue ID. +410 : Quiz has not started Yet. + 500 : Wrong Answer -The API links: +### The API Routes: quiz/auth/register - For registering a user diff --git a/manage.py b/manage.py index 28b8a863..992a1128 100755 --- a/manage.py +++ b/manage.py @@ -5,8 +5,7 @@ def main(): - os.environ.setdefault('DJANGO_SETTINGS_MODULE', - 'Digital_Fortress_Backend.settings.development') + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Digital_Fortress_Backend.settings') try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/requirements.txt b/requirements.txt index 1ed0da7a..45532e71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,16 +3,23 @@ attrs==19.1.0 black==19.3b0 cachetools==3.1.1 certifi==2019.6.16 +cffi==1.14.4 chardet==3.0.4 Click==7.0 -Django==2.2.4 +cryptography==3.3.1 +Django==2.2.13 django-cors-headers==3.0.2 django-grappelli==2.13.1 +django-rest-knox==4.1.0 djangorestframework==3.10.3 google-auth==1.6.3 idna==2.8 +Pillow==8.0.1 +psycopg2-binary==2.8.3 pyasn1==0.4.6 pyasn1-modules==0.2.6 +pycparser==2.20 +python-decouple==3.1 pytz==2019.2 requests==2.22.0 rsa==4.0 @@ -20,6 +27,3 @@ six==1.12.0 sqlparse==0.3.0 toml==0.10.0 urllib3==1.25.3 -django-rest-knox==4.1.0 -python-decouple==3.1 -psycopg2-binary==2.8.3 \ No newline at end of file