Shared Object

Vedremo brevemente alcuni esempi di pagine con condivisione di dati.

La condivisione è resa possibile dall’utilizzo di oggetti condivisi (Shared Object) residenti sul server e che agiscono come diramatori di eventi da un client agli altri client.

Suggerimento

Affinché gli sharedObjects funzionino sulla propria istanza è necessario rispettare due pre-requisiti:

  • aver attivato i websockets nel siteconfig dell’istanza:

    <GenRoBag>
        <wsgi mainpackage="sandbox" websockets="True"/>
    
  • aver avviato il server in modalità tornado:

    gnrwsgiserve sandboxpg --t
    

Per prima cosa riprendiamo una semplice pagina con 3 campi:

Il codice è assolutamente banale:

def main(self,root,**kwargs):
  fb=root.formbuilder(cols=1, datapath='mydata')
  fb.textbox('^.name', lbl='Name')
  fb.textbox('^.address', lbl='Address')
  fb.numbertextbox('^.age', lbl='Age')

Ogni utente di questa pagina vede solo i propri dati.

Vediamo ora la stessa form con i campi condivisi:

Ed ecco nuovamente il codice:

def main(self,root,**kwargs):
  root.sharedObject('mydata',shared_id='so_test1')
  fb=root.formbuilder(cols=1, datapath='mydata')
  fb.textbox('^.name', lbl='Name')
  fb.textbox('^.address', lbl='Address')
  fb.numbertextbox('^.age', lbl='Age')

Notiamo che l’unica differenza è che usando un’istruzione root.sharedObject('mydata',shared_id='so_test1') abbiamo assegnato uno shared_id alla zona mydata. Questo permette al server di gestire la collaborazione tra gli utenti che condividono lo stesso oggetto. Inoltre il sistema provvede in automatico a bloccare per un utente il campo che ha il focus nella form di un altro utente.

Vediamo ora un altro esempio. Una griglia con editing condivisa.

In questo esempio più amici possono decidere in modo collaborativo come contribuire alla buona riuscita di un picnic decidendo cibi e bevande da portare. Il risultato può poi essere esportato.

Uno sguardo al codice:

def main(self,root,**kwargs):
  root.sharedObject('shared_data',shared_id='so_picnic')
  grid = root.quickGrid(value='^shared_data.rows')
  grid.column('name',name='Name',width='30em',edit=True)
  grid.column('food',name='Food',width='20em',
               edit=dict(values='Pasta,Food,Drinks'))
  grid.tools('addrow,delrow,export')

Gli sharedObject hanno la possibilità di salvarsi in modo che ritornando alla pagina in un qualunque momento si possano trovare i valori inseriti.

Ed ecco il codice:

def main(self,root,**kwargs):
    root.sharedObject('shared_data',shared_id='so_picnic_saved')
               autoSave=True,autoLoad=True)
    grid = root.quickGrid(value='^shared_data.rows')
    grid.column('name',name='Name',width='30em',edit=True)
    grid.column('food',name='Food',width='20em',
                 edit=dict(values='Pasta,Food,Drinks'))
    grid.tools('addrow,delrow,export')

Notiamo che è bastato aggiungere gli attributi shared_autoSave=True e shared_autoLoad=True e questo ha attivato il salvataggio automatico dello shared object.

Ed ecco ora una versione che gestisce molti shared object e quindi consente di organizzare più picnic con amici diversi e in date diverse (ma attenti a non ingrassare…)

Ed ecco il codice:

class GnrCustomWebPage(object):
  def main(self,root,**kwargs):
      bc=root.borderContainer()
      fb=bc.contentPane(region='top').formbuilder(cols=1)
      fb.textbox('^picnic_name',lbl="Picnic name")
      bc.sharedObject('shared_data',shared_id='^picnic_name',
                      autoLoad=True,autoSave=True)
      grid = bc.contentPane(region='center').quickGrid(value='^shared_data.rows')
      grid.column('name',name='Name',width='30em',edit=True)
      grid.column('food',name='Food',width='20em',
                   edit=dict(values='Pasta,Food,Drinks'))
      grid.tools('addrow,delrow,export')

Notiamo che questa volta chiediamo il nome del nostro picnic e al variare del nome l’istruzione:

bc.sharedObject('shared_data',shared_id='^picnic_name',
                     autoLoad=True,autoSave=True)

provvede a scollegare lo store precedente e a collegare quello nuovo ogni volta che nel campo “Picnic name” cambiamo valore.