def __init__(self, name): self.name = name parts = name.split('.') key = parts.pop() if '[' in key: i = key.index('[') parts.append(key[:i]) key = key[i:] for n in parts: if not self._param_re.match(n): raise Error, 'invalid parameter: %s' % name # support param["foo"] syntax for dicts if parts and key.startswith('[') and key.endswith(']'): key = unescape_quoted_string(key[1:-1]) if key.startswith('_'): raise TemplateSyntaxError(self, 'invalid dictionary key in: %s' % name) elif not self._param_re.match(key): raise Error, 'invalid parameter: %s' % name else: pass self.path = parts self.key = key
def __init__(self, name): self.name = name parts = name.split('.') key = parts.pop() if '[' in key: i = key.index('[') parts.append(key[:i]) key = key[i:] for n in parts: if not self._param_re.match(n): raise Error, 'invalid parameter: %s' % name # support param["foo"] syntax for dicts if parts and key.startswith('[') and key.endswith(']'): key = unescape_quoted_string(key[1:-1]) if key.startswith('_'): raise TemplateSyntaxError( self, 'invalid dictionary key in: %s' % name) elif not self._param_re.match(key): raise Error, 'invalid parameter: %s' % name else: pass self.path = parts self.key = key
def parse_list(string): list = TemplateParamList() for i, w in enumerate( split_quoted_strings(string, unescape=False) ): if i % 2: if w != ',': raise TemplateSyntaxError(self, string) elif w.startswith('"') or w.startswith("'"): list.append(TemplateLiteral(unescape_quoted_string(w))) else: list.append(TemplateParam(w)) return list
def parse_list(string): list = TemplateParamList() for i, w in enumerate(split_quoted_strings(string, unescape=False)): if i % 2: if w != ',': raise TemplateSyntaxError(self, string) elif w.startswith('"') or w.startswith("'"): list.append(TemplateLiteral(unescape_quoted_string(w))) else: list.append(TemplateParam(w)) return list
def _parse_query(self, string): words = split_quoted_strings(string, unescape=False) tokens = [] while words: w = words.pop(0) if w.lower() in operators: tokens.append(operators[w.lower()]) elif keyword_re.match(w): keyword = keyword_re[1].lower() term = keyword_re[2] or words.pop(0) term = unescape_quoted_string(term) tokens.append((keyword, term)) else: w = unescape_quoted_string(w) tokens.append(("content", w)) # default keyword # ~ print tokens root = AndGroup() while tokens: token = tokens.pop(0) if token in (OPERATOR_AND, OPERATOR_OR): pass # AND is the default, OR shoulds not appear here, ignore silently elif tokens and tokens[0] == OPERATOR_OR: # collect terms joined by OR assert isinstance(token, tuple) group = [token] while len(tokens) >= 2 and tokens[0] == OPERATOR_OR and isinstance(tokens[1], tuple): tokens.pop(0) group.append(tokens.pop(0)) root.append(OrGroup(group)) else: # simple term in AND group assert isinstance(token, tuple) root.append(token) # ~ print root return root
def parse_expr(self, string): '''This method parses an expression and returns an object of either class TemplateParam, TemplateParamList or TemplateFuntionParam. (All these classes have a method "evaluate()" which takes an TemplateDict as argument and returns a value for the result of the expression.) ''' string = string.strip() def parse_list(string): list = TemplateParamList() for i, w in enumerate( split_quoted_strings(string, unescape=False) ): if i % 2: if w != ',': raise TemplateSyntaxError(self, string) elif w.startswith('"') or w.startswith("'"): list.append(TemplateLiteral(unescape_quoted_string(w))) else: list.append(TemplateParam(w)) return list if string.startswith('[') and string.endswith(']'): # list like ['foo', 'bar', page.title] return parse_list(string[1:-1]) elif string.startswith('"') or string.startswith("'"): # quoted string return TemplateLiteral(unescape_quoted_string(string)) elif string.find('(') > 0: # function like foo('bar', page.title) i = string.find('(') name = string[:i] args = parse_list(string[i+1:-1]) return TemplateFunctionParam(name, args) else: return TemplateParam(string)
def parse_expr(self, string): '''This method parses an expression and returns an object of either class TemplateParam, TemplateParamList or TemplateFuntionParam. (All these classes have a method "evaluate()" which takes an TemplateDict as argument and returns a value for the result of the expression.) ''' string = string.strip() def parse_list(string): list = TemplateParamList() for i, w in enumerate(split_quoted_strings(string, unescape=False)): if i % 2: if w != ',': raise TemplateSyntaxError(self, string) elif w.startswith('"') or w.startswith("'"): list.append(TemplateLiteral(unescape_quoted_string(w))) else: list.append(TemplateParam(w)) return list if string.startswith('[') and string.endswith(']'): # list like ['foo', 'bar', page.title] return parse_list(string[1:-1]) elif string.startswith('"') or string.startswith("'"): # quoted string return TemplateLiteral(unescape_quoted_string(string)) elif string.find('(') > 0: # function like foo('bar', page.title) i = string.find('(') name = string[:i] args = parse_list(string[i + 1:-1]) return TemplateFunctionParam(name, args) else: return TemplateParam(string)
def _parse_query(self, string): # First do a raw tokenizer words = split_quoted_strings(string, unescape=False, strict=False) tokens = [] while words: if operators_re.match(words[0]): w = operators_re[0] words[0] = words[0][len(w):] else: w = words.pop(0) if w.lower() in operators: tokens.append(operators[w.lower()]) elif keyword_re.match(w): keyword = keyword_re[1].lower() string = keyword_re[2] or words.pop(0) string = unescape_quoted_string(string) if keyword == 'links': keyword = 'linksfrom' tokens.append(QueryTerm(keyword, string)) else: w = unescape_quoted_string(w) if tag_re.match(w): tokens.append(QueryTerm('tag', w[1:])) else: tokens.append(QueryTerm('contentorname', w)) # default keyword #~ print tokens # Then parse NOT operator out tokens, mytokens = [], tokens while mytokens: token = mytokens.pop(0) if token == OPERATOR_NOT: if mytokens and isinstance(mytokens[0], QueryTerm): token = mytokens.pop(0) token.inverse = True tokens.append(token) else: pass # ignore else: tokens.append(token) #~ print tokens # Finally group in AND and OR groups root = QueryGroup(OPERATOR_AND) while tokens: token = tokens.pop(0) if isinstance(token, QueryTerm): if tokens and tokens[0] == OPERATOR_OR: # collect terms joined by OR assert isinstance(token, QueryTerm) group = QueryGroup(OPERATOR_OR) group.append(token) while len(tokens) >= 2 and tokens[0] == OPERATOR_OR \ and isinstance(tokens[1], QueryTerm): tokens.pop(0) group.append(tokens.pop(0)) root.append(group) else: # simple term in AND group root.append(token) else: assert token in (OPERATOR_AND, OPERATOR_OR) pass # AND is the default, OR should not appear here, ignore silently #~ print root return root