Post on 23-Jan-2015
description
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Diego Manhaes Pinheiro
Nucleo de Pesquisa em Sistemas de InformacaoInstituto Federal Fluminense - Campus Campos Centro
me@dmpinheiro.net
27 de Setembro de 2010
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
ZODB
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Componentes
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
wget http://python-distribute.org/distribute_setup.py
python2.6 distribute_setup.py
easy_install pip
pip install virtualenv
virtualenv ~/grokenv
source ~/grokenv/bin/activate
easy_install pip
pip install grokproject
grokproject example
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
import grok
class Example(grok.Application, grok.Container):
pass
class Index(grok.View):
pass # see app_templates/index.pt
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
<html>
<head>
</head>
<body>
<h1>Congratulations!</h1>
<p>Your Grok application is up and running.
Edit <code>example/app_templates/index.pt</code> to change
this page.</p>
</body>
</html>
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Conceitos basicos
• Application - Representa o sistema.
• View - Descreve um endereco para acesso web.
• Model - Descreve um conceito de negociosimples.
• Container - Descreve um objeto de negocio quepode conter outros objetos.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Criando duas Applicacoes
bin/paster serve parts/etc/debug.iniTraceback (most recent call last):
File ".../scan.py", line 40, in check_module_component
File ".../etc/site.zcml", line 4.2-4.31
File ".../src/example/configure.zcml", line 5.2-5.27
GrokError: Multiple possible contexts for <class ’example.app.Index’>,
please use the ’context’ directive.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
View
• Associada a um objeto de negocio.
• Metodo render e chamado toda vez que apagina e acessada.
• Nome da classe e torna-se parte do enderecoURL.
• E possıvel adicionar images atraves da variavelstatic.
• View e associada automaticamente com aclasse.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Entendendo o esquema de publicacao deobjetos
http://localhost:8080/app01/1/editar
• http://localhost:8080 - Endereco onde oservidor onde o framework esta funcionando.
• app01 - Nome da Aplicacao
• 1 - nome de um objeto
• editar - nome da view
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Modelimport grok
from persistent.list import PersistentList
class Carro(grok.Model):
def __init__(self,nome, modelo=None,ano=None,opcionais=None):
self.nome
self.modelo=None
self.ano=None
self.opcionais = PersistentList(opcionais)
def say_greetings(self):
print "Hello, my friend! Stay awhile and listen!"
def incluir_opcional(self,opcional):
self.opcionais.append(opcional)
self._p_changed = True
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Container
• Objetos que contem outros objetos.
• Usa a API de dicionario.
• identificador utilizado torna-se parte da URL.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Codigo criando um Container
import grok
class Example(grok.Application, grok.Container):
pass
class Content(grok.Model):
pass
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Codigo usando um Container:Test-Layer: functional
>>> from example.app import Example, Content
>>> root = getRootFolder()
>>> root[’app’] = app = Example()
>>> first_content = Content()
>>> app[’first’] = first_content
>>> app[’second’] = Content()
>>> list(app.keys())
[u’first’, u’second’]
>>> list(app.values()) #doctest: +ELLIPSIS
[<example.app.Content object at ... >, <example.app.Content object at ... >]
>>> app.has_key(2)
True
>>> app.items()
[(’first’,<>),(2,<>)]
>>> len(app)
2
>>> app.get(’first’)
<>
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Container
• Usa a API de dicionario.
• identificador utilizado torna-se parte da URL.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Forms
• Mecanismo para a definicao de formularios.
• Utiliza o conceito de widgets.
• E possıvel criar sua proprias widgets.
• DisplayForm, EditForm, AddForm
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Formsimport grok
from models import Person
from example.app import Example
from zope.formlib.widgets import RadioWidget as _RadioWidget
from zope.schema import Bool, TextLine, Datetime, Choice
import uuid
class Index(grok.View):
grok.context(Example)
def list_of_persons(self):
return self.context.keys()
def RadioWidget(field, request):
vocabulary = field.vocabulary
widget = _RadioWidget(field, vocabulary, request)
return widget
PERSON_FIELDS = {’name’: TextLine(title=u’Nome’,description=u’Informe o teu nome:’),
’date_of_birth’: Datetime(title=u’Data de Nascimento’,
description=u’Informe sua data de nascimento’),
’gender’: Choice(title=u’Sexo’,description=u’’,values=(u’Masculino’,u’Feminino’,))}
class ViewPerson(grok.DisplayForm):
grok.name(’index’)
grok.context(Person)
form_fields = grok.Fields(**PERSON_FIELDS)
class EditPerson(grok.EditForm):
grok.name(’editar’)
grok.context(Person)
form_fields = grok.Fields(**PERSON_FIELDS)
@grok.action(u’Editar Pessoa’)
def edit_person(self,**data):
self.applyData(self.context,**data)
self.redirect(’index’)
class AddPerson(grok.AddForm):
grok.name(’adicionar’)
grok.context(Example)
form_fields = grok.Fields(**PERSON_FIELDS)
form_fields[’gender’].custom_widget = RadioWidget
@grok.action(u"Create a object")
def creating_a_object(self, **data):
self.create(str(uuid.uuid4()) ,**data)
self.redirect(’index’)
def create(self,a_id, **data):
a_person = Person(**data)
self.context[a_id] = a_person
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Forms
import grok
class Example(grok.Application, grok.Container):
pass
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Viewlet
• Define uma area que pode ser compartilhadaentre varias visoes.
• E associada a um viewletmanager, que e aresponsavel por
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
ViewletManagerimport grok
class Example(grok.Application, grok.Container):
pass
class Index(grok.View):
pass
class AreadoUsuario(grok.ViewletManager):
grok.view(Index)
grok.name(’example.main’)
class UserName(grok.Viewlet):
grok.name(’user’)
grok.order(30)
grok.viewletmanager(AreadoUsuario)
def render(self):
return "Hello!"
class Preferences(grok.Viewlet):
grok.name(’preferences’)
grok.order(10)
grok.viewletmanager(AreadoUsuario)
def render(self):
return "Greetings!"
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Princıpios de O.O.
Program to a interface, not to a implementation.Composition over inheritance.Depend upon abstractions (interfaces), not uponconcrete classes.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Definindo Interfaces com Python
Esqueca sobre classes e sobre conceitoscomplicados. Interfaces permitem:
• Permite expor uma API.
• Permite que mecanismos consultem umainterface.
• Interfaces precisam ser declaradas comoimplementadas na definicao da sua classe.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Utility
Conhecido tambem como Service Pattern.
• Funciona utilizando uma interface comoconsulta.
• O modulo zope.component e o teu amigo.
• Usando uma interface como base pode-se tervarias Utility.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
import grok
from datetime import datetime
from example.interfaces import IDateUtility, IQuizUtility
class Example(grok.Application, grok.Container):
pass
class Index(grok.View):
grok.context(Example)
class ComicQuizUtility(grok.LocalUtility):
grok.name("comic")
grok.implements(IQuizUtility)
class DateUtility(grok.GlobalUtility):
grok.implements(IDateUtility)
def now(self):
return datetime.now()
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
:Test-Layer: functional
>>> from example.app import Example
>>> from example.interfaces import IDateUtility, IQuizUtility
>>> root = getRootFolder()
>>> root[’app’] = Example()
>>> import zope.component
>>> date_utility = zope.component.getUtility(IDateUtility)
>>> date_utility.now().strftime(’%d/%m/%Y’)
’27/09/2010’
>>> quiz_utility = zope.component.getUtility(IQuizUtility, name="weather")
Traceback (most recent call last):
...
ComponentLookupError: (<InterfaceClass example.interfaces.IQuizUtility>, ’weather’)
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
GlobalUtility
Funciona como o Service so que e valido paraqualquer aplicacao.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Adapter#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import grok
from interfaces import IPortaVGA, IPortaMiniDVI
class Example(grok.Application, grok.Container):
pass
class Index(grok.View):
pass # see app_templates/index.pt
class AdaptadorDVItoVGA(grok.Adapter):
grok.implements(IPortaVGA)
grok.context(IPortaMiniDVI)
def conectar_entrada_vga(self,cable):
self.context.conectar_entrada_minidvi(self)
print "Conectando o adaptador VGA."
class Macbook(object):
grok.implements(IPortaMiniDVI)
def conectar_entrada_minidvi(self, cable):
print "Conectando na Porta MiniDVI em um Macbook."
class NotebookHP(object):
grok.implements(IPortaVGA)
def conectar_entrada_vga(self,cable):
print "Conectando na porta VGA de um notebook HP."
class Projetor(object):
pass
def plugar_laptop_em_um_projetor(laptop,projetor):
dispositivo_vga = IPortaVGA(laptop,None)
if dispositivo_vga is None:
print "Voce precisa de um adaptador."
else:
dispositivo_vga.conectar_entrada_vga(projetor)
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
MultiAdapter
:Test-Layer: functional
>>> from example.app import Macbook, NotebookHP, Projetor
>>> from example.app import plugar_laptop_em_um_projetor
>>> meu_notebook = Macbook()
>>> projetor_da_apresentacao = Projetor()
>>> plugar_laptop_em_um_projetor(meu_notebook,projetor_da_apresentacao)
Conectando na Porta MiniDVI em um Macbook.
Conectando o adaptador VGA.
>>> notebook_do_elesbom = NotebookHP()
>>> plugar_laptop_em_um_projetor(notebook_do_elesbom,projetor_da_apresentacao)
Conectando na porta VGA de um notebook HP.
>>> from zope.component import getAdapter,queryAdapter
>>> from example.interfaces import IPortaVGA
>>> adaptador = queryAdapter(meu_notebook,IPortaVGA)
>>> type(adaptador)
<class ’example.app.AdaptadorDVItoVGA’>
>>> outro_adaptador = getAdapter(notebook_do_elesbom,IPortaVGA)
Traceback (most recent call last):
...
ComponentLookupError: (<example.app.NotebookHP object at ... <InterfaceClass example.interfaces.IPortaVGA>, u’’)
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
MultiAdapter
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Definindo a Seguranca
import grok
class UmaPermissao(grok.Permission):
grok.name("example.register")
class VerHome(grok.Permission):
grok.name("example.homeaccess")
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Definindo a Seguranca
import grok
from permissions import VerHome, UmaPermissao
class Membro(grok.Role):
grok.name("example.Membro")
grok.permissions( ’example.ViewHome’, ’example.register’,)
# grok.permissions( ViewHome, UmaPermissao,)
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import grok
import permissions
class Example(grok.Application, grok.Container):
pass
class Segredo(grok.View):
grok.require("example.homeaccess")
def render(self,**kwargs):
return """<html>
<body>
<img src="" tal:attributes="static/malandro.jpg"/>
</body>
</html>
"""
class Index(grok.View):
grok.require(permissions.VerHome)
@grok.require("example.register")
def available_users(self):
return u"Greetings Stranger!"
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Conectando a DB Relacional
Existem dois mecanismos para utilizar mapeamentoobjeto relacional transparente com o Grok: omegrok.rdb e o stormcontainer. O primeiro e umacamada que segue o conjunto de operacoes doobjetos Grok so que ao inves de Armazenar osdados no ZODB. ele usa o SQlAlchemy para efetuaro mapeamento. O nva.stormcontainer utiliza umoutro mecanismo de .
• megrok.rdb
• nva.stormcontainer
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Definindo as classes o megrok.rdbimport grok
from sqlalchemy import Column, ForeignKey
from sqlalchemy.types import Integer, String
from sqlalchemy.orm import relation
from megrok import rdb
from z3c.saconfig import EngineFactory, GloballyScopedSession
from z3c.saconfig.interfaces import (IEngineFactory, IScopedSession,
IEngineCreatedEvent)
TEST_DSN = ’sqlite:///:memory:’
metadata = rdb.MetaData()
engine_factory = EngineFactory(TEST_DSN)
scoped_session = GloballyScopedSession()
grok.global_utility(engine_factory, provides=IEngineFactory, direct=True)
grok.global_utility(scoped_session, provides=IScopedSession, direct=True)
class Example(grok.Application, grok.Container):
pass
class Index(grok.View):
grok.context(Example)
pass # see app_templates/index.pt
class Cursos(rdb.Container):
pass
class Departamento(rdb.Model):
rdb.metadata(metadata)
id = Column(’id’,Integer, primary_key=True)
nome = Column(’nome’,String(50))
cursos = relation(’Curso’,
backref=’departamento’,
collection_class=Cursos)
class Curso(rdb.Model):
rdb.metadata(metadata)
id = Column(’id’,Integer, primary_key=True)
departmento_id = Column(’departamento_id’, Integer,
ForeignKey(’departamento.id’))
nome = Column(’nome’,String(50))
@grok.subscribe(IEngineCreatedEvent)
def engine_criada(event):
rdb.setupDatabase(metadata)
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Criando as classes de mapeamento
:Test-Layer: functional
>>> from example.app import Example
>>> from megrok import rdb
>>> root = getRootFolder()
>>> root[’app’] = Example()
>>> from example.app import Curso, Departamento
>>> session = rdb.Session()
>>> filosofia = Departamento(nome="Filosofia")
>>> session.add(filosofia)
>>> logica = Curso(nome="Logica")
>>> etica = Curso(nome="Etica")
>>> metafisica = Curso(nome="Metafısica")
>>> session.add_all([logica, etica, metafisica])
>>> filosofia.cursos.set(logica)
>>> filosofia.cursos.set(etica)
>>> filosofia.cursos.set(metafisica)
>>> for key, value in sorted(filosofia.cursos.items()):
... print key, value.nome, value.departmento.nome
1 Logica Filosofia
2 Etica Filosofia
3 Metafısica Filosofia
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Definindo as classes usando onva.stormcontainer
import grok
from nva.stormcontainer import StormContainer
from storm.locals import Storm, Int, Unicode, Reference
class Example(grok.Application, grok.Container):
pass
class Grupo(StormContainer, grok.Container):
def __init__(self):
super(Grupo,self).__init__()
self.setClassName(’example.app.Pessoa’)
self.setStoreUtilityName(’test’)
class Compania(StormContainer, grok.Container):
def __init__(self):
super(Compania,self).__init__()
self.setClassName(’example.app.Departamento’)
self.setStoreUtilityName(’test’)
class Departamento(grok.Model,Storm):
__storm_table__ = "departamento"
id_departamento = Int(primary=True)
nome = Unicode()
class Pessoa(grok.Model,Storm):
__storm_table__ = "pessoa"
id_pessoa = Int(primary=True)
nome = Unicode()
departamento = Reference(id_pessoa, Departamento.id_departamento)
@grok.subscribe(Example, grok.ApplicationInitializedEvent)
def define_store(obj, event):
from zope.component import getUtility
zstorm = getUtility(IZStorm)
zstorm.set_default_uri("test", "sqlite:")
store = zstorm.get(’test’)
store.execute("")
result = store.execute("""
CREATE TABLE pessoa (
id_pessoa INTEGER PRIMARY KEY,
nome VARCHAR,
departamento INTEGER NOT NULL);
CREATE TABLE departamento (
id_departamento INTEGER PRIMARY KEY,
nome VARCHAR);
""")
store.commit()
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Do a functional doctest test on the app.
========================================
:Test-Layer: functional
Let’s first create an instance of Example at the top level:
>>> from example.app import Example,Grupo, Compania, Pessoa, Departamento
>>> root = getRootFolder()
>>> root[’app’] = app = Example()
>>> app[’pessoas’] = pessoas = Grupo()
>>> app[’departamentos’] = iff = Compania()
>>> print iff.id, pessoas.id
None, None
>>> import transaction
>>> transaction.commit()
>>> print iff.id, pessoas.id
None, None
>>> nsi = Departamento()
>>> nsi.nome = "Nucleo de Pesquisa em Sistemas de Informac~ao"
>>> iff[’id’] = Com
>>> app[’departamentos’]
>>> pessoa = Pessoa()
>>> pessoa.nome = "Diego"
>>>
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Usando o megrok.login
Permite definir rapidamente um sistema de usuarioe paginas de login e logout.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Usando o megrok.strictrequire
Forca a definicao de seguranca para todas as Views.Procedimentos simples de uso : Inclua comodependencia.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Outros modulos• megrok.navigation - Permite criar menus e
associa-los com classes Views.• megrok.jinja - Usar a sintaxe Jinja para a
criacao de modelos de paginas.• megrok.genshi - Usar a sintaxe Genshi para a
criacao de modelos de paginas.• megrok.z3ctable - Permite criar tabulacoes em
html facilmente a partir de item de containers.• megrok.traject - Permite criar mecanismo facil
de ”atravessamento”de URLS.• megrok.chameleon - Permite aumentar a
performance dos modelos de paginas.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Conclusoes
• Possui uma gama gigante de componentes.
• Agora e possıvel fazer coisas simples.
• OO rulez!
• Flexibilidade infinita.
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Documentacao
• http://grok.zope.org
• http://github.com/dmpinheiro/Tutorial-Grok-pt-br
• http://apidoc.zope.org
• http://wiki.zope.org/zope3/book.pdf
• http://nsi.iff.edu.br/dicas-e-tutoriais/zca
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Livros
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Enriqueca sua cultura inutil: a origem dapalavra grok
A palavra grok vem do livro strange in strange landpor robert a. heinlein.
Referencia : http://en.wikipedia.org/wiki/grok
Grok - mais um framework web Programando com o Grok Modulos externos Consideracoes Finais
Obrigado!!!• me@dmpinheiro.net
• github.com/dmpinheiro
• slideshare.com/dmpinheiro
• launchpad.net/dmpinheiro