Fix for goodreads not working anymore (due to blocked requests calls by goodreads.com)

This commit is contained in:
Ozzie Isaacs 2024-05-10 15:24:24 +02:00
commit c8c3b3cba3
5 changed files with 43 additions and 26 deletions

View File

@ -186,7 +186,6 @@ def create_app():
services.ldap.init_app(app, config) services.ldap.init_app(app, config)
if services.goodreads_support: if services.goodreads_support:
services.goodreads_support.connect(config.config_goodreads_api_key, services.goodreads_support.connect(config.config_goodreads_api_key,
config.config_goodreads_api_secret_e,
config.config_use_goodreads) config.config_use_goodreads)
config.store_calibre_uuid(calibre_db, db.Library_Id) config.store_calibre_uuid(calibre_db, db.Library_Id)
# Configure rate limiter # Configure rate limiter

View File

@ -1806,11 +1806,8 @@ def _configuration_update_helper():
# Goodreads configuration # Goodreads configuration
_config_checkbox(to_save, "config_use_goodreads") _config_checkbox(to_save, "config_use_goodreads")
_config_string(to_save, "config_goodreads_api_key") _config_string(to_save, "config_goodreads_api_key")
if to_save.get("config_goodreads_api_secret_e", ""):
_config_string(to_save, "config_goodreads_api_secret_e")
if services.goodreads_support: if services.goodreads_support:
services.goodreads_support.connect(config.config_goodreads_api_key, services.goodreads_support.connect(config.config_goodreads_api_key,
config.config_goodreads_api_secret_e,
config.config_use_goodreads) config.config_use_goodreads)
_config_int(to_save, "config_updatechannel") _config_int(to_save, "config_updatechannel")

View File

@ -114,8 +114,6 @@ class _Settings(_Base):
config_use_goodreads = Column(Boolean, default=False) config_use_goodreads = Column(Boolean, default=False)
config_goodreads_api_key = Column(String) config_goodreads_api_key = Column(String)
config_goodreads_api_secret_e = Column(String)
config_goodreads_api_secret = Column(String)
config_register_email = Column(Boolean, default=False) config_register_email = Column(Boolean, default=False)
config_login_type = Column(Integer, default=0) config_login_type = Column(Integer, default=0)
@ -422,19 +420,13 @@ def _encrypt_fields(session, secret_key):
except OperationalError: except OperationalError:
with session.bind.connect() as conn: with session.bind.connect() as conn:
conn.execute(text("ALTER TABLE settings ADD column 'mail_password_e' String")) conn.execute(text("ALTER TABLE settings ADD column 'mail_password_e' String"))
conn.execute(text("ALTER TABLE settings ADD column 'config_goodreads_api_secret_e' String"))
conn.execute(text("ALTER TABLE settings ADD column 'config_ldap_serv_password_e' String")) conn.execute(text("ALTER TABLE settings ADD column 'config_ldap_serv_password_e' String"))
session.commit() session.commit()
crypter = Fernet(secret_key) crypter = Fernet(secret_key)
settings = session.query(_Settings.mail_password, _Settings.config_goodreads_api_secret, settings = session.query(_Settings.mail_password, _Settings.config_ldap_serv_password).first()
_Settings.config_ldap_serv_password).first()
if settings.mail_password: if settings.mail_password:
session.query(_Settings).update( session.query(_Settings).update(
{_Settings.mail_password_e: crypter.encrypt(settings.mail_password.encode())}) {_Settings.mail_password_e: crypter.encrypt(settings.mail_password.encode())})
if settings.config_goodreads_api_secret:
session.query(_Settings).update(
{_Settings.config_goodreads_api_secret_e:
crypter.encrypt(settings.config_goodreads_api_secret.encode())})
if settings.config_ldap_serv_password: if settings.config_ldap_serv_password:
session.query(_Settings).update( session.query(_Settings).update(
{_Settings.config_ldap_serv_password_e: {_Settings.config_ldap_serv_password_e:

View File

@ -18,18 +18,51 @@
import time import time
from functools import reduce from functools import reduce
import requests
import xmltodict
from goodreads.client import GoodreadsClient
from goodreads.request import GoodreadsRequest
try: try:
from goodreads.client import GoodreadsClient import Levenshtein
except ImportError: except ImportError:
from betterreads.client import GoodreadsClient Levenshtein = False
try: import Levenshtein
except ImportError: Levenshtein = False
from .. import logger from .. import logger
class my_GoodreadsClient(GoodreadsClient):
def request(self, *args, **kwargs):
"""Create a GoodreadsRequest object and make that request"""
req = my_GoodreadsRequest(self, *args, **kwargs)
return req.request()
class GoodreadsRequestException(Exception):
def __init__(self, error_msg, url):
self.error_msg = error_msg
self.url = url
def __str__(self):
return self.url, ':', self.error_msg
class my_GoodreadsRequest(GoodreadsRequest):
def request(self):
resp = requests.get(self.host+self.path, params=self.params,
headers={"User-agent":"Mozilla/5.0 (X11; Linux x86_64; rv:125.0) "
"Gecko/20100101 Firefox/125.0"})
if resp.status_code != 200:
raise GoodreadsRequestException(resp.reason, self.path)
if self.req_format == 'xml':
data_dict = xmltodict.parse(resp.content)
return data_dict['GoodreadsResponse']
else:
raise Exception("Invalid format")
log = logger.create() log = logger.create()
_client = None # type: GoodreadsClient _client = None # type: GoodreadsClient
@ -38,20 +71,20 @@ _CACHE_TIMEOUT = 23 * 60 * 60 # 23 hours (in seconds)
_AUTHORS_CACHE = {} _AUTHORS_CACHE = {}
def connect(key=None, secret=None, enabled=True): def connect(key=None, enabled=True):
global _client global _client
if not enabled or not key or not secret: if not enabled or not key:
_client = None _client = None
return return
if _client: if _client:
# make sure the configuration has not changed since last we used the client # make sure the configuration has not changed since last we used the client
if _client.client_key != key or _client.client_secret != secret: if _client.client_key != key:
_client = None _client = None
if not _client: if not _client:
_client = GoodreadsClient(key, secret) _client = GoodreadsClient(key, None)
def get_author_info(author_name): def get_author_info(author_name):

View File

@ -162,10 +162,6 @@
<label for="config_goodreads_api_key">{{_('Goodreads API Key')}}</label> <label for="config_goodreads_api_key">{{_('Goodreads API Key')}}</label>
<input type="text" class="form-control" id="config_goodreads_api_key" name="config_goodreads_api_key" value="{% if config.config_goodreads_api_key != None %}{{ config.config_goodreads_api_key }}{% endif %}" autocomplete="off"> <input type="text" class="form-control" id="config_goodreads_api_key" name="config_goodreads_api_key" value="{% if config.config_goodreads_api_key != None %}{{ config.config_goodreads_api_key }}{% endif %}" autocomplete="off">
</div> </div>
<div class="form-group">
<label for="config_goodreads_api_secret_e">{{_('Goodreads API Secret')}}</label>
<input type="password" class="form-control" id="config_goodreads_api_secret_e" name="config_goodreads_api_secret_e" value="" autocomplete="off">
</div>
</div> </div>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">