Example #1
0
	def __init__(self, pattern, destination_path, regexp_flags=re.I, match_on_full_url=False, 
							 methods=None, params={}):
		'''Create a new regular expressions-based filter.
		
		:param pattern:					 Pattern
		:type	pattern:					 string or re.Regex
		
		:param destination_path:	Path to leaf, expressed in internal canonical form.
															i.e. "/controller/leaf".
		:type	destination_path:	string
		
		:param regexp_flags:			Defaults to ``re.I`` (case-insensitive)
		:type	regexp_flags:			int
		
		:param match_on_full_url: Where there or not to perform matches on complete
															URL (i.e. "https://foo.tld/bar?question=2").
															Defauts to False (i.e.matches on path only. "/bar")
		:type	match_on_full_url: bool
		
		:param params:						Parameters are saved and later included in every call to
															leafs taking this route.
		:type	params:						dict
		'''
		if not isinstance(regexp_flags, int):
			regexp_flags = 0
		
		if isinstance(pattern, RegexType):
			self.pattern = pattern
		elif not isinstance(pattern, basestring):
			raise ValueError('first argument "pattern" must be a Regex object or a string, not %s'\
				% type(pattern).__name__)
		else:
			self.pattern = re.compile(pattern, regexp_flags)
		
		if not isinstance(destination_path, (basestring, URL)):
			raise ValueError('second argument "destination_path" must be a string or URL, not %s'\
				% type(destination_path).__name__)
		
		self.destination_path = _prep_path(destination_path)
		self.match_on_full_url = match_on_full_url
		self.params = params
		
		if isinstance(methods, (list, tuple)):
			self.methods = methods
		elif methods is not None:
			if not isinstance(methods, basestring):
				raise TypeError('methods must be a tuple or list of strings, '\
					'alternatively a string, not a %s.' % type(methods))
			self.methods = (methods,)
		else:
			self.methods = None
Example #2
0
 def format_members(cls, o, colorize=False):
   s = []
   items = []
   longest_k = 0
   types = {}
   type_i = 0
   color = 0
   
   for k in dir(o):
     v = getattr(o,k)
     if len(k) > longest_k:
       longest_k = len(k)
     if colorize:
       t = str(type(v))
       if t not in types:
         types[t] = type_i
         type_i += 1
       color = 31 + (types[t] % 5)
     items.append((k,v,color))
   
   if colorize:
     pat = '\033[1;%%dm%%-%ds\033[m = \033[1;%%dm%%s\033[m' % longest_k
   else:
     pat = '%%-%ds = %%s' % longest_k
   
   for k,v,color in items:
     v = cls._repr.repr(v)
     if colorize:
       s.append(pat % (color, k, color, v))
     else:
       s.append(pat % (k, v))
   
   return '\n'.join(s)
Example #3
0
 def send_response(self, rsp):
   '''Send the response to the current client, finalizing the current HTTP
   transaction.
   '''
   # Empty rsp
   if rsp is None:
     # The leaf might have sent content using low-level functions,
     # so we need to confirm the response has not yet started and 
     # a custom content length header has not been set.
     if not self.response.has_begun:
       self.response.adjust_status(False)
     return
   
   # Add headers if the response has not yet begun
   if not self.response.has_begun:
     # Add Content-Length header
     if self.response.find_header('Content-Length:') == -1:
       self.response.headers.append('Content-Length: %d' % len(rsp))
     # Add Content-Type header
     self.response.serializer.add_content_type_header(self.response, self.response.charset)
     # Has content or not?
     if len(rsp) > 0:
       # Make sure appropriate status is set, if needed
       self.response.adjust_status(True)
       # Add ETag if enabled
       etag = config.get('smisk.mvc.etag')
       if etag is not None and self.response.find_header('ETag:') == -1:
         h = etag(''.join(self.response.headers))
         h.update(rsp)
         self.response.headers.append('ETag: "%s"' % h.hexdigest())
     else:
       # Make sure appropriate status is set, if needed
       self.response.adjust_status(False)
   
   # Debug print
   if log.level <= logging.DEBUG:
     self._log_debug_sending_rsp(rsp)
   
   # Send headers
   self.response.begin()
   
   # Head does not contain a payload, but all the headers should be exactly
   # like they would with a GET. (Including Content-Length)
   if self.request.method != 'HEAD':
     # Send body
     if __debug__:
       assert isinstance(rsp, str), 'type(rsp) == %s' % type(rsp)
     self.response.write(rsp)
Example #4
0
	def _resolve(self, raw_path):
		# Tokenize path
		path = tokenize_path(raw_path)
		node = control.root_controller()
		cls = node
		
		log.debug('resolving %s (%r) on tree %r', raw_path, path, node)
		
		# Check root
		if node is None:
			return wrap_exc_in_callable(http.ControllerNotFound('No root controller exists'))
		
		# Special case: empty path == root.__call__
		if not path:
			try:
				node = node().__call__
				log.debug('found leaf: %s', node)
				return node
			except AttributeError:
				return wrap_exc_in_callable(http.MethodNotFound('/'))
		
		# Traverse tree
		for part in path:
			log.debug('looking at part %r', part)
			found = None
			
			# 1. Search subclasses first
			log.debug('matching %r to subclasses of %r', part, node)
			try:
				subclasses = node.__subclasses__()
			except AttributeError:
				log.debug('node %r does not have subclasses -- returning MethodNotFound')
				return wrap_exc_in_callable(http.MethodNotFound(raw_path))
			for subclass in node.__subclasses__():
				if _node_name(subclass, subclass.controller_name()) == part:
					if getattr(subclass, 'hidden', False):
						continue
					found = subclass
					break
			if found is not None:
				node = found
				cls = node
				continue
			
			# 2. Search methods
			log.debug('matching %r to methods of %r', part, node)
			# Aquire instance
			if type(node) is type:
				node = node()
			for k,v in node.__dict__.items():
				if _node_name(v, k.lower()) == part:
					# If the leaf is hidden, we skip it
					if getattr(v, 'hidden', False):
						continue
					# If the leaf is not defined directly on parent node node, and
					# node.delegate evaluates to False, we bail out
					if not control.leaf_is_visible(v, cls):
						node = None
					else:
						found = v
					break
			
			# Check found node
			if found is not None:
				node = found
				node_type = type(node)
				# The following two lines enables accepting prefix routes:
				#if node_type is MethodType or node_type is FunctionType:
				#	break
			else:
				# Not found
				return wrap_exc_in_callable(http.MethodNotFound(raw_path))
		
		# Did we hit a class/type at the end? If so, get its instance.
		if type(node) is type:
			try:
				cls = node
				node = cls().__call__
				if not control.leaf_is_visible(node, cls):
					node = None
			except AttributeError:
				# Uncallable leaf
				node = None
		
		# Not callable?
		if node is None or not callable(node):
			return wrap_exc_in_callable(http.MethodNotFound(raw_path))
		
		log.debug('found leaf: %s', node)
		return node