# HG changeset patch # User Ludovic Chabant # Date 1514970293 28800 # Node ID 8ca8c2713c92bd745037785aa31152a28c3d0982 # Parent 47690e0c55e6a102258c84f71a4f5ad0c3816ce6 web: Optimize the page resolver. diff -r 47690e0c55e6 -r 8ca8c2713c92 wikked/resolver.py --- a/wikked/resolver.py Wed Jan 03 00:58:22 2018 -0800 +++ b/wikked/resolver.py Wed Jan 03 01:04:53 2018 -0800 @@ -12,6 +12,27 @@ logger = logging.getLogger(__name__) +re_wiki_tag = re.compile( + r'^
( data-wiki-([a-z]+)="([^"]+)")*)' + r'>(?P.*)
$', + flags=re.MULTILINE) +re_wiki_tag_attr = re.compile( + r'data-wiki-(?P[a-z]+)="(?P[^"]+)"') +re_wiki_link = re.compile( + r'' + r'(?P.*?)') + +re_wiki_query_param = re.compile( + r'(^|\|)\s*(?P(__)?[a-zA-Z][a-zA-Z0-9_\-]+)\s*=(?P[^\|]+)') +re_wiki_query_template_ref = re.compile(r'^\[\[.*\]\]$') +re_wiki_query_local_meta = re.compile(r'^__[a-zA-Z][a-zA-Z0-9_\-]+$') + class FormatterNotFound(Exception): """ An exception raised when not formatter is found for the @@ -108,12 +129,13 @@ } def __init__(self, page, ctx=None, parameters=None, page_getter=None, - pages_meta_getter=None): + pages_meta_getter=None, can_use_resolved_meta=False): self.page = page self.ctx = ctx or ResolveContext(page) self.parameters = parameters self.page_getter = page_getter or self._getPage self.pages_meta_getter = pages_meta_getter or self._getPagesMeta + self.can_use_resolved_meta = can_use_resolved_meta self.output = None self.env = None @@ -146,7 +168,7 @@ return self.wiki.db.getPage(url, fields=fields) def _getPagesMeta(self): - fields = ['url', 'title', 'local_meta'] + fields = ['url', 'title', 'local_meta', 'meta'] return self.wiki.db.getPages(fields=fields) def _unsafeRun(self): @@ -178,9 +200,7 @@ meta_value = m.group('value') meta_opts = {} if m.group('opts'): - for c in re.finditer( - r'data-wiki-(?P[a-z]+)="(?P[^"]+)"', - m.group('opts')): + for c in re_wiki_tag_attr.finditer(m.group('opts')): opt_name = c.group('name') opt_value = c.group('value') meta_opts[opt_name] = opt_value @@ -190,13 +210,7 @@ return resolver(meta_opts, meta_value) return '' - final_text = re.sub( - r'^
( data-wiki-([a-z]+)="([^"]+)")*)' - r'>(?P.*)
$', - repl2, - final_text, - flags=re.MULTILINE) + final_text = re_wiki_tag.sub(repl2, final_text) # If this is the root page, with all the includes resolved and # collapsed into one text, we need to run the final steps. @@ -229,11 +243,7 @@ return ('
' - r'(?P.*?)') - for i, m in enumerate(re.finditer(arg_pattern, args)): + for i, m in enumerate(re_wiki_include_param.finditer(args)): value = m.group('value').strip() value = html_unescape(value) value = self._renderTemplate(value, self.parameters, @@ -319,9 +326,7 @@ # Parse the query. parameters = dict(self.default_parameters) meta_query = {} - arg_pattern = r"(^|\|)\s*(?P(__)?[a-zA-Z][a-zA-Z0-9_\-]+)\s*="\ - r"(?P[^\|]+)" - for m in re.finditer(arg_pattern, query): + for m in re_wiki_query_param.finditer(query): key = m.group('name').lower() if key in parameters: parameters[key] = m.group('value') @@ -383,7 +388,7 @@ def _valueOrPageText(self, value, with_url=False): stripped_value = value.strip() - if re.match(r'^\[\[.*\]\]$', stripped_value): + if re_wiki_query_template_ref.match(stripped_value): include_url = stripped_value[2:-2] try: page = self.page_getter(include_url) @@ -394,7 +399,7 @@ return (page.url, page.text) return page.text - if re.match(r'^__[a-zA-Z][a-zA-Z0-9_\-]+$', stripped_value): + if re_wiki_query_local_meta.match(stripped_value): meta = self.page.getLocalMeta(stripped_value) if with_url: return (None, meta) @@ -405,6 +410,21 @@ return value def _isPageMatch(self, page, name, value, level=0): + # If we can use the resolved meta properties of the page, this is + # a lot easier, since we just, well, check that. + if self.can_use_resolved_meta: + actual = page.getMeta(name) + if (actual is not None and + ((type(actual) is list and value in actual) or + (actual == value))): + return True + return False + + # Can't use the resolved meta properties, for instance because we have + # a bunch of other resolvers like us busy resolving the other pages' + # properties, and so we don't know which ones are ready or not. + # We'll need to parse pages "manually". + # # Check the page's local meta properties. meta_keys = [name] if level > 0: diff -r 47690e0c55e6 -r 8ca8c2713c92 wikked/webimpl/edit.py --- a/wikked/webimpl/edit.py Wed Jan 03 00:58:22 2018 -0800 +++ b/wikked/webimpl/edit.py Wed Jan 03 01:04:53 2018 -0800 @@ -101,7 +101,9 @@ def preview_edited_page(wiki, url, raw_text): dummy = DummyPage(wiki, url, raw_text) - resolver = PageResolver(dummy) + # We can pass `can_use_resolved_meta` since we know we have the only + # resolver running right now... this will speed things up dramatically. + resolver = PageResolver(dummy, can_use_resolved_meta=True) dummy._setExtendedData(resolver.run()) return dummy.text