def retrieve(self, resource_tag, tag_query=None, **kw): view = kw.pop('view', None) resource_type = dbtype_from_tag(resource_tag) log.debug('retrieving type %s', resource_type) nodes = resource_query(resource_type, tag_query, **kw) response = etree.Element('resource') db2tree(nodes, parent=response, view=view, baseuri=self.url) log.debug("tree converted: %s", view) #log.debug("tree converrted: %s" % etree.tostring(response)) return response
def new_resource(self, resource, parent=None, flush=True, **kw): '''Create a new resouce in the local database based on the resource tree given. ''' view = kw.pop('view', None) if isinstance(resource, basestring): log.debug('attributes= %s ', kw) resource = etree.Element(resource, **kw) log.debug('created %s ', resource) if parent is None and resource.get('resource_uniq') is None: resource.set('resource_uniq', self.resource_uniq()) else: if isinstance(parent, etree._Element): parent = parent.get('uri') if isinstance(parent, basestring): parent = load_uri(parent) node = bisquik2db(doc=resource, parent=parent) log.debug("new_resource %s", node) # Invalidate the top level container i.e. /data_service/<resource_type> #self.cache_invalidate(r.get('uri').rsplit('/', 1)[0]) if flush: self.flushchanges(node, parent) self.cache_invalidate_resource(node) r = db2tree(node, baseuri=self.url, view=view) return r
def update_resource(self, resource, new_resource=None, replace=True, flush=True, **kw): """update a resource with a new values @param resource: an etree element or uri @param new_resource: an etree element if resource is a uri @param replace: replace all members (if false then appends only) @param kw: view parameters for return """ uri = None log.debug('resource = %s' % resource) if isinstance(resource, etree._Element): uri = resource.get('uri') elif isinstance(resource, basestring): uri = resource if new_resource is None: raise BadValue( 'update_resource uri %s needs new_value to update ' % uri) if uri is not None: resource = load_uri(uri) log.debug('resource %s = %s' % (uri, resource)) node = bisquik2db(doc=new_resource, resource=resource, replace=replace) #response = etree.Element ('response') #self.cache_invalidate(r.get('uri')) if flush: self.flushchanges(node) self.cache_invalidate_resource(resource) r = db2tree(node, baseuri=self.url, **kw) return r
def query(self, resource_tag=None, parent=None, cache=True, **kw): '''Query the local database with expr''' #resource_type = dbtype_from_tag(resource_tag) parent_uri = getattr(parent, 'uri', None) if isinstance(parent, etree._Element): parent = parent.get('uri') if isinstance(parent, basestring): parent_uri = parent parent = load_uri(parent) log.debug('query: %s %s %s', resource_tag, parent_uri, kw) uri = "%s/%s" % (parent_uri or self.url, resource_tag or '') if cache: response = self.cache_check(uri, **kw) if response: xml = etree.XML(response) return xml params = kw.copy() view = params.pop('view', None) if view == 'count': count = resource_count(resource_tag, parent=parent, **params) response = etree.Element('resource') etree.SubElement(response, resource_tag or 'resource', count=str(count)) else: nodelist = resource_query(resource_tag, parent=parent, **params) if view == 'query': return nodelist full_url = "%s?%s" % (uri, "&".join("%s=%s" % (k, v) for k, v in kw.items())) response = etree.Element('resource', uri=full_url) db2tree(nodelist, parent=response, view=view, baseuri=self.url, **params) if cache: self.cache_save(uri, response=etree.tostring(response), **kw) #log.debug ("DS: " + etree.tostring(response)) return response
def append_resource(self, resource, tree=None, flush=True, **kw): '''Append an element to resource (a node) ''' if isinstance(resource, etree._Element): uri = resource.get('uri') resource = load_uri(uri) dbresource = bisquik2db(doc=tree, parent=resource) #self.cache_invalidate(r.get('uri')) if flush: self.flushchanges(dbresource, resource) self.cache_invalidate_resource(dbresource) r = db2tree(dbresource, baseuri=self.url, **kw) return r
def update(self, resource_tree, replace_all=False, flush=True, **kw): view = kw.pop('view', None) #if replace_all: # uri = resource_tree.get ('uri') # r = load_uri(resource_tree.get('uri')) # r.clear() resource = bisquik2db(doc=resource_tree, replace=replace_all) #response = etree.Element ('response') #self.cache_invalidate(r.get('uri')) if flush: self.flushchanges(resource) self.cache_invalidate_resource(resource) r = db2tree(resource, parent=None, view=view, baseuri=self.url) return r
def resource_load(self, uniq=None, ident=None, action=RESOURCE_READ, view=None): "Load a resource by uniq code or db ident (deprecated)" query = resource_load('resource', uniq=uniq, ident=ident) query = resource_permission(query, action=action) resource = query.first() if resource: xtree = db2tree(resource, baseuri=self.url, view=view) return xtree log.debug("load failure for resource %s", uniq) return None
def resource_output(self, resource, response=None, view=None, format=None, progressive=False, **kw): #if response is None: log.debug("resource_outtput %s", self.uri) DBSession.flush() if isinstance(resource, list): response = etree.Element('resource') db2tree(resource, view=view, parent=response, baseuri=self.uri) elif resource is not None: response = db2tree(resource, view=view, parent=response, baseuri=self.uri, **kw) #transaction.commit() accept_header = tg.request.headers.get('accept') formatter, content_type = find_formatter(format, accept_header) tg.response.headers['Content-Type'] = content_type return formatter(response, view=view)
def get_resource(self, resource, **kw): uri = None if isinstance(resource, etree._Element): uri = resource.get('uri') elif isinstance(resource, basestring): uri, params = strip_url_params(resource) params.update(kw) kw = params #log.debug ("get_resource %s %s", uri, str(kw)) if uri is not None: log.debug("get_resource %s %s", uri, str(kw)) response = self.cache_check(uri, **kw) if response: log.debug("get_resource:CACHE response") try: xml = etree.XML(response) return xml except etree.XMLSyntaxError: log.exception(' while reading cached resourced %s got %s', uri, response) service, clname, ida, rest = parse_bisque_uri(uri) resource = load_uri(uri, query=True) if rest: # Fetch resource is really a query log.debug("get_resource:QUERY %s %s %s ->", service, ida, rest) if resource is not None: resource = resource.first() resource = self.query(resource_tag=rest[-1], parent=resource, **kw) #self.cache_save (uri, response=etree.tostring(resource), **kw) #resource.set('uri', uri) return resource resource = prepare_permissions(resource, user_id=None, with_public=True) log.debug("got resource %s", str(resource)) resource = resource.first() log.debug("get_resource: uri %s -> %s", uri, str(resource)) if resource is None: return resource xtree = db2tree(resource, baseuri=self.url, **kw) uri = uri or xtree.get('uri') self.cache_save(uri, response=etree.tostring(xtree), **kw) return xtree
def load(self, resource_url, astree=False, **kw): """Simulate a webfetch """ log.debug('parsing %s', resource_url) #if resource_url.startswith(self.url): url = urlparse.urlsplit(resource_url) if url[3]: kwargs = dict([p.split('=') for p in url[3].split('&')]) kwargs.update(kw) else: kwargs = kw serverpath = urlparse.urlsplit(self.url)[2] commonurl = os.path.commonprefix([serverpath, url[2]]) requesturl = url[2][len(commonurl):] path = requesturl.rstrip('/').split('/') # remove initial /ds log.debug('path server(%s) req(%s) path( %s)', serverpath, url[2], path) log.debug('passing to self.default %s %s', path[2:], kwargs) format = kwargs.pop('format', None) view = kwargs.pop('view', None) parent = None controller = None def load_token(token): if is_uniq_code(token): return resource_load(uniq=token).first() try: token = int(token) return resource_load(ident=token).first() except ValueError: pass return None resource_type = None resource = None # Determine First element (force path to be TYPE/[ID] Pairs token = path.pop(0) resource = load_token(token) if resource: if path: parent = resource resource = None else: path.insert(0, token) # process as TYPE/[ID] pairs now while path: # Process type token = path.pop(0) resource_type = dbtype_from_name(token) # Process ID if path: token = path.pop(0) resource = load_token(token) # More path to process.. move it into parent if path: parent = resource resource = None #log.debug ("path=%s resource_type=%s resource=%s, parent=%s", path, resource_type, resource, parent) #log.debug ("final path=%s resource_type=%s resource=%s, parent=%s", path, resource_type, resource, parent) response = etree.Element('resource') if resource is None: # We are dealing with query if view == "count": count = resource_count(resource_type, parent=parent, **kwargs) xtag = resource_type[0] etree.SubElement(response, xtag, count=str(count)) else: resource = resource_query(resource_type, parent=parent, **kwargs) db2tree(resource, baseuri=self.url, view=view, parent=response, **kwargs) else: if view != "count": response = db2tree(resource, baseuri=self.url, view=view, parent=None, **kwargs) if astree: return response formatter, content_type = find_formatter(format) return formatter(response)
def dir(self, resource, **kw): """GET /ds/images : fetch group of object Create a listing of the resource. Several options are allowed view={short,full,deep},[clean],[canonical], tags=tag expression i.e. [TAG:]VAL [AND|OR [TAG:]VAL]+ xxx=val match an attribute on the resorce """ view = kw.pop('view', 'short') tag_query = kw.pop('tag_query', '') tag_order = kw.pop('tag_order', '') wpublic = kw.pop('wpublic', None) format = kw.pop('format', None) offset = int(kw.get('offset', 0)) progressive = kw.pop('progressive', False) permcheck = kw.pop( 'permcheck', None) # disallow from web side as will be pass in kw #limit = kw.pop('limit', None) log.info('DIR %s %s', request.url, self.uri) # Do not use loading #parent = getattr(request.bisque,'parent', None) parent = resource #specials = set(['tag_names', 'tag_values', 'gob_types']) if kw.pop('noparent', None): parent = False user_id = identity.get_user_id() if parent is None and view != 'count': if not isinstance(view, basestring): abort(400, "Illegal view parameter %s" % view) viewmap = { None: 1000000, 'short': 1000000, 'full': 10000, 'deep': 1000 } maxlimit = viewmap.get(view, 10000) limit = kw.pop('limit', None) or maxlimit limit = min(int(limit), maxlimit) kw['limit'] = str(limit) log.debug("limiting top level to %s", limit) else: limit = None params = kw.copy() newparams = dict(view=view, offset=offset, limit=limit, tag_query=tag_query, tag_order=tag_order, format=format, wpublic=wpublic) #params.update ( [(k, unicode(v).encode('utf8') ) for k,v in newparams.items() if v ]) params.update(newparams) params = dict([(k, unicode(v).encode('utf8')) for k, v in params.items() if v]) request_uri = "%s?%s" % (request.path, urllib.urlencode(params)) if view == 'count': limit = None count = resource_count(self.resource_type, parent=parent, user_id=user_id, tag_query=tag_query, tag_order=tag_order, wpublic=wpublic, **kw) xtag = self.resource_type[1].xmltag response = etree.Element('resource', uri=request_uri) etree.SubElement(response, 'tag', name="count", value=str(count), type="number") else: # Never return more than 1000 items in a top level query resources = resource_query( self.resource_type, parent=parent, user_id=user_id, tag_query=tag_query, tag_order=tag_order, wpublic=wpublic, #limit = limit, **kw) response = etree.Element('resource', uri=request_uri) db2tree(resources, parent=response, view=view, baseuri=self.uri, progressive=progressive, **kw) accept_header = tg.request.headers.get('accept') formatter, content_type = find_formatter(format, accept_header) tg.response.headers['Content-Type'] = content_type text_response = formatter(response, view=view) #ex = etree.XML (text_response) #log.debug ("text_response %d" % len(ex) ) return text_response