GenroPy, un framework innovativo per applicazioni web AJAX

Post on 05-Dec-2014

980 views 3 download

description

Roberto Lupi

Transcript of GenroPy, un framework innovativo per applicazioni web AJAX

Un progetto in

GenroPyFramework tutto italiano

per applicazioni web e AJAX

sabato 29 maggio 2010

Un progetto in

GenroPyFramework tutto italiano

per applicazioni web e AJAX

gestionali

sabato 29 maggio 2010

Roberto Lupi@robertolupi

• 10 anni di esperienza web

• enterprise e intranet

• Clienti: Amadori, Merloni, 21 banche

• Italia e India

• oggi: direttore tecnico di MedMediasoftware per la sanità

• http://www.medmediagroup.it/

sabato 29 maggio 2010

Siti vs. applicazioni

sabato 29 maggio 2010

Business logic

Web AJAXBase dati

ORM

XML

/

JSON

Object-relationalimpedance mismatch

domain objects / GUIimpedance mismatch

!!

PDF

RDBMSvs. objects

domain objects vs. GUI

sabato 29 maggio 2010

HTML✗

sabato 29 maggio 2010

Personalizzazioni?

sabato 29 maggio 2010

Stampe?

sabato 29 maggio 2010

La storia

sabato 29 maggio 2010

Stansabato 29 maggio 2010

Il progetto

sabato 29 maggio 2010

Il progetto

15 processiamministrativi

sabato 29 maggio 2010

Il progetto

15 processiamministrativi

200+ formsWeb

sabato 29 maggio 2010

Il progetto

15 processiamministrativi

190 reports e forms PDF

200+ formsWeb

sabato 29 maggio 2010

Il progetto

15 processiamministrativi

190 reports e forms PDF

200+ formsWeb

sabato 29 maggio 2010

sabato 29 maggio 2010

2 sviluppatori

sabato 29 maggio 2010

2 designers2 sviluppatori

sabato 29 maggio 2010

2 mesi2 designers2 sviluppatori

sabato 29 maggio 2010

sabato 29 maggio 2010

GenroPy

sabato 29 maggio 2010

sabato 29 maggio 2010

Bags

sabato 29 maggio 2010

Bags

gerarchica ed ordinatasimile a XML

valori ed attributi

sabato 29 maggio 2010

Bags

gerarchica ed ordinatasimile a XML

valori ed attributi

lazy loadingdinamica

observer pattern

sabato 29 maggio 2010

Bags

gerarchica ed ordinatasimile a XML

valori ed attributi

lazy loadingdinamica

observer patterndatabase

versatilefiles XML directory trees

web services

sabato 29 maggio 2010

Bags

gerarchica ed ordinatasimile a XML

valori ed attributi

lazy loadingdinamica

observer pattern

base datiuniversale

interfaccia utente

domain specific languages

databaseversatile

files XML directory trees

web services

sabato 29 maggio 2010

Business

Logic

Web AJAXBase dati

ORM

XML

/

JSON

PDFBags

sabato 29 maggio 2010

Database

sabato 29 maggio 2010

Quasi un ORM...

class Table(object): def config_db(self, pkg): tbl = pkg.table('user', pkey='id', name_long='!!User', rowcaption='username,email:%s (%s)') self.sysFields(tbl,ins=True, upd=True, md5=True) tbl.column('id',size='22',group='_',readOnly='y',name_long='Id') tbl.column('username', size=':32',name_long='!!Username', unique='y', _sendback=True, indexed='y',validate_notnull=True,validate_notnull_error='!!Mandatory field') tbl.column('email',name_long='Email',validate_notnull=True, validate_notnull_error='!!Mandatory field') tbl.column('firstname', size=':32',name_long='!!First name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('lastname', size=':32',name_long='!!Last name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('registration_date', 'D' ,name_long='!!Registration Date') tbl.column('auth_tags', name_long='!!Authorization Tags') tbl.column('status', name_long='!!Status', size='4', validate_values_conf='!!Confirmed', validate_values_wait='!!Waiting') tbl.column('md5pwd', name_long='!!PasswordMD5', size=':65') tbl.column('locale', name_long='!!Default Language', size=':12') tbl.column('preferences', dtype='X', name_long='!!Preferences') tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name') # ... metodi d'utilità ... def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

sabato 29 maggio 2010

Quasi un ORM...

class Table(object): def config_db(self, pkg): tbl = pkg.table('user', pkey='id', name_long='!!User', rowcaption='username,email:%s (%s)') self.sysFields(tbl,ins=True, upd=True, md5=True) tbl.column('id',size='22',group='_',readOnly='y',name_long='Id') tbl.column('username', size=':32',name_long='!!Username', unique='y', _sendback=True, indexed='y',validate_notnull=True,validate_notnull_error='!!Mandatory field') tbl.column('email',name_long='Email',validate_notnull=True, validate_notnull_error='!!Mandatory field') tbl.column('firstname', size=':32',name_long='!!First name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('lastname', size=':32',name_long='!!Last name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('registration_date', 'D' ,name_long='!!Registration Date') tbl.column('auth_tags', name_long='!!Authorization Tags') tbl.column('status', name_long='!!Status', size='4', validate_values_conf='!!Confirmed', validate_values_wait='!!Waiting') tbl.column('md5pwd', name_long='!!PasswordMD5', size=':65') tbl.column('locale', name_long='!!Default Language', size=':12') tbl.column('preferences', dtype='X', name_long='!!Preferences') tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name') # ... metodi d'utilità ... def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

tbl.column('id',size='22',group='_',readOnly='y',name_long='Id')

sabato 29 maggio 2010

Quasi un ORM...

class Table(object): def config_db(self, pkg): tbl = pkg.table('user', pkey='id', name_long='!!User', rowcaption='username,email:%s (%s)') self.sysFields(tbl,ins=True, upd=True, md5=True) tbl.column('id',size='22',group='_',readOnly='y',name_long='Id') tbl.column('username', size=':32',name_long='!!Username', unique='y', _sendback=True, indexed='y',validate_notnull=True,validate_notnull_error='!!Mandatory field') tbl.column('email',name_long='Email',validate_notnull=True, validate_notnull_error='!!Mandatory field') tbl.column('firstname', size=':32',name_long='!!First name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('lastname', size=':32',name_long='!!Last name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('registration_date', 'D' ,name_long='!!Registration Date') tbl.column('auth_tags', name_long='!!Authorization Tags') tbl.column('status', name_long='!!Status', size='4', validate_values_conf='!!Confirmed', validate_values_wait='!!Waiting') tbl.column('md5pwd', name_long='!!PasswordMD5', size=':65') tbl.column('locale', name_long='!!Default Language', size=':12') tbl.column('preferences', dtype='X', name_long='!!Preferences') tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name') # ... metodi d'utilità ... def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

validate_notnull=True,validate_notnull_error='!!Mandatory field'

sabato 29 maggio 2010

Quasi un ORM...

class Table(object): def config_db(self, pkg): tbl = pkg.table('user', pkey='id', name_long='!!User', rowcaption='username,email:%s (%s)') self.sysFields(tbl,ins=True, upd=True, md5=True) tbl.column('id',size='22',group='_',readOnly='y',name_long='Id') tbl.column('username', size=':32',name_long='!!Username', unique='y', _sendback=True, indexed='y',validate_notnull=True,validate_notnull_error='!!Mandatory field') tbl.column('email',name_long='Email',validate_notnull=True, validate_notnull_error='!!Mandatory field') tbl.column('firstname', size=':32',name_long='!!First name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('lastname', size=':32',name_long='!!Last name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('registration_date', 'D' ,name_long='!!Registration Date') tbl.column('auth_tags', name_long='!!Authorization Tags') tbl.column('status', name_long='!!Status', size='4', validate_values_conf='!!Confirmed', validate_values_wait='!!Waiting') tbl.column('md5pwd', name_long='!!PasswordMD5', size=':65') tbl.column('locale', name_long='!!Default Language', size=':12') tbl.column('preferences', dtype='X', name_long='!!Preferences') tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name') # ... metodi d'utilità ... def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name')

sabato 29 maggio 2010

Quasi un ORM...

class Table(object): def config_db(self, pkg): tbl = pkg.table('user', pkey='id', name_long='!!User', rowcaption='username,email:%s (%s)') self.sysFields(tbl,ins=True, upd=True, md5=True) tbl.column('id',size='22',group='_',readOnly='y',name_long='Id') tbl.column('username', size=':32',name_long='!!Username', unique='y', _sendback=True, indexed='y',validate_notnull=True,validate_notnull_error='!!Mandatory field') tbl.column('email',name_long='Email',validate_notnull=True, validate_notnull_error='!!Mandatory field') tbl.column('firstname', size=':32',name_long='!!First name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('lastname', size=':32',name_long='!!Last name', validate_notnull=True,validate_case='c',validate_notnull_error='!!Mandatory field') tbl.column('registration_date', 'D' ,name_long='!!Registration Date') tbl.column('auth_tags', name_long='!!Authorization Tags') tbl.column('status', name_long='!!Status', size='4', validate_values_conf='!!Confirmed', validate_values_wait='!!Waiting') tbl.column('md5pwd', name_long='!!PasswordMD5', size=':65') tbl.column('locale', name_long='!!Default Language', size=':12') tbl.column('preferences', dtype='X', name_long='!!Preferences') tbl.formulaColumn('fullname', "firstname||' '||lastname", name_long=u'!!Name') # ... metodi d'utilità ... def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

def trigger_onUpdating(self, record,**kwargs): # ... def trigger_onInserting(self, record,**kwargs): # ...

sabato 29 maggio 2010

GUI

sabato 29 maggio 2010

HTML✗

sabato 29 maggio 2010

Dojo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

AJAX semplicissimo

sabato 29 maggio 2010

sabato 29 maggio 2010

Package(s)

sabato 29 maggio 2010

Istanze

Package(s)

sabato 29 maggio 2010

Siti

Istanze

Package(s)

sabato 29 maggio 2010

Siti

Istanze

Package(s)

GUI

Database

Risorse

sabato 29 maggio 2010

Siti

Istanze

Package(s)

GUI

Database

Risorse

Mixin

sabato 29 maggio 2010

Siti

Istanze

Package(s)

GUI

Database

Risorse

Mixin

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

sabato 29 maggio 2010

Siti

Istanze

Package(s)

GUI

Database

Risorse

Mixin

class GnrCustomWebPage(object): def windowTitle(self): return '!!Hello world'

def main(self, root, **kwargs): tabber = root.tabContainer() tab = tabber.contentPane(title='Tab') tab.button('Che ore sono?',action='FIRE chiedi_ora;') root.dataRpc('risultato','dammi_ora',_fired='^chiedi_ora') tab.div('^risultato') def rpc_dammi_ora(self): return datetime.datetime.now()

def rpc_dammi_ora(self): return Bag('http://www.example.com/websvc/get_time')['Europe.Rome']

sabato 29 maggio 2010

Stampe

sabato 29 maggio 2010

sabato 29 maggio 2010

Codice

sabato 29 maggio 2010

Editor PDFCodice

sabato 29 maggio 2010

Il progettoatto II

sabato 29 maggio 2010

User

Inserimento dati tramite form Web

Inserimento dati tramite form PDF

Stampa ed archiviazione

Utente

sabato 29 maggio 2010

sabato 29 maggio 2010

m4.py (mixin)

Componenti

fascicolo.py (webpage)

form richiesta

formato dati PDF

azioni pre / post

elementi GUI condivisi nelle forms

GUI comune

communicazione con PDF

sabato 29 maggio 2010

class Table(object):

def config_db(self, pkg): tbl = pkg.table('documento', pkey='id',name_long='!!Documento', name_plural='!!Documenti', rowcaption="$descrizione") self.sysAndComuneIdFields(tbl) tbl.column('fascicolo',name_long='!!Fascicolo') tbl.column('modello',name_long='!!Modello') tbl.column('data','D',name_long='!!Data del documento') tbl.column('ts_richiesta','DH',name_long='!!Data e ora') tbl.column('dati_richiesta','X',group='_',name_long='!!Dati richiesta', _sendback=True) tbl.column('dati_pdf','X',group='_',name_long='!!Dati del documento PDF') tbl.column('descrizione',name_long='!!Descrizione') tbl.column('user_id',size='22',group='_', _sendback=True).relation('adm.user.id',mode='foreignkey',onDelete='cascade',deferred=True, one_one=True)

Tabella “documento”

sabato 29 maggio 2010

class Table(object):

def config_db(self, pkg): tbl = pkg.table('documento', pkey='id',name_long='!!Documento', name_plural='!!Documenti', rowcaption="$descrizione") self.sysAndComuneIdFields(tbl) tbl.column('fascicolo',name_long='!!Fascicolo') tbl.column('modello',name_long='!!Modello') tbl.column('data','D',name_long='!!Data del documento') tbl.column('ts_richiesta','DH',name_long='!!Data e ora') tbl.column('dati_richiesta','X',group='_',name_long='!!Dati richiesta', _sendback=True) tbl.column('dati_pdf','X',group='_',name_long='!!Dati del documento PDF') tbl.column('descrizione',name_long='!!Descrizione') tbl.column('user_id',size='22',group='_', _sendback=True).relation('adm.user.id',mode='foreignkey',onDelete='cascade',deferred=True, one_one=True)

Tabella “documento”

sabato 29 maggio 2010

class Table(object):

def config_db(self, pkg): tbl = pkg.table('documento', pkey='id',name_long='!!Documento', name_plural='!!Documenti', rowcaption="$descrizione") self.sysAndComuneIdFields(tbl) tbl.column('fascicolo',name_long='!!Fascicolo') tbl.column('modello',name_long='!!Modello') tbl.column('data','D',name_long='!!Data del documento') tbl.column('ts_richiesta','DH',name_long='!!Data e ora') tbl.column('dati_richiesta','X',group='_',name_long='!!Dati richiesta', _sendback=True) tbl.column('dati_pdf','X',group='_',name_long='!!Dati del documento PDF') tbl.column('descrizione',name_long='!!Descrizione') tbl.column('user_id',size='22',group='_', _sendback=True).relation('adm.user.id',mode='foreignkey',onDelete='cascade',deferred=True, one_one=True)

Tabella “documento”

sabato 29 maggio 2010

class Personale(BaseComponent):

py_requires="elezforms:BaseElezForms" def formPersonale(self, pane, **base_kwargs): kwargs = {'width': '100%', 'border_spacing': '4px'} kwargs.update(base_kwargs) fb = pane.formbuilder(cols=2, dbtable="comune.personale", **kwargs) fb.field('num') fb.field('nominativo', autospan=1) fb.field('data_nas', autospan=1) fb.field('qualifica', autospan=1) fb.field('categoria', autospan=1) fb.field('ufficio', autospan=1) fb.field('num_ore', autospan=1) fb.field('incarico', autospan=1) return fb

Componenti

sabato 29 maggio 2010

class Personale(BaseComponent):

# ... continua ... def selezionaMoltiPersonale(self, parentBC, **base_kwargs): kwargs = dict( label="Personale", basename="personale", table="comune.personale", selectionPars=dict(order_by="nominativo")) kwargs.update(base_kwargs) self.selezionaMolti(parentBC, **kwargs) def personale_struct(self, struct): r = struct.view().rows() r.fieldcell("num", width="4em") r.fieldcell("nominativo", width="15em") r.fieldcell("data_nas", width="8em", format_fullYear=True) r.fieldcell("categoria", width="10em") r.fieldcell("ufficio", width="15em") return struct

Componenti

sabato 29 maggio 2010

class Modulo(object):

def windowTitle(self): return '!!1/4. Nomina messi notificatori straordinari' def fascicolo(self): return 'f1' def modelli(self): return [('1_4', '1/4. Nomina messi notificatori straordinari')]

def abilitaCompilazioneGuidata(self): return True

def enableSaveDatiPdf(self): return False

def div_toolbar(self, div): div.button("Personale", connect_onclick="genro.gotoURL('/comune/personale')")

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id", multiple=True))

Mixin

sabato 29 maggio 2010

class Modulo(object):

def windowTitle(self): return '!!1/4. Nomina messi notificatori straordinari' def fascicolo(self): return 'f1' def modelli(self): return [('1_4', '1/4. Nomina messi notificatori straordinari')]

def abilitaCompilazioneGuidata(self): return True

def enableSaveDatiPdf(self): return False

def div_toolbar(self, div): div.button("Personale", connect_onclick="genro.gotoURL('/comune/personale')")

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id", multiple=True))

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

Mixin

sabato 29 maggio 2010

class Modulo(object):

def windowTitle(self): return '!!1/4. Nomina messi notificatori straordinari' def fascicolo(self): return 'f1' def modelli(self): return [('1_4', '1/4. Nomina messi notificatori straordinari')]

def abilitaCompilazioneGuidata(self): return True

def enableSaveDatiPdf(self): return False

def div_toolbar(self, div): div.button("Personale", connect_onclick="genro.gotoURL('/comune/personale')")

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id", multiple=True))

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id",multiple=True))

Mixin

sabato 29 maggio 2010

class Modulo(object):

def windowTitle(self): return '!!1/4. Nomina messi notificatori straordinari' def fascicolo(self): return 'f1' def modelli(self): return [('1_4', '1/4. Nomina messi notificatori straordinari')]

def abilitaCompilazioneGuidata(self): return True

def enableSaveDatiPdf(self): return False

def div_toolbar(self, div): div.button("Personale", connect_onclick="genro.gotoURL('/comune/personale')")

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id", multiple=True))

Mixin

sabato 29 maggio 2010

class Modulo(object):

def windowTitle(self): return '!!1/4. Nomina messi notificatori straordinari' def fascicolo(self): return 'f1' def modelli(self): return [('1_4', '1/4. Nomina messi notificatori straordinari')]

def abilitaCompilazioneGuidata(self): return True

def enableSaveDatiPdf(self): return False

def div_toolbar(self, div): div.button("Personale", connect_onclick="genro.gotoURL('/comune/personale')")

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaMoltiPersonale(bc, values="#dati_richiesta.personale_id", label="Seleziona i messi notificatori")

def formatoDatiPdf(self, root): root.personale(onLoad=self.selezionaRecord('$comune_id = :comune_id and $id in :personale_id', personale_id="=dati_richiesta.personale_id", multiple=True))

def form_NuovaRichiesta(self, parentBC,**kwargs): bc = parentBC.borderContainer(**kwargs) self.selezionaSezione(bc, storeRecord="#dati_richiesta.sezione", label="Seleziona la sezione")

def formatoDatiPdf(self, root): sez = root.sezione(onLoad=self.creaRecord(datapath='dati_richiesta.sezione')) sez.attestazione(onLoad=self.selezionaRecord(where='$comune_id = :comune_id and $sezione_id = :sezione_id and not fuori_comune', sezione_id='=parent.id', order_by='$sesso,$nominativo', multiple=True))

Mixin

sabato 29 maggio 2010

RSS Reader

sabato 29 maggio 2010

#!/usr/bin/env pythonw# -*- coding: UTF-8 -*-## untitled## Created by Giovanni Porcari on 2007-03-24.# Copyright (c) 2007 Softwell. All rights reserved.#

""" RSS READER """from gnr.core.gnrbag import Bag

class GnrCustomWebPage(object): maintable='rss.feed' css_require='rssreader' def pageAuthTags(self, **kwargs): return 'user' def main(self, root, **kwargs): layout = root.borderContainer(design="sidebar") self.left(layout.borderContainer(region='left', width="30%", splitter=True, _class='fakeclass',datapath='feed')) self.top(layout.contentPane(region='top',height='30%', splitter=True,_class='fakeclass')) center = layout.stackContainer(region='center',_class='fakeclass',selectedPage='^rss.page') center.contentPane(pageName='loading').div('...Loading...') center.contentPane(pageName='loaded').iframe(height='100%',width='100%', delay=2000,border='0', onUpdating='genro.setData("rss.page","loading");', onLoad='genro.setData("rss.page","loaded");', src='^rss.link') def left(self,bc): self.feedform(bc.contentPane(region='top',_class='fakeclass')) center = bc.contentPane(region='center',_class='fakeclass') center.tree(storepath='.tree',labelAttribute='caption',selected_k_id='.curr.pkey', selected_k_url='.curr.url',_fired='^.refreshTree', inspect='shift') center.dataRpc('.tree','getFeeds',_fired='^.refresh',_onResult='FIRE .refreshTree',_onStart=True) center.dataRpc('rss.rows','getItems',url='^.curr.url',_if='url',_else="null")

def feedform(self,pane): fb = pane.formbuilder(cols=2,border_spacing='4px',datapath='.record',formId='rss', controllerPath='form',pkeyPath='feed.curr.pkey', width='90%',dbtable='rss.feed') #fb.textbox(value='^.topic',lbl='!!Topic',width='100%') #fb.textbox(value='^.title',lbl='!!Title',width='100%') #fb.textbox(value='^.url',lbl='!!Address',colspan='2',width='100%') fb.field('topic',autospan=1) fb.field('title',autospan=1) fb.field('url',autospan=2) fb.button('!!Save',action="genro.formById('rss').save();", disabled='==!_valid',_valid='^form.valid') fb.button('!!New',action="FIRE feed.curr.pkey='*newrecord*';") # == ritorna un espressione javascript pane.dataController(""" genro.formById('rss').load({destPkey:destPkey});""", destPkey='^.curr.pkey',_onStart=True) pane.dataRpc('.savedId','saveFeed',record='=.record', _onResult=""" genro.formById('rss').saved(); FIRE .refresh;""",nodeId='rss_saver') pane.dataRecord('.record','rss.feed',pkey='=.curr.pkey',nodeId='rss_loader', _onResult="genro.formById('rss').loaded()") def rpc_saveFeed(self,record=None,**kwargs): tblfeed = self.db.table(self.maintable) if not record['id']: record['username'] = self.user tblfeed.insert(record) else: tblfeed.update(record) self.db.commit() return record['id'] def rpc_getFeeds(self): results = self.db.table(self.maintable).getFeeds(user = self.user) return results

def rpc_getItems(self,url=None,**kwargs): rss=Bag(url)['rss.channel'].digest('#v') rows = Bag() for i,item in enumerate(rss): if isinstance(item,Bag): rows.setItem('n_%i' %i,None,title=item['title'],link=item['link'],description=item['description']) return rows def item_struct(self): struct = self.newGridStruct() r = struct.view().rows() r.cell('title', name='!!Title', width='20em',classes='titleCell') r.cell('description', name='!!Description', width='50em',classes='descCell') return struct def top(self,pane): pane.includedView(storepath='rss.rows', nodeId='rssItemsGrid',autoWidth=True, selected_link='rss.link', struct=self.item_struct())

RSS Reader

109 righe

sabato 29 maggio 2010

Presente Futuro

sabato 29 maggio 2010

Futuro

Community, Community, Community

sabato 29 maggio 2010

Grazie!

Roberto Lupi

roberto@lupi.an.ithttp://www.medmediagroup.it/

GenroPyhttp://www.genropy.org/

http://blog.lupi-software.com/http://svn.genropy.org/genro/trunk

@robertolupi

sabato 29 maggio 2010