You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
11 KiB
Python

"""main flask app routes handlers
2 years ago
There are two types of routes, first the 'static' routes :
2 years ago
- /
- /about
- /actes
- /contact
- /privacy
- /termsofservice
Then the 'dynamic' (calculated) routes :
2 years ago
- /actes
- /actes/<house>, sample: /actes/Anjou
- /actes/<house>/<prince>, sample: /actes/Anjou/isa_i
- /acte/<house>/<prince>/<dateitem>, sample: /acte/Anjou/Isabelle_i/1441_08_05a
2 years ago
- /geoloc
"""
2 years ago
import datetime
2 years ago
import typing as t
from collections import defaultdict
2 years ago
from flask import Blueprint, render_template, request, url_for, redirect
import folium
from folium.plugins import MarkerCluster, MiniMap
from pymongo import ASCENDING
2 years ago
2 years ago
from .dbinit import *
from .helper import make_timeitem_from_filename, plaintext_response
2 years ago
main = Blueprint("main", __name__, url_prefix="/")
# ______________________________________________________________________________
# routes
@main.route("/", methods=('GET', 'POST'))
2 years ago
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")
2 years ago
@main.route("/about/", methods=('GET', 'POST'))
2 years ago
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")
2 years ago
@main.route("/actes/", methods=('GET', 'POST'))
2 years ago
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)
2 years ago
@main.route("/actes/<house>", methods=('GET', 'POST'))
2 years ago
def actes(house):
2 years ago
"""*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()
2 years ago
# sample result:
# [('Louis II de Bourbon', 'lo_ii'), ('Anne Dauphine', 'ann_i'), ('Agnès de Bourgogne', 'agn_i'), ('Charles Ier de Bourbon', 'ch_i')]
2 years ago
# [('Agnès de Bourgogne', 'agn_i'), ('Anne Dauphine', 'ann_i'), ('Charles Ier de Bourbon', 'ch_i'), ('Louis II de Bourbon', 'lo_ii')
2 years ago
princes = princes_in_houses[house]
2 years ago
# TODO : modify the html template's design in order to suppress this ugly line
2 years ago
princes = [(prc['prince_name'], prc['prince_code']) for prc in princes]
return render_template("corpus.html", house=house.capitalize(), princes=princes)
2 years ago
2 years ago
@main.route("/actes/<house>/<prince>", methods=('GET', 'POST'))
def prince_corpus(house=None, prince=None):
"""copora prince, *timeline* view
2 years ago
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}
},
2 years ago
#{
# "$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]
2 years ago
invert_prince_bigram = {val: key for key, val in prince_bigram.items()}
# constructing the dateitem
for trs in transformed_query:
2 years ago
trs['dateitem'] = make_timeitem_from_filename(trs['filename'])
bigram, number = trs['prince_code'].split('_')
long_prince_bigram = inverted_prince_bigram(bigram) + '_' + number
2 years ago
#
sorted_list = sorted(transformed_query, key=lambda x: x['date_time'])
return render_template("prince_corpus.html", house=house, duke_name=prince_long_name,
2 years ago
prince_name=long_prince_bigram.capitalize(), actes=sorted_list)
@main.route("/acte/<house>/<prince>/<dateitem>", 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})
2 years ago
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():
2 years ago
"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)
marker_cluster = MarkerCluster().add_to(m)
minimap = MiniMap()
m.add_child(minimap)
markers = defaultdict(list)
2 years ago
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']
name_prince = result['prince_name']
dateday = result['date']
markers[place_name].append([url, latitude, longitude, filename, name_prince, dateday])
for key, value in markers.items():
name = key.capitalize()
latitude = value[0][1]
longitude = value[0][2]
urls = [(url[0], url[-2], url[-1]) for url in value]
actes_place = [f"<a href='{item[0]}' target='_top'>{item[1]} ({item[2]})</a><br />" for item in urls]
popup_text =f"""
<div style='max-height: 200px; overflow-y: auto;'>
<h2 style="text-align: center;">{name}</h2>
<div style="font-size: 16px;">
{''.join(actes_place)}
</div>
</div>
"""
popup = folium.Popup(popup_text, min_width=100, max_width=400)
if latitude is not None:
folium.CircleMarker( # choice : marker (Circle, CircleMarker or Marker, optional)
location=[latitude, longitude],
radius = 15,
popup=popup,
color='darkblue',
opacity=0.4,
fill_color='blue',
fill_opacity=0.2
# icon=folium.Icon(color='darkblue', icon="cloud", prefix='fa')
).add_to(marker_cluster)
# to remove marker_cluster : .add_to(m)
# marker's colors : 'red', 'blue', 'gray', 'darkred', 'lightred',
# 'orange', 'beige', 'green', 'darkgreen', 'lightgreen', 'darkblue',
# 'lightblue', 'purple', 'darkpurple', 'pink', 'cadetblue',
# 'lightgray', 'black'
geolocalisation = m._repr_html_()
return render_template("map.html", geolocalisation=geolocalisation)
@main.route("/contact", methods=('GET', 'POST'))
2 years ago
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))
2 years ago
return render_template("contact.html", title="Contact")
@main.route("/termsofservice", methods=('GET', 'POST'))
2 years ago
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))
2 years ago
return render_template("terms.html", title="Mentions légales")
@main.route("/privacy", methods=('GET', 'POST'))
2 years ago
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))
2 years ago
return render_template("privacy.html", title="Politique de confidentialité")