"""main flask app routes handlers There are two types of routes, first the 'static' routes : - / - /about - /actes - /contact - /privacy - /termsofservice Then the 'dynamic' (calculated) routes : - /actes - /actes/, sample: /actes/Anjou - /actes//, sample: /actes/Anjou/isa_i - /acte///, sample: /acte/Anjou/Isabelle_i/1441_08_05a - /geoloc """ import datetime import typing as t from collections import defaultdict from flask import Blueprint, render_template, request, url_for, redirect import folium from pymongo import ASCENDING from .dbinit import * from .helper import make_timeitem_from_filename, plaintext_response main = Blueprint("main", __name__, url_prefix="/") # ______________________________________________________________________________ # routes @main.route("/", methods=('GET', 'POST')) def home(): """home route""" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) return render_template("home.html") @main.route("/about/", methods=('GET', 'POST')) def about(): """about route""" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) return render_template("about.html") @main.route("/actes/", methods=('GET', 'POST')) def corpora_all(): """copora all lists houses sample_house_names = ["Bourbon", "Berry", "Anjou", ...] """ if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) houses = list(housecol.find()) return render_template("corpora_all.html", houses=houses) @main.route("/actes/", methods=('GET', 'POST')) def actes(house): """*actes* route, sample route: '/actes/Bourbon' or '/actes/Berry' shows the princes in the selected house :param: the house in the url is the house name with a capital letter at the beginning example: `house = "Berry"` """ if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) # house in the store shall be in lower case, but let's force it, just in case house = house.lower() # sample result: # [('Louis II de Bourbon', 'lo_ii'), ('Anne Dauphine', 'ann_i'), ('Agnès de Bourgogne', 'agn_i'), ('Charles Ier de Bourbon', 'ch_i')] # [('Agnès de Bourgogne', 'agn_i'), ('Anne Dauphine', 'ann_i'), ('Charles Ier de Bourbon', 'ch_i'), ('Louis II de Bourbon', 'lo_ii') princes = princes_in_houses[house] # TODO : modify the html template's design in order to suppress this ugly line princes = [(prc['prince_name'], prc['prince_code']) for prc in princes] return render_template("corpus.html", house=house.capitalize(), princes=princes) @main.route("/actes//", methods=('GET', 'POST')) def prince_corpus(house=None, prince=None): """copora prince, *timeline* view sample route: '/actes/Berry/je_i' or '/actes/Anjou/lo_i' """ if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) prince_code = prince.lower() house = house.lower() prince_long_name = extract_prince_in_house(house, prince_code)['prince_name'] query = list(actecol.aggregate([ { "$match": {"house": house, "prince_code": prince_code} }, #{ # "$sort": {"date_time": ASCENDING} #}, { '$group': {'_id': {'prince_name': '$prince_name', 'prince_code': '$prince_code', 'filename': '$filename', 'date': '$date', "date_time": "$date_time", "analysis": '$analysis', "place": "$place.name", "diplo_state": "$diplo_state", "diplo_type": "$diplo_type", "image": "$image" } } } ])) transformed_query = [pr['_id'] for pr in query] invert_prince_bigram = {val: key for key, val in prince_bigram.items()} # constructing the dateitem for trs in transformed_query: trs['dateitem'] = make_timeitem_from_filename(trs['filename']) bigram, number = trs['prince_code'].split('_') long_prince_bigram = inverted_prince_bigram(bigram) + '_' + number # sorted_list = sorted(transformed_query, key=lambda x: x['date_time']) return render_template("prince_corpus.html", house=house, duke_name=prince_long_name, prince_name=long_prince_bigram.capitalize(), actes=sorted_list) @main.route("/acte///", methods=('GET', 'POST')) def acte(house=None, prince=None, dateitem=None): """specific prince's acte view :params: - house - prince - date + item (sample: 1441_08_05a) :url location sample: /acte/Anjou/Isabelle_i/1441_08_05a url transcription samples: /acte/Anjou/Isabelle_i/1441_08_05a -> anj_isa_i_1441_08_05a /acte/Bourbon/Anne_i/1388_09_15a -> brb_ann_i_1388_09_15a """ if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) filestem = make_acteid_from_route(house, prince, dateitem) result = actecol.find_one({'_id': filestem}) return render_template("acte.html", house=house, prince=result.get('prince_code'), #infos=None, place=None, doc=None, arch=None, #diplo=diplo_t[0].replace("_", " "), state=state[0], output_doc=result.get('xmlcontent'), name_prince=result.get("prince_name"), folium=result.get("folium"), transcribers=result.get('transcribers'), image=result.get('image')) @main.route("/geolocalisation", methods=('GET', 'POST')) def geolocalisation(): "global folium/leaflet map" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) m = folium.Map(location=[46.603354, 1.888334], zoom_start=6) markers = defaultdict(list) for result in actecol.find(): place = result['place'] filename = result['filename'] name = place['name'] place_name = name.lower() url = result['url'] latitude = place['latitude'] longitude = place['longitude'] markers[place_name].append([url, latitude, longitude, filename]) for key, value in markers.items(): name = key.capitalize() latitude = value[0][1] longitude = value[0][2] urls = [(url[0], url[3]) for url in value] #print("urls", urls) popup = [f"{name}
"] for location, see in urls: popup.append(f"{see}
") popup = "".join(popup) if latitude is not None: folium.Marker( location=[latitude, longitude], popup= popup, icon=folium.Icon(color='lightgray', icon="circle", prefix='fa') ).add_to(m) geolocalisation = m._repr_html_() return render_template("map.html", geolocalisation=geolocalisation) @main.route("/contact", methods=('GET', 'POST')) def contact() -> t.Text: """Displays the Contact page""" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) return render_template("contact.html", title="Contact") @main.route("/termsofservice", methods=('GET', 'POST')) def terms() -> t.Text: """Displaysthe T&C page.""" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) return render_template("terms.html", title="Mentions légales") @main.route("/privacy", methods=('GET', 'POST')) def privacy() -> t.Text: """Displays the privacy policy page.""" if request.method == 'POST': search = request.form['search'] return render_template("plainsearch.html", search=search, actes=plaintext_response(search, actecol, prince_bigram)) return render_template("privacy.html", title="Politique de confidentialité")