Exercice de logique de journal Python

Pour l'exercice "Log Puzzle", vous allez utiliser du code Python pour résoudre deux énigmes. Cet exercice utilise le module urllib, comme indiqué dans la section Utilitaires Python. Les fichiers correspondant à cet exercice se trouvent dans le répertoire "logpuzzle" de google-python-exercises (téléchargez le fichier google-python-exercises.zip si ce n'est pas déjà fait ; pour en savoir plus, consultez Configurer). Ajoutez votre code au fichier "logpuzzle.py".

L'image d'un animal a été décomposée en de nombreuses images étroites à rayures verticales. Les images de rayures se trouvent quelque part sur Internet, chacune ayant sa propre URL. Les URL sont masquées dans un fichier journal de serveur Web. Votre mission consiste à trouver les URL et à télécharger toutes les bandes afin de recréer l'image d'origine.

Les URL des tranches sont masquées dans les fichiers journaux Apache (le serveur Web Open Source apache est le serveur le plus utilisé sur Internet). Chaque fichier journal provient d'un serveur et les URL de segments souhaitées sont masquées dans les journaux. Le fichier journal encode le serveur dont il provient comme suit: le fichier journal animal_code.google.com provient du serveur code.google.com (officiellement, nous disons que le nom du serveur est celui qui suit le premier trait de soulignement). Le fichier journal animal_code.google.com contient les données de l'image du puzzle "animal". Bien que les données des fichiers journaux aient la syntaxe d'un véritable serveur Web Apache, les données dépassant ce qui est nécessaire pour le puzzle sont des données aléatoires provenant d'un vrai fichier journal.

Voici à quoi ressemble une seule ligne du fichier journal (c'est exactement ce à quoi ressemblent les fichiers journaux Apache):

10.254.254.28 - - [06/Aug/2007:00:14:08 -0700] "GET /foo/talks/ HTTP/1.1"
200 5910 "-" "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4"

Les premiers chiffres correspondent à l'adresse du navigateur à l'origine de la demande. La partie la plus intéressante est la requête "GET path HTTP", qui indique le chemin d'une requête Web reçue par le serveur. Le chemin lui-même ne contient jamais d'espaces et est séparé de GET et HTTP par des espaces (suggestion d'expression régulière: \S (S majuscule) correspond à tout caractère qui n'est pas d'espace). Recherchez les lignes du journal où la chaîne "puzzle" apparaît dans le chemin, en ignorant les nombreuses autres lignes du journal.

Partie A - Fichier journal dans les URL

Complétez la fonction read_urls(filename) qui extrait les URL du puzzle à partir d'un fichier journal. Recherchez toutes les URL des chemins d'accès "puzzle" dans le fichier journal. Combinez le chemin de chaque URL avec le nom du serveur contenu dans le nom du fichier pour former une URL complète, par exemple "http://www.example.com/chemin/puzzle/de/dans/fichier". Excluez les URL qui s'affichent plusieurs fois. La fonction read_urls() doit renvoyer la liste des URL complètes, triées par ordre alphabétique et sans doublons. En prenant les URL par ordre alphabétique, vous obtiendrez les segments de l'image dans l'ordre correct de gauche à droite pour recréer l'image d'origine de l'animal. Dans le cas le plus simple, main() doit simplement imprimer les URL, une par ligne.

$ ./logpuzzle.py animal_code.google.com
http://code.google.com/something/puzzle-animal-baaa.jpg
http://code.google.com/something/puzzle-animal-baab.jpg
...

Partie B - Télécharger le puzzle d'images

Complétez la fonction download_images() qui prend une liste triée d’URL et un répertoire. Téléchargez l'image de chaque URL dans le répertoire donné, en créant d'abord le répertoire si nécessaire (consultez le module "os" pour créer un répertoire, et la fonction "urllib.urlretrieve()" pour le téléchargement d'une URL). Nommez les fichiers image locaux en utilisant un schéma simple tel que "img0", "img1", "img2", etc. Vous pouvez imprimer une petite ligne de sortie indiquant l'état "Récupération..." lors du téléchargement de chaque image. Cette opération peut être lente et il est utile d'avoir des indications sur le fonctionnement du programme. Chaque image est une petite tranche verticale de l'original. Comment assembler les tranches pour recréer l'original ? Il suffit d'un peu de code HTML pour le résoudre (il n'est pas nécessaire de connaître le langage HTML).

La fonction download_images() doit également créer un fichier index.html dans le répertoire avec une balise *img* pour afficher chaque fichier image local. Les tags img doivent être placés sur une seule ligne, sans séparation. De cette façon, le navigateur affiche toutes les tranches ensemble de manière transparente. Vous n'avez pas besoin de connaître le langage HTML pour effectuer cette opération. Il vous suffit de créer un fichier index.html de ce type:

<html>
<body>
<img src="img0"><img src="img1"><img src="img2">...
</body>
</html>

Voici à quoi devrait ressembler le jeu lorsque vous pourrez télécharger ce jeu d'animaux:

$ ./logpuzzle.py --todir animaldir animal_code.google.com
$ ls animaldir
img0  img1  img2  img3  img4  img5  img6  img7  img8  img9  index.html

Lorsque tout fonctionne, ouvrez le fichier index.html dans un navigateur pour afficher l'image d'origine de l'animal. Quel est l'animal illustré sur l'image ?

Partie C - Décrochage de segments d'image

Le second est l'image d'un lieu très célèbre, dont le tri est personnalisé. Pour le premier puzzle, les URL peuvent être triées par ordre alphabétique afin d'organiser les images correctement. Pour le tri, l'URL complète est utilisée. Cependant, si l'URL se termine par "-motchars-motclé.jpg", par exemple "http://example.com/foo/puzzle/bar-abab-baaa.jpg", elle doit être représentée par le deuxième mot du tri (par exemple, "baaa"). Ainsi, si vous triez une liste d'URL se terminant par le format word-word.jpg, les URL seront classées selon le deuxième mot.

Étendez votre code pour classer correctement ces URL. Vous devriez ensuite être en mesure de décoder le deuxième puzzle place_code.google.com présentant un lieu célèbre. Quel lieu affiche-t-il ?

Paternité CC: les images utilisées dans ce puzzle ont été mises à disposition par leurs propriétaires sous la licence Creative Commons Attribution 2.5, ce qui encourage généreusement à remixer des contenus comme celui-ci. L'image de l'animal provient de l'utilisateur zappowbang sur flickr et l'image du lieu provient de la valeur booléennesplit de l'utilisateur sur Flickr.