Source code for election_day.views.archive

from __future__ import annotations

from operator import itemgetter

from morepath import redirect

from fs.errors import ResourceNotFound
from morepath.request import Response
from onegov.election_day import ElectionDayApp
from onegov.election_day.collections import (
    AllMunicipalArchivedResultCollection
)
from onegov.election_day.collections import ArchivedResultCollection
from onegov.election_day.collections import MunicipalArchivedResultCollection
from onegov.election_day.collections import (
    MunicipalityArchivedResultCollection
)
from onegov.election_day.collections import (
    MunicipalityYearArchivedResultCollection
)
from onegov.election_day.models import MunicipalityRedirect
from onegov.election_day.collections import SearchableArchivedResultCollection
from onegov.election_day.forms import ArchiveSearchFormElection
from onegov.election_day.forms import ArchiveSearchFormVote
from onegov.election_day.layouts import DefaultLayout
from onegov.election_day.layouts.archive import ArchiveLayout
from onegov.election_day.models import Principal
from onegov.election_day.security import MaybePublic
from onegov.core.security import Public
from onegov.election_day.utils import add_last_modified_header
from onegov.election_day.utils import get_summaries
from webob.exc import HTTPNotFound


from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from onegov.core.types import JSON_ro
    from onegov.core.types import RenderData
    from onegov.election_day.request import ElectionDayRequest
    from webob.response import Response as webob_Response


@ElectionDayApp.view(model=MunicipalityRedirect, permission=Public)
[docs] def view_municipality_redirect( self: MunicipalityRedirect, request: ElectionDayRequest ) -> webob_Response: return redirect( request.link( MunicipalityArchivedResultCollection( request.session, self.municipality ) ) )
@ElectionDayApp.html( model=ArchivedResultCollection, template='archive.pt', permission=MaybePublic )
[docs] def view_archive( self: ArchivedResultCollection, request: ElectionDayRequest ) -> RenderData: """ Shows all the results from the elections and votes for a given year or date. """ layout = DefaultLayout(self, request) results, _ = self.by_date() return { 'layout': layout, 'date': self.date, 'archive_items': self.group_items(results, request), 'show_communal_nav': True, 'show_archive_links': True, }
@ElectionDayApp.html( model=MunicipalArchivedResultCollection, template='archive.pt', permission=MaybePublic )
[docs] def view_archive_municipal( self: MunicipalArchivedResultCollection, request: ElectionDayRequest ) -> RenderData: layout = DefaultLayout(self, request) mun_archive = layout.municipality_archive results, _ = self.by_date() latest_years = mun_archive.get_latest_year_by_municipality() slugs = {r.domain_segment for r in results if r.domain_segment} municipality_links = { slug: _municipality_archive_url( mun_archive, slug, latest_years, request ) for slug in slugs } return { 'layout': layout, 'date': self.date, 'archive_items': self.group_items(results, request), 'municipal_view': True, 'municipality_display_names': ( request.app.principal.municipality_display_name_by_slug ), 'municipality_links': municipality_links, }
@ElectionDayApp.html( model=AllMunicipalArchivedResultCollection, template='archive.pt', permission=MaybePublic )
[docs] def view_archive_all_municipal( self: AllMunicipalArchivedResultCollection, request: ElectionDayRequest ) -> RenderData: layout = DefaultLayout(self, request) mun_archive = layout.municipality_archive latest_years = mun_archive.get_latest_year_by_municipality() municipality_links = { name: _municipality_archive_url( mun_archive, slug, latest_years, request ) for slug, name in sorted( request.app.principal.municipality_display_name_by_slug.items(), key=itemgetter(1), ) if slug in latest_years } return { 'layout': layout, 'date': None, 'archive_items': None, 'municipality_links': municipality_links, 'all_municipal_view': True, }
[docs] def _municipality_archive_url( mun_archive: MunicipalityArchivedResultCollection, slug: str, latest_years: dict[str, int], request: ElectionDayRequest, ) -> str: if slug in latest_years: return request.link( mun_archive.for_municipality(slug).for_year(latest_years[slug]) ) return request.link(mun_archive.for_municipality(slug))
[docs] def _municipality_display_name( sanitized: str, request: ElectionDayRequest, ) -> str: return request.app.principal.municipality_display_name_by_slug.get( sanitized, sanitized )
[docs] def _municipality_view_data( self: MunicipalityArchivedResultCollection, request: ElectionDayRequest, year: int | None = None ) -> RenderData: layout = DefaultLayout(self, request) results, _ = self.by_municipality() return { 'layout': layout, 'date': str(year) if year else None, 'active_year': year, 'archive_items': self.group_items(results, request), 'municipality_collection': self, 'municipality_name': _municipality_display_name( self.municipality, request ), 'municipality_view': True, 'show_archive_links': True, }
@ElectionDayApp.html( model=MunicipalityArchivedResultCollection, template='archive.pt', permission=MaybePublic )
[docs] def view_archive_municipality( self: MunicipalityArchivedResultCollection, request: ElectionDayRequest ) -> RenderData: return _municipality_view_data(self, request)
@ElectionDayApp.html( model=MunicipalityYearArchivedResultCollection, template='archive.pt', permission=MaybePublic )
[docs] def view_archive_municipality_year( self: MunicipalityYearArchivedResultCollection, request: ElectionDayRequest ) -> RenderData: return _municipality_view_data(self, request, year=self.year)
@ElectionDayApp.json( model=ArchivedResultCollection, name='json', permission=MaybePublic, open_data=True )
[docs] def view_archive_json( self: ArchivedResultCollection, request: ElectionDayRequest ) -> JSON_ro: """ Shows all the results from the elections and votes for a given year or date as JSON. """ results, last_modified = self.by_date() @request.after def add_headers(response: Response) -> None: add_last_modified_header(response, last_modified) return { 'canton': request.app.principal.id, 'name': request.app.principal.name, 'results': get_summaries(results, request), 'archive': { str(year): request.link(self.for_date(str(year))) for year in self.get_years() } }
@ElectionDayApp.html( model=Principal, template='archive.pt', permission=MaybePublic )
[docs] def view_principal( self: Principal, request: ElectionDayRequest ) -> RenderData: """ Shows all the results from the elections and votes of the last election day. It's the landing page. """ layout = DefaultLayout(self, request) archive = ArchivedResultCollection(request.session) current, _ = archive.current() return { 'layout': layout, 'archive_items': archive.group_items(current, request), 'date': None, 'show_communal_nav': True, 'show_archive_links': True, }
@ElectionDayApp.json( model=Principal, name='json', permission=MaybePublic, open_data=True )
[docs] def view_principal_json( self: Principal, request: ElectionDayRequest ) -> JSON_ro: """ Shows all the results from the elections and votes of the last election day as JSON. """ archive = ArchivedResultCollection(request.session) current, last_modified = archive.current() @request.after def add_headers(response: Response) -> None: add_last_modified_header(response, last_modified) return { 'canton': self.id, 'name': self.name, 'results': get_summaries(current, request), 'archive': { str(year): request.link(archive.for_date(str(year))) for year in archive.get_years() } }
[docs] def search_form( model: SearchableArchivedResultCollection, request: ElectionDayRequest, form: None = None ) -> type[ArchiveSearchFormVote | ArchiveSearchFormElection]: if model.item_type == 'vote': return ArchiveSearchFormVote return ArchiveSearchFormElection
@ElectionDayApp.form( model=SearchableArchivedResultCollection, template='archive_search.pt', form=search_form, permission=MaybePublic, ) @ElectionDayApp.view( model=Principal, name='archive-download', permission=MaybePublic )
[docs] def view_archive_download( self: Principal, request: ElectionDayRequest ) -> Response: filestorage = request.app.filestorage assert filestorage is not None if not filestorage.isdir('archive'): raise HTTPNotFound() try: zip_dir = filestorage.opendir('archive/zip') content = None with zip_dir.open('archive.zip', mode='rb') as zipfile: content = zipfile.read() if not content: raise HTTPNotFound() return Response( content, content_type='application/zip', content_disposition='inline; filename=Archive.zip' ) except (FileNotFoundError, ResourceNotFound) as exception: raise HTTPNotFound() from exception