Menus de Torta com Python e Cairo

Um tempinho atrás experimentei fazer uma interface do tipo pie menu, aqueles menus circulares, usando Python e Cairo. A idéia era usar num tipo de arena de combate usando marcadores para representar os lutadores, com ações escolhidas em menus de contexto circulares.

Melhor um screencast que palavras:

Veja o código aqui. Os arquivos são arena.py (execute este), p_token.py e piemenu.py.
Ou use o subversion:

svn checkout http://setanta-labs.googlecode.com/svn/trunk/pycairo piemenu

Funciona assim: a classe Arena é um widget que pode conter objetos da classe Token (os marcadores representando personagens), estes por sua vez contém um objeto da classe PieMenu, que é composto por vários itens.

Em código:

arena = Arena()

piemenu = PieMenu()
piemenu.add_item('icon1.png', do_callback, 2) # (icon, callback function, callback params...)
piemenu.add_item('icon2.png', do_callback)

token = Token((200, 100), 'token-icon.png', piemenu) # (position, icon, menu)

arena.add_token(token)

Então você adiciona a Arena num container qualquer e está pronto.

Habemus VoIP!

Finalmente consegui fazer minha primeira chamada de VoIP com o Ereséva! Viva!
Mas antes de explicar o problema, deixe-me mostrar a arquitetura da coisa toda.

Tapioca-Ereséva
Álvares de Azevedo é uma cara conectado

Funciona assim: o Ereséva usa Tapioca-Python (que é um binding para Tapioca-GLib) para conectar às redes de IM e estabelecer sessões de VoIP; o framework Tapioca se comunica via D-Bus usando a especificação do Telepathy para solicitar serviços aos Connection Managers, que “traduzem” as solicitações recebidas para o protocolo relevante, e o mesmo no sentido oposto; para estabelecer uma sessão de VoIP entra em cena o Stream Engine, que usa GStreamer para montar um pipeline com os codecs necessários e controlar o fluxo de mídia entre a aplicação cliente e a rede.

Estava tentando voipar faz alguns dias, atormentando muitas pessoas no processo (ver lista dos voipadores no final), mas toda vez que um dos meus testadores atendia não se ouvia nenhum som, e a ligação caía. Analisando mais de perto, descobri que o Stream Engine estava dando erros de fluxo de dados, mas Birunko e Tester, do canal #tapioca-voip no Freenode, me mostraram que o problema estava no processo de build. Corrigido isso pude voipar em paz. Com uma ressalva: consegui ouvir, mas não ser ouvido. Pode ser um problema de configuração no microfone ou ainda um problema do Stream Engine. Mas vou deixar pra descobrir mais tarde pois o dever acadêmico chama!

Instalação

Para usar o Ereséva você precisa de instalar o que está descrito no Installation Guide do Tapioca, (incluindo o Tapioca-Python), então baixe:

svn co https://tapioca-voip.svn.sourceforge.net/svnroot/tapioca-voip/trunk/ereseva ereseva

e instale o Ereséva com aquele processo de build de sempre: ./autogen.sh, make, sudo make install, não esquecendo de instalar o pacote pylint (sudo apt-get install pylint).

O Ereséva ainda tem vários pequenos e irritantes bugs, então sinta-se a vontade pra bug-reportar os problemas que te incomodarem.

Heróicos VoIPeiros

Como disse antes, enchi o saco de várias pessoas com os testes, e a esses bravos e pacientes VoIPeiros eu presto homenagem. Principalmente porque o sofrimento deles está longe de acabar! MuaHAHAHa

Como prometido, vou agora torná-los famosos:

  • Chicoti
  • Davi “Mestre” Pires
  • David Aragão
  • Ian Moreira
  • Pedro Leite
  • Renata “Cachinhos” Garcia

Foi Renata a primeira com quem consegui falar usando o Ereséva (ela estava usando o GoogleTalk no Windows) e por isso exibo aqui o avatar simpsoniano que ela fez.

Avatar Renata Cachinhos

Update: obrigado a Renata Bezerra, por ter pacientemente ajudado a corrigir as altamente bugadas e incompletas (pelo lado do Tapioca-Python) instruções de instalação da wiki do tapioca!

Renatas ajudam! :)

Ereséva – codinome Azevedo (ex-Colligo)

No último episódio o Colligo havia sido citado positivamente no Ars Technica, mas logo após aconteceu de descobrirmos através de um comentário que o nome Colligo pertencia a uma empresa gold parceira da Microsoft. O humor do universo em que vivemos é mesmo insuperável, me pergunto se existirá algum universo chato onde só aconteceriam coisas sem graça.

Depois de muita procura Kenneth apareceu com o nome Ereséva, que em Tupi quer dizer algo como “o quê você quer dizer”. O problema de trademark estava acabado, mas não o de pronúncia, então durante uma reunião onde todos falaram o nome das formas mais variadas e criativas, Lauro (não o Moura, mas o Lauro sênior, que acha que blog é coisa de miguxo) saiu com Azevedo. Birunko (que é um miguxo que também não tem blog), acrescentou que numa linguagem há muito esquecida Azevedo significava “aquele que faz VoIP”. E assim foi escolhido o codinome totalmente não oficial do projeto.

AzeVoIP
Álvares de Azevedo, o garoto propaganda totalmente não oficial do Ereséva

Desde a última vez que falei do Colligo Ereséva várias coisas (além do nome) mudaram, e apesar de ter uns bugs menores vou deixá-los quietos e me concentrar em fazer o VoIP funcionar, porque tá todo mundo perguntando disso. :)

Agora o screenshot obrigatório pra mostrar o estado do codinome Azevedo:

Ereséva

Pra baixar e instalar (e testar e relatar bugs! :D) siga as instruções aqui, lembrando de trocar colligo por ereseva.

Vala para Mobile

Como você já deve saber, o sistema de tipos e orientação a objetos de GTK+ é baseado na GLib. E como você já deve saber, botar pra funcionar orientação a objetos em C é um troço bem engenhoso, mas muito doido e cansativo. Daí que boa parte dos programas em GTK+ é escrita em linguagens de alto nível usando bindings (PyGTK, GTK#, gtkmm, java-gnome).

Os bindings são muito úteis, mas para um programa feito em PyGTK funcionar, é necessário ter instalados em seu sistema GTK+, Python e PyGTK. Num sistema Linux regular tudo isso já está lá e ninguém percebe. Já numa máquina Windows pode ser um pouco demais pedir pra o usuário instalar esses mondrongos antes do seu programa de 800kb. O problema no desktop não é falta espaço em disco ou memória, e sim evitar importunar o usuário com a instalação de dependências que ele não precisa saber que existem. (Tem gente trabalhando nesse último problema.)

Mas o que me motivou a escrever esse post foram os sistemas móveis. Já temos uma certa quantidade de plataformas móveis baseadas em GTK+ (e GStreamer, e outras GLib-coisas): Maemo, OpenMoko, OLPC. Bindings para linguagens de alto nível estão normalmente disponíveis e sua instalação costuma ser transparente para o usuário. Só não é transparente para os recursos limitados do dispositivo portátil, mas pedir aos desenvolvedores que usem GLib-C[1] certamente não vai te tornar um cara mais popular.

Vala

Vala é uma linguagem com sintaxe próxima de C#, com algumas adaptações para se encaixar melhor no sistema de tipos do GObject. Pelo menos é isso que diz no site. Já a wikipedia diz o seguinte:

Vala (valá-), meaning “enclosure” in Vedic Sanskrit, is an Asura of the Rigveda and the Atharvaveda, the brother of Vrtra.
(…)
Historically, it has the same origin as the Vrtra myth, being derived from the same root, and from the same root also as Varuna, *val-/var- (PIE *wel-) “to cover, to enclose” (perhaps cognate to veil).

Wikipedia: Vala (Vedic)

Antes de você começar a pensar que se trata de mais um binding pra GTK+, vou esclarecer que a saída gerada pelo compilador Vala é nada menos que código GLib-C, que pode ser compilado normalmente pelo GCC para binários nativos, linkando diretamente com bibliotecas baseadas na glib. Vala é algo que, fazendo uma analogia ao asura do mito védico, cobre/envolve o código GLib-C, ocultando sua complexidade. A ligação Vala-C é feita por um arquivo .vapi, que, como cansei de dizer, só é necessário em tempo de compilação.

Voltando ao cenário dos dispositivos móveis, com Vala o desenvolvedor tem o conforto equivalente a um binding de alto nível, e o portátil não tem de pagar o preço por isso. Abstração sem overhead!

Instalando

Pegue a versão mais recente em http://live.gnome.org/Vala/Release e compile da maneira usual. Além das ferramentas de praxe, Bison e Flex precisam estar instalados (no Debian/Ubuntu são os pacotes bison e flex).

Comparação

Vejamos um código bem simples em Vala, apenas uma classe que herda de um GObject e acrescenta um campo de texto.

// example.vala
using GLib;
public class MyObject : Object
{
protected string text { get; set; }
public MyObject () {
text = "";
}
}

Para gerar o código C (.h e .c), chame: valac example.vala

Os get e set da linha abaixo

protected string text { get; set; }

dão origem a

char* my_object_get_text (MyObject* self)
{
g_return_val_if_fail (IS_MY_OBJECT (self), NULL);

return self->priv->_text;
}

void my_object_set_text (MyObject* self, const char* value)
{
g_return_if_fail (IS_MY_OBJECT (self));

char* __temp2 = NULL;
const char* __temp1 = NULL;
self->priv->_text = (__temp2 = (__temp1 = value, (__temp1 == NULL ? NULL : g_strdup (__temp1))), (self->priv->_text = (g_free (self->priv->_text), NULL)), __temp2);
}

Mais Código

Como este blog honra as calças que veste, os seguintes códigos de exemplo (junto com um Makefile) podem ser encontrados no svn do google:

Minha intenção é gerar os bindings pra algumas coisas interessantes como tapioca-glib e hildon. Pode levar um tempo, mas assim que estiver pronto posto algo.

[1] GLib-C é a forma como Steven Hendrickx se refere a código C escrito no estilo orientado a objetos da GLib em seu texto Glib-C: C as an alternative Object Oriented Environment.

OLPC num Futuro Mad Max

Já se perguntou o que vai estar fazendo no fim da civilização ocidental? É, pode acabar mesmo! Aconteceu outras vezes, nenhuma civilização escapa, de repente parece que está tudo bem, aí pimba, os bárbaros invadem, o clima muda e as colheitas são perdidas, alguma revolta interna põe tudo de cabeça pra baixo, ou tudo isso junto. Enfim, de repente o caos impera, ninguém é de ninguém e o que conta é a sobrevivência. Você pode até ficar pensando que nós somos diferentes do que veio antes porque temos internet, aviões, televisão, mas uma das características das civilizações que caem é estar deslumbrada com ela própria pouco antes da queda. Mil anos de Roma e o que saiu disso? Idade Média. :D

Agora me dirijo a você programador ou programadora, já imaginou qual seu papel num futuro do tipo Mad Max? Pois é né, o dia todo numa cadeira, desenvolvendo habilidades que giram em torno de um dispositivo que precisa de energia elétrica, conexão de rede e assim vai. Assim como as girafas, nos tornamos seres ridiculamente especializados. Num mundo sem energia e conectividade seremos inúteis e qualquer grupo em sã consciência nos deixaria pra morrer no deserto nas mãos das gangues de motocicletas.

Mas agora seus problemas apocalípticos se acabaram! Chegou o revolucionário XO, do projeto OLPC! Com ele a sua utilidade e conseqüentemente sobrevivência estão garantidas num futuro apocalíptico estilo Mad Max! A energia do dispositivo pode ser recarregada manualmente; não é necessária a existência de grandes corporações de comunicações para o uso da rede mesh; ele foi feito leve, robusto e resistente (pra levar bagaço das crianças), o que é perfeito pra aquela fuga desesperada pela vida no mundo caótico do futuro; e melhor, quase tudo no XO é feito em Python (e PyGTK e outras coisas)!

Cuidado com as gangues motorizadas em busca de energia!
Software para simular ataques das gangues motorizadas do futuro apocalíptico.

Então o que está esperando? Apóie a idéia do OLPC, mesmo que seja por interesse pessoal. Tem de ser assim se quisermos sobreviver!

Colligo, Tapioca, Python

Depois de entender e explicar o que era Tapioca, meus chefes no INdT (devido a minha condição de estagiário, quase todos são meus chefes :P) me destacaram pra ajudar Kenneth (que faz um código muito bom e foi muito paciente com minha lentidão inicial) no desenvolvimento do Colligo, uma aplicação de IM que usa o muito recente tapioca-python, que são os bindings python para tapioca-glib.

Os bindings para python também são trabalho do Kenneth, e conforme usávamos seus recursos no Colligo os defeitos iam aparecendo e sendo corrigidos, assim tapioca-python está ficando em muito boa forma. Lembrem-se, a melhor forma de aprimorar algo é usando, que por indução nos leva até o dito popular “Panela velha é que faz comida boa”. Voltando ao assunto, até a próxima sexta releases são esperados, e pacotes .deb não devem estar nada distantes.

Acredito que ter bindings python para qualquer biblioteca de mais baixo nível é muito importante, porque remove muitas barreiras para os desenvolvedores interessados em testá-la. A importância que o pessoal do GStreamer e do D-Bus dá à suas versões em python é um exemplo disso.

Agora o screenshot do Colligo (esta versão que eu estava trabalhando nesse sábado tem algumas coisas fora de lugar, mas segunda eu dou um jeito):

Colligo

Ah! Tinha esquecido a fama e a fortuna: meu nome apareceu no Planet GNOME! Isso porque o blog do Kenneth é agregado lá, aliás nesse post dele vocês podem ver mais screenshots.

Código:

Para instalar o Colligo você vai precisar dos seguintes componentes:

Quando tudo estiver instalado entre no diretório do Colligo e execute

python setup.py build
sudo python setup.py install

Isso colocará o Colligo no menu Aplicações->Internet.

O tutorial de instalação do tapioca deve ajudar um bocado, inclusive indicando as dependências. E meu tutorial também pode esclarecer um pouquinho. (Jabá! ;) ) Embora seja sobre a tapioca-glib pode servir para entender o tapioca-python, além de explicar alguns conceitos teóricos (e ter diagramas coloridos!).

[1] Gabble é um connection manager para redes Jabber, a versão indicada para download aqui é o release mais recente de quando esse post foi escrito, mas como ela está em intenso desenvolvimento, é bom dar uma checada nas últimas versões. Perceba que no tutorial de instalação indicado a versão usada é a 0.5.1, isso porque estava no Ubuntu Edgy e a versão da libdbus-glib-1-dev já não era suficiente da 0.5.2 em diante. Usuários do Feisty (ou aqueles que preferirem compilar tudo na mão) não devem ter esse problema.

Update: esqueci de mencionar que gabble passou a depender da telepathy-glib. O link já está na lista acima.

Update2: Graças a solotim no canal #tapioca-voip do Freenode percebi que o processo de instalação estava incompleto. Agora está legal. Brigado. :)

TagMap 0.7.6

Este release do TagMap é candidato a ser colocado na página oficial do Tagmar 2, esperando apenas revisão. Muitos dados foram adicionados, mas ainda falta alguma coisa. Como vou começar a ficar sem tempo, espero que o povo goste e alguém dê um passo à frente para ajudar a inserir dados (não requer habilidades de programação).

Bug reports são extremamente bem-vindos.

Quando TagMap chegar no 1.0 posso me dedicar ao gerador de personagens.

Downloads no lugar de sempre:

P.S.: Ainda estou devendo o pacote .deb.

Sinais em PyGTK e Google Code Search

Os valores manipulados na classe ValueWheel (que criei com Cairo e mencionei num post anterior) influenciam diretamente alguns valores derivados que deverão ser atualizados em tempo real. Então acabei de aprendendo algo sobre sinais em PyGTK. Bem, na verdade sinais com GObject, o sistema de objetos de GTK.

É bem simples:

1. Criar o sinal com gobject.signal_new, os parâmetros são: nome (qualquer um, eu chamei de ‘value-changed’), classe, forma de tratar o sinal, tipo de retorno, tipos dos parametros (nesse caso tipos de dados normais de python).

gobject.signal_new('value-changed', ValueWheel,

gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,))

2. Emitir o sinal quando algum valor mudar. Junto com o sinal eu mando o atributo values, para o destinatário do sinal receber o atributo modificado.

self.emit('value-changed', self.values)

3. Na aplicação que usa o widget conectar o sinal a um callback

instancia_de_wheel.connect('value-changed', funcao_callback)

A assinatura do callback é def funcao_callback(widget, data), onde data será self.values.
O código mais atual está em ValueWheel.py

Google Code Search

Existem muitos bons tutoriais sobre GObject e PyGTK, mas o que me ajudou mesmo a pôr a coisa pra funcionar foi o Google Code Search. Não tem nada melhor que ver como algo é feito num código “pra valer”. Para os sinais eu usei a busca: lang:python gobject.signal_new

Tutoriais