def test_article_with_filename_metadata(self): page = self.read_file(path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', } self.assertDictHasSubset(page.metadata, expected) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=r'(?P<date>\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': SafeDatetime(2012, 11, 30), } self.assertDictHasSubset(page.metadata, expected) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=(r'(?P<date>\d{4}-\d{2}-\d{2})' r'_(?P<Slug>.*)' r'#(?P<MyMeta>.*)-(?P<author>.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': SafeDatetime(2012, 11, 30), 'slug': 'md_w_filename_meta', 'mymeta': 'foo', } self.assertDictHasSubset(page.metadata, expected)
def test_article_with_filename_metadata(self): page = self.read_file(path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA='(?P<date>\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': SafeDatetime(2012, 11, 30), } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=('(?P<date>\d{4}-\d{2}-\d{2})' '_(?P<Slug>.*)' '#(?P<MyMeta>.*)-(?P<author>.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': SafeDatetime(2012, 11, 30), 'slug': 'md_w_filename_meta', 'mymeta': 'foo', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key)
def test_article_with_metadata(self): reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read(_path('article_with_md_extension.md')) expected = { 'category': 'test', 'title': 'Test md File', 'summary': '<p>I have a lot to test</p>', 'date': SafeDatetime(2010, 12, 2, 10, 14), 'modified': SafeDatetime(2010, 12, 2, 10, 20), 'tags': ['foo', 'bar', 'foobar'], } self.assertDictHasSubset(metadata, expected) content, metadata = reader.read( _path('article_with_markdown_and_nonascii_summary.md')) expected = { 'title': 'マックOS X 10.8でパイソンとVirtualenvをインストールと設定', 'summary': '<p>パイソンとVirtualenvをまっくでインストールする方法について明確に説明します。</p>', 'category': '指導書', 'date': SafeDatetime(2012, 12, 20), 'modified': SafeDatetime(2012, 12, 22), 'tags': ['パイソン', 'マック'], 'slug': 'python-virtualenv-on-mac-osx-mountain-lion-10.8', } self.assertDictHasSubset(metadata, expected)
def test_article_with_metadata(self): page = self.read_file(path='article_with_metadata.rst') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': '<p class="first last">Multi-line metadata should be' ' supported\nas well as <strong>inline' ' markup</strong> and stuff to "typogrify' '"...</p>\n', 'date': SafeDatetime(2010, 12, 2, 10, 14), 'modified': SafeDatetime(2010, 12, 2, 10, 20), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key)
def test_readfile_path_metadata_explicit_dates(self): test_file = 'article_with_metadata_explicit_dates.html' page = self.read_file(path=test_file, DEFAULT_DATE='fs') expected = { 'date': SafeDatetime(2010, 12, 2, 10, 14), 'modified': SafeDatetime(2010, 12, 31, 23, 59) } self.assertDictHasSubset(page.metadata, expected)
def test_article_extra_path_metadata_dont_overwrite(self): # EXTRA_PATH_METADATA['author'] should get ignored # since we don't overwrite already set values input_file_path = '2012-11-29_rst_w_filename_meta#foo-bar.rst' page = self.read_file( path=input_file_path, FILENAME_METADATA=(r'(?P<date>\d{4}-\d{2}-\d{2})' r'_(?P<Slug>.*)' r'#(?P<MyMeta>.*)-(?P<orginalauthor>.*)'), EXTRA_PATH_METADATA={ input_file_path: { 'author': 'Charlès Overwrite', 'key-1b': 'value-1b' } }) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'Rst with filename metadata', 'date': SafeDatetime(2012, 11, 29), 'slug': 'rst_w_filename_meta', 'mymeta': 'foo', 'reader': 'rst', 'key-1b': 'value-1b' } self.assertDictHasSubset(page.metadata, expected)
def merge_date_url(value, url): """ Given a Pelican setting URL that contains a placeholder for a date, and a date, it will combine the two to return the resulting URL. Args ---- value (datetime.datetime): a date url (string): a Pelican URL setting Returns ------- string: combined URL """ try: return url.format(date=value) except ValueError: # will throw a "ValueError" if the value is a datetime.datetime and the url # contains a "-" (e.g. "{date:%-d}") (used in Pelican to strip the leading # zero) try: return url.format( date=SafeDatetime(value.year, value.month, value.day)) except ValueError as e: logger.error( "%s ValueError. value: %s, type(value): %s, url: %s", LOG_PREFIX, value, type(value), url, ) raise e
def test_article_with_footnote(self): settings = get_settings() ec = settings['MARKDOWN']['extension_configs'] ec['markdown.extensions.footnotes'] = {'SEPARATOR': '-'} reader = readers.MarkdownReader(settings) content, metadata = reader.read( _path('article_with_markdown_and_footnote.md')) expected_content = ( '<p>This is some content' '<sup id="fnref-1"><a class="footnote-ref" href="#fn-1"' '>1</a></sup>' ' with some footnotes' '<sup id="fnref-footnote"><a class="footnote-ref" ' 'href="#fn-footnote">2</a></sup></p>\n' '<div class="footnote">\n' '<hr>\n<ol>\n<li id="fn-1">\n' '<p>Numbered footnote ' '<a class="footnote-backref" href="#fnref-1" ' 'title="Jump back to footnote 1 in the text">↩</a></p>\n' '</li>\n<li id="fn-footnote">\n' '<p>Named footnote ' '<a class="footnote-backref" href="#fnref-footnote"' ' title="Jump back to footnote 2 in the text">↩</a></p>\n' '</li>\n</ol>\n</div>') expected_metadata = { 'title': 'Article with markdown containing footnotes', 'summary': ('<p>Summary with <strong>inline</strong> markup ' '<em>should</em> be supported.</p>'), 'date': SafeDatetime(2012, 10, 31), 'modified': SafeDatetime(2012, 11, 1), 'multiline': [ 'Line Metadata should be handle properly.', 'See syntax of Meta-Data extension of ' 'Python Markdown package:', 'If a line is indented by 4 or more spaces,', 'that line is assumed to be an additional line of the value', 'for the previous keyword.', 'A keyword may have as many lines as desired.', ] } self.assertEqual(content, expected_content) self.assertDictHasSubset(metadata, expected_metadata)
def test_article_with_footnote(self): reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_markdown_and_footnote.md')) expected_content = ( '<p>This is some content' '<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" ' 'rel="footnote">1</a></sup>' ' with some footnotes' '<sup id="fnref:footnote"><a class="footnote-ref" ' 'href="#fn:footnote" rel="footnote">2</a></sup></p>\n' '<div class="footnote">\n' '<hr />\n<ol>\n<li id="fn:1">\n' '<p>Numbered footnote ' '<a class="footnote-backref" href="#fnref:1" rev="footnote" ' 'title="Jump back to footnote 1 in the text">↩</a></p>\n' '</li>\n<li id="fn:footnote">\n' '<p>Named footnote ' '<a class="footnote-backref" href="#fnref:footnote" rev="footnote"' ' title="Jump back to footnote 2 in the text">↩</a></p>\n' '</li>\n</ol>\n</div>') expected_metadata = { 'title': 'Article with markdown containing footnotes', 'summary': ('<p>Summary with <strong>inline</strong> markup ' '<em>should</em> be supported.</p>'), 'date': SafeDatetime(2012, 10, 31), 'modified': SafeDatetime(2012, 11, 1), 'slug': 'article-with-markdown-containing-footnotes', 'multiline': [ 'Line Metadata should be handle properly.', 'See syntax of Meta-Data extension of Python Markdown package:', 'If a line is indented by 4 or more spaces,', 'that line is assumed to be an additional line of the value', 'for the previous keyword.', 'A keyword may have as many lines as desired.', ] } self.assertEqual(content, expected_content) for key, value in metadata.items(): self.assertEqual(value, expected_metadata[key], key)
def datetime_from_period(value): """ Converts "period" into a datetime object. On yearly/monthly/daily archive pages, a "period" object is supplied so you know what timeperiod the particular archive page is for. This converts it to a datetime.datetime object, so it can be further processed. If a month is not provided (i.e. the period is for a yearly archive), January is assumed. If a day is not provided (i.e. the period is for a yearly or monthly archive), the 1st is assumed. You can also generate a tuple of (up to three) integers to get a datetime out, using the integer representation for the month (1=January, etc). If passes a single integer, it is assumed to represent a year. Args ---- value (tuple or int): input period Returns ------- datetime.datetime: value converted """ if isinstance(value, int): value = (value, ) if len(value) >= 2 and isinstance(value[1], int): placeholder_month = SafeDatetime(2021, value[1], 1).strftime("%B") elif len(value) == 1: placeholder_month = SafeDatetime(2021, 1, 1).strftime("%B") else: placeholder_month = value[1] new_value = " ".join(( str(value[0]), placeholder_month, str(value[2]) if len(value) >= 3 else "1", )) new_datetime = SafeDatetime.strptime(new_value, "%Y %B %d") return new_datetime
def test_readfile_path_metadata_implicit_date_explicit_modified(self): test_file = 'article_with_metadata_implicit_date_explicit_modified.html' page = self.read_file(path=test_file, DEFAULT_DATE='fs') expected = { 'date': SafeDatetime.fromtimestamp(os.stat(_path(test_file)).st_mtime), 'modified': SafeDatetime(2010, 12, 2, 10, 14), } self.assertDictHasSubset(page.metadata, expected)
def default_metadata(settings=None, process=None): metadata = {} if settings: if 'DEFAULT_CATEGORY' in settings: value = settings['DEFAULT_CATEGORY'] if process: value = process('category', value) metadata['category'] = value if settings.get('DEFAULT_DATE', None) and settings['DEFAULT_DATE'] != 'fs': metadata['date'] = SafeDatetime(*settings['DEFAULT_DATE']) return metadata
def test_typed_metadata(): content, metadata = read_content_metadata('metadata.md') expected = { 'title': 'Metadata', 'list': ['a', 'b', 'c'], 'date': SafeDatetime(2017, 1, 6, 22, 24), 'int': 42, 'bool': False, 'summary': '<p>a summary</p>', } assert_dict_contains(metadata, expected)
def test_article_with_metadata_and_contents_attrib(self): page = self.read_file(path='article_with_metadata_and_contents.html') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': 'Summary and stuff', 'date': SafeDatetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } self.assertDictHasSubset(page.metadata, expected)
def test_article_with_metadata(self): page = self.read_file(path='article_with_metadata.html') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': 'Summary and stuff', 'date': SafeDatetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key)
def test_article_with_optional_filename_metadata(self): page = self.read_file(path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA='(?P<date>\d{4}-\d{2}-\d{2})?') expected = { 'date': SafeDatetime(2012, 11, 30), 'reader': 'markdown', } self.assertDictHasSubset(page.metadata, expected) page = self.read_file(path='empty.md', FILENAME_METADATA='(?P<date>\d{4}-\d{2}-\d{2})?') expected = { 'reader': 'markdown', } self.assertDictHasSubset(page.metadata, expected) self.assertNotIn('date', page.metadata, 'Date should not be set.')
def default_metadata(settings=None, process=None): metadata = {} if settings: for name, value in dict(settings.get('DEFAULT_METADATA', {})).items(): if process: value = process(name, value) metadata[name] = value if 'DEFAULT_CATEGORY' in settings: value = settings['DEFAULT_CATEGORY'] if process: value = process('category', value) metadata['category'] = value if settings.get('DEFAULT_DATE', None) and \ settings['DEFAULT_DATE'] != 'fs': metadata['date'] = SafeDatetime(*settings['DEFAULT_DATE']) return metadata
def test_article_extra_path_metadata(self): input_with_metadata = '2012-11-29_rst_w_filename_meta#foo-bar.rst' page_metadata = self.read_file( path=input_with_metadata, FILENAME_METADATA=( r'(?P<date>\d{4}-\d{2}-\d{2})' r'_(?P<Slug>.*)' r'#(?P<MyMeta>.*)-(?P<author>.*)' ), EXTRA_PATH_METADATA={ input_with_metadata: { 'key-1a': 'value-1a', 'key-1b': 'value-1b' } } ) expected_metadata = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'Rst with filename metadata', 'date': SafeDatetime(2012, 11, 29), 'slug': 'rst_w_filename_meta', 'mymeta': 'foo', 'reader': 'rst', 'key-1a': 'value-1a', 'key-1b': 'value-1b' } self.assertDictHasSubset(page_metadata.metadata, expected_metadata) input_file_path_without_metadata = 'article.rst' page_without_metadata = self.read_file( path=input_file_path_without_metadata, EXTRA_PATH_METADATA={ input_file_path_without_metadata: { 'author': 'Charlès Overwrite' } } ) expected_without_metadata = { 'category': 'misc', 'author': 'Charlès Overwrite', 'title': 'Article title', 'reader': 'rst', } self.assertDictHasSubset( page_without_metadata.metadata, expected_without_metadata)
def test_datetime(self): # If DATETIME is set to a tuple, it should be used to override LOCALE dt = SafeDatetime(2015, 9, 13) page_kwargs = self._copy_page_kwargs() # set its date to dt page_kwargs['metadata']['date'] = dt page = Page(**page_kwargs) # page.locale_date is a unicode string in both python2 and python3 dt_date = dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT']) # dt_date is a byte string in python2, and a unicode string in python3 # Let's make sure it is a unicode string (relies on python 3.3 supporting the u prefix) if type(dt_date) != type(u''): # python2: dt_date = unicode(dt_date, 'utf8') self.assertEqual(page.locale_date, dt_date) page_kwargs['settings'] = get_settings() # I doubt this can work on all platforms ... if platform == "win32": locale = 'jpn' else: locale = 'ja_JP.utf8' page_kwargs['settings']['DATE_FORMATS'] = { 'jp': (locale, '%Y-%m-%d(%a)') } page_kwargs['metadata']['lang'] = 'jp' import locale as locale_module try: page = Page(**page_kwargs) self.assertEqual(page.locale_date, '2015-09-13(\u65e5)') except locale_module.Error: # The constructor of ``Page`` will try to set the locale to # ``ja_JP.utf8``. But this attempt will failed when there is no # such locale in the system. You can see which locales there are # in your system with ``locale -a`` command. # # Until we find some other method to test this functionality, we # will simply skip this test. unittest.skip("There is no locale %s in this system." % locale)
def test_pelican_day(self): my_date = SafeDatetime(2016, 11, 4, 12, 34) assert (jinja_filters.merge_date_url( my_date, self.DAY_ARCHIVE_URL) == "posts/2016/11/04/")