summaryrefslogtreecommitdiff
path: root/build-concerts.py
diff options
context:
space:
mode:
Diffstat (limited to 'build-concerts.py')
-rwxr-xr-xbuild-concerts.py174
1 files changed, 16 insertions, 158 deletions
diff --git a/build-concerts.py b/build-concerts.py
index 43dce57..6e99673 100755
--- a/build-concerts.py
+++ b/build-concerts.py
@@ -1,16 +1,17 @@
#!/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 (
+ DATE_FORMATTERS,
+ guess_language,
+ read_concerts,
+ relative_path,
+ tmplocale,
+ touchup_plaintext,
+)
# TODO: change some jargon:
@@ -18,115 +19,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)
@@ -177,28 +69,20 @@ THUMBNAIL_TEMPLATE = '''\
'''
-@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))
-
-
def format_credits(illustration):
- credits = illustration.source_name
+ attribution = illustration.source_name
if illustration.source_link is not None:
- credits = (f'<a href="{illustration.source_link}" target="_blank">'
- f'{illustration.source_name}'
- '</a>')
+ attribution = (
+ f'<a href="{illustration.source_link}" target="_blank">'
+ f'{illustration.source_name}'
+ '</a>'
+ )
if illustration.license_info is not None:
- credits += ' / ' + illustration.license_info.format()
+ attribution += ' / ' + illustration.license_info.format()
- return credits
+ return attribution
def format_thumbnail(concert, imgdir, lang):
@@ -256,18 +140,6 @@ DETAILS_TEMPLATE = '''\
'''
-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'),
- },
-}
-
-
def detail_block(tag, classes, content):
opener = f'<{tag} class="{" ".join(classes)}">'
closer = f'</{tag}>'
@@ -286,20 +158,6 @@ def break_lines(lines):
return tuple(line+'<br>' for line in lines[:-1]) + (lines[-1],)
-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
-
-
def print_concert_details(concert, lang):
concert_id = f'concert-{concert.time.strftime("%F")}'
classes = ('details',)