Fazendo Tapioca no INdT

Boas novas pra mim mesmo! Passei no processo seletivo pra estagiário do Instituto Nokia de Tecnologia em Recife. Vou trabalhar no framework Tapioca, que é um tipo de GStreamer para Instant Messaging e VoIP.

Desenvolvimento OpenSource remunerado! \o/

E Lauro também! Parabéns!

Agradecimentos à Celina e Marcelo Santana que fizeram o contato, e Sandro, Marcio e Inalda que foram muito legais no processo seletivo.

E um agradecimento especial a quem quer que tenha sido que colocou um Nintendo Wii na sala de convivência do INdT!

Nova Brasil FM e o Advento da Propaganda Reversa

Verificando as estatísticas do wordpress vi que praticamente todo dia alguém acessa o post sobre como ouvir a Nova Brasil FM pelo Banshee. Analisem, eu falo sobre a Nova Brasil FM e recebo visitas por isso, normalmente não é o contrário? “Você está ouvindo a Nova Brasil FM, visitem o blog Head Like a Hole. E agora Nação Zumbi.” Quer dizer que ao falar sobre “tópicos quentes” e seu post aparecer num resultado do Google, o blogueiro torna-se uma Rêmora, e o fluxo da propaganda é invertido.

Mas não é por causa disso que vou passar a usar títulos como “Gatinhas Molhadas preferem GCC”.

Fui um Lobo Noite Passada

Sonhei ontem que tinha sido transformado num lobo, e era engraçado ter um focinho comprido e tantos pêlos pela cara. Havia algum tipo de rinha de bichos que acontecia em galerias de esgoto subterrâneas e eu tive de ir lá ficar num tipo de “jaula de espera”. Por algum motivo tinha de fazer isso por alguns amigos que também tinham virado bichos. Os carcereiros pareciam ser gabirus enormes e eram bem debochados, agiam como se eu fosse prisioneiro, como se eu não estivesse lá espontaneamente, mas quando chegaram perto da jaula agarrei um com os dentes (acho que ele usava uma camiseta) e mostrei um pouco de raiva (controlada). Havia uma loba comigo, e ela estava muito furiosa, latia bastante para os ratos. Uma visão assustadora, mas não me incomodava nem um pouco, tinha uma sensação que ela estava comigo, era algum sentimento de matilha.

Pouco depois estávamos fora, correndo pela cidade. Lembro de pular sobre um banco de praça, parar um instante e continuar correndo. Havia outros, mas eu não via. Acho que a loba era uma pessoa também, mas estava tão satisfeita como loba que pensei que ela esqueceria disso uma hora ou outra. Eu por outro lado lembrava que era humano, embora estivesse curtindo muito esse negócio de ser lobo.

Lobo
(Canis Lupus)

A sensação de estar num corpo muito diferente do seu é interessante.

Onde Está Minha Mente

Numa das intermináveis discussões sobre o que existe e o que não existe no universo, Luciano, um auto-reputado ateu ortodoxo, e eu discutíamos sobrevivência da mente após a morte do corpo.

No primeiro ponto de vista a mente é uma função do corpo e morre com ele. Sendo uma função do corpo está sob todas as leis físicas do universo e sendo assim, se tivermos dados sobre o estado inicial do cérebro e conhecermos todas as regras, podemos calcular o pensamento que vai estar passando pela cabeça que contém o tal cérebro. Com mais dados e mais regras podemos fazer isso com qualquer cérebro, com sociedades inteiras, civilizações. Enfim, isso significa que sua opinião sobre este post e o próprio post são totalmente previsíveis, então nem se dê ao trabalho de escrevê-la… se bem que eu me dei o trabalho de escrever esse post, então não tenho moral pra falar nada.

No ponto de vista número dois a mente pode existir sem o corpo. Nesse caso uma coisa externa a um sistema físico dá ordens à esse sistema. A mente pensa algo, comandos são enviados ao corpo via sistema nervoso e temos algo que poderia ser considerado telecinese.

Onde está a mente?

O Rapaz Sem Cérebro

O pediatra e pesquisador John Lorber, da Universidade de Shefield, ao submeter um rapaz à tomografia computadorizada descobriu que ele tinha 1 milímetro de tecido cerebral pesando 50 a 150 gramas, em lugar dos 4,5 centímetros e 1,5 kg habituais. Era um caso de hidrocefalia – e o que faltava de seu cérebro estava preenchido com líquido cefalorraquidiano, que normalmente funciona como um “amortecedor”. A cabeça dele era um aquário de pensamentos.

E agora que você já começou a pensar sobre a capacidade intelectual do sujeito, saiba que ele tem um QI de 126, se graduou com honras em matemática, e possui uma vida social regular.

Esse tipo de fato complica ainda mais a pergunta “onde está a mente?”, mas se me perguntare vou preferir ser uma mente telecinética do que um marionete de um universo mecanicista sem propósito. E pra acabar com música, fecho com Pixies (na versão do Placebo pro filme Clube da Luta):

“With your feet in the air and your head on the ground
Try this trick and spin it, yeah
Your head will collapse
But there’s nothing in it
And you’ll ask yourself

Where is my mind
Where is my mind
Where is my mind”

Refs:

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

Dragando e Dropando com PyGTK

Liberei mais uma versão (0.7, “O Domo de Arminus”, e o instalador para windows só depois do carnaval quando poderei usar os windows da escola) de TagMap, com algumas funcionalidades novas: salvar/carregar trilhas desenhadas no mapa; exportar trilhas para html (exemplo); e arrastar itens da lista de locais para o mapa muda o foco para o local largado.

Sobre o drag-n-drop, trata-se de arrastar um item de TreeView para um Viewport (veja foto), e isso precisou de mais cuidados do que eu esperava. Primeiro é preciso definir a fonte e alvo do arrastar e soltar, além dos tipos de dados que poderão ser enviados:

treeview.drag_source_set(gtk.gdk.BUTTON1_MASK,

[('text/plain', gtk.TARGET_SAME_APP, 1)],
gtk.gdk.ACTION_COPY)

viewport.drag_dest_set(gtk.DEST_DEFAULT_MOTION |

gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP,
[('text/plain', gtk.TARGET_SAME_APP, 1)],
gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_COPY)

Um callback é definido para o treeview preparar os dados:

treeview.connect('drag-data-get', self.drag_data_get_cb)

(...)

def drag_data_get_cb(self, treeview, context, selection, info, timestamp):

treeselection = treeview.get_selection()
model, iter = treeselection.get_selected()
selection.set('text/plain', 8, model.get_value(iter, 2))

E outro para o quando o destinatário recebê-los:

viewport.connect('drag-data-received', self.place_data_received)

(...)

def place_data_received(self, widget, ct, x, y, selection, info, timestamp):

self.processa_dados(selection.data)

Falei por alto só pra mostrar (inclusive pra mim mesmo depois que esquecer) um quadro geral de drag-n-drop dentro de uma mesma aplicação. Essas coisas estão bem melhor explicadas em:

Além do código do TagMap.

Aventuras no Cairo

Alguns dias atrás comecei a mexer na muito falada (e que será adotada pelo Firefox) biblioteca de desenho vetorial Cairo, com o propósito de fazer um widget em PyGTK representando um heptágono cujos vértices pudessem ser movidos. Eventualmente passei um tempo aprendendo o básico até estancar num problema irritante, que pra variar tinha uma solução simples.

Heptágono

Para criar meu widget, chamado ValueWheel, precisei extender GtkDrawingArea e criar meus próprios métodos para interceptar alguns eventos, como “expose-event”, que acontece toda vez que uma janela, ou parte dela, precisa ser redesenhada. Quando clicava numa das bolinhas nos vértices e a arrastava, meu método que cuidava do “motion-notify-event” reposicionava a tal bolinha e redesenhava tudo. O grande problema é que esses redesenhos estavam muito lentos, com direito a piscada e tudo.

Bastante tempo depois, procurando no Google Code Search, descobri que o jeito certo de fazer a coisa não era ordenar o redesenho diretamente, e sim forçar a emissão do evento expose. Coloquei essas quatro linhas no método de movimento:

alloc = self.get_allocation()
rect = gtk.gdk.Rectangle(0, 0, alloc.width, alloc.height)
self.window.invalidate_rect(rect, True)
self.window.process_updates(True)

Era necessário apenas “invalidar” a área que foi redesenhada e avisar que um update era necessário, que magicamente o widget se redesenhou e sem piscar.

Aos interessados em Cairo eu recomendo:

E o código sobre o qual este post fala é esse: ValueWheel.py

TagMap aceito pela comunidade Tagmar

Ontem conversei com Marcelo Rodrigues, um dos criadores do Tagmar original (fato que eu esqueci, e que foi seguido por uma gafe; shame on me!) e líder do projeto Tagmar 2. Ele me propôs tornar o TagMap parte do projeto Tagmar 2, com direito à link na página e tudo mais. Claro que achei excelente!

Marcelo lembrou que as licenças do TagMap (GPL) e do Tagmar 2 (Creative Commons Atribuição-Uso Não-Comercial-Compatilhamento) são incompatíveis, pois a GPL permite a comercialização e a outra não. Contudo, lembrando o caso da Id Software, que costuma liberar o código fonte de seus jogos como software livre, mas deixando de fora o conteúdo do jogo (fases, monstros, objetos, etc), chegamos a conclusão que podemos lançar o TagMap seguindo os rigores da lei mantendo ele como GPL e deixando claro os direitos e a licença sobre as imagens e textos vindas do projeto Tagmar 2.

Seja como for, só depois do carnaval.

TagMap 0.6

Mais um release do TagMap, com uma quantidade expressiva de alterações.

captura_da_tela-tagmap-mapa-interativo-de-tagmar.png

Uma das novas funcionalidades é a lista (com busca) de locais, que pode ser vista à esquerda no screenshot. Ainda faltam outras funcionalidades e sobram alguns bugs, mas está bastante usável, então sinta-se livre para me dizer os defeitos ou novas idéias.

Downloads para windows (depois um pacote pra Debian/Ubuntu):

“Deployment” em Windows com Py2Exe e NSIS

Deployment segundo a wikipedia:

Software deployment é toda atividade que torna um sistema de software disponível para uso.

Como o TagMap é feito em Python+GTK, e pelo que vi o público interessado é composto majoritariamente de usuários de windows, pedir que eles instalem Python, GTK+ e PyGTK pra só então chegar em meu humilde programa, certamente seria uma barreira. Claro que tem o excelente All-in-one PyGTK for windows installer, mas se dá pra facilitar por quê não?

As duas ferramentas necessárias são o Py2Exe, responsável por tornar o script um legítimo executável, e o NSIS, que serve para criar instaladores next-next-finish e que vai fazer todo mundo te olhar como gente grande. ;P

Py2Eexe

O Py2Exe cria o executável a partir de um arquivo de configuração, no caso do TagMap foi o setup_win32.py. Observando o arquivo você verá que não é muito complicado, só substituir alguns valores e pronto; claro que mudanças maiores vão exigir algum estudo, mas se o seu projeto for em PyGTK com Glade pode pegar o meu e apenas trocar os valores (como eu mesmo fiz ;) ).

No prompt do DOS (ugh!) e no diretório do programa execute:

python setup_win32.py py2exe

Depois de algum trabalho por parte do script será gerado um diretório dist contendo (no meu caso) tagmap.exe, alguns DLLs e outros arquivos. Para executar em qualquer computador basta instalar antes GTK, mas ele também pode ser embutido.

Uma bom código para observar e aprender (e copiar) é o do GAJIM.

NSIS

Com o MakeNSIS que vem com o Nullsoft Scriptable Install System você pode ler um script que descreve o roteiro das perguntas feitas pelo instalador next-next-finish. Claro que ninguém vai ler só apertar o botão insistentemente até chegar no final. Meus scripts são o installer.nsi e installer_gtk.nsi, ambos podem ser facilmente adaptados para outros projetos. Como o nome deve indicar, o segundo script cria um instalador que coloca o GTK junto com o programa, pode parecer um desperdício de espaço, mas com as conexões rápidas e os HDs grandes de hoje em dia esse é um problema muito menor que mandar o usuário baixar um monte de dependências manualmente.

Bem, não tem muito mais o que explicar, até porque ainda estou aprendendo, mas um tutorial completo e direto pode ser encontrado em PyGTK and Py2Exe HowTo.

E os instaladores do TagMap (numa versão muito alfafa) pra windows, com e sem GTK:

P.S.: Um agradecimento especial pra minha gatinha que pacientemente me ajudou a testar. :*