← Blog of oldlisper

Новый блог

· 26.04.2011 00:00
· original author: archimag

Новый блог

Давно уже хотел написать свой блог на CL, но всё не было достаточной мотивации. Но тут недавно я обнаружил, что MongoDB это то, что мне действительно нужно в свете стоящих передо мной задач. Досадно, но существующий драйвер cl-mongo - мало пригоден для работы (его автор, судя по всему, находится на довольно ранней стадии изучения Common Lisp). Так что я решил написать новый драйвер. Собственно, благодаря весьма разумному дизайну бинарного протокола MongoDB основаня техническая работа была выполненна в течении двух дней, но дальше начинается самое интересное - отработка дизайна. Я считаю, что сделать хороший дизайн можно только работая над реальными проектами, но использовать mongo-cl-driver сразу в боевом проекте у меня духа не хватает. И я решил сделать серию небольших проектов на его базе. И первым таким проектом являтся данный блог.

Поскольку я не дизайнер и не имею соответствующих склонностей, то дизайн позаимствовал из давно уже понравившегося мне блоге hades.name.

Импортировать посты из старого блога оказалось достаточно просто, blogger позволяет выгрузить свои сообщения в формате Atom, который обрабатывается довольно тривиальным образом:

(defparameter *xpath-atom-entry*
  "/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, при чём, вставлять куски кода был сущий ад. А теперь всё просто.

Собственно, это был первый пост в новой версии блога. Если вы это читаете, то тест пройден ))