Depois que fiz uma aplicação em Python pra enviar #FF pras pessoas que sigo, recebi alguns pedidos pra mostra um HOWTO ou algo parecido. Como foi um procedimento bastante longo de se descrever, resolvi seguir o modelo "Jack estripador" e mandar em partes:
Pode parecer um certo exagero, mas é que precisei adaptar várias coisas tanto na parte 1 quanto na 3. Se eu descrever tudo de uma vez só, vai ficar muito, mas muuuuuuito longo.
Agora falando um pouco sobre python-twitter, esse é um módulo (ou classe) pra conectar no Twitter (duh!). A versão que está nos respositórios do Debian/Ubuntu é ainda a antiga, 0.6, que partia do princípio que a autenticação no twitter se fazia através de username e password. Atualmente o Twitter usa uma forma mais rebuscada, pra evitar o envio desses por meios não seguros e possível roubo de identidade, utilizando um método de token. Você cria uma aplicação com um registro no Twitter e o mesmo pede autorização ao usuário pra se conectar em sua conta. Irei comentar melhor isso na parte 2.
Voltando à instalação no Debian/Ubuntu, que no momento em que escrevo estão nos releases 6.0.1 (Squeeze) e 10.10 (Maverick Meerkat), é preciso baixar o python-twitter, que está na versão 0.8.1, a partir do projeto em:
Essa versão de python já traz o novo método de autenticação baseado em oauth2. E falando nesse, o oauth que vem em Debian/Ubuntu também está desatualizado e não funiona com essa versão nova do Twitter que exige tokens. Então é necessário baixar a versão do site e instalar:
Eu baixei a versão 1.5.167 e funcionou corretamente por aqui.
Eu já previamente deixei esses pacotes disponíveis aqui, mas com arquitetura i386. Mas deixei também os fontes pra gerar os pacotes.
Se você tiver os pacotes build-essential e dpkg-dev, deve bastar pra iniciar a instalação. Basta descompactar o arquivo tar.gz utilizando o dsc, como por exemplo:
dpkg-source -x -b python-twitter_0.8.2.dsc
Isso criará o diretório do pacote, no caso python-twitter-0.8.2. Em seguinda basta entrar nesse diretório e gerar o pacote:
dpkg-buildpackage
Isso criará o pacote DEB na sua arquitetura.
Um olhar mais minuscioso notará que estou fornecendo o pacote 0.8.2 do python-twitter, que não existe no repositório ainda. Esse pacote contém uma atualização minha :-)
Com tudo isso instalado, já é possível testar se o python-twitter está instalado corretamente e na versão correta:
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import twitter
>>> twitter.__version__
'0.8.2'
Se ao invés disso você tiver a versão 0.8.1, a corrente do site, a maioria das coisas que fiz funcionarão, exceto a listagem de seguidores (followers).
Como alguém já disse antes: nem todo restart é bom.
Mas infelizmente isso é necessário em alguns momentos. E meu roteador wireless Netgear WGR614 v7 chegou nesse ponto. Diariamente ele exige um leve "restart" pra poder funcionar direito na parte wireless, do contrário nada consegue se conectar nele: notebook, netbook, xbox360, celulares...
Deve ser alguma feature chinesa pois todos os produtos de lá padecem do mesmo mal, que sempre começa a aparecer depois de mais de 1 ano de uso. Deve ser uma estratégia de marketing pra nos forçar a fazer um upgrade. Igual ao Windows.
Mas voltando ao problema e sua solução, resolvi partir pra um restart automático (restart do bom, pra deixar claro). Então primeiramente descobri que o roteador faz um restart ao salvar as configurações de wireless. Em seguinda utilizei o Add-on do firefox, Live HTTP Headers, que ajudou a capturar os dados enviados ao equipamento:
POST /wlg_adv.cgi HTTP/1.1
Host: 192.168.34.1
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://192.168.34.1/WLG_adv.htm
Authorization: Basic ZnVjazp5b3U=
Content-Type: application/x-www-form-urlencoded
Content-Length: 60
enable_ap=enable_ap&ssid_bc=ssid_bc&enable_wmm=0&Apply=Apply
O router exige autenticação, o que pode ser visto pela entrada "Authorization: Basic ZnVjazp5b3U=", que não usa criptografia mas um encode de base 64.
Então criei um script pra fazer o trabalho sujo e enviar os mesmos dados ao roteador, mas em Python.
#! /usr/bin/env python
# Script to restart daily my wireless router
# by Helio Loureiro
import httplib
import base64
import urllib
from time import ctime
user = "admin"
passw = "password"
host = "192.168.0.1"
def GetAuth(user = "user", passw = "passwd"):
auth = user + ":" + passw
return base64.encodestring(auth)[:-1]
headers = {
"Host" : host ,
"User-Agent" : "Mozilla/5.0 (Python)",
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ,
"Accept-Language" : "pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3",
"Accept-Encoding" : "gzip,deflate",
"Accept-Charset" : "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
"Referer" : "http://192.168.34.1/WLG_adv.htm" ,
"Authorization" : "Basic " + GetAuth(user, passw),
"Content-Type" : "application/x-www-form-urlencoded"
}
post_params = {
"enable_ap" : "enable_ap" ,
"ssid_bc" : "ssid_bc",
"enable_wmm" : "0",
"Apply" : "Apply"
}
params = urllib.urlencode(post_params)
web = httplib.HTTPConnection(host)
web.request("POST", "/wlg_adv.cgi", params, headers)
response = web.getresponse()
if (response.status == 200):
print "[" + ctime() + "] Wireless router restarted successfully"
else:
print "[" + ctime() + "] Restart FAILED"
data = response.read()
web.close()
Os dados necessários são usuário, senha e IP do roteador wireless (user, passw e host). Adicionando o script à crontab, o roteador será reiniciado diariamente, aumentando um pouco mais a longevidade de tal produto Chinês.
Pode ser preciosismo meu, mas resolvi criar uma chamada em alguns programas para limpar a tela, ao estilo do comando clear.
Não imaginava por quais veredas inóspitas eu iria entrar...
Primeiramente devo dizer que é fácil fazer uma chamada pra um subshell e utilizar o próprio aplicativo clear.
#! /usr/bin/python
from os import system
system("clear")
Funciona, mas é tosco. E eu queria uma solução "unix like", daquelas que a gente tem orgulho de contar na mesa do bar, no encontro com amigos nerds (afinal serão os únicos que entenderão o que você estava dizendo, o que não significa que vão compartilhar o mesmo sentimento de orgulho que você estava sentindo).
Então mergulhei na biblioteca ncurses. Tentei algumas linhas simples, chamando um método curses.clear().
#! /usr/bin/python
import curses
scrn = curses.initscr()
scrn.clear()
curses.endwin()
Realmente funcionou, mas de uma forma indesejada, não restaurando as propriedades do terminal (você perde a alimentação do cursor, que só é restaurada após utililizar o comando reset).
Então resolvi utilizar o módulo termios para salvar o estado do terminal, e recuperar o mesmo após o método curses.clear(). Ficou um pouco maior do que eu imaginava, mas funcionou muito bem. Agora posso fazer meus scripts Python limparem a tela de uma forma muito elegante.
#! /usr/bin/python
import curses
import termios
from sys import stdin
fd = stdin.fileno()
scr = termios.tcgetattr(fd)
scrn = curses.initscr()
scrn.clear()
termios.tcsetattr(fd, termios.TCSADRAIN, scr)
Ano novo, vida nova. Mudanças no trabalho (de área) e um pouco de férias. Até dia 18, estarei aproveitando meus dias em ócio, um pouco produtivo, espero eu, uma vez que vendi minha prancha de surf e estou esperando uma outra (maior)ficar pronta.
Durante o natal e ano novo, recebi vários SMSs desejando felicidades, etc. Com meu ócio criativo à 1000, resolvi voltar um pouco aos velhos códigos de Python, com Tkinter. Criei uma interface para envio de SMSs em massa, tipo SPAM.
Terrível tentação aos SPAMMERs e melancólico sofrimento para nossos celulares. Mas felizmente utilizei uma interface interna da Ericsson para isso, então somente funcionários poderão utilizar. Fora isso, não pretendo liberar o código externamente. Talvez dentro da empresa, onde já ganhei um relógio com frequencímetro cardíaco devido às minhas contribuições em 2008.
Falando do código, muito simples, utilizando Entry(), Text(), Label() e Button(). Na verdade a facilidade é graças ao Tk mesmo. As fontes das letras anteriormente eram bem *toscas*, assim como o widget, que era todo cinza. Consegui melhorar a aparência do mesmo com o código abaixo:
root = Tk()
root.option_add("*Font", "arial")
root.option_add("*Label.Font", "helvetica 9 bold")
root.option_add("*Background", "gray")
root.option_add("*selectBackground", "light gray")
root.option_add("*selectForeground", "black")
root.config(background="gray")
Estou tentando melhorar o código adicionando um splash screen no início, e outra tela durante o envio, uma vez que ao apertar o botão para enviar, a tela "congela" e só volta ao final. Infelizmente já notei que o Tk é limitado nesse ponto... vamos ver onde chego.
Também depois de *lançamento*, descobri que somente 154 caractéres são enviados. Preciso ver se coloco algum contador pra evitar cortes. Se você recebeu uma mensagem truncada, já sabe: fui eu :-)
E feliz 2009!