Как читать Википедию на вашем iPod



Любите читать статьи из Википедии? Почему бы не сделать их доступными постоянно? Данный рецепт показывает, как закачать на ваш iPod тысячу страниц из Википедии.Я как-то раз уже говорил, что готов заплатить от $100 за карманную версию Википедии, которую я мог бы синхронизировать через Wi-Fi, взять с собой в дорогу и читать, сидя, например, в автобусе. Вот только этот мой комментарий так и остался гласом вопиющего в пустыне. Ну, что же тут можно поделать. Тогда я взял и написал на Perl скрипт, который загружает статьи из Википедии на мой iPod.

Скрипт под названием WikiPod начинает работать на одной странице Википедии, проходит по всем найденным ссылкам и загружает все страницы на iPod. Затем этот скрипт поступает точно так же по отношению к каждой из ссылок, найденной на новых страницах, и этот процесс продолжается до тех пор, пока не закончатся ссылки или пока не будет достигнут указанный вами предел. Текст моего скрипта на Perl приведен в листинге.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199//Скрипт для закачивания статей из Википедии на iPod  #!/usr/bin/perl## wikiPod 1.6## Usage# ——# wikiPod <wikipedia URL> <path to iPod notes directory> <# MB to fill>## About# ——# This perl script formats wikipedia articles for viewing on an iPod using# the iPod’s «Notes» feature. Starting at the wikipedia URL specified on the# command-line, all links are followed and the corresponding pages are saved# to the iPod, continuing until the amount of space specified on the command-# line has been filled.## Note that the iPod may take some time to load the articles on first browse.# Once it has completed this process (which seems to continue even if youleave# and do other tasks on the iPod), notes load quickly. I highly recommend# plugging the iPod in while this process completes, as is it disk- (and thus# battery-) intensive.## Version History# —————# 1.0: 10/1/2006 Initial release# 1.1: 10/14/2006 Fixed problem with / characters in URL,# allowed users to leave off the trailing slash,# and limited how many MB we’ll fetch# 1.2: 10/14/2006 Includes tag to properly display UTF-8 encoded chars# 1.3: 10/14/2006 Stops after 1000 notes, since the iPod won’t display# more than that. Also fixed missing slash in dupe check.# 1.4: 10/14/2006 Script now sleeps for two seconds between page requests# to comply with wikipedia’s robots.txt file, which states# that «friendly, low-speed bots are welcome viewing articlepages».# 1.5: 10/14/2006 Sleep is set for four seconds now.# 1.6: 11/22/2006 Now gives additional feedback to the user. (David Still)###############################################################use POSIX qw(ceil floor);sub WritePage;sub SanitizeHTML;if (@ARGV != 3){print «usage: wikiPod <wikipedia URL> <path to iPod notes directory> » .»<# MB to fill>nn»;exit;}$numPages = 0;$fullURL = $ARGV[0];$notesDir = $ARGV[1];$numMB = $ARGV[2];# This should not be changed, lest ye feel the wrath of the Wikimediafolks# TODO: allow pages to be read from a local db cacheif ($numMB > 50){$numMB = 50;}$numKBytes = $numMB * 1024;# Get the locale-specific wikipedia hostname and initial page name$fullURL =~ /http://(.*).wikipedia.org/wiki/(.*)/;$URLprefix = «http://» . $1 . «.wikipedia.org/wiki/»;# The pages to process# (WritePage sticks links on to the end of this array)@links = ($2);# Loop until we’ve filled up all our allotted space (MB or 1000 notes),# or until there are no more links to getwhile ((($numPages * 4) < $numKBytes) && (@links > 0) && ($numPages < 1000)){# Get the next pagemy $currentPage = shift(@links);# Process the next pageWritePage($currentPage);# Keep the user informedprint «nTransferred » . $numPages . » pages…»;}# We’re done!print «nDone transferring » . $numPages . » pages!nn»;sub WritePage {my $name = shift(@_);# Replace slashes with underscore for the filenamemy $safeFilename = $name;$safeFilename =~ s///_/s;# Don’t do anything if we’ve already processed this page!if (-e ($notesDir . «/» . $safeFilename)){return;}# Download the starting page ($ARGV[0] is the first param)my $CMD = «curl -s «» . $URLprefix . $name .»»»;# Execute the command and store the results in $HTMLmy $HTML = `$CMD`;# Extract the content$HTML =~ /<div id=»content»>(.*)<!— end content —>/s;my $content = SanitizeHTML($1);for ($count = 0; $count < ceil(length($content)/4000); $count++){$section = substr($content, $count * 4000, 4000);$section = $section . «nn»;# Hitting «menu» goes back, so an explicit «back» link isn’t necessary.# if ($count > 0)# {# if ($count == 1) {# $section = $section . «<A HREF=»» . $name . «»>Prev page</A>»;# }# else {# $section = $section . «<A HREF=»» . $name .# ($count — 1) . «»>Prev page</A>»;# }## if (($count + 1) < ceil(length($content)/4000)) {# $section = $section . » | «;# }# }if (($count + 1) < ceil(length($content)/4000)){$section = $section . «<A HREF=»» . «z» .$safeFilename . ($count + 1) . «»>Next page</A>»;}# Prepend our content with a tag to let the iPod know we’re doing UTF-8# More info: http://docs.info.apple.com/article.html?artnum=61894$section = «<?xml encoding=»UTF8″?>» . $section;# Calculate the filename and add a slash whether the user specified# one or not — this is messy but it works.if ($count == 0){$filename = «>» . $notesDir . «/» . $safeFilename;}else{$filename = «>» . $notesDir . «/z» . $safeFilename . $count;}# Open a new fileopen my $file, $filename or die «Can’t write file: $!»;# Write our data out to a fileprint $file $section;# Flush the buffer and close the fileclose $file;# Increment the number of pages we’ve done$numPages++;}# Sleep for four seconds to obey the wikipedia robots.txt filesleep(4);sub SanitizeHTML {# Put the HTML to be sanitized in $rawmy $raw = shift(@_);# Remove non-article content$raw =~ s/<div id=»siteNotice»>.*?</div>//s;$raw =~ s/<div id=»jump-to-nav»>.*?</div>//s;$raw =~ s/<table class=»messagebox protected».*?</table>//s;$raw =~ s/<div class=»thumb tleft»>.*?</div>.*?</div>//s;$raw =~ s/<div class=»thumb tright»>.*?</div>.*?</div>//s;$raw =~ s/<!— end content —>.*//s;# OPTIONAL# Remove disambiguation links… we generally don’t want to follow those$raw =~ s/<div class=»dablink»>.*?</div>//s;# OPTIONAL# Remove tables# $raw =~ s/<table .*?</table>//gs;# Remove category links$raw =~ s/<div id=»catlinks»>.*?</div>//s;# Remove everything at and below the References section$raw =~ s/<ol class=»references».*//s;# Convert the <h1> heading to a __TITLE__$raw =~ s/<h1class=»firstHeading»>(.*?)</h1>/__TITLE__$1__ENDTITLE__/s;# Convert wiki links to __LINK__$raw =~ s/<a href=»/wiki/(.*?)».*?>(.*?)</a>/__LINKURL__$1__LINKTEXT__$2__ENDLINK__/gsx;# <p> and <br> become carriage returns$raw =~ s/<p>/n/ig;$raw =~ s/<br>/n/ig;# <li> becomes -$raw =~ s/<li>/- /ig;# All other tags disappear$raw =~ s/<.+?>//gs;# Convert __TITLE__ back into an actual title$raw =~ s/__TITLE__(.*?)__ENDTITLE__/<TITLE>$1</TITLE>/s;# Get rid of __LINK__ tags that point to images or special wikipedia locations$raw =~ s/__LINKURL__(S+?):(S+?)__LINKTEXT__.*?__ENDLINK__//gs;# Convert all other __LINK__ tags back into valid links$raw =~s/__LINKURL__(.*?)__LINKTEXT__(.*?)__ENDLINK__/<A HREF=»$1″>$2</A>/gs;# Strip whitespace$raw =~ s/s*//;$raw =~ s/n/__W__/g;$raw =~ s/ss+//g;$raw =~ s/__W__(__W__)+/nn/g;$raw =~ s/__W__/n/g;# Find all the links in the documentmy @linkUrls = $raw =~ /<A HREF=»(.*?)»/g;push(@links, @linkUrls);# Back where it came fromreturn $raw;}


Ручной ввод этого скрипта довольно трудоемок, поэтому, если вы хотите им пользоваться, просто скачайте его с домашней страницы Мэтта Свана (Matt Swann) http://homepage.mac.com/swannman/wikiPod.zip.

Загрузив скрипт, переместите его на рабочий стол (сразу же после скачивания скрипт, скорее всего, попадет в папку Downloads). Запустите приложение Terminal и дайте следующую команду:

1$ cd ~/Desktop

Как только вы перейдете на рабочий стол, дайте следующую команду:

1$ chmod 755 wikiPod

Эта команда сделает скрипт исполняемым файлом, после чего вы будете полностью готовы к его использованию.

Использование скрипта

Использование скрипта не сводится к обычному двойному щелчку мышью, но и сложным оно не является тоже. Примонтируйте ваш iPod в дисковом режиме (определить, находится ли ваш iPod в дисковом режиме, можно по присутствию значка iPod на рабочем столе). Затем откройте приложение Terminal.app и введите следующую команду:

1$ cd ~/Desktop

Перейдите на страницу Википедии, с которой хотели бы начать. Для данного примера я выбрал страницу, посвященную iPod. Введите следующую команду:

1$ ./wikiPod http://en.wikipedia.org/wiki/IPod

Обратите внимание, что хотя вы и не можете этого видеть в печатном варианте, но в конце этой команды, сразу же за словом IPod, должен следовать символ пробела. Иными словами, вам следует ввести эту команду, добавить в ее конец символ пробела, нажав на клавиатуре клавишу Space.

Выполните двойной щелчок мышью на значке iPod и перетащите папку Notes в окно приложения Terminal. Если вы уверенно чувствуете себя с командной строкой, то тогда введите следующий путь: /Volumes/youriPod/Notes. Здесь youriPod — это имя вашего iPod. Наконец, введите количество Мбайт дискового пространства, которое вы хотите отвести под статьи Википедии. В итоге введенная вами командная строка должна будет выглядеть примерно следующим образом: $ ./wikiPod http://en.wikipedia.org/wiki/IPod /Volumes/youriPod/Notes 10. Нажмите клавишу Enter, и ваш iPod начнет заполняться статьями из Википедии (рис. 7.28).

Рис. 7.28. Приложение Terminal выполнит за вас всю тяжелую работу
Рис. 7.28. Приложение Terminal выполнит за вас всю тяжелую работу

Перейдите обратно в папку iPod, выполните двойной щелчок мышью по папке Notes и наблюдайте за тем, как происходит загрузка статей из Википедии, отформатированных для вашего iPod (рис. 7.29).

Рис. 7.29. Страницы из Википедии загружаются на ваш iPod!
Рис. 7.29. Страницы из Википедии загружаются на ваш iPod!

Когда работа скрипта завершится, он выведет следующее сообщение: Done transferring x pages! После появления этого сообщения вы можете отмонтировать ваш iPod.

С использованием заметок на iPod связана одна проблема. Когда вы впервые перейдете в меню Notes после синхронизации с iTunes или загрузки новых статей из Википедии, iPod потребуется проинспектировать каждую страницу с тем, чтобы убедиться в правильности ссылок. Для этого потребуется довольно продолжительное время (и хорошо заряженная батарея, так как в ходе этого процесса будет идти интенсивная работа с диском). Поэтому я рекомендую на время этого процесса оставить iPod подключенным. Вот это действительно неприятный момент. Автор скрипта пытается найти какое-то решение этой проблемы, но, честно говоря, настроен он не слишком оптимистично.

Думаю, что после предложенного решения вы захотите использовать в качестве заметок на вашем iPod не только статьи из Википедии. Хорошая новость заключается в том, что вы можете модифицировать этот скрипт таким образом, чтобы закачивать на iPod любые источники с Web-содержимым. Это я оставляю на ваше усмотрение. Кроме того, это будет полезное упражнение, которое позволит вам попрактиковаться в написании скриптов на Perl.