summaryrefslogtreecommitdiff
path: root/helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'helpers.py')
-rw-r--r--helpers.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/helpers.py b/helpers.py
index faf14e7..162d39e 100644
--- a/helpers.py
+++ b/helpers.py
@@ -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')))