diff --git a/fimfarchive/converters/alpha_beta.py b/fimfarchive/converters/alpha_beta/__init__.py similarity index 68% rename from fimfarchive/converters/alpha_beta.py rename to fimfarchive/converters/alpha_beta/__init__.py index eb2fa5d..3f761d6 100644 --- a/fimfarchive/converters/alpha_beta.py +++ b/fimfarchive/converters/alpha_beta/__init__.py @@ -22,6 +22,7 @@ Alpha to beta converter for story meta. # +import json from copy import deepcopy from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple from urllib.parse import quote_plus as urlquote @@ -33,8 +34,9 @@ from jmespath.parser import ParsedResult from fimfarchive.flavors import MetaFormat from fimfarchive.stories import Story +from fimfarchive.utils import ResourceLoader -from .base import Converter +from ..base import Converter __all__ = ( @@ -42,147 +44,14 @@ __all__ = ( ) +load = ResourceLoader(__package__) + + HOST = 'https://www.fimfiction.net' +TAGS = json.loads(load('tags.json')) EPOCH = arrow.get(0).isoformat() -TAGS = { - '2nd Person': { - 'id': 225, - 'name': 'Second Person', - 'old_id': 'g:second_person', - 'type': 'content', - 'url': 'https://www.fimfiction.net/tag/second-person', - }, - 'Adventure': { - 'id': 226, - 'name': 'Adventure', - 'old_id': 'g:adventure', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/adventure', - }, - 'Alternate Universe': { - 'id': 240, - 'name': 'Alternate Universe', - 'old_id': 'g:alternate_universe', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/alternate-universe', - }, - 'Anthro': { - 'id': 227, - 'name': 'Anthro', - 'old_id': 'g:anthro', - 'type': 'content', - 'url': 'https://www.fimfiction.net/tag/anthro', - }, - 'Comedy': { - 'id': 228, - 'name': 'Comedy', - 'old_id': 'g:comedy', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/comedy', - }, - 'Crossover': { - 'id': 229, - 'name': 'Crossover', - 'old_id': 'g:crossover', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/crossover', - }, - 'Dark': { - 'id': 122, - 'name': 'Dark', - 'old_id': 'g:dark', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/dark', - }, - 'Drama': { - 'id': 230, - 'name': 'Drama', - 'old_id': 'g:drama', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/drama', - }, - 'Equestria Girls': { - 'id': 123, - 'name': 'Equestria Girls', - 'old_id': 'g:equestria_girls', - 'type': 'series', - 'url': 'https://www.fimfiction.net/tag/equestria-girls', - }, - 'Horror': { - 'id': 231, - 'name': 'Horror', - 'old_id': 'g:horror', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/horror', - }, - 'Human': { - 'id': 232, - 'name': 'Human', - 'old_id': 'g:human', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/human', - }, - 'Mystery': { - 'id': 233, - 'name': 'Mystery', - 'old_id': 'g:mystery', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/mystery', - }, - 'Random': { - 'id': 234, - 'name': 'Random', - 'old_id': 'g:random', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/random', - }, - 'Romance': { - 'id': 120, - 'name': 'Romance', - 'old_id': 'g:romance', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/romance', - }, - 'Sad': { - 'id': 235, - 'name': 'Sad', - 'old_id': 'g:sad', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/sad', - }, - 'Sci-Fi': { - 'id': 236, - 'name': 'Science Fiction', - 'old_id': 'g:scifi', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/scifi', - }, - 'Slice of Life': { - 'id': 237, - 'name': 'Slice of Life', - 'old_id': 'g:slice_of_life', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/slice-of-life', - }, - 'Thriller': { - 'id': 238, - 'name': 'Thriller', - 'old_id': 'g:thriller', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/thriller', - }, - 'Tragedy': { - 'id': 239, - 'name': 'Tragedy', - 'old_id': 'g:tragedy', - 'type': 'genre', - 'url': 'https://www.fimfiction.net/tag/tragedy', - }, -} - - class Handler(Iterable[Tuple[str, Any]]): """ Maps story meta to another style. diff --git a/fimfarchive/converters/alpha_beta/tags.json b/fimfarchive/converters/alpha_beta/tags.json new file mode 100644 index 0000000..657470a --- /dev/null +++ b/fimfarchive/converters/alpha_beta/tags.json @@ -0,0 +1,135 @@ +{ + "2nd Person": { + "id": 225, + "name": "Second Person", + "old_id": "g:second_person", + "type": "content", + "url": "https://www.fimfiction.net/tag/second-person" + }, + "Adventure": { + "id": 226, + "name": "Adventure", + "old_id": "g:adventure", + "type": "genre", + "url": "https://www.fimfiction.net/tag/adventure" + }, + "Alternate Universe": { + "id": 240, + "name": "Alternate Universe", + "old_id": "g:alternate_universe", + "type": "genre", + "url": "https://www.fimfiction.net/tag/alternate-universe" + }, + "Anthro": { + "id": 227, + "name": "Anthro", + "old_id": "g:anthro", + "type": "content", + "url": "https://www.fimfiction.net/tag/anthro" + }, + "Comedy": { + "id": 228, + "name": "Comedy", + "old_id": "g:comedy", + "type": "genre", + "url": "https://www.fimfiction.net/tag/comedy" + }, + "Crossover": { + "id": 229, + "name": "Crossover", + "old_id": "g:crossover", + "type": "genre", + "url": "https://www.fimfiction.net/tag/crossover" + }, + "Dark": { + "id": 122, + "name": "Dark", + "old_id": "g:dark", + "type": "genre", + "url": "https://www.fimfiction.net/tag/dark" + }, + "Drama": { + "id": 230, + "name": "Drama", + "old_id": "g:drama", + "type": "genre", + "url": "https://www.fimfiction.net/tag/drama" + }, + "Equestria Girls": { + "id": 123, + "name": "Equestria Girls", + "old_id": "g:equestria_girls", + "type": "series", + "url": "https://www.fimfiction.net/tag/equestria-girls" + }, + "Horror": { + "id": 231, + "name": "Horror", + "old_id": "g:horror", + "type": "genre", + "url": "https://www.fimfiction.net/tag/horror" + }, + "Human": { + "id": 232, + "name": "Human", + "old_id": "g:human", + "type": "genre", + "url": "https://www.fimfiction.net/tag/human" + }, + "Mystery": { + "id": 233, + "name": "Mystery", + "old_id": "g:mystery", + "type": "genre", + "url": "https://www.fimfiction.net/tag/mystery" + }, + "Random": { + "id": 234, + "name": "Random", + "old_id": "g:random", + "type": "genre", + "url": "https://www.fimfiction.net/tag/random" + }, + "Romance": { + "id": 120, + "name": "Romance", + "old_id": "g:romance", + "type": "genre", + "url": "https://www.fimfiction.net/tag/romance" + }, + "Sad": { + "id": 235, + "name": "Sad", + "old_id": "g:sad", + "type": "genre", + "url": "https://www.fimfiction.net/tag/sad" + }, + "Sci-Fi": { + "id": 236, + "name": "Science Fiction", + "old_id": "g:scifi", + "type": "genre", + "url": "https://www.fimfiction.net/tag/scifi" + }, + "Slice of Life": { + "id": 237, + "name": "Slice of Life", + "old_id": "g:slice_of_life", + "type": "genre", + "url": "https://www.fimfiction.net/tag/slice-of-life" + }, + "Thriller": { + "id": 238, + "name": "Thriller", + "old_id": "g:thriller", + "type": "genre", + "url": "https://www.fimfiction.net/tag/thriller" + }, + "Tragedy": { + "id": 239, + "name": "Tragedy", + "old_id": "g:tragedy", + "type": "genre", + "url": "https://www.fimfiction.net/tag/tragedy" + } +} diff --git a/fimfarchive/utils.py b/fimfarchive/utils.py index e538cc9..1688d05 100644 --- a/fimfarchive/utils.py +++ b/fimfarchive/utils.py @@ -25,7 +25,8 @@ Various utilities. import json import os import shutil -from typing import Any, Dict, Optional, Type, TypeVar +from typing import Any, Dict, Optional, Type, TypeVar, Union +from pkg_resources import resource_string from fimfarchive.flavors import Flavor from fimfarchive.stories import Story @@ -126,3 +127,41 @@ def find_flavor(story: Story, flavor: Type[F]) -> Optional[F]: return current return None + + +class ResourceLoader: + """ + Loads resources from a package. + """ + + def __init__(self, package: str, binary: bool = False) -> None: + """ + Constructor. + + Args: + package: The package to load from. + binary: Set to return binary data. + """ + self.package = package + self.binary = binary + + def __call__(self, name: str, binary: bool = None) -> Union[str, bytes]: + """ + Loads a package resource. + + Args: + name: The name of the resource to load. + binary: Set to return binary data. + + Returns: + A resource as string or bytes. + """ + if binary is None: + binary = self.binary + + data = resource_string(self.package, name) + + if binary: + return data + else: + return data.decode()