Ver Feed RSS

root@blog:/# chmod o+r *

Python & USBManager: Notificações

Avalie este Post de Blog
Continuando a serie de posts sobre o Python e o USBManager... A noite de ontem foi dedicada a dois assuntos: Sinais no DBus/HAL e Notificações com Python e GTK. Vamos começar com o essencial: Sinais.


Sinais no DBus/HAL

"Sinais, ah, já vi esse filme!". Não!! Não é isso... Sinais (signals) é o nome utilizado para se referir a "eventos" na interface gráfica. Quando temos um botão na interface e você clica nele é gerado um sinal. Quem estiver "escutando" esse sinal toma uma "atitude".

O bom do DBus/HAL é que ele implementa alguns tipos de sinais, assim eu consigo descobrir quando um dispositivo foi inserido/removido ou quando uma propriedade de um dispositivo foi alterado. Essa última eu achei uma das mais interessantes pois vai simplificar muito o controle das informações na interface. Em compensação terei que reescrever toda a lógica aplicação

Vou mostrar um exemplo rápido sobre como "escutar" os sinais do DBus...

Código :
[FONT=Courier New][COLOR=DarkOrange]
[/COLOR][/FONT][FONT=Courier New][COLOR=DarkOrange]import[/COLOR][/FONT][FONT=Courier New] gobject
[/FONT][FONT=Courier New][COLOR=DarkOrange]import[/COLOR][/FONT][FONT=Courier New] dbus[/FONT][FONT=Courier New][COLOR=DarkOrange]
from [/COLOR][/FONT][FONT=Courier New]dbus.mainloop.glib [/FONT][FONT=Courier New][COLOR=DarkOrange]import [/COLOR][/FONT][FONT=Courier New]DBusGMainLoop
 
DBusGMainLoop(set_as_default=True)[/FONT][FONT=Courier New][COLOR=DarkOrange]
 
def [/COLOR][/FONT][FONT=Courier New][COLOR=Blue]device_add[/COLOR][/FONT][FONT=Courier New](volume_udi):
    [/FONT][FONT=Courier New][COLOR=DarkOrange]print [/COLOR][/FONT][FONT=Courier New][COLOR=SeaGreen]'New device added: '[/COLOR][/FONT][FONT=Courier New], volume_udi[/FONT][FONT=Courier New][COLOR=DarkOrange]
 
def [/COLOR][/FONT][FONT=Courier New][COLOR=Blue]device_removed[/COLOR][/FONT][FONT=Courier New](volume_udi=None):[/FONT][FONT=Courier New][COLOR=DarkOrange]
    print [/COLOR][/FONT][FONT=Courier New][COLOR=SeaGreen]'A device was removed!'[/COLOR][/FONT][FONT=Courier New][COLOR=DarkOrange]
 
def [/COLOR][/FONT][FONT=Courier New][COLOR=Blue]properties_changed[/COLOR][/FONT][FONT=Courier New](key, was_added=None, was_removed=None, path=None):
    [/FONT][FONT=Courier New][COLOR=DarkOrange]print [/COLOR][/FONT][FONT=Courier New][COLOR=SeaGreen]'Properties changed on'[/COLOR][/FONT][FONT=Courier New], path
 
bus = dbus.SystemBus()
hal_manager_obj = bus.get_object([/FONT] [FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal\\"[/COLOR][/FONT][FONT=Courier New], [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"/org/freedesktop/Hal/Manager\\"[/COLOR][/FONT][FONT=Courier New])
hal_manager = dbus.Interface(hal_manager_obj, [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal.Manager\\"[/COLOR][/FONT][FONT=Courier New])[/FONT]
 
[FONT=Courier New][COLOR=DarkRed]# Connecting singals for new devices[/COLOR][/FONT][FONT=Courier New]
hal_manager.connect_to_signal([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"DeviceAdded\\"[/COLOR][/FONT][FONT=Courier New], device_add)
hal_manager.connect_to_signal([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"DeviceRemoved\\"[/COLOR][/FONT][FONT=Courier New], device_removed)[/FONT][FONT=Courier New][COLOR=DarkRed]
 
# Only Storage Devices[/COLOR][/FONT][FONT=Courier New]
volume_udi_list = hal_manager.FindDeviceByCapability ([/FONT][FONT=Courier New][COLOR=SeaGreen]'volume'[/COLOR][/FONT][FONT=Courier New])[/FONT][FONT=Courier New][COLOR=DarkOrange]
for [/COLOR][/FONT][FONT=Courier New]volume_udi [/FONT][FONT=Courier New][COLOR=DarkOrange]in [/COLOR][/FONT][FONT=Courier New]volume_udi_list:
[/FONT][FONT=Courier New][COLOR=DarkRed]    # Some needed variables[/COLOR][/FONT][FONT=Courier New]
    volume_obj = bus.get_object ([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal\\"[/COLOR][/FONT][FONT=Courier New], volume_udi)
    volume = dbus.Interface(volume_obj, [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal.Device\\"[/COLOR][/FONT][FONT=Courier New])
    storage_udi = volume.GetProperty ([/FONT][FONT=Courier New][COLOR=SeaGreen]'block.storage_device'[/COLOR][/FONT][FONT=Courier New])
    storage_obj = bus.get_object ([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal\\"[/COLOR][/FONT][FONT=Courier New], storage_udi)
    storage = dbus.Interface(storage_obj, [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"org.freedesktop.Hal.Device\\"[/COLOR][/FONT][FONT=Courier New])
 
[/FONT]  [FONT=Courier New][COLOR=DarkRed]  # Only USB devices[/COLOR][/FONT][FONT=Courier New]
    [/FONT][FONT=Courier New][COLOR=DarkOrange]if [/COLOR][/FONT][FONT=Courier New]storage.GetProperty([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"storage.bus\\"[/COLOR][/FONT][FONT=Courier New]) == [/FONT][FONT=Courier New][COLOR=SeaGreen]'usb'[/COLOR][/FONT][FONT=Courier New]:
[/FONT] [FONT=Courier New][COLOR=DarkRed]       # Properties changed signal[/COLOR][/FONT][FONT=Courier New]
        volume_obj.connect_to_signal([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"PropertyModified\\"[/COLOR][/FONT][FONT=Courier New], properties_changed, path_keyword=[/FONT][FONT=Courier New][COLOR=SeaGreen]'path'[/COLOR][/FONT][FONT=Courier New])[/FONT]
 
[FONT=Courier New]loop = gobject.MainLoop()
loop.run()
[/FONT]
Bem... Não vou me ater muita a explicar o código mas basicamente ele faz os imports, define as funções pra gerar um output, cria o DBus, se conecta aos sinais, lista os dispositivos de armazenamento pega somente os dispositivos via USB, se coneta ao sinal de propriedades alteradas (aos dispositivos conectados atualmente) e por último entra num loop infinito.

Importante ressaltar que se for utilizar esse código em uma interface GTK é desnecessário o import do módulo gobject e o loop pois o gtk.main() vai substituí-lo. Outra coisa importante é que esse código só imprime a alteração propriedades de dispositivos que estejam conectados no momento que o programa é executado. Já a adição/remoção de dispositivos funcionará para qualquer dispositivos. Isso ocorre porque não nos "conectamos" aos dispositivos conectados por último.

Vamos para o mais interessante...



Notificações com Python e GTK

Agora que temos como saber se foram adicionados/removidos dispositivos vamos avisar isso para o usuário. Para isso usei a biblioteca pynotify.

Uma notificação deve estar atrelada a um StatusIcon (ou mais conhecido como SystemTray). Vamos alterar o código do StatusIcon que eu postei ontem...

Código :
[FONT=Courier New][COLOR=DarkOrange]import[/COLOR][/FONT][FONT=Courier New] pygtk
pygtk.require([/FONT][FONT=Courier New][COLOR=SeaGreen]'2.0'[/COLOR][/FONT][FONT=Courier New])
[/FONT] [FONT=Courier New][COLOR=DarkOrange]import [/COLOR][/FONT][FONT=Courier New]gtk
[/FONT] [FONT=Courier New][COLOR=DarkOrange]import [/COLOR]pynotify[/FONT]
[FONT=Courier New] 
statusIcon = gtk.StatusIcon()
statusIcon.set_from_file([/FONT] [FONT=Courier New][COLOR=SeaGreen]\\"small_icon.png\\"[/COLOR][/FONT][FONT=Courier New])
statusIcon.set_visible(True)
statusIcon.set_tooltip([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"USB Volume Storage Manager\\"[/COLOR][/FONT][FONT=Courier New])[/FONT]
[FONT=Courier New]
pynotify.init([/FONT][FONT=Courier New][COLOR=SeaGreen]\\"USB Volume Storage Manager\\"[/COLOR][/FONT][FONT=Courier New])
 
notification = pynotify.Notification([/FONT] [FONT=Courier New][COLOR=SeaGreen]\\"Título da notificação\\"[/COLOR][/FONT][FONT=Courier New], [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"Esse é um texto para a notificação...\\"[/COLOR][/FONT][FONT=Courier New], [/FONT][FONT=Courier New][COLOR=SeaGreen]\\"dialog-information\\"[/COLOR][/FONT][FONT=Courier New])
notification.attach_to_status_icon(statusIcon)
notification.set_urgency(pynotify.URGENCY_LOW)
notification.set_timeout(5000)
notification.show()[/FONT]
Quem viu o último post notou que são só 6 linhas a mais:

  1. Iniciar o pynotify;
  2. Instanciar uma notificação;
  3. Vinculá-lo a uma StatusIcon;
  4. Setar uma urgência;
  5. Setar um timeout (tempo para a notificação desaparecer automaticamente);
  6. Mostrar a notificação


Agora vou mostrar como implementei isso no USBManager:



Alguém ai tem mais idéias de notificações?!?!

É isso ai pessoal... Sempre que aprendo algo novo em Python fico impressionado com a facilidade do código (tirando o DBus e HAL que foi f***)!

Hum... Como será que isso fica no sistema de notificação do Ubuntu 9.04??

Até mais...

Atualizado 20-01-2010 em 08:13 por Magnun

Categorias
Dicas , Python , Dicas , Projetos , USBManager

Comentários


+ Enviar Comentário