From 034bfb7419b0f9646091ead6fd4fcfabb5cecf8c Mon Sep 17 00:00:00 2001 From: Joakim Soderlund Date: Mon, 19 Dec 2016 00:26:24 +0100 Subject: [PATCH] Use flavors in fetchers and stories --- fimfarchive/fetchers.py | 17 ++++++++++++++++- fimfarchive/stories.py | 3 ++- tests/conftest.py | 13 +++++++++++++ tests/test_fetchers.py | 16 ++++++++++++++++ tests/test_stories.py | 23 +++++++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/fimfarchive/fetchers.py b/fimfarchive/fetchers.py index 3fb0de7..5d976ee 100644 --- a/fimfarchive/fetchers.py +++ b/fimfarchive/fetchers.py @@ -32,6 +32,7 @@ from zipfile import ZipFile, BadZipFile import requests from fimfarchive.exceptions import InvalidStoryError, StorySourceError +from fimfarchive.flavors import StorySource, DataFormat, MetaPurity from fimfarchive.stories import Story @@ -45,6 +46,8 @@ class Fetcher: prefetch_meta = False prefetch_data = False + flavors = frozenset() + def __enter__(self): """ Returns self for use in with statements. @@ -95,7 +98,7 @@ class Fetcher: else: data = None - return Story(key, self, meta, data) + return Story(key, self, meta, data, self.flavors) def fetch_data(self, key): """ @@ -140,6 +143,12 @@ class FimfictionFetcher(Fetcher): data_path = 'https://www.fimfiction.net/download_story.php' meta_path = 'https://www.fimfiction.net/api/story.php' + flavors = frozenset(( + StorySource.FIMFICTION, + DataFormat.HTML, + MetaPurity.DIRTY, + )) + def get(self, url, **kwargs): """ Performs an HTTP GET request. @@ -211,6 +220,12 @@ class FimfarchiveFetcher(Fetcher): prefetch_meta = True prefetch_data = True + flavors = frozenset(( + StorySource.FIMFARCHIVE, + DataFormat.EPUB, + MetaPurity.CLEAN, + )) + def __init__(self, file): """ Initializes a `FimfarchiveFetcher` instance. diff --git a/fimfarchive/stories.py b/fimfarchive/stories.py index ad49fe9..f1d026b 100644 --- a/fimfarchive/stories.py +++ b/fimfarchive/stories.py @@ -27,12 +27,13 @@ class Story: Represents a story. """ - def __init__(self, key, fetcher, meta=None, data=None): + def __init__(self, key, fetcher=None, meta=None, data=None, flavors=()): if fetcher is None and (data is None or meta is None): raise ValueError("Story must contain fetcher if lazy.") self.key = key self.fetcher = fetcher + self.flavors = set(flavors) self._meta = meta self._data = data diff --git a/tests/conftest.py b/tests/conftest.py index e5637fb..035165e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,7 @@ from unittest.mock import MagicMock import pytest from fimfarchive.fetchers import Fetcher +from fimfarchive.flavors import Flavor @pytest.fixture @@ -40,3 +41,15 @@ def fetcher(): fetcher.fetch_data = MagicMock(method='fetch_data') return fetcher + + +@pytest.fixture +def flavor(): + """ + Returns a flavor with A and B members. + """ + class MyFlavor(Flavor): + A = () + B = () + + return MyFlavor diff --git a/tests/test_fetchers.py b/tests/test_fetchers.py index c9b5e37..7e5d2d2 100644 --- a/tests/test_fetchers.py +++ b/tests/test_fetchers.py @@ -106,6 +106,22 @@ class TestFetcher: fetcher.close.assert_called_once_with() + def test_empty_flavors_are_passed_to_story(self, fetcher): + """ + Tests story contains empty flavors from fetcher. + """ + fetcher.flavors = set() + story = fetcher.fetch(VALID_STORY_KEY) + assert story.flavors == set() + + def test_custom_flavors_are_passed_to_story(self, fetcher, flavor): + """ + Tests story contains custom flavors from fetcher. + """ + fetcher.flavors = {flavor.A} + story = fetcher.fetch(VALID_STORY_KEY) + assert story.flavors == {flavor.A} + class TestFimfictionFetcher: """ diff --git a/tests/test_stories.py b/tests/test_stories.py index f036886..865a120 100644 --- a/tests/test_stories.py +++ b/tests/test_stories.py @@ -188,3 +188,26 @@ class TestStory: story.data assert not story.has_data + + def test_flavors_are_copied(self, fetcher, flavor): + """ + Tests story flavor change does not affect fetcher. + """ + flavors = {flavor.A} + story = Story(KEY, fetcher, flavors=flavors) + story.flavors.remove(flavor.A) + + assert story.flavors is not flavors + assert story.flavors == set() + assert flavors == {flavor.A} + + def test_flavors_are_stored_in_set(self, fetcher, flavor): + """ + Tests flavor sequence is converted to set. + """ + flavors = [flavor.A] + story = Story(KEY, fetcher, flavors=flavors) + + assert story.flavors is not flavors + assert story.flavors == {flavor.A} + assert type(story.flavors) == set