diff --git a/fimfarchive/commands/update.py b/fimfarchive/commands/update.py index b66b1a9..aceb7d7 100644 --- a/fimfarchive/commands/update.py +++ b/fimfarchive/commands/update.py @@ -26,7 +26,7 @@ import traceback from argparse import ArgumentParser, Namespace, FileType from typing import Any, Iterable, Iterator, Optional -from jmespath import search +from jmespath import compile as jmes from fimfarchive.fetchers import Fetcher, FimfarchiveFetcher, FimfictionFetcher from fimfarchive.flavors import UpdateStatus @@ -59,6 +59,14 @@ class StoryFormatter(Iterable[str]): 'action', ) + paths = { + 'author': jmes('author.name'), + 'status': jmes('completion_status || status'), + 'words': jmes('num_words || words'), + 'likes': jmes('num_likes || likes'), + 'dislikes': jmes('num_dislikes || dislikes'), + } + def __init__(self, story: Story) -> None: """ Constructor. @@ -73,7 +81,12 @@ class StoryFormatter(Iterable[str]): Returns a value from story meta, or None. """ meta = self.story.meta - return meta.get(key) + path = self.paths.get(key) + + if path: + return path.search(meta) + else: + return meta.get(key) def __iter__(self) -> Iterator[str]: """ @@ -90,22 +103,13 @@ class StoryFormatter(Iterable[str]): """ return '\n'.join(self) - @property - def author(self) -> Optional[str]: - """ - Returns the name of the author, or None. - """ - meta = self.story.meta - return search('author.name', meta) - @property def approval(self) -> Optional[str]: """ Returns the likes to dislikes ratio, or None. """ - meta = self.story.meta - likes = meta.get('likes') - dislikes = meta.get('dislikes') + likes = self.likes + dislikes = self.dislikes try: ratio = likes / (likes + dislikes) diff --git a/tests/commands/test_update.py b/tests/commands/test_update.py index 931b8b0..93cb114 100644 --- a/tests/commands/test_update.py +++ b/tests/commands/test_update.py @@ -65,9 +65,9 @@ class TestStoryFormatter(): story = story.merge(meta=meta, flavors=flavors) self.assert_formatted_equals(expected, story) - def test_complete_meta(self, story): + def test_old_meta(self, story): """ - Tests story formatting with complete meta. + Tests story formatting with old-style meta. """ flavors: Set[Flavor] = { UpdateStatus.CREATED, @@ -102,6 +102,44 @@ class TestStoryFormatter(): story = story.merge(meta=meta, flavors=flavors) self.assert_formatted_equals(expected, story) + def test_new_meta(self, story): + """ + Tests story formatting with new-style meta. + """ + flavors: Set[Flavor] = { + UpdateStatus.CREATED, + } + + meta: Dict[str, Any] = { + 'title': 'A', + 'author': { + 'name': 'B' + }, + 'status': 'visible', + 'completion_status': 'C', + 'num_words': 4, + 'num_likes': 3, + 'num_dislikes': 2, + 'chapters': [ + 1 + ], + } + + expected = """ + Title: A + Author: B + Status: C + Words: 4 + Likes: 3 + Dislikes: 2 + Approval: 60% + Chapters: 1 + Action: Created + """ + + story = story.merge(meta=meta, flavors=flavors) + self.assert_formatted_equals(expected, story) + def test_edge_meta(self, story): """ Tests story formatting with some edge cases.