Перенос постов из Drupal в Acrylamid
В этой заметке я постараюсь рассказать о процессе переноса постов из старого блога на Drupal в новый на Acrylamid.
Прежде всего надо отдать ему должное — он из коробки неплохо умеет импортировать контент из произвольных движков через RSS или дамп в формате Wordpress. В простых случаях этого более, чем достаточно, но мне нужно было нечто большее.
Задачу перед собой я поставил так:
- Перенести все посты и комментарии к ним.
- Содержимое постов:
- По возможности сохранить форматирование, в том числе и в самых старых постах, где я использовал bbcode.
- Преобразовать html в markdown для тех случаев, где это возможно.
- Заменить метки друпаловского модуля Inline на обычные ссылки.
- Извлечь из тела поста «feature images» (не могу подобрать адекватный перевод :-( «Картинка для привлечения внимания»?..) и перенести в мета-информацию о посте, чтобы можно было правильно ее стилизовать и размещать без лишней мороки.
- Аналогично поступить с музыкальными видео, которые я добавляю в конец поста в виде постскриптума, при этом необходимо сохранить и их правильные заголовки.
- Структура адресов:
- Сделать более-менее вменяемые URL постов. Например, транслитерированный
кошмар вроде
/blog/aleks/ispolzuem-svn-v-upravlenii-saitom-chast-pervaya-teoreticheskie-soobrazheniya
превратить в более вменяемое/2008/Use-SVN-website-governance-Part-one-theoretical-considerations.html
. - Скорректировать все внутренние ссылки на посты, чтобы они указывали на
правильные адреса постов. Попутно — все внутренние ссылки, картинки и тому
подобное с полными адресами виде
http://nevkontakte.(com|org.ru)/whatever
позаменять на просто/whatever
, чтобы обезопасить себя от проблем в случае смены домена или, например, перехода на https. - Организовать редиректы со старых адресов постов на новые для поисковиков и внешних ссылок.
- Сделать более-менее вменяемые URL постов. Например, транслитерированный
кошмар вроде
Желающие могут сразу отправляться изучать репозиторий на ГитХабе, в который я залил скрипты, выполняющие всю эту работу.
Для того, чтобы решить все эти задачи, мне нужно было добыть из базы данных
Друпала сведения из четырех таблиц: drupal_node
и drupal_node_revisions
(посты,
sql),
drupal_comments
(комментарии,
sql)
и drupal_url_alias
(«человекопонятные» адреса постов,
sql).
В целом процесс импорта выглядел примерно так: извлечение нужных данных из БД →
конвертация базовой мета-информации в объекты Python → приведение её в формат,
близкий к тому, что используется в Acrylamid → присвоение посту нового,
аккуратного URL → применение цепочки фильтров к содержимому постов, решающих
большую часть из поставленных задач → экспорт постов в формат Acrylamid →
построение карт переадресаций для поисковиков и людей, приходящих по старым
внешним ссылкам.
Генерация URL постов
Как я уже упомянул, на Drupal адрес поста генерировался путем банальной
транслитерации русского заголовка поста, и выглядел он совершенно нечитаемо. Как
мне сейчас кажется, лучше уж было использовать короткие адреса /node/1234
. С
другой стороны, в переходить на такую схему адресов мне представлялось
неудобным, так как на новом движке пришлось бы нумеровать из вручную, а это
уничтожает второе достоинство такого подхода.
Единственная альтернатива — использовать в адресе не транслитерацию, а перевод заголовка на английский. И чтобы не насиловать себя переводом заголовков двухсот с лишним постов (233-х, если быть точным) стоило воспользоваться машинным переводом. С одной стороны, это неизбежно даст некоторое количество ляпов, с другой стороны это не критично и в большинстве случаев перевод вполне адекватен.
К моему разочарованию, у Google Translate не оказалось нормального API и даже «пиратской» обертки на python к их веб-интерфейсу. Я уже было собрался лезть и с помощью Firebug выяснять, как он общается с сервером, когда меня неожиданно выручил Яндекс со своим Яндекс.Переводчиком. Качество перевода у него было похуже, но зато имелся вполне официальный API и даже готовый модуль для питона.
Для полноты счастья, я сделал кэширование обращений к переводчику, чтобы, с одной стороны, не делать двести HTTP запросов при всяком тестовом запуске скрипта и, с другой, не схлопотать ненароком бан со стороны Яндекса за подозрительную активность. С этой милой привычкой Яндекса я познакомился еще давно. Сделать это оказалось предельно просто с помощью модуля filecache.
Преобразование формата постов
По началу именно эта часть работы пугала меня больше всего. Пытаться сделать все на регулярных выражениях — известный способ получить себе еще одну проблему.
Some people, when confronted with a problem, think: “I know, I’ll use regular expressions.” Now they have two problems.
Jamie Zawinski
Спасла меня, как оказалось, довольно известная библиотека: Beautiful Soup 4. Несмотря на довольно странное название, она позволяет буквально творить чудеса с HTML-кодом. Помимо достаточно богатых возможностей по манипулированию DOM, она умеет искать в нем по самым разным хитрым критериям, вплоть до самописных функций-предикатов.
Этот код сначала находит тег <iframe>
и <object>
, которые могут быть
вставленным кодом youtube, потом ищет перед ним тег <h3>
, откуда извлекает
название и исполнителя песни, добавляет их в мета-информацию поста и вырезает
уже ненужные теги из тела. Как бы я это безумие делал рерулярками — страшно
подумать…
Остальные преобразования я делал аналогичным методом: найти нужный тег, вырезать, преобразовать его содержимое, вставить на место.
To be continued…
В следующем посте я подробнее рассмотрю проблему смены структуры URL блога и создания редиректов на месте старых ссылок.