Source code for org.views.publications

from collections import OrderedDict
from onegov.core.security import Public
from onegov.file import File
from onegov.file.utils import name_without_extension
from onegov.org import OrgApp, _
from onegov.org.layout import PublicationLayout
from onegov.org.models import GeneralFileCollection
from onegov.org.models import PublicationCollection
from onegov.core.elements import Link
from sqlalchemy import desc, literal


from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from collections.abc import Sequence
    from datetime import datetime
    from onegov.core.types import RenderData
    from onegov.file.types import FileStats
    from onegov.org.request import OrgRequest
    from typing import NamedTuple

[docs] class FileRow(NamedTuple):
[docs] id: str
[docs] name: str
[docs] stats: FileStats | None
[docs] created: datetime
[docs] MONTHS = ( _('January'), _('Feburary'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December'), )
@OrgApp.html( model=PublicationCollection, permission=Public, template='publications.pt' )
[docs] def view_publications( self: PublicationCollection, request: 'OrgRequest', layout: PublicationLayout | None = None ) -> 'RenderData': layout = layout or PublicationLayout(self, request) # filter by year, from latest to first year s = self.first_year(layout.timezone) or self.year e = layout.today().year years = range(e, s - 1, -1) if s is not None else () filters = { 'years': tuple( Link( text=str(year), active=year == self.year, url=request.link(self.for_year(year=year)), rounded=True ) for year in years ) } # load the publications and bucket them into months publications: Sequence[list[FileRow]] = tuple([] for i in range(12)) query = self.query().with_entities( File.id, File.name, File.stats, File.created.op('AT TIME ZONE')( literal(layout.timezone.zone) # noqa: MS001 ).label('created'), ).order_by(desc(File.created)) for f in query: publications[f.created.month - 1].append(f) # group the publications by months, while merging empty months today = layout.today() grouped: dict[str, list[FileRow] | None] = OrderedDict() spool: Sequence[str] = () def apply_spool(spool: 'Sequence[str]') -> 'Sequence[str]': if spool: if len(spool) == 1: label = spool[0] else: label = f'{spool[0]} - {spool[-1]}' grouped[label] = None return () for ix, publications_ in enumerate(reversed(publications)): month = 12 - ix # exclude current year's months if they are in the future if self.year == today.year and month > today.month: continue if not publications_: spool = (*spool, request.translate(MONTHS[month - 1])) continue spool = apply_spool(spool) grouped[request.translate(MONTHS[month - 1])] = publications_ apply_spool(spool) # link to file and thumbnail by id def link(f: 'FileRow', name: str = '') -> str: return request.class_link(File, {'id': f.id}, name=name) return { 'title': _('Publications'), 'layout': layout, 'model': self, 'filters': filters, 'link': link, 'grouped': grouped, 'name_without_extension': name_without_extension, 'filedigest_handler': request.class_link( GeneralFileCollection, name='digest' ) }