Мне нравится экономить время. Как известно, у многих людей серфинг в интернете занимает львиную долю всего трафика, и отнимает время. Однако хочется быть в курсе последних новостей или публикаций на интересующих ресурсах.
Понятно, что для этого давно придумали RSS-агрегаторы и сервисы типа Google Reader. Понятно, что многие браузеры также на это способны.
Осталось добавить, что через crontab -e или подобные средства легко добавить проверку по расписанию, скажем раз в 20 минут, что я и сделал.
Понятно, что для этого давно придумали RSS-агрегаторы и сервисы типа Google Reader. Понятно, что многие браузеры также на это способны.
Интерфейс Linux-агрегатора aKregator
Однако, я не люблю заводить отдельные программы без лишней необходимости, забивать себе голову деталями интерфейса. К тому же, хочется во-первых, кросплатформенного решения задачи, во-вторых, непринужденной и удобной формы подачи. Все это сподвигнуло меня сделать все вручную на связке Python + Tkinter. Сказано - сделано. На момент написания у меня был установлен Python версии 2.7 (но пойдет и 2.6 и возможно более ранние). К чему писать парсер самому когда есть весьма качественные готовые решения? Одним из таких является Universal Feed Parser под версией 5.1.1. Взять его можно здесь. Установка очень простая. Например под windows сначала распаковываем, у меня это был каталог D:\feedparser-5.1.1. Запускаем установку setup.py install (возможно понадобится setuptools упрощающий установку, его можно взять его здесь).
Собственно установка
Открываем редактор Python (под виндами я пользуюсь обычно IDLE, поскольку "из коробки", легко проверять-отлаживать на ходу, плюс подсветка кода, автокомплит и автоматически проставляются нужные отступы). Теперь самое интересное, пишем код:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import feedparser
import time
import shelve
import os
import sys
import webbrowser
from Tkinter import *
popuptimeout = 10 # timeout for popup informer in seconds
count = 5 # number of displaying new posts
bgcolor = '#fcdd76' # background color of popup window
# second parameter must be url e.g. http://habrahabr.ru/rss/hubs
if len(sys.argv) < 2:
sys.exit('Usage: %s url' % sys.argv[0])
url = sys.argv[1]
tmpname = url.replace('http://','').replace('/','').replace('.','')
tmpfile = shelve.open(tmpname,'c')
rss = feedparser.parse(url)
labels = []
links = []
# check for temporary file
if not os.path.isfile(tmpname):
exit('something wrong with file ' + tmpname + '. press enter to exit')
# main processing
for entry in rss.entries:
if len(labels) >= count:
break
link = entry.link.encode('utf-8')
newstr = entry.title
if not link in tmpfile:
# convert the given time format to datetime
posted = time.strftime("%d.%m.%Y %H:%M", entry['updated_parsed'])
tmpfile[link] = 1
labels.append(newstr + ' ' + posted)
links.append(link)
tmpfile.close()
# function to make captions clickable
def click(event):
text = event.widget.cget("text")
link = links[labels.index(text)]
if link:
try:
browser=webbrowser.get('firefox')
except:
browser=webbrowser.get('')
browser.open_new(link)
# show a new post we have
if bool(labels):
root = Tk()
root.configure(background=bgcolor)
root.attributes('-alpha',0.8) # transparency
for i in filter(lambda x: x<=count,xrange(len(labels))):
label = Label(root,text=labels[i],bg=bgcolor)
label.pack(side="top")
label.bind("<Button-1>",click)
root.geometry("-1-20")
root.overrideredirect(True)
root.after(popuptimeout*1000,root.destroy)
root.mainloop()
После подключения нужных модулей идет объявление полезных переменных, позволяющих настроить время жизни всплывающего сообщения, количество отображаемых новых сообщений, фоновый цвет окна. Списки labels и links будут хранить заголовки и ссылки на сообщения. Для сохранения в файл уже просмотренных объектов хорошо подойдет модуль shelve. Файлы будут сохраняться в домашней директории на unix-системах, и в директории со скриптом на windows и иметь имя основанное на url ресурса. Основная обработка скормленной ленты происходит в цикле for. При наличии хоть одного нового сообщения значение функции bool(labels) вернет True, и начнется отрисовка простенького окошка. Инструкция root.attributes('-alpha',0.8) настроит степень прозрачности (у меня это сработало только на windows), хотя в этом и нет необходимости. Конструкцией filter мы отбираем из всех сообщений лишь столько, сколько указано в count, и не более. label.bind привязывает клик левой кнопкой мыши к событию click() чтобы каждая новость стала кликабельной. root.geometry задает место появления окошка (для меня весьма удобно было показывать его у панели задач возле часов). root.after уничтожает окно после истечения заданного времени. Теперь перейдет к функции click(). По нажатию на новость event.widget.cget получает текст сообщения, по которому мы находим и ссылку. Модуль webbrowser, входящий в состав Python, запускает ссылку в firefox или другом установленном у вас браузере. Очень просто и удобно. Ну и посмотрим, собственно на результат (испытывал на лентах habrahabr.ru и sibnovosti.ru):
Вот так-вот в windows xp
Вот так-вот в linux с KDE
Немного полезных линков по теме:
Документация по Tkinter-у раз



На некоторых системах может не работать открывание ссылки в окне браузера, тогда надо поменять browser=webbrowser.get('firefox') на другое значение, например browser=webbrowser.get('windows-default'). Чтобы узнать, на какое именно, можно в интерпретаторе питона выполнить команду print webbrowser._browsers
ОтветитьУдалить