mirror of
https://github.com/task-17-lct/backend.git
synced 2024-11-27 09:53:44 +03:00
resolve confs
This commit is contained in:
commit
7a12da6974
|
@ -378,4 +378,4 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
YANDEX_TOKEN = env("YANDEX_TOKEN", default="")
|
YANDEX_TOKEN = env("YANDEX_TOKEN", default="56653e15-3063-43c9-9707-3476dc13ae9d")
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
from drf_spectacular.utils import extend_schema
|
from drf_spectacular.utils import extend_schema
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from random import choice
|
from random import choice
|
||||||
from passfinder.recomendations.service.service import generate_tour
|
from passfinder.recomendations.service.service import generate_tour, get_events
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
from .consts import *
|
from .consts import *
|
||||||
|
from passfinder.recomendations.models import UserPreferences
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from random import sample
|
||||||
|
|
||||||
|
|
||||||
from passfinder.events.api.serializers import (
|
from passfinder.events.api.serializers import (
|
||||||
|
@ -53,7 +56,8 @@ def get(self, request):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return Response(data=routes)
|
return Response(data=routes)
|
||||||
|
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
request=RouteInputSerializer, responses={200: RouteSerializer(many=True)}
|
request=RouteInputSerializer, responses={200: RouteSerializer(many=True)}
|
||||||
|
@ -111,7 +115,7 @@ def post(self, request):
|
||||||
hotel_stars = []
|
hotel_stars = []
|
||||||
res = []
|
res = []
|
||||||
|
|
||||||
for _ in range(5):
|
for _ in range(2):
|
||||||
if city_id:
|
if city_id:
|
||||||
region = get_object_or_404(City, oid=city_id)
|
region = get_object_or_404(City, oid=city_id)
|
||||||
else:
|
else:
|
||||||
|
@ -165,7 +169,7 @@ class ListCityApiView(ListAPIView):
|
||||||
queryset = (
|
queryset = (
|
||||||
City.objects.annotate(points_count=Count("points"))
|
City.objects.annotate(points_count=Count("points"))
|
||||||
.filter(title__in=city_in_hotels)
|
.filter(title__in=city_in_hotels)
|
||||||
.filter(points_count__gt=200)
|
.filter(points_count__gt=400)
|
||||||
.order_by("title")
|
.order_by("title")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -178,17 +182,20 @@ def post(self, request, *args, **kwargs):
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
data = serializer.data
|
data = serializer.data
|
||||||
route = UserRoute.objects.create(user=self.request.user)
|
route = UserRoute.objects.create(user=self.request.user)
|
||||||
|
up, _ = UserPreferences.objects.get_or_create(user=request.user)
|
||||||
for date in data["points"]:
|
for date in data["points"]:
|
||||||
date_obj = UserRouteDate.objects.create(
|
date_obj = UserRouteDate.objects.create(
|
||||||
date=parse_datetime(date["date"]).date(), route=route
|
date=parse_datetime(date["date"]).date(), route=route
|
||||||
)
|
)
|
||||||
for point in date["paths"]:
|
for point in date["paths"]:
|
||||||
if point["type"] == "point":
|
if point["type"] == "point":
|
||||||
|
model_point = BasePoint.objects.get(oid=point["point"]["oid"])
|
||||||
UserRoutePoint.objects.create(
|
UserRoutePoint.objects.create(
|
||||||
date=date_obj,
|
date=date_obj,
|
||||||
duration=point["time"],
|
duration=point["time"],
|
||||||
point=BasePoint.objects.get(oid=point["point"]["oid"]),
|
point=model_point,
|
||||||
)
|
)
|
||||||
|
up.add_point(model_point)
|
||||||
else:
|
else:
|
||||||
UserRouteTransaction.objects.create(
|
UserRouteTransaction.objects.create(
|
||||||
date=date_obj,
|
date=date_obj,
|
||||||
|
|
|
@ -13,9 +13,6 @@ def get_position_weather(lat: float, lon: float) -> list[(str, str)]:
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
days = []
|
temp_feels = data["forecasts"][0]["parts"]["day"]["feels_like"]
|
||||||
|
weather = data["forecasts"][0]["parts"]["day_short"]["condition"]
|
||||||
for d in data["forecasts"]:
|
return temp_feels, weather
|
||||||
days.append((d["date"], d["parts"]["day_short"]["condition"]))
|
|
||||||
return days
|
|
||||||
return []
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from random import sample
|
from random import sample
|
||||||
|
from passfinder.events.api.serializers import RouteInputSerializer
|
||||||
|
from passfinder.events.api.consts import city_in_hotels
|
||||||
|
|
||||||
|
|
||||||
class TinderView(viewsets.GenericViewSet):
|
class TinderView(viewsets.GenericViewSet):
|
||||||
|
@ -93,6 +95,7 @@ def get_daily_selection(self, request, *args, **kwargs):
|
||||||
@action(methods=["POST"], detail=False, serializer_class=DailySelectionSerializer)
|
@action(methods=["POST"], detail=False, serializer_class=DailySelectionSerializer)
|
||||||
def generate_daily_selection(self, request, *args, **kwargs):
|
def generate_daily_selection(self, request, *args, **kwargs):
|
||||||
points = []
|
points = []
|
||||||
|
print(request.data['nodes'])
|
||||||
for point in request.data["nodes"]:
|
for point in request.data["nodes"]:
|
||||||
if point["action"] == "right":
|
if point["action"] == "right":
|
||||||
points.append(Event.objects.get(oid=point["oid"]))
|
points.append(Event.objects.get(oid=point["oid"]))
|
||||||
|
@ -100,6 +103,40 @@ def generate_daily_selection(self, request, *args, **kwargs):
|
||||||
path = generate_points_path(request.user, points, 3)
|
path = generate_points_path(request.user, points, 3)
|
||||||
|
|
||||||
return Response(data={"path": path})
|
return Response(data={"path": path})
|
||||||
|
|
||||||
|
@action(methods=['POST'], detail=False, serializer_class=RouteInputSerializer)
|
||||||
|
def build_events(self, request, *args, **kwargs):
|
||||||
|
serializer = RouteInputSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
data =serializer.data
|
||||||
|
|
||||||
|
what_to_see = data["what_to_see"]
|
||||||
|
if what_to_see is None:
|
||||||
|
what_to_see = [
|
||||||
|
"attractions",
|
||||||
|
"museum",
|
||||||
|
"movie",
|
||||||
|
"concert",
|
||||||
|
"artwork",
|
||||||
|
"plays",
|
||||||
|
"shop",
|
||||||
|
"gallery",
|
||||||
|
"theme_park",
|
||||||
|
"viewpoint",
|
||||||
|
"zoo",
|
||||||
|
]
|
||||||
|
city_id = data["city"]
|
||||||
|
allowed_regions = []
|
||||||
|
if city_id:
|
||||||
|
allowed_regions = [City.objects.get(oid=city_id)]
|
||||||
|
else:
|
||||||
|
allowed_regions = sample(
|
||||||
|
list(City.objects.annotate(points_count=Count("points"))
|
||||||
|
.filter(title__in=city_in_hotels)
|
||||||
|
.filter(points_count__gt=400)), 5)
|
||||||
|
return Response(data=get_events(request.user, allowed_regions, what_to_see))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OnboardingViewset(viewsets.GenericViewSet):
|
class OnboardingViewset(viewsets.GenericViewSet):
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 4.2.1 on 2023-05-28 07:19
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("events", "0027_city_temperature_city_weather_condition"),
|
||||||
|
("recomendations", "0008_userpreferences_preferred_categories_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="userpreferences",
|
||||||
|
name="prefered_other",
|
||||||
|
field=models.ManyToManyField(related_name="other_users", to="events.event"),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Generated by Django 4.2.1 on 2023-05-28 08:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("events", "0027_city_temperature_city_weather_condition"),
|
||||||
|
("recomendations", "0009_userpreferences_prefered_other"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="userpreferences",
|
||||||
|
name="prefered_hotels",
|
||||||
|
field=models.ManyToManyField(related_name="hotels_user", to="events.hotel"),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="userpreferences",
|
||||||
|
name="prefered_restaurants",
|
||||||
|
field=models.ManyToManyField(
|
||||||
|
related_name="restaurant_user", to="events.restaurant"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from passfinder.users.models import User
|
from passfinder.users.models import User
|
||||||
from passfinder.events.models import Event, Hotel, Restaurant
|
from passfinder.events.models import Event, Hotel, Restaurant, BasePoint
|
||||||
|
from passfinder.events.api.serializers import ObjectRouteSerializer
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,6 +48,52 @@ class UserPreferences(models.Model):
|
||||||
base_field=models.IntegerField(), null=True, blank=True
|
base_field=models.IntegerField(), null=True, blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
prefered_other = models.ManyToManyField(Event, related_name='other_users')
|
||||||
|
prefered_hotels = models.ManyToManyField(Hotel, related_name='hotels_user')
|
||||||
|
prefered_restaurants = models.ManyToManyField(Restaurant, related_name='restaurant_user')
|
||||||
|
|
||||||
|
def add_point(self, point: BasePoint):
|
||||||
|
print(point, type(point))
|
||||||
|
if isinstance(point, Event):
|
||||||
|
event = point
|
||||||
|
if event.type == 'play':
|
||||||
|
self.preferred_concerts.add(event)
|
||||||
|
elif event.type == 'movie':
|
||||||
|
self.preffered_movies.add(event)
|
||||||
|
elif event.type == 'attraction':
|
||||||
|
self.prefferred_attractions.add(event)
|
||||||
|
elif event.type == 'museum':
|
||||||
|
self.prefferred_museums.add(event)
|
||||||
|
else:
|
||||||
|
self.prefered_other.add(event)
|
||||||
|
self.save()
|
||||||
|
if isinstance(point, Hotel):
|
||||||
|
self.prefered_hotels.add(point)
|
||||||
|
self.save()
|
||||||
|
if isinstance(point, Restaurant):
|
||||||
|
self.prefered_restaurants.add(point)
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
|
def get_points(self):
|
||||||
|
points = [
|
||||||
|
*list(self.preffered_plays.all()),
|
||||||
|
*list(self.prefered_hotels.all()),
|
||||||
|
*list(self.prefered_restaurants.all()),
|
||||||
|
*list(self.preferred_concerts.all()),
|
||||||
|
*list(self.preffered_movies.all()),
|
||||||
|
*list(self.prefferred_attractions.all()),
|
||||||
|
*list(self.prefferred_museums.all()),
|
||||||
|
*list(self.prefered_other.all()),
|
||||||
|
]
|
||||||
|
return list(
|
||||||
|
map(
|
||||||
|
lambda x: ObjectRouteSerializer(x).data,
|
||||||
|
points
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NearestEvent(models.Model):
|
class NearestEvent(models.Model):
|
||||||
event = models.ForeignKey(
|
event = models.ForeignKey(
|
||||||
|
@ -55,26 +102,6 @@ class NearestEvent(models.Model):
|
||||||
nearest = models.ManyToManyField(Event, related_name="nearest_model_rev_rel")
|
nearest = models.ManyToManyField(Event, related_name="nearest_model_rev_rel")
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
from passfinder.recomendations.service.service import generate_tour
|
|
||||||
|
|
||||||
from passfinder.users.models import User
|
|
||||||
|
|
||||||
from passfinder.events.models import City
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
start_date = datetime(year=2023, month=6, day=10)
|
|
||||||
end_date = datetime(year=2023, month=6, day=13)
|
|
||||||
|
|
||||||
c = City.objects.get(title='Таганрог')
|
|
||||||
|
|
||||||
u = User.objects.all()[0]
|
|
||||||
|
|
||||||
generate_tour(u, c, start_date, end_date)
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class NearestHotel(models.Model):
|
class NearestHotel(models.Model):
|
||||||
hotel = models.ForeignKey(
|
hotel = models.ForeignKey(
|
||||||
Hotel, on_delete=models.CASCADE, related_name="nearest_hotel_rel"
|
Hotel, on_delete=models.CASCADE, related_name="nearest_hotel_rel"
|
||||||
|
|
|
@ -367,8 +367,13 @@ def calculate_mean_metric(
|
||||||
except:
|
except:
|
||||||
return 10
|
return 10
|
||||||
for fav in favorite_events:
|
for fav in favorite_events:
|
||||||
dists.append(model.get_distance(rev_mapping[fav.oid], target_event_idx))
|
try:
|
||||||
return sum(dists) / len(dists)
|
dists.append(model.get_distance(rev_mapping[fav.oid], target_event_idx))
|
||||||
|
except: pass
|
||||||
|
try:
|
||||||
|
return sum(dists) / len(dists)
|
||||||
|
except ZeroDivisionError:
|
||||||
|
return 10
|
||||||
|
|
||||||
|
|
||||||
def calculate_favorite_metric(event: Event, user: User):
|
def calculate_favorite_metric(event: Event, user: User):
|
||||||
|
@ -720,6 +725,14 @@ def generate_path(
|
||||||
start_time += timedelta(seconds=point_route["time"])
|
start_time += timedelta(seconds=point_route["time"])
|
||||||
path.extend([transition_route, point_route])
|
path.extend([transition_route, point_route])
|
||||||
candidates = None
|
candidates = None
|
||||||
|
|
||||||
|
# = "Сгенерируй описание туристического маршрута, проходящего через следующие точки:\n"
|
||||||
|
|
||||||
|
# prompt += 'Отель: {hotel.name}\n'
|
||||||
|
# for i in points:
|
||||||
|
# prompt += f'Название: {i.title}\nОписание: {i.description}\nТип: {i.type}\n\n'
|
||||||
|
# print(promptprompt)
|
||||||
|
|
||||||
return points, path, disallowed_rests
|
return points, path, disallowed_rests
|
||||||
|
|
||||||
|
|
||||||
|
@ -814,21 +827,26 @@ def range_candidates(candidates, user, favorite_events):
|
||||||
"concert": [concert_model, rev_concert_mapping],
|
"concert": [concert_model, rev_concert_mapping],
|
||||||
"plays": [plays_model, rev_plays_mapping],
|
"plays": [plays_model, rev_plays_mapping],
|
||||||
}
|
}
|
||||||
|
try:
|
||||||
if candidates[0].type in ["attraction", "museum", "movie", "concert", "plays"]:
|
if candidates[0].type in ["attraction", "museum", "movie", "concert", "plays"]:
|
||||||
candidates = sorted(
|
candidates = sorted(
|
||||||
candidates,
|
map(
|
||||||
key=lambda cand: calculate_mean_metric(
|
lambda x: [
|
||||||
favorite_events, cand, *model_mappings[cand.type]
|
calculate_mean_metric(
|
||||||
),
|
favorite_events, x, *model_mappings[x.type]
|
||||||
)
|
), x
|
||||||
return candidates[0:10]
|
],
|
||||||
return sample(candidates, 10)
|
candidates
|
||||||
|
),
|
||||||
|
key=lambda x: x[0],
|
||||||
|
)
|
||||||
|
return candidates[0:10]
|
||||||
|
return sample(candidates, 10)
|
||||||
|
except: return []
|
||||||
|
|
||||||
|
|
||||||
def get_personal_recomendations(user):
|
|
||||||
up, _ = UserPreferences.objects.get_or_create(user=user)
|
candidates_generate_strategy = {
|
||||||
candidates_generate_strategy = {
|
|
||||||
"plays": [
|
"plays": [
|
||||||
lambda pref: flat_list(
|
lambda pref: flat_list(
|
||||||
list(
|
list(
|
||||||
|
@ -903,8 +921,17 @@ def get_personal_recomendations(user):
|
||||||
lambda pref: sample(list(Event.objects.filter(type="zoo")), 10),
|
lambda pref: sample(list(Event.objects.filter(type="zoo")), 10),
|
||||||
lambda x: [],
|
lambda x: [],
|
||||||
],
|
],
|
||||||
|
"artwork": [
|
||||||
|
lambda pref: sample(list(Event.objects.filter(type="zoo")), 10),
|
||||||
|
lambda x: [],
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_personal_recomendations(user):
|
||||||
|
up, _ = UserPreferences.objects.get_or_create(user=user)
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
for category_candidate in up.preferred_categories:
|
for category_candidate in up.preferred_categories:
|
||||||
candidates = candidates_generate_strategy[category_candidate][0](up)
|
candidates = candidates_generate_strategy[category_candidate][0](up)
|
||||||
|
@ -914,7 +941,36 @@ def get_personal_recomendations(user):
|
||||||
res.append(
|
res.append(
|
||||||
{
|
{
|
||||||
"category": category_candidate,
|
"category": category_candidate,
|
||||||
"events": list(map(lambda x: ObjectRouteSerializer(x).data, ranged)),
|
"events": list(map(lambda x: ObjectRouteSerializer(x[1]).data, ranged)),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def get_events(
|
||||||
|
user: User,
|
||||||
|
allowed_regions: Iterable[City],
|
||||||
|
what_to_see: Iterable[str]
|
||||||
|
):
|
||||||
|
up, _ = UserPreferences.objects.get_or_create(user=user)
|
||||||
|
events = Event.objects.filter(type__in=what_to_see, city__in=allowed_regions)
|
||||||
|
ranged = []
|
||||||
|
for category in what_to_see:
|
||||||
|
candidates = events.filter(type=category)
|
||||||
|
ranged.extend(
|
||||||
|
range_candidates(
|
||||||
|
candidates,
|
||||||
|
user,
|
||||||
|
candidates_generate_strategy[category][1](up)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ranged.sort(key=lambda x: x[0])
|
||||||
|
return list(
|
||||||
|
map(
|
||||||
|
lambda x: ObjectRouteSerializer(x[1]).data,
|
||||||
|
ranged[0:10]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def remap_points(date: datetime.date, region: City, )
|
|
@ -6,6 +6,8 @@
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
|
from passfinder.recomendations.models import UserPreferences
|
||||||
|
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
UserSerializer,
|
UserSerializer,
|
||||||
UserRegisterSerializer,
|
UserRegisterSerializer,
|
||||||
|
@ -54,6 +56,5 @@ class ListUserFavoritePointsApiView(generics.ListAPIView):
|
||||||
serializer_class = PointSerializer
|
serializer_class = PointSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return BasePoint.objects.filter(
|
up, _ = UserPreferences.objects.get_or_create(user=self.request.user)
|
||||||
user_preferences__user=self.request.user, user_preferences__type="favorite"
|
return up.get_points()
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user