Mostrando postagens com marcador dicas. Mostrar todas as postagens
Mostrando postagens com marcador dicas. Mostrar todas as postagens

quarta-feira, 5 de fevereiro de 2014

Dica: Como fazer o Google Hangout Funcionar no Debian

Há algumas semanas instalei o Debian testing em um notebook, porém tive problemas para fazer funcionar o plugin do Google Hangout, que costumo usar bastante para reuniões online, pois trabalho remotamente. Após a instalação do plugin (que é um pacote .deb disponível no site deles) e reiniciar o navegador, ele não consegue identificar que o plugin está instalado e, com isso, não consigo entrar nos hangouts.

Depois de procurar bastante, descobri em uma thread no Google Groups dos produtos da Google e consegui resolver o problema! Parece que o problema estava relacionado a conflitos com os pacotes libudev0 e libcairo2. Para resolver, basta executar os seguintes comandos:

apt-get remove libudev0
wget http://snapshot.debian.org/archive/debian/20130927T214600Z/pool/main/c/cairo/libcairo2_1.12.14-4_amd64.deb
dpkg -i libcairo2_1.12.14-4_amd64.deb

Os comandos devem ser executados como usuário root (diretamente ou através do sudo).

quarta-feira, 2 de junho de 2010

Porque eu adoro o sistema de views do web2py

Vindo de mim, um elogio ao web2py pode parecer tendencioso, já que sou um dos desenvolvedores do framework. Porém uma coisa que me fascinou, mesmo antes de me tornar desenvolvedor, foi a implementação da camada de apresentação (views, do modelo MVC).

No web2py a camada de apresentação é parecida com código PHP: você utiliza a linguagem que precisar para apresentação do conteúdo (HTML, CSS, XML, JavaScript ou qualquer outra que desejar) e pode embutir código Python no meio. A grande sacada - que trás muita simplicidade e flexibilidade ao desenvolvedor - é exatamente o fato de podemos embutir código Python. Com isso, ganhamos inúmeras vantagens:

  • Você não precisa aprender a utilizar uma linguagem de templates nova: é Python - mesma linguagem em que você programa seus models e controllers!
  • Como o código da view pode ser transformado em um módulo Python, a execução da view fica muito mais rápida, pois o web2py a traduz para código Python puro e então o compila para bytecode;
  • Você não fica limitado a uma linguagem restrita (como são as linguagens criadas para a camada de apresentação) - você pode utilizar todo o poder que Python lhe proporciona sempre!
  • Você pode criar qualquer formato de saída para sua camada de apresentação, o que significa que não necessariamente a saída da sua view precisa ser escrita em alguma linguagem de marcação (HTML, XML etc.). Você pode, por exemplo, ter uma view que gera um arquivo JPEG, um texto em RTF, um documento em PDF, um arquivo em CSV e por aí vai;
  • A camada de apresentação está desacoplada das outras camadas, o que significa que uma única view pode servir a vários controllers ou um único controller pode ter como apresentação várias views diferentes em ocasiões diferentes.

Eu poderia citar vários outros exemplos (inclusive da ótima integração da camada de apresentação com as outras camadas do framework), mas as outras dicas ficarão diluídas nos próximos artigos. Porém, não poderia deixar esse artigo sem código. Como todo bom programador, vamos ao que interessa:

Exemplo 1 - View gerando HTML

Digamos que possuímos um sistema de inscrição em eventos e precisamos listar uma tabela com o nome do participante inscrito e assinalar se ele pagou ou não a inscrição. Dessa forma, possuímos um model (por exemplo, models/db.py) parecido com:

db.define_table('participante',
    Field('nome', 'string', length=250),
    # inclua outros campos aqui
    Field('pagou', 'boolean'),
)

Então precisamos de um controller que seleciona os nomes dos inscritos e o estado do pagamento. Vamos chamar esse controller de controllers/usuarios.py:

def tabela_de_pagamentos():
    inscritos = db().select(db.participante.nome, db.participante.pagou,
                            orderby=db.participante.nome)
    return {'nome_e_pagamento': inscritos}

Com isso, nossa view será executada em um ambiente onde a variável nome_e_pagamento existe e seu conteúdo é o que foi retornado pelo controller acima. Vamos então criar uma view que gera HTML para o controller acima. Coloque no arquivo views/usuarios/tabela_de_pagamentos.html:

{{if len(nome_e_pagamento) == 0:}}
Não temos usuários cadastrados! :-(
{{else:}}
<table>
  <tr>
    <td> Nome </td>
    <td> Pagou? </td>
  </tr>
{{
for usuario in nome_e_pagamento:
    if usuario.pagou:
        pagou = 'Sim'
    else:
        pagou = 'Não'
    pass
}}
  <tr>
    <td> {{=usuario.nome}} </td>
    <td> {{=pagou}} </td>
  </tr>
{{pass
pass}}

Tudo o que está entre {{...}} será executado como código Python. Além disso, o web2py inclui algumas novas palavras-chave para ajudar no processo de criação de views, são elas:

  • {{=expressão_Python}}: executa expressão_Python e imprime o resultado no local;
  • {{extend 'arquivo.html'}}: utiliza a view arquivo.html como base para essa view;
  • {{include}}: indica onde outras views que utilizam essa como base serão adicionadas.

Pode parecer estranho acima o uso da keyword pass. Elas estão lá por conta de uma definição no sistema de apresentação do web2py: por conta de espaços na camada de apresentação fazerem diferença, seria complicado em todos os casos o programador manter a endentação correta do código.
Para resolver esse problema o web2py então gera um novo código baseado em nossa view, ignorando a endentação que utilizamos - ele auto-endenta o código quando encontra if, for etc. Para voltar um nível, como a endentação na view é ignorada, precisamos utilizar a palavra reservada do Python pass. Note que essa palavra reservada faz parte da linguagem e sua função é apenas "passar" (não executa comando algum) - nesse caso ela serve como um sinal para o web2py voltar um nível na endentação.
Note que como a endentação é feita automaticamente, eu não precisaria ter endentado o código entre {{...}}. Porém nesse caso a endentação não atrapalha o código de retorno da minha view e por motivos de organização deixei o código endentado.

Para o exemplo acima, se acessarmos a URL http://localhost:8000/welcome/usuarios/tabela_de_pagamentos (ou http://localhost:8000/welcome/usuarios/tabela_de_pagamentos.html) teríamos como retorno a view acima processada, como nos dois exemplos abaixo, sem e com dados inseridos na tabela:

View do web2py mostrando tabela de pagamentos vazia
View do web2py mostrando tabela de pagamentos cheia

Nota: utilizei/modifiquei a aplicação welcome (que já vem com o web2py) para fazer esses exemplos.

Exemplo 2 - View gerando CSV

Para os mesmos model e controller acima poderíamos ter uma view que gera um arquivo CSV com os dados, em vez de HTML. Vamos então criar o arquivo views/usuarios/tabela_de_pagamentos.csv:

{{
import cStringIO
csv = cStringIO.StringIO()
nome_e_pagamento.export_to_csv_file(csv)
response.write(csv.getvalue())
csv.close()
}}

Não vou entrar em detalhes do código acima, mas para quem estranhou a presença do objeto response fica a explicação: o web2py, para aumentar a produtividade do desenvolvedor, leva a sério o conceito Don't Repeat Yourself e, por isso, ele mesmo importa automaticamente os objetos de sua API que precisamos utilizar (nesse caso, o objeto response).

Feito o código acima, ao entrarmos em http://localhost:8000/welcome/usuarios/tabela_de_pagamentos.csv será feito o download de um arquivo CSV. Abrindo, teremos:

Arquivo CSV gerado pela view do web2py sendo visto no OpenOffice.org

Como disse acima, poderíamos utilizar outras extensões nas views e gerar quaisquer tipos de arquivos que quisermos com código Python. Em uma aplicação que desenvolvi há alguns meses precisei criar views que gerassem PDF (para relatórios sob demanda) e tudo funcionou perfeitamente.
Espero que os exemplos acima tenham explicitado o poder e flexibilidade que esse sistema de apresentação possui. Dúvidas? Entre na lista brasileira de usuários web2py e perguntem-me lá!

quarta-feira, 14 de outubro de 2009

Onde encontrar documentação do web2py

Muita gente me pergunta sobre documentação do web2py e reclama que o manual "oficial" não é gratuito. A ideia desse post é listar as formas de se obter documentação atualizada sobre o framework. Então, seguem, da mais barata pra mais cara:

A segunda edição do manual ainda não está disponível no Wiley e na Amazon (essas duas só possuem a primeira edição, que não possui informações sobre as novas funcionalidades do framework). Acredito que estarão disponíveis daqui há algum tempo.

Existem também a lista de discussão de desenvolvedores do web2py, porém apenas pessoas convidadas (que contribuíram em algo com o projeto) podem entrar - de qualquer forma, ela é aberta para leitura - e o AlterEgo, o FAQ do web2py (o conteúdo dele será movido em breve para a wiki).

E então, conseguiu encontrar o que estava procurando sobre o web2py? Não? Por quê? Quando conseguir, não esqueça de adicionar uma entrada na wiki. ;-)

--
   Álvaro Justen
   Peta5

quarta-feira, 26 de agosto de 2009

Dicas web2py: lendo e enviando tweets

Esse é o primeiro artigo de uma série que pretendo postar aqui no blog. Nessa "série" Dicas web2py serão postados artigos simples e rápidos para ajudarem desenvolvedores que utilizam o web2py como framework para desenvolvimento Web. Em um futuro não muito distante também estarão aqui pequenos tutoriais para quem ainda está iniciando. :-)

Se você usa o framework para desenvolvimento Web web2py, com pouquíssimas linhas você consegue enviar e receber tweets de maneira bem fácil. Resolvi postar essa dica aqui depois de corrigir alguns bugs no código que foi publicado no AlterEgo (um local onde armazenamos receitas de bolo para o web2py).

Seguindo a dica no AlterEgo dá pra ver que utilizando o simplejson fica fácil! Como o web2py web2py já possui o simplejson por padrão então não precisamos de mais nada!
Segue o código:

#Enviando tweets
def post_tweet(username, password, message):
    from urllib import urlencode
    from base64 import b64encode
    from urllib2 import Request, urlopen
    import gluon.contrib.simplejson as sj
    args= urlencode([('status', message)])
    headers = {}
    headers['Authorization'] = 'Basic ' + b64encode(username + ':' + password)
    request = Request('http://twitter.com/statuses/update.json', args, headers)
    return sj.loads(urlopen(request).read())


#Lendo tweets
def get_tweets(user):
    from gluon.tools import fetch
    import gluon.contrib.simplejson as sj
    page = fetch('http://twitter.com/%s?format=json' % user)
    return sj.loads(page)['#timeline']

Para usar:

#Enviando um tweet:
post_tweet('meu_usuario', 'minha_senha', 'Olá, Twitter! Estou no @web2py...')

#Recebendo tweets do usuário 'web2py':
meus_tweets = get_tweets('web2py')

Depois disso é só retornar meus_tweets na função de seu controller e utilizar na view como quiser. Bem simples, né? O código acessa a API do Twitter através da urllib2 e usa o simplejson para transformar uma string JSON em um dicionário Python.
No caso da função post_tweet temos um dicionário como retorno, que possui dados sobre o tweet enviado (id, data/hora, usuário etc.), já a função get_tweets retorna uma string com os tweets já em HTML.

O código acima já é utilizado no web2py: a interface administrativa (aplicação admin) mostra os últimos tweets do @web2py (procure pela função twitter no controller default.py).

--
   Álvaro Justen
   Peta5 - Telecomunicações e Software Livre

domingo, 12 de julho de 2009

Liberando (bastante!) espaço com o localepurge

Se você tem um netbook com pouco espaço de armazenamento vai entender bem: estava eu ontem procurando arquivos para serem descartados em meu EeePC (que tem meros 4GB em seu SSD) quando me deparei com a situação de que não dava pra remover mais nada em meu diretório home. Desespero? Nada! Ainda tinham os programas que eu poderia desinstalar...que me renderam mais 3MB livres! (?) Antes de eu começar a remover programas que eu realmente utilizava me lembrei que há alguns anos o KurtKraut me recomendou o localepurge.

localepurge é nada mais que um shell script de 227 linhas que remove arquivos de localização/tradução para os softwares instalados de línguas que você não utiliza. Além disso, o pacote Debian do localepurge vem com um arquivo de configuração que faz com que ele seja executado toda vez que o apt rodar, dessa forma ele consegue remover os arquivos desnecessários logo que um novo pacote é instalado. No fim você fica com os softwares que quer e somente com os arquivos de tradução de que precisa!

Gostou? Para instalar, basta:

# apt-get install localepurge

Assim que o pacote for instalado o debconf perguntará quais línguas você quer manter. Em meu caso, selecionei pt_BR e en_US (UTF-8). Após a instalação basta rodar o comando localepurge, como rodei no meu EeePC:

moveeel:~# localepurge
localepurge: Disk space freed in /usr/share/locale: 338416K
localepurge: Disk space freed in /usr/share/man: 4800K

Total disk space freed by localepurge: 343216K

Consegui liberar 335MB de espaço! Pouco? Não para quem tem 4GB de espaço - isso representa praticamente 8,2% do espaço total disponível.

Depois disso só faltou a conexão à Internet funcionar bem para eu instalar o TeXLive e postar aqui no blog, mas como nem tudo é perfeito, só tive acesso agora.

Atenção: como o localepurge não é totalmente integrado ao sistema de gerenciamento de pacotes do Debian a deleção de arquivos de localização pode gerar "warnings", já que alguns arquivos pertencentes aos pacotes não estarão mais lá enquanto "deveriam" estar, então quando for conferir se todos estão lá o Debian (ou derivados) pode reclamar. Mas não se preocupe: a deleção desses arquivos é inofensiva. Porém, se você quiser reinstalar os arquivos removidos dê uma olhada no script que vem com o pacote: /usr/share/doc/localepurge/reinstall_debs.sh.

   Álvaro Justen
   Peta5 - Telecomunicações e Software Livre