How many time mates?
Nesse post vou mostrar como criar o mais simples plugin no Rhythmbox. Vou narrar meu passo a passo nessa odisseia.
Tudo começa no lastfm, alguns de vocês talvez saibam o que é isso. O Lastfm é um site, rede social para amantes de música. Nele você tem seus amigos, vizinhos que são listados com base no grau de afinidade musical e claro tem uma lista com as músicas e bandas que você mais ouve, está ouvindo ou já ouviu. O Rhythmbox atual já vem com um plugin do lastfm que quando você ativa pode marcar as suas músicas favoritas e ter uma lista de bandas similares, etc. Todo esse plugin foi feito claro com a API do last que se encontra totalmente disponível para que você brinque. Mas o ponto não é usar a API do lastfm e sim usar alguém que já usa este recurso. “Como assim Kirotawa?”. Vou explicar, existem inúmeros recursos oferecidos por terceiros no last um deles é adicionar gráficos das bandas mais ouvidas por nomes ou gênero. Veja esse exemplo abaixo:
O que estes recursos fazem é calcular através do seu login do lastfm os estilos musicais que mais gosta (a imagem acima) e criar um link para uma imagem com o gráfico. Feito isso tudo que você tem a fazer é copiar o link e adicionar no seu perfil e páh! Esta feito.
Agora vamos entender o que o meu simples plugin faz, quais os recursos que eu usei e como ele funciona. O site que gera a imagem que vai pro meu plugin é esse aqui sivy.net. Este site gera uma imagem, neste caso, com a capa dos cds dos artistas que mais escuto, o top 10. Gerando um link que se posto no lastfm mostra a imagem. Até aqui tudo bem. O problema é que este site cobra para ficar atualizando, ou seja, se você quer que a imagem mude sempre você terá de pagar ou ficar atualizando na mão. Eu até sou a favor de pagar, mas sou liso e queria que a minha imagem se atualizasse sem eu ter que pagar. Como eu sabia exatamente como fazer isso, crawleando o site e pegando o link e depois só teria que injetar no lastfm, bem, não deu muito certo. Primeiro tentei fazer isso usando o GAE (google app engine) como intermediário, mas graças ao tempo que o sky.net leva para gerar a imagem, mais de 5/10 segundos, o GAE me xinga e não resolve o meu problema, pois dá time expired. Usei o urllib open, depois o urlfetch do próprio GAE e nadas! Foi então que desisti de fazer um webcrawler pra por a imagem atualizada no meu lastfm =/ e pensei – horas bolas porque não tacar isso no rhythmbox. Foi o que fiz. Mas antes vou descrever tudo que fiz, alguns passos devem ser inúteis, mas eu precisava testar cada um deles, eu simplesmente gosto de ver como as coisas funfam ;).
Passos.:
1) Usei uma bazuka para matar uma mosca. Como o sky.net faz post dos dados eu precisava saber o que tanto ele passava para poder preencher o form do jeito certo. Para descobrir isso eu apelei ao wireshark um sniffer que me mostra todos os dados que estão sendo passados por post. Bastou usar esse filtro: http.request.method == “POST”. Assim eu pude ver tudo que era necessário a ser passado no form e páh, só precisei nomear as variáveis e preencher elas em um dicionário.
values =
{
'nick':'kirotawa','type':2,'period':'3month','count':10, 'align':1,
'font':20,'font_zoom':100,'generate':'Generate', 'colortext':'0;0;0',
'colorbackground':'255;255;255'
}
2) Criar o webcrawler usando o urlopen e o BeautifulSoup. Deem uma lida neste blog e vão saber do que estou falando.
3) Com o link para a imagem eu só precisei salvá-la ou usar o link e carregar ela no pixbuf do gdk (como eu já testei e deu paw quando tento carregar ela via url no pixbuf eu preferi salvá-la). A mágica para fazer ela, a imagem, ser sempre atualizada com minha lista, é gerar uma nova imagem sempre que entro no rhythmbox pela primeira vez. “Como você fez isso?”. Usei a força, joguei a imagem salva na pasta /tmp e pronto :P. Ele só gera uma vez a cada entrada no rhythmbox pela primeira vez após login. Porém isso tem um custo, um preço caro. Como disse antes o sivy.net é lento, logo a resposta pro urllib é lenta, logo o rhythmbox fica ? LENTO, isso se não trava. Pesquisando achei algo falando de um tal de rb.get_url, mas a documentação do rhythmbox é pobre e não me ajudou muito, por isso o plugin vai ficar lento por enquanto até que eu descubra como esse trem (get_url) funciona. Afinal eu preciso passar tudo via post, recuperar o html todo e filtrar só minha IMAGE_URL.
Finalizando, o plugin não é lá essas coisas, é o mais simples e burro, mas tive de revisar tanta coisa e estudar outras (GAE, urllib, BeautifulSoup, gtk, gdk ) que valeu muito a pena. Segue abaixo o código do meu plugin :P.
import os
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup
from gi.repository import GdkPixbuf, GObject, RB, Peas, Gtk, Gdk
IMAGE_PATH = "/tmp/top10.jpeg"
class Load(object):
''' Class load and make the low level that is necessary '''
url = "http://lastfm.sivy.net/?do=albumForm-submit"
values = {
'nick':'login_here','type':2,'period':'3month','count':10, 'align':1,
'font':20,'font_zoom':100,'generate':'Generate', 'colortext':'0;0;0',
'colorbackground':'255;255;255'
}
def __init__(self):
data = urllib.urlencode(self.values)
request = urllib2.Request(self.url, data)
response = urllib2.urlopen(request)
document = response.read()
soup = BeautifulSoup(document)
image = soup.find('textarea').contents[0]
image = image.split('[img]')[1].split('[/img]')[0]
file_image = open(IMAGE_PATH,'wb')
file_image.write(urllib.urlopen(image).read())
file_image.close()
class Top10Plugin(GObject.Object, Peas.Activatable):
object = GObject.property(type=GObject.GObject)
def __init__(self):
super(Top10Plugin, self).__init__()
if not os.path.exists(IMAGE_PATH):
Load()
def do_activate(self):
shell = self.object
self.image = Gtk.Image()
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file (IMAGE_PATH)
self.image.set_from_pixbuf(self.pixbuf) # , 175, 328)
self.container = Gtk.VBox ()
self.container.pack_start (self.image, True, True, 6)
shell.add_widget(self.container, RB.ShellUILocation.RIGHT_SIDEBAR, False, True)
self.container.show_all()
def do_deactivate(self):
shell = self.object
shell.remove_widget(self.container, RB.ShellUILocation.RIGHT_SIDEBAR)
self.image = None
self.pixbuf = None
self.container = None
O que faz o plugin…
Read Full Post »