Показаны сообщения с ярлыком интернет. Показать все сообщения
Показаны сообщения с ярлыком интернет. Показать все сообщения

20101012

Безболезненный upload с помощью Wondershaper

Наверное, многие замечали, особенно на домашнем интернете, что во время интенсивной закачивания данных в сеть (во время upload), соединение начинает «тормозить». Страницы сайтов подолгу не открываются, скачивание и медиапотоки подвисают на месте... Это легко измерить: у меня дома, например, пинг до гугла вырастает с 50 мс до порядка 1000 мс, при этом около 8% пакетов вообще теряются.

Причина этого явления (чаще всего) — загрузка в сеть занимает весь доступный исходящий канал, а соединения по протоколу TCP/IP требуют двухсторонней связи. Даже если мы пытаемся что-то просто скачать, машина должна посылать обратно пакеты подтверждения приёма (т.н. ACK). Если же исходящий канал весь занят, то и пакеты подтверждения, какими бы маленькими они не были, надолго задерживаются, и, соответственно, перестают приходить и входящие пакеты, даже если ширина входящего канала достаточна.

Решить эту проблему можно с помощью скрипта wondershaper (есть в составе большинства дистрибутивов). Он позволяет установить ограничения на скорость загрузки из сети и в сеть. Хитрость в том, чтобы вначале узнать свою реальную скорость соединения, а потом установить ограничения чуть-чуть ниже реальной доступной скорости. В этом случае будет всегда оставаться «запас» для своевременной передачи служебных пакетов, и задержки станут гораздо меньше.

Например, я хочу выложить кучу фотографий на яндекс-фотки. Иду на internet.yandex.ru и измеряю скорость соединения с Яндексом, сегодня вечером у меня получилось так:

Вниз: 4044 Кбит/с. Вверх: 490 Кбит/с.

Можно пойти на testspeed.net или другую измерительную страничку. Можно измерить вручную. Главное, получить реальные значения скорости в килобитах в секунду.

После этого надо включить wondershaper на используемом сетевом интерфейсе и указать ему значения немного меньше измеренных. Сетевой интерфейс — это обычно wlan0 в случае соединения по WiFi, или eth0 в случае соединения по локальной сети. Чтобы уточнить, можно выполнить команду route -n в терминале, имя используемого интерфейса искать в строке с флагами UG.

$ sudo wondershaper wlan0 3900 450


Готово. Запускаем загрузку в сеть (выкладываем фото, видео, раздаём торренты, и т.д.), измеряем время пинга. Чудесным образом, даже во время загрузки, пинг у меня упал до 61 мс, что не сильно больше его минимального значения при свободном канале, а веб-страницы стали скачиваться вполне шустро. Если не помогло с первого раза, можно попробовать ограничить скорость закачивания в сеть ещё сильнее.

Чтобы отключить wondershaper, выполнить:

$ sudo wondershaper clear интерфейс

20100114

Кнопки твиттера, жуйки, я.ру и ЖЖ для Blogger

Приятно, когда на тебя ссылаются, поэтому любой заядлый блоггер любит всякие кнопки вроде «retweet» и «в делишез». «Retweet» особенно: в микроблогах ссылаются охотнее. Однако кроме твиттера, у нас есть ещё и ЖЖ, и Я.ру, и juick. А вот каким-нибудь stumbleupon никто не пользуется.

Никакие готовые кнопки мне не понравились: 1) большинство из них неправильно работает, если заметка находится на главной странице, 2) они почти все требуют установки чужих скриптов, часто тормозных 3) многие кнопки игнорируют популярные в России (и среди моих читателей) ЖЖ, Я.ру и juick. Вот и пришлось сделать самому.

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

Что получилось

Первая версия выглядит примерно так (это просто картинка, не кликать! — настоящие кнопки внизу заметки):

Кнопки подписал по-русски. Для надёжности расшифровал. Проверил, точно работают «пожужжать |жж», «двумЯ.РУками |я.ру» и «расчирикать |twi». Кнопка для жуйки по идее должна работать, только я её проверить не смог, потому что у меня обработчик XMPP URI не настроен. Пожалуйста, проверьте, кто пользуется, отпишитесь и скажите, как надо поправить, если что.

Как установить себе

В шаблоне блога «раскрыть виджеты», найти подходящее место (например, я выбрал post-footer-line-2) и добавить туда такой код:

<div class="sharemebuttons">
<a class="shareme" expr:href='"http://www.livejournal.com/update.bml?subject=Ссылка: "
+ data:post.title + "&amp;event=" + data:post.title + ": "
+ data:post.url'>пожужжать |жж</a>

<a class="shareme" expr:href='"http://my.ya.ru/posts_add_link.xml?title="
+ data:post.title + "&amp;URL=" + data:post.url'>двумЯ.РУками |я.ру</a>

<a class="shareme" expr:href='"xmpp:juick@juick.com?message;body="
+ data:post.title + " " + data:post.url'>перетереть |juick</a>

<a class="shareme" expr:href='"http://www.google.com/reader/link?url="
+ data:post.url + "&amp;title=" + data:post.title + "&amp;srcURL="
+ data:blog.homePageUrl + "&amp;srcTitle=" + data:title'>побузить |buzz</a>

<a class="shareme" expr:href='"http://twitter.com/home?status="
+ data:post.url + " " + data:post.title'>расчирикать |twi</a>
</div>

Для ЖЖ бы хорошо в event помещать уже HTML-код, но у меня пока не получилось.

Надо, наверное, добавить красивые графические иконки (не знаю, дойдут ли руки, но собственноручно нарисованный чижик для твиттера у меня уже есть; нет ничего для жуйки и жж). Пока довольствуюсь вот таким фрагментом CSS (тоже черновой вариант, вставлять в таблицу стилей в верху шаблона):
div.sharemebuttons {
margin-top: 1em;
margin-bottom: 1em;
}
a.shareme, a.shareme:visited {
text-decoration: none;
padding: 3px 8px;
margin: 0em 8px 0em 0px;
background-color: #94cc32;
color: white;
}
a.shareme:hover {
background-color: #aced3a;
color: white;
}

Всякие улучшения приветствуются. Ну и ссылки, конечно :-)

Доп. 1: добавил кнопку для «Я.ру».

Доп. 2: исправление для кнопки «Я.ру» — чтобы при нажатии на кнопку незалогинненному пользователю вначале предлагалось войти в «Я.ру», добавить в шаблон блога такой Javascript-код (например, перед </head>):
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("a.shareme[href^='http://my.ya.ru']").attr("href", function() {
return "http://passport.yandex.ru/passport?mode=auth&amp;retpath=" + escape(this.href);
});
});
</script>
Без этого скрипта кнопка тоже работает, но только для залогинненых пользователей «Я.ру».

Доп. 3: добавил кнопку для Google Buzz (через Reader).

20091124

Скрипт для создания статического значка Flickr

Делюсь маленьким и несовершенным скриптом, который, надеюсь, кому-то всё же окажется полезен. Скрипт генерирует картинку-бейджик с последними фотками на Flickr. Зачем он нужен? Официальные виджеты Flickr основаны на Javascript и на флэше, их не везде можно вставлять. А статическую картинку можно куда угодно вставлять, хоть в ЖЖ, хоть на форумах...

В общем, скрипт состоит, на самом деле, из двух. Первый, вспомогательный, на питоне, flickrlatest.py находит и печатает ссылки на миниатюры N последних фоток заданного пользователя. Для работы нужно иметь ключ API, который скрипт считывает из файла ~/.flickr.apikey.

Второй скрипт, основной, обычный скрипт на bash, скачивает нужные картинки и объединяет их Graphics Magick-ом (при желании легко заменить на Image Magick, но, как я недавно узнал, GM быстрее, используется и на самом фликере, так что решил переходить потихоньку на GM).

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

mkflickrbadge.sh пользователь геометрия файл-куда-сохранить.png


Несколько примеров.

$ mkflickrbadge.sh arboreus 3x2 arboreus-3x2.png


Flickr badge 3×2


$ mkflickrbadge.sh dobrych 5x1 dobrych-5x1.png


Flickr badge 5×1


Можно использовать NSID вместо имени пользователя:

$ mkflickrbadge.sh 7333287@N07 2x2 marjina-2x2.png


Flickr badge 2×2


Надеюсь, идея понятна. Скачать скрипты можно c битбакета (архив.zip). Распаковать, сделать скрипты исполняемыми, положить где-нибудь в PATH. Как добавить в crontab — умолчу.

P.S. Отмечу в качестве альтернативы скрипту — вебсервис http://www.flickriver.com/badge/create.

20090828

Скорое обновление RuNIX.org

Наконец собрался и подготовил обновление планеты русских блогов о *NIX RuNIX.org. Дело в том, что скрипт Planet Planet, на котором аггрегатор работает сейчас уже давно не обновляется, а на смену ему пришёл Planet Venus. Вот на него и переходим.

Грядущие изменения, большие и маленькие:
  • Другой, на мой вкус более аккуратный и человечный, шаблон.
  • Список блогов теперь можно сворачивать (будет такой маааленький треугольник в заголовке списка). По наведению на название блога из списка, открывается меню недавних из этого блога.
  • Появилась возможность навигации с клавиатуры (для тех, кто читает планету на сайте). Переход между записями по клавишам j и k можно включить в боковой врезке.
  • Если в фиде определена картинка пользователя (Channel image или Icon), планета может её использовать. RSS 2.0 из ЖЖ, например, такие картинки отдаёт (соответственно, у некоторых авторов автоматически появятся портреты). Естественно, присылать нам свои фотки 64×64 по-прежнему можно.
  • После перехода на Planet Venus, мы теперь можем пропускать заметки с будущими датами и изменения atom:updated (Помните, когда порой вдруг валились кучей старые посты какого-нибудь блога, как правило на blogspot? Вот чтобы так не было, и нужно). Должно стать лучше.
  • Шаблон теперь на XSLT, поэтому появилась определённая свобода в обработке записей (я в XSLT не силён, но думаю, справимся). Можно будет что-то исправлять или фильтровать. Дополнительно теперь есть возможность подключать фильтры-плагины.
На сайт runix.org изменения попадут после того, как GQ установит на сервере новый скрипт. Посмотреть одним глазком на новую планету уже можно здесь — для сравнения сохранил как было.

Кто не заметил ссылку — новая планет будет выглядеть так.

Приветствуются замечания по делу (если по вёрстске — лучше сразу патч к CSS, если считаете, что что-то нужно фильтровать-менять — поделюсь XSLT, обсудим). Если что-то из ряда вон и лучше ничего не трогать — кричите!

Есть некоторые задумки (не факт, что скоро сделаю):
  • добавить какой-нибудь ticket-tracker, чтобы заявки и жалобы быстрее собирать и все могли их видеть и комментировать;
  • сделать javascript-овый флажок «пожаловаться» рядом с каждой записью, чтобы вовремя замечать неподходящий или неинтересный материал (я не всегда успеваю такой заметить, а написать письмо читателям обычно более лениво, чем ткнуть в кнопку);
Помощь и пожелания принимаются.

P.S. Да, забыл предупредить. Допускаю, что при обновлении скрипта некоторые записи пройдут повторно. Прошу извинить за неудобство.

20090421

Редактирование HTML и XML в Vim

Пару слов о редактировании HTML и XML файлов в Vim. О выделении HTML-тэгов я уже писал. Мне в конфигурации Vim по умолчанию не хватает
  • работающего % для перехода между парными тэгами (как обычно он переходит между парными скобками),
  • автоматического добавления закрывающих тэгов,
  • быстрого окружения тэгом выделенного фрагмента.
  • быстрого удаления окружающего тэга.
  • кодирования и раскодирования HTML Entities («>» как «&gt;» и обратно)
Почти всё это сразу есть в плагине xml.vim. Кроме HTML Entites, настроить кодирование которых тоже можно.

Установка и настройка

Cкачать файл xml.vim, сохранить в ~/.vim/ftplugin/xml.vim, сделать на него символическую ссылку с ~/.vim/ftplugin/html.vim. В ~/.vimrc включить загрузку плагинов по типам файлов:
filetype plugin on
Теперь при открытии XML и HTML файлов будет включаться этот плагин.

Для кодирования HTML Entities поместить в ~/.vim/plugin/ файл htmlesc.vim.

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

Переход между парными тэгами. Чтобы перемещаться между тэгами, поместить курсор внутрь тэга (например, на </div>), нажать %, курсор переместится к парному тэгу (т.е. к <div>).

Вставка закрывающих тэгов происходит автоматически при нажатии >. Таким образом, набрав <div> мы получим:
<div></div>
При желании, можно переназначить комбинацию для автодополнения тэга. Для этого в ~/.vimrc до загрузки плагина определяем переменную xml_tag_completion_map. Например, так:
let xml_tag_completion_map = ">>"
— в этом случае закрывающий тэг появится только при повторном нажатии на >.

Окружение фрагмента тэгом тоже сразу работает. Достаточно выделить фрагмент и нажать \x. Программа спросит каким тэгом окружить и аккуратно вставит и открывающий, и закрывающий тэги.

Удаление тэга — обратная операция. Нажимаем \d и ближайший окружающий тэг будет убран, но весь текст внутри тэга останется нетронутым.

В последних двух командах можно вместо \ назначить любую другую клавишу. Почитать документацию по плагину: :help xml-plugin.txt.

Кодирование и раскодирование HTML Entities. Для этого, напомню, мы используем скрипт ~/.vim/plugin/htmlesc.vim. Ctrl+h превращает нормальный текст в HTML («>» в «&gt;»), а Ctrl+u — обратно. Работает построчно.

Другие способы

Есть плагин closetag.vim. Он просто добавляет команду, закрывающую тэги, команда привязывается к сочетанию клавиш и вызывается вручную. Использовать просто: Ctrl+_ — закрыть текущий тэг, это удобно, когда его текст тэга уже написан. Этот плагин я тоже использую.

Есть отдельный скрипт, позволяющий окружать фрагменты текста тэгом. Примерно то же самое, что и \x в xml.vim.

По теме

Выделение HTML-тегов, строк и блоков кода в Vim
Как быстро закомментировать/раскомментировать блок кода в Vim

20090413

Функциональное веб-программирование

Многие читали Beating the Averages Пола Грэхэма (есть перевод). Он использовал Lisp, и считает, что именно поэтому создал самое удачное веб-приложение (которое потом превратилось в Yahoo! Store). Прекрасно!

А вот что реально уже готово и можно использовать прямо сейчас? Я решил не зацикливаться на Хаскеле, и вспомнил, что есть ещё Erlang, Caml, Scala, Scheme, Lisp. Стоило только начать поиски, и я нашёл много интересного. Делюсь находками.

1. Язык программирования Erlang и каркас для разработки веб-приложений Nitrogen. Кстати, сайт Nitrogen на нём же, видимо, и работает. Рекомендую посмотреть видео:

Видео: возможности Nitrogen (дек. 2008) (.mov)

скринкаст: Новые возможности Nitrogen (дек. 2008)


Обратите внимание на счётчик числа строк, нужных, чтобы запрограммировать страницу (такой счётчик есть и на всех страницах сайта Nitrogen). Число, как правило, двузначное. Меня лично поразило вот это — запуск долгоиграющих процессов на сервере. 31 строчка! Чтобы сделать подобное на Python и Django, мне пришлось попыхтеть.

Кроме Nitrogen, для Erlang есть ещё Erlyweb и Erlang Web.

2. Язык программирования Haskell и сервер приложений Happstack. Самое приятное, что проект хоть ещё и молодой, но уже работающий. На нём сделан Happstack-tutorial, на нём работает Patch-tag.com. Первые энтузиасты даже делают на нём свои блоги.

Запустить его на своей машине оказалось не очень трудно. И он работает. Но всё же, я чувствую, мне потребуется время, чтобы с ним более-менее разобраться. Документация, с точки зрения новичка, конечно, уступает документации Django.

Основная отличительная черта Happstack: реляционная база данных ему не нужна. Можно пользоваться теми структурами данных, которые наиболее удобны. Возможность с одной стороны спорная, полагаться на неё страшно, с другой — весьма интересная.

Вот маленькая презентация Happstack:

Но и не Happstack единым. Читаем Is Haskell a Good Choice for Web Applications?. Весьма обнадёживает. Исходник работающего сайта — в подарок.

3. Язык программирования Scala (гибридный функциональный язык программирований для виртуальной машины Java) и каркас для веб-приложений Lift. Можно посмотреть на его демо.

Интересно, что буквально на днях Гугл объявил поддержку Java на AppEgnine, и народные умельцы уже используют там Scala. Более того, точно так же на AppEngine запустили и Lift.
Scala — по-итальянски лестница. Думаю, игра слов scala — lift теперь всем понятна.


4. Язык программирования Caml и каркас для веб-приложений Ocsigen. Точнее, как я понял, Ocsigen — это веб-сервер, а каркас для веб-приложений называется Eliom. И есть ещё набор библиотек Ocsimore. Однако это детали.

Интересные особенности Ocsigen: валидность XHTML документа гарантируется на уровне типов языка, активно используется стиль отложенных вычислений, управление сессиями, URL-схемами и параметрами страниц автоматическое.

В репозитариях основных дистрибутивов Ocsigen уже есть, так что приступить к использованию будет легко. Вот, например, вики-органайзер написанный с использованием Ocsigen. Разработчики тоже не стесняются использовать детище для своих сайтов. Добрый знак. Работает, говорят, очень быстро. Однако будем помнить, что это прежде всего исследовательский проект.

Читая сайт Ocsigen, нашёл и совершенно удивительный проект. Немного не в тему, но очень здорово: O'Browser, написанная на Javascript виртуальная машина для байт-кода OCaml. Что это значит? Значит, что код на OCaml можно встраивать в веб-страницы! Вот, например, клон Boulderdash. Что-то подобное есть и для Haskell.


5. Язык программирования Scheme и каркас для веб-приложений LeftParen. Документация выглядит толково. К сожалению, не нашёл сайтов, которые его используют. Или какого-нибудь демонстрационного сайта.

Вообще-то LeftParen построен вокруг уже довольно развитой инфраструктуры для веб-программирования в PLT Scheme. И её вполне можно использовать непосредственно, см. документацию и учебник.

Для Scheme есть ещё Icing.

6. Язык программирования Lisp и веб-каркас Weblocks. Сайт и документация очень мне понравились. Если бы я писал на Лиспе, начал бы, наверное, с этого каркаса. Вот демонстрация.

Есть ещё KPAX (это не русское слово, просто такое смешное сокращение!). Пишут, что уже давно и серьёзно используется, но документация страдает. Для Лиспа есть ещё UnCommon Web, BKNR.

7. Ещё один диалект Лиспа — язык программирования Clojure, как и Scala рассчитан на использование на платформе JVM. Надо ли говорить, что и для него есть веб-каркас: Compojure. И на AppEngine его тоже оперативно запустили.



Вот так-то. Сколько всего, оказывается. Глаза разбегаются.

Созвучен этой заметке будет вот этот пост.

20090319

Как вставить формулу LaTeX в блоге или на форуме

Я уже как-то писал о том, как сделать картинку из формулы. Однако есть ещё более простые способы вставить формулу на веб-страницу.

1-й способ. Javascript-библиотека jsTeXrender (yourequations.com). GPLv3, кстати. Исходный код здесь (в том числе, серверной части).

Где-нибудь на странице подгружаем скрипт. Например, вставляем такой код перед </body>:
<script type="text/javascript" src="http://tex.yourequations.com/"></script>
А все формулы LaTeX пишем внутри тегов <pre lang="eq.latex"/> и <code lang="eq.latex">:
<pre lang="eq.latex">
\!i\hbar\frac{\partial}{\partial t}\psi=-\frac{\hbar^2}{2m}\nabla^2\psi+V\psi
</pre>
И получаем:

\!i\hbar\frac{\partial}{\partial t}\psi=-\frac{\hbar^2}{2m}\nabla^2\psi+V\psi
Плюсы: легко использовать, библиотечку можно разместить у себя. Формулы остаются читаемы даже при выключенном скрипте. При добавлении новых формул ничего настраивать не надо.

2-й способ. Javascript библиотека jsMath. В отличие от описанного в предыдущем способе jsTeXrender, jsMath не требует настроенного сервера для работы, а рисует формулы сама.

Для использования, нужно подгрузить библиотеку:
<script src="путь/к/библиотеке/easy/load.js"></script>
а формулы, по умолчанию можно писать прямо как в LaTeX:
\[
\!i\hbar\frac{\partial}{\partial t}\psi=-\frac{\hbar^2}{2m}\nabla^2\psi+V\psi
\]
jsMath находит их сама и перерисовывает как надо. При желании, маркеры начала и конца формулы можно настроить.

Рисует формулы jsMath хорошо. Достаточно сказать, что именно jsMath используется в стандартном интерфейсе блокнота Sage. Дополнительные примеры можно посмотреть на сайте jsMath.

Плюсы: простота использования и установки, только Javascript, без серверной части. Минусы: для качественного отображения предлагает пользователю установку специальных шрифтов, Javascript более тяжеловесный и медленный.

3-й способ. Идём на страничу Texify.com. Вводим туда свою формулу и получаем код для вставки на страницу.

texify example

Можно вставлять формулы и не заходя на сайт, URL картинок формируется так: http://www.texify.com/img/формула-LaTeX.gif. Очень удобно, если формулу надо поправить.

Дополнение. Выданный на texify.com адрес картинки с некоторых пор не работает за пределами сайта texify.com, так что картинку придётся сохранить, куда-то выложить и только после этого вставить, куда надо. Всё это лишает Texify.com смысла.

Аналогичный сервис доступен на mathURL.com. Как и tinyurl.com, он генерирует короткие адреса для картинок с формулами. Вот результат

формула нарисованная mathurl.com

Плюсы: минимум усилий для вставки одной-двух формул. Не зависит от скрипта (можно использовать, например, в ЖЖ или на форумах). Минусы: зависимость от внешнего веб-сервиса.

4-й способ. Похож на первые два, только картинку создаёт CGI-программка mimetex. Программка написана на Си, и TeX-а для своей работы не требует. Формула вставляется так:
<img src="http://ваш.сервер/cgi-bin/mimetex.cgi?формула-LaTeX" alt="формула-LaTeX">
а выглядит так:

mimetex example

Плюсы: легко организовать почти на любом сервере, где разрешены CGI-скрипты, не требует на нём установки LaTeX. Никакой зависимости от сторонних веб-сервисов. Минус: нужен свой сервер.

Вариант этого способа — CGI-программка mathtex. В отличие от mimetex, она использует настоящий LaTeX, установленный на сервере, и dvipng, чтобы создавать картинки. В остальном аналогична.

5-й способ. Есть настоящий pastebin для физиков и математиков. mathbin.net. Там можно постить фрагменты текста, и прямо там обсуждать, как на форуме. Это, однако, немного другой жанр.

5-й способ. Недавно возможность отрисовывать формулу LaTeX в виде картинки появилась в Google Charts. Ссылка на картинку формируется так: http://chart.apis.google.com/chart?cht=tx&chl=формула LaTeX. Например:

Google Charts example

(ссылка на картинку: http://chart.apis.google.com/chart?cht=tx&chl=\huge\!i\hbar\frac{\partial}{\partial%20t}\psi=-\frac{\hbar^2}{2m}\nabla^2\psi+V\psi).

6-й способ. Описан в этом блоге. Опять с подключением внешних скриптов, в этот раз предоставленных сайтом watchmath.com, которые, в свою очередь, обращаются к сервису mathcache.appspot.com. Отрисовкой формул занимается экземпляр mathTeX (см. выше), запущенный кем-то на инфраструктуре Amazon. Скрипты же позволяют вставлять формулы как в LaTeX, просто $формула$ или \[ формула \]. Подключаются скрипты так:
<script type="text/javascript"
src="http://mathcache.s3.amazonaws.com/replacemath.js"></script>
<script type="text/javascript">
replaceMath( document.body );
</script>
Пример отрисовки:
пример mathcache.appspot.com
По стилю использования получается похоже на jsMath. Примечание: при использовании этого скрипта все знаки «доллара» на сайте придётся защищать тегом <code>.

Ещё кое-какие способы перечислены здесь.

20090224

epi2fox: конвертация закладок Epiphany в Firefox 3

Я давно уже использовал Эпифанию (Epiphany) в качестве основного браузера, в основном потому, что её система закладок с тагами мне кажется наиболее удобной. Однако поскольку в FF3 закладки тоже можно метить тагами, то я решил опять попробовать Firefox в качестве основного браузера. Оставалось только перенести свои закладки из Epiphany в Firefox.

Поскольку ничего готового не нашлось, то написал скрипт epi2fox.py. Предполагая, что профиль Firefox практически пуст, использовать так:
$ epi2fox.py ~/.mozilla/firefox/вашпрофиль/places.sqlite
Скрипт не идеален, в частности, есть проблема дублирующихся закладок. Epiphany такие закладки разрешает (несколько разных закладок на один и тот же URL), а FF — нет. Сейчас дубли просто игнорируются, хотя, наверное, правильнее было бы их объединять.

Как бы то ни было, с моей задачей скрипт справился удовлетворительно. Может и кому-нибудь ещё пригодится.

Ссылки:
epi2fox, репозиторий скрипта
схема базы данных закладок в FF3 (PDF)
epi2fox: import Epiphany bookmarks into Firefox 3 (это объявление по-английски)

Для облегчения поиска закладок по тагам, может ещё пригодится расширение TagSifter. С ним гораздо лучше, чем без него.

PS. Да, конечно, перед использованием лучше сделать резервную копию places.sqlite, если там что-то уже есть.

20090128

Скрипт rss2xmpp, кросспост чего угодно в Jabber

В общем, скрипт лежит на BitBucket: rss2xmpp.py.

Использование:
$ rss2xmpp.py адрес-фида джаббер-ID-адресата
Фид можно почти любой: и RSS, и Atom. Записи пересылаются отдельными сообщениями в прямом хронологическом порядке, история отосланных сохраняется. При первом запуске скрипт создаст файл~/.rss2xmpp, куда нужно внести настройки учётной записи Jabber для отправки сообщений. По умолчанию в этот файл вписываются настройки для GoogleTalk.

Для работы скрипты нужны: FeedParser, html2text, и xmpppy, и, конечно, Python. Забавное наблюдение: все зависимости оказались пакетированы во FreeBSD, все, кроме python-html2text в Debian unstable, а в убунте только python-feedparser.

Ещё одно постороннее замечание. BitBucket, как хостинг для Mercurial, мне понравился: сразу дают доступ по SSH (т.е. можно положить ключи и пользоваться без пароля), есть простой Issue-tracker и вики (отключаемы), а вдобавок разрешают и один бесплатный частный (закрытый) репозиторий. Зато freeHg полностью некоммерческий и минималистичный.

rss2xmpp, a script to crosspost any feed to Jabber (этот пост по-английски)

20080903

Простая CMS для AppEngine

Я далёк от серьёзной веб-разработки. Однако довольно регулярно мне приходится делать или браться поддерживать/изменять разные небольшие сайты (до 10–20 страниц). Надо сказать, что готовые решения в этой весовой категории меня ни разу не удовлетворяли.

  • Полноценные CMS всегда оказывались слишком тяжёлые (слишком универсальные) и навязывали слишком сложную (ИМХО) модель и структуру сайта. Их код слишком большой, чтобы можно было что-то быстро под себя переделать. В общем, в программировании я не любитель «отсекать лишнее».
  • Комбинирование языков облёгчённой разметки (Markdown, reST), щепотки PHP и готовых систем шаблонов (вроде Smarty) решало задачу, но требовало решать её каждый раз заново («лепить»).
  • Собственный набор макросов m4 для генерации сайтов был не очень удачен (но «велосипед был вновь изобретён»).
  • Попытки использовать Google Pages или облегчённые вики в качестве движка оставили смешанное чувство (здесь нужно долго и нудно «замазывать»).

В общем, на каникулах развлёк себя знакомством с Google AppEngine (который предоставляет бесплатный и масштабируемых хостинг для веб-приложений), а заодно, в свете того, что нужно сделать очередной мини-сайт, решил сделать для AppEngine простую мини-CMS. Требования у меня к ней были такие:

  • Максимально простая модель сайта: «плоский» сайт из нескольких страниц с автоматически генерируемым «меню».
  • Человек далёкий от веб-разработки должен иметь возможность легко изменять содержимое сайта. Легко — это значит не только «не зная HTML», но и «без страха перед навороченной админкой», и «не зная английского».
  • Должна быть возможность использовать облегчённые языков разметки (Markdown, reST), которые мне кажутся более предпочтительными, чем WYSIWYG-редакторы.
  • Код должен быть достаточно коротким и простым, чтобы понять и изменить его было легко.
  • Доступность бесплатного безрекламного хостинга для динамического сайта:)
В результате пары дней приятных усилий получилось вот что. Дабы подчеркнуть простоту кода (в данный момент это всего 5 кБ), я эту мини-систему управления сайтом нарёк Hello Web. Кое-что ещё надо доработать, но, в целом, уже вполне функциональная вещь. Сам сайт HelloWeb на ней же и работает.

Надеюсь, кому-то кроме меня эта мини-CMS окажется полезна. Лицензия — преданная гуглоанафеме, но свободная и мне симпатичная GNU Affero GPL. Собственно, узнал об этой политике Гугла по отношению к Affero GPL как раз попытавшись завести проект на Google Code. «Ну не хотят, так не хотят,» — решил я, — репозиторий исходного кода был размещён на freeHg.org.

В общем, исправления и дополнения кода приветствуются.

20080830

Как сохранить видео-поток ASF в файл

Как сохранять видеоролики со всяких там ютубов все уже давно знают (см. clive). На некоторых же сайтах (к примеру, на vesti.ru) видео лежит в виде ASF-потоков. Если не плеваться на некошерность таких видео-потоков, то их вполне можно смотреть после установки плагина totem-mozilla, затем только нужно один раз, с помощью контекстного меню плагина, открыть видео непосредственно в видеопроигрывателе и согласиться на установку нужных кодеков. После этого все такие ролики будут показываться прямо в браузере.

Теперь о том, как сохранять эти ролики в файл. Опять же, используя контекстное меню плагина, копируем адрес потока, а затем перекодируем поток уже в нормальный видео-файл с помощью mencoder. В общем, вот мой мини-скрипт vstream2avi:

#!/bin/sh

usage="usage: `basename $0` video_stream_URL video_file"

if  [ $# -ne 2 ]; then
        echo $usage
        exit -1
fi

STREAM=$1
VFILE=$2
BITRATE=4000

mencoder "$STREAM" \
        -oac mp3lame -lameopts vbr=3 \
        -ovc xvid -xvidencopts chroma_opt:vhq=3:pass=2:bitrate=${BITRATE}:autoaspect \
        -o "$VFILE"


И пример использования:
$ vstream2avi.sh mms://video.rfn.ru/rtr-vesti/147104.asf Putin_interview_CNN_20080827.avi

20080226

Как записать интернет-радиостанцию в файл

Я время от времени пользуюсь пакетом streamripper, чтобы сохранять вещание интернет-радиостанций в файл. Обычно я использую его примерно так:
$ streamripper http://адрес-mp3-потока-радиостанции -a radio.mp3 -M 50 -t
— сохранить всё в один файл radio.mp3 («-a radio.mp3», без этой опции каждый трек должен писаться в отдельный файл, но увы не все интернет-радиостанции разделяют треки и далеко не все вещают id3-тэги), писать максимум 50 мегабайт («-M 50»), а при разрыве соединения временные файлы не перезаписывать («-t») (предыдущие фрагменты тогда остаются в Название-станции/incomplete/).

Записываемый файл можно прямо на лету слушать mplayerом.

Применений этому множество:
  • можно сохранять радиопередачи по расписанию (crontab),
  • можно пропускать рекламу (благо, её длительность обычно фиксированна) и затянувшийся трёп,
  • можно повторно прослушать название понравившейся песни,
  • можно повторно прослушать саму песню,
  • можно пропускать неприятные песни,
  • можно спокойно поставить радио «на паузу»…
А вот и список разных российских радиостанций, доступных онлайн.

Дополнение: для streamripper есть несколько графических интерфейсов. Пользователи GNU/Linux могут воспользоваться StreamTuner, Tunapie или KRadioRipper. Вот так выглядит StreamTuner:

20080218

Кросспост RSS в ЖЖ (bash-скрипт)

Обновление: Более совершенный скрипт для кросспоста был написан мной на Haskell. Подробности здесь.


Захотелось мне наладить автоматическую публикацию ссылок на мои записи в ЖЖ…

Сразу же нашёл сервис rss2lj. Он, однако, в настоящий момент не работает. После этого стал искать, как сделать то же самое своими силами.

Нашёл, что есть два механизма автоматической публикации в ЖЖ. Первый — с использованием XMLRPC. Как это делается на PHP желющие могут увидеть в исходниках плагина к вордпресс lj_crosspost. Второй способ — использовать возможность emailpost в ЖЖ. В этом случае письма, отправленные на адрес вида пользователь@post.livejournal.com будут публиковаться как посты.

Я выбрал второй вариант, потому что письма можно слать из любого скрипта одной командой, а возиться с авторизацией через XMLRPC не хотелось. Правда, функция emailpost в ЖЖ не бесплатна, платить за неё надо либо чистым золотом, либо рекламой. Остановился на рекламе, включив в ЖЖ «улучшенный рекламой эккаунт» :)

После этого оставалось написать скрипт, который бы брал RSS и делал из него много писем. В действительности, такой скрипт уже есть. Можете взглянуть на rss2email, лежащий в репозиториях Debian. Впрочем, он скорее предназначен для чтения RSS через email, а я хотел лишь вытаскивать из RSS ссылки.

Вытащить нужные поля из RSS можно и xmlstarlet-ом:
curl -g http://feeds.feedburner.com/sovety?alt=rss -s | \
xmlstarlet sel -t -m "/rss/channel/item" \
-v "guid" -n -v "pubDate" -n \
-v "title" -n -v "link" -n
Оставалось только атоматически формировать из этих полей текст письма (awk-ом), отсылать всё это в ЖЖ (mutt-ом) и отмечать на память уже отосланные записи (чтобы не слать повторно). Получился вот такой скрипт.

Теперь анонсы моих постов можно прочитать и в ЖЖ: jetxee.livejournal.com.

Что не работает: ЖЖ приходит в ступор, получая письма, в Subject которых UTF-8. По идее Subject должен становиться заголовком поста, но выходит ерунда. ЖЖ должен особым образом обрабатывать в письме строки вида lj-tags: blabla, давая записям тэги, но у меня это тоже почему-то не срабатывает.

20071123

Синхронизация каталогов по SSH и по FTP

Бывает полезно синхронизовать (зеркалировать) каталоги на локальной и удалённой машинах. Например, изменившийся сайт на хостинг выложить или копию чего-то изменяющегося себе скачать...

Пусть есть два каталога: на локальной машине и на удалённой. Предполагаем, что изменения происходит только в одном месте (для объединения параллельных изменений нужно использовать средства управления версиями вроде subversion, а не средства синхронизации). Нужно перенести все произошедшие изменения в другой из них. Это и есть задача синхронизации.

Обычно синхронизация двух каталогов делается с помощью Rsync и SSH.

Пусть изменяется удалённый каталог, копируем его на локальную машину так:
$ rsync -avz --delete -e ssh логин@удалённый.хост:путь/откуда/ путь/куда

Если же «отражаем» локальный каталог на удалённую машину (выкладываем изменённый сайт на хостинг), то
$ rsync -avz --delete -e ssh путь/откуда/ логин@удалённый.хост:путь/куда

Полезно поиграться с командой добавляя и убирая слэш («/») после названия исходного каталога, чтобы понять, что он делает (или почитать man rsync). Потренироваться, кстати, можно и с двумя локальными каталогами.

Если удалять файлы, исчезнувшие в исходном каталоге, но присутствующие в целевом, не нужно — ключ --delete убрать.

Всё это хорошо, да вот только доступ по SSH есть далеко не всегда (например, если хостинг дешёвый...). Иногда требуется синхронизировать каталоги по FTP. Это умеет программка lftp. О том, как пользоваться lftp, уже писали. Поэтому напишу кратко по теме, а остальное — см. man lftp.

Вытянуть каталог с удалённого сервера (синхронизировать локальный каталог с удалённым):
$ lftp -e 'mirror -e каталог-на-сервере локальный-каталог; bye;' -u логин,пароль удалённый.хост

И наоборот, выложить локальный каталог на удалённый сервер:
$ lftp -e 'mirror -R локальный-каталог каталог-на-сервере; bye;' -u логин,пароль удалённый.хост


Это, конечно, можно делать и используя lftp в интерактивном режиме. Если команде mirror параметры не давать, то синхронизуются текущий удалённый и текущий локальный каталог.

Конечно, если задачи синхронизации не стоит, а нужно просто выложить или скачать каталог со всеми подкаталогами, то тогда задачу можно решить проще, scp -r или рекурсивный put, имеющийся во многих других FTP-клиентах, для этого будут достаточны.

Смотрите также:

Резервное копирование и шифрование архивов с помощью cpio (или tar) и gpg

20071114

RuNIX.org — планета русских блогов о BSD, GNU/Linux и свободном ПО. Вторая итерация

Идея создания единой ленты русских блогов о *nix нашла поддержку. Сейчас на http://feeds.feedburner.com/ru_nix_blogs подписано уже почти 80 человек.

Более того, Alexander GQ Gerasiov предоставил сервер для размещения полноценной планеты и доменное имя, RuNIX.org, так что планета с моего Google Reader-а переезжает туда, а создаваться единая лента будет силами скрипта planetplanet.

Теперь в сообщениях планеты будет видно имена/ники авторов и (если авторы пришлют мне графические файлы 64×64) — аватары авторов. Также появилась возможность изменять период обновления ленты. Да и читать через веб теперь, по-моему, удобнее.

RSS-лента ru_nix_blogs будет теперь перезаряжена с RuNIX.org, поэтому для существующих подписчиков ничего измениться не должно (максимум, будут скачаны повторно недавние сообщения). В любом случае, в ближайшее время возможны какие-то технические накладки, о которых прошу своевременно сообщать, а за возникшие неудобства извинить.

Итак, встречайте:
RuNIX.org — планета блогов о *NIX на русском языке.

20071113

Как скачать альбом Picasaweb целиком (без Picasa)

Написал маленький скрипт download-picasa-album, позволяющий из коммандной строки за раз скачать все изображения из альбома Picasaweb в полном разрешении.

Использовать так:
download-picasa-album 'ссылка-на-RSS-фид-альбома'


И все фотографии албома скачиваются и помещаются в текущую директорию. Русские буквы в именах файлах обрабатываются нормально (в UTF-8 локали), а вот пробелы, думаю, вызовут проблемы в том месте, где awk вызывает wget. Надо бы поправить...

Да, можно вместо ссылки давать имя файла с уже скачанным фидом.

Скачать скрипт


Идею заимствовал у Дмитрия Астапова, но воспользовался xmlstarlet вместо Xtract и оформил всё это дело в виде скрипта. Кусок awk-кода, декодирующий URL взял с сайта Huidae Cho. Скрипту также требуется iconv.

Дополнение: Похоже, мой скрипт удачно скачивает только открытые альбомы; надо будет посмотреть, что там ломается с частными альбомами. В общем, если мой скрипт у вас не работает, можете попробовать ещё скрипт Loïc Serf-а. Код его скрипта можно найти также в комментариях ниже.

P.S. Вот, теперь из коммандной строки, не устанавливая громоздкую Picasa, можно не только выкладывать фотографии на Picasaweb, но и скачивать альбомы друзей. Я доволен.

20071108

Видеосвязь в Skype для Linux

А в Skype для Linux появилась, наконец, видео-связь.


Скачать Skype 2.0 beta для Linux.

20071031

Идея: планета русских *nix блогов

Кратко

Единая RSS-лента всех известных мне линукс-блогов на русском языке.

А вместо блог-ролла у меня теперь список последних постов в этих линукс-блогах. Добавлен он вот так:


Проблема


Вот читаю регулярно всякие русские линукс-блоги, а всех нас — так и не знаю. В этом отношении у пользователей ЖЖ с его системой друзей и сообществ удобств больше: им проще узнать друг о друге. А мы узнаём друг о друге в основном случайно.

Да, есть поиск... Но честно говоря, я им не пользуюсь. Почти. Только чтобы перед тем, как писать длинный пост, проверить, что тему никто до меня сильно не пахал, то есть, чтобы не делать двойную работу :)

Да, есть блог-роллы, по которым никто не кликает...

Да, есть Google Reader, в который можно добавить фиды по очереди всех людей из поиска... А если появиться ещё кто-то, то как об этом узнать?

Решение


А есть зато такая концепция сайта, как «планета». Идея: собрать RSS-фиды со всех независимых личных блогов членов сообщества и соединить в единый поток. Смотрите, например, http://planet.debian.org/.

Это удобно: появляется естественное единство сообщества, при этом каждый волен вести свой блог так и там, где ему вздумается. А интересующийся может не подписываться на каждый из блогов по отдельности. Можно подписаться на фид «планеты».

Есть уже для этого готовый скрипт: http://www.planetplanet.org/. Для PlanetPlanet нужен Python и cron на сервере. У меня доступа к такому серверу сейчас нет. Зато я узнал, как объединять несколько RSS потоков в один с помощью Google Reader-а. Для начала, я решил, чтобы испытать идею — и это сойдёт. А что вышло — смотрите в конце поста.

Итак, я взял список ссылок на известные блоги с http://iar.spb.ru/doku.php, вытащил из них вот таким скриптиком ссылки на фиды, преобразовал полученный список фидов в OPML формат (онлайн-конвертер здесь), и загрузил в свой Google Reader, добавив к тем блогам, которые у меня там уже были. После этого пошерстил список на предмет соответствия заявленной тематике (об этом ниже). Затем просто пометил их одним тегом, сделал этот тег общедоступным и отжёг выданный мне RSS на feedburner.

Теперь все русские *nix блоги (из моего списка) можно читать на одной странице, как «планету». И даже можно на них подписаться на все за раз.

Теперь о критериях отбора. Членом клуба может быть примерно такой блог:
  • индивидуальный
  • на русском языке
  • посвящённый использованию или разработке GNU/Linux, *BSD или другого свободного программного обеспечения или родственным темам (как минимум 80% — тематические посты)
  • где есть интересное и уникальное содержимое (а не копипаст)


Новые блоги будут добавляться (и удаляться) мной вручную, если кажутся подходящими (заявку на вступление в клуб писать в комментарии) или неподходящими. Благо сообщество линукс-блоггеров достаточно небольшое. Адрес фида такой: http://feeds.feedburner.com/ru_nix_blogs

Ну как вам такая идея, нравится? Если затея понравится — может доживём до полноценной планеты :)

20070912

Как выглядит новая система закладок Firefox

Появились «скриншоты» будущей новой системы закладок Firefox, placesOrganizer. Выглядит многообещающе. В общем, наконец, удобный поиск, возможность присваивать закладкам метки-теги, а в перспективе и будут создаваться и мини-скриншоты страниц, на которые указывают закладки.

Preview of new Firefox3 bookmarking system


Пока же буду дальше пользоваться Epiphany в качестве основного браузера. Организация коллекции закладок с помощью тегов в ней была придумана уже давно, надёжно работает уже сейчас и сделана довольно удобно.

20070830

Веб-сервер в одну строчку: версия 2.1

Алексей Свешников опубликовал в своём блоге пример веб-сервера, занимающего одну строчку на bash. Очень меня этой безделушкой порадовал. Красиво!

Однако его «сервер» у меня не заработал :)

Если запрос слать телнетом, то вроде что-то шлёт в ответ, а если запрашивать браузером или wget — нет. Пишется: ««127.0.0.1» разорвал соединение».

У меня возникло подозрение, что это из-за того, что скрипт начинает отвечать, не дождавшись конца HTTP запроса (а должен читать заголовки запроса до пустой строки). Я это исправил и wget заработал.

Также, при выдаче каталога хорошо бы отдавать Content-Type, подумал я. Например, без верного Content-Type wget сохраняет пустой файл.

И честно говорить, что это HTTP/1.0. Или поставить HTTP/1.1 и добавить Connection: close. (HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in every message. —RFC2616)

Потом ещё я увидел, что символы перевода строк где-то «защищаются» bash. А именно во время вывода echo. Приходят литералы «\n» вместо кодов CRLF. А положено, чтобы шли именно CRLF. И заголовок ответа также должен заканчиваться пустой строкой.

В общем, вот мой вариант (эта версия у меня работает и с браузером, и с wget):

true; while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;E=NOTYET;while [ ${#E} -gt 0 ];do $r E;E=`$e $E|tr -d "\r\n"`;done;f=`$e $b|sed 's/[^a-z0-9_.-]//gi'`;h="HTTP/1.0";o="$h 200 OK\r\n";c="Content";if [ -z $f ];then($e -e $o;ls|(while $r n;do if test -f ${n}; then $e "<a href=\"/$n\">$n</a><br>";fi;done););elif [ -f $f ];then $e -e "$o$c-Type: `file -ib $f`\n$c-Length: `stat -c%s $f`\n";cat $f;else $e -e "$h 404 Not Found\n\n404\n";fi)';done


Эта версия ещё и скрывает подкаталоги текущего каталога, показывая только файлы. Набирать одной строчкой и смотреть результаты на 127.0.0.1:8080.