diff options
| author | Kévin Le Gouguec <kevin.legouguec@gmail.com> | 2022-02-21 15:18:39 +0100 |
|---|---|---|
| committer | Kévin Le Gouguec <kevin.legouguec@gmail.com> | 2022-02-21 15:18:39 +0100 |
| commit | 6d9636d35c5d0d244208165010bb70635c98ab2c (patch) | |
| tree | be5bcd97216003f3dc3f900570a7be513830e922 | |
| parent | 0645754d5742c955965d35cdbd617d550f959146 (diff) | |
| download | quatuorbellefeuille.com-6d9636d35c5d0d244208165010bb70635c98ab2c.tar.xz | |
Move some concert stuff to common helpers
The RSS builder will need it.
| -rwxr-xr-x | build-concerts.py | 114 | ||||
| -rw-r--r-- | helpers.py | 112 |
2 files changed, 113 insertions, 113 deletions
diff --git a/build-concerts.py b/build-concerts.py index 43dce57..7b0f75d 100755 --- a/build-concerts.py +++ b/build-concerts.py @@ -1,16 +1,13 @@ #!/usr/bin/env python3 from contextlib import contextmanager -from dataclasses import dataclass from datetime import datetime import locale -from operator import attrgetter from pathlib import Path import re from sys import argv -from typing import Iterator, Optional -from helpers import relative_path +from helpers import guess_language, read_concerts, relative_path # TODO: change some jargon: @@ -18,115 +15,6 @@ from helpers import relative_path # - canceled => warning -LICENSE_URLS = { - 'CC0': 'https://creativecommons.org/publicdomain/zero', - 'CC BY': 'https://creativecommons.org/licenses/by', - 'CC BY-SA': 'https://creativecommons.org/licenses/by-sa', -} - -LICENSE_RE = re.compile( - '('+'|'.join(LICENSE_URLS.keys())+')' + ' ([0-9.]+)' -) - - -@dataclass -class LicenseInfo: - tag: str - version: str - - @classmethod - def deserialize(cls, info): - if info is None: - return None - return cls(*LICENSE_RE.fullmatch(info).groups()) - - def format(self): - url = f'{LICENSE_URLS[self.tag]}/{self.version}/' - - return f'<a href="{url}" target="_blank">{self.tag}</a>' - - -@dataclass -class Illustration: - file: str - alt_text: str - source_name: str - source_link: Optional[str] - license_info: Optional[LicenseInfo] - - @classmethod - def deserialize(cls, d): - return cls(d['pic_file'], - d['pic_alt'], - d['pic_src'], - d['pic_link'], - LicenseInfo.deserialize(d['pic_license'])) - - -@dataclass -class Concert: - time: datetime - place: str - address: str - pieces: Iterator[str] - instructions: str - illustration: Illustration - warning: Optional[str] - - @classmethod - def deserialize(cls, d): - return cls( - time=datetime.strptime(d['time'], '%d/%m/%Y %Hh%M'), - place=d['place'], - address=d['address'], - pieces=d['pieces'], - instructions=d['instructions'], - illustration=Illustration.deserialize(d), - warning=d['warning'] - ) - - -def optional(line): - return f'(?:{line})?' - - -CONCERT_LINES = ( - r'QUAND : (?P<time>[^\n]+)\n', - r'O[UÙ] : (?P<place>[^\n]+)\n', - 'ADRESSE :\n', - '(?P<address>.+?)\n', - 'PROGRAMME :\n', - '(?P<pieces>.+?)\n', - 'INSTRUCTIONS :\n', - '(?P<instructions>.+?)\n', - 'ILLUSTRATION :\n', - r'fichier : (?P<pic_file>[^\n]+)\n', - r'légende : (?P<pic_alt>[^\n]+)\n', - r'source : (?P<pic_src>[^\n]+)\n', - optional(r'lien : (?P<pic_link>[^\n]+)\n'), - optional(r'licence : (?P<pic_license>[^\n]+)\n'), - optional(r'AVERTISSEMENT : (?P<warning>[^\n]+)\n'), -) - -CONCERT_RE = re.compile(''.join(CONCERT_LINES), flags=re.DOTALL) - - -def guess_language(filename): - parent = str(Path(filename).parent) - if parent == '.': - return 'fr' - return parent - - -def read_concerts(filename): - with open(filename) as f: - concerts = ( - Concert.deserialize(match) - for match in re.finditer(CONCERT_RE, f.read()) - ) - return tuple(sorted(concerts, key=attrgetter('time'))) - - def split_concerts(concerts, threshold): cutoff = len(concerts) @@ -1,5 +1,17 @@ +from dataclasses import dataclass +from datetime import datetime +from operator import attrgetter from os import path from pathlib import Path +import re +from typing import Iterator, Optional + + +def guess_language(filename): + parent = str(Path(filename).parent) + if parent == '.': + return 'fr' + return parent def relative_path(*, to, ref): @@ -7,3 +19,103 @@ def relative_path(*, to, ref): # os.path.dirname('x') yields '' rather than '.'. # 😮💨 return path.relpath(to, Path(ref).parent) + + +_LICENSE_URLS = { + 'CC0': 'https://creativecommons.org/publicdomain/zero', + 'CC BY': 'https://creativecommons.org/licenses/by', + 'CC BY-SA': 'https://creativecommons.org/licenses/by-sa', +} + +_LICENSE_RE = re.compile( + '('+'|'.join(_LICENSE_URLS.keys())+')' + ' ([0-9.]+)' +) + +@dataclass +class LicenseInfo: + tag: str + version: str + + @classmethod + def deserialize(cls, info): + if info is None: + return None + return cls(*_LICENSE_RE.fullmatch(info).groups()) + + def format(self): + url = f'{_LICENSE_URLS[self.tag]}/{self.version}/' + + return f'<a href="{url}" target="_blank">{self.tag}</a>' + + +@dataclass +class Illustration: + file: str + alt_text: str + source_name: str + source_link: Optional[str] + license_info: Optional[LicenseInfo] + + @classmethod + def deserialize(cls, d): + return cls(d['pic_file'], + d['pic_alt'], + d['pic_src'], + d['pic_link'], + LicenseInfo.deserialize(d['pic_license'])) + + +@dataclass +class Concert: + time: datetime + place: str + address: str + pieces: Iterator[str] + instructions: str + illustration: Illustration + warning: Optional[str] + + @classmethod + def deserialize(cls, d): + return cls( + time=datetime.strptime(d['time'], '%d/%m/%Y %Hh%M'), + place=d['place'], + address=d['address'], + pieces=d['pieces'], + instructions=d['instructions'], + illustration=Illustration.deserialize(d), + warning=d['warning'] + ) + + +def _optional(line): + return f'(?:{line})?' + +_CONCERT_LINES = ( + r'QUAND : (?P<time>[^\n]+)\n', + r'O[UÙ] : (?P<place>[^\n]+)\n', + 'ADRESSE :\n', + '(?P<address>.+?)\n', + 'PROGRAMME :\n', + '(?P<pieces>.+?)\n', + 'INSTRUCTIONS :\n', + '(?P<instructions>.+?)\n', + 'ILLUSTRATION :\n', + r'fichier : (?P<pic_file>[^\n]+)\n', + r'légende : (?P<pic_alt>[^\n]+)\n', + r'source : (?P<pic_src>[^\n]+)\n', + _optional(r'lien : (?P<pic_link>[^\n]+)\n'), + _optional(r'licence : (?P<pic_license>[^\n]+)\n'), + _optional(r'AVERTISSEMENT : (?P<warning>[^\n]+)\n'), +) + +_CONCERT_RE = re.compile(''.join(_CONCERT_LINES), flags=re.DOTALL) + + +def read_concerts(filename): + with open(filename) as f: + concerts = ( + Concert.deserialize(match) + for match in re.finditer(_CONCERT_RE, f.read()) + ) + return tuple(sorted(concerts, key=attrgetter('time'))) |
