import xchat
import feedparser
LASTFM_USER = 'wiliamsouza83'
URL = 'http://ws.audioscrobbler.com/1.0/user/%s/recenttracks.rss' % LASTFM_USER
def do_request(word, word_eol, userdata):
....if len(word) < 2:
........xchat.command('help LISTEN')
....elif not isinstance(int(word[1]), int):
........print 'Second arg must be an int!'
....else:
........rss = feedparser.parse(URL)
........for n in range(int(word[1])):
........xchat.command('me listen %s' % rss['entries'][n]['link'])
....return xchat.EAT_ALL
xchat.hook_command('LISTEN',
...................do_request,
...................help='/LISTEN [number]. Show the latest played track from last.fm.')
quinta-feira, 18 de outubro de 2007
Recently played tracks from last.fm
segunda-feira, 9 de abril de 2007
Django serialization.
Bastante usado em unittest e doctests.
Você pode carregar manualmente usando
wiliam@wiliam:~/dev/myapp$ python manage.py shell
>>> from myapp.purchase.models import Country
>>> from django.core import serializers
>>> f = open('countries.json', 'w')
>>> data = serializers.serialize("json", Country.objects.all())
>>> f.write(data)
>>> f.close()
Você pode carregar manualmente usando
python manage.py loaddata:
wiliam@wiliam:~/dev/myapp$ python manage.py loaddata fixtures/countries.json
Loading 'fixtures/countries' fixtures...
Installing json fixture 'fixtures/countries' from absolute path.
Installed 242 object(s) from 1 fixture(s)
sábado, 31 de março de 2007
Ticket #3882 (closed: fixed)
Já está disponível na versão de desenvolvimento do Django o localflavor BR.
Ticket: #3882
Changeset 4874 e 4908
Ticket: #3882
Changeset 4874 e 4908
quinta-feira, 29 de março de 2007
django.contrib.localflavor.br
Primeira versão implementada, agora vem os teste.
Coisas pra resolver:
O widget
"""
BR-specific Form helpers
"""
from django.newforms import ValidationError
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
from django.newforms.util import smart_unicode
from django.utils.translation import gettext
import re
phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
class BRZipCodeField(RegexField):
..def __init__(self, *args, **kwargs):
....super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
....max_length=None, min_length=None,
....error_message=gettext(u'Enter a zip code in the format XXXXX-XXX.'),
....*args, **kwargs)
class BRPhoneNumberField(Field):
..def clean(self, value):
....super(BRPhoneNumberField, self).clean(value)
....if value in EMPTY_VALUES:
......return u''
....value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
....m = phone_digits_re.search(value)
....if m:
......return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
....raise ValidationError(u'Phone numbers must be in XX-XXXX-XXXX format.')
class BRStateSelect(Select):
.."""
..A Select widget that uses a list of brazilian states/territories
..as its choices.
.."""
..def __init__(self, attrs=None):
....from br_states import STATE_CHOICES # relative import
....super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
Coisas pra resolver:
>>> from django.contrib.localflavor.br.forms import BRZipCodeField, BRPhoneNumberField, BRStateField, BRStateSelect
>>> from django import newforms as forms
>>> class BRForms(forms.Form):
... zipcode = BRZipCodeField()
... phone = BRPhoneNumberField()
... statef = BRStateField()
... statec = forms.ChoiceField(widget=BRStateSelect)
...
>>> brf = BRForms()
>>> print brf.as_table()
...
>>>>
O widget
BRStateSelect ainda não é renderizado corretamente, isso acontece com os fields que tem Select como classe base. A solução que vem sendo adotada usa o método __init__, que nesse caso não fica elegante pois teríamos que importa STATE_CHOICES de br_states.py. Bom o tempo está apertado, tenho que ir, aqui tem um exemplo de como usar o __init__, a única diferença e que os dados vem da banco de dados.
quarta-feira, 28 de março de 2007
Qual o tamanho da comunidade Django?
Qual o tamanho da comunidade Django? essa pergunta foi feita e respondida aqui por Jacob Kaplan-Moss.
Ajuste inteligente do settings.py
Com essa dica, teremos dois arquivos de configuração que revezam entre versão de desenvolvimento e produção, o arquivo
local_settings.py contém nossa configuração de desenvolvimento, assim não precisamos nos preocupar com settings.py na hora da distribuição, pois settings.py sabe quando deve dar passagem as configurações do arquivo local_settings.py.
terça-feira, 27 de março de 2007
2 terabytes de video e audio sobre Python
Django e o quebra cabeça com newforms
Basicamente temos duas formas para usar o newforms a primeira consiste em usar as funções
Acompanhe agora a segunda forma de uso do newforms. O método
Testando 123:
Agora vamos usar nossa imaginação, imagine que o produto retornado por
Temos duas soluções, a primeira e renomear todos os campos
Qual das soluções escolher?
Isso vai depender de você. Qual você preferer?
form_for_model() e form_for_instance(), para a primeira função você deve passar a classe que define seu modelo e para segunda você passa a instância desta classe e o newforms encarrega-se de gerar o formulário para você. Na segunda forma você define seu formulário como uma classe que herda de Form. Considere a definição do modelo abaixo:
class Product(models.Model):
..description = models.CharField(maxlength=200)
..category = models.ForeignKey(Category)
..quantity = models.IntegerField()
..cost = models.FloatField(max_digits=10, decimal_places=2)
..detail = models.TextField(maxlength=400, blank=True)
Usando form_for_model:
>>> from django import newforms as form
>>> from warehouse.models import Product
>>> ProductForm = form.form_for_model(Product)
>>> pf = ProductForm()
>>> print pf.as_table() # retorna nosso formulário como tabela, em branco.
Usando form_for_instance:
>>> from django import newforms as form
>>> from warehouse.models import Product
>>> p = Product.objects.get(pk=1)
>>> ProductForm = form.form_for_instance(p)
>>> pf = ProductForm()
>>> pf.as_table() # retorna nosso formulário como tabela, com valores.
Acompanhe agora a segunda forma de uso do newforms. O método
__init__ serve para carrega todas as categorias disponíveis no banco. Considere a definição do formulário abaixo:
class ProductForm(forms.Form):
..def __init__(self, *args, **kwargs):
....super(ProductForm, self).__init__(*args, **kwargs)
....self.fields['category'].choices = [('', '----------')] + [
.......(c.id, c.name) for c in Category.objects.all()]
..description = forms.CharField(max_length=200)
..detail = forms.CharField(max_length=400)
..category = forms.ChoiceField(choices=())
..quantity = forms.IntegerField()
Testando 123:
Mesmo conceito usado com form_for_model:
>>> from warehouse.forms import ProductForm
>>> pf = ProductForm()
>>> pf.as_table()# retorna nosso formulário como tabela, em branco.
Mesmo conceito usado com form_for_instance:
>>> p = Product.objects.get(pk=1)
>>> pf = ProductForm(p.__dict__)
>>> pf.as_table() # retorna nosso formulário como tabela, com valores.
Agora vamos usar nossa imaginação, imagine que o produto retornado por
Product.objects.get(pk=1) faça parte do categoria "Keyboards", e que naturalmente essa opção deveria estar selecionada no campo category, infelizmente não é isso que acontece. Mas espere com form_for_model() e form_for_instance() funciona! Aqui está o código do newforms de uma olhada tente achar o erro:) Brincadeira! é uma boa leitura, eu li varias vezes. Essa falha acontece pela diferença entre o nome do campo category definido em nossa classe ProductForm e o dicionário retornado por p.__dict__ que retorna uma chave de nome category_id representando a categoria em vez de category, o que gera uma ValidationError.
>>> p.__dict__
{'description': 'Turtle', 'detail': 'ABNT2', 'cost': 46.73, 'category_id': 2, 'id': 1, 'quantity': 1}
>>>
Temos duas soluções, a primeira e renomear todos os campos
foreignkey para uma nomenclatura nome + _id e a segunda foi passada pelo Daniel Vaz (sniper_cool) que consiste em passar a categoria que deve ser selecionada usando a propriedade initial.
>>> p = Product.objects.get(pk=1)
>>> pf.fields['category'].initial= p.id
>>> pf.as_table() # retorna nosso formulário como tabela, com valores corretos.
Qual das soluções escolher?
Isso vai depender de você. Qual você preferer?
segunda-feira, 26 de março de 2007
PyGTK widget usando Cairo e Pango
Abaixo um widget em PyGTK usando Cairo e Pango com Scroll de texto, a ideia é colocar esse widget em um applet Gnome, para que ele fique passando noticias agregadas com o Straw.
import gobject
import pango
import gtk
from gtk import gdk
class ScrolledTextWidget(gtk.Widget):
..def __init__(self):
....gtk.Widget.__init__(self)
....self.__start = True
....self.set_font()
....self.set_text('Caio Eduardo Canestraro de Souza',
..................'Ana Julia Canestraro de Souza')
....# update once a milisecond - time.sleep(0.010)
....gobject.timeout_add(30, self.do_redraw)
..def set_font(self, font='Sans', size=10):
....font = '%s %s' % (font, size)
....self._font = pango.FontDescription(font)
..def set_text(self, t, tt):
....self.p = self.create_pango_layout(t)
....self.p.set_font_description(self._font)
....self.pp = self.create_pango_layout(tt)
....self.pp.set_font_description(self._font)
..def do_realize(self):
....self.set_flags(self.flags() | gtk.REALIZED)
....self.window = gdk.Window(
....self.get_parent_window(),
....width=self.allocation.width,
....height=self.allocation.height,
....window_type=gdk.WINDOW_CHILD,
....wclass=gdk.INPUT_OUTPUT,
....event_mask=self.get_events() | gdk.EXPOSURE_MASK)
....self.window.set_user_data(self)
....self.style.attach(self.window)
....self.style.set_background(self.window, gtk.STATE_NORMAL)
....self.window.move_resize(*self.allocation)
..def do_unrealize(self):
....self.window.set_user_data(None)
..def do_size_request(self, requisition):
....width, height = self.p.get_size()
....requisition.width = 150 # Fixed width
....requisition.height = height // pango.SCALE
..def do_size_allocate(self, allocation):
....self.allocation = allocation
....if self.flags() & gtk.REALIZED:
....self.window.move_resize(*allocation)
..def do_expose_event(self, event):
....# Create first context
....c = self.window.cairo_create()
....c.rectangle(event.area.x, event.area.y,
....event.area.width, event.area.height)
....c.clip()
....# Create second context
....cc = self.window.cairo_create()
....cc.rectangle(event.area.x, event.area.y,
....event.area.width, event.area.height)
....cc.clip()
....fw, fh = self.p.get_pixel_size() # First text size
....fww, fhh = self.pp.get_pixel_size() # Second text size
....x, y, h, w = self.get_allocation() # Window size
....if self.__start:
......self.x = h
......self.y = 3 # Fixed value
......self.xx = h + fw + 5
......self.yy = self.y
....# First context
....c.move_to(self.x, self.y)
....c.update_layout(self.p)
....c.show_layout(self.p)
....# Second context
....cc.move_to(self.xx, self.yy)
....cc.update_layout(self.pp)
....cc.show_layout(self.pp)
....if self.x == -fw:
......self.x = self.xx + fww + 5
....elif self.xx == -fw:
......self.xx = self.x + fw + 5
....else:
......self.x = self.x - 1
......self.xx = self.xx - 1
......self.__start = False
..def do_redraw(self):
....if self.window:
......alloc = self.get_allocation()
......rect = gdk.Rectangle(alloc.x, alloc.y,
...........................alloc.width, alloc.height)
......self.window.invalidate_rect(rect, True)
......self.window.process_updates(True)
....# keep running this event
....return True
gobject.type_register(ScrolledTextWidget)
Widget personalizado usando Glade3 e PyGTK
Tutorial escrito por Ali Afshar, mostra como podemos ter nossos widgets feitos com PyGTK disponíveis dentro do Glade3.
Custom pygtk widgets in glade3
Custom pygtk widgets in glade3 part 2
Custom pygtk widgets in glade3
Custom pygtk widgets in glade3 part 2
Assinar:
Postagens (Atom)