def table_script_resource_tree_data(self, table=None, res_type=None): #pkg,tblname = table.split('.') tblobj = self.db.table(table) pkg = tblobj.pkg.name tblname = tblobj.name result = Bag() resources = self.site.resource_loader.resourcesAtPath( page=self, pkg=None, path='tables/_default/%s' % res_type) resources_pkg = self.site.resource_loader.resourcesAtPath( page=self, pkg=pkg, path='tables/%s/%s' % (tblname, res_type)) resources_custom = self.site.resource_loader.resourcesAtPath( page=self, pkg=self.package.name, path='tables/_packages/%s/%s/%s' % (pkg, tblname, res_type)) resources.update(resources_pkg) resources.update(resources_custom) forbiddenNodes = [] def cb(node, _pathlist=None): has_parameters = False if node.attr['file_ext'] == 'py': resmodule = gnrImport(node.attr['abs_path']) tags = getattr(resmodule, 'tags', '') if tags and not self.application.checkResourcePermission( tags, self.userTags): if node.label == '_doc': forbiddenNodes.append('.'.join(_pathlist)) return caption = getattr(resmodule, 'caption', node.label) description = getattr(resmodule, 'description', '') description = getattr(resmodule, 'needSelection', True) if node.label == '_doc': result.setAttr( '.'.join(_pathlist), dict(caption=caption, description=description, tags=tags, has_parameters=has_parameters)) else: mainclass = getattr(resmodule, 'Main', None) assert mainclass, 'Main class is mandatory in tablescript resource' has_parameters = hasattr(mainclass, 'parameters_pane') result.setItem('.'.join(_pathlist + [node.label]), None, caption=caption, description=description, resource=node.attr['rel_path'][:-3], has_parameters=has_parameters) pl = [] resources.walk(cb, _pathlist=pl) if '_common' in result: n = result.popNode('_common') if len(result): result.setItem('r_zz', None, caption='-') result.setItem(n.label, n.value, n.attr) for forbidden in forbiddenNodes: result.pop(forbidden) return result
def getMenuBag(self,root_id=None,userTags=None,exportMode=None): root_id = root_id or self.rootId() q = self.query(where="$hierarchical_pkey LIKE :root_id || '/%%' " , root_id=root_id,columns='*,$hlevel,$page_label,$page_filepath,$page_tbl,$page_metadata', order_by='$_h_count') f = q.fetch() if not f: return result = Bag() app = self.db.application forbidden = [] for i,r in enumerate(f): if userTags is True or (app.checkResourcePermission(r['tags'], userTags) and not r['parent_id'] in forbidden): kw = dict() r = dict(r) if r['page_id']: kw['table'] = r.pop('page_tbl',None) kw['file'] = r.pop('page_filepath',None) if r['page_metadata']: kw.update(asDict(r['page_metadata'])) labelClass = 'menu_shape menu_page' else: kw['isDir'] = True labelClass='menu_shape menu_level_%i' %(r['hlevel']-2) if not exportMode: kw['labelClass'] = labelClass result.setItem(r['hierarchical_pkey'].split('/')[1:],None,label=r['label'],tags=r['tags'], **kw) else: forbidden.append(r['id']) empty = True while empty: empty = False for pathlist,n in result.getIndex(): if n.attr.get('isDir') and ( (n.value is None) or not n.value): result.popNode(pathlist) empty = True return result
def table_script_resource_tree_data(self, table=None, res_type=None): #pkg,tblname = table.split('.') tblobj = self.db.table(table) pkg = tblobj.pkg.name tblname = tblobj.name result = Bag() resources = self.site.resource_loader.resourcesAtPath(page=self,pkg=None,path='tables/_default/%s' % res_type) resources_pkg = self.site.resource_loader.resourcesAtPath(page=self,pkg=pkg, path='tables/%s/%s' % (tblname, res_type)) resources_custom = self.site.resource_loader.resourcesAtPath(page=self,pkg=self.package.name, path='tables/_packages/%s/%s/%s' % (pkg,tblname, res_type)) resources.update(resources_pkg) resources.update(resources_custom) forbiddenNodes = [] def cb(node, _pathlist=None): has_parameters = False if node.attr['file_ext'] == 'py': resmodule = gnrImport(node.attr['abs_path']) tags = getattr(resmodule, 'tags', '') if tags and not self.application.checkResourcePermission(tags, self.userTags): if node.label == '_doc': forbiddenNodes.append('.'.join(_pathlist)) return caption = getattr(resmodule, 'caption', node.label) description = getattr(resmodule, 'description', '') description = getattr(resmodule, 'needSelection', True) if node.label == '_doc': result.setAttr('.'.join(_pathlist), dict(caption=caption, description=description, tags=tags, has_parameters=has_parameters)) else: mainclass = getattr(resmodule, 'Main', None) assert mainclass, 'Main class is mandatory in tablescript resource' has_parameters = hasattr(mainclass, 'parameters_pane') result.setItem('.'.join(_pathlist + [node.label]), None, caption=caption, description=description, resource=node.attr['rel_path'][:-3], has_parameters=has_parameters) pl=[] resources.walk(cb,_pathlist=pl) if '_common' in result: n = result.popNode('_common') if len(result): result.setItem('r_zz',None,caption='-') result.setItem(n.label,n.value,n.attr) for forbidden in forbiddenNodes: result.pop(forbidden) return result
class SharedObject(object): default_savedir = 'site:async/sharedobjects' def __init__(self,manager,shared_id,expire=None,startData=None,read_tags=None,write_tags=None, filepath=None, dbSaveKw=None, saveInterval=None, autoSave=None, autoLoad=None,**kwargs): self.manager = manager self.lock=locks.Lock() self.server = manager.server self.shared_id = shared_id self._data = Bag(dict(root=Bag(startData))) self.read_tags = read_tags self.write_tags = write_tags self._data.subscribe('datachanges', any=self._on_data_trigger) self.subscribed_pages = dict() self.expire = expire or 0 self.focusedPaths = {} if self.expire<0: self.expire = 365*24*60*60 self.timeout=None self.autoSave=autoSave self.saveInterval=saveInterval self.autoLoad=autoLoad self.changes=False self.dbSaveKw=dbSaveKw self.onInit(**kwargs) @property def savepath(self): return self.server.gnrsite.getStaticPath(self.default_savedir,'%s.xml' %self.shared_id) @property def data(self): return self._data['root'] @property def sql_data_column(self): return self.dbSaveKw.get('data_column') or 'shared_data' @property def sql_backup_column(self): return self.dbSaveKw.get('backup_column') or 'shared_backup' @lockedThreadpool def save(self): if self.changes : if self.dbSaveKw: kw = dict(self.dbSaveKw) tblobj = self.server.db.table(kw.pop('table')) handler = getattr(tblobj, 'saveSharedObject', None) if handler: handler(self.shared_id, self.data, **kw) else: self.sql_save(tblobj) self.server.db.commit() else: self.data.toXml(self.savepath,unresolved=True,autocreate=True) self.changes=False @lockedThreadpool def load(self): if self.dbSaveKw: tblobj = self.server.db.table(self.dbSaveKw['table']) handler = getattr(tblobj, 'loadSharedObject', None) if handler: data = handler(self.shared_id) else: data = self.sql_load(tblobj) elif os.path.exists(self.savepath): data = Bag(self.savepath) else: data = Bag() self._data['root'] = data self.changes=False def sql_save(self, tblobj): backup = self.dbSaveKw.get('backup') data_column = self.sql_data_column with tblobj.recordToUpdate(self.shared_id) as record: if not self.data: print 'NO DATA IN SAVING', self.shared_id record[data_column] = deepcopy(self.data) onSavingHandler=getattr(tblobj, 'shared_onSaving',None) if onSavingHandler: onSavingHandler(record) if backup: backup_column = self.sql_backup_column if not record[backup_column]: record[backup_column] = Bag() n = 0 else: n = int(record[backup_column].keys()[-1].split('_')[1])+1 record[backup_column].setItem('v_%s' % n, record[data_column], ts=datetime.now()) if len (record[backup_column]) > backup: record[backup_column].popNode('#0') def sql_load(self, tblobj, version=None): record = tblobj.record(self.shared_id).output('bag') onLoadingHandler=getattr(tblobj, 'shared_onLoading',None) if onLoadingHandler: onLoadingHandler(record) if not version: return record[self.sql_data_column] else: return record[self.sql_backup_column].getItem('v_%i'% version) def onInit(self,**kwargs): if self.autoLoad: self.load() def onSubscribePage(self,page_id): pass #print 'onSubscribePage',self.shared_id,page_id def onUnsubscribePage(self,page_id): pass #print 'onUnsubscribePage',self.shared_id,page_id def onDestroy(self): print 'onDestroy',self.shared_id if self.autoSave: self.save() def onShutdown(self): if self.autoSave: self.save() def subscribe(self,page_id=None,**kwargs): page = self.server.pages[page_id] privilege= self.checkPermission(page) if privilege: page.sharedObjects.add(self.shared_id) subkwargs=dict(kwargs) subkwargs['page_id']=page_id subkwargs['user']=page.user self.subscribed_pages[page_id] = subkwargs self.server.sharedStatus.sharedObjectSubscriptionAddPage(self.shared_id,page_id,subkwargs) self.onSubscribePage(page) result=dict(privilege=privilege,data=self.data) return result def unsubscribe(self,page_id=None): self.subscribed_pages.pop(page_id,None) self.server.sharedStatus.sharedObjectSubscriptionRemovePage(self.shared_id,page_id) self.onUnsubscribePage(page_id) if not self.subscribed_pages: self.timeout=self.server.delayedCall(self.expire,self.manager.removeSharedObject,self) def checkPermission(self,page): privilege = 'readwrite' if self.read_tags and not self.server.gnrapp.checkResourcePermission(self.read_tags,page.userTags): privilege = None elif self.write_tags and not self.server.gnrapp.checkResourcePermission(self.write_tags,page.userTags): privilege = 'readonly' return privilege @lockedCoroutine def datachange(self,page_id=None,path=None,value=None,attr=None,evt=None,fired=None,**kwargs): if fired: data = Bag(dict(value=value,attr=attr,path=path,shared_id=self.shared_id,evt=evt,fired=fired)) self.broadcast(command='som.sharedObjectChange',data=data,from_page_id=page_id) else: path = 'root' if not path else 'root.%s' %path if evt=='del': self._data.popNode(path,_reason=page_id) else: self._data.setItem(path,value,_attributes=attr,_reason=page_id) def _on_data_trigger(self, node=None, ind=None, evt=None, pathlist=None,reason=None, **kwargs): self.changes=True if reason=='autocreate': return plist = pathlist[1:] if evt=='ins' or evt=='del': plist = plist+[node.label] path = '.'.join(plist) data = Bag(dict(value=node.value,attr=node.attr,path=path,shared_id=self.shared_id,evt=evt)) from_page_id = reason self.broadcast(command='som.sharedObjectChange',data=data,from_page_id=from_page_id) def onPathFocus(self, page_id=None,curr_path=None,focused=None): if focused: self.focusedPaths[curr_path]=page_id else: self.focusedPaths.pop(curr_path,None) self.broadcast(command='som.onPathLock',from_page_id=page_id,data=Bag(dict(locked=focused,lock_path=curr_path))) def broadcast(self,command=None, data=None, from_page_id=None,): envelope = Bag(dict(command=command,data=data)).toXml() channels = self.server.channels for p in self.subscribed_pages.keys(): if p != from_page_id: channels.get(p).write_message(envelope)