Лог-головоломка на Python. Упражнение

В упражнении «Загадка с журналами» вы будете использовать код Python для решения двух головоломок. В этом упражнении используется модуль urllib, как показано в разделе «Утилиты Python» . Файлы для этого упражнения находятся в каталоге «logpuzzle» внутри google-python-exercisions (загрузите google-python-exercisions.zip , если вы еще этого не сделали, подробности см. в разделе «Настройка» ). Добавьте свой код в файл «logpuzzle.py».

Изображение животного разбито на множество узких вертикальных полос. Изображения полосок есть где-то в Интернете, каждое со своим URL-адресом. URL-адреса скрыты в файле журнала веб-сервера. Ваша задача — найти URL-адреса и загрузить все полосы изображений, чтобы воссоздать исходное изображение.

URL-адреса фрагментов скрыты внутри файлов журналов Apache (веб-сервер Apache с открытым исходным кодом является наиболее широко используемым сервером в Интернете). Каждый файл журнала взят с определенного сервера, а URL-адреса нужных фрагментов скрыты в журналах. Файл журнала кодирует сервер, с которого он поступает, следующим образом: файл журнала Animal_code.google.com взят с сервера code.google.com (формально мы скажем, что имя сервера — это то, что следует за первой чертой подчеркивания). Файл журнала Animal_code.google.com содержит данные для изображения головоломки «животное». Хотя данные в файлах журналов имеют синтаксис настоящего веб-сервера Apache, данные, выходящие за рамки того, что необходимо для решения головоломки, представляют собой рандомизированные данные из реального файла журнала.

Вот как выглядит одна строка из файла журнала (именно так выглядят файлы журнала 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"

Первые несколько цифр — это адрес запрашивающего браузера. Самая интересная часть — это «GET path HTTP», показывающий путь веб-запроса, полученного сервером. Сам путь никогда не содержит пробелов и отделяется от GET и HTTP пробелами (рекомендация по регулярному выражению: \S (заглавные буквы S) соответствует любому символу, не являющемуся пробелом). Найдите в журнале строки, в пути которых появляется строка «головоломка», игнорируя множество других строк в журнале.

Часть A. Файл журнала на URL-адреса

Завершите функцию read_urls(filename), которая извлекает URL-адреса головоломки из файла журнала. Найдите все URL-адреса путей «головоломки» в файле журнала. Объедините путь от каждого URL-адреса с именем сервера из имени файла, чтобы сформировать полный URL-адрес, например «http://www.example.com/path/puzzle/from/inside/file». Отфильтровывайте URL-адреса, которые появляются более одного раза. Функция read_urls() должна возвращать список полных URL-адресов, отсортированных в алфавитном порядке и без дубликатов. Взяв URL-адреса в алфавитном порядке, вы получите фрагменты изображения в правильном порядке слева направо, чтобы воссоздать исходное изображение животного. В простейшем случае функция main() должна просто распечатать URL-адреса, по одному в строке.

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

Часть B. Головоломка с загрузкой изображений

Завершите функцию download_images(), которая принимает отсортированный список URL-адресов и каталог. Загрузите изображение с каждого URL-адреса в заданный каталог, сначала создав каталог, если необходимо (см. модуль «os», чтобы создать каталог, и «urllib.urlretrieve()» для загрузки URL-адреса). Назовите локальные файлы изображений по простой схеме, например «img0», «img1», «img2» и т. д. Возможно, вы захотите напечатать небольшую строку вывода статуса «Получение...» при загрузке каждого изображения, поскольку это может быть медленным, и приятно иметь некоторую информацию о том, что программа работает. Каждое изображение представляет собой небольшой вертикальный срез оригинала. Как соединить кусочки вместе, чтобы воссоздать оригинал? Эту проблему можно легко решить с помощью небольшого количества HTML (знание HTML не требуется).

Функция download_images() также должна создать в каталоге файл index.html с тегом *img* для отображения каждого локального файла изображения. Все теги img должны находиться на одной строке без разделения. Таким образом, браузер плавно отображает все фрагменты вместе. Для этого вам не нужно знание HTML; просто создайте файл index.html, который выглядит следующим образом:

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

Вот как это должно выглядеть, когда вы сможете скачать пазл с животными:

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

Когда все заработает, при открытии index.html в браузере должно появиться исходное изображение животного. Что за животное на картинке?

Часть C. Дескремблирование фрагмента изображения

Вторая головоломка включает в себя изображение очень известного места, но зависит от некоторой пользовательской сортировки. Для первой головоломки URL-адреса можно отсортировать в алфавитном порядке, чтобы правильно упорядочить изображения. При сортировке используется весь URL-адрес. Однако мы скажем, что если URL-адрес заканчивается шаблоном «- wordcharswordchars .jpg», например «http://example.com/foo/puzzle/bar-abab-baaa.jpg», тогда URL-адрес должен быть представлено вторым словом в сортировке (например, «бааа»). Таким образом, сортировка списка URL-адресов, каждый из которых заканчивается шаблоном word-word.jpg, должна упорядочивать URL-адреса по второму слову.

Расширьте свой код, чтобы правильно упорядочить такие URL-адреса, и тогда вы сможете расшифровать вторую головоломку Place_code.google.com, которая показывает известное место. Какое место оно показывает?

С указанием авторства CC: изображения, использованные в этой головоломке, были предоставлены их владельцами по лицензии Creative Commons Attribution 2.5 , которая щедро поощряет создание ремиксов контента, подобных этому. Изображение животного предоставлено пользователем zappowbang с сайта flickr, а изображение места — от пользователя booleansplit с сайта flickr.