From 83a266929c1b8042f194353ae67e6880f95fd2e9 Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Thu, 13 Apr 2023 15:47:58 +0200 Subject: [PATCH 1/2] Bulk event references by postal codes #428 --- project/cli/event.py | 8 ++++ project/services/event.py | 38 ++++++++++++++++++- project/services/event_search.py | 4 ++ project/services/reference.py | 12 +++--- tests/cli/test_event.py | 63 ++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 7 deletions(-) diff --git a/project/cli/event.py b/project/cli/event.py index 76c7c98..fa38172 100644 --- a/project/cli/event.py +++ b/project/cli/event.py @@ -1,3 +1,4 @@ +import click from flask.cli import AppGroup from project import app @@ -11,4 +12,11 @@ def update_recurring_dates(): event.update_recurring_dates() +@event_cli.command("create-bulk-references") +@click.argument("admin_unit_id") +@click.argument("postal_codes", nargs=-1) +def create_bulk_event_references(admin_unit_id, postal_codes): + event.create_bulk_event_references(admin_unit_id, list(postal_codes)) + + app.cli.add_command(event_cli) diff --git a/project/services/event.py b/project/services/event.py index 5b1891c..6d403c0 100644 --- a/project/services/event.py +++ b/project/services/event.py @@ -39,6 +39,7 @@ from project.models import ( sanitize_allday_instance, ) from project.services.event_search import EventSearchParams +from project.services.reference import upsert_event_reference from project.utils import get_pending_changes, get_place_str from project.views.utils import truncate @@ -102,6 +103,23 @@ def fill_event_filter(event_filter, params): func.ST_DistanceSphere(Location.coordinate, point) <= params.distance, ) + if params.postal_code: + if type(params.postal_code) is list: + postalCodes = params.postal_code + else: + postalCodes = [params.postal_code] + + postalCodeFilters = None + for postalCode in postalCodes: + postalCodeFilter = Location.postalCode.ilike(postalCode + "%") + if postalCodeFilters is not None: + postalCodeFilters = or_(postalCodeFilters, postalCodeFilter) + else: + postalCodeFilters = postalCodeFilter + + if postalCodeFilters is not None: + event_filter = and_(event_filter, postalCodeFilters) + if params.favored_by_user_id: user_favorite_exists = UserFavoriteEvents.query.filter( UserFavoriteEvents.event_id == Event.id, @@ -606,8 +624,6 @@ def create_ical_events_for_event(event: Event) -> list: # list[icalendar.Event] def create_ical_events_for_search( params: EventSearchParams, ) -> list: # list[icalendar.Event] - from project.services.event import create_ical_events_for_event, get_events_query - result = list() events = get_events_query(params).all() @@ -629,3 +645,21 @@ def update_recurring_dates(): db.session.commit() app.logger.info(f"{len(events)} event(s) were updated.") + + +def create_bulk_event_references(admin_unit_id: int, postalCodes: list): + params = EventSearchParams() + params.set_default_date_range() + params.postal_code = postalCodes + + query = get_events_query(params) + query = query.filter(Event.admin_unit_id != admin_unit_id) + + count = 0 + events = query.all() + for event in events: + if upsert_event_reference(event.id, admin_unit_id): + count = count + 1 + + db.session.commit() + app.logger.info(f"{count} reference(s) created.") diff --git a/project/services/event_search.py b/project/services/event_search.py index 6c6e0bb..31771cd 100644 --- a/project/services/event_search.py +++ b/project/services/event_search.py @@ -30,6 +30,7 @@ class EventSearchParams(object): self.sort = None self.status = None self.favored_by_user_id = None + self.postal_code = None @property def date_from(self): @@ -148,6 +149,9 @@ class EventSearchParams(object): if "event_list_id" in request.args: self.event_list_id = self.load_list_param("event_list_id") + if "postal_code" in request.args: + self.postal_code = self.load_list_param("postal_code") + if "sort" in request.args: self.sort = request.args["sort"] diff --git a/project/services/reference.py b/project/services/reference.py index 8299185..8048d9e 100644 --- a/project/services/reference.py +++ b/project/services/reference.py @@ -12,17 +12,19 @@ from project.models import ( def create_event_reference_for_request(request): + return upsert_event_reference(request.event_id, request.admin_unit_id) + + +def upsert_event_reference(event_id: int, admin_unit_id: int): result = EventReference.query.filter( and_( - EventReference.event_id == request.event_id, - EventReference.admin_unit_id == request.admin_unit_id, + EventReference.event_id == event_id, + EventReference.admin_unit_id == admin_unit_id, ) ).first() if result is None: - result = EventReference( - event_id=request.event_id, admin_unit_id=request.admin_unit_id - ) + result = EventReference(event_id=event_id, admin_unit_id=admin_unit_id) result.rating = 50 db.session.add(result) diff --git a/tests/cli/test_event.py b/tests/cli/test_event.py index c3c207b..407c78c 100644 --- a/tests/cli/test_event.py +++ b/tests/cli/test_event.py @@ -5,3 +5,66 @@ def test_update_recurring_dates(client, seeder, app): runner = app.test_cli_runner() result = runner.invoke(args=["event", "update-recurring-dates"]) assert result.exit_code == 0 + + +def _create_event(seeder, admin_unit_id, postalCode): + from project.models import Location + + return seeder.create_event( + admin_unit_id, + place_id=seeder.upsert_event_place( + admin_unit_id, + postalCode, + Location( + postalCode=postalCode, + ), + ), + ) + + +def test_create_bulk_event_references(client, seeder, app): + user_id, admin_unit_id = seeder.setup_base() + event_id_own = _create_event(seeder, admin_unit_id, "38640") + + other_admin_unit_id = seeder.create_admin_unit(user_id, "Other Crew", verified=True) + event_id_38640 = _create_event(seeder, other_admin_unit_id, "38640") + event_id_38690 = _create_event(seeder, other_admin_unit_id, "38690") + event_id_55555 = _create_event(seeder, other_admin_unit_id, "55555") + + runner = app.test_cli_runner() + result = runner.invoke( + args=[ + "event", + "create-bulk-references", + str(admin_unit_id), + "38640", + "38642", + "38644", + "38690", + ] + ) + assert result.exit_code == 0 + + with app.app_context(): + from project.models import EventReference + + assert ( + EventReference.query.filter(EventReference.admin_unit_id == admin_unit_id) + .filter(EventReference.event_id == event_id_38640) + .first() + ) + assert ( + EventReference.query.filter(EventReference.admin_unit_id == admin_unit_id) + .filter(EventReference.event_id == event_id_38690) + .first() + ) + assert ( + EventReference.query.filter(EventReference.admin_unit_id == admin_unit_id) + .filter(EventReference.event_id == event_id_55555) + .first() + ) is None + assert ( + EventReference.query.filter(EventReference.admin_unit_id == admin_unit_id) + .filter(EventReference.event_id == event_id_own) + .first() + ) is None From 48f1c73874aac3f0c8c3eca8d4106ccec6363739 Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Thu, 13 Apr 2023 22:04:11 +0200 Subject: [PATCH 2/2] Bulk event references by postal codes #428 --- project/services/event.py | 2 +- project/services/event_search.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/services/event.py b/project/services/event.py index 6d403c0..e0f4222 100644 --- a/project/services/event.py +++ b/project/services/event.py @@ -106,7 +106,7 @@ def fill_event_filter(event_filter, params): if params.postal_code: if type(params.postal_code) is list: postalCodes = params.postal_code - else: + else: # pragma: no cover postalCodes = [params.postal_code] postalCodeFilters = None diff --git a/project/services/event_search.py b/project/services/event_search.py index 31771cd..b122d15 100644 --- a/project/services/event_search.py +++ b/project/services/event_search.py @@ -149,7 +149,7 @@ class EventSearchParams(object): if "event_list_id" in request.args: self.event_list_id = self.load_list_param("event_list_id") - if "postal_code" in request.args: + if "postal_code" in request.args: # pragma: no cover self.postal_code = self.load_list_param("postal_code") if "sort" in request.args: