diff --git a/src/onegov/landsgemeinde/custom.py b/src/onegov/landsgemeinde/custom.py
index 3bb6d71c29..23e8ef6c31 100644
--- a/src/onegov/landsgemeinde/custom.py
+++ b/src/onegov/landsgemeinde/custom.py
@@ -85,7 +85,7 @@ def get_top_navigation(
yield ( # type:ignore[misc]
Bunch(id=-1, access='public', published=True),
Link(
- text=_('Assemblies'),
+ text=_('Archive'),
url=request.class_link(AssemblyCollection)
),
()
diff --git a/src/onegov/landsgemeinde/layouts/assembly.py b/src/onegov/landsgemeinde/layouts/assembly.py
index 36d82d8edf..ea6484bd89 100644
--- a/src/onegov/landsgemeinde/layouts/assembly.py
+++ b/src/onegov/landsgemeinde/layouts/assembly.py
@@ -19,7 +19,7 @@ class AssemblyCollectionLayout(DefaultLayout):
@cached_property
def title(self) -> str:
- return _('Assemblies')
+ return _('Archive')
@cached_property
def og_description(self) -> str:
@@ -74,7 +74,7 @@ def breadcrumbs(self) -> list[Link]:
return [
Link(_('Homepage'), self.homepage_url),
Link(
- _('Assemblies'),
+ _('Archive'),
self.request.link(self.assembly_collection())
),
Link(self.title, self.request.link(self.model))
diff --git a/src/onegov/landsgemeinde/templates/macros.pt b/src/onegov/landsgemeinde/templates/macros.pt
index 43192eadd6..fd81b1e949 100644
--- a/src/onegov/landsgemeinde/templates/macros.pt
+++ b/src/onegov/landsgemeinde/templates/macros.pt
@@ -244,7 +244,6 @@
- Auskunft
more…
diff --git a/src/onegov/search/indexer.py b/src/onegov/search/indexer.py
index 067e62849d..9ace8171ba 100644
--- a/src/onegov/search/indexer.py
+++ b/src/onegov/search/indexer.py
@@ -10,6 +10,8 @@
from operator import itemgetter
from queue import Queue, Empty, Full
+from sqlalchemy.orm.exc import ObjectDeletedError
+
from onegov.core.utils import is_non_string_iterable
from onegov.search import index_log, log, Searchable, utils
from onegov.search.errors import SearchOfflineError
@@ -907,59 +909,65 @@ def put(self, translation: 'Task') -> None:
log.error('The orm event translator queue is full!')
def index(self, schema: str, obj: Searchable) -> None:
- if obj.es_skip:
- return
+ try:
+ if obj.es_skip:
+ return
- if obj.es_language == 'auto':
- language = self.detector.detect_object_language(obj)
- else:
- language = obj.es_language
+ if obj.es_language == 'auto':
+ language = self.detector.detect_object_language(obj)
+ else:
+ language = obj.es_language
+
+ translation: IndexTask = {
+ 'action': 'index',
+ 'id': getattr(obj, obj.es_id),
+ 'id_key': obj.es_id,
+ 'schema': schema,
+ 'type_name': obj.es_type_name, # FIXME: not needed for fts
+ 'tablename': obj.__tablename__, # type:ignore[attr-defined]
+ 'language': language,
+ 'properties': {}
+ }
- translation: IndexTask = {
- 'action': 'index',
- 'id': getattr(obj, obj.es_id),
- 'id_key': obj.es_id,
- 'schema': schema,
- 'type_name': obj.es_type_name, # FIXME: not needed for fts
- 'tablename': obj.__tablename__, # type:ignore[attr-defined]
- 'language': language,
- 'properties': {}
- }
+ mapping_ = self.mappings[obj.es_type_name].for_language(language)
- mapping_ = self.mappings[obj.es_type_name].for_language(language)
+ for prop, mapping in mapping_.items():
- for prop, mapping in mapping_.items():
+ if prop == 'es_suggestion':
+ continue
- if prop == 'es_suggestion':
- continue
+ convert = self.converters.get(mapping['type'], lambda v: v)
+ raw = getattr(obj, prop)
- convert = self.converters.get(mapping['type'], lambda v: v)
- raw = getattr(obj, prop)
+ if is_non_string_iterable(raw):
+ translation['properties'][prop] = [convert(v) for v in raw]
+ else:
+ translation['properties'][prop] = convert(raw)
- if is_non_string_iterable(raw):
- translation['properties'][prop] = [convert(v) for v in raw]
+ if obj.es_public:
+ contexts = {'es_suggestion_context': ['public']}
else:
- translation['properties'][prop] = convert(raw)
+ contexts = {'es_suggestion_context': ['private']}
- if obj.es_public:
- contexts = {'es_suggestion_context': ['public']}
- else:
- contexts = {'es_suggestion_context': ['private']}
-
- suggestion = obj.es_suggestion
+ suggestion = obj.es_suggestion
- if is_non_string_iterable(suggestion):
- translation['properties']['es_suggestion'] = {
- 'input': suggestion,
- 'contexts': contexts
- }
- else:
- translation['properties']['es_suggestion'] = {
- 'input': [suggestion],
- 'contexts': contexts
- }
+ if is_non_string_iterable(suggestion):
+ translation['properties']['es_suggestion'] = {
+ 'input': suggestion,
+ 'contexts': contexts
+ }
+ else:
+ translation['properties']['es_suggestion'] = {
+ 'input': [suggestion],
+ 'contexts': contexts
+ }
- self.put(translation)
+ self.put(translation)
+ except ObjectDeletedError as ex:
+ if hasattr(obj, 'id'):
+ log.error(f'Object {obj.id} was deleted before indexing: {ex}')
+ else:
+ log.error(f'Object {obj} was deleted before indexing: {ex}')
def delete(self, schema: str, obj: Searchable) -> None:
diff --git a/tests/onegov/fsi/test_models.py b/tests/onegov/fsi/test_models.py
index 1b4652dffd..00e0afb9c7 100644
--- a/tests/onegov/fsi/test_models.py
+++ b/tests/onegov/fsi/test_models.py
@@ -1,4 +1,6 @@
import datetime
+
+from freezegun import freeze_time
from sedate import utcnow
from onegov.fsi.models.course_attendee import CourseAttendee
@@ -44,57 +46,67 @@ def test_attendee(
def test_course_event(scenario):
-
- scenario.add_attendee()
- scenario.add_course(name='Course')
- scenario.add_course_event(scenario.latest_course, max_attendees=20)
- delta = datetime.timedelta(days=366)
-
- # Add a participant via a subscription
- event = scenario.latest_event
- scenario.add_subscription(event, None, dummy_desc='Placeholder')
- scenario.add_subscription(event, scenario.latest_attendee)
-
- # Add inactive attendee
- scenario.add_attendee(active=False)
- scenario.add_subscription(event, scenario.latest_attendee)
-
- scenario.commit()
- scenario.refresh()
-
- event = scenario.latest_event
- assert event.subscriptions.count() == 3
- assert event.attendees.count() == 2
- assert event.available_seats == 20 - 3
- assert event.possible_subscribers().first() is None
-
- # Test possible and excluded subscribers
- scenario.add_attendee(username='2@example.org')
- attendee_2 = scenario.latest_attendee
-
- # event = scenario.latest_event
- assert event.course
- assert event.possible_subscribers(year=event.end.year).all() == [
- attendee_2
- ]
-
- scenario.add_course_event(
- scenario.latest_course,
- start=event.start + delta, end=event.end + delta,
- max_attendees=20
- )
- event2 = scenario.latest_event
-
- # Event for a year later, exclude the one who has a subscription to this
- # course
- assert event.possible_subscribers(year=event.end.year + 1).count() == 1
- assert event2.possible_subscribers(year=event.end.year).count() == 1
- assert event2.possible_subscribers(year=event.end.year + 1).count() == 2
- assert event.possible_subscribers(external_only=True).count() == 0
- assert event.excluded_subscribers().count() == 2
- assert event2.possible_subscribers().first() == attendee_2
-
- assert scenario.latest_course.future_events.count() == 2
+ # if current date is last or second last day of the year, then freeze to
+ # 28th of december
+ if utcnow().date().month == 12 and utcnow().date().day in (30, 31):
+ freeze_date = '2024-12-28'
+ else:
+ freeze_date = utcnow().date()
+
+ with freeze_time(freeze_date):
+ scenario.add_attendee()
+ scenario.add_course(name='Course')
+ scenario.add_course_event(scenario.latest_course, max_attendees=20)
+ delta = datetime.timedelta(days=366)
+
+ # Add a participant via a subscription
+ event = scenario.latest_event
+ scenario.add_subscription(event, None, dummy_desc='Placeholder')
+ scenario.add_subscription(event, scenario.latest_attendee)
+
+ # Add inactive attendee
+ scenario.add_attendee(active=False)
+ scenario.add_subscription(event, scenario.latest_attendee)
+
+ scenario.commit()
+ scenario.refresh()
+
+ event = scenario.latest_event
+ assert event.subscriptions.count() == 3
+ assert event.attendees.count() == 2
+ assert event.available_seats == 20 - 3
+ assert event.possible_subscribers().first() is None
+
+ # Test possible and excluded subscribers
+ scenario.add_attendee(username='2@example.org')
+ attendee_2 = scenario.latest_attendee
+
+ # event = scenario.latest_event
+ assert event.course
+ assert event.possible_subscribers(year=event.end.year).all() == [
+ attendee_2
+ ]
+
+ scenario.add_course_event(
+ scenario.latest_course,
+ start=event.start + delta, end=event.end + delta,
+ max_attendees=20
+ )
+ event2 = scenario.latest_event
+
+ # Event for a year later, exclude the one who has a subscription to
+ # this course
+ assert event.possible_subscribers(
+ year=event.end.year + 1).count() == 1
+ assert event2.possible_subscribers(
+ year=event.end.year).count() == 1
+ assert event2.possible_subscribers(
+ year=event.end.year + 1).count() == 2
+ assert event.possible_subscribers(external_only=True).count() == 0
+ assert event.excluded_subscribers().count() == 2
+ assert event2.possible_subscribers().first() == attendee_2
+
+ assert scenario.latest_course.future_events.count() == 2
def test_subscription(session, attendee, course_event):
diff --git a/tests/onegov/landsgemeinde/test_views.py b/tests/onegov/landsgemeinde/test_views.py
index 3c02cdb96a..e5ac61231e 100644
--- a/tests/onegov/landsgemeinde/test_views.py
+++ b/tests/onegov/landsgemeinde/test_views.py
@@ -18,13 +18,13 @@ def assert_last_modified():
client_with_es.login('admin@example.org', 'hunter2')
- page = client_with_es.get('/').click('Landsgemeinden')
+ page = client_with_es.get('/').click('Archiv')
assert 'Noch keine Landsgemeinden erfasst.' in page
assert 'Zum Liveticker' not in page
# add assembly
with freeze_time('2023-05-07 9:30'):
- page = page.click('Landsgemeinde', index=1)
+ page = page.click('Landsgemeinde')
page.form['date'] = '2023-05-07'
page.form['state'] = 'ongoing'
page.form['overview'] = '
Lorem ipsum
'
@@ -167,7 +167,7 @@ def assert_last_modified():
# delete agenda item
with freeze_time('2023-05-07 9:37'):
page.click('Löschen')
- page = page.click('Landsgemeinde', index=2)
+ page = page.click('Landsgemeinde', index=1)
assert 'Lorem ipsum dolor sit amet
' in page
assert 'A. consectetur adipiscing' not in page
assert_last_modified()
@@ -175,7 +175,7 @@ def assert_last_modified():
# delete landsgemeinde
with freeze_time('2023-05-07 9:38'):
page.click('Löschen')
- page = page.click('Landsgemeinden', index=0)
+ page = page.click('Archiv', index=0)
assert 'Noch keine Landsgemeinden erfasst.' in page
@@ -189,8 +189,8 @@ def test_view_pages_cache(landsgemeinde_app):
# add assembly
client.login('admin@example.org', 'hunter2')
- page = client.get('/').click('Landsgemeinden')
- page = page.click('Landsgemeinde', index=1)
+ page = client.get('/').click('Archiv')
+ page = page.click('Landsgemeinde')
page.form['date'] = '2023-05-07'
page.form['state'] = 'completed'
page.form['overview'] = 'Lorem'