Afficheur de voisinage
Cette page fait partie de la documentation de l'API MediaWiki Action. |
Présentation
Dans ce tutoriel, vous apprendrez comment rechercher les pages wiki qui sont en rapport avec l'endroit géographique où vous vous trouvez en utilisant l'Api Action de MediaWiki.
Ce tutoriel vous montrera comment faire cela en utilisant :
- environnement de travail Python et Flask
- environnements de travail JavaScript, jQuery et Bootstrap The latter are loaded from Wikimedia Toolforge for privacy reasons.
- module Geosearch de l'API Action de MediaWiki
- API Geolocation
Processus pas à pas pour construire cette application
Etape 1 : installer l'environnement de développement Python et Flask
Pour configurer l'environnement de développement Python pour une application Flask, vous devez installer Python, créer un environnement virtuel et installer Flask.
Voici comment configurer l'environnement de développement pour construire l'application :
$ mkdir nearby-places-viewer
$ cd nearby-places-viewer/
This will create a new directory and change into it
$ python3 --version #Python 3.6.5
This command checks your Python version
$ python3 -m venv venv
This command will create a virtual environment named 'venv'
$ source venv/bin/activate
This will activate the virtual environment
$ pip install Flask
This command will install the Flask package with all its dependencies
|
Etape 2: créer une application Flask simple
Générer une page statique simple
Insérer le code suivant dans $HOME/nearby-places-viewer/nearby.py
#!/usr/bin/python3
"""
nearby.py
MediaWiki Action API Code Samples
Nearby places viewer app: Demo of geo search for wiki pages
near a location using the Geolocation API and MediaWiki Action
API's Geosearch module.
MIT license
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
""" Displays the index page accessible at '/'
"""
return render_template('places.html')
if __name__ == '__main__':
app.run()
|
Sauvegardez cette ligne unique de code <h1>Nearby places viewer</h1>
dans un fichier HTML à l'intérieur du répertoire templates
: $HOME/nearby-places-viewer/templates/places.html
Note :
Dans cette application simple, nous utilisons la méthode render_template
qui génère le modèle places.html
du répertoire templates
.
Puis exécutez votre application Flask avec la commande python nearby.py
et ouvrez http://127.0.0.1:5000/
pour voir votre application dans le navigateur.
Vous devriez voir l'Afficheur de voisinage dans la fenêtre de votre navigateur.
Mettre en forme votre application
Remettons en forme un peu l'application.
Ajoutez un élément de type bouton pour valider les données à rechercher dans le fichier HTML et reliez les balises pour charger une feuille de style externe et une autre interne.
La feuille de style externe est dans ce cas l'URL d'un fichier CSS pour la fonte Amatic
.
Remplacer le code existant dans $HOME/nearby-places-viewer/templates/places.html
par :
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">
<h1>Nearby places viewer</h1>
<button>Click here to search</button>
Insérer le code suivant dans $HOME/nearby-places-viewer/static/style.css
h1 {
font-family: 'Amatic SC', cursive;
font-size: 2.5em;
font-weight: normal;
color: black;
}
button {
font-size: 16px;
padding: 10px 25px;
cursor: pointer;
text-decoration: none;
color: white;
border-radius: 4px;
background-color: #7c7ce0;
margin-bottom: 20px;
}
|
Affichage des applications
$HOME/nearby-places-viewer ├── templates/ │ └── places.html ├── static/ │ └── static.css ├── nearby.py └── venv/
Etape 3 : obtenir les coordonnées de votre lieu actuel
D'abord, pour obtenir les pages wiki liées à votre voisinage, vous devrez disposer des coordonnées géographiques de là où vous vous trouvez. Pour faire cela, vous pouvez utiliser l'API Geolocation avec un peu de code JavaScript.
Si vous cliquez sur le bouton Cliquez ici pour chercher, l'application fait un appel à l'API Geolocation et récupère la position actuelle de votre appareil via l'objet Navigator.geolocation
de l'API.
La réponse renvoyée par l'API est un objet Position
à partir duquel vous pouvez obtenir la latitude et la longitude.
Note : Quand votre application réalise un appel à l'API, vous être notifié et on vous demande d'autoriser votre navigateur à accéder à votre emplacement.
Insérer le code suivant dans $HOME/nearby-places-viewer/static/places.js
$( document ).ready(function() {
var x = document.getElementById( "places-list" );
$( 'button' ).click(function() {
getLocation();
});
function getLocation() {
x.innerHTML = "Searching your location..";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(fetchPlaces);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function fetchPlaces(position) {
x.innerHTML = position.coords.latitude + "|" + position.coords.longitude;
}
});
Reliez le JavaScript personnalisé /static/places.js
et jQuery
à partir du fichier HTML
:
$HOME/nearby-places-viewer/templates/places.html
<!-- Add these two lines at the top -->
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/places.js"></script>
<!-- Add this line after the button element -->
<div id="places-list"></div>
Etape 4 : envoyer les coordonnées géographiques au serveur avec AJAX
Cette application utilise la méthode AJAX de jQuery pour envoyer les données de localisation obtenues à l'étape 3 au serveur et les POSTer sans rafraîchir la page vers une route Python Flask /
dans $HOME/nearby-places-viewer/nearby.py
.
Pour l'étape suivante, nous ajoutons un appel AJAX à la fonction fetchPlaces
dans $HOME/nearby-places-viewer/static/places.js
.
Note :
A ce point, si vous essayez d'exécuter votre application, vous aurez probablement une erreur dans la fenêtre de votre navigateur parce que nous n'avons pas ajouté de support pour la route /
pour de gérer nos requêtes POST.
function fetchPlaces(position) {
var data = {
"latitude": position.coords.latitude,
"longitude": position.coords.longitude
};
$.ajax({
url: "/",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function (response) {
x.innerHTML = "Success!";
},
error: function () {
x.innerHTML = "An error occurred while fetching places!";
}
});
}
Etape 5 : récupérer les lieux du voisinage avec l'API Action de MediaWiki
D'abord, étendez la route Python Flask /
dans $HOME/nearby-places-viewer/nearby.py
pour gérer les requêtes POST.
Vous pouvez faire cela en ajoutant à la fois GET et POST dans la liste des arguments de methods
du paramètre de route.
Ensuite, vous pouvez obtenir les données de géolocalisation disponibles au format JSON
à partir de l'objet request
et les passer à la fonction fetch_places_nearby()
pour un traitement ultérieur.
@app.route('/', methods=['GET', 'POST'])
def index():
""" Displays the index page accessible at '/'
"""
if request.method == "POST":
data = request.get_json()
latitude = data['latitude']
longitude = data['longitude']
results = fetch_places_nearby(latitude, longitude)
return jsonify(results=results)
return render_template('places.html')
Le code de la fonction fetch_places_nearby()
fait une requête GET
à l'API Action pour rechercher les pages du wiki à proximité d'un lieu.
L'appel de l'API se fait avec le point d'accès https://en.wikipedia.org/w/api.php
et les paramètres de la chaîne de requête.
Voici quelques paramètres clés :
action=query
module principal pour demander les informationsgenerator=geosearch
list
des sous-modules du module de requête utilisé comme module générateur pour obtenir les résultats de recherche d'un ensemble de pagesprop=coordinates|pageimages|description|info
indique les propriétés à renvoyer pour les pages
Note : Pour plus d'informations sur le module geosearch, voir API:Geosearch/fr .
def fetch_places_nearby(lat, lon):
params = {
"action": "query",
"prop": "coordinates|pageimages|description|info",
"inprop": "url",
"pithumbsize": 144,
"generator": "geosearch",
"ggsradius": 10000,
"ggslimit": 10,
"ggscoord": str(lat) + "|" + str(lon),
"format": "json",
}
res = SESSION.get(url=API_ENDPOINT, params=params)
data = res.json()
places = data['query'] and data['query']['pages']
# TODO: further process 'places' list
return places
Voir le code complet de Python et Flask avec les directives import et la liste places
traitée.
Cette application utilise le paquet Haversine
disponible dans Python pour calculer la distance entre deux coordonnées géographiques.
$HOME/nearby-places-viewer/nearby.py |
---|
#!/usr/bin/python3
"""
nearby.py
MediaWiki Action API Code Samples
Nearby places viewer app: Demo of geo search for wiki pages near a location using
the Geolocation API and MediaWiki Action API's Geosearch module.
MIT license
"""
from flask import Flask, request, render_template, jsonify
import requests
from haversine import haversine
APP = Flask(__name__)
SESSION = requests.Session()
API_ENDPOINT = 'https://en.wikipedia.org/w/api.php'
@APP.route('/', methods=['GET', 'POST'])
def index():
""" Displays the index page accessible at '/'
"""
if request.method == "POST":
data = request.get_json()
latitude = data['latitude']
longitude = data['longitude']
results = fetch_places_nearby(latitude, longitude)
return jsonify(results=results)
return render_template('places.html')
def fetch_places_nearby(lat, lon):
""" Fetches nearby places via MediaWiki Action API's Geosearch module
"""
params = {
"action": "query",
"prop": "coordinates|pageimages|description|info",
"inprop": "url",
"pithumbsize": 144,
"generator": "geosearch",
"ggsradius": 10000,
"ggslimit": 10,
"ggscoord": str(lat) + "|" + str(lon),
"format": "json",
}
res = SESSION.get(url=API_ENDPOINT, params=params)
data = res.json()
places = data['query'] and data['query']['pages']
results = []
for k in places:
title = places[k]['title']
description = places[k]['description'] if "description" in places[k] else ''
thumbnail = places[k]['thumbnail']['source'] if "thumbnail" in places[k] else ''
article_url = places[k]['fullurl']
cur_loc = (lat, lon)
place_loc = (places[k]['coordinates'][0]['lat'], places[k]['coordinates'][0]['lon'])
distance = round(haversine(cur_loc, place_loc, unit='mi'), 2)
results.append({
'title': title,
'description': description,
'thumbnail': thumbnail,
'articleUrl': article_url,
'distance': distance
})
return results
if __name__ == '__main__':
APP.run(debug=True)
|
Etape 6 : créer une interface utilisateur pour lister les lieux à partir de la réponse JSON
Gère les données JSON renvoyées par le serveur dans la procédure de rappel AJAX success
et utilise la propriété DOM innerHTML
du HTML pour modifier le contenu de div
.
success: function (response) {
var places = response["results"],
no_thumb = "..";
x.innerHTML = "";
for (var p in places) {
var thumbnail = places[p].thumbnail || no_thumb;
x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
places[p]["articleUrl"] + "\" target=\"_blank\">" +
places[p]["title"] + "</a></h5><p>" +
places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
thumbnail + " \"></div></div>";
}
}
Afficher le code JavaScript complet avec la procédure de rappel AJAX avec succès.
$HOME/nearby-places-viewer/static/places.js |
---|
$( document ).ready(function() {
var x = document.getElementById( "places-list" );
$( ".btn-search" ).click(function() {
getLocation();
});
function getLocation() {
x.innerHTML = "Searching your location..";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(fetchPlaces);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function fetchPlaces(position) {
var data = {
"latitude": position.coords.latitude,
"longitude": position.coords.longitude
};
$.ajax({
url: "/",
type: "POST",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function (response) {
var places = response["results"],
no_thumb = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Gnome-image-missing.svg/200px-Gnome-image-missing.svg.png";
x.innerHTML = "";
for (var p in places) {
var thumbnail = places[p].thumbnail || no_thumb;
x.innerHTML += "<div class=\"item\"><div class=\"col-xs-8 no-padding\"><h5><a href=\"" +
places[p]["articleUrl"] + "\" target=\"_blank\">" +
places[p]["title"] + "</a></h5><p>" +
places[p]["description"] + "</p><span>📍" + places[p]["distance"] +
" miles</p></div><div class=\"col-xs-4 no-padding\"><img src=\"" +
thumbnail + " \"></div></div>";
}
},
error: function () { x.innerHTML = "An error occurred while fetching places!"; }
});
}
});
|
Etape 7 : modification du style avec Bootstrap
Vous avez peut-être remarqué que l'extrait de code de l'Etape 6 utilise des noms de classe Bootstrap. Effectivement, nous intégrons l'environnement de développement Bootstrap à cette étape pour ajouter l'architecture d'un affichage dynamique à l'interface utilisateur des lieux. Pour faire cela, apportons quelques modifications supplémentaires aux fichiers CSS et HTML.
Afficher l'ensemble du code CSS et HTML.
$HOME/nearby-places-viewer/static/style.css |
---|
.places-container .no-padding {
padding: 0;
}
.places-container .info {
text-align: center;
}
.places-container .viewer-heading {
font-family: 'Amatic SC', cursive;
font-size: 2.5em;
font-weight: normal;
color: black;
}
.places-container .btn-search {
font-size: 16px;
padding: 10px 25px;
cursor: pointer;
text-decoration: none;
color: white;
border-radius: 4px;
background-color: #7c7ce0;
}
.places-container .list {
margin-top: 20px;
}
.places-container .item {
min-height: 100px;
}
.places-container .item p,
span {
font-size: 12px;
margin: 2px;
}
.places-container .item span {
color: gray;
}
.places-container .item img {
float: right;
width: 80px;
height: 80px;
border-radius: 5px;
object-fit: cover;
}
.places-container .item a {
color: #7c7ce0;
}
|
$HOME/nearby-places-viewer/templates/places.html |
---|
<title>Nearby places viewer</title>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="/static/places.js"></script>
<link rel="stylesheet" href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700">
<link rel="stylesheet" href="/static/style.css">
<div class="container places-container col-lg-4 col-xs-12">
<div class="col-xs-12 no-padding info">
<h1 class="viewer-heading">Nearby places viewer</h1>
<button class="btn-search">Click here to search</button>
</div>
<div class="col-xs-12 no-padding list" id="places-list">
</div>
</div>
|
Étapes suivantes
- Contribuez en enregistrant l'application de démonstration que vous avez réalisée utilisant l'API MediaWiki, dans ce dépôt d'exemples de code.
Voir aussi
- API:Geosearch/fr
- tutoriels Flask
- Nearby est une application pour la montre intelligente Pebble qui récupère les articles Wikipedia de votre voisinage.