By default the post urls are like this:
http://www.mysite.com/blog/default/post/2010/10/10/my-article
but this can be shortened using routes.py from web2py to have some like this:
http://www.mysite.com/blog/2010/10/10/my-article
To do this I have to edit routes.py with come with web2py and add this line
(r'.*:/blog/(?P(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01]).*)$',r'/blog/default/post/\g')
And make this changes in instant press: edit models/_aconfig.py and change this
SHORT_URL = False
to
SHORT_URL = True
In Beta 2 of Instant Press has SyntaxHighlighter. SyntaxHighlighter is a fully functional self-contained code syntax highlighter developed in JavaScript. To get an idea of what SyntaxHighlighter is capable of, have a look at the code:
def test(): print "Hello world"
By default syntaxhighlighter is disabled, to enabled edit in models/ the file _aconfig.py and change this line:
SYNTAX_HIGHLIGHT = False
to
SYNTAX_HIGHLIGHT = True
To use we need to put the code between <pre class="brush: python"> here my code </pre>
By default are enabled syntax code of this language: css, python js. To enabled more languages you have to edit views/web2py_ajax.html
This a part of a compilation of tips of Web2py Frameworks, this script was made it by Massimo Dipierro.
Replace your web2py/routes.py with this:
try: config=open('routes.conf','r').read()
except: config=''
def auto_in(apps):
routes=[
('/robots.txt','/welcome/static/robots.txt'),
('/favicon.ico','/welcome/static/favicon.ico'),
('/admin$a','/admin$a'),
]
for a,b in [x.strip().split() for x in apps.split('\n') \
if x.strip() and not x.strip().startswith('#')]:
if not b.startswith('/'): b='/'+b
if b.endswith('/'): b=b[:-1]
app = b.split('/')[1]
routes+=[
('.*:https?://(.*\.)?%s:$method /' % a,'%s' % b),
('.*:https?://(.*\.)?%s:$method /static/$a' % a,'%s/static/
$a' % app),
('.*:https?://(.*\.)?%s:$method /appadmin/$a' % a,'%s/
appadmin/$a' % app),
('.*:https?://(.*\.)?%s:$method /$a' % a,'%s/$a' % b),
]
return routes
def auto_out(apps):
routes=[]
for a,b in [x.strip().split() for x in apps.split('\n') \
if x.strip() and not x.strip().startswith('#')]:
if not b.startswith('/'): b='/'+b
if b.endswith('/'): b=b[:-1]
app = b.split('/')[1]
routes+=[
('%s/static/$a' % app,'static/$a'),
('%s/appadmin/$a' % app, '/appadmin/$a'),
('%s/$a' % b, '/$a'),
]
return routes
routes_in=auto_in(config)
routes_out=auto_out(config)
what does it do? It writes routes for you based on a simpler routing
configuration file called routes.conf. here is an example:
----- BEGIN routes.conf-------
127.0.0.1 /examples/default
domain1.com /app1/default
domain2.com /app2/default
domain3.com /app3/default
----- END ----------
It maps a domain (the left had side) into an app and it shortens the URLs for the app, by removing the listed path prefix. That means
http://domain1.com/index will be mapped into /app1/default/index
http://domain2.com/index will be mapped into /app2/default/index
It is safe in that it preserves admin, appadmin, static files, favicon.ico and robots.txt.
http://domain1.com/favicon.ico
http://domain1.com/robots.txt
http://domain1.com/admin/... /admin/...
http://domain1.com/appadmin/... /app1/appadmin/...
http://domain1.com/static/... /app1/static/...
and vice-versa.
It does assume one app per domain. I think something like this should be default since lots of people find routes.py hard to work with.
Comments? Suggestions?
Massimo
"Instant Press is an open source CMS developed in Web2py Framework. Instant Press is simple, easy to use and attractive. Upload to your web2py framework or to Google Application Engine and you are ready to start!".
screenshot of instant press
Instant press was a proof of concept, of what can I do in web2py, ajax and jquery. I developed in almost 3 months.
Get it from here.
This is my first article made with CMS Instant Press. This is a test article.
Thanks,
Estou em Brasília para o CONSEGI, o Congresso Internacional de Software Livre e Governo Eletrônico. O evento teve quase 5000 inscritos e hoje foi seu primeiro dia - vai até sexta.
Como era de se esperar, a galera do Rio de Janeiro está em peso aqui! São várias comunidades reunidas: PythOnRio, DojoRio, #horaextra, dentre outras. Está bombando! :-)
Um fato bastante interessante que vi acontecendo foi que o Governo fomentou a vinda de estudantes de escolas da região - esses estudantes já usam software livre em seus laboratórios, porém ainda não conhecem o ecossistema de software livre. Aqui eles estão conhecendo as comunidades, interagindo, aprendendo e apresentando suas experiências - hoje mesmo rolou um openspace em que Oscar Bacelar, eu e vários estudantes trocamos ideias sobre software livre, educação e sociedade. Os próximos dias prometem!
Amanhã palestrarei sobre Arduino na sala John von Neumann de 11h às 12h, depois pretendemos fazer um openspace onde a galera possa brincar e aprender mais sobre a plataforma. Mais a tarde, de 14h às 18h, darei uma oficina sobre web2py na sala BT-04. Na sexta-feira teremos um Coding Dojo às 12h na sala de desconferência!
Para mais detalhes sobre o que a galera do Rio vai aprontar aqui, veja o post que Jonh Edson fez no blog da PythOnRio. Se você não está por aqui, assita o CONSEGI ao vivo através do streaming do SERPRO. Porém, se você está na capital federal, vai palestrar ou pretende participar das atividades, comente!
Bah, ao final da tarde de hoje partirei para Porto Alegre/RS, pois amanhã começa a 11ª edição do FISL - Fórum Internacional de Software Livre. O evento se estenderá até sábado, formando a maior festa de software livre da América Latina! \o/
A galera do Rio estará em peso lá, com muitas palestras! Tive 4 propostas aceitas e minha primeira palestra será amanhã às 9h. Veja a lista de minhas atividades:
Além disso, tentarei organizar um Coding Dojo e um openspace sobre Arduino. Obviamente, levarei o Turiquinhas versão 2 (meu carrinho controlado por Wi-Fi, feito com Arduino). Também me encontrarei lá com o Jon "maddog" Hall, presidente da Linux International, para trocar ideias sobre hack and beer, Arduino e outras coisas mais.
Para quem não vai, resta acompanhar o evento pelo Twitter, assistir às palestras ao vivo pela TV Software Livre ou ouvir a Rádio Software Livre.
Você vai ao FISL11? Nos encontramos lá!
É com prazer que anuncio que um artigo meu sobre o web2py foi publicado na edição desse mês da revista TI Digital. A revista começou a circular a partir de quinta-feira passada (1º de julho) e possui meu artigo em três páginas.
Em toda edição da revista o pessoal da Arteccom disponibiliza alguns artigos da revista para download em seu site, e nesse mês o meu foi um deles! Veja a página da edição de julho da revista TI Digital para mais detalhes. Também recomendo a compra da mesma, que possui 75 páginas e vários artigos de pessoas importantes da área, abordando diversas outras tecnologias voltadas para Web; custa R$7,90 e você encontra nas melhores bancas. :-)
Quem ler o artigo até o final vai perceber que coloquei um bônus (gratuito! :-D) para que os leitores interessados aprendam melhor sobre o framework - e se você está bastante interessado e quer aprender ainda mais, veja meu artigo sobre o curso de web2py que ministrarei no Rio de Janeiro.
Espero que vocês gostem e que meu trabalho lhe seja útil! Eu já comprei a minha TI Digital de julho, e você? Leu? O que achou? Comente!
Convidados pela Tempo Real Eventos, Bruno Cezar Rocha e eu ministraremos cursos sobre Python e web2py - eu ficarei responsável pelas turmas no Rio de Janeiro e ele pelas turmas em São Paulo.
Python é uma linguagem de programação dinâmica de altíssimo nível, utilizada em larga escala por empresas como Google (que atualmente emprega o criador da linguagem), Dreamworks, Industrial Light & Magic, NASA, dentre muitas outras. No Brasil, é utilizada pela Locaweb, Globo.com, SERPRO, Interlegis (órgão vinculado ao Senado Federal), entre outras. Diversos softwares como GIMP, Inkscape e Blender utilizam Python para extensões e criação de plugins.
O web2py é um framework para desenvolvimento Web escrito em Python, software livre e gratuito, que tem como um de seus principais objetivos agilidade e facilidade no desenvolvimento de aplicações Web seguras, baseadas em banco de dados.
Ele possibilita ao desenvolvedor pensar apenas na aplicação que está desenvolvendo (sem demandar configurações de linguagem e ferramentas), fazendo com que o desenvolvedor foque no problema que precisa resolver, e não em problemas relacionados à linguagem ou a alguma ferramenta. Possui integração com mais de 10 sistemas de banco de dados, e vários subssistemas, como: criação automática de formulários com validação, autenticação e autorização, gerador de códigos AJAX para melhor interação do usuário com a aplicação, upload seguro de arquivos, integração com vários padrões Web (XML, RSS etc.), dentre outros.
Os treinamentos acontecerão no estilo "tutorial mão na massa", onde cada aluno tem um computador para testar e treinar o que está sendo ensinado; o objetivo desses treinamentos é capacitação no desenvolvimento de aplicações Web utilizando Python e web2py a desenvolvedores que procuram uma ferramenta para desenvolvimento ágil, dinâmico, seguro e fácil de utilizar. O curso acontecerá em um sábado (assim que fecharmos a turma ou no máximo em 45 dias), o dia todo: de 9 às 17h. Caso exista interesse em treinamento in company, entre em contato comigo (alvaro [arroba] justen [ponto] eng [ponto] br).
O treinamento é dividido em dois módulos: Básico e Avançado. Para o módulo básico, é preciso ter conhecimento básico em HTML e lógica de programação (em qualquer linguagem) e para cursar o módulo avançado, é aconselhável que o interessado tenha participado do primeiro módulo, ou tenha conhecimentos equivalentes.
Os treinamentos possuirão apostila própria e durante eles será desenvolvida uma aplicação Web completa e funcional. Serão abordados vários temas com relação a desenvolvimento Web como MVC, sessões, autenticação e autorização, internacionalização, deploy, Google App Engine, dentre outros. Além disso, tudo será baseado em software livre: os computadores do laboratório terão Ubuntu 10.04.
O valor da inscrição em cada módulo é R$249,00 e, juntamente com o treinamento, cada aluno terá direito a:
Gostou da ementa dos cursos? Gostaria de que mais algum assunto fosse adicionado? Tem interesse em algum dos cursos? Comente!


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:
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:
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:
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:
Nota: utilizei/modifiquei a aplicação welcome (que já vem com o web2py) para fazer esses exemplos.
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:
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á!
Como comentei no post anterior, semana passada estive na PythOnCampus do LNCC/IST, em Petrópolis. E a caravana não pára: nesse sábado teremos mais uma edição da PythOnCampus em Madureira, na Estácio.
Para quem não conhece, PythOnCampus é um evento itinerante onde a comunidade de desenvolvedores Python do estado do Rio de Janeiro (PythOnRio) se reúne para levar conhecimentos sobre a linguagem, software livre, metodologias ágeis e experiência de mercado para os alunos de um determinado campus universitário. As PythOnCampi geralmente possuem sessões de Coding Dojo, levadas pela galera do DojoRio e minicursos de Python e/ou ferramentas da linguagem.
Galeras da PythOnRio e DojoRio na PythOnCampus LNCC-IST
Nesse sábado darei minha contribuição com a palestra Economizando tempo e dinheiro com frameworks Web, que acontecerá às 12h. Nela abordarei conceitos básicos de frameworks MVC, passarei por alguns exemplos de frameworks para desenvolvimento Web escritos em Python e, para finalizar, mostrarei um exemplo de aplicação Web com o web2py.
O que você está esperando? Se inscreva gratuitamente na PythOnCampus Madureira/Estácio - nos vemos lá!








I have decided to share some of the libraries that I have found usefulwhen creating web2py apps. The contains lots of goodies, and some niceshortcuts.
And more!
The whole library is designed to be installed like any other pythonpackage using setuptools. For basic usage you can just import thepackage normally.
However, the plugins are there for convenience, and so that I can keepthem all in the same place, but you will need to copy them to your appto actually use them.
Read the documentation here
http://static.thadeusb.com/web2py_utils/index.html
And the source code is located here
http://hg.thadeusb.com/Web/web2py_utils/summary
I am open to ideas/suggestions, and if you want to contribute let me know!


So you are ready to deploy your newly finished web2py app, but you don't like the idea of having to manually insert all of this fixture data again!
Create a new model, and name it x_fixtures.py. This way it will execute after all of your models.
Then for every table that you want to pre-populate use the following snippet. I will use an example for the auth_user table to pre-create a test user.
if db(db.auth_user.id > 0).count() == 0: db.auth_user.insert( first_name='Testers', last_name='Inc', email='test@user.com', password='<include a pre-encrypted password here>', )Basically, if we have no records in the table, insert the defaults! This is probably more useful in situations where you have pre-defined data that can be dynamic, such as a list of status codes.
if db(db.status.id > 0).count() == 0:db.status.insert(name='pending', kkey='P')db.status.insert(name='processing', kkey='R')db.status.insert(name='done', kkey='D')You can easily keep your data fixtures in a YAML file and load them into the database by using the pyyaml library.
Here is the example YAML file for what we just inserted.
auth_user: - first_name: Testerslast_name: Incemail: test@user.compassword: <include a pre-encrypted password here>status: - name: In-Queuekkey: Q - name: Pendingkkey: P - name: Processingkkey: R - name: Donekkey: DWe just open the file, pass this to pyyaml, and insert into the database, easy right?
import yamldata = yaml.load(open('/path/to/applications/myapp/private/fixtures.yaml'))for table_name, rows in data: for r in rows: db[table_name].insert(**r )Video on Generate web2py model by using yaml -> http://vimeo.com/10837176
Now you have gone done it, you placed your code on the production server, and found a bug! Now we need to reset the database to square one.
Note: Your table indexes will not reset to 0
Add the following code to the top of your x_fixtures.py file, when you want to reset the database, just change RESET to True.
RESET = Falseif RESET: for table in db.tables: # Make sure to cascade, or this will fail # for tables that have FK references. db[table].truncate("CASCADE")db.commit()Make sure to remove your x_fixtures.py file when you are ready to go live! And compile that app!
Web2py has a nice built-in feature supported execution of byte-code compiled applications. When you compile your application, web2py actually will byte-code compile all models, controllers and views. Web2py is the only framework to date that will compile your views as well!
The end result is a much faster application. Since this is the most desired way to run web2py on a production system, we need a way to compile the application externally. Either through a build tool or if you do not have access to the "admin" application on your production server.
It is very simple, use this quick one-liner from the root web2py directory.
python -c "import gluon.compileapp; gluon.compileapp.compile_application('applications/<appname>')"Compiling your application has another added benefit. You can update your application code, and web2py will continue to use the already compiled version. This way you do not have to bring your site down for a simple upgrade! Just be sure to re-compile when your ready to use the new code.
If your web server supports the X-Sendfile header, you are able to stream your uploaded files from the web server, instead of through web2py. Here is a snippet from Cherokee Website explaining the X-Sendfile header.
X-Sendfile is a special, non-standard HTTP header that has been supported by Cherokee for a while. At first you might think it is no big deal, but think again.It can be enabled in any CGI, FastCGI or SCGI backend. Basically its job is to instruct the web server to ignore the content of the response and replace it by whatever is specified in the header. The main advantage of this is that it will be Cherokee the one serving the file, making use of all its optimizations. It is useful for processing script-output of e.g. php, perl, ruby or any cgi.
This is particularly useful because it hands the load to Cherokee, all the response headers from the backend are forwarded, the whole application uses a lot less resources and performs several times faster not having to worry about a task best suited for a web server.
You retain the ability to check for special privileges or dynamically deciding anything contemplated by your backend’s logic, you speed up things a lot while having more resources freed, and you can even specify the delivery of files outside of the web server’s document root path. Of course, this is to be done solely in controlled environments. In short, it offers a huge performance gain at absolutely no cost.
Now lets implement this in web2py. Using the following database table
db.define_table('document', Field('file', 'upload'))Replace your download function with the following.
def download(): document = db(db.document.id == request.args(0)).select().first() response.headers['X-Sendfile'] = os.path.join(request.folder, 'uploads', document.file)One of the nice things about MS Access is that you can define a query, and it will be accessible to your code anywhere else in the database. You can even base another query off of a query. Making queries inheritable properties. Another nice feature available to queries in MS Access is parameterization, the ability to pass variables to your queries before they execute.
The DAL in web2py allows you to save a query as an object for later use. The DAL will only execute SQL to the database on special commands such as .select(), .count(), .update(), .delete(), etc...
With a Query object, you can drill basic queries down as fine grained as you want. I find that the query naming convention typically used for MS Access fits well with web2py.
qry_published = (db.post.status == "publish")qry_blog = (db.post.type == "blog")qry_page = (db.post.type == "page")# get all publishedall_pub = db(qry_published).select()# get all blog postsposts = db(qry_blog)(qry_published).select()# get unpublished pagesunpub_pages = db(~qry_published)(qry_page).select()As you can see, the chaining ability can be very powerful, concise, and allows you to focus on your business logic.
We can accomplish parameterized queries by using functions!
qry_between = lambda start, end: ((db.post.pub_date >= start) & (db.post.pub_date <= end))# get all published posts in the last monthimport datetimearchive = db(qry_between(request.now - datetime.timedelta(days=30), request.now)(qry_published).select()In an previous post I discussed dynamic queries. We can easily apply the concepts of both dynamic queries with parameterized queries.
# given args:# arg1 = "published"# arg2 = "between 2009-12-25 2010-01-15"qset=db()if arg1 == "published": qset=qset(qry_published)if arg2.startswith("between"): qset=qset(qry_between(arg2.split()[1], arg2.split()[2]))qset.select()With these tips you will be able to increase your productivity with web2py by keeping your code simple, concise, and DRY (don't repeat yourself)
As of web2py version 1.75.1 there is also another argument that can be passed to the DAL constructor to check table names and column names against reserved SQL keywords in target back-end databases.
This argument is check_reserved; it defaults to None.
This is a list of strings that contain the database back-end adapter names, with two extra options all and common.
The adapter name is the same as used in the DAL connection string. So if you want to check against PostgreSQL and MSSQL then your connection string would look as follows
>>> db = DAL('sqlite://storage.db', pool_size=0, check_reserved=['postgres', 'mssql'])The DAL will scan the keywords in the same order as of the list.
There are two extra options all and common. If you specify all, it will check against all known SQL keywords. If you specify common, it will only check against common SQL keywords such as SELECT, INSERT, UPDATE, etc.
For supported back-ends you may also specify if you would like to check against the non-reserved SQL keywords as well. In this case you would append _nonreserved to the name. For example check_reserved=['postgres', 'postgres_nonreserved'].
The following database backends support reserved words checking.
* PostgreSQL ('postgres')_nonreserved* MySQL ('mysql')* FireBird ('firebird')_nonreserved* MSSQL ('mssql')* Oracle ('oracle')


Here are a couple of ways to expose any python file-like object as download-able in a web2py controller.
You might want to do this if you have a generated pdf report, or allowing an export of the sites content.
From your controller, you can stream a large file by using the stream function of the response object.
return response.stream(filelikeobject, chunk_size=64*1024)You might also want to set the content type of what you are returning, as well as a new disposition (filename).
def export(): from gluon.contenttype import contenttype response.headers['Content-Type'] = contenttype('.csv') response.headers['Content-disposition'] = 'attachment; filename=%s_database.csv' % ( request.now ) import csv, cStringIO s = cStringIO.StringIO() db.export_to_csv_file(s, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC) return s.getvalue()So you need to write a query to get rows that exist between dates. This is a situation where the simplicity of the web2py DAL really shows, and how close it is to SQL really shines.
db( (db.mytable.start_date >= request.vars.date_begin)&(db.mytable.end_date <= request.vars.date_end)).select()That looks a whole lot nicer than the other ways of doing things.
We can also check if there are conflicts between records say if we were allocating resources.
Here is the sample pseudocode
# If the date ends in an existing time slotdbstart < begin and dbend > begin then conflict=True# If the date begins in an existing time slotdbstart < end and dbend > end then conflict=True# If the date is in the middle of an existing time slotdbstart > begin and dbend < end then conflict=TrueAnd here is the implementation for web2py
if db( (db.mytable.start_date < request.vars.date_begin) &(db.mytable.end_date > request.vars.date_begin)).select().count() > 0: conflict = Trueif db( (db.mytable.start_date < request.vars.date_end) &(db.mytable.end_date > request.vars.date_end)).select().count() > 0: conflict = Trueif db( (db.mytable.start_date > request.vars.date_begin) &(db.mytable.end_date < request.vars.date_end)).select().count() > 0: conflict = TrueIt is possible to define common db columns, e.g. posted_by, posted_on, etc... once and define on the appropriate table to inherit these common columns.
The DAL makes this quite easy. You define a Table with the common fields that you would like to inherit from. When defining your database tables, you will pass this table along as an argument, web2py will handle inheriting its fields.
from gluon.sql import Tabledates = Table(None, 'tmp', Field('posted_on', 'datetime', default=request.now), Field('posted_by', db.auth_user, default=auth.user.id),)db.define_table('posts', dates, Field('content', 'text'),)db.define_table('links', dates, Field('linkto', 'string', length=500),)In many cases you might need a query based on multiple sets of information. Think of a search box, where you would like to provide the option to search in multiple areas (title, content, authors) or exclude these areas. Or a customer management system, in which a query can be provided by the customer name, phone number, or any other number of options that can be filtered down. There are of course, any number of situations that you may need IF logic in your database queries.
Appending results of several database SELECT statements would not be advisable, since it accesses the database several times, and leads to slow, inefficient design. The goal is to only hit the database once, while getting all of the needed information.This is where a dynamic query would come in handy. In web2py, this can be accomplished in multiple ways.
The simplest way of creating a dynamic web2py query is to start off with a blank Set object, and then filter the query down from there.
qset=db()if arg1 == "xyz": qset=qset(db.abc.id > 0)if arg2 == "xyz": qset=qset(db.def.id > 0)qset.select()For a more advanced version, you can append a query to a list and use python's reduce function.
queries=[]if arg1 == "xyz": queries.append(db.abc.id > 0)if arg2 == "xyz": queries.append(db.def.id > 0)query = reduce(lambda a,b:(a&b),queries)query.select()Or if you are doing the same kind of query, to a list of results
q = request.vars.qquery = ( # Start off with a default query db.page.title.lower().like(q) | db.page.content.lower().like(q))# Then run through each element, and search for that specific word in the test.for qs in filter(lambda a: a != '', q.split(' ')): query = query | db.page.content.lower().like(qs.strip())rows = db(query).select()One of the finer new features in web2py is the ability to declare what is called a "virtual field".
A virtual field is a function that gets called/calculated when the web2py DAL performs a select on the database tables.
The neat thing about virtual fields, is it allows us to give the DAL ORM functionalities like you would find in django and sqlalchemy.
db.define_table('sales', Field('item'), Field('item_total', 'double'), Field('tax_percentage', 'double'), Field('trans_date', 'datetime'),)class Sales(): def total(self): return self.sales.item_total * self.sales.tax_percentage def tax(self): return self.total() - self.sales.item_totaldb.sales.virtualfields.append(Sales())2009_sales = db( (db.sales.trans_date <= "2009-12-31") (db.sales.trans_date >= "2009-01-01") ).select(orderby=~db.sales.trans_date)for sale in 2009_sales: print "Item: ", sale.item print "Price: ", sale.item_total print "Tax: ", sale.tax # Notice, we are getting from our virtualfield class we defined! print "Total: ", sale.totalSometimes you might want a lazy virtualfield that only gets calculated when you call it. A blog post permalink would be a situation where this would be beneficial.
db.define_table('post', Field('title'), Field('content'))class Post(): def permalink(self): def lzy():# Define an inner function that will perform our actionreturn URL(r=request, c='default', f='view', args=self.post.title.replace(' ', '-')) # We are only returning a reference to the function, this will get called later! return lzydb.post.virtualfields.append(Post())for row in db(db.post.id > 0): print row.title print row.permalink() # Notice, we have to call the fucntion! print contentNessa semana, dias 27 e 28 de novembro de 2009 - sexta e sábado - teremos mais uma PythOnCampus, dessa vez no IFF em Campos dos Goytacazes - é a PythOnCampus em Campos!
O pessoal do NSI/IFF está organizando o evento, que contará com palestras e minicursos sobre Python e tem como objetivo trazer o conhecimento e a experiência dos profissionais da área pra dentro da instituição, qualificando e preparando os alunos tanto para o mercado de trabalho como para a vida acadêmica. O Hugo Lopes Tavares me convidou para palestrar lá - e como eu gostei, palestrarei duas vezes! Uma sobre web2py e outra sobre Coding Dojo + Dojo Rio.
Teremos minicursos e palestras sobre a linguagem, Coding Dojo, frameworks para desenvolvimento ágil, software livre e outros assuntos - todo o conhecimento será compartilhado por profissionais da PythOnRio que estarão lá representando suas instituições: Canonical, Globo.com, IFF, Peta5, SERPRO, UENF, UFF, dentre outras. Confira a programação completa da PythOnCampus IFF.
A sessão de Coding Dojo e apresentação que farei do Dojo Rio acontecerá na sexta-feira (27) às 15h30min, já minha palestra/handson sobre web2py será no sábado (28) às 16h30min.
O que está esperando? Faça sua inscrição para a PythOnCampus em Campos! As vagas para o auditório e minicursos são limitadas. O preço para inscrição em minicursos é de 1 kilograma de arroz, feijão ou macarrão (fazer inscrição no site e levar ao NSI, sala 133, bloco A).
Confira também os folhetos com a programação: folheto 1 e folheto 2.
Se você é de Niterói ou do Rio e gostaria de participar, comente aqui no blog para marcarmos a ida - o pessoal deve sair daqui na quinta-feira (26) por volta das 19h.
Nos vemos lá! :-)
Na quarta-feira passada estive no The Developer's Conference 2009 "Rio de Janeiro", que aconteceu em Niterói. Fui convidado por Mário Mariani e Thiago Diogo, figuras que trabalham na PROAC-NTi/UFF e que conheci no Coding Dojo@Niterói.
O evento, focado em Java, contou com a participação de nomes internacionais e nacionais da linguagem e lotou o auditório da Geociências, no campus Praia Vermelha da UFF - o público, em sua maioria, eram alunos do curso de Ciência da Computação da mesma universidade. Na verdade, esse evento é itinerante e passou por outros locais do Brasil, como São Paulo e Floripa!
Apesar de eu não utilizar Java, gostei do evento, principalmente por ver o que andam fazendo com outras linguagens em termos de Web, já que trabalho com desenvolvimento Web em Python e desenvolvo o web2py. Sinceramente não entendi bem porque existe tanta "burocracia" para utilizar as bibliotecas e frameworks apresentados lá - talvez porque eu esteja acostumado a usar DRY e Python.
O que mais gostei no evento foram as duas últimas palestras: uma sobre o Google App Engine e, inusitadamente, sobre o Arduino.
Para quem não conhece, o Arduino é a junção de uma plataforma de hardware e software livres (com documentação em Creative Commons!) para computação física. Trocando em miúdos: é uma plaquinha que você conecta na USB do seu computador e, através de uma IDE, programa o que quiser e envia o código para a plaquinha. Seu código faz interface com o hardware, podendo ser conectado a sensores (luminosidade, temperatura etc.), LEDs, motores e outros componentes (comunicação via Ethernet, Bluetooth etc.). É bastante legal, principalmente para quem está aprendendo eletrônica.
Foto por Nicholas Zambetti, do site oficial do Arduino
A minha surpresa no TDC foi justamente por ter uma palestra sobre Arduino - que nada tem a ver com Java! Vinícius Senger, da GlobalCode, fez a palestra sobre Arduino, anunciando o novo produto dessa mesma empresa, o Program-ME: hardware baseado no Arduino com alguns componentes extras. Bem legal o projeto!
Eu já vinha me interessando pelo Arduino há alguns meses e há 3 semanas comprei um. Foi bastante proveitoso o evento visto que pude conversar bastante com o Vinícius sobre. :-)
Obviamente, tive que aproveitar a oportunidade de ter mais de 200 estudantes de computação para falar do Coding Dojo e, de quebra, do Hora Extra. Expliquei em alguns poucos minutos o que é e convidei a galera - é o Coding Dojo Rio conquistando territórios!
Foto por Pedro Menezes e seu celular
--
Álvaro Justen - Turicas
Peta5
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
No último final de semana mexi em algumas linhas de código da aplicação web2py-wiki, como:
Com a ajuda do Massimo Di Pierro - criador do web2py -, migramos a antiga wiki para essa nova aplicação para meu servidor, isso nos trará um pouco mais de flexibilidade pra atualizar quando surgirem versões novas.
Agora a wiki está no endereço http://wiki.web2py.com/ (em vez de http://www.web2py.com/wiki/).
Alguns planos futuros:
Se você gostaria de contribuir com o desenvolvimento dessa aplicação ou utilizá-la em seu site, baixe o código-fonte no projeto web2py-wiki no Launchpad.
Se você tem ideias de novas funcionalidades, quer reportar bugs ou tratar qualquer outro assunto relacionado a essa aplicação, por favor entre em contato.
E agora cabe a nós, usuários do web2py, contribuir com o projeto de documentação do framework! Basta cada um enviar o que para a wiki do web2py. :-)
--
Álvaro Justen
Peta5 - Telecomunicações e Software Livre
Eu já tinha comentado aqui no blog que iria em vários eventos em setembro. Fui, palestrei em alguns e acabei de enviar pro Videolog.tv o vídeo de minha palestra sobre web2py no Fórum de Tecnologia em Software Livre do SERPRO-RJ - o evento aconteceu de 15 a 17 de setembro, e minha palestra foi no dia 16.
A palestra é voltada ao público iniciante: quem ainda não utiliza framework para desenvolvimento Web (usando Python) e quem ainda não conhece o web2py.
O vídeo está disponível para download: download em OGV da palestra sobre web2py, por Álvaro Justen - Turicas.
Visualize também o vídeo no Videolog.tv:
--
Álvaro Justen
Peta5 - Telecomunicações e Software Livre
O segundo semestre do ano costuma ter mais eventos de TI que o primeiro (principalmente eventos sobre software livre). Com as passagens compradas e inscrições já feitas, seguem alguns eventos desse mês que pretendo ir:
Se você conhece outro evento que não está aqui, comente! Fique à vontade para falar de eventos que acontecerão em outubro, novembro e dezembro também.
Se você vai em algum desses eventos, comente!
Até lá! ;-)
--
Álvaro Justen
Peta5 - Telecomunicações e Software Livre
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