середу, 26 листопада 2014 р.

Музей корупції "Межигір'я"

Этим летом мы с Викой побывали в музее коррупции "Межигір'я". Ниже будет небольшой фоторепортаж. О размерах бывшего обиталища Януковича скажу следующее. Сначала мы ездили минут 45 на электромобиле с обзорной экскурсией. Затем взяли на прокат велосипеды и катались еще два часа, рассматривая более подробные разные интересности. Потом еще почти час ходили по зоопарку. Устали довольно сильно. При этом не успели посетить Хонку и так и не нашли дорожку с пеньками. Так что надо будет съездить еще раз.


Вот на таких автомобильчиках проводится обзорная экскурсия.


На входе дают на прокат велосипеды. Обходить пешком все территорию нереально.






На всех фонарных столбах висит Янукович изображен герб семьи Януковичей. К сожалению, видно плохо



Знаменитая Хонка. Название происходит от финского слова "сосна"


Набережная

Экскурсовод сказал, что длина - 6 км., как в Феодосии. Я не измерял, но визуально сравнима с феодосийской

Молоко Батя пил от собственных коров



Прочая живность

Галеон



Тревожить покой Януковича не рекомендовалось

Гараж

Сад...

... и теплица

В зоопарке очень много козлов. Подозреваю, что Янукович чувствовал к ним какую-то близость (хотя и не хорошо сравнивать бедных животных с ним)





Высота забора - 6м.

Слава Україні!


середу, 12 листопада 2014 р.

Проверка правильности ссылок в Markdown-файлах

Введение

В статье Ведение блога на Blogger с помощью Vim я описал ведение блога на Blogger с помощью Vim и специального python-скрипта, который используется для публикации текстов. Как правило, хороший пост содержит некоторое количество ссылок. Естественно, хотелось бы быть уверенным, что ссылки не содержат ошибок. Способ проверки, изложенный в статье не очень подходит, так как предложенный скрипт просто выводит ссылку и результат её проверки. Более удобной бы была проверка в соответствии с идеологией Vim: с помощью :make и quickfix. Рассмотрим, как можно добиться такого функционала.

Выбор инструмента

Для проверки ссылок будем использовать linkchecker. Данный инструмент может проверять как сайты, так и локальные файлы. Также он поддерживает систему плагинов. Например, существуют плагины для проверки ссылок в документах MS Word или pdf-файлах.
Установка:
sudo pip install LinkChecker

Теперь можно проверять файлы:
linkchecker -v --check-extern t.html
LinkChecker 9.3              Copyright (C) 2000-2014 Bastian Kleineidam
...
Start checking at 2014-11-12 16:16:56+003
...
URL        http://xvadim.chgk.info/wb1/'
Name404'
Parent URL file:///Users/vadimkhohlov/work/blogger/t.html, line 6, col 9
Real URL   http://xvadim.chgk.info/wb1/
Check time 1.696 seconds
Size       284B
Result     Error: 404 Not Found
...

Разработка плагина

Инициализация

Файл с кодом плагина должен располагаться в подкаталоге linkcheck/plugins. Задача плагина - извлечь все ссылки из файла. Корректность ссылок будет проверять сам linkchecker.
Класс в нашем случае должен наследоваться от _ContentPlugin:
from . import _ContentPlugin
from .. import log, LOG_PLUGIN
class MarkdownCheck(_ContentPlugin):
    _default_filename_re = re.compile(r'.*\.(markdown|md(own)?|mkdn?)$')

    def __init__(self, config):
        super(MarkdownCheck, self).__init__(config)
        self.filename_re = self._default_filename_re

    def applies_to(self, url_data, pagetype=None):
        return self.filename_re.search(url_data.base_url) is not None
Метод applies_to должен вернуть True если плагин умеет обрабатывать данный файл. linkchecker пытается самостоятельно определить тип файла и передаёт его через параметр pagetype. Однако, в нашем случае он этого сделать не может. Поэтому приходится анализировать имя файла.

Обработка файла

Обрабатывает файл метод check(self, url_data):
_link_res = [re.compile(r'<((https?|ftp):[^\'">\s]+)>', re.I)]
def check(self, url_data):
    content = url_data.get_content()
    self._check_by_re(url_data, content)
def _save_url(self, url_data, content, url_text, url_pos):
    line = content.count('\n', 0, url_pos) + 1
    column = url_pos - content.rfind('\n', 0, url_pos)
    url_data.add_url(url_text.translate(None, '\n '), line=line, column=column)
def _check_by_re(self, url_data, content):
    for link_re in self._link_res:
        for u in link_re.finditer(content):
            self._save_url(url_data, content, u.group(1), u.start(1))
С помощью регулярного выражения метод выбирает автоссылки вида <http://autolink.com> и добавляет их к объекту url_data. Номер строки вычисляется как количество символов \n, а столбец - как расстояние до ближайшего левого \n.

Дополнительные настройки плагина

Для того, чтобы данный плагин был активирован, необходимо в файле ~/.linkchecker/linkcheckerrc добавить строку:
[MarkdownCheck]
Было бы неплохо как-то параметризовать маску имени файла. Например, я, как писал ранее, сохраняю файлы постов блога с расширением blog. Добиться этого можно следующим кодом:
_filename_re_key = "filename_re"
def __init__(self, config):
        super(MarkdownCheck, self).__init__(config)
        self.filename_re = self._default_filename_re
        pattern = config.get(self._filename_re_key)
        if pattern:
            try:
                self.filename_re = re.compile(pattern)
            except re.error as msg:
                log.warn(LOG_PLUGIN, "Invalid regex pattern %r: %s" % (pattern, msg))

    @classmethod
    def read_config(cls, configparser):
        """Read configuration file options."""
        config = dict()
        config[cls._filename_re_key] = configparser.get(cls.__name__, cls._filename_re_key) \
            if configparser.has_option(cls.__name__, cls._filename_re_key) else None
        return config
Скрипт ищет в конфиге параметр с ключем filename_re. Если не находит, использует стандартную маску имён Markdown-файлов. После этого конфиг может быть таким:
[MarkdownCheck]
filename_re=.*.(blog|markdown|md(own)?|mkdn?)$

Установка

Форк с моим кодом лежит на Github. Pull-request я отправил. Пока же можно вручную подложить файл плагина markdowncheck.py в нужное место: .../site-packages/linkcheck/plugins

Настройка Vim

Для настройки Vim необходимо задать две переменные: makeprg - команда, которая будет вызываться по :make errorformat - фильтр, с помощью которого будут из вывода команды выбираться строки с ошибками
Для обработки файла я использую такую команду: linkchecker -v --check-extern -f ~\/work/blogger/lrc -o csv file_name Аргумент --check-extern говорит, что надо проверять не только правильность ссылок, но и их валидность. С помощью -o csv задаётся формат вывода в виде csv-файла, содержащего по одной строке на каждую ссылку. Таким образом, настройки Vim будут следующими:
set makeprg=linkchecker\ -v\ --check-extern\ -f\ ~\/work\/blogger\/lrc\ -o\ csv\ '%'
set errorformat=%-G#%.%#,
                \%-Gurlname;parentname;%.%#,
                \%-G%.%#;True;%.%#,
                \%-G%.%#URLs\ checked%.%#,
                \%.%#;file://%f;;%m;;%.%#;False;%.%#;%l;%c;%.%#;%.%#;%.%#;%.%#;%.%#;%.%#;
Из вывода команды мы отбрасываем все строки, кроме содержащих информацию об ошибочных ссылках (с помощью первых четырёх элементов errorformat). Мила ЙововичПятый элемент errorformat обрабатывает все строки, в которых в седьмом столбце стоит False, т.ё. строки с информацией об ошибке. Назначение некоторых элементов errorformat:
  • %-G - пропустить строку, удовлетворяющую заданному шаблону
  • %f - имя файла
  • %m - текст сообщения об ошибке
  • %l - номер строки
  • %c - номер столбца
  • %.%# - транслируется в регэксп .*

С такими настройками, выполнив команду :make и открыв quickfix-окно, получим следующее:

Теперь можно использовать всю мощь режима quickfix, например, перемещаться по ошибочным ссылкам с помощью :cn.
Приятного блоггинга с помощью лучшего в мире редактора!