MaginBook sem a infra do Lackey

Mudei de idéia em relação a usar a infraestrutura do LackeyCCG.

Optei por implementar um plugin que dado uma lista de siglas de sets de Magic, acesse um site e carregue as informações dos cards, gravando-as num banco de dado SQLite. Foi uma escolha mais divertida.

Outra vez a biblioteca BeautifulSoup foi incrível. Navegar na árvore de tags HTML e extrair os dados é moleza com ela.

Glade, Mac OS e MaginBook

Ora, as coisas não poderiam ficar melhores. Depois do trabalho de pesquisa que estava tendo para fazer certas coisas com Gtk, descobri que seria possível utilizar o Glade no Mac OS X. Baixei o binário e problema resolvido.

O trabalho é devagar, pois procuro o melhor jeito para desenvolver o MaginBook. Além de um tutorial ou outro sobre Gtk e Glade, consegui um exemplo inesperado, um organizador de decks e cards feito em Python com Gtk! O criador do Magiclibrary escreveu um comentário num post anterior sobre este assunto. Fui atrás dos códigos-fonte da aplicação para saber como ele resolveu certas coisas. O bacana é que ele também utilizou o Glade como ferramenta para montar a interface gráfica.

Só lembrando a vocês que só vou disponibilizar o código da aplicação quando ela estiver conseguindo baixar a descrição das cartas e suas imagens.

Além do mais, é importante salientar que vou usar a infra-estrutura de plugins do LackeyCCG, onde já se fornece praticamente tudo: informações sobre blocos, edições, descrição das cartas e imagens.

Organizador de Decks em Python

Tenho um Nokia N800 que está parado deste que resolvi adotar uma agenda não-eletrônica. O fato do tablet não ter uma bateria de uma boa duração, muitas vezes não tinha a agenda disponível quando realmente precisava.

Bom, desde então fiquei pensando numa maneira de torná-lo útil novamente. Como eu jogo Magic The Gathering, um jogo de cartas colecionáveis, seria interessante ter uma lista de cartas e decks sempre à mão.

As funcionalidades que pretendo implementar para este organizador de decks, que chamarei de Maginbook:

  • Pesquisa de cartas
  • Download de novas cartas
  • Criar e baixar decks da Internet
  • Exportar decks para programas como MWS, LackeyCCG e Apprentice
  • Cotação das cartas

Eu comecei a testar as bibliotecas necessárias para este trabalho. Depois publico o código em algum repositório. Haverá duas versões: uma para Linux/Mac e outro para o Nokia N800 e outros tablets da linha.

DiceDnd 1.1

Depois de um final de semana complicado e acamado, voltei a escrever na segunda-feira os melhoramentos do DiceDnd. Pretendia melhorar o visual, habilitar o modo fullscreen e ainda fazer um pacote debian para distribuir o programa. Devido às dificuldades encontradas, fiquei somente no melhoramento visual. Pois bem, tirei umas fotos do aplicativo funcionando (não descobri uma função print screen no N800) e ainda estou disponibilizando uma nova versão abaixo.

Vou ficar devendo o fullscreen e o pacote.

DiceDnd no Nokia N800
DiceDnd no Nokia N800
DiceDnD com o resultado da jogada de dados
DiceDnD com o resultado da jogada de dados

fonte do dicednd.py (atualizado)

#!/usr/bin/python2.5

import osso
import gtk
import hildon

def labela(texto):
    fonte = '%s'
    etiqueta = gtk.Label(fonte % texto)
    etiqueta.set_use_markup(True)
    return etiqueta

def string_jogada(vezes, dado, soma):
    if soma > 0:
        sinal = '+'
    elif soma == 0:
        sinal = ''
    else:
        sinal = '-'
    return '%dd%d%s%s' % (vezes, dado, sinal, abs(soma) or '')

class DiceDnD(hildon.Program):
    def __init__(self):
        self.dado_atual = 0
        self.vezes = 0
        self.soma = 0
        hildon.Program.__init__(self)
        self.window = hildon.Window()
        self.window.set_title('DiceDnd')
        self.window.set_border_width(40)
        self.window.connect("destroy", self.quit)
        self.add_window(self.window)

        tabela = gtk.Table(5,4,False)
        self.window.add(tabela)        

        self.dado4 = gtk.Button()
        self.dado4.add(labela('4'))
        self.dado6 = gtk.Button()
        self.dado6.add(labela('6'))
        self.dado8 = gtk.Button()
        self.dado8.add(labela('8'))
        self.dado10 = gtk.Button()
        self.dado10.add(labela('10'))
        self.dado12 = gtk.Button()
        self.dado12.add(labela('12'))
        self.dado20 = gtk.Button()
        self.dado20.add(labela('20'))
        self.botaoMais = gtk.Button()
        self.botaoMais.add(labela('+'))
        self.botaoMenos = gtk.Button()
        self.botaoMenos.add(labela('-'))
        self.botaoJogar = gtk.Button()
        self.botaoJogar.add(labela('Jogar'))
        self.frame = gtk.Frame()
        self.montagem = gtk.Label('Jogada')
        self.frame.add(self.montagem)
        
        tabela.attach(self.dado4,0,1,0,1)
        tabela.attach(self.dado6,1,2,0,1)
        tabela.attach(self.dado8,2,3,0,1)
        tabela.attach(self.dado10,0,1,1,2)
        tabela.attach(self.dado12,1,2,1,2)
        tabela.attach(self.dado20,2,3,1,2)
        tabela.attach(self.botaoMais,0,1,2,3)
        tabela.attach(self.botaoJogar,1,2,2,3)
        tabela.attach(self.botaoMenos,2,3,2,3)
        tabela.attach(self.frame,0, 3, 3, 4)
        
        self.dado4.connect('clicked',self.preparar,4)
        self.dado6.connect('clicked',self.preparar,6)
        self.dado8.connect('clicked',self.preparar,8)
        self.dado10.connect('clicked',self.preparar,10)
        self.dado12.connect('clicked',self.preparar,12)
        self.dado20.connect('clicked',self.preparar,20)
        self.botaoMais.connect('clicked',self.incrementar,1)
        self.botaoMenos.connect('clicked',self.incrementar,-1)
        self.botaoJogar.connect('clicked',self.mostrar)
        
        self.window.show_all()
        
    def mostrar(self, button):
        if self.dado_atual == 0:
            return
        import random
        total = 0
        for i in range(self.vezes):
            total += random.randint(1,self.dado_atual)
        total = total + self.soma
        jogada = string_jogada(self.vezes, self.dado_atual, self.soma)
        self.show_message('%s' % total)

    def preparar(self, button,valor):
        if valor  self.dado_atual:
            self.dado_atual = valor
            self.vezes = 1
            self.soma = 0
        else:
            self.vezes += 1
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))
            
    def incrementar(self, button,valor):
        self.soma = self.soma + valor
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))


    def show_message(self, message):
        dlg = hildon.Note('information', (self.window, message))
        dlg.run()
        dlg.destroy()
        #pango_markup = '%s\n%s' % ('DiceDnD', message)
        #hildon.hildon_banner_show_information_with_markup(gtk.Label(''), None, pango_markup)

    def quit(self, evt):
        gtk.main_quit()
        
    def run(self):
        gtk.main()

def main():
    prog = DiceDnD()
    prog.run()

if __name__ == "__main__":
    main()

A Árvore dos Sonhos

Vivemos num mundo sem fantasias, não é mesmo? Elas são produzidas por mãos humanas, enlatadas e só permanecem dentro de uma TV, um computador ou um livro. Quantas pessoas hoje contam histórias fabulosas sobre dias de outrora? Aqueles dias em que o mágico vinha a nós de surpresa?

Na infância, eu encontrei uma fada, num riacho de chuva de inverno, embaixo de um bueiro de ferrovia. Estava sozinho, sentindo tão plenamente a natureza cheia de vida, que ofuscava meus olhos e meus sentidos, e , ao mesmo tempo, via tudo tão claramente. As cores estavam mais vivas, mais profundas. A luz refletida no orvalho da manhã era pleno de uma energia que eu não compreendia.

Sentei numa pedra úmida e reta. Rabiscava o chão molhado com um graveto e não sei no que pensava naquele momento. Coisas de criança, talvez. Mas então, ouvi um chorinho baixo que vinha do túnel por onde as águas corriam. Era de menina, isso eu logo percebi. O que faz aí? Não tem medo de cobras? Eu estava realmente aflito, ali era um lugar escuro e perigoso. Não era um lugar para meninas. Meninas só andavam pelas calçadas da rua.

– Eu não sou uma menina, sou uma ninfa. A voz doce, pequena e sublime que voou da escuridão, como uma brisa cheirando a chuva, balançou meu coração. Ainda não a tinha visto, mas já sabia que a dona daquela voz era linda. Nenhuma menina na rua que eu conhecia tinha aquela voz. Nem na cidade, podia ter certeza até. Se ela era uma ninfa, eu queria ver.

– Porque está chorando? O que te fizeram?  Perguntei, com o coração apertado.

– Vão destruir meu lar. Amanhã.

– Onde você mora? Saia daí, deve estar bem molhado aí?

Nossa! Quando ela mostrou sua face diante da luz da manhã eu implorei aos anjos que não me tirassem a visão. Que sempre me permitissem acompanhar aquela menina graciosa correndo nos campos de inverno do sertão. Ela estava ali diante de mim com olhos miúdos, castanhos e úmidos, um nariz fino e pequeno refletindo uma inocência tamanha que chegava a ser mágica. Os lábios eram finos, tristes; aos vê-los senti vontade sem tamanho de salvar sua casa.

Era menor que eu, vestia uma blusa de couro sem mangas e uma saia de tecido grosso de algodão. Os pés estavam descalços e pisavam no desenho que fiz ali.

—–

A minha sugestão é que continuem a estória, um pequeno capítulo por vez a cada de um de vocês. Feliz Natal.

Python for Unix and Linux System Administration

Estou lendo o livro Python for Unix and Linux System Administration e estou gostando muito, por isso estou aqui escrevendo sobre ele.

Este livro da editora O’Reilly, escrito por Noah Gift e Jeremy M. Jones é uma coleção de problemas-solução em Python. Nele você encontra de quase tudo. Seu lançamento recente (Agosto de 2008) contempla as novidades do Python 2.5, apesar de já estamos com Python 2.6 pronto para instalarmos em nossas máquinas.

Ele está voltado para administradores de sistemas que precisam resolver problemas recorrentes e repetitivos e necessitam de uma ferramente ágil e completa. Python pareceu ser a escolha adequada, apesar dos autores confessarem que a escolha ter sido bem subjetiva.

Ao ler suas páginas fica claro que  o material contido nele serve para todos os programadores. É uma forma maravilhosa de conhecer bibliotecas e funções nunca antes utilizadas por nós, ou descobrirmos novas formas de fazer as coisas com as que já conhecíamos (eu descobri).

Logicamente, tem coisas que são quase exclusivamente para administradores de redes e nos deleitamos como tarefas complexas podem ser resolvidas em poucas linhas de código. Sinaliza também o fato de que a vida de um administrador de redes já é dura e não precisa ficar pior. Desenvolver suas próprias ferramentas em Python é algo prazeroso.

Há um maravilhoso capítulo chamado Package Management explanando coisas como Setuptools e os Python Eggs, os ovos de cobra, os conhecidos arquivos de distribuição. Só por este capítulo eu compraria o livro.

E tem mais. Sobre persistência de dados, temos o simples shelve, o ZODB, SQLite, Storm ORM e SQLAlchemy. É uma aula de atualidades do mundo Python.

Há coisas que já li a respeito mas não me aprofundei, como, por exemplo, Buildout, Twisted, Scapy, entre outros.

Vou continuar lendo. Leitura recomendada.

TurboGears 2: solução de problemas durante a instalação

Pediram-me para documentar a instalação do TurboGears 2. Vocês podem encontrar os passos para a instalação aqui.

O restante deste post é sobre como solucionar certos problemas. Então, se você seguiu a documentação oficial e não teve problemas não precisa mais ler este post.

É bom salientar que fiz a instalação no Ubuntu Linux.

Installing TurboGears 2 from Source

Nesse ponto, quando vocês forem instalar o tg2 com python setup.py develop, vocês não encontrarão o arquivo setup.py. Ocorre que agora o tg2 usa o paver como instalador. Ou seja, documentação desatualizada. Na raiz de tg2 execute sudo paver develop.

Pode ser que durante o download das dependências do tgdev, não seja encontrado a versão 0.8.7dev do ToscaWidgets. Se este for o caso, é melhor você esperar um tempo para eles disponibilizarem-na e então sincronize a cópia de trabalho com svn update. Depois, execute novamente sudo python setup.py develop.

Concluídas as demandas, você já pode brincar com o TurboGears 2. Comece pelo Wiki em 20 minutos.

Estou querendo instalar o TG2 no Windows, então os problemas que possa encontrar vou colocar como comentário aqui.

Primeiro contato com TurboGears 2

Como o Twitter não está muito bem, vai ser por aqui mesmo que informo aos amigos e colegas pythonistas que tive pela primeira vez contato com o TurboGears 2 hoje. Acabei de fazer o exemplo da Wiki.

Aos poucos, devo começar a me aprofundar no uso dele, uma vez que estamos pensando em adotar o framework para o desenvolvimento de um projeto. Queremos que nossa aplicação acompanhe o desenvolvimento do TurboGears, mesmo que isso seja arriscado.

Tive um razoável trabalho para instalá-lo na minha máquina. O trabalho não se deveu ao fato de tê-lo de obter via Subversion, mas sim porque alguns pacotes não estavam sendo encontrados pelo easy_install. Também precisei usar o Paver para baixar umas dependências. Isso a documentação de instalação não explicou. Devo fazer a instalação também no notebook do Stênio. Não anotei nada, espero conseguir.

Apesar dele manter a API bastante semelhante ao TurboGears 1, há componentes novos. A curiosidade foi aguçada por conta disso. Estava tão por fora, que somente agora fiquei sabendo sobre o Paver, criado pelo próprio Kevin Dangoor. Parece-me um melhoramento sobre o processo de instalação/distribuição/empacotamento.

Deixemos para outros posts demais conclusões sobre o TG2.

O cárater Microsoft

Deve ser gostoso continuar sendo usuário do sistema operacional Windows mesmo sabendo dos meios sujos de como a Microsoft trabalha. Há muito deixei de lado o Windows e sou um usuário fiel do Linux. Tenho notebook e computador em casa. Rodam com Ubuntu Linux. No computador da casa dos meus pais, também roda Linux. Então, leia isso e veja se você pode ficar indignado. Eu fiquei.

Para meus amigos que desejam experimentar Linux, estou oferecendo suporte de seis meses gratuito. Só mesmo para aumentar o número de usuários Linux.

Não sou xiita, só acordei de mau-humor.

Receita Federal e a compra do Office 2007

Nos dias atuais, um órgão público ainda querer fazer licitação do Office 2007, quando há soluções facilmente mais baratas, é lamentável. O OpenOffice está aí, no mercado, um conjunto de ferramentas muito parecidas com o pacote da Microsoft. Será que vão continuar com esta sandice? Vão comprar cerca de 44 mil licenças que irá custa ao Estado uns 40 milhões de reais?

Lamentável, senhores da Receita.

Fonte: Convergência Digital