Публикую данный пост по просьбе уважаемого VladX, у которого возникло временное недопонимание с кармой.
Апплет — это маленькое приложение, встраиваемое непосредственно в панель GNOME. Обычно апплет выполняет какой-то опеределенный узкий функционал (изменение громкости, монтирование устройств), что выгодно отличает его от громоздкого оконного приложения. На самом деле знающему Python кодеру не составит труда написать собственный апплет, но и для незнающих есть выход: большое количество полезных (и не очень) апплетов лежит на сайте gnomefiles.org, помимо этого, на официальном сайте есть примеры написания апплетов на C.
Итак, мы пишем апплет. Апплет должен что-то делать. Наш апплет, например, будет показывать хабракарму и хабрасилу. Для получения всей этой информации мы будем использовать API хабра.
Вот так начинается наш апплет. Тут все понятно — импортируем нужные библиотеки, заносим в переменные нужные параметры. Во избежание всяких проблем с русскими символами будем использовать кодировку UTF-8 (и Вам, кстати, советую всегда поступать так же).
Это, собственно, самая интересная часть апплета. Метод-конструктор __init__ () инициализирует объект, метод __init_popupmenu () добавляет в контекстное меню комманды «Открыть» и «О программе» и задает соответствующий им callback-метод. Метод get_info () получает ответ от сервера и обрабатывает его на предмет заветных чисел кармы и силы. Было бы глупо использовать специальный xml-парсер в столь тривиальной задаче, поэтому обойдемся простым быдлокодерским способом.
Эти функции одинаковы в большинстве апплетов на Python, необходимо только изменить аргументы, передаваемые методу bonobo_factory на свои.
Также есть один полезный момент: при передаче скрипту параметра --run-in-window апплет запускается в отдельном окне, что очень помогает при отладке.
Ну вот, казалось бы, и все. Но нет — апплет написан, но в списке апплетов гнома его нет. Чтобы это исправить, нужно положить файлик (в данном случае можно использовать имя gnomeMyAppletFactory.server) в директорию /usr/lib64/bonobo/servers с примерно таким содержанием:
Не забываем поменять путь к скрипту на свой и разрешить его исполнение с помощью chmod +x.
Удачного коддинга, %username%!
p.s. При подготовке материала использовался ресурс highlight.hohli.com.
Апплет — это маленькое приложение, встраиваемое непосредственно в панель GNOME. Обычно апплет выполняет какой-то опеределенный узкий функционал (изменение громкости, монтирование устройств), что выгодно отличает его от громоздкого оконного приложения. На самом деле знающему Python кодеру не составит труда написать собственный апплет, но и для незнающих есть выход: большое количество полезных (и не очень) апплетов лежит на сайте gnomefiles.org, помимо этого, на официальном сайте есть примеры написания апплетов на C.
Поехали!
Итак, мы пишем апплет. Апплет должен что-то делать. Наш апплет, например, будет показывать хабракарму и хабрасилу. Для получения всей этой информации мы будем использовать API хабра.
#!/usr/bin/env python
# coding=utf-8
import sys, os, gtk, gtk.gdk, pygtk, gnomeapplet, gnome
pygtk.require('2.0')
__USER__ = 'VladX'
__URL__ = 'http://habrahabr.ru/api/profile/' + __USER__
Вот так начинается наш апплет. Тут все понятно — импортируем нужные библиотеки, заносим в переменные нужные параметры. Во избежание всяких проблем с русскими символами будем использовать кодировку UTF-8 (и Вам, кстати, советую всегда поступать так же).
class MyApplet (gnomeapplet.Applet):
def __init__ (self, applet, iid):
self.applet = applet
self.applet.set_name('MyApplet')
self.hbox = gtk.HBox()
self.applet.add(self.hbox)
self.event = gtk.EventBox()
self.hbox.add(self.event)
self.info = gtk.Label()
self.event.add(self.info) # Чтобы объект мог реагировать на различные события, его нужно поместить в Event Box
self.event.set_tooltip_text('Хабраюзер ' + __USER__)
self.event.connect('button-press-event', self.callback_button)
self.__init_popupmenu()
self.applet.connect('destroy', self.callback_destroy)
self.applet.show_all() # Показываем все это на панели
self.info.set_text(self.get_info())
def __init_popupmenu (self):
self.applet.setup_menu('''
<popup name='button3'>
<menuitem name='Open Item' verb='Open' stockid='gtk-open'/>
<menuitem name='About Item' verb='About' stockid='gtk-about'/>
</popup>''', [
('Open', self.callback_open),
('About', self.callback_about)
], None)
def get_info (self):
'''Делаем запрос, например, при помощи Pycurl'''
import pycurl, StringIO
content = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, __URL__)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.WRITEFUNCTION, content.write) # Задаем метод, записывающий ответ в переменную
c.perform()
c.close()
content = content.getvalue()
'''Парсим код'''
try:
karma = content[content.index('<karma>')+7:content.index('</karma>')]
except:
karma = '*'
try:
rating = content[content.index('<rating>')+8:content.index('</rating>')]
except:
rating = '*'
return karma + '/' + rating
def callback_button (self, widget, event):
self.callback_open(self)
def callback_open (self, event, data=None):
'''Открываем в браузере по клику'''
gnome.url_show (
'http://' +
__USER__.replace('_', '-') + # Заменяем в поддомене символы подчеркивания на дефисы
'.habrahabr.ru/'
)
def callback_about (self, event, data=None):
'''Показываем стандартное окошко среды GNOME'''
os.system('gnome-about')
def callback_destroy (self, applet):
'''Уничтожаем объект'''
del self.applet
Это, собственно, самая интересная часть апплета. Метод-конструктор __init__ () инициализирует объект, метод __init_popupmenu () добавляет в контекстное меню комманды «Открыть» и «О программе» и задает соответствующий им callback-метод. Метод get_info () получает ответ от сервера и обрабатывает его на предмет заветных чисел кармы и силы. Было бы глупо использовать специальный xml-парсер в столь тривиальной задаче, поэтому обойдемся простым быдлокодерским способом.
def applet_factory (applet, iid):
MyApplet(applet, iid)
return True
def main (args):
if len(sys.argv) == 2 and sys.argv[1] == 'run-in-window':
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title('It works!')
window.connect('destroy', gtk.main_quit)
applet = gnomeapplet.Applet()
applet_factory(applet, None)
applet.reparent(window)
window.show_all()
gtk.main()
sys.exit()
elif len(sys.argv) == 2 and sys.argv[1] == 'help':
'''Выводим хелп по параметрам'''
print '''
--run-in-window - run applet independent of gnome-panel
--help - show this message'''
else:
gnomeapplet.bonobo_factory('OAFIID:GNOME_MyApplet_Factory',
MyApplet.__gtype__,
'My Applet',
'1.0',
applet_factory)
if __name__ == '__main__':
main(sys.argv)
Эти функции одинаковы в большинстве апплетов на Python, необходимо только изменить аргументы, передаваемые методу bonobo_factory на свои.
Также есть один полезный момент: при передаче скрипту параметра --run-in-window апплет запускается в отдельном окне, что очень помогает при отладке.
Ну вот, казалось бы, и все. Но нет — апплет написан, но в списке апплетов гнома его нет. Чтобы это исправить, нужно положить файлик (в данном случае можно использовать имя gnomeMyAppletFactory.server) в директорию /usr/lib64/bonobo/servers с примерно таким содержанием:
<oaf_info>
<oaf_server iid='OAFIID:GNOME_MyApplet_Factory' type='exe' location='/home/vlad/applets/src/habrapplet.py'>
<oaf_attribute name='repo_ids' type='stringv'>
<item value='IDL:Bonobo/GenericFactory:1.0' />
<item value='IDL:Bonobo/Unknown:1.0' />
</oaf_attribute>
<oaf_attribute name='name' type='string' value='My Applet' />
<oaf_attribute name='description' type='string' value='Show your karma and ratio' />
</oaf_server>
<oaf_server iid='OAFIID:GNOME_MyApplet' type='factory' location='OAFIID:GNOME_MyApplet_Factory'>
<oaf_attribute name='repo_ids' type='stringv'>
<item value='IDL:GNOME/Vertigo/PanelAppletShell:1.0' />
<item value='IDL:Bonobo/Control:1.0' />
<item value='IDL:Bonobo/Unknown:1.0' />
</oaf_attribute>
<oaf_attribute name='name' type='string' value='My First Applet' />
<oaf_attribute name='name-ru' type='string' value='Хабрапплет' />
<oaf_attribute name='description' type='string' value='Show your karma and ratio' />
<oaf_attribute name='description-ru' type='string' value='Отображает вашу карму и хабрасилу' />
<oaf_attribute name='panel:category' type='string' value='Utility' />
<oaf_attribute name='panel:icon' type='string' value='computer.png' />
</oaf_server>
</oaf_info>
Не забываем поменять путь к скрипту на свой и разрешить его исполнение с помощью chmod +x.
Удачного коддинга, %username%!
p.s. При подготовке материала использовался ресурс highlight.hohli.com.