mirror of
				https://github.com/task-17-lct/backend.git
				synced 2025-11-01 00:37:26 +03:00 
			
		
		
		
	added save route
This commit is contained in:
		
							parent
							
								
									dd7ce0f5fa
								
							
						
					
					
						commit
						bb3f767db8
					
				|  | @ -1,3 +1,5 @@ | |||
| from drf_spectacular.types import OpenApiTypes | ||||
| from drf_spectacular.utils import extend_schema_field | ||||
| from rest_framework import serializers | ||||
| from rest_framework.generics import get_object_or_404 | ||||
| 
 | ||||
|  | @ -9,6 +11,8 @@ | |||
|     BasePoint, | ||||
|     Region, | ||||
|     Restaurant, | ||||
|     UserRoute, | ||||
|     UserRouteDate, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -78,20 +82,17 @@ class Meta: | |||
| 
 | ||||
| class InputRoutePointSerializer(serializers.Serializer): | ||||
|     type = serializers.ChoiceField(choices=["point", "transition"]) | ||||
|     time = serializers.IntegerField(min_value=0, required=True) | ||||
|     duration = serializers.IntegerField(min_value=0, required=True) | ||||
| 
 | ||||
|     # point | ||||
|     point = serializers.CharField( | ||||
|         min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True | ||||
|     ) | ||||
|     point_type = serializers.CharField( | ||||
|         required=False, allow_blank=True, allow_null=True | ||||
|     ) | ||||
| 
 | ||||
|     # transition | ||||
|     point_from = serializers.CharField( | ||||
|         min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True | ||||
|     ) | ||||
|     point_to = serializers.CharField( | ||||
|         min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True | ||||
|     ) | ||||
|     distance = serializers.FloatField(min_value=0, required=False, allow_null=True) | ||||
| 
 | ||||
|     def validate(self, data): | ||||
|  | @ -99,24 +100,49 @@ def validate(self, data): | |||
|             if "point" not in data or not data["point"]: | ||||
|                 raise serializers.ValidationError("Point id is required") | ||||
|             get_object_or_404(BasePoint, oid=data["point"]) | ||||
|             if "distance" not in data or not data["point_type"]: | ||||
|                 raise serializers.ValidationError("Point type is required") | ||||
|         else: | ||||
|             if "point_to" not in data or not data["point_to"]: | ||||
|                 raise serializers.ValidationError("Point to id is required") | ||||
|             get_object_or_404(BasePoint, oid=data["point_to"]) | ||||
|             if "point_from" not in data or not data["point_from"]: | ||||
|                 raise serializers.ValidationError("Point from id is required") | ||||
|             get_object_or_404(BasePoint, oid=data["point_from"]) | ||||
|             if "distance" not in data or not data["distance"]: | ||||
|                 raise serializers.ValidationError("Distance is required") | ||||
| 
 | ||||
|         return data | ||||
| 
 | ||||
| 
 | ||||
| class InputRouteSerializer(serializers.Serializer): | ||||
| class InputRouteDateSerializer(serializers.Serializer): | ||||
|     date = serializers.DateField() | ||||
|     points = serializers.ListSerializer(child=InputRoutePointSerializer()) | ||||
| 
 | ||||
| 
 | ||||
| class ResaurantSerializer(serializers.ModelSerializer): | ||||
| class InputRouteSerializer(serializers.Serializer): | ||||
|     dates = serializers.ListSerializer(child=InputRouteDateSerializer()) | ||||
| 
 | ||||
| 
 | ||||
| class ListUserRouteSerializer(serializers.ModelSerializer): | ||||
|     class Meta: | ||||
|         model = UserRoute | ||||
|         fields = ["id", "created"] | ||||
| 
 | ||||
| 
 | ||||
| class UserRouteDateSerializer(serializers.ModelSerializer): | ||||
|     points = serializers.SerializerMethodField(method_name="get_points") | ||||
| 
 | ||||
|     @extend_schema_field(InputRoutePointSerializer) | ||||
|     def get_points(self, obj): | ||||
|         return [x.get_json() for x in obj.points.all()] | ||||
| 
 | ||||
|     class Meta: | ||||
|         model = UserRouteDate | ||||
|         fields = ["date", "points"] | ||||
| 
 | ||||
| 
 | ||||
| class UserRouteSerializer(serializers.ModelSerializer): | ||||
|     class Meta: | ||||
|         model = UserRoute | ||||
|         fields = ["created", "dates"] | ||||
| 
 | ||||
| 
 | ||||
| class RestaurantSerializer(serializers.ModelSerializer): | ||||
|     class Meta: | ||||
|         model = Restaurant | ||||
|         exclude = ("phones",) | ||||
|  |  | |||
|  | @ -4,14 +4,18 @@ | |||
|     BuildRouteApiView, | ||||
|     ListRegionApiView, | ||||
|     ListCityApiView, | ||||
|     SaveRouteSerializer, | ||||
|     SaveRouteApiView, | ||||
|     ListUserFavoriteRoutes, | ||||
|     RetrieveRoute, | ||||
| ) | ||||
| 
 | ||||
| app_name = "events" | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     path("route/build", BuildRouteApiView.as_view(), name="build_route"), | ||||
|     path("route/save", SaveRouteSerializer.as_view(), name="save_route"), | ||||
|     path("route/save", SaveRouteApiView.as_view(), name="save_route"), | ||||
|     path("route/list", ListUserFavoriteRoutes.as_view(), name="list_routes"), | ||||
|     path("route/<int:pk>", RetrieveRoute.as_view(), name="get_route"), | ||||
|     path("data/regions", ListRegionApiView.as_view(), name="regions"), | ||||
|     path("data/cities", ListCityApiView.as_view(), name="cities"), | ||||
| ] | ||||
|  |  | |||
|  | @ -1,4 +1,10 @@ | |||
| from rest_framework.generics import GenericAPIView, ListAPIView, get_object_or_404 | ||||
| from rest_framework.generics import ( | ||||
|     GenericAPIView, | ||||
|     ListAPIView, | ||||
|     get_object_or_404, | ||||
|     RetrieveAPIView, | ||||
| ) | ||||
| from rest_framework.exceptions import MethodNotAllowed | ||||
| from rest_framework.response import Response | ||||
| from drf_spectacular.utils import extend_schema | ||||
| from django.db.models import Count | ||||
|  | @ -15,6 +21,8 @@ | |||
|     RouteInputSerializer, | ||||
|     CitySerializer, | ||||
|     InputRouteSerializer, | ||||
|     ListUserRouteSerializer, | ||||
|     UserRouteSerializer, | ||||
| ) | ||||
| from passfinder.events.models import ( | ||||
|     BasePoint, | ||||
|  | @ -23,6 +31,7 @@ | |||
|     UserRoute, | ||||
|     UserRoutePoint, | ||||
|     UserRouteTransaction, | ||||
|     UserRouteDate, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -99,7 +108,7 @@ class ListCityApiView(ListAPIView): | |||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class SaveRouteSerializer(GenericAPIView): | ||||
| class SaveRouteApiView(GenericAPIView): | ||||
|     serializer_class = InputRouteSerializer | ||||
| 
 | ||||
|     def post(self, request, *args, **kwargs): | ||||
|  | @ -107,16 +116,37 @@ def post(self, request, *args, **kwargs): | |||
|         serializer.is_valid(raise_exception=True) | ||||
|         data = serializer.data | ||||
|         route = UserRoute.objects.create(user=self.request.user) | ||||
|         for point in data["points"]: | ||||
|             if point["type"] == "point": | ||||
|                 UserRoutePoint.objects.create( | ||||
|                     route=route, point=BasePoint.objects.get(oid=point["point"]) | ||||
|                 ) | ||||
|             else: | ||||
|                 UserRouteTransaction.objects.create( | ||||
|                     route=route, | ||||
|                     point_from=BasePoint.objects.get(oid=point["point_from"]), | ||||
|                     point_to=BasePoint.objects.get(oid=point["point_to"]), | ||||
|                 ) | ||||
|         for date in data["dates"]: | ||||
|             date_obj = UserRouteDate.objects.create(date=date["date"], route=route) | ||||
|             for point in date["points"]: | ||||
|                 if point["type"] == "point": | ||||
|                     UserRoutePoint.objects.create( | ||||
|                         date=date_obj, | ||||
|                         duration=point["duration"], | ||||
|                         point=BasePoint.objects.get(oid=point["point"]), | ||||
|                     ) | ||||
|                 else: | ||||
|                     UserRouteTransaction.objects.create( | ||||
|                         date=date_obj, | ||||
|                         duration=point["duration"], | ||||
|                         distance=point["distance"], | ||||
|                     ) | ||||
| 
 | ||||
|         return Response(data=data) | ||||
| 
 | ||||
| 
 | ||||
| class ListUserFavoriteRoutes(ListAPIView): | ||||
|     serializer_class = ListUserRouteSerializer | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         return UserRoute.objects.filter(user=self.request.user) | ||||
| 
 | ||||
| 
 | ||||
| class RetrieveRoute(RetrieveAPIView): | ||||
|     serializer_class = UserRouteSerializer | ||||
| 
 | ||||
|     def get_object(self): | ||||
|         route = get_object_or_404(UserRoute, pk=self.kwargs["pk"]) | ||||
|         if route.user != self.request.user: | ||||
|             raise MethodNotAllowed | ||||
|         return route | ||||
|  |  | |||
|  | @ -0,0 +1,49 @@ | |||
| # Generated by Django 4.2.1 on 2023-05-26 21:13 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ("events", "0024_basepoint_price"), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroute", | ||||
|             name="user", | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroutepoint", | ||||
|             name="baseuserroutepoint_ptr", | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroutepoint", | ||||
|             name="point", | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroutetransaction", | ||||
|             name="baseuserroutepoint_ptr", | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroutetransaction", | ||||
|             name="point_from", | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name="userroutetransaction", | ||||
|             name="point_to", | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name="BaseUserRoutePoint", | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name="UserRoute", | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name="UserRoutePoint", | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name="UserRouteTransaction", | ||||
|         ), | ||||
|     ] | ||||
|  | @ -0,0 +1,156 @@ | |||
| # Generated by Django 4.2.1 on 2023-05-26 21:14 | ||||
| 
 | ||||
| from django.conf import settings | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||
|         ("contenttypes", "0002_remove_content_type_name"), | ||||
|         ("events", "0025_remove_userroute_user_and_more"), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name="BaseUserRouteDatePoint", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "id", | ||||
|                     models.BigAutoField( | ||||
|                         auto_created=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         verbose_name="ID", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("duration", models.IntegerField()), | ||||
|             ], | ||||
|             options={ | ||||
|                 "abstract": False, | ||||
|                 "base_manager_name": "objects", | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="UserRoute", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "id", | ||||
|                     models.BigAutoField( | ||||
|                         auto_created=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         verbose_name="ID", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("created", models.DateTimeField(auto_now_add=True)), | ||||
|                 ( | ||||
|                     "user", | ||||
|                     models.ForeignKey( | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         related_name="routes", | ||||
|                         to=settings.AUTH_USER_MODEL, | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="UserRouteTransaction", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "baseuserroutedatepoint_ptr", | ||||
|                     models.OneToOneField( | ||||
|                         auto_created=True, | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="events.baseuserroutedatepoint", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("distance", models.FloatField()), | ||||
|             ], | ||||
|             options={ | ||||
|                 "abstract": False, | ||||
|                 "base_manager_name": "objects", | ||||
|             }, | ||||
|             bases=("events.baseuserroutedatepoint",), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="UserRouteDate", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "id", | ||||
|                     models.BigAutoField( | ||||
|                         auto_created=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         verbose_name="ID", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("date", models.DateField()), | ||||
|                 ( | ||||
|                     "route", | ||||
|                     models.ForeignKey( | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         related_name="dates", | ||||
|                         to="events.userroute", | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
|             options={ | ||||
|                 "unique_together": {("date", "route")}, | ||||
|             }, | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name="baseuserroutedatepoint", | ||||
|             name="date", | ||||
|             field=models.ForeignKey( | ||||
|                 on_delete=django.db.models.deletion.CASCADE, | ||||
|                 related_name="points", | ||||
|                 to="events.userroutedate", | ||||
|             ), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name="baseuserroutedatepoint", | ||||
|             name="polymorphic_ctype", | ||||
|             field=models.ForeignKey( | ||||
|                 editable=False, | ||||
|                 null=True, | ||||
|                 on_delete=django.db.models.deletion.CASCADE, | ||||
|                 related_name="polymorphic_%(app_label)s.%(class)s_set+", | ||||
|                 to="contenttypes.contenttype", | ||||
|             ), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="UserRoutePoint", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "baseuserroutedatepoint_ptr", | ||||
|                     models.OneToOneField( | ||||
|                         auto_created=True, | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="events.baseuserroutedatepoint", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("point_type", models.CharField(max_length=250)), | ||||
|                 ( | ||||
|                     "point", | ||||
|                     models.ForeignKey( | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         to="events.basepoint", | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
|             options={ | ||||
|                 "abstract": False, | ||||
|                 "base_manager_name": "objects", | ||||
|             }, | ||||
|             bases=("events.baseuserroutedatepoint",), | ||||
|         ), | ||||
|     ] | ||||
|  | @ -245,23 +245,45 @@ def __str__(self): | |||
|         return f"{self.user}'s route" | ||||
| 
 | ||||
| 
 | ||||
| class BaseUserRoutePoint(PolymorphicModel): | ||||
| class UserRouteDate(models.Model): | ||||
|     date = models.DateField() | ||||
|     route = models.ForeignKey( | ||||
|         "UserRoute", related_name="points", on_delete=models.CASCADE | ||||
|         "UserRoute", related_name="dates", on_delete=models.CASCADE | ||||
|     ) | ||||
| 
 | ||||
|     class Meta: | ||||
|         unique_together = ("date", "route") | ||||
| 
 | ||||
| class UserRoutePoint(BaseUserRoutePoint): | ||||
| 
 | ||||
| class BaseUserRouteDatePoint(PolymorphicModel): | ||||
|     date = models.ForeignKey( | ||||
|         "UserRouteDate", related_name="points", on_delete=models.CASCADE | ||||
|     ) | ||||
|     duration = models.IntegerField() | ||||
| 
 | ||||
| 
 | ||||
| class UserRoutePoint(BaseUserRouteDatePoint): | ||||
|     type = "point" | ||||
|     point = models.ForeignKey("BasePoint", on_delete=models.CASCADE) | ||||
|     point_type = models.CharField(max_length=250) | ||||
| 
 | ||||
|     def get_json(self): | ||||
|         return { | ||||
|             "type": "point", | ||||
|             "duration": self.duration, | ||||
|             "point": self.point.oid, | ||||
|             "point_name": self.point.title, | ||||
|             "point_type": self.point_type, | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| class UserRouteTransaction(BaseUserRoutePoint): | ||||
| class UserRouteTransaction(BaseUserRouteDatePoint): | ||||
|     type = "transition" | ||||
|     point_from = models.ForeignKey( | ||||
|         "BasePoint", related_name="user_route_point_from", on_delete=models.CASCADE | ||||
|     ) | ||||
|     point_to = models.ForeignKey( | ||||
|         "BasePoint", related_name="user_route_point_to", on_delete=models.CASCADE | ||||
|     ) | ||||
|     distance = models.FloatField() | ||||
| 
 | ||||
|     def get_json(self): | ||||
|         return { | ||||
|             "type": "transition", | ||||
|             "duration": self.duration, | ||||
|             "distance": self.distance, | ||||
|         } | ||||
|  |  | |||
|  | @ -2,7 +2,12 @@ | |||
| from .mapping.mapping import * | ||||
| from .models.models import * | ||||
| from passfinder.events.models import Event, Region, Hotel, BasePoint, City, Restaurant | ||||
| from passfinder.events.api.serializers import HotelSerializer, EventSerializer, ResaurantSerializer, ObjectRouteSerializer | ||||
| from passfinder.events.api.serializers import ( | ||||
|     HotelSerializer, | ||||
|     EventSerializer, | ||||
|     RestaurantSerializer, | ||||
|     ObjectRouteSerializer, | ||||
| ) | ||||
| from passfinder.recomendations.models import * | ||||
| from random import choice, sample | ||||
| from collections import Counter | ||||
|  | @ -44,12 +49,7 @@ def nearest_attraction(attraction, nearest_n): | |||
| 
 | ||||
| def nearest_mus(museum, nearest_n): | ||||
|     return get_nearest_( | ||||
|         museum, | ||||
|         "museum", | ||||
|         mus_mapping, | ||||
|         rev_mus_mapping, | ||||
|         nearest_n, | ||||
|         mus_model | ||||
|         museum, "museum", mus_mapping, rev_mus_mapping, nearest_n, mus_model | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -94,9 +94,9 @@ def get_nearest_event(event, nearest_n): | |||
|         return nearest_concert(event, nearest_n) | ||||
|     if event.type == "movie": | ||||
|         return nearest_movie(event, nearest_n) | ||||
|     if event.type == 'museum': | ||||
|     if event.type == "museum": | ||||
|         return nearest_mus(event, nearest_n) | ||||
|     if event.type == 'attraction': | ||||
|     if event.type == "attraction": | ||||
|         return nearest_attraction(event, nearest_n) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -259,7 +259,7 @@ def dist_func(event1: Event, event2: Event): | |||
|         return dist | ||||
|     except: | ||||
|         return 1000000 | ||||
|     #return (event1.lon - event2.lon) ** 2 + (event1.lat - event2.lat) ** 2 | ||||
|     # return (event1.lon - event2.lon) ** 2 + (event1.lat - event2.lat) ** 2 | ||||
| 
 | ||||
| 
 | ||||
| def generate_nearest(): | ||||
|  | @ -299,7 +299,7 @@ def generate_nearest_restaurants(): | |||
|         nr.save() | ||||
|         if i % 100 == 0: | ||||
|             print(i) | ||||
|      | ||||
| 
 | ||||
|     for i, hotel in enumerate(Hotel.objects.all()): | ||||
|         sorted_rests = list(sorted(rests.copy(), key=lambda x: dist_func(x, hotel))) | ||||
|         nr = NearestRestaurantToHotel.objects.create(hotel=hotel) | ||||
|  | @ -309,7 +309,6 @@ def generate_nearest_restaurants(): | |||
|             print(i) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def match_points(): | ||||
|     regions = list(City.objects.all()) | ||||
|     for i, point in enumerate(Event.objects.all()): | ||||
|  | @ -349,10 +348,12 @@ def calculate_favorite_metric(event: Event, user: User): | |||
|     if event.type == "movie": | ||||
|         preferred = pref.preffered_movies.all() | ||||
|         return calculate_mean_metric(preferred, event, cinema_model, rev_cinema_mapping) | ||||
|     if event.type == 'attraction': | ||||
|     if event.type == "attraction": | ||||
|         preferred = pref.prefferred_attractions.all() | ||||
|         return calculate_mean_metric(preferred, event, attracion_model, rev_attraction_mapping) | ||||
|     if event.type == 'museum': | ||||
|         return calculate_mean_metric( | ||||
|             preferred, event, attracion_model, rev_attraction_mapping | ||||
|         ) | ||||
|     if event.type == "museum": | ||||
|         preferred = pref.prefferred_museums.all() | ||||
|         return calculate_mean_metric(preferred, event, mus_model, rev_mus_mapping) | ||||
|     return 1000000 | ||||
|  | @ -366,7 +367,7 @@ def get_nearest_favorite( | |||
|         if candidate not in exclude_events: | ||||
|             first_event = candidate | ||||
|             break | ||||
|      | ||||
| 
 | ||||
|     if first_event is None: | ||||
|         result = events[0] | ||||
|     else: | ||||
|  | @ -408,28 +409,34 @@ def generate_point(point: BasePoint): | |||
|         "type": "point", | ||||
|         "point": event_data, | ||||
|         "point_type": "point", | ||||
|         "time": timedelta(minutes=90+choice(range(-10, 90, 10))).seconds | ||||
|         "time": timedelta(minutes=90 + choice(range(-10, 90, 10))).seconds, | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| def generate_restaurant(point: BasePoint): | ||||
|     rest_data = ObjectRouteSerializer(point).data | ||||
|      | ||||
| 
 | ||||
|     return { | ||||
|         "type": "point", | ||||
|         "point": rest_data, | ||||
|         "point_type": "restaurant", | ||||
|         "time": timedelta(minutes=90+choice(range(-10, 90, 10))).seconds | ||||
|         "time": timedelta(minutes=90 + choice(range(-10, 90, 10))).seconds, | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| def generate_multiple_tours(user: User, city: City, start_date: datetime.date, end_date: datetime.date): | ||||
| def generate_multiple_tours( | ||||
|     user: User, city: City, start_date: datetime.date, end_date: datetime.date | ||||
| ): | ||||
|     hotels = sample(list(Hotel.objects.filter(city=city)), 5) | ||||
|     pool = Pool(5) | ||||
|     return pool.map(generate_tour, [(user, start_date, end_date, hotel) for hotel in hotels]) | ||||
|     return pool.map( | ||||
|         generate_tour, [(user, start_date, end_date, hotel) for hotel in hotels] | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| def generate_tour(user: User, city: City, start_date: datetime.date, end_date: datetime.date): | ||||
| def generate_tour( | ||||
|     user: User, city: City, start_date: datetime.date, end_date: datetime.date | ||||
| ): | ||||
|     UserPreferences.objects.get_or_create(user=user) | ||||
|     hotel = choice(list(Hotel.objects.filter(city=city))) | ||||
|     current_date = start_date | ||||
|  | @ -438,15 +445,10 @@ def generate_tour(user: User, city: City, start_date: datetime.date, end_date: d | |||
|     while current_date < end_date: | ||||
|         local_points, local_paths = generate_path(user, points, hotel) | ||||
|         points.extend(local_points) | ||||
|         paths.append( | ||||
|             { | ||||
|                 'date': current_date, | ||||
|                 'paths': local_paths | ||||
|             } | ||||
|         ) | ||||
|         paths.append({"date": current_date, "paths": local_paths}) | ||||
| 
 | ||||
|         current_date += timedelta(days=1) | ||||
|      | ||||
| 
 | ||||
|     return paths, points | ||||
| 
 | ||||
| 
 | ||||
|  | @ -456,55 +458,82 @@ def generate_hotel(hotel: Hotel): | |||
|         "type": "point", | ||||
|         "point": hotel_data, | ||||
|         "point_type": "hotel", | ||||
|         "time": timedelta(minutes=90+choice(range(-10, 90, 10))).seconds | ||||
|         "time": timedelta(minutes=90 + choice(range(-10, 90, 10))).seconds, | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| def generate_path(user: User, disallowed_points: Iterable[BasePoint], hotel: Hotel): | ||||
|     # region_events = Event.objects.filter(region=region) | ||||
| 
 | ||||
|     #candidates = NearestHotel.objects.get(hotel=hotel).nearest_events.all() | ||||
|     allowed_types = ['museum', 'attraction'] | ||||
|     # candidates = NearestHotel.objects.get(hotel=hotel).nearest_events.all() | ||||
|     allowed_types = ["museum", "attraction"] | ||||
| 
 | ||||
|     start_point = NearestRestaurantToHotel.objects.get(hotel=hotel).restaurants.first() | ||||
| 
 | ||||
|     candidates = list(filter(lambda x: x.type in allowed_types, map(lambda x: x.event, start_point.nearestrestauranttoevent_set.all()[0:100]))) | ||||
|     candidates = list( | ||||
|         filter( | ||||
|             lambda x: x.type in allowed_types, | ||||
|             map( | ||||
|                 lambda x: x.event, start_point.nearestrestauranttoevent_set.all()[0:100] | ||||
|             ), | ||||
|         ) | ||||
|     ) | ||||
|     points = [start_point] | ||||
|     path = [ | ||||
|         generate_hotel(hotel), | ||||
|         generate_route(start_point, hotel),  | ||||
|         generate_restaurant(points[-1]) | ||||
|         generate_route(start_point, hotel), | ||||
|         generate_restaurant(points[-1]), | ||||
|     ] | ||||
| 
 | ||||
|     start_time = datetime.combine(datetime.now(), time(hour=10)) | ||||
| 
 | ||||
|     how_many_eat = 1 | ||||
| 
 | ||||
| 
 | ||||
|     while start_time.hour < 22 and start_time.day == datetime.now().day: | ||||
|         if (start_time.hour > 14 and how_many_eat == 1) or (start_time.hour > 20 and how_many_eat == 2): | ||||
|             point = NearestRestaurantToEvent.objects.get(event=points[-1]).restaurants.all()[0] | ||||
|         if (start_time.hour > 14 and how_many_eat == 1) or ( | ||||
|             start_time.hour > 20 and how_many_eat == 2 | ||||
|         ): | ||||
|             point = NearestRestaurantToEvent.objects.get( | ||||
|                 event=points[-1] | ||||
|             ).restaurants.all()[0] | ||||
|             points.append(point) | ||||
|             candidates = list(filter(lambda x: x.type in allowed_types, map(lambda x: x.event, point.nearestrestauranttoevent_set.all()[0:100]))) | ||||
|             candidates = list( | ||||
|                 filter( | ||||
|                     lambda x: x.type in allowed_types, | ||||
|                     map( | ||||
|                         lambda x: x.event, | ||||
|                         point.nearestrestauranttoevent_set.all()[0:100], | ||||
|                     ), | ||||
|                 ) | ||||
|             ) | ||||
|             if not len(candidates): | ||||
|                 candidates = list(map(lambda x: x.event, point.nearestrestauranttoevent_set.all()[0:100])) | ||||
|              | ||||
|                 candidates = list( | ||||
|                     map( | ||||
|                         lambda x: x.event, | ||||
|                         point.nearestrestauranttoevent_set.all()[0:100], | ||||
|                     ) | ||||
|                 ) | ||||
| 
 | ||||
|             path.append(generate_restaurant(points[-1])) | ||||
|             start_time += timedelta(seconds=path[-1]['time']) | ||||
|             start_time += timedelta(seconds=path[-1]["time"]) | ||||
|             how_many_eat += 1 | ||||
|             continue | ||||
| 
 | ||||
|         if start_time.hour > 17: | ||||
|             allowed_types = ['play', 'concert', 'movie'] | ||||
|             allowed_types = ["play", "concert", "movie"] | ||||
| 
 | ||||
|         if candidates is None: | ||||
|             candidates = NearestEvent.objects.get(event=points[-1]).nearest.filter(type__in=allowed_types) | ||||
|             candidates = NearestEvent.objects.get(event=points[-1]).nearest.filter( | ||||
|                 type__in=allowed_types | ||||
|             ) | ||||
|             if not len(candidates): | ||||
|                 candidates = NearestEvent.objects.get(event=points[-1]).nearest.all() | ||||
| 
 | ||||
|         try: | ||||
|             points.append(get_nearest_favorite(candidates, user, points + disallowed_points)) | ||||
|              | ||||
|             points.append( | ||||
|                 get_nearest_favorite(candidates, user, points + disallowed_points) | ||||
|             ) | ||||
| 
 | ||||
|         except AttributeError: | ||||
|             points.append(get_nearest_favorite(candidates, user, points)) | ||||
| 
 | ||||
|  | @ -518,17 +547,21 @@ def generate_path(user: User, disallowed_points: Iterable[BasePoint], hotel: Hot | |||
|     return points, path | ||||
| 
 | ||||
| 
 | ||||
| def calculate_distance(sample1: Event, samples: Iterable[Event], model: AnnoyIndex, rev_mapping): | ||||
| def calculate_distance( | ||||
|     sample1: Event, samples: Iterable[Event], model: AnnoyIndex, rev_mapping | ||||
| ): | ||||
|     metrics = [] | ||||
| 
 | ||||
|     for sample in samples: | ||||
|         metrics.append(model.get_distance(rev_mapping[sample1.oid], rev_mapping[sample.oid])) | ||||
|      | ||||
|         metrics.append( | ||||
|             model.get_distance(rev_mapping[sample1.oid], rev_mapping[sample.oid]) | ||||
|         ) | ||||
| 
 | ||||
|     return sum(metrics) / len(metrics) | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| def get_onboarding_attractions(): | ||||
|     sample_attractions = sample(list(Event.objects.filter(type='attraction')), 200) | ||||
|     sample_attractions = sample(list(Event.objects.filter(type="attraction")), 200) | ||||
|     first_attraction = choice(sample_attractions) | ||||
| 
 | ||||
|     attractions = [first_attraction] | ||||
|  | @ -537,12 +570,10 @@ def get_onboarding_attractions(): | |||
|         mx_dist = 0 | ||||
|         mx_attraction = None | ||||
|         for att in sample_attractions: | ||||
|             if att in attractions: continue  | ||||
|             if att in attractions: | ||||
|                 continue | ||||
|             local_dist = calculate_distance( | ||||
|                 att, | ||||
|                 attractions, | ||||
|                 attracion_model,  | ||||
|                 rev_attraction_mapping | ||||
|                 att, attractions, attracion_model, rev_attraction_mapping | ||||
|             ) | ||||
|             if local_dist > mx_dist: | ||||
|                 mx_dist = local_dist | ||||
|  | @ -552,4 +583,4 @@ def get_onboarding_attractions(): | |||
| 
 | ||||
| 
 | ||||
| def get_onboarding_hotels(stars=Iterable[int]): | ||||
|     return sample(list(Hotel.objects.filter(stars__in=stars)), 10) | ||||
|     return sample(list(Hotel.objects.filter(stars__in=stars)), 10) | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ | |||
| from rest_framework.generics import get_object_or_404 | ||||
| 
 | ||||
| from passfinder.events.models import BasePoint | ||||
| from passfinder.users.clickhouse_models import UserPreferenceClickHouse | ||||
| from passfinder.users.models import UserPreference | ||||
| 
 | ||||
| User = get_user_model() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user