refactored code

This commit is contained in:
Alexander Karpov 2023-05-28 00:11:44 +03:00
parent f8f0902e97
commit dff6a050ea
13 changed files with 523 additions and 440 deletions

View File

@ -23,7 +23,7 @@ def _update_or_create_site_with_sequence(site_model, connection, domain, name):
# site is created. # site is created.
# To avoid this, we need to manually update DB sequence and make sure it's # To avoid this, we need to manually update DB sequence and make sure it's
# greater than the maximum value. # greater than the maximum value.
max_id = site_model.objects.order_by('-id').first().id max_id = site_model.objects.order_by("-id").first().id
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute("SELECT last_value from django_site_id_seq") cursor.execute("SELECT last_value from django_site_id_seq")
(current_id,) = cursor.fetchone() (current_id,) = cursor.fetchone()

View File

@ -1,47 +1,49 @@
city_in_hotels = {'Астрахань', city_in_hotels = {
'Балашиха', "Астрахань",
'Березники', "Балашиха",
'Благовещенск', "Березники",
'Владикавказ', "Благовещенск",
'Волгоград', "Владикавказ",
'Волгодонск', "Волгоград",
'Волжский', "Волгодонск",
'Воронеж', "Волжский",
'Грозный', "Воронеж",
'Дзержинск', "Грозный",
'Екатеринбург', "Дзержинск",
'Златоуст', "Екатеринбург",
'Ижевск', "Златоуст",
'Каменск-Уральский', "Ижевск",
'Киров', "Каменск-Уральский",
'Кисловодск', "Киров",
'Колпино', "Кисловодск",
'Комсомольск-на-Амуре', "Колпино",
'Копейск', "Комсомольск-на-Амуре",
'Кострома', "Копейск",
'Красноярск', "Кострома",
'Курган', "Красноярск",
'Люберцы', "Курган",
'Магнитогорск', "Люберцы",
'Махачкала', "Магнитогорск",
'Москва', "Махачкала",
'Мытищи', "Москва",
'Нальчик', "Мытищи",
'Нижнекамск', "Нальчик",
'Нижний Тагил', "Нижнекамск",
'Новочебоксарск', "Нижний Тагил",
'Одинцово', "Новочебоксарск",
'Омск', "Одинцово",
'Оренбург', "Омск",
'Орск', "Оренбург",
'Пермь', "Орск",
'Подольск', "Пермь",
'Пятигорск', "Подольск",
'Салават', "Пятигорск",
'Санкт-Петербург', "Салават",
'Томск', "Санкт-Петербург",
'Тюмень', "Томск",
'Уфа', "Тюмень",
'Хасавюрт', "Уфа",
'Химки', "Хасавюрт",
'Энгельс'} "Химки",
"Энгельс",
}

View File

@ -72,41 +72,39 @@ class RouteInputSerializer(serializers.Serializer):
child=serializers.ChoiceField([1, 2, 3, 4, 5]), child=serializers.ChoiceField([1, 2, 3, 4, 5]),
required=False, required=False,
allow_empty=True, allow_empty=True,
allow_null=True allow_null=True,
) )
what_to_see = serializers.ListField( what_to_see = serializers.ListField(
child=serializers.ChoiceField( child=serializers.ChoiceField(
[ [
'attractions', "attractions",
'museum', "museum",
'movie', "movie",
'concert', "concert",
'artwork', "artwork",
'plays', "plays",
'shop', "shop",
'gallery', "gallery",
'theme_park', "theme_park",
'viewpoint', "viewpoint",
'zoo' "zoo",
] ]
), ),
required=False, required=False,
allow_empty=True, allow_empty=True,
allow_null=True allow_null=True,
) )
where_stay = serializers.ListField( where_stay = serializers.ListField(
child=serializers.ChoiceField([ child=serializers.ChoiceField(["hotel", "apartment", "hostel"]),
'hotel', 'apartment', 'hostel'
]),
required=False, required=False,
allow_empty=True, allow_empty=True,
allow_null=True allow_null=True,
) )
where_eat = serializers.ListField( where_eat = serializers.ListField(
child=serializers.ChoiceField(['restaurant', 'bar', 'cafe']), child=serializers.ChoiceField(["restaurant", "bar", "cafe"]),
required=False, required=False,
allow_empty=True, allow_empty=True,
allow_null=True allow_null=True,
) )
with_kids = serializers.BooleanField(required=False, allow_null=True) with_kids = serializers.BooleanField(required=False, allow_null=True)
with_animals = serializers.BooleanField(required=False, allow_null=True) with_animals = serializers.BooleanField(required=False, allow_null=True)

View File

@ -59,72 +59,67 @@ def get(self, request):
request=RouteInputSerializer, responses={200: RouteSerializer(many=True)} request=RouteInputSerializer, responses={200: RouteSerializer(many=True)}
) )
def post(self, request): def post(self, request):
movement_mapping = { movement_mapping = {"walk": 3.0, "bike": 15.0, "scooter": 30.0, "auto": 50.0}
'walk': 3.0,
'bike': 15.0,
'scooter': 30.0,
'auto': 50.0
}
serializer = RouteInputSerializer(data=request.data) serializer = RouteInputSerializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
data = serializer.data data = serializer.data
city_id = data["city"] city_id = data["city"]
try: try:
start_date = datetime.strptime(data['date_from'], '%Y-%m-%d') start_date = datetime.strptime(data["date_from"], "%Y-%m-%d")
except: except:
start_date = None start_date = None
try: try:
end_date = datetime.strptime(data['date_to'], '%Y-%m-%d') end_date = datetime.strptime(data["date_to"], "%Y-%m-%d")
except: except:
end_date = None end_date = None
try: try:
movement = data['movement'] movement = data["movement"]
except KeyError: except KeyError:
movement = 'walk' movement = "walk"
hotel_stars = data['stars'] hotel_stars = data["stars"]
if hotel_stars is None: if hotel_stars is None:
hotel_stars = [] hotel_stars = []
hotel_type = data['where_stay'] hotel_type = data["where_stay"]
if hotel_type is None: if hotel_type is None:
hotel_type = ['hotel'] hotel_type = ["hotel"]
where_eat = data['where_eat'] where_eat = data["where_eat"]
if where_eat is None: if where_eat is None:
where_eat = ['restaurant', 'bar', 'cafe'] where_eat = ["restaurant", "bar", "cafe"]
what_to_see = data['what_to_see'] what_to_see = data["what_to_see"]
if what_to_see is None: if what_to_see is None:
what_to_see = [ what_to_see = [
'attractions', "attractions",
'museum', "museum",
'movie', "movie",
'concert', "concert",
'artwork', "artwork",
'plays', "plays",
'shop', "shop",
'gallery', "gallery",
'theme_park', "theme_park",
'viewpoint', "viewpoint",
'zoo' "zoo",
] ]
if 'hotel' not in hotel_type: if "hotel" not in hotel_type:
hotel_stars = [] hotel_stars = []
region = None
res = [] res = []
for _ in range(5): for _ in range(5):
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:
region = choice(City.objects.annotate(points_count=Count('points')).filter(title__in=city_in_hotels).filter(points_count__gt=400)) region = choice(
City.objects.annotate(points_count=Count("points"))
.filter(title__in=city_in_hotels)
.filter(points_count__gt=400)
)
if not start_date and end_date: if not start_date and end_date:
tour_length = choice([timedelta(days=i) for i in range(1, 4)]) tour_length = choice([timedelta(days=i) for i in range(1, 4)])
start_date = end_date - tour_length start_date = end_date - tour_length
@ -137,8 +132,6 @@ def post(self, request):
tour_length = choice([timedelta(days=i) for i in range(1, 4)]) tour_length = choice([timedelta(days=i) for i in range(1, 4)])
end_date = start_date + tour_length end_date = start_date + tour_length
print(request.user, region, start_date, end_date)
tour = generate_tour( tour = generate_tour(
request.user, request.user,
region, region,
@ -148,14 +141,16 @@ def post(self, request):
stars=hotel_stars, stars=hotel_stars,
hotel_type=hotel_type, hotel_type=hotel_type,
where_eat=where_eat, where_eat=where_eat,
what_to_see=what_to_see what_to_see=what_to_see,
)
res.append(
{
"city": region.title,
"date_from": start_date,
"date_to": end_date,
"path": tour[0],
}
) )
res.append({
'city': region.title,
'date_from': start_date,
'date_to': end_date,
'path': tour[0]
})
return Response(data=res) return Response(data=res)
@ -168,7 +163,10 @@ class ListRegionApiView(ListAPIView):
class ListCityApiView(ListAPIView): class ListCityApiView(ListAPIView):
serializer_class = CitySerializer serializer_class = CitySerializer
queryset = ( queryset = (
City.objects.annotate(points_count=Count('points')).filter(title__in=city_in_hotels).filter(points_count__gt=200).order_by('title') City.objects.annotate(points_count=Count("points"))
.filter(title__in=city_in_hotels)
.filter(points_count__gt=200)
.order_by("title")
) )

View File

@ -277,7 +277,7 @@ def get_json(self):
"lon": self.point.lon, "lon": self.point.lon,
"title": self.point.title, "title": self.point.title,
"description": self.point.description, "description": self.point.description,
"oid": self.point.oid "oid": self.point.oid,
}, },
"point_type": self.point_type, "point_type": self.point_type,
"time": self.duration, "time": self.duration,

View File

@ -1,5 +1,9 @@
from rest_framework import serializers from rest_framework import serializers
from passfinder.events.api.serializers import EventSerializer, HotelSerializer, ObjectRouteSerializer from passfinder.events.api.serializers import (
EventSerializer,
HotelSerializer,
ObjectRouteSerializer,
)
class TinderProceedSerializer(serializers.Serializer): class TinderProceedSerializer(serializers.Serializer):
@ -27,12 +31,16 @@ class HotelOnboardingRetrieve(serializers.Serializer):
class TinderGetEventFilterSerializer(serializers.Serializer): class TinderGetEventFilterSerializer(serializers.Serializer):
type = serializers.ListField(child=serializers.ChoiceField(['attraction', 'museum', 'movie', 'play', 'concert'])) type = serializers.ListField(
child=serializers.ChoiceField(
["attraction", "museum", "movie", "play", "concert"]
)
)
event = EventSerializer() event = EventSerializer()
class DailySelectionNodeSerializer(serializers.Serializer): class DailySelectionNodeSerializer(serializers.Serializer):
action = serializers.ChoiceField(['left', 'right']) action = serializers.ChoiceField(["left", "right"])
oid = serializers.CharField() oid = serializers.CharField()
@ -56,9 +64,23 @@ class StarSelectionSerializer(serializers.Serializer):
class CategorySelectionSerializer(serializers.Serializer): class CategorySelectionSerializer(serializers.Serializer):
categories = serializers.ListField(child=serializers.ChoiceField( categories = serializers.ListField(
['attractions', 'museum', 'movie', 'concert', 'artwork', 'plays', 'shop', 'gallery', 'theme_park', 'viewpoint', 'zoo'] child=serializers.ChoiceField(
)) [
"attractions",
"museum",
"movie",
"concert",
"artwork",
"plays",
"shop",
"gallery",
"theme_park",
"viewpoint",
"zoo",
]
)
)
class RecomendationNode(serializers.Serializer): class RecomendationNode(serializers.Serializer):
@ -66,6 +88,5 @@ class RecomendationNode(serializers.Serializer):
events = serializers.ListField(child=ObjectRouteSerializer()) events = serializers.ListField(child=ObjectRouteSerializer())
class SelfRecomendationSerializer(serializers.Serializer): class SelfRecomendationSerializer(serializers.Serializer):
recomendations = serializers.ListField(child=RecomendationNode(), write_only=True) recomendations = serializers.ListField(child=RecomendationNode(), write_only=True)

View File

@ -20,28 +20,34 @@ class TinderView(viewsets.GenericViewSet):
model = Event model = Event
queryset = Event.objects.all() queryset = Event.objects.all()
@action(methods=['GET'], detail=False, serializer_class=EventSerializer) @action(methods=["GET"], detail=False, serializer_class=EventSerializer)
def start(self, request: Request, *args: Any, **kwargs: Any): def start(self, request: Request, *args: Any, **kwargs: Any):
UserPreferences.objects.get_or_create(user=request.user) UserPreferences.objects.get_or_create(user=request.user)
event = EventSerializer(choice(Event.objects.all())) event = EventSerializer(choice(Event.objects.all()))
return Response(data=event.data, status=200) return Response(data=event.data, status=200)
@csrf_exempt @csrf_exempt
@action(methods=['POST'], detail=True, serializer_class=TinderProceedSerializer) @action(methods=["POST"], detail=True, serializer_class=TinderProceedSerializer)
def proceed(self, request: Request, pk): def proceed(self, request: Request, pk):
update_preferences_state(request.user, Event.objects.get(oid=pk), request.data['action']) update_preferences_state(
event = get_next_tinder(request.user, Event.objects.get(oid=pk), request.data['action']) request.user, Event.objects.get(oid=pk), request.data["action"]
)
event = get_next_tinder(
request.user, Event.objects.get(oid=pk), request.data["action"]
)
if event is None: if event is None:
return Response(data={}, status=404) return Response(data={}, status=404)
return Response(data={'event': EventSerializer(event).data}, status=200) return Response(data={"event": EventSerializer(event).data}, status=200)
@action(methods=['POST'], detail=False, serializer_class=TinderGetEventFilterSerializer) @action(
methods=["POST"], detail=False, serializer_class=TinderGetEventFilterSerializer
)
def get_event(self, request: Request): def get_event(self, request: Request):
# отдавать под пользователя # отдавать под пользователя
events = Event.objects.filter(type__in=request.data['type']) events = Event.objects.filter(type__in=request.data["type"])
return Response(data={ return Response(
'event': EventSerializer(choice(events)).data data={"event": EventSerializer(choice(events)).data}, status=200
}, status=200) )
class PersonalRecommendation(viewsets.GenericViewSet): class PersonalRecommendation(viewsets.GenericViewSet):
@ -49,15 +55,11 @@ class PersonalRecommendation(viewsets.GenericViewSet):
model = Event model = Event
queryset = Event.objects.all() queryset = Event.objects.all()
@action(methods=["GET"], detail=False, serializer_class=SelfRecomendationSerializer)
@action(methods=['GET'], detail=False, serializer_class=SelfRecomendationSerializer)
def recommendations(self, request, *args, **kwargs): def recommendations(self, request, *args, **kwargs):
return Response( return Response(data=get_personal_recomendations(request.user), status=200)
data=get_personal_recomendations(request.user),
status=200
)
@action(methods=['GET'], detail=True) @action(methods=["GET"], detail=True)
def get_nearest_user_distance(self, request, pk, *args, **kwargs): def get_nearest_user_distance(self, request, pk, *args, **kwargs):
request_point = pk request_point = pk
if len(Event.objects.filter(oid=pk)): if len(Event.objects.filter(oid=pk)):
@ -68,96 +70,90 @@ def get_nearest_user_distance(self, request, pk, *args, **kwargs):
request_point = Hotel.objects.get(oid=pk) request_point = Hotel.objects.get(oid=pk)
res = nearest_distance_points(request_point, request.user) res = nearest_distance_points(request_point, request.user)
return Response( return Response(
data=list( data=list(map(lambda event: EventSerializer(event).data, res)), status=200
map(
lambda event: EventSerializer(event).data,
res
)
),
status=200
) )
@action(methods=['GET'], detail=False, serializer_class=DailySelectionSerializerInput()) @action(
methods=["GET"], detail=False, serializer_class=DailySelectionSerializerInput()
)
def get_daily_selection(self, request, *args, **kwargs): def get_daily_selection(self, request, *args, **kwargs):
city = choice(City.objects.annotate(points_count=Count('points')).filter(points_count__gt=200)) city = choice(
City.objects.annotate(points_count=Count("points")).filter(
points_count__gt=200
)
)
events = sample(list(Event.objects.filter(city=city)), 10) events = sample(list(Event.objects.filter(city=city)), 10)
return Response( return Response(
data={ data={
'city': city.title, "city": city.title,
'events': list( "events": list(map(lambda event: EventSerializer(event).data, events)),
map(
lambda event: EventSerializer(event).data,
events
)
)
} }
) )
@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 = []
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"]))
path = generate_points_path(request.user, points, 3) path = generate_points_path(request.user, points, 3)
return Response( return Response(data={"path": path})
data={
'path': path
}
)
class OnboardingViewset(viewsets.GenericViewSet): class OnboardingViewset(viewsets.GenericViewSet):
serializer_class = EventSerializer serializer_class = EventSerializer
model = Event model = Event
queryset = Event.objects.all() queryset = Event.objects.all()
@action(methods=['POST'], detail=False, serializer_class=HotelOnboardingRetrieve) @action(methods=["POST"], detail=False, serializer_class=HotelOnboardingRetrieve)
def hotels(self, reqeust, *args, **kwargs): def hotels(self, reqeust, *args, **kwargs):
hotels = get_onboarding_hotels(reqeust.data['stars']) hotels = get_onboarding_hotels(reqeust.data["stars"])
res = HotelOnboardingRetrieve({'hotels': hotels}).data res = HotelOnboardingRetrieve({"hotels": hotels}).data
return Response(res, 200) return Response(res, 200)
@action(methods=['POST'], detail=False, serializer_class=EventOnboardingRetrieve) @action(methods=["POST"], detail=False, serializer_class=EventOnboardingRetrieve)
def event(self, request, *args, **kwargs): def event(self, request, *args, **kwargs):
events = get_onboarding_attractions() events = get_onboarding_attractions()
res = EventOnboardingRetrieve({'events': events}).data res = EventOnboardingRetrieve({"events": events}).data
return Response(res, 200) return Response(res, 200)
@action(methods=['GET'], detail=True) @action(methods=["GET"], detail=True)
def add_to_favorites(self, request, pk, *args, **kwargs): def add_to_favorites(self, request, pk, *args, **kwargs):
pref, _ = UserPreferences.objects.get_or_create(user=request.user) pref, _ = UserPreferences.objects.get_or_create(user=request.user)
event = Event.objects.get(oid=pk) event = Event.objects.get(oid=pk)
if event.type == 'attraction': if event.type == "attraction":
pref.prefferred_attractions.add(event) pref.prefferred_attractions.add(event)
elif event.type == 'museum': elif event.type == "museum":
pref.prefferred_museums.add(event) pref.prefferred_museums.add(event)
elif event.type == 'movie': elif event.type == "movie":
pref.preffered_movies.add(event) pref.preffered_movies.add(event)
elif event.type == 'play': elif event.type == "play":
pref.preffered_plays.add(event) pref.preffered_plays.add(event)
elif event.type == 'concert': elif event.type == "concert":
pref.preferred_concerts.add(event) pref.preferred_concerts.add(event)
pref.save() pref.save()
return Response(status=200) return Response(status=200)
@action(methods=['POST'], detail=False, serializer_class=StarSelectionSerializer) @action(methods=["POST"], detail=False, serializer_class=StarSelectionSerializer)
def set_hotel_stars(self, request, *args, **kwargs): def set_hotel_stars(self, request, *args, **kwargs):
up, _ = UserPreferences.objects.get_or_create(user=request.user) up, _ = UserPreferences.objects.get_or_create(user=request.user)
up.preferred_stars = request.data['stars'] up.preferred_stars = request.data["stars"]
up.save() up.save()
return Response(status=200) return Response(status=200)
@action(methods=['POST'], detail=False, serializer_class=CategorySelectionSerializer) @action(
methods=["POST"], detail=False, serializer_class=CategorySelectionSerializer
)
def set_categories(self, request, *args, **kwargs): def set_categories(self, request, *args, **kwargs):
up, _ = UserPreferences.objects.get_or_create(user=request.user) up, _ = UserPreferences.objects.get_or_create(user=request.user)
up.preferred_categories = request.data['categories'] up.preferred_categories = request.data["categories"]
up.save() up.save()
return Response(status=200) return Response(status=200)

View File

@ -7,29 +7,53 @@
class UserPreferences(models.Model): class UserPreferences(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
preffered_plays = models.ManyToManyField(Event, related_name='preffered_user_play') preffered_plays = models.ManyToManyField(Event, related_name="preffered_user_play")
unpreffered_plays = models.ManyToManyField(Event, related_name='unpreffered_users_play') unpreffered_plays = models.ManyToManyField(
Event, related_name="unpreffered_users_play"
)
preffered_movies = models.ManyToManyField(Event, related_name='preffered_user_movie') preffered_movies = models.ManyToManyField(
unpreffered_movies = models.ManyToManyField(Event, related_name='unpreffered_user_movie') Event, related_name="preffered_user_movie"
)
unpreffered_movies = models.ManyToManyField(
Event, related_name="unpreffered_user_movie"
)
preferred_concerts = models.ManyToManyField(Event, related_name='preffered_users_concert') preferred_concerts = models.ManyToManyField(
unpreferred_concerts = models.ManyToManyField(Event, related_name='unpreffered_users_concert') Event, related_name="preffered_users_concert"
)
unpreferred_concerts = models.ManyToManyField(
Event, related_name="unpreffered_users_concert"
)
prefferred_attractions = models.ManyToManyField(Event, related_name='preffered_users_attractions') prefferred_attractions = models.ManyToManyField(
unprefferred_attractions = models.ManyToManyField(Event, related_name='unpreffered_users_attractions') Event, related_name="preffered_users_attractions"
)
unprefferred_attractions = models.ManyToManyField(
Event, related_name="unpreffered_users_attractions"
)
prefferred_museums = models.ManyToManyField(Event, related_name='preffered_users_museums') prefferred_museums = models.ManyToManyField(
unprefferred_museums = models.ManyToManyField(Event, related_name='unpreffered_users_museums') Event, related_name="preffered_users_museums"
)
preferred_categories = ArrayField(base_field=models.CharField(max_length=100), null=True, blank=True) unprefferred_museums = models.ManyToManyField(
preferred_stars = ArrayField(base_field=models.IntegerField(), null=True, blank=True) Event, related_name="unpreffered_users_museums"
)
preferred_categories = ArrayField(
base_field=models.CharField(max_length=100), null=True, blank=True
)
preferred_stars = ArrayField(
base_field=models.IntegerField(), null=True, blank=True
)
class NearestEvent(models.Model): class NearestEvent(models.Model):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='nearest_model_rel') event = models.ForeignKey(
nearest = models.ManyToManyField(Event, related_name='nearest_model_rev_rel') Event, on_delete=models.CASCADE, related_name="nearest_model_rel"
)
nearest = models.ManyToManyField(Event, related_name="nearest_model_rev_rel")
""" """
from passfinder.recomendations.service.service import generate_tour from passfinder.recomendations.service.service import generate_tour
@ -50,9 +74,12 @@ class NearestEvent(models.Model):
""" """
class NearestHotel(models.Model): class NearestHotel(models.Model):
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, related_name='nearest_hotel_rel') hotel = models.ForeignKey(
nearest_events = models.ManyToManyField(Event, related_name='nearest_hotel_rev_rel') Hotel, on_delete=models.CASCADE, related_name="nearest_hotel_rel"
)
nearest_events = models.ManyToManyField(Event, related_name="nearest_hotel_rev_rel")
class NearestRestaurantToEvent(models.Model): class NearestRestaurantToEvent(models.Model):
@ -60,7 +87,6 @@ class NearestRestaurantToEvent(models.Model):
restaurants = models.ManyToManyField(Restaurant) restaurants = models.ManyToManyField(Restaurant)
class NearestRestaurantToHotel(models.Model): class NearestRestaurantToHotel(models.Model):
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE) hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
restaurants = models.ManyToManyField(Restaurant) restaurants = models.ManyToManyField(Restaurant)

View File

@ -21,6 +21,7 @@ def build_dict(list_mapping):
mapping.update({idx: elem}) mapping.update({idx: elem})
return mapping return mapping
def build_rev_dict(list_mapping): def build_rev_dict(list_mapping):
mapping = {} mapping = {}
for idx, elem in enumerate(list_mapping): for idx, elem in enumerate(list_mapping):
@ -28,37 +29,37 @@ def build_rev_dict(list_mapping):
return mapping return mapping
with open('passfinder/recomendations/service/mapping/attractions.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/attractions.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
attraction_mapping = build_dict(lst) attraction_mapping = build_dict(lst)
rev_attraction_mapping = build_rev_dict(lst) rev_attraction_mapping = build_rev_dict(lst)
with open('passfinder/recomendations/service/mapping/kino.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/kino.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
cinema_mapping = build_dict(lst) cinema_mapping = build_dict(lst)
rev_cinema_mapping = build_rev_dict(lst) rev_cinema_mapping = build_rev_dict(lst)
with open('passfinder/recomendations/service/mapping/spektakli.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/spektakli.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
plays_mapping = build_dict(lst) plays_mapping = build_dict(lst)
rev_plays_mapping = build_rev_dict(lst) rev_plays_mapping = build_rev_dict(lst)
with open('passfinder/recomendations/service/mapping/excursii.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/excursii.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
excursion_mapping = build_dict(lst) excursion_mapping = build_dict(lst)
rev_excursion_mapping = build_rev_dict(lst) rev_excursion_mapping = build_rev_dict(lst)
with open('passfinder/recomendations/service/mapping/concerts.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/concerts.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
concert_mapping = build_dict(lst) concert_mapping = build_dict(lst)
rev_concert_mapping = build_rev_dict(lst) rev_concert_mapping = build_rev_dict(lst)
with open('passfinder/recomendations/service/mapping/mus.pickle', 'rb') as file: with open("passfinder/recomendations/service/mapping/mus.pickle", "rb") as file:
lst = pickle.load(file) lst = pickle.load(file)
mus_mapping = build_dict(lst) mus_mapping = build_dict(lst)
rev_mus_mapping = build_rev_dict(lst) rev_mus_mapping = build_rev_dict(lst)

View File

@ -2,25 +2,25 @@
N_DIMENSIONAL = 768 N_DIMENSIONAL = 768
attracion_model = AnnoyIndex(N_DIMENSIONAL, 'angular') attracion_model = AnnoyIndex(N_DIMENSIONAL, "angular")
attracion_model.load('passfinder/recomendations/service/models/dost.ann') attracion_model.load("passfinder/recomendations/service/models/dost.ann")
cinema_model = AnnoyIndex(N_DIMENSIONAL, 'angular') cinema_model = AnnoyIndex(N_DIMENSIONAL, "angular")
cinema_model.load('passfinder/recomendations/service/models/kino.ann') cinema_model.load("passfinder/recomendations/service/models/kino.ann")
plays_model = AnnoyIndex(N_DIMENSIONAL, 'angular') plays_model = AnnoyIndex(N_DIMENSIONAL, "angular")
plays_model.load('passfinder/recomendations/service/models/spektatli.ann') plays_model.load("passfinder/recomendations/service/models/spektatli.ann")
excursion_model = AnnoyIndex(N_DIMENSIONAL, 'angular') excursion_model = AnnoyIndex(N_DIMENSIONAL, "angular")
excursion_model.load('passfinder/recomendations/service/models/excursii.ann') excursion_model.load("passfinder/recomendations/service/models/excursii.ann")
concert_model = AnnoyIndex(N_DIMENSIONAL, 'angular') concert_model = AnnoyIndex(N_DIMENSIONAL, "angular")
concert_model.load('passfinder/recomendations/service/models/concerts.ann') concert_model.load("passfinder/recomendations/service/models/concerts.ann")
mus_model = AnnoyIndex(N_DIMENSIONAL, 'angular') mus_model = AnnoyIndex(N_DIMENSIONAL, "angular")
mus_model.load('passfinder/recomendations/service/models/mus.ann') mus_model.load("passfinder/recomendations/service/models/mus.ann")

View File

@ -51,12 +51,7 @@ def nearest_attraction(attraction, nearest_n):
def nearest_mus(museum, nearest_n): def nearest_mus(museum, nearest_n):
return get_nearest_( return get_nearest_(
museum, museum, "museum", mus_mapping, rev_mus_mapping, nearest_n, mus_model
"museum",
mus_mapping,
rev_mus_mapping,
nearest_n,
mus_model
) )
@ -101,9 +96,9 @@ def get_nearest_event(event, nearest_n):
return nearest_concert(event, nearest_n) return nearest_concert(event, nearest_n)
if event.type == "movie": if event.type == "movie":
return nearest_movie(event, nearest_n) return nearest_movie(event, nearest_n)
if event.type == 'museum': if event.type == "museum":
return nearest_mus(event, nearest_n) return nearest_mus(event, nearest_n)
if event.type == 'attraction': if event.type == "attraction":
return nearest_attraction(event, nearest_n) return nearest_attraction(event, nearest_n)
@ -288,10 +283,7 @@ def generate_nearest_rest():
all_events = list(Event.objects.all()) all_events = list(Event.objects.all())
for i, rest in enumerate(Restaurant.objects.all()): for i, rest in enumerate(Restaurant.objects.all()):
sorted_events = list( sorted_events = list(
sorted( sorted(all_events.copy(), key=lambda event: dist_func(rest, event))
all_events.copy(),
key=lambda event: dist_func(rest, event)
)
) )
nearest = NearestEventToRestaurant.objects.create(restaurant=rest) nearest = NearestEventToRestaurant.objects.create(restaurant=rest)
nearest.events.set(sorted_events[0:100]) nearest.events.set(sorted_events[0:100])
@ -360,7 +352,6 @@ def match_restaurants():
print(i) print(i)
def calculate_mean_metric( def calculate_mean_metric(
favorite_events: Iterable[Event], favorite_events: Iterable[Event],
target_event: Event, target_event: Event,
@ -393,10 +384,12 @@ def calculate_favorite_metric(event: Event, user: User):
if event.type == "movie": if event.type == "movie":
preferred = pref.preffered_movies.all() preferred = pref.preffered_movies.all()
return calculate_mean_metric(preferred, event, cinema_model, rev_cinema_mapping) return calculate_mean_metric(preferred, event, cinema_model, rev_cinema_mapping)
if event.type == 'attraction': if event.type == "attraction":
preferred = pref.prefferred_attractions.all() preferred = pref.prefferred_attractions.all()
return calculate_mean_metric(preferred, event, attracion_model, rev_attraction_mapping) return calculate_mean_metric(
if event.type == 'museum': preferred, event, attracion_model, rev_attraction_mapping
)
if event.type == "museum":
preferred = pref.prefferred_museums.all() preferred = pref.prefferred_museums.all()
return calculate_mean_metric(preferred, event, mus_model, rev_mus_mapping) return calculate_mean_metric(preferred, event, mus_model, rev_mus_mapping)
return 10 return 10
@ -430,23 +423,15 @@ def get_nearest_favorite(
base_event: Event, base_event: Event,
exclude_events: Iterable[Event] = [], exclude_events: Iterable[Event] = [],
velocity=3.0, velocity=3.0,
top_k=1 top_k=1,
): ):
sorted_events = list( sorted_events = list(
sorted( sorted(
filter(lambda event: event not in exclude_events, events), filter(lambda event: event not in exclude_events, events),
key=lambda event: key=lambda event: calculate_favorite_metric(event, user)
calculate_favorite_metric(event, user) * * get_exponential_koef(time_func(dist_func(event, base_event), velocity))
get_exponential_koef( * get_category_similarity_coef(event, user),
time_func(
dist_func(
event, base_event
),
velocity
)
) *
get_category_similarity_coef(event, user)
) )
) )
@ -465,7 +450,6 @@ def time_func(km_distance: float, velocity: float):
return timedelta(minutes=(km_distance) / (velocity / 60)) return timedelta(minutes=(km_distance) / (velocity / 60))
def generate_route(point1: BasePoint, point2: BasePoint, velocity): def generate_route(point1: BasePoint, point2: BasePoint, velocity):
distance = dist_func(point1, point2) distance = dist_func(point1, point2)
time = time_func(distance, velocity) time = time_func(distance, velocity)
@ -483,7 +467,7 @@ def generate_point(point: BasePoint):
"point": event_data, "point": event_data,
"point_type": "point", "point_type": "point",
"time": timedelta(minutes=90 + choice(range(-10, 90, 10))).seconds, "time": timedelta(minutes=90 + choice(range(-10, 90, 10))).seconds,
"distance": 0 "distance": 0,
} }
@ -494,14 +478,18 @@ def generate_restaurant(point: BasePoint):
"type": "point", "type": "point",
"point": rest_data, "point": rest_data,
"point_type": "restaurant", "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) hotels = sample(list(Hotel.objects.filter(city=city)), 5)
pool = Pool(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( def generate_tour(
@ -511,9 +499,21 @@ def generate_tour(
end_date: datetime.date, end_date: datetime.date,
avg_velocity=3.0, avg_velocity=3.0,
stars=[], stars=[],
hotel_type=['hotel', 'hostel', 'apartment'], hotel_type=["hotel", "hostel", "apartment"],
where_eat=['restaurant', 'bar', 'cafe'], where_eat=["restaurant", "bar", "cafe"],
what_to_see=['attractions', 'museum', 'movie', 'concert', 'artwork', 'plays', 'shop', 'gallery', 'theme_park', 'viewpoint', 'zoo'] what_to_see=[
"attractions",
"museum",
"movie",
"concert",
"artwork",
"plays",
"shop",
"gallery",
"theme_park",
"viewpoint",
"zoo",
],
): ):
UserPreferences.objects.get_or_create(user=user) UserPreferences.objects.get_or_create(user=user)
@ -536,15 +536,10 @@ def generate_tour(
disallowed_rest, disallowed_rest,
avg_velocity, avg_velocity,
where_eat=where_eat, where_eat=where_eat,
what_to_see=what_to_see what_to_see=what_to_see,
) )
points.extend(local_points) points.extend(local_points)
paths.append( paths.append({"date": current_date, "paths": local_paths})
{
'date': current_date,
'paths': local_paths
}
)
disallowed_rest = local_disallowed_rest disallowed_rest = local_disallowed_rest
current_date += timedelta(days=1) current_date += timedelta(days=1)
return paths, points return paths, points
@ -557,7 +552,7 @@ def generate_hotel(hotel: Hotel):
"point": hotel_data, "point": hotel_data,
"point_type": "hotel", "point_type": "hotel",
"time": 0, "time": 0,
"distance": 0 "distance": 0,
} }
@ -575,26 +570,37 @@ def nearest_distance_points(point: BasePoint, user: User, velocity: float=3.0):
return top_nearest return top_nearest
def generate_path( def generate_path(
user: User, user: User,
disallowed_points: Iterable[BasePoint], disallowed_points: Iterable[BasePoint],
hotel: Hotel, hotel: Hotel,
disallowed_rests: Iterable[Restaurant], disallowed_rests: Iterable[Restaurant],
avg_velocity: float, avg_velocity: float,
where_eat=['restaurant', 'bar', 'cafe'], where_eat=["restaurant", "bar", "cafe"],
what_to_see=['attractions', 'museum', 'movie', 'concert', 'artwork', 'plays', 'shop', 'gallery', 'theme_park', 'viewpoint', 'zoo'] what_to_see=[
"attractions",
"museum",
"movie",
"concert",
"artwork",
"plays",
"shop",
"gallery",
"theme_park",
"viewpoint",
"zoo",
],
): ):
allowed_types = [ allowed_types = [
'museum', "museum",
'attraction', "attraction",
'artwork', "artwork",
'shop', "shop",
'gallery', "gallery",
'theme_park', "theme_park",
'zoo', "zoo",
'other', "other",
'viewpoint' "viewpoint",
] ]
if len(set(allowed_types) & set(what_to_see)) == 0: if len(set(allowed_types) & set(what_to_see)) == 0:
allowed_types = what_to_see allowed_types = what_to_see
@ -602,9 +608,15 @@ def generate_path(
allowed_types = list(set(allowed_types) & set(what_to_see)) allowed_types = list(set(allowed_types) & set(what_to_see))
print(allowed_types, hotel) print(allowed_types, hotel)
if isinstance(hotel, City): if isinstance(hotel, City):
start_points_candidate = Restaurant.objects.filter(city=hotel).filter(~Q(oid__in=disallowed_rests)) start_points_candidate = Restaurant.objects.filter(city=hotel).filter(
~Q(oid__in=disallowed_rests)
)
else: else:
start_points_candidate = NearestRestaurantToHotel.objects.filter(hotel=hotel).first().restaurants.filter(~Q(oid__in=disallowed_rests)) start_points_candidate = (
NearestRestaurantToHotel.objects.filter(hotel=hotel)
.first()
.restaurants.filter(~Q(oid__in=disallowed_rests))
)
if len(start_points_candidate.filter(type__in=where_eat)): if len(start_points_candidate.filter(type__in=where_eat)):
start_points_candidate = start_points_candidate.filter(type__in=where_eat) start_points_candidate = start_points_candidate.filter(type__in=where_eat)
@ -612,7 +624,11 @@ def generate_path(
start_point = start_points_candidate[0] start_point = start_points_candidate[0]
disallowed_rests.append(start_point.oid) disallowed_rests.append(start_point.oid)
candidates = NearestEventToRestaurant.objects.get(restaurant=start_point).events.all().filter(type__in=allowed_types) candidates = (
NearestEventToRestaurant.objects.get(restaurant=start_point)
.events.all()
.filter(type__in=allowed_types)
)
points = [start_point] points = [start_point]
@ -620,22 +636,26 @@ def generate_path(
path = [ path = [
generate_hotel(hotel), generate_hotel(hotel),
generate_route(start_point, hotel, avg_velocity), generate_route(start_point, hotel, avg_velocity),
generate_restaurant(start_point) generate_restaurant(start_point),
] ]
else: else:
path = [ path = [generate_restaurant(start_point)]
generate_restaurant(start_point)
]
start_time = datetime.combine(datetime.now(), time(hour=10)) start_time = datetime.combine(datetime.now(), time(hour=10))
how_many_eat = 1 how_many_eat = 1
while start_time.hour < 22 and start_time.day == datetime.now().day: 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): if (start_time.hour > 14 and how_many_eat == 1) or (
start_time.hour > 20 and how_many_eat == 2
):
print(points, start_time) print(points, start_time)
try: try:
point_candidates = NearestRestaurantToEvent.objects.filter(event=points[-1]).first().restaurants.filter(~Q(oid__in=disallowed_rests)) point_candidates = (
NearestRestaurantToEvent.objects.filter(event=points[-1])
.first()
.restaurants.filter(~Q(oid__in=disallowed_rests))
)
if len(point_candidates.filter(type__in=where_eat)): if len(point_candidates.filter(type__in=where_eat)):
point_candidates = point_candidates.filter(type__in=where_eat) point_candidates = point_candidates.filter(type__in=where_eat)
point = point_candidates[0] point = point_candidates[0]
@ -643,41 +663,51 @@ def generate_path(
disallowed_rests.append(point.oid) disallowed_rests.append(point.oid)
points.append(point) points.append(point)
candidates = NearestEventToRestaurant.objects.get(restaurant=point).events.all().filter(type__in=allowed_types) candidates = (
NearestEventToRestaurant.objects.get(restaurant=point)
.events.all()
.filter(type__in=allowed_types)
)
if len(candidates) < 2: if len(candidates) < 2:
candidates = NearestEventToRestaurant.objects.get(restaurant=point).events.all() candidates = NearestEventToRestaurant.objects.get(
restaurant=point
).events.all()
path.append(generate_restaurant(points[-1])) path.append(generate_restaurant(points[-1]))
start_time += timedelta(seconds=path[-1]['time']) start_time += timedelta(seconds=path[-1]["time"])
how_many_eat += 1 how_many_eat += 1
continue continue
except: except:
return points, path, disallowed_rests return points, path, disallowed_rests
if start_time.hour > 17: if start_time.hour > 17:
allowed_types = [ allowed_types = [
'play', "play",
'concert', "concert",
'movie', "movie",
'shop', "shop",
'gallery', "gallery",
'theme_park', "theme_park",
'viewpoint' "viewpoint",
] ]
if len(set(allowed_types) & set(what_to_see)) == 0: if len(set(allowed_types) & set(what_to_see)) == 0:
allowed_types = what_to_see allowed_types = what_to_see
else: else:
allowed_types = list(set(allowed_types) & set(what_to_see)) allowed_types = list(set(allowed_types) & set(what_to_see))
if candidates is None: 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 len(candidates) < 2: if len(candidates) < 2:
candidates = NearestEvent.objects.get(event=points[-1]).nearest.all() candidates = NearestEvent.objects.get(event=points[-1]).nearest.all()
try: try:
points.append(get_nearest_favorite(candidates, user, points[-1], points + disallowed_points)) points.append(
get_nearest_favorite(
candidates, user, points[-1], points + disallowed_points
)
)
except: except:
points.append(get_nearest_favorite(candidates, user, points[-1], points)) points.append(get_nearest_favorite(candidates, user, points[-1], points))
@ -716,12 +746,10 @@ def get_onboarding_attractions():
mx_dist = 0 mx_dist = 0
mx_attraction = None mx_attraction = None
for att in sample_attractions: for att in sample_attractions:
if att in attractions: continue if att in attractions:
continue
local_dist = calculate_distance( local_dist = calculate_distance(
att, att, attractions, attracion_model, rev_attraction_mapping
attractions,
attracion_model,
rev_attraction_mapping
) )
if local_dist > mx_dist: if local_dist > mx_dist:
mx_dist = local_dist mx_dist = local_dist
@ -737,12 +765,20 @@ def get_onboarding_hotels(stars=Iterable[int]):
def generate_points_path(user: User, points: Iterable[Event], velocity=3.0): def generate_points_path(user: User, points: Iterable[Event], velocity=3.0):
if len(points) < 7: if len(points) < 7:
candidates = NearestEvent.objects.get(event=points[0]).nearest.all() candidates = NearestEvent.objects.get(event=points[0]).nearest.all()
points.extend(list(get_nearest_favorite(candidates, user, points[0], [], velocity, 7-len(points)))) points.extend(
list(
get_nearest_favorite(
candidates, user, points[0], [], velocity, 7 - len(points)
)
)
)
dist_matrix = [[0 for j in range(len(points))] for i in range(len(points))] dist_matrix = [[0 for j in range(len(points))] for i in range(len(points))]
for i in range(len(dist_matrix)): for i in range(len(dist_matrix)):
for j in range(len(dist_matrix)): for j in range(len(dist_matrix)):
dist_matrix[i][j] = time_func(dist_func(points[i], points[j]), velocity).seconds dist_matrix[i][j] = time_func(
dist_func(points[i], points[j]), velocity
).seconds
for i in range(len(dist_matrix)): for i in range(len(dist_matrix)):
dist_matrix[i][0] = 0 dist_matrix[i][0] = 0
dist_matrix = np.array(dist_matrix) dist_matrix = np.array(dist_matrix)
@ -755,14 +791,9 @@ def generate_points_path(user: User, points: Iterable[Event], velocity=3.0):
visited_points = [perm_pts[0]] visited_points = [perm_pts[0]]
for pt in perm_pts[1:]: for pt in perm_pts[1:]:
res.extend([ res.extend(
generate_route( [generate_route(visited_points[-1], pt, velocity), generate_point(pt)]
visited_points[-1], )
pt,
velocity
),
generate_point(pt)
])
visited_points.append(pt) visited_points.append(pt)
return res return res
@ -777,21 +808,19 @@ def flat_list(lst):
def range_candidates(candidates, user, favorite_events): def range_candidates(candidates, user, favorite_events):
model_mappings = { model_mappings = {
'attraction': [attracion_model, rev_attraction_mapping], "attraction": [attracion_model, rev_attraction_mapping],
'museum': [mus_model, rev_mus_mapping], "museum": [mus_model, rev_mus_mapping],
'movie': [cinema_model, rev_cinema_mapping], "movie": [cinema_model, rev_cinema_mapping],
'concert': [concert_model, rev_concert_mapping], "concert": [concert_model, rev_concert_mapping],
'plays': [plays_model, rev_plays_mapping] "plays": [plays_model, rev_plays_mapping],
} }
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, candidates,
key=lambda cand: calculate_mean_metric( key=lambda cand: calculate_mean_metric(
favorite_events, favorite_events, cand, *model_mappings[cand.type]
cand, ),
*model_mappings[cand.type]
)
) )
return candidates[0:10] return candidates[0:10]
return sample(candidates, 10) return sample(candidates, 10)
@ -800,80 +829,92 @@ def range_candidates(candidates, user, favorite_events):
def get_personal_recomendations(user): def get_personal_recomendations(user):
up, _ = UserPreferences.objects.get_or_create(user=user) up, _ = UserPreferences.objects.get_or_create(user=user)
candidates_generate_strategy = { candidates_generate_strategy = {
'plays': [lambda pref: flat_list( "plays": [
lambda pref: flat_list(
list( list(
map( map(
lambda cand: nearest_plays( lambda cand: nearest_plays(cand, 30), pref.preffered_plays.all()
cand, 30
),
pref.preffered_plays.all()
) )
), ),
), lambda pref: pref.preffered_plays.all()], ),
'movie': [lambda pref: flat_list( lambda pref: pref.preffered_plays.all(),
],
"movie": [
lambda pref: flat_list(
list( list(
map( map(
lambda cand: nearest_movie( lambda cand: nearest_movie(cand, 30),
cand, 30 pref.preffered_movies.all(),
),
pref.preffered_movies.all()
) )
), ),
), lambda pref: pref.preffered_movies.all()], ),
'concert': [lambda pref: flat_list( lambda pref: pref.preffered_movies.all(),
],
"concert": [
lambda pref: flat_list(
list( list(
map( map(
lambda cand: nearest_concert( lambda cand: nearest_concert(cand, 30),
cand, 30 pref.preferred_concerts.all(),
),
pref.preferred_concerts.all()
) )
), ),
), lambda pref: pref.preferred_concerts.all()], ),
'attractions': [lambda pref: flat_list( lambda pref: pref.preferred_concerts.all(),
],
"attractions": [
lambda pref: flat_list(
list( list(
map( map(
lambda cand: nearest_attraction( lambda cand: nearest_attraction(cand, 30),
cand, 30 pref.prefferred_attractions.all(),
),
pref.prefferred_attractions.all()
) )
), ),
), lambda pref: pref.prefferred_attractions.all()], ),
'museum': [lambda pref: flat_list( lambda pref: pref.prefferred_attractions.all(),
],
"museum": [
lambda pref: flat_list(
list( list(
map( map(
lambda cand: nearest_mus( lambda cand: nearest_mus(cand, 30),
cand, 30 pref.prefferred_museums.all(),
),
pref.prefferred_museums.all()
) )
), ),
), lambda pref: pref.prefferred_museums.all()], ),
'shop': [lambda pref: sample(list(Event.objects.filter(type='shop')), 10), lambda x: []], lambda pref: pref.prefferred_museums.all(),
'gallery': [lambda pref: sample(list(Event.objects.filter(type='gallery')), 10), lambda x: []], ],
'theme_park': [lambda pref: sample(list(Event.objects.filter(type='theme_park')), 10), lambda x: []], "shop": [
'viewpoint': [lambda pref: sample(list(Event.objects.filter(type='viewpoint')), 10), lambda x: []], lambda pref: sample(list(Event.objects.filter(type="shop")), 10),
'zoo': [lambda pref: sample(list(Event.objects.filter(type='zoo')), 10), lambda x: []], lambda x: [],
],
"gallery": [
lambda pref: sample(list(Event.objects.filter(type="gallery")), 10),
lambda x: [],
],
"theme_park": [
lambda pref: sample(list(Event.objects.filter(type="theme_park")), 10),
lambda x: [],
],
"viewpoint": [
lambda pref: sample(list(Event.objects.filter(type="viewpoint")), 10),
lambda x: [],
],
"zoo": [
lambda pref: sample(list(Event.objects.filter(type="zoo")), 10),
lambda x: [],
],
} }
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)
ranged = range_candidates( ranged = range_candidates(
candidates, candidates, user, candidates_generate_strategy[category_candidate][1](up)
user,
candidates_generate_strategy[category_candidate][1](up)
) )
res.append( res.append(
{ {
'category': category_candidate, "category": category_candidate,
'events': list( "events": list(map(lambda x: ObjectRouteSerializer(x).data, ranged)),
map(
lambda x: ObjectRouteSerializer(x).data,
ranged
)
)
} }
) )
return res return res