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