def test_Index_eq(self): """Two distinct Index objects with same attrs compare equal""" index_a = Index(page_number=1, settings=self.settings, posts=self.posts) index_b = Index(page_number=1, settings=self.settings, posts=self.posts) index_c = Index(page_number=2, settings=self.settings, posts=self.posts) self.assertEqual(index_a, index_b) self.assertNotEqual(index_a, index_c)
def test_Index_output_path(self): """Index properly sets output path""" self.settings['paths']['output root'] = '' indexes = [ Index(page_number=n, settings=self.settings, posts=[]) for n in range(1, 3) ] self.assertEqual(Path('index.html'), indexes[0].output_path) self.assertEqual(Path('page-2.html'), indexes[1].output_path)
def test_Index_paginate_posts_result(self): """Result of paginate_posts on known date gives expected result""" expected = [ Index(page_number=1, settings=self.settings, posts=self.posts[-2:]), Index(page_number=2, settings=self.settings, posts=self.posts[-4:-2]), Index(page_number=3, settings=self.settings, posts=self.posts[:-4]) ] expected[0].older_index_url = expected[1].url expected[1].older_index_url = expected[2].url expected[2].newer_index_url = expected[1].url expected[1].newer_index_url = expected[0].url result = Index.paginate_posts(posts=self.posts, settings=self.settings) self.assertEqual(expected, result)
def test_Index_iter(self): """Index should support iteration over its posts Looping over an Index should be equivalent to looping its posts list attribute. """ expected = sorted(self.posts, reverse=True) index = Index(page_number=1, settings=self.settings, posts=self.posts) self.assertEqual(expected, [p for p in index])
def test_Index_url(self): """Index properly sets URL""" base_url = 'http://example.com' self.settings['site']['url'] = base_url indexes = [ Index(page_number=n, settings=self.settings, posts=[]) for n in range(1, 3) ] self.assertEqual(base_url, indexes[0].url) self.assertEqual(base_url + '/page-2.html', indexes[1].url)
def test_Index_attrs(self): """Each Index returned by paginate_posts has the correct attributes""" attr_list = [ 'page_number', 'newer_index_url', 'older_index_url', 'output_path', 'url', 'posts' ] result = Index.paginate_posts(posts=self.posts, settings=self.settings) for index in result: for attribute in attr_list: self.assertTrue(hasattr(index, attribute))
def setUp(self): os.chdir(TEST_BLOG_DIR) settings_path = TEST_BLOG_DIR.joinpath('settings.json') self.settings = load_settings(files=[settings_path], local=False) self.output_dir = Path(self.settings['paths']['output root']) self.files = [ Post(title='', slug='post', date=datetime(2015, 1, 1), body='', settings=self.settings), Page(title='', slug='page', body='', settings=self.settings), Index(posts=[], settings=self.settings, page_number=1), ] # Make dummy files and directories for f in self.files: f.output_path.parent.mkdir(parents=True, exist_ok=True) f.output_path.touch()
def process_blog(*, settings, write_only_new=True, posts=True, pages=True, index=True, archives=True, feeds=True, sitemap=True, extensions=True): """Create output files from the blog's source By default, create the entire blog. Certain parts can be disabled by setting their corresponding parameter to False. By default, only Pages and Posts that are considered new (by checking content.is_new) are written out. This can be overridden by passing False to write_only_new. Sitemap can be created by itself but will raise if the first index, or any of the page or post output files don't exist. This is because the sitemap depends on knowing the mtime of those files on disk. If extensions is False, posts and pages are not processed with any extension modules present in the extensions directory. """ content_dir = Path(settings['paths']['content root']) posts_dir = content_dir.joinpath(settings['paths']['posts subdir']) pages_dir = content_dir.joinpath(settings['paths']['pages subdir']) env = jinja_environment(user_templates=settings['paths']['templates root'], settings=settings) post_filenames = markdown_files(posts_dir) page_filenames = markdown_files(pages_dir) posts_list = [] pages_list = [] for class_, file_list, obj_list in [(Post, post_filenames, posts_list), (Page, page_filenames, pages_list)]: for fn in file_list: try: obj_list.append(class_.from_file(fn, settings)) except DraftError: print('{file} is marked as a draft'.format(file=fn), file=sys.stderr) posts_list.sort(reverse=True) pages_list.sort() objects_to_write = [] extensions_loaded = False if extensions: extensions_dir = Path(settings['paths']['extensions root']) if extensions_dir.exists(): modules = load_extensions(extensions_dir) extensions_loaded = True processed = apply_extensions(modules=modules, stage=ExtensionStage.posts_and_pages, pages=pages_list, posts=posts_list, settings=settings) posts_list = processed['posts'] pages_list = processed['pages'] objects_to_write.extend(processed['new_objects']) content_objects = [] if posts: content_objects.extend(posts_list) if pages: content_objects.extend(pages_list) if write_only_new: content_objects = [c for c in content_objects if c.is_new] objects_to_write.extend(content_objects) if index: indexes = Index.paginate_posts(posts=posts_list, settings=settings) objects_to_write.extend(indexes) if archives: objects_to_write.append(Archives(posts=posts_list, settings=settings)) if feeds: objects_to_write.append(RSSFeed(posts=posts_list, settings=settings)) objects_to_write.append(JSONFeed(posts=posts_list, settings=settings)) if extensions_loaded: processed = apply_extensions(modules=modules, stage=ExtensionStage.objects_to_write, objects=objects_to_write, settings=settings) objects_to_write = processed['objects'] for obj in objects_to_write: obj.render_to_disk(environment=env, build_date=datetime.now(tz=pytz.utc), all_posts=posts_list, all_pages=pages_list) if sitemap: if index: front_page = indexes[0] else: # Create dummy front so the sitemap can be generated by itself front_page = Index(page_number=1, posts=[], settings=settings) if not Index.output_path.exists(): Index.output_path.touch() content_list = posts_list + pages_list + [front_page] sitemap = Sitemap(content=content_list, settings=settings) sitemap.render_to_disk(environment=env)
def test_Index_compare(self): """Index objects compare by page number""" index_a = Index(page_number=1, settings=self.settings, posts=[]) index_b = Index(page_number=2, settings=self.settings, posts=[]) self.assertLess(index_a, index_b)
def test_Index_paginate_order(self): """paginate_posts returns Index objects ordered first to last""" result = Index.paginate_posts(posts=self.posts, settings=self.settings) for expected_number, index in enumerate(result, start=1): self.assertEqual(expected_number, index.page_number)
def test_Index_paginate_posts_per_index(self): """paginate_posts gives each Index the right number of posts""" result = Index.paginate_posts(posts=self.posts, settings=self.settings) for expected_count, index in zip([2, 2, 1], result): self.assertEqual(expected_count, len(index.posts))
def test_Index_posts_sorted(self): """Index sorts posts by newest before storing them""" index = Index(page_number=1, settings=self.settings, posts=self.posts) self.assertEqual(sorted(self.posts, reverse=True), index.posts)