def get_descriptor(self, ident): user = identity.get_user_id() if user not in self.d: self.d[user] = {} d = self.d[user] if ident not in d: d[ident] = ResourceDescriptor(ident) return d[ident]
def cache_save(self, url, user_id=None, response=None, **kw): args = ["%s=%s" % (k, v) for k, v in sorted(kw.items())] full_url = "%s?%s" % (url, "&".join(args)) log.debug("CACHE SAVE url %s", full_url) if user_id is None and identity.not_anonymous(): user_id = identity.get_user_id() self.server_cache.save(full_url, {'Content-Type': 'text/xml'}, response, user_id)
def cache_check(self, url, user_id=None, **kw): args = ["%s=%s" % (k, v) for k, v in sorted(kw.items())] full_url = "%s?%s" % (url, "&".join(args)) if user_id is None and identity.not_anonymous(): user_id = identity.get_user_id() log.debug("CACHE CHECK url %s", full_url) header, response = self.server_cache.fetch(full_url, user_id) return response
def __init__(self, resource_type = None, parent = None, owner_id = None, mex_id = None): """Create a taggable resource : not usually called directly @param resource_type: A string type of the new resource i.e. user, project etc. @param parent: A parent of the resource or None @owner_id: An integer ID, a BQUser, current user if None, False : don't set @mex_id: An integer ID, A ModuleExecution, current mex if None, or False : don't set """ if resource_type is None: resource_type = self.xmltag self.resource_type = resource_type # By defualt you are the document if parent: parent.children.append(self) self.document = parent.document self.perm = parent.perm self.hidden = parent.hidden else: self.document = self self.resource_uniq = make_uniq_code() self.perm = PRIVATE #self.hidden = None #if self.resource_type == 'mex': # self.mex = self # session['mex'] = self #if self.resource_type == 'user': # self.owner = self self.ts = datetime.now() #log.debug("new taggable user:"******"mex_id = %s" , mex_id) if mex_id is not None: log.debug ("setting mex_id %s" , mex_id) self.mex_id = mex_id if owner_id is not False: owner_id = owner_id or identity.get_user_id() if owner_id is not None: if isinstance(owner_id, Taggable): self.owner = owner_id else: self.owner_id = owner_id else: log.warn ("CREATING taggable %s with no owner" , str(self) ) admin = identity.get_admin() if admin: log.warn("Setting owner to admin") self.owner_id = admin.id
def delete(self, resource, **kw): """DELETE /ds/images/1/tags/2 : delete a specific resource """ log.info('DELETE %s', request.url) user = kw.pop('user', None) if user is not None and identity.is_admin(): self.set_new_identity(user) resource = self.check_access(resource, RESOURCE_EDIT) response = etree.Element('resource') if resource is not None: uri = resource.uri resource_delete(resource, user_id=identity.get_user_id()) response.set('uri', uri) return self.resource_output(resource=None, response=response, **kw)
def cache_invalidate_resource(self, resource, user_id=None): if user_id is None and identity.not_anonymous(): user_id = identity.get_user_id() self.server_cache.invalidate_resource(resource, user_id)
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
def _default(self, *path, **kw): request = tg.request response = tg.response path = list(path) resource = None if not hasattr(request, 'bisque'): bisque = Bunch() request.bisque = bisque bisque = request.bisque user_id = identity.get_user_id() usecache = asbool(kw.pop('cache', True)) http_method = request.method.lower() log.debug('Request "%s" with %s?%s', http_method, request.path, str(kw)) #log.debug ('Request "%s" ', path) #check the http method is supported. try: method_name = dict(get='get', head='check', post='append', put='modify', delete='delete')[http_method] except KeyError: abort(501) if not path: #If the request path is to a collection. #self.check_cache_header(http_method, resource) if http_method == 'post': #If the method is a post, we call self.create which returns #a class which is passed into the self.new method. resource = self.create(**kw) assert resource is not None method_name = 'new' elif http_method == 'get': resource = getattr(request.bisque, 'parent', None) method_name = 'dir' # if parent: # self.check_cache_header (http_method, parent) # #If the method is a get, call the self.index method, which # #should list the contents of the collection. # accept_header = headers = value = None # if usecache: # headers, value = self.server_cache.fetch(request.url, user=user_id) # if headers: # _, accept_header = find_formatter (accept_header=request.headers.get ('accept')) # content_type = headers.get ('Content-Type') # if value and accept_header == content_type: # response.headers.update(headers) # cherrypy.response.headers.update (headers) # else: # #self.add_cache_header(None) # value = self.dir(**kw) # self.server_cache.save (request.url, # response.headers, # value, user=user_id) # #self.add_cache_header(resource) # return value elif http_method == 'put': resource = getattr(bisque, 'parent', None) method_name = 'replace_all' elif http_method == 'delete': resource = getattr(bisque, 'parent', None) method_name = 'delete_all' elif http_method == 'head': # Determine whether the collection has changed resource = getattr(bisque, 'parent', None) method_name = "check" else: #Any other methods get rejected. abort(501) if resource is None and method_name != 'dir': #if we don't have a resource by now, (it wasn't created) #then try and load one. if path: token = path.pop(0) resource = self.load(token) if resource is None: #No resource found? if user_id is None: abort(401) abort(404) #if we have a path, check if the first token matches this #classes children. if path: token = path.pop(0) log.debug('Token: ' + str(token)) child = self.get_child_resource(token) if child is not None: bisque.parent = resource log.debug("parent = %s", str(resource)) #call down into the child resource. return child._default(*path, **kw) # if http_method == 'get': # #if this resource has children, make sure it has a '/' # #on the end of the URL # if getattr(self, 'children', None) is not None: # if request.path[-1:] != '/': # redirect(request.path + "/") #resource = self.server_cache.force_load(resource) self.check_cache_header(http_method, resource) method = getattr(self, method_name) #pylons.response.headers['Content-Type'] = 'text/xml' log.debug("Dispatch for %s", method_name) try: if http_method in ('post', 'put'): clen = int(request.headers.get('Content-Length', 0)) content_type = request.headers.get('Content-Type') inputer = find_inputer(content_type) if not inputer: log.debug("Bad media type in post/put:%s", content_type) abort(415, "Bad media type in post/put:%s" % content_type) # xml arg is for backward compat value = method(resource, xml=inputer(request.body_file, clen), **kw) # if content.startswith('text/xml') or \ # content.startswith('application/xml'): # data = request.body_file.read(clen) # #log.debug('POST '+ data) # #kw['xml_text'] = data # value = method(resource, xml=data, **kw) # elif content.startswith("application/json"): # try: # #data = request.body_file.read(clen) # data = d2xml (json.load (request.body_file)) # value = method(resource, xml=data, **kw) # except Exception as e: # log.exception ("while reading json content") # abort(415, "Bad media type in post/put:%s" % content ) # else: # #response = method(resource, doc = None, **kw) # # Raise illegal operation (you should provide XML) # log.debug ("Bad media type in post/put:%s" , content) # abort(415, "Bad media type in post/put:%s" % content ) # #self.server_cache.invalidate(request.url, user=user_id) self.server_cache.invalidate_resource(resource, user=user_id) elif http_method == 'delete': self.server_cache.invalidate_resource(resource, user=user_id) value = method(resource, **kw) #self.server_cache.invalidate(request.url, user=user_id) elif http_method == 'get': accept_header = headers = value = None if usecache: headers, value = self.server_cache.fetch(request.url, user=user_id) if headers: content_type = headers.get('Content-Type') _, accept_header = find_formatter( accept_header=request.headers.get('accept')) if value and accept_header == content_type: response.headers.update(headers) return value else: #run the requested method, passing it the resource value = method(resource, **kw) # SET content length? self.server_cache.save(request.url, response.headers, value, user=user_id) self.add_cache_header(resource) else: # http_method == HEAD value = method(resource, **kw) #set the last modified date header for the response return value except identity.BQIdentityException: response.status_int = 401 return "<response>FAIL</response>"
def invalidate_resource(self, resource): self.server_cache.invalidate_resource(resource, user=identity.get_user_id())
def invalidate(self, url): self.server_cache.invalidate(url, user=identity.get_user_id())