Commits (5)
include jht_flyergen/cms-logo.png
include jht_flyergen/template.tex
......@@ -22,7 +22,7 @@ from json import dumps
from sys import argv
from sys import stdout
from jht_flyergen.engine import fetch_data, generate_flyer, process_sessions, read_data
from jht_flyergen.engine import fetch_data, render, generate_tex, process_sessions, read_data
TEST_URL = 'https://events.ccc.de/congress/2018/wiki/index.php/Special:Ask/cl:YzpVT9tKxFAM_KKaouzLQl5ERH1QYb8gp03t2Z5LSVJK_XrTdRcUcplhhjAZqmQyPGstkGKOhofWQZmQUoKRqWdR1LGuoEzSjYkCJ3w7fbxDl0hdq2IUEjf37RqneMOa1wuEXUeo4oeQtIM6DMqGLTSHR69XdfNQxecUez0eTRZuDk9e0Dw87_1Cu6dn7STOFmvBP_hm-pTasSr3bg2bD8_GOaQNq3xRid9X5f9RXUINZ-7s7sqNxHxbzIynnUCmWH6fhlnYbJslFsM9JizFg9DMF_YD' # pylint: disable=line-too-long
......@@ -30,19 +30,23 @@ def parse_arguments(args):
"""Parses command-line arguments.
parser = ArgumentParser()
parser.add_argument('-d', '--day', nargs='?', default=28,
help='day of month (default: 28)')
parser.add_argument('-l', '--links', action='store_true',
help='generate QR codes with links to sessions\'s wiki pages')
parser.add_argument('-m', '--homepage',
parser.add_argument('-m', '--homepage', default='https://junghack.de',
help='JHT homepage URL')
parser.add_argument('-p', '--print', action='store_true',
help='print filtered data of session with index PRINT, starting at 1; ' +
parser.add_argument('-p', '--print',
help='print filtered data of session with index PRINT, starting at 1; '
'0 prints all sessions')
parser.add_argument('-t', '--tex', action='store_true',
help='print tex document to stdout')
parser.add_argument('output', nargs='?',
help='path to output file; if omitted raw PDF data is written to stdout')
sources = parser.add_argument_group('data sources').add_mutually_exclusive_group(required=True)
sources.add_argument('-u', '--url', nargs='?', const=TEST_URL,
help='URL to fetch JSON data from; ' +
help='URL to fetch JSON data from; '
'if URL is omitted, a hard-coded URL returning test data is used')
sources.add_argument('-f', '--file', dest='path',
help='path to file containing JSON data')
......@@ -63,13 +67,16 @@ def main():
sessions = fetch_data(args.url)
elif args.path:
sessions = read_data(args.path)
sessions = process_sessions(sessions)
sessions = process_sessions(sessions, int(args.day))
if args.print:
end = int(args.print)
pretty_print(sessions[0 : end if end else -1])
flyer = generate_flyer(sessions, args.homepage, args.links)
tex = generate_tex(sessions, args.homepage, args.links)
if args.tex:
flyer = render(tex)
if args.output:
with open(args.output, 'wb') as output:
......@@ -40,28 +40,39 @@ def fetch_data(url: str) -> List[Dict]:
results: Dict = load(urlopen(url))['results']
return list(results.values())
def generate_flyer(sessions: List[Dict], homeurl: str, links=True) -> bytes:
"""Generates a PDF from self-organized session data.
def generate_tex(sessions: List[Dict], homeurl: str, links=True) -> str:
"""Generates a LaTeX document from self-organized session data.
sessions: processed self-organized session data
homeurl: URL of JHT homepage
links: if set, QR codes with links to session wiki page are generated
a LaTeX document
env = make_env(loader=FileSystemLoader(dirname(__file__)))
libpath = dirname(__file__)
env = make_env(loader=FileSystemLoader(libpath))
template = env.get_template('template.tex')
pdf = build_pdf(template.render(sessions=sessions, homeurl=homeurl, links=links))
return pdf.__bytes__()
tex = template.render(libpath=libpath, sessions=sessions, homeurl=homeurl, links=links)
return tex
def process_sessions(sessions: List[Dict]) -> List[Dict]:
def process_sessions(sessions: List[Dict], day: int) -> List[Dict]:
"""Filters out irrelevant sessions and sanitizes session data.
sessions: a list of raw session data as read from URL / file
day: day of month on which JHT takes place
a list of filtered, re-organized session data
def is_correct_date(start: Dict) -> bool:
return datetime.fromtimestamp(int(start['timestamp'])).day == 27
return datetime.fromtimestamp(int(start['timestamp'])).day == day
def relevant(session: Dict) -> bool:
return bool(list(filter(is_correct_date, session['printouts']['Start'])))
sessions = [transform_session(s) for s in sessions if relevant(s)]
sessions = [transform_session(s, day) for s in sessions if relevant(s)]
sessions = [s for ss in sessions for s in ss]
sessions.sort(key=lambda a: a['start'])
return sessions
......@@ -77,7 +88,18 @@ def read_data(path: str) -> List[Dict]:
with open(path) as data_file:
return load(data_file)
def transform_session(session: Dict) -> Dict:
def render(tex: str) -> bytes:
"""Renders a LaTeX document.
tex: a LaTeX document
raw PDF bytes
return build_pdf(tex).__bytes__()
def transform_session(session: Dict, day: int) -> List[Dict]:
"""Re-organizes self-organized session data for easier access in templates.
Also filters out superfluous stuff, that appears to be always empty.
......@@ -88,15 +110,20 @@ def transform_session(session: Dict) -> Dict:
an uncluttered, organized version of the input dict containing only relevant data
def build_session(title, url, providers, start):
result = {}
result['title'] = title
result['url'] = url
result['providers'] = providers
result['start'] = start
return result
def parse_date(start: Dict) -> datetime:
return datetime.fromtimestamp(int(start['timestamp']))
def process_provider(provider: Dict) -> str:
return sub('Assembly:', '', sub('Static:', '', provider['fulltext']))
result = {}
result['title'] = sub('Session:', '', session['fulltext'])
result['url'] = session['fullurl']
providers = list(map(process_provider, session['printouts']['organized by']))
result['providers'] = ', '.join(providers)
title = sub('Session:', '', session['fulltext'])
url = session['fullurl']
providers = ', '.join(map(process_provider, session['printouts']['organized by']))
starts = list(map(parse_date, session['printouts']['Start']))
result['start'] = list(filter(lambda d: d.day == 27, starts))[0].strftime('%H:%M')
return result
starts = [s.strftime('%H:%M') for s in filter(lambda d: d.day == day, starts)]
return [build_session(title, url, providers, s) for s in starts]
......@@ -5,9 +5,12 @@
\newcommand{\thetitle}{Angebote für Junghacker*innen}
\newcommand{\theauthor}{Chaos macht Schule}
......@@ -21,8 +24,10 @@
\raisebox{3em}{\textbf{\Large \thetitle}}
%- if links
......@@ -49,8 +54,9 @@
%- endif
%- if homeurl
Weitere Informationen: \qquad \url{\VAR{homeurl}} \hfill \qrcode{\VAR{homeurl}}
\parbox{12em}{Weitere Informationen: \\ \url{\VAR{homeurl}}}
%- endif