Use flavors in fetchers and stories

This commit is contained in:
Joakim Soderlund 2016-12-19 00:26:24 +01:00
parent 543d8f02e9
commit 034bfb7419
5 changed files with 70 additions and 2 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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:
"""

View file

@ -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