Commit 8f525b96 authored by Patrick van der Leer's avatar Patrick van der Leer
Browse files

Refs #14

parent bfc79fd2
Pipeline #316 passed with stage
in 6 minutes and 51 seconds
......@@ -18,6 +18,7 @@ class Config(metaclass=MetaFlaskEnv):
PROJECT_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
GOODREADS_DEV_KEY = "p1H3dvMm6SK1nVpv8bhdTA"
GOOGLE_BOOKS_DEV_KEY = "AIzaSyBYtu01k1nOctODtTOphSJ7f4-dBbshvjw"
BLACKHOLE_PATH = os.path.join(PROJECT_ROOT, "blackhole")
LIBRARY_PATH = os.path.join(PROJECT_ROOT, "library")
......
......@@ -14,3 +14,4 @@ migrate = Migrate()
cache = Cache()
jwt = JWTManager()
scheduler = Scheduler()
from flask import current_app
from flask_script import Manager
from eBookHub.managers.source.goodreads import goodreads_manager
from .goodreads import goodreads_manager
from .google import google_books_manager
source_manager = Manager(current_app, usage="Source lookups")
source_manager.add_command('goodreads', goodreads_manager)
source_manager.add_command('google', google_books_manager)
__all__ = [
"source_manager"
......
from flask import current_app
from flask_script import Manager, prompt
from eBookHub.source import google_books_client
google_books_manager = Manager(current_app, usage="Google Books lookup")
@google_books_manager.command
@google_books_manager.option('-i', '--id', dest='id', default=None)
def by_id(id=None): # pragma: no cover
if id is None:
id = prompt("ID")
book = google_books_client.book_id(id)
from pprint import pprint
pprint(book)
@google_books_manager.command
@google_books_manager.option('-t', '--title', dest='q', default=None)
def search_title(q=None): # pragma: no cover
if q is None:
q = prompt("Title")
book = google_books_client.search_title(q)
from pprint import pprint
pprint(book)
@google_books_manager.command
@google_books_manager.option('-a', '--author', dest='q', default=None)
def search_author(q=None): # pragma: no cover
if q is None:
q = prompt("Author")
book = google_books_client.search_author(q)
from pprint import pprint
pprint(book)
__all__ = [
"google_books_manager"
]
from .goodreads import GoodreadsClient
from .google import GoogleBooksClient
goodreads_client = GoodreadsClient()
google_books_client = GoogleBooksClient()
sources = [
]
......@@ -8,7 +10,7 @@ sources = [
def init_sources(app):
global sources
for source in [goodreads_client]:
for source in [goodreads_client, google_books_client]:
source.init_app(app)
sources.append(source)
......@@ -16,6 +18,8 @@ def init_sources(app):
__all__ = [
"GoodreadsClient",
"goodreads_client",
"GoogleBooksClient",
"google_books_client",
"init_sources",
"sources",
......
......@@ -19,6 +19,10 @@ class SourceAbstract(ABC):
self.transformer = self.transformer_klass()
assert isinstance(self.transformer, TransformerAbstract)
@abstractmethod
def search(self, q): # pragma: no cover
pass
@abstractmethod
def search_title_and_author(self, title, author): # pragma: no cover
pass
......@@ -28,11 +32,11 @@ class SourceAbstract(ABC):
pass
@abstractmethod
def search_title(self, title): # pragma: no cover
def search_title(self, title): # pragma: no cover
pass
@abstractmethod
def search_isbn(self, isbn): # pragma: no cover
def search_isbn(self, isbn): # pragma: no cover
pass
def transform_book(self, result):
......@@ -43,7 +47,7 @@ class SourceAbstract(ABC):
def parse(self, title, authors=None):
"""
#HashTag doneIsbetterThanPerfect
#HashTag doneIsBetterThanPerfect
:param title:
:param authors:
:return:
......
......@@ -23,6 +23,9 @@ class GoodreadsClient(SourceAbstract):
def book_id(self, eid):
return self.transformer.convert_book(self.client.Book.show(eid))
def search(self, q):
raise NotImplementedError
@cache.memoize()
def search_author(self, author):
return self.client.search_author(author)
......
from collections import OrderedDict
from googleapiclient.discovery import build, Resource
from eBookHub import cache
from eBookHub.parser.exceptions import NoResultsException
from eBookHub.source.abstract import SourceAbstract
from eBookHub.source.transformer import GoogleBooksTransformer
class GoogleBooksClient(SourceAbstract):
client = None
transformer_klass = GoogleBooksTransformer
def init_app(self, app=None):
super().init_app(app)
self.client = build('books', 'v1', developerKey=app.config.get("GOOGLE_BOOKS_DEV_KEY"))
assert isinstance(self.client, Resource)
@cache.memoize()
def search(self, q):
return self.parse_search_result(
self.client.volumes().list(
# source='public',
q=q
).execute().get('items', [])
)
@cache.memoize()
def book_id(self, eid):
return self.client.volumes().get(volumeId=eid).execute()
@cache.memoize()
def search_author(self, author):
return self.search(q="inauthor:{}".format(author))
@cache.memoize()
def search_title(self, title):
return self.search(q="intitle:{}".format(title))
@cache.memoize()
def search_isbn(self, isbn):
return self.search(q="isbn:{}".format(isbn))
@cache.memoize()
def search_title_and_author(self, title, author):
return self.search(q="intitle:{}+inauthor:{}".format(title, author))
def parse_search_result(self, result):
if len(result) == 0:
raise NoResultsException()
elif len(result) > 1:
books = []
for entry in result:
books.append(self.transformer.convert_book(self.book_id(entry['id'])))
return books
return self.transformer.convert_book(self.book_id(result[0]['id']))
from .goodreads import GoodreadsTransformer
from .google import GoogleBooksTransformer
__all__ = [
"GoodreadsTransformer"
"GoodreadsTransformer",
"GoogleBooksTransformer"
]
......@@ -22,7 +22,7 @@ class GoodreadsTransformer(TransformerAbstract):
for in_key, ex_key in cls.book_mapping.items():
try:
container[in_key] = result[ex_key]
except IndexError:
except (IndexError, KeyError):
pass
container['authors'] = cls.convert_author(result['authors']['author'])
......
from .abstract import TransformerAbstract
class GoogleBooksTransformer(TransformerAbstract):
book_mapping = {
"google_id": "id",
"title": "title",
# "isbn_10": "isbn",
# "isbn_13": "isbn13",
"language": "language",
"pageCount": "num_pages",
}
author_mapping = {
}
@classmethod
def map_book(cls, result):
# weird shit...
info = result.get("volumeInfo")
info['id'] = result.get("id")
info['authors'] = result.get("volumeInfo").get("authors", None)
container = {}
for in_key, ex_key in cls.book_mapping.items():
try:
container[in_key] = info[ex_key]
except (IndexError, KeyError):
pass
container['authors'] = cls.convert_author(info.get("authors"))
return container
@classmethod
def map_author(cls, result):
return {
"name": result
}
@classmethod
def convert_book(cls, result):
if isinstance(result, list):
return [cls.convert_book(x) for x in result]
container = cls.map_book(result)
return container
@classmethod
def convert_author(cls, result):
if isinstance(result, list):
return [cls.convert_author(x) for x in result]
return cls.map_author(result)
......@@ -24,4 +24,5 @@ apscheduler
python-magic
pycountry
goodreads_api_client
\ No newline at end of file
goodreads_api_client
google-api-python-client
\ No newline at end of file
# -*- coding: utf-8 -*-
from flask_testing import TestCase
from eBookHub.source import google_books_client
from eBookHub.jobs.blackhole import process_file
from eBookHub.parser.exceptions import NoResultsException
from eBookHub.parser.filename import FilenameParser
from tests.base import MyTestCase
class GoogleBooksSourceTestCase(MyTestCase, TestCase):
line = 'Eriksson, Jerker & Sundquist, Hakan Axlander - [Kihlberg & Zetterlund 01] Het kraaienmeisje.epub'
def test_process_file(self):
parser = FilenameParser()
book_data_raw = parser.parse(self.line)
google_books_client.parse(book_data_raw['title'], book_data_raw['authors'])
def test_process_file_function(self):
process_file(self.line)
def test_search_book_isbn(self):
with self.assertRaises(NoResultsException):
google_books_client.search_isbn("1234567890")
with self.assertRaises(NoResultsException):
google_books_client.search_isbn("1234567890123")
# stupid api, returns result at random...
try:
google_books_client.search_isbn("9789403153605")
except NoResultsException:
pass
def test_search_book_title(self):
google_books_client.search_title("test")
def test_search_author(self):
google_books_client.search_author("test")
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment