Scala : TD 2
`Paradigmes et langages non classiques 2014
Ce TD permet de manipuler et d’approfondir les différents concepts
abordés lors du troisième cours Scala. Le même fichier
de configuration pour sbt
pourra être initialement utilisé et sera
complété par la suite.
Observables
Écrire une fonction qui retourne un observable contenant les caractères composant le résultat d’une requête HTTP :
def fromURL(url: String): Observable[Char]
puis une fonction qui, en utilisant la précédente, renvoie le contenu agrégé sous la forme d’une chaîne de caractères :
def getContent(url: String): Observable[String]
Ces observables, quand un nouvel abonné arrivera, devront s’exécuter dans le
scheduler IOScheduler()
(dans le package rx.lang.scala.schedulers
). On
utilisera pour cela la méthode subscribeOn(…)
de l’observable. Seul fromURL
nécessite d’être ainsi équipé, puisque par défaut les observables ne faisant que
traiter celui-ci hériteront de cette propriété.
Ne pas hésiter, pendant le développement, à afficher l’url demandée, pour suivre facilement la trace des requêtes lorsqu’elles sont faites.
Si on souhaite utiliser les fonctions de créations d’observables autre que la fonction
qui prend un abonné, on tirera avantageusement parti de Observable.defer
qui permet de ne retourner un
observable que lorsqu’il a un abonné.
Note : pour une requête aussi simple (GET
), on pourra utiliser Scala.io.Source.fromURL
.
JSON library
Certains services web retournent des données au format
JSON. Pour les analyser,
on utilisera la bibliothèque spray-json, qu’il
faudra ajouter à sbt
.
Écrire une fonction qui, en utilisant getContent, renvoie une valeur JSON à partir d’une URL:
def getJSON(url: String): Observable[JsValue]
On testera cette fonction avec l’URL http://ip.jsontest.com/
qui retourne un objet JSON avec un champ “ip” contenant l’adresse IP de l’appelant.
Trakt API
Le site trakt permet de récupérer des informations sur les différentes séries télévisées, les films, etc. En plus d’être visualisables dans un navigateur, ces informations sont disponibles sous la forme d’une API accessible en REST renvoyant les résultats sous la forme d’objets JSON ou XML.
Pour pouvoir utiliser cette API, il faut obtenir une clé qui devra accompagner les requêtes. Une fois enregistré, la clé s’obtient ici (Settings / API).
Récupération de l’heure
Écrire un observable permettant de récupérer l’heure telle que vue par le serveur Trakt.
val traktTimestamp: Observable[Int]
En prévision des autres appels à l’API Trakt, on pourra créer des fonctions utilitaires permettant d’accéder à une fonctionnalité donnée de l’API sans répéter la clé d’API et le chemin complet :
def getTraktJSON(path: String, args: Iterable[String] = List()): Observable[JsValue]
def getTraktMap(path: String, args: Iterable[String] = List()): Observable[Map[String, JsValue]]
Récupération des informations sur une série télévisée
Écrire une fonction permettant de récupérer les informations sur les
différentes saisons d’une série télévisée. title
est soit le champ
d’identification de Trakt (tvdb_id
) soit le slug de la série qu’on
obtient en regardant l’URL de la page de présentation d’une série (par
exemple “the-walking-dead” pour la série
The Walking Dead).
def traktShowSeasons(title: String): Observable[Season]
où le type Season
est défini comme:
case class Season(season: Int,
: Int,
episodes: String,
url: Map[String, String]) images
On utilisera l’object mapper de spray-json pour convertir facilement une chaîne JSON
en type Season
.
Récupération des mises à jour
Écrire un observable permettant de récupérer les mises à jour ayant eu lieu sur les séries
télévisées dans les 12 dernières heures (en utilisant l’heure déterminée par traktTimestamp
).
Chaque série sera représentée sous la forme d’un dictionnaire Scala.
val traktUpdated: Observable[Map[String, JsValue]]
Nom des séries mises à jour
Écrire un observable qui renvoie le nom des séries mises à jour ainsi que leur date de mise à jour
et leur champ tvdb_id
.
val traktUpdatedByName: Observable[(String, Int, Int)]
On pourra tirer parti de la méthode parallel
des observables qui permet d’effectuer des opérations
en parallèle et de recoller les résultats.
Bonus : tri par nombre d’épisodes
Écrire un observable retournant la même information que traktUpdated
mais en triant les
séries par nombre décroissant total d’épisodes.
val traktUpdatedByEpisodes: Observable[(String, Int, Int)]
On pourra, par exemple, utiliser un observable renvoyant le nombre total d’épisodes pour une
série télévisée donnée en utilisant traktShowSeasons
, combiner cette information avec
la liste obtenue par traktUpdated
, convertir les données sous forme de liste, les trier, et
les réexploser.