Simplify bookwyrm connector abstract

This commit is contained in:
Mouse Reeve 2020-11-28 18:56:28 -08:00
parent 9d84346d3c
commit c9433a3c7e
3 changed files with 54 additions and 71 deletions

View file

@ -16,20 +16,13 @@ class ConnectorException(HTTPError):
''' when the connector can't do what was asked '''
class AbstractConnector(ABC):
''' generic book data connector '''
class AbstractMinimalConnector(ABC):
''' just the bare bones, for other bookwyrm instances '''
def __init__(self, identifier):
# load connector settings
info = models.Connector.objects.get(identifier=identifier)
self.connector = info
self.key_mappings = []
# fields we want to look for in book data to copy over
# title we handle separately.
self.book_mappings = []
# the things in the connector model to copy over
self_fields = [
'base_url',
@ -44,15 +37,6 @@ class AbstractConnector(ABC):
for field in self_fields:
setattr(self, field, getattr(info, field))
def is_available(self):
''' check if you're allowed to use this connector '''
if self.max_query_count is not None:
if self.connector.query_count >= self.max_query_count:
return False
return True
def search(self, query, min_confidence=None):
''' free text search '''
resp = requests.get(
@ -70,9 +54,40 @@ class AbstractConnector(ABC):
results.append(self.format_search_result(doc))
return results
@abstractmethod
def get_or_create_book(self, remote_id):
''' pull up a book record by whatever means possible '''
@abstractmethod
def parse_search_data(self, data):
''' turn the result json from a search into a list '''
@abstractmethod
def format_search_result(self, search_result):
''' create a SearchResult obj from json '''
class AbstractConnector(AbstractMinimalConnector):
''' generic book data connector '''
def __init__(self, identifier):
super().__init__(identifier)
self.key_mappings = []
# fields we want to look for in book data to copy over
# title we handle separately.
self.book_mappings = []
def is_available(self):
''' check if you're allowed to use this connector '''
if self.max_query_count is not None:
if self.connector.query_count >= self.max_query_count:
return False
return True
def get_or_create_book(self, remote_id):
# try to load the book
book = models.Book.objects.select_subclasses().filter(
origin_id=remote_id
@ -157,7 +172,7 @@ class AbstractConnector(ABC):
def update_book_from_data(self, book, data, update_cover=True):
''' for creating a new book or syncing with data '''
book = self.update_from_mappings(book, data, self.book_mappings)
book = update_from_mappings(book, data, self.book_mappings)
author_text = []
for author in self.get_authors_from_data(data):
@ -246,39 +261,28 @@ class AbstractConnector(ABC):
def get_cover_from_data(self, data):
''' load cover '''
@abstractmethod
def parse_search_data(self, data):
''' turn the result json from a search into a list '''
@abstractmethod
def format_search_result(self, search_result):
''' create a SearchResult obj from json '''
@abstractmethod
def expand_book_data(self, book):
''' get more info on a book '''
def update_from_mappings(self, obj, data, mappings):
''' assign data to model with mappings '''
for mapping in mappings:
# check if this field is present in the data
value = data.get(mapping.remote_field)
if not value:
continue
def update_from_mappings(obj, data, mappings):
''' assign data to model with mappings '''
for mapping in mappings:
# check if this field is present in the data
value = data.get(mapping.remote_field)
if not value:
continue
# extract the value in the right format
try:
value = mapping.formatter(value)
except:
continue
# extract the value in the right format
try:
value = mapping.formatter(value)
except:
continue
# assign the formatted value to the model
obj.__setattr__(mapping.local_field, value)
return obj
# assign the formatted value to the model
obj.__setattr__(mapping.local_field, value)
return obj
def get_date(date_string):

View file

@ -1,9 +1,9 @@
''' using another bookwyrm instance as a source of book data '''
from bookwyrm import activitypub, models
from .abstract_connector import AbstractConnector, SearchResult
from .abstract_connector import AbstractMinimalConnector, SearchResult
class Connector(AbstractConnector):
class Connector(AbstractMinimalConnector):
''' this is basically just for search '''
def get_or_create_book(self, remote_id):
@ -14,24 +14,3 @@ class Connector(AbstractConnector):
def format_search_result(self, search_result):
return SearchResult(**search_result)
def get_remote_id_from_data(self, data):
pass
def is_work_data(self, data):
pass
def get_edition_from_work_data(self, data):
pass
def get_work_from_edition_date(self, data):
pass
def get_cover_from_data(self, data):
pass
def expand_book_data(self, book):
pass
def get_authors_from_data(self, data):
pass

View file

@ -7,7 +7,7 @@ from django.core.files.base import ContentFile
from bookwyrm import models
from .abstract_connector import AbstractConnector, SearchResult, Mapping
from .abstract_connector import ConnectorException
from .abstract_connector import get_date, get_data
from .abstract_connector import get_date, get_data, update_from_mappings
from .openlibrary_languages import languages
@ -184,7 +184,7 @@ class Connector(AbstractConnector):
data = get_data(url)
author = models.Author(openlibrary_key=olkey)
author = self.update_from_mappings(author, data, self.author_mappings)
author = update_from_mappings(author, data, self.author_mappings)
name = data.get('name')
# TODO this is making some BOLD assumption
if name: