From 0ae749981b1fcaf9dcb5db9626a6fcfc4734f579 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Thu, 19 Aug 2021 14:40:59 +0200
Subject: [PATCH] =?UTF-8?q?API=20pro=20JS=20na=20zad=C3=A1v=C3=A1n=C3=AD?=
 =?UTF-8?q?=20=C5=A1kol?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 mo/web/__init__.py |  1 +
 mo/web/api.py      | 78 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 mo/web/api.py

diff --git a/mo/web/__init__.py b/mo/web/__init__.py
index 1be472cf..efde0989 100644
--- a/mo/web/__init__.py
+++ b/mo/web/__init__.py
@@ -215,6 +215,7 @@ except ImportError:
 
 
 # Většina webu je v samostatných modulech
+import mo.web.api
 import mo.web.auth
 import mo.web.jinja
 import mo.web.menu
diff --git a/mo/web/api.py b/mo/web/api.py
new file mode 100644
index 00000000..9b1f3306
--- /dev/null
+++ b/mo/web/api.py
@@ -0,0 +1,78 @@
+from flask import request
+from flask.json import jsonify
+from sqlalchemy.orm import joinedload
+import werkzeug.exceptions
+
+import mo.db as db
+from mo.util_format import inflect_with_number
+from mo.web import app
+
+
+@app.route('/api/')
+def api_root():
+    """Slouží jako prefix pro konstrukci URL v JavaScriptu."""
+    raise werkzeug.exceptions.NotFound()
+
+
+@app.route('/api/find-town')
+def api_find_town():
+    query = request.args.get('q')
+    if query is None or len(query) < 2:
+        return jsonify(error='Zadejte alespoň 2 znaky jména obce.')
+    elif '%' in query:
+        return jsonify(error='Nepovolené znaky ve jménu obce.')
+    else:
+        # FIXME: Hledání bez akcentů
+        # FIXME: Hodil by se index...
+        max_places = 50
+        places = (db.get_session().query(db.Place)
+                  .filter_by(level=3)
+                  .filter(db.Place.name.ilike(query + '%'))
+                  .options(joinedload(db.Place.parent_place))
+                  .order_by(db.Place.name, db.Place.place_id)
+                  .limit(max_places)
+                  .all())
+        if not places:
+            return jsonify(error='Nenalezena žádná obec.')
+        # XXX: Nemůže se stát, že nastane přesná shoda a k tomu příliš mnoho nepřesných?
+        if len(places) >= max_places:
+            return jsonify(error='Nalezeno příliš mnoho obcí. Zadejte prosím více znaků jména.')
+
+        res = []
+        for p in places:
+            name = p.name
+            if p.name != p.parent_place.name:
+                name += f' (okres {p.parent_place.name})'
+            res.append([p.place_id, name])
+
+        msg = inflect_with_number(len(res), 'Nalezena %s obec.', 'Nalezeny %s obce.', 'Nalezeno %s obcí.')
+
+        return jsonify(found=res, msg=msg)
+
+
+@app.route('/api/get-schools')
+def api_get_schools():
+    town = request.args.get('town')
+    if town is None or not town.isnumeric():
+        raise werkzeug.exceptions.BadRequest()
+    town_id = int(town)
+
+    places = (db.get_session().query(db.Place)
+              .filter_by(level=4, type=db.PlaceType.school, parent=town_id)
+              .options(joinedload(db.Place.school))
+              .order_by(db.Place.name)
+              .all())
+
+    zs = []
+    ss = []
+    for p in places:
+        s = {
+            'id': p.place_id,
+            'name': p.name,
+        }
+        if p.school.is_zs:
+            zs.append(s)
+        if p.school.is_ss:
+            ss.append(s)
+
+    return jsonify(zs=zs, ss=ss)
-- 
GitLab