2023-05-03 11:56:13 +02:00
|
|
|
from rest_framework import viewsets
|
2023-05-07 11:48:53 +02:00
|
|
|
from rest_framework.response import Response
|
2023-05-11 01:52:32 +02:00
|
|
|
from rest_framework.views import APIView, View
|
|
|
|
from rest_framework.request import Request
|
2023-05-16 08:24:22 +02:00
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
2023-05-11 01:52:32 +02:00
|
|
|
|
2023-05-16 09:42:44 +02:00
|
|
|
from django.http import HttpResponseBadRequest, HttpResponse, JsonResponse, HttpRequest
|
2023-05-15 06:54:30 +02:00
|
|
|
from django.db.models.query import QuerySet
|
|
|
|
|
|
|
|
from django.core.validators import validate_email
|
|
|
|
from django.core.exceptions import ValidationError
|
2023-04-10 09:34:57 +02:00
|
|
|
|
2023-05-16 17:08:04 +02:00
|
|
|
from .models import Apartament, User, PsychTestAnswers, AuthToken
|
2023-05-03 11:56:13 +02:00
|
|
|
from .serializer import (ApartamentListSerializer,
|
2023-05-12 14:10:12 +02:00
|
|
|
ApartamentDetailSerializer,
|
2023-05-15 05:12:05 +02:00
|
|
|
PsychTestAddResultSerializer,
|
2023-05-16 19:00:45 +02:00
|
|
|
PublicUserSerializer,
|
|
|
|
PsychTestReultsSerializer,
|
2023-05-16 19:02:17 +02:00
|
|
|
UserSerializer,
|
2023-05-16 17:08:04 +02:00
|
|
|
TokenSerializer)
|
2023-05-01 12:39:34 +02:00
|
|
|
|
2023-05-16 18:51:21 +02:00
|
|
|
from .authlib import *
|
|
|
|
|
2023-05-16 17:08:04 +02:00
|
|
|
import json, math, random, re, requests, oidc_client, base64, uuid, time, ipware as iplib
|
|
|
|
ipware = iplib.IpWare();
|
2023-05-01 12:39:34 +02:00
|
|
|
|
2023-05-03 11:56:13 +02:00
|
|
|
class ApartamentViewSet(viewsets.ReadOnlyModelViewSet):
|
|
|
|
"""Вывод списка квартир или отдельной квартиры"""
|
2023-05-01 12:39:34 +02:00
|
|
|
|
2023-05-03 11:56:13 +02:00
|
|
|
def get_queryset(self):
|
2023-05-01 12:39:34 +02:00
|
|
|
apartaments = Apartament.objects.all()
|
2023-05-03 11:56:13 +02:00
|
|
|
return apartaments
|
|
|
|
|
|
|
|
def get_serializer_class(self):
|
|
|
|
if self.action == 'list':
|
|
|
|
return ApartamentListSerializer
|
|
|
|
elif self.action == "retrieve":
|
2023-05-07 11:48:53 +02:00
|
|
|
return ApartamentDetailSerializer
|
|
|
|
|
2023-05-15 18:24:06 +02:00
|
|
|
|
2023-05-09 13:17:51 +02:00
|
|
|
class ApartamentGetManyViewSet(viewsets.ReadOnlyModelViewSet):
|
2023-05-07 11:48:53 +02:00
|
|
|
"""Вывод отдельных квартир для сравнения"""
|
2023-05-09 13:03:37 +02:00
|
|
|
def get_queryset(self): # получение id квартир для избранного или сравнения
|
2023-05-09 10:32:18 +02:00
|
|
|
pk = self.request.query_params.get("pk", None) # получение id пользователя
|
|
|
|
|
|
|
|
if self.action == "retrieve": # если для страницы сравнения
|
|
|
|
apartaments_id = User.objects.get(pk=pk).apartaments_for_comparison.split(',') # получение id квартир
|
|
|
|
elif self.action == "list": # если для страницы избранного
|
|
|
|
apartaments_id = User.objects.get(pk=pk).favorites_apartaments.split(',') # получение id квартир
|
|
|
|
|
2023-05-09 13:03:37 +02:00
|
|
|
queryset = []
|
|
|
|
for i in apartaments_id:
|
|
|
|
queryset.append(Apartament.objects.get(pk=i))
|
|
|
|
|
|
|
|
return queryset
|
2023-05-09 10:32:18 +02:00
|
|
|
|
2023-05-09 11:05:47 +02:00
|
|
|
def retrieve(self, request, *args, **kwargs):
|
2023-05-09 13:03:37 +02:00
|
|
|
queryset = self.get_queryset()
|
2023-05-09 11:05:47 +02:00
|
|
|
apartaments = []
|
2023-05-09 13:03:37 +02:00
|
|
|
for i in queryset:
|
|
|
|
apartaments.append(ApartamentDetailSerializer(i).data)
|
|
|
|
return Response({'results': apartaments})
|
|
|
|
|
|
|
|
def list(self, request, *args, **kwargs):
|
|
|
|
queryset = self.get_queryset()
|
|
|
|
apartaments = []
|
|
|
|
for i in queryset:
|
|
|
|
apartaments.append(ApartamentListSerializer(i).data)
|
2023-05-09 11:05:47 +02:00
|
|
|
return Response({'results': apartaments})
|
2023-05-11 01:52:32 +02:00
|
|
|
|
2023-05-15 18:24:06 +02:00
|
|
|
|
2023-05-11 01:52:32 +02:00
|
|
|
class ApartmentFilter(viewsets.ViewSet):
|
|
|
|
"""Вывод списка квартир или отдельной квартиры"""
|
|
|
|
|
|
|
|
def list(self, req: Request):
|
|
|
|
filters = dict(req.data);
|
2023-05-11 15:11:38 +02:00
|
|
|
unfiltered = Apartament.objects.all();
|
2023-05-11 01:52:32 +02:00
|
|
|
filtered = [];
|
|
|
|
|
2023-05-11 15:11:38 +02:00
|
|
|
# TODO: Some better converting practice?
|
|
|
|
filters['price_range']['from'] = int(filters['price_range']['from']);
|
|
|
|
filters['price_range']['to'] = int(filters['price_range']['to']);
|
|
|
|
filters['area_range']['from'] = int(filters['area_range']['from']);
|
|
|
|
filters['area_range']['to'] = int(filters['area_range']['to']);
|
|
|
|
filters['rooms'] = int(filters['rooms'])
|
|
|
|
|
2023-05-11 01:52:32 +02:00
|
|
|
for entry in unfiltered:
|
2023-05-11 15:11:38 +02:00
|
|
|
if (filters['price_range']['from'] >= entry.price and (filters['price_range']['to'] != -1 and filters['price_range']['to'] <= entry.price)):
|
2023-05-11 01:52:32 +02:00
|
|
|
continue;
|
2023-05-11 15:11:38 +02:00
|
|
|
if (filters['area_range']['from'] >= entry.perimetrs and (filters['area_range']['to'] != -1 and filters['area_range']['to'] <= entry.perimetrs)):
|
2023-05-11 01:52:32 +02:00
|
|
|
continue;
|
2023-05-11 15:11:38 +02:00
|
|
|
if (filters['rooms'] != -1 and entry.rooms != filters['rooms']):
|
2023-05-11 01:52:32 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
filtered.append(entry);
|
|
|
|
|
2023-05-12 14:10:12 +02:00
|
|
|
return Response(ApartamentListSerializer(filtered, many=True).data);
|
|
|
|
|
|
|
|
|
|
|
|
class PsychTestAddResultViewSet(viewsets.ViewSet):
|
2023-05-12 15:01:55 +02:00
|
|
|
def get_object(self, pk):
|
2023-05-15 18:24:06 +02:00
|
|
|
return User.objects.get(pk=pk)
|
|
|
|
def create(self, request, pk):
|
2023-05-12 15:01:55 +02:00
|
|
|
user = self.get_object(pk)
|
2023-05-15 18:24:06 +02:00
|
|
|
results = request.data
|
|
|
|
PsychTestAnswers.objects.create(
|
|
|
|
user=user,
|
2023-05-16 16:36:03 +02:00
|
|
|
first_question=results[0],
|
|
|
|
second_question=results[1],
|
|
|
|
third_question=results[2],
|
|
|
|
fourth_question=results[3],
|
|
|
|
fifth_question=results[4],
|
|
|
|
sixth_question=results[5],
|
|
|
|
seventh_question=results[6],
|
|
|
|
eighth_question=results[7],
|
|
|
|
nineth_question=results[8],
|
|
|
|
tenth_question=results[9],
|
|
|
|
eleventh_question=results[10],
|
|
|
|
twelfth_question=results[11]
|
2023-05-15 18:24:06 +02:00
|
|
|
)
|
|
|
|
return Response({'successfully': 'results post'})
|
|
|
|
|
2023-05-15 05:12:05 +02:00
|
|
|
|
|
|
|
class CompatibleUsersView(viewsets.ViewSet):
|
|
|
|
def list(self, req: Request):
|
|
|
|
user_data = dict(req.data);
|
2023-05-15 06:54:30 +02:00
|
|
|
|
|
|
|
# TODO: Verify auth
|
|
|
|
vvsu_login = user_data['openid'];
|
|
|
|
|
|
|
|
# Exclude already viewed users
|
|
|
|
exclude = [];
|
|
|
|
if ('exclude' in user_data.keys()):
|
|
|
|
exclude = user_data['exclude'];
|
|
|
|
|
|
|
|
try:
|
|
|
|
validate_email(vvsu_login);
|
|
|
|
except ValidationError:
|
|
|
|
return Request({'error': 'bad login'}, 400);
|
|
|
|
|
|
|
|
try:
|
|
|
|
this_user = User.objects.get(openid_addr=vvsu_login);
|
|
|
|
except User.DoesNotExist:
|
|
|
|
return Response({'error': 'user not found'}, 404);
|
|
|
|
|
2023-05-16 19:00:45 +02:00
|
|
|
try:
|
|
|
|
answers_this_user = PsychTestReultsSerializer(PsychTestAnswers.objects.get(user=this_user)).dict;
|
|
|
|
except PsychTestAnswers.DoesNotExist:
|
|
|
|
return Response({'error': 'answers not found'}, 404);
|
2023-05-15 06:54:30 +02:00
|
|
|
|
2023-05-16 19:00:45 +02:00
|
|
|
users_answers_query = PsychTestReultsSerializer(PsychTestAnswers.objects.all(), many=True).dict
|
2023-05-15 06:54:30 +02:00
|
|
|
|
|
|
|
users = [];
|
|
|
|
|
2023-05-16 19:00:45 +02:00
|
|
|
for user_answers in users_answers_query:
|
|
|
|
score = 0
|
|
|
|
for i in range(1, 12):
|
|
|
|
if answers_this_user[i] == user_answers[i]:
|
|
|
|
score += 1
|
|
|
|
if score / 12 * 100 > 30:
|
|
|
|
users.append(UserSerializer(User.objects.get(pk=user_answers[0])).data)
|
2023-05-15 06:54:30 +02:00
|
|
|
|
2023-05-16 19:00:45 +02:00
|
|
|
# for user in users_query:
|
|
|
|
# if (abs(user.psych_test_result - score) < 20):
|
|
|
|
# users.append(PublicUserSerializer(user).data);
|
2023-05-15 06:54:30 +02:00
|
|
|
|
|
|
|
|
2023-05-15 13:01:57 +02:00
|
|
|
return Response(users);
|
|
|
|
|
2023-05-16 09:42:44 +02:00
|
|
|
class UserLogin(APIView):
|
2023-05-16 17:08:04 +02:00
|
|
|
|
2023-05-16 09:42:44 +02:00
|
|
|
# TODO: Remove csrf exempt when index.html is loaded through django
|
|
|
|
@csrf_exempt
|
|
|
|
def post(self, req: HttpRequest):
|
2023-05-16 11:35:20 +02:00
|
|
|
|
2023-05-16 18:10:17 +02:00
|
|
|
# for debug purposes
|
|
|
|
# return HttpResponse("""{"user_data": {"id": 1, "name": "\u041d\u0438\u043a\u0438\u0442\u0430 \u041f\u0443\u0441\u0442\u043e\u0432\u0430\u043b\u043e\u0432", "date_of_birth": null, "about_me": "", "gender": "?", "phone": "+00000", "email": null, "telegram": null, "discord": null, "city": null, "role": "s", "photo_provider": "VVSU", "openid_addr": "blek__@vvsu.ru", "openid_id": "096C78CD-4943-4D57-BC6D-5CDE12F686E3"}, "new_user": false, "token": {"id": 2, "user": 1, "key": "e1c24581-523a-4f60-973f-02ba873b3edc", "expires": 1684423572, "ip": "127.0.0.1"}}""");
|
|
|
|
|
2023-05-16 14:55:05 +02:00
|
|
|
if (req.session.has_key('auth_data')):
|
|
|
|
# TODO: Return user object instead of error
|
|
|
|
return JsonResponse({'error': 'already authenticated'})
|
|
|
|
|
2023-05-16 09:42:44 +02:00
|
|
|
if (req.content_type != 'application/json'):
|
|
|
|
res = HttpResponse({'error': 'bad content type'});
|
|
|
|
res.status_code = 400;
|
|
|
|
return res;
|
2023-05-16 11:35:20 +02:00
|
|
|
|
2023-05-16 09:42:44 +02:00
|
|
|
data = json.loads(req.body.decode('utf8'));
|
|
|
|
|
2023-05-16 11:35:20 +02:00
|
|
|
if not ('code' in data and 'code_verifier' in data):
|
|
|
|
res = JsonResponse({'error': 'no code'});
|
|
|
|
res.status_code = 400;
|
2023-05-16 14:55:05 +02:00
|
|
|
return res;
|
2023-05-16 11:35:20 +02:00
|
|
|
|
2023-05-16 17:08:04 +02:00
|
|
|
auth_data = get_oauth_token('https://vvsu.ru/connect', {
|
|
|
|
'grant_type': 'authorization_code',
|
|
|
|
'redirect_uri': 'https://pairent.vvsu.ru/sign-in/',
|
|
|
|
'code': data['code'],
|
|
|
|
'code_verifier': data['code_verifier'],
|
|
|
|
'client_id': 'it-hub-client',
|
|
|
|
'client_secret': 'U8y@uPVee6Q^*729esHTo4Vd'
|
|
|
|
});
|
2023-05-16 14:55:05 +02:00
|
|
|
|
2023-05-16 15:40:32 +02:00
|
|
|
if ('error' in auth_data):
|
|
|
|
return JsonResponse(auth_data);
|
2023-05-16 09:42:44 +02:00
|
|
|
|
2023-05-16 14:55:05 +02:00
|
|
|
user = None;
|
|
|
|
new_user = False;
|
|
|
|
|
2023-05-16 17:08:04 +02:00
|
|
|
vvsu_data = get_oauth_data('https://vvsu.ru/connect', auth_data['access_token']);
|
|
|
|
|
2023-05-16 15:40:32 +02:00
|
|
|
if ('error' in vvsu_data):
|
|
|
|
res = JsonResponse(vvsu_data);
|
|
|
|
res.status_code = 500;
|
|
|
|
return res;
|
2023-05-16 11:35:20 +02:00
|
|
|
|
2023-05-16 14:55:05 +02:00
|
|
|
if ('error' in vvsu_data):
|
|
|
|
res = JsonResponse(vvsu_data);
|
2023-05-16 15:40:32 +02:00
|
|
|
res.status_code = 500;
|
2023-05-16 14:55:05 +02:00
|
|
|
return res
|
2023-05-16 09:42:44 +02:00
|
|
|
|
2023-05-16 14:55:05 +02:00
|
|
|
vvsu_data['vvsu_login'] += '@vvsu.ru';
|
|
|
|
try:
|
|
|
|
user = User.objects.get(openid_addr=vvsu_data['vvsu_login']);
|
|
|
|
except User.DoesNotExist:
|
2023-05-16 15:40:32 +02:00
|
|
|
user = register(vvsu_data['vvsu_login'], vvsu_data['id'], f"{vvsu_data['given_name']} {vvsu_data['family_name']}");
|
2023-05-16 14:55:05 +02:00
|
|
|
new_user = True;
|
|
|
|
|
|
|
|
return JsonResponse({
|
2023-05-16 15:40:32 +02:00
|
|
|
'user_data': PublicUserSerializer(user).data,
|
2023-05-16 17:08:04 +02:00
|
|
|
'new_user': new_user,
|
|
|
|
'token': TokenSerializer(create_auth_token(user.id, ipware.get_client_ip(req.META)[0].exploded)).data
|
2023-05-16 14:55:05 +02:00
|
|
|
});
|
2023-05-16 12:07:50 +02:00
|
|
|
|
|
|
|
class UserGet(APIView):
|
|
|
|
def get(self, req: HttpRequest):
|
|
|
|
if not ('id' in req.GET.keys() or 'login' in req.GET.keys()):
|
|
|
|
res = JsonResponse({'error': 'no id or login'});
|
|
|
|
res.status_code = 400;
|
|
|
|
return res;
|
|
|
|
|
|
|
|
id_type = 'id' if 'id' in req.GET.keys() else 'login';
|
|
|
|
id = req.GET.get(id_type);
|
|
|
|
|
|
|
|
if (id_type == 'login'):
|
|
|
|
if not id.endswith('@vvsu.ru'):
|
|
|
|
id += '@vvsu.ru';
|
|
|
|
id_type = 'openid_addr';
|
|
|
|
|
|
|
|
user = None;
|
|
|
|
try:
|
|
|
|
user = User.objects.get(**{id_type: id});
|
|
|
|
except User.DoesNotExist:
|
|
|
|
res = JsonResponse({'error': 'not found'});
|
|
|
|
res.status_code = 404;
|
|
|
|
return res;
|
|
|
|
|
2023-05-16 19:00:45 +02:00
|
|
|
return JsonResponse(PublicUserSerializer(user).data);
|
|
|
|
|