changeset 64:0b4f4c23770a

Removed specific "include"-related properties from the code and DB. (they can already be accessed via the meta) Fixed a bug with handling includes in queries. Better code in some places in the formatter.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 07 Feb 2013 22:34:13 -0800
parents 97efd73f2158
children c6dcf6716d26
files tests/test_page.py wikked/db.py wikked/formatter.py wikked/page.py
diffstat 4 files changed, 76 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/tests/test_page.py	Wed Feb 06 23:48:34 2013 -0800
+++ b/tests/test_page.py	Thu Feb 07 22:34:13 2013 -0800
@@ -21,7 +21,6 @@
         self.assertEqual('A test page.', page.text)
         self.assertEqual({}, page.local_meta)
         self.assertEqual([], page.local_links)
-        self.assertEqual([], page.local_includes)
 
     def testPageMeta(self):
         self.wiki = self._getWikiFromStructure({
@@ -35,7 +34,6 @@
         self.assertEqual('A page with simple meta.\n\n', page.text)
         self.assertEqual({'bar': 'baz', 'is_test': True}, page.local_meta)
         self.assertEqual([], page.local_links)
-        self.assertEqual([], page.local_includes)
 
     def testPageTitleMeta(self):
         self.wiki = self._getWikiFromStructure({
@@ -49,7 +47,6 @@
         self.assertEqual('A page with a custom title.\n', page.text)
         self.assertEqual({'title': 'TEST-TITLE'}, page.local_meta)
         self.assertEqual([], page.local_links)
-        self.assertEqual([], page.local_includes)
 
     def testPageOutLinks(self):
         self.wiki = self._getWikiFromStructure({
@@ -98,7 +95,7 @@
             'Trans Desc.txt': "BLAH\n"
             })
         foo = Page(self.wiki, 'foo')
-        self.assertEqual(['trans-desc'], foo.local_includes)
+        self.assertEqual({'include': 'trans-desc'}, foo.local_meta)
         self.assertEqual(
                 "A test page.\n%s" % format_include('trans-desc'),
                 foo.formatted_text)
@@ -110,7 +107,6 @@
             'Trans Desc.txt': "BLAH: [[Somewhere]]\n{{bar: 42}}\n{{__secret: love}}\n{{+given: hope}}"
             })
         foo = Page(self.wiki, 'foo')
-        self.assertEqual(['trans-desc'], foo.local_includes)
         self.assertEqual([], foo.local_links)
         self.assertEqual({'include': 'trans-desc'}, foo.local_meta)
         self.assertEqual(
@@ -119,7 +115,6 @@
         self.assertEqual(
                 "A test page.\nBLAH: %s\n\n\n\n" % format_link('Somewhere', 'somewhere', True),
                 foo.text)
-        self.assertEqual(['trans-desc'], foo.all_includes)
         self.assertEqual(['somewhere'], foo.all_links)
         self.assertEqual({'bar': '42', 'given': 'hope', 'include': 'trans-desc'}, foo.all_meta)
 
--- a/wikked/db.py	Wed Feb 06 23:48:34 2013 -0800
+++ b/wikked/db.py	Thu Feb 07 22:34:13 2013 -0800
@@ -214,11 +214,6 @@
              title TEXT,
              raw_text TEXT,
              formatted_text TEXT)''')
-        c.execute('''DROP TABLE IF EXISTS includes''')
-        c.execute('''CREATE TABLE includes
-            (id INTEGER PRIMARY KEY AUTOINCREMENT,
-             source TEXT,
-             target TEXT)''')
         c.execute('''DROP TABLE IF EXISTS links''')
         c.execute('''CREATE TABLE links
             (id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -312,11 +307,6 @@
                 (source, target) VALUES (?, ?)''',
                 (page.url, link_url))
 
-        for inc_url in page.local_includes:
-            c.execute('''INSERT INTO includes
-                (source, target) VALUES (?, ?)''',
-                (page.url, inc_url))
-
     def _removePage(self, page_id, c):
         c.execute('''SELECT url FROM pages WHERE id=?''', (page_id,))
         row = c.fetchone()
@@ -325,7 +315,6 @@
         c.execute('''DELETE FROM pages WHERE id=?''', (page_id,))
         c.execute('''DELETE FROM meta WHERE page_id=?''', (page_id,))
         c.execute('''DELETE FROM links WHERE source=?''', (row['url'],))
-        c.execute('''DELETE FROM includes WHERE source=?''', (row['url'],))
 
     def _getPage(self, row, c):
         db_page = {
@@ -336,7 +325,6 @@
             'content': row['raw_text'],
             'formatted': row['formatted_text'],
             'links': [],
-            'includes': [],
             'meta': {}
             }
 
@@ -345,11 +333,6 @@
         for r in c.fetchall():
             db_page['links'].append(r['target'])
 
-        c.execute('''SELECT target FROM includes
-            WHERE source=?''', (row['url'],))
-        for r in c.fetchall():
-            db_page['includes'].append(r['target'])
-
         c.execute('''SELECT page_id, name, value
             FROM meta WHERE page_id=?''', (row['id'],))
         for r in c.fetchall():
--- a/wikked/formatter.py	Wed Feb 06 23:48:34 2013 -0800
+++ b/wikked/formatter.py	Thu Feb 07 22:34:13 2013 -0800
@@ -68,7 +68,6 @@
         BaseContext.__init__(self, url, slugify)
         self.ext = ext
         self.out_links = []
-        self.included_pages = []
         self.meta = {}
 
 
@@ -79,6 +78,13 @@
     """
     def __init__(self, wiki):
         self.wiki = wiki
+        self.coercers = {
+                'include': self._coerceInclude
+                }
+        self.processors = {
+                'include': self._processInclude,
+                'query': self._processQuery
+                }
 
     def formatText(self, ctx, text):
         text = self._preProcessWikiSyntax(ctx, text)
@@ -105,21 +111,31 @@
         def repl(m):
             meta_name = str(m.group('name')).lower()
             meta_value = str(m.group('value'))
-            if meta_value is not None and len(meta_value) > 0:
-                if meta_name not in ctx.meta:
-                    ctx.meta[meta_name] = meta_value
-                elif isinstance(ctx.meta[meta_name], types.StringTypes):
-                    ctx.meta[meta_name] = [ctx.meta[meta_name], meta_value]
-                else:
-                    ctx.meta[meta_name].append(meta_value)
+
+            if meta_value is None or meta_value == '':
+                # No value provided: this is a "flag" meta.
+                ctx.meta[meta_name] = True
+                return ''
+
+            # If we actually have a value, coerce it, if applicable,
+            # and get the name without the modifier prefix.
+            clean_meta_name, meta_modifier = get_meta_name_and_modifiers(meta_name)
+            coerced_meta_value = meta_value
+            if clean_meta_name in self.coercers:
+                coerced_meta_value = self.coercers[clean_meta_name](ctx, meta_value)
+
+            # Then, set the value on the meta dictionary, or add it to
+            # other existing meta values with the same key.
+            if meta_name not in ctx.meta:
+                ctx.meta[meta_name] = coerced_meta_value
+            elif isinstance(ctx.meta[meta_name], types.StringTypes):
+                ctx.meta[meta_name] = [ctx.meta[meta_name], coerced_meta_value]
             else:
-                ctx.meta[meta_name] = True
+                ctx.meta[meta_name].append(coerced_meta_value)
 
-            clean_meta_name, meta_modifier = get_meta_name_and_modifiers(meta_name)
-            if clean_meta_name == 'include':
-                return self._processInclude(ctx, meta_modifier, meta_value)
-            elif clean_meta_name == 'query':
-                return self._processQuery(ctx, meta_modifier, meta_value)
+            # Process it, or remove it from the output text.
+            if clean_meta_name in self.processors:
+                return self.processors[clean_meta_name](ctx, meta_modifier, coerced_meta_value)
             return ''
 
         # Single line meta.
@@ -163,16 +179,24 @@
 
         return text
 
+    def _coerceInclude(self, ctx, value):
+        pipe_idx = value.find('|')
+        if pipe_idx < 0:
+            return ctx.getAbsoluteUrl(value.strip())
+        else:
+            url = ctx.getAbsoluteUrl(value[:pipe_idx].strip())
+            parameters = value[pipe_idx + 1:].replace('\n', '')
+            return url + '|' + parameters
+
     def _processInclude(self, ctx, modifier, value):
         # Includes are run on the fly.
         pipe_idx = value.find('|')
         if pipe_idx < 0:
-            included_url = ctx.getAbsoluteUrl(value.strip())
+            included_url = value
             parameters = ''
         else:
-            included_url = ctx.getAbsoluteUrl(value[:pipe_idx].strip())
-            parameters = value[pipe_idx + 1:].replace('\n', '')
-        ctx.included_pages.append(included_url)
+            included_url = value[:pipe_idx]
+            parameters = value[pipe_idx + 1:]
 
         url_attr = ' data-wiki-url="%s"' % included_url
         mod_attr = ''
@@ -236,15 +260,12 @@
         self.text = ''
         self.meta = {}
         self.out_links = []
-        self.included_pages = []
         if page:
             self.meta = dict(page.local_meta)
             self.out_links = list(page.local_links)
-            self.included_pages = list(page.local_includes)
 
     def add(self, other):
         self.out_links += other.out_links
-        self.included_pages += other.included_pages
         for original_key, val in other.meta.iteritems():
             # Ignore internal properties. Strip include-only properties
             # from their prefix.
@@ -402,23 +423,44 @@
 
     def _isPageMatch(self, page, name, value, level=0):
         # Check the page's local meta properties.
-        actual = page.local_meta.get(name)
-        if (actual is not None and
-                ((type(actual) is list and value in actual) or
-                (actual == value))):
-            return True
-
-        # If this is an include, also look for 'include-only'
-        # meta properties.
+        meta_keys = [name]
         if level > 0:
-            actual = page.local_meta.get('+' + name)
+            # If this is an include, also look for 'include-only'
+            # meta properties.
+            meta_keys.append('+' + name)
+        for key in meta_keys:
+            actual = page.local_meta.get(key)
             if (actual is not None and
                     ((type(actual) is list and value in actual) or
                     (actual == value))):
                 return True
 
+        # Gather included pages' URLs.
+        # If this is an include, also look for `+include`'d pages,
+        # and if not, `__include`'d pages.
+        include_meta_values = []
+        include_meta_keys = ['include']
+        if level > 0:
+            include_meta_keys.append('+include')
+        else:
+            include_meta_keys.append('__include')
+        for key in include_meta_keys:
+            i = page.local_meta.get(key)
+            if i is not None:
+                if (type(i) is list):
+                    include_meta_values += i
+                else:
+                    include_meta_values.append(i)
+        included_urls = []
+        for v in include_meta_values:
+            pipe_idx = v.find('|')
+            if pipe_idx > 0:
+                included_urls.append(v[:pipe_idx])
+            else:
+                included_urls.append(v)
+
         # Recurse into included pages.
-        for url in page.local_includes:
+        for url in included_urls:
             p = self.wiki.getPage(url)
             if self._isPageMatch(p, name, value, level + 1):
                 return True
--- a/wikked/page.py	Wed Feb 06 23:48:34 2013 -0800
+++ b/wikked/page.py	Thu Feb 07 22:34:13 2013 -0800
@@ -52,11 +52,6 @@
         return self._meta['links']
 
     @property
-    def local_includes(self):
-        self._ensureMeta()
-        return self._meta['includes']
-
-    @property
     def all_meta(self):
         self._ensureExtendedMeta()
         return self._ext_meta['meta']
@@ -67,11 +62,6 @@
         return self._ext_meta['links']
 
     @property
-    def all_includes(self):
-        self._ensureExtendedMeta()
-        return self._ext_meta['includes']
-
-    @property
     def in_links(self):
         return self.wiki.db.getLinksTo(self.url)
 
@@ -117,7 +107,6 @@
         meta['formatted'] = f.formatText(ctx, meta['content'])
         meta['meta'] = ctx.meta
         meta['links'] = ctx.out_links
-        meta['includes'] = ctx.included_pages
 
         # Add some common meta.
         meta['title'] = re.sub(r'\-', ' ', filename_split[0])
@@ -137,7 +126,6 @@
             self._ext_meta['text'] = out.text
             self._ext_meta['meta'] = out.meta
             self._ext_meta['links'] = out.out_links
-            self._ext_meta['includes'] = out.included_pages
         except CircularIncludeError as cie:
             template_path = os.path.join(
                     os.path.dirname(__file__),
@@ -152,8 +140,7 @@
                         'url_trail': cie.url_trail
                         }),
                     'meta': {},
-                    'links': [],
-                    'includes': []
+                    'links': []
                     }
 
     @staticmethod
@@ -205,8 +192,7 @@
                 'formatted': db_page['formatted'],
                 'meta': db_page['meta'],
                 'title': db_page['title'],
-                'links': db_page['links'],
-                'includes': db_page['includes']
+                'links': db_page['links']
                 }
         return meta