summaryrefslogtreecommitdiff
path: root/helpers.py
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@gmail.com>2022-03-20 15:28:54 +0100
committerKévin Le Gouguec <kevin.legouguec@gmail.com>2022-03-20 15:28:54 +0100
commitd557e77493201690f880f67a209ab07e95cd16bb (patch)
tree9f528b27708f510327f4ad45ec7926178d0c79e4 /helpers.py
parent368daac4cd6a33352d92eddfe656e2f357275c8b (diff)
parenta3b76e82d935d78e41aa54c3228dbd6fb9e36fc1 (diff)
downloadquatuorbellefeuille.com-d557e77493201690f880f67a209ab07e95cd16bb.tar.xz
Merge branch 'build-feed'
Diffstat (limited to 'helpers.py')
-rw-r--r--helpers.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/helpers.py b/helpers.py
index faf14e7..11a13ca 100644
--- a/helpers.py
+++ b/helpers.py
@@ -1,5 +1,19 @@
+from contextlib import contextmanager
+from dataclasses import dataclass
+from datetime import datetime
+import locale
+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 +21,141 @@ def relative_path(*, to, ref):
# os.path.dirname('x') yields '' rather than '.'.
# 😮‍💨
return path.relpath(to, Path(ref).parent)
+
+
+@contextmanager
+def tmplocale(lang):
+ old_lang, encoding = locale.getlocale()
+ try:
+ locale.setlocale(locale.LC_TIME, (lang, encoding))
+ yield
+ finally:
+ locale.setlocale(locale.LC_TIME, (old_lang, encoding))
+
+
+_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')))
+
+
+_TOUCHUPS = (
+ (re.compile('([0-9])(st|nd|rd|th|er|ère|nde|ème)'), r'\1<sup>\2</sup>'),
+ (re.compile('(https://[^ ]+)'), r'<a href="\1" target="_blank">\1</a>'),
+ (re.compile('([^ ]+@[^ ]+)'), r'<a href="mailto:\1">\1</a>'),
+)
+
+
+def touchup_plaintext(plaintext):
+ text = plaintext
+ for regexp, repl in _TOUCHUPS:
+ text = regexp.sub(repl, text)
+ return text
+
+
+DATE_FORMATTERS = {
+ 'en': {
+ 'date': lambda d: d.strftime('%A %B %-d, %Y'),
+ 'time': lambda d: d.strftime('%I:%M %P'),
+ },
+ 'fr': {
+ 'date': lambda d: d.strftime('%A %-d %B %Y').capitalize(),
+ 'time': lambda d: d.strftime('%Hh%M'),
+ },
+}