Преамбула
Для слежения за RSS удобно использовать так называемые программы-агрегаторы. Также в настоящий момент набрали популярность онлайн агрегаторы, такие, как Google Reader. Но бывают случаи, когда их функциональность является избыточной, например, если за определённой лентой нужно последить в течении дня или нескольких дней и нет желания засорять свои агрегаторы временными ссылками. Вот и мне понадобился такой инструмент.
Инструмент должен был решать следующие задачи:
— уведомлять об обновлениях
— возможность быстро перейти по ссылке
— не хранить данных, сессий и пр.
Вот что в результате получилось:
А о том как — читайте ниже.
Консоль
Первое, что мне удалось найти — это rsstail.
rsstail — это консольная программа, которая позволяет следить за обновлениями ленты в реальном времени. Данная программа выполняет свои функции на все сто, но, как оказалось, переключаться на консоль и выискивать глазами последние записи неудобно.
Графическое приложение
Далее последовала попытка подойти с другой стороны — найти простейшие графические читалки.
Результат этих поисков показал, что большинство даже самых простых читалок является полноценными агрегаторами и их функционал, для такой простой задачи, как слежение за одним фидом, слишком избыточен.
Совмещение графики и консоли
Попробуем прикрутить к rsstail какой-нибудь графический модуль уведомлений (трей).
Было испробовано:
— notify-send (не годится, т.к. не обрабатываются события мыши)
— gtrayicon (работает как тригер: включение/выключение, а так же после запуска нельзя изменить tooltip-сообщение)
— zenity (была попытка использовать ключ --notification, но этот режим реализован всё ещё не полностью)
На этом поиски закончились, задача получить простой feed-reader оказалась не такой простой.
Наскриптуем!
Ну а здесь у нас почти нет границ!
Весь код я постарался откомментировать, поэтому разобраться и переделать под себя будет несложно.
Помещаем иконку с сообщениями в трей
#!/usr/bin/env ruby #scriptname: libs/rsstray.rb require 'gtk2' browser = 'libs/browser.sh' # signal is using for pushing commands to the main thread signal = Queue.new # Create tray icon si = Gtk::StatusIcon.new # Choose icon image si.icon_name = 'application-rss+xml' # Hide tray icon si.visible = false # Bind action mouse button si.signal_connect('activate') { signal.push('open') } # Bind menu mouse button si.signal_connect('popup-menu') { if signal.num_waiting != 0 then signal.push('') end } # Main thread that reads data from pipe Thread.start do # Get line line by line from pipe while line = STDIN.gets # A record isn't ready yet ready=0 # Parse line case line when /^Title: (.*)$/ then title = $1 when /^Link: (.*)$/ then link = $1 when /^Pub.date: (.*)$/ then pubdate = $1; ready=1 end # Read next line if record ins't ready if not (ready == 1) then next end # Send url to STDOUT puts link # Check if all properties are exist if defined? title and defined? link and defined? pubdate message = title + "\n\n" + link + "\n\n" + pubdate else message = "Something wrong has happened..." end # Set tooltip message for tray icon si.set_tooltip(message) # Make tray icon visible si.set_visible(true) # Wait for signal and open browser if signal is 'open' # and go futher if signal isn't 'open' while signal.pop == 'open' pid = fork { exec(browser, link ) } Process.detach(pid) end # Hide tray icon si.set_visible(false) end # Exit if EOF Gtk.main_quit end # Start main GTK loop Gtk.main
Подаём данные на вход «трей»-скрипта
#!/bin/bash #scriptname: rssreader.sh # Go to script directory cd $(dirname $0) || exit 1 # Check arguments [ -z "$1" ] && { echo "usage: $0 http://address_of_rss_feed [number_of_initially_show_items]"; exit 0; } [ -z "$2" ] && num=1 || num=$2 # Lunch rsstail and tray icon rsstail -zpl -n $num -u "$1" | libs/rsstray.rb
Запускаем браузер по событию из трей скрипта
#!/bin/bash #scriptname: libs/browser.sh firefox "$1" 2> /dev/null & disown
Как пользоваться
Запуск
rssreader.sh http://habrahabr.ru/rss 5
Где habrahabr.ru/rss — это адрес ленты, а 5 — это число последних записей, которые попадут в читалку сразу после запуска. Если число это число не указывать, то по умолчанию используется 1.
Систем трей
— Поднести к иконке — появляется краткая информация о текущей записи в tooltip-окошке
— Кнопка «действие» (обычно левая) — открыть текущую запись в браузере
— Кнопка «контекстное меню» (обычно правая) — перейти к следующей записи
— Если записей больше нет, то иконка пропадает до тех пор пока не появятся новые
Несколько комментариев
— Работа скриптов проверена в Ubuntu 10.10 + ruby 1.8.7
— Для корректной работы скриптов необходимо установить: ruby, libgtk2-ruby, rsstail
— rsstail по умолчанию проверяет обновления каждые 15 минут
— Мне не удалось найти достойную реализацию fork + detach для ruby 1.8 (без установки дополнительных библиотек), поэтому пришлось использовать грязный трюк и отцеплять процесс браузера от процесса читалки с помощью «bash» и "& disown".
В ruby 1.9 этого делать бы не пришлось, но он пока ещё не mainstream.
Послесловие
Скрипты простой RSS-читалки могут быть полезны не только пользователю, который не хочет добавлять ленту по какой-то причине в свой основной ридер, но и веб-разработчику, тестирующему RSS-ридер на тестовом сайте, и как демонстрация возможностей скриптовых движков. Ещё можно поиграться с другой стороны и подавать на входе не RSS, а, например, сообщения от Nagios с помощью nagtail.