import datetime import json import uuid import logging from collections import defaultdict from io import BytesIO from typing import Iterable, Mapping from flask import Flask, request, render_template, send_file, jsonify from icalendar import Calendar, Event, Alarm from unidecode import unidecode 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(): if request.method == "POST": with open("vardadienas.json") as f: vdienas = json.load(f) cal = defaultdict(list) for selected_name in request.form.getlist("words"): month, day, name = selected_name.split("__") vdmd = vdienas[str(int(month))][str(int(day))] if name in vdmd["normal"] or name in vdmd["special"]: 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 ) return render_template("namedays.html") @app.route("/search/") def calendar_search(): term = request.args.get("term") results = [] if term: term = unidecode(term.lower(), errors="preserve") with open("mapping.json") as f: mapping = json.load(f) for kind in ["normal", "special"]: words = { "text": kind.title(), "children": [ {"id": key, "text": value} for key, value in mapping[kind].items() if unidecode(value.lower(), errors="preserve").startswith(term) ], } if words["children"]: results.append(words) return jsonify({"results": results, "pagination": {"more": False}}) if __name__ == "__main__": app.run("0.0.0.0", 5000, True, False)