219 lines
8.7 KiB
Python
Executable File
219 lines
8.7 KiB
Python
Executable File
from jinja2 import Environment, FileSystemLoader
|
|
import csv
|
|
from datetime import datetime
|
|
import os
|
|
|
|
DAYS_SR = ["PON", "UTO", "SRE", "ČET", "PET", "SUB", "NED"]
|
|
DAYS_EN = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
|
|
TYPES_DICT = {
|
|
"hack": ("hakaton", "hackathon"),
|
|
"lecture": ("predavanje", "lecture"),
|
|
"workshop": ("radionica", "workshop"),
|
|
"discussion": ("diskusija", "discussion"),
|
|
"lightning": ("kratka predavanja", "short talks"),
|
|
"movie": ("film", "movie"),
|
|
"meeting": ("sastanak", "meeting"),
|
|
"conference": ("konferencija", "conference"),
|
|
"music": ("svirka", "gig"),
|
|
"party": ("zabava", "entertainment"),
|
|
}
|
|
|
|
env = Environment(loader=FileSystemLoader('template'))
|
|
|
|
def load_events(csv_path:str) -> list[dict]:
|
|
events = []
|
|
with open(csv_path, encoding='utf-8') as csv_file:
|
|
csv_reader = csv.DictReader(csv_file, skipinitialspace=True)
|
|
for event in csv_reader:
|
|
event_date = event["datum"]
|
|
event_date_parsed = datetime.strptime(event_date, "%d-%m-%Y").date()
|
|
event_time = event["vreme"]
|
|
event_location = event["lokacija"]
|
|
event_title = event["tema"]
|
|
types = event["tip"].split()
|
|
link = event.get("link", "")
|
|
current_event = {"date":event_date_parsed,
|
|
"time":event_time,
|
|
"location": event_location,
|
|
"title":event_title.strip(),
|
|
"types": types,
|
|
"link": link}
|
|
events.append(current_event)
|
|
return events
|
|
|
|
def build_ical(events: list[dict]) -> str:
|
|
today = datetime.today().now()
|
|
events_ical = ""
|
|
with open("template/head.ical", "r") as file:
|
|
events_ical += file.read()
|
|
for event in events:
|
|
title = event["title"]
|
|
location = event["location"]
|
|
date = event["date"]
|
|
time = event["time"]
|
|
url = event["link"]
|
|
|
|
uid = str(date.month).zfill(2) + str(date.day).zfill(2) + time[:2]
|
|
date_str = str(date.year) + str(date.month).zfill(2) + str(date.day).zfill(2)
|
|
created = str(today.year) + str(today.month).zfill(2) + str(today.day).zfill(2) + "T" + str(today.hour).zfill(2) + str(today.minute).zfill(2) + str(today.second).zfill(2) + "Z"
|
|
date_str = date_str + "T" + time.replace(":", "") + "00"
|
|
|
|
event_template_str = env.get_template("event.ical").render(
|
|
UID=uid,
|
|
CREATED=created,
|
|
DATE=date_str,
|
|
TITLE=title,
|
|
URL=url,
|
|
LOCATION="DC Krov\\, Kraljice Marije 47\\, 6\\, Beograd\\, Serbia" if location.startswith("DC Krov") else ("Matematički fakultet\\, Svetog Nikole 39\\, Beograd\\, Serbia" if location.startswith("Matematički fakultet (Učionica 153)") else location)
|
|
)
|
|
events_ical += event_template_str
|
|
|
|
with open("template/end.ical", "r") as file:
|
|
events_ical += file.read()
|
|
return events_ical
|
|
|
|
def render_page(template_name, output_path, context):
|
|
template = env.get_template(template_name)
|
|
with open(output_path, "w") as file:
|
|
file.write(template.render(context))
|
|
|
|
# Main execution
|
|
events = sorted(load_events("dogadjaji.csv"), key=lambda e: e["date"])
|
|
today = datetime.today().date()
|
|
|
|
past_events = sorted([e for e in events if e["date"] <= today], key=lambda e: e["date"], reverse=True)
|
|
new_events = [e for e in events if e["date"] >= today]
|
|
|
|
sr_types = {k: v[0] for k, v in TYPES_DICT.items()}
|
|
en_types = {k: v[1] for k, v in TYPES_DICT.items()}
|
|
|
|
# Build Serbian Pages
|
|
render_page("events-sr.html", "pages/sr/events.html", {
|
|
"lang": "sr",
|
|
"title": "Događaji",
|
|
"sr_link": "/events_archive",
|
|
"events_html": env.from_string("""
|
|
{% for event in events %}
|
|
<div class='event'>
|
|
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
|
|
{% if event.link %}
|
|
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
|
|
{% else %}
|
|
<div class='title'>{{ event.title }}</div>
|
|
{% endif %}
|
|
{% if 'https://' in event.location %}
|
|
{% set place, link = event.location.split('https://') %}
|
|
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
|
|
{% else %}
|
|
<div class='place'>@{{ event.location.strip() }}</div>
|
|
{% endif %}
|
|
{% if event.types %}
|
|
<div class='types'>
|
|
{% for t in event.types %}
|
|
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
""").render(events=new_events, types_names=sr_types)
|
|
})
|
|
|
|
render_page("events-en.html", "pages/en/events.html", {
|
|
"lang": "en",
|
|
"title": "Events",
|
|
"sr_link": "/events_archive",
|
|
"events_html": env.from_string("""
|
|
{% for event in events %}
|
|
<div class='event'>
|
|
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
|
|
{% if event.link %}
|
|
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
|
|
{% else %}
|
|
<div class='title'>{{ event.title }}</div>
|
|
{% endif %}
|
|
{% if 'https://' in event.location %}
|
|
{% set place, link = event.location.split('https://') %}
|
|
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
|
|
{% else %}
|
|
<div class='place'>@{{ event.location.strip() }}</div>
|
|
{% endif %}
|
|
{% if event.types %}
|
|
<div class='types'>
|
|
{% for t in event.types %}
|
|
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
""").render(events=new_events, types_names=en_types)
|
|
})
|
|
|
|
# Build Archive Pages
|
|
render_page("events_archive-sr.html", "pages/sr/events_archive.html", {
|
|
"lang": "sr",
|
|
"title": "Arhiva događaja",
|
|
"sr_link": "/events",
|
|
"events_html": env.from_string("""
|
|
{% for event in events %}
|
|
<div class='event'>
|
|
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
|
|
{% if event.link %}
|
|
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
|
|
{% else %}
|
|
<div class='title'>{{ event.title }}</div>
|
|
{% endif %}
|
|
{% if 'https://' in event.location %}
|
|
{% set place, link = event.location.split('https://') %}
|
|
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
|
|
{% else %}
|
|
<div class='place'>@{{ event.location.strip() }}</div>
|
|
{% endif %}
|
|
{% if event.types %}
|
|
<div class='types'>
|
|
{% for t in event.types %}
|
|
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
""").render(events=past_events, types_names=sr_types)
|
|
})
|
|
|
|
render_page("events_archive-en.html", "pages/en/events_archive.html", {
|
|
"lang": "en",
|
|
"title": "Events archive",
|
|
"sr_link": "/en/events",
|
|
"events_html": env.from_string("""
|
|
{% for event in events %}
|
|
<div class='event'>
|
|
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
|
|
{% if event.link %}
|
|
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
|
|
{% else %}
|
|
<div class='title'>{{ event.title }}</div>
|
|
{% endif %}
|
|
{% if 'https://' in event.location %}
|
|
{% set place, link = event.location.split('https://') %}
|
|
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
|
|
{% else %}
|
|
<div class='place'>@{{ event.location.strip() }}</div>
|
|
{% endif %}
|
|
{% if event.types %}
|
|
<div class='types'>
|
|
{% for t in event.types %}
|
|
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
""").render(events=past_events, types_names=en_types)
|
|
})
|
|
|
|
# Build ical
|
|
with open("site/events.ical", "w") as file:
|
|
file.write(build_ical(new_events))
|