\documentclass[11pt,a4paper]{article}
\newcommand{\UPSUDSKIPFONTS}{}

\input{td-upsud}
\usepackage{amsfonts}

\newcommand{\matiere}{Web 2}
\newcommand{\parcours}{Agrégation d'Informatique}
\newcommand{\jour}{13 décembre 2021}
\newcommand{\titre}{{\LARGE \bf TP n\up{o} 3}
}
\newenvironment{xmldoc}{\begin{minipage}[t]{0.8\columnwidth}\begin{framed}\begin{alltt}}{
\end{alltt}\end{framed}\end{minipage}}

\newcommand{\noeud}{n\oe{}ud}
\newcommand{\noeuds}{\noeud{}s}

\begin{document}
\entete

\section*{Requête Wikimedia}
Le but de ce TP est de fournir une page HTML permettant de rechercher
des images sur Wikipedia (anglais) à partir d'un mot clé. On utilise
pour cela l'API Wikimedia qui permet d'interroger la base Wikimedia
(contenant entre autres les données wikipedia) de manière automatisée.

Le principe général est le suivant. On effectue une requête AJAX POST à
l'URL :
\begin{verbatim}
https://www.mediawiki.org/w/api.php?format=json&formatversion=2&p1=v1&p2=v2&...&pn=vn
\end{verbatim}
où les \texttt{pi=vi} sont des paramètres bien choisis. On obtient en
réponse (que la requête soit correcte ou resulte en erreur) une chaîne
de caractère représentant un objet JSON que l'on peut décoder et
utiliser depuis Javascript.

\paragraph{Analyse}
\emph{Cette partie est à réaliser au brouillon, pour se donner une
  idée de la complexité de la tâche.}

On suppose données deux URLs :
\begin{itemize}
  \item \texttt{searchImage?query=str} renvoie tous les noms de fichiers d'image
    en rapport avec la chaîne de caractère passée en argument.
  \item \texttt{getURL?file=filename} renvoie l'URL du fichier donner
    en argument.
  \end{itemize}
  Par exemple, si on effectue une requête HTTP sur:
\begin{verbatim}
http://wikimedia.org/searchImage?query=str
\end{verbatim}
  on obtient:
\begin{verbatim}
File:Bread rolls.jpg
File:French Bread.jpg
File:Rye Bread.png
…
\end{verbatim}
  et si on effectue maintenant une requête HTTP sur:
\begin{verbatim}
http://wikimedia.org/getURL?file=File:Bread rolls.jpg
\end{verbatim}
  on obtient:
\begin{verbatim}
https://upload.wikimedia.org/wikipedia/commons/6/61/Bread_rolls.jpg
\end{verbatim}

On rappelle que la seule façon de lire une URL depuis du code
Javascript est de faire une requête AJAX asynchrone (i.e. qui appelle
un callback lorsque la réponse du serveur est disponible).

On suppose que l'utilisateur a fourni une chaîne de caractère à
chercher (par exemple « Bread ») et on souhaîte afficher toutes les
images correspondantes.

Donner la suite d'action à effectuer, d'abord grossièrement, puis en
détaillant de plus en plus chaque action, pour arriver à un
pseudo-code exhibant les problèmes d'asynchronisme.


\paragraph{Implémentation par promesses}

\begin{enumerate}
\item Ouvrir le fichier \texttt{mediawiki.js}, lire le code de la
   fonction \texttt{MediaWiki.ajax} et le compléter à l'endroit indiqué.

\item Compléter le code de la fonction \texttt{MediaWiki.query} aux
  endroits indiqués. Cette fonction doit utiliser
  \texttt{MediaWiki.ajax} pour effectuer la requête et renvoyer une
  promesse qui resoudra vers un objet Javascript qui sera la résultat
  de la requête MediaWiki décodée.

\item Compléter la fonction \texttt{MediaWiki.getImageURL(file)}. Cette dernière prend en argument un nom de fichier
  (\texttt{file}). La fonction \texttt{getImageURL} effectue une
  requête auprès de l'API MediaWiki (en utilisant
  \texttt{MediaWiki.query})
  avec les paramètres suivants :
  \begin{description}
    \item[\texttt{titles}] : le nom de fichier (\texttt{file})
    \item[\texttt{action}] : la chaîne fixe \texttt{"query"}
    \item[\texttt{prop}] : la chaîne fixe \texttt{"imageinfo"}
    \item[\texttt{iiprop}] : la chaîne fixe \texttt{"url"}
  \end{description}
  La fonction doit renvoyer une promesse  Javascript se résolvant sur
  un objet décrivant l'URL de l'image.
  Tester la fonction dans la console Javascript de la manière suivante
  :
\begin{verbatim}
MediaWiki.getImageURL("File:Voiture 1905.jpg").then((r) => {
              console.log('OK');
              console.log(r)
           });
\end{verbatim}
Vérifier que la fonction affiche le résultat attendu 
et explorer l'objet affiché dans la console pour voir comment accéder
à l'URL d'une image dans un tel résultat. Donner une expression
Javascript permettant d'aller chercher l'URL dans un tel objet
\texttt{o}.

\begin{reponse}
Voir le fichier joint. En explorant l'objet résultat, on se rend
compte que pour accéder à l'URL, il faut aller chercher l'URL grace à
l'expression:
\begin{verbatim}
o.query.pages[0].imageinfo[0].url
\end{verbatim}
\end{reponse}
\item Compléter la fonction
  \texttt{MediaWiki.searchImages(str)}. Cette dernière prend en
  argument un nom de fichier
  (\texttt{file}). La fonction \texttt{searchImages} effectue une
  requête auprès de l'API MediaWiki (en utilisant
  \texttt{MediaWiki.query})
  avec les paramètres suivants :
  \begin{description}
    \item[\texttt{srsearch}] : la chaîne (\texttt{str})
    \item[\texttt{action}] : la chaîne fixe \texttt{"query"}
    \item[\texttt{srnamespace}] : la chaîne fixe \texttt{"6"}
    \item[\texttt{list}] : la chaîne fixe \texttt{"search"}
    \item[\texttt{utf8}] : la chaîne fixe \texttt{"1"}
    \item[\texttt{srlimit}] : la chaîne fixe \texttt{"20"}
  \end{description}
Dans un premier temps, afficher simplement dans la console le résultat
de la requête AJAX et constater que c'est un objet javascript dont la
propriété \texttt{query} contient un tableau dont chaque élément est
un objet dont la propriété \texttt{title} contient le nom de fichier
recherché.

Modifier ensuite \texttt{searchImages} pour convertir la propriété
\texttt{query} mentionnée ci-dessus en un tableau d'URL menant aux
images correspondantes (en utilisant \texttt{MediaWiki.getImageURL}).
On ne conservera que les URLs se terminant par
\texttt{svg}, \texttt{jpg}, \texttt{jpeg} ou
\texttt{png} (majuscule ou minuscule).

Votre fonction \texttt{searchImages} doit renvoyer une promesse se
résolvant sur le tableau d'URLs.
\item Tester la fonction dans la console Javascript de la manière
  suivante :
\begin{verbatim}
MediaWiki.searchImages( "Bread").then((e) => {
                                        console.log('OK');
                                        console.log(e);
                       });
\end{verbatim}
Vérifier que l'on obtient bien un tableau de 20 URLs (ayant rapport
avec du pain).
\item Lire le fichier \texttt{index.html} et compléter enfin le
  fichier \texttt{init.js}. On souhaite que lorsque le bouton
  \texttt{Rechercher} est cliqué (évènement \texttt{click}), alors la
  chaîne contenue dans la boite de texte (propriété \texttt{value} de
  l'objet Javascript représentant la boite de saisie) soit utilisée
  pour une recherche d'image et que les images trouvées soient
  affichées dans le \texttt{div} d'id \texttt{searchResult} (on créera
  pour chaque URL \textit{u} un élément \texttt{<img src=\textit{u}
    />}.

La requête pouvant prendre du temps, que se passe-t'il si on clique
plusieur fois rapidement sur le bouton ? proposer une solution.
\begin{reponse}
Si on appuie rapidement sur le bouton, une requête peut se lancer
alors que la précédente n'est pas finie. Les résultats peuvent arriver de
manière asynchrone et se mélanger. On choisit donc de désactiver le
bouton le temps que la requête finisse.
\end{reponse}
\end{enumerate}


\end{document}
