98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
import datetime
|
|
import json
|
|
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)
|