Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: cms/converters.py

Issue 29472555: Issue 4867 - Add global get_pages_metadata to template converters (Closed)
Patch Set: refactor file metadata parsing, fix tests Created June 26, 2017, 7:22 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/expected_output/global » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cms/converters.py
===================================================================
--- a/cms/converters.py
+++ b/cms/converters.py
@@ -111,35 +111,44 @@
def handle_entityref(self, name):
self._append_text(self.unescape('&{};'.format(name)))
def handle_charref(self, name):
self._append_text(self.unescape('&#{};'.format(name)))
+def get_page_metadata(page, data):
+ """Generator which gets per page metadata and corresponding line indices"""
+ for i, line in enumerate(data.splitlines()):
+ if not re.search(r'^\s*[\w\-]+\s*=', line):
+ break
+ name, value = line.split('=', 1)
+ value = value.strip()
+ if value.startswith('[') and value.endswith(']'):
+ value = [element.strip() for element in value[1:-1].split(',')]
+ yield name.strip(), value, i
+
+
class Converter:
whitelist = {'a', 'em', 'sup', 'strong', 'code', 'span'}
missing_translations = 0
total_translations = 0
def __init__(self, params, key='pagedata'):
self._params = params
self._key = key
self._attribute_parser = AttributeParser(self.whitelist)
self._seen_defaults = {}
# Read in any parameters specified at the beginning of the file
data, filename = params[key]
lines = data.splitlines(True)
- for i, line in enumerate(lines):
- if not re.search(r'^\s*[\w\-]+\s*=', line):
- break
- name, value = line.split('=', 1)
- params[name.strip()] = value.strip()
+ for name, value, i in get_page_metadata(params['page'], data):
Vasily Kuznetsov 2017/06/27 13:32:15 This refactoring moved the code into a separate fu
Jon Sonesen 2017/06/28 14:31:19 The line index is required to strip the metadata f
Jon Sonesen 2017/07/03 09:06:06 Done.
+ params[name] = value
lines[i] = '\n'
params[key] = (''.join(lines), filename)
def localize_string(
self, page, name, default, comment, localedata, escapes):
def escape(s):
return re.sub(r'.',
@@ -378,16 +387,17 @@
'linkify': self.linkify,
'toclist': self.toclist,
}
globals = {
'get_string': self.get_string,
'has_string': self.has_string,
'get_page_content': self.get_page_content,
+ 'get_pages_metadata': self.get_pages_metadata,
}
for dirname, dictionary in [('filters', filters),
('globals', globals)]:
for filename in self._params['source'].list_files(dirname):
root, ext = os.path.splitext(filename)
if ext.lower() != '.py':
continue
@@ -466,16 +476,51 @@
locale, url = self._params['source'].resolve_link(page, locale)
return jinja2.Markup('<a{}>'.format(''.join(
' {}="{}"'.format(name, jinja2.escape(value)) for name, value in [
('href', url),
('hreflang', locale)
] + attrs.items()
)))
+ def get_pages_metadata(self, filters=None):
+ if not isinstance(filters, dict) and filters:
Vasily Kuznetsov 2017/06/27 13:32:15 This code seems to allow things like `filters = []
Jon Sonesen 2017/06/28 14:31:19 Acknowledged.
Jon Sonesen 2017/07/03 09:06:06 Done.
+ raise TypeError('Filters are not a dictionary')
+
+ return_data = []
+ for page_name, _format in self._params['source'].list_pages():
+ data, filename = self._params['source'].read_page(page_name,
+ _format)
+ page_data = {'page': page_name}
+ for name, value, i in get_page_metadata(page_name, data):
+ page_data[name] = value
+ if self.filter_metadata(filters, page_data) is True:
+ return_data.append(page_data)
+ return return_data
+
+ def filter_metadata(self, filters, metadata):
+ # if only the page key is in the metadata then there
+ # was no user defined metadata
+ if metadata.keys() == ['page']:
Vasily Kuznetsov 2017/06/27 13:32:15 Is this a requirement that such metadata should be
Jon Sonesen 2017/06/28 14:31:19 This is done to keep a uniform api, the previous i
Jon Sonesen 2017/07/03 09:06:06 Still waiting on julians opinion, i guess i get wh
juliandoucette 2017/07/03 21:48:51 I don't understand the question. Can you please ex
Vasily Kuznetsov 2017/07/04 07:43:48 The question is: if a page has no explicit metadat
juliandoucette 2017/07/04 09:57:24 Or that I queried by page name?
Vasily Kuznetsov 2017/07/04 10:23:34 The content is not in the dictionary currently. It
+ return False
+ if filters is None:
+ return True
+ for filter_name, filter_value in filters.items():
+ if filter_name not in metadata:
+ return False
+ if isinstance(metadata[filter_name], list):
+ if isinstance(filter_value, basestring):
+ filter_value = [filter_value]
+ for option in filter_value:
+ if str(option) not in metadata[filter_name]:
+ return False
+ elif filter_value != metadata[filter_name]:
+ return False
+ return True
+
def toclist(self, content):
toc_re = r'<h(\d)\s[^<>]*\bid="([^<>"]+)"[^<>]*>(.*?)</h\1>'
flat = []
for match in re.finditer(toc_re, content, re.S):
flat.append({
'level': int(match.group(1)),
'anchor': jinja2.Markup(match.group(2)).unescape(),
'title': jinja2.Markup(match.group(3)).unescape(),
« no previous file with comments | « no previous file | tests/expected_output/global » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld