2022-10-24 13:31:08 +03:00

101 lines
3.2 KiB
Python

import datetime
import json
import logging
import uuid
from collections import defaultdict
from io import BytesIO
from typing import Iterable, Mapping
from flask import Flask, jsonify, render_template, request, send_file
from icalendar import Alarm, Calendar, Event
from unidecode import unidecode
app = Flask(__name__)
LV_MONTHS = {
1: "jan",
2: "feb",
3: "mar",
4: "apr",
5: "mai",
6: "jūn",
7: "jūl",
8: "aug",
9: "sep",
10: "okt",
11: "nov",
12: "dec",
}
# 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": f"{value} ({key.split('__')[1]}. {LV_MONTHS[int(key.split('__')[0])]}.)",
}
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", 8000, True, False)