import datetime import json import uuid from collections import defaultdict from io import BytesIO from typing import Iterable, Mapping from flask import Flask, request, render_template, send_file from icalendar import Calendar, Event, Alarm app = Flask(__name__) # Source JSON created from http://vvc.gov.lv/export/sites/default/files/paplasinatais_saraksts.pdf def generate_ical_for_mapping(cal: Mapping[datetime.date, Iterable[str]]) -> BytesIO: ical = Calendar() ical['VERSION'] = "2.0" ical['PRODID'] = "NameDays" for date, names in sorted(cal.items(), key=lambda x: x[0]): ev = Event() ev.add("SUMMARY", ", ".join(sorted(names))) ev.add("DTSTART", date) ev.add("DTEND", date + datetime.timedelta(days=1)) ev.add("DTSTAMP", datetime.datetime(2000, 1, 1)) ev.add("RRULE", {"FREQ": "YEARLY"}) ev.add("CATEGORY", "Anniversary") ev.add("UID", uuid.uuid4()) alert = Alarm() alert.add("action", "DISPLAY") alert.add("TRIGGER", datetime.timedelta(hours=9)) alert.add("DESCRIPTION", "Default description") ev.add_component(alert) ical.add_component(ev) return BytesIO(ical.to_ical(True)) @app.route('/', methods=["POST", "GET"]) def calendar(): with open("vardadienas.json") as f: vdienas = json.load(f) names_dict = { f"{int(month):02}_{int(day):02}_{name}": name for month, month_data in vdienas.items() for day, day_data in month_data.items() for names in day_data.values() for name in names } if request.method == "POST": cal = defaultdict(list) for selected_name in request.form.getlist("words"): if selected_name in names_dict: month, day, name = selected_name.split("_") date = datetime.date(2000, int(month), int(day)) cal[date].append(name) if cal: name = f"{uuid.uuid4().hex}.ics" f = generate_ical_for_mapping(cal) return send_file(f, mimetype="text/calendar", as_attachment=True, download_name=name) words = ((k,v) for k,v in sorted(names_dict.items(), key=lambda x: x[1])) return render_template("namedays.html", words=words) if __name__ == "__main__": app.run("0.0.0.0", 5000, True, False)