Новый блог
Давно уже хотел написать свой блог на CL, но всё не было достаточной мотивации. Но тут недавно я обнаружил, что MongoDB это то, что мне действительно нужно в свете стоящих передо мной задач. Досадно, но существующий драйвер cl-mongo - мало пригоден для работы (его автор, судя по всему, находится на довольно ранней стадии изучения Common Lisp). Так что я решил написать новый драйвер. Собственно, благодаря весьма разумному дизайну бинарного протокола MongoDB основаня техническая работа была выполненна в течении двух дней, но дальше начинается самое интересное - отработка дизайна. Я считаю, что сделать хороший дизайн можно только работая над реальными проектами, но использовать mongo-cl-driver сразу в боевом проекте у меня духа не хватает. И я решил сделать серию небольших проектов на его базе. И первым таким проектом являтся данный блог.
Поскольку я не дизайнер и не имею соответствующих склонностей, то дизайн позаимствовал из давно уже понравившегося мне блоге hades.name.
Импортировать посты из старого блога оказалось достаточно просто, blogger позволяет выгрузить свои сообщения в формате Atom, который обрабатывается довольно тривиальным образом:
"/atom:feed/atom:entry[thr:total and not(app:control/app:draft)]")
(defparameter *xpath-entry-tags*
"atom:category[@scheme='http://www.blogger.com/atom/ns#']/@term")
(defun calc-sha1-id (title published)
(ironclad:byte-array-to-hex-string
(ironclad:digest-sequence
:sha1 (babel:string-to-octets (format nil "~A~A" title published)
:encoding :utf-8))))
(defun import-from-atom-feed (path blog)
(xtree:with-parse-document (feed path)
(let ((xpath:*default-ns-map* '(("atom" "http://www.w3.org/2005/Atom")
("thr" "http://purl.org/syndication/thread/1.0")
("app" "http://purl.org/atom/app#")))
(posts (mongo:collection blog "posts")))
(iter (for rawentry in-xpath-result *xpath-atom-entry* on feed)
(for entry = (son))
(for title = (xpath:find-string rawentry "atom:title"))
(for published = (local-time:parse-timestring (xpath:find-string rawentry "atom:published")))
(setf (gethash "_id" entry)
(calc-sha1-id title published))
(setf (gethash "title" entry)
title)
(setf (gethash "published" entry)
published)
(setf (gethash "updated" entry)
(local-time:parse-timestring (xpath:find-string rawentry "atom:updated")))
(setf (gethash "content" entry)
(xpath:find-string rawentry "atom:content"))
(setf (gethash "tags" entry)
(map 'vector
#'xtree:text-content
(xpath:find-list rawentry *xpath-entry-tags*)))
(mongo:insert-op posts entry)))))
Примечательно, что на данном сервере нет инсталяции MongoDB (ибо используется довольно старая версия Debian). Ставить руками MongoDB у меня никакого желания не было, поэтому я просто взял бесплатную 16-ти мегабайтную базу на MongoHQ и держу посты там. Из-за этого скорость работы может быть на такой быстрой, как хотелось бы.
Ну и наконец я имею возможность писать посты в формате reStructuredText, что приятно само по себе. Ибо в старом блоге надо было писать в HTML, при чём, вставлять куски кода был сущий ад. А теперь всё просто.
Собственно, это был первый пост в новой версии блога. Если вы это читаете, то тест пройден ))