mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-23 10:01:04 +00:00
Merge branch 'main' into book-series-v1
This commit is contained in:
commit
5cc158e3be
11 changed files with 74 additions and 28 deletions
|
@ -32,6 +32,8 @@ REDIS_ACTIVITY_PORT=6379
|
||||||
REDIS_ACTIVITY_PASSWORD=redispassword345
|
REDIS_ACTIVITY_PASSWORD=redispassword345
|
||||||
# Optional, use a different redis database (defaults to 0)
|
# Optional, use a different redis database (defaults to 0)
|
||||||
# REDIS_ACTIVITY_DB_INDEX=0
|
# REDIS_ACTIVITY_DB_INDEX=0
|
||||||
|
# Alternatively specify the full redis url, i.e. if you need to use a unix:// socket
|
||||||
|
# REDIS_ACTIVITY_URL=
|
||||||
|
|
||||||
# Redis as celery broker
|
# Redis as celery broker
|
||||||
REDIS_BROKER_HOST=redis_broker
|
REDIS_BROKER_HOST=redis_broker
|
||||||
|
@ -39,6 +41,8 @@ REDIS_BROKER_PORT=6379
|
||||||
REDIS_BROKER_PASSWORD=redispassword123
|
REDIS_BROKER_PASSWORD=redispassword123
|
||||||
# Optional, use a different redis database (defaults to 0)
|
# Optional, use a different redis database (defaults to 0)
|
||||||
# REDIS_BROKER_DB_INDEX=0
|
# REDIS_BROKER_DB_INDEX=0
|
||||||
|
# Alternatively specify the full redis url, i.e. if you need to use a unix:// socket
|
||||||
|
# REDIS_BROKER_URL=
|
||||||
|
|
||||||
# Monitoring for celery
|
# Monitoring for celery
|
||||||
FLOWER_PORT=8888
|
FLOWER_PORT=8888
|
||||||
|
|
|
@ -4,12 +4,7 @@ import redis
|
||||||
|
|
||||||
from bookwyrm import settings
|
from bookwyrm import settings
|
||||||
|
|
||||||
r = redis.Redis(
|
r = redis.from_url(settings.REDIS_ACTIVITY_URL)
|
||||||
host=settings.REDIS_ACTIVITY_HOST,
|
|
||||||
port=settings.REDIS_ACTIVITY_PORT,
|
|
||||||
password=settings.REDIS_ACTIVITY_PASSWORD,
|
|
||||||
db=settings.REDIS_ACTIVITY_DB_INDEX,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def erase_streams():
|
def erase_streams():
|
||||||
|
|
|
@ -4,12 +4,7 @@ import redis
|
||||||
|
|
||||||
from bookwyrm import settings
|
from bookwyrm import settings
|
||||||
|
|
||||||
r = redis.Redis(
|
r = redis.from_url(settings.REDIS_ACTIVITY_URL)
|
||||||
host=settings.REDIS_ACTIVITY_HOST,
|
|
||||||
port=settings.REDIS_ACTIVITY_PORT,
|
|
||||||
password=settings.REDIS_ACTIVITY_PASSWORD,
|
|
||||||
db=settings.REDIS_ACTIVITY_DB_INDEX,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RedisStore(ABC):
|
class RedisStore(ABC):
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
env = Env()
|
env = Env()
|
||||||
env.read_env()
|
env.read_env()
|
||||||
DOMAIN = env("DOMAIN")
|
DOMAIN = env("DOMAIN")
|
||||||
VERSION = "0.5.3"
|
VERSION = "0.5.4"
|
||||||
|
|
||||||
RELEASE_API = env(
|
RELEASE_API = env(
|
||||||
"RELEASE_API",
|
"RELEASE_API",
|
||||||
|
@ -21,7 +21,7 @@ RELEASE_API = env(
|
||||||
PAGE_LENGTH = env("PAGE_LENGTH", 15)
|
PAGE_LENGTH = env("PAGE_LENGTH", 15)
|
||||||
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
|
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
|
||||||
|
|
||||||
JS_CACHE = "ad848b97"
|
JS_CACHE = "cd848b9a"
|
||||||
|
|
||||||
# email
|
# email
|
||||||
EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
|
EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
|
||||||
|
@ -207,7 +207,10 @@ REDIS_ACTIVITY_HOST = env("REDIS_ACTIVITY_HOST", "localhost")
|
||||||
REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379)
|
REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379)
|
||||||
REDIS_ACTIVITY_PASSWORD = env("REDIS_ACTIVITY_PASSWORD", None)
|
REDIS_ACTIVITY_PASSWORD = env("REDIS_ACTIVITY_PASSWORD", None)
|
||||||
REDIS_ACTIVITY_DB_INDEX = env("REDIS_ACTIVITY_DB_INDEX", 0)
|
REDIS_ACTIVITY_DB_INDEX = env("REDIS_ACTIVITY_DB_INDEX", 0)
|
||||||
|
REDIS_ACTIVITY_URL = env(
|
||||||
|
"REDIS_ACTIVITY_URL",
|
||||||
|
f"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}",
|
||||||
|
)
|
||||||
MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200))
|
MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200))
|
||||||
|
|
||||||
STREAMS = [
|
STREAMS = [
|
||||||
|
@ -232,7 +235,7 @@ else:
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django_redis.cache.RedisCache",
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
"LOCATION": f"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}",
|
"LOCATION": REDIS_ACTIVITY_URL,
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,6 +35,7 @@ Sender = namedtuple("Sender", ("remote_id", "key_pair"))
|
||||||
class Signature(TestCase):
|
class Signature(TestCase):
|
||||||
"""signature test"""
|
"""signature test"""
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""create users and test data"""
|
"""create users and test data"""
|
||||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||||
|
@ -86,7 +87,7 @@ class Signature(TestCase):
|
||||||
data = json.dumps(get_follow_activity(sender, self.rat))
|
data = json.dumps(get_follow_activity(sender, self.rat))
|
||||||
digest = digest or make_digest(data)
|
digest = digest or make_digest(data)
|
||||||
signature = make_signature(signer or sender, self.rat.inbox, now, digest)
|
signature = make_signature(signer or sender, self.rat.inbox, now, digest)
|
||||||
with patch("bookwyrm.views.inbox.activity_task.delay"):
|
with patch("bookwyrm.views.inbox.activity_task.apply_async"):
|
||||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||||
return self.send(signature, now, send_data or data, digest)
|
return self.send(signature, now, send_data or data, digest)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
""" test for app action functionality """
|
""" test for app action functionality """
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
import responses
|
import responses
|
||||||
|
from responses import matchers
|
||||||
|
|
||||||
from django.contrib.auth.models import Group, Permission
|
from django.contrib.auth.models import Group, Permission
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
@ -45,6 +46,44 @@ class EditBookViews(TestCase):
|
||||||
remote_id="https://example.com/book/1",
|
remote_id="https://example.com/book/1",
|
||||||
parent_work=self.work,
|
parent_work=self.work,
|
||||||
)
|
)
|
||||||
|
# pylint: disable=line-too-long
|
||||||
|
self.authors_body = "<?xml version='1.0' encoding='UTF-8' ?><?xml-stylesheet type='text/xsl' href='http://isni.oclc.org/sru/DB=1.2/?xsl=searchRetrieveResponse' ?><srw:searchRetrieveResponse xmlns:srw='http://www.loc.gov/zing/srw/' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:diag='http://www.loc.gov/zing/srw/diagnostic/' xmlns:xcql='http://www.loc.gov/zing/cql/xcql/'><srw:version>1.1</srw:version><srw:records><srw:record><isniUnformatted>0000000084510024</isniUnformatted></srw:record></srw:records></srw:searchRetrieveResponse>"
|
||||||
|
|
||||||
|
# pylint: disable=line-too-long
|
||||||
|
self.author_body = "<?xml version='1.0' encoding='UTF-8' ?><?xml-stylesheet type='text/xsl' href='http://isni.oclc.org/sru/DB=1.2/?xsl=searchRetrieveResponse' ?><srw:searchRetrieveResponse xmlns:srw='http://www.loc.gov/zing/srw/' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:diag='http://www.loc.gov/zing/srw/diagnostic/' xmlns:xcql='http://www.loc.gov/zing/cql/xcql/'><srw:records><srw:record><srw:recordData><responseRecord><ISNIAssigned><isniUnformatted>0000000084510024</isniUnformatted><isniURI>https://isni.org/isni/0000000084510024</isniURI><dataConfidence>60</dataConfidence><ISNIMetadata><identity><personOrFiction><personalName><surname>Catherine Amy Dawson Scott</surname><nameTitle>poet and novelist</nameTitle><nameUse>public</nameUse><source>VIAF</source><source>WKP</source><subsourceIdentifier>Q544961</subsourceIdentifier></personalName><personalName><forename>C. A.</forename><surname>Dawson Scott</surname><marcDate>1865-1934</marcDate><nameUse>public</nameUse><source>VIAF</source><source>NLP</source><subsourceIdentifier>a28927850</subsourceIdentifier></personalName><sources><codeOfSource>VIAF</codeOfSource><sourceIdentifier>45886165</sourceIdentifier><reference><class>ALL</class><role>CRE</role><URI>http://viaf.org/viaf/45886165</URI></reference></sources><externalInformation><information>Wikipedia</information><URI>https://en.wikipedia.org/wiki/Catherine_Amy_Dawson_Scott</URI></externalInformation></ISNIMetadata></ISNIAssigned></responseRecord></srw:recordData></srw:record></srw:records></srw:searchRetrieveResponse>"
|
||||||
|
|
||||||
|
responses.get(
|
||||||
|
"http://isni.oclc.org/sru/",
|
||||||
|
content_type="text/xml",
|
||||||
|
match=[
|
||||||
|
matchers.query_param_matcher(
|
||||||
|
{"query": 'pica.na="Sappho"'}, strict_match=False
|
||||||
|
)
|
||||||
|
],
|
||||||
|
body=self.authors_body,
|
||||||
|
)
|
||||||
|
|
||||||
|
responses.get(
|
||||||
|
"http://isni.oclc.org/sru/",
|
||||||
|
content_type="text/xml",
|
||||||
|
match=[
|
||||||
|
matchers.query_param_matcher(
|
||||||
|
{"query": 'pica.na="Some Guy"'}, strict_match=False
|
||||||
|
)
|
||||||
|
],
|
||||||
|
body=self.authors_body,
|
||||||
|
)
|
||||||
|
|
||||||
|
responses.get(
|
||||||
|
"http://isni.oclc.org/sru/",
|
||||||
|
content_type="text/xml",
|
||||||
|
match=[
|
||||||
|
matchers.query_param_matcher(
|
||||||
|
{"query": 'pica.isn="0000000084510024"'}, strict_match=False
|
||||||
|
)
|
||||||
|
],
|
||||||
|
body=self.author_body,
|
||||||
|
)
|
||||||
|
|
||||||
models.SiteSettings.objects.create()
|
models.SiteSettings.objects.create()
|
||||||
|
|
||||||
|
@ -97,6 +136,7 @@ class EditBookViews(TestCase):
|
||||||
result.context_data["cover_url"], "http://local.host/cover.jpg"
|
result.context_data["cover_url"], "http://local.host/cover.jpg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
def test_edit_book_add_author(self):
|
def test_edit_book_add_author(self):
|
||||||
"""lets a user edit a book with new authors"""
|
"""lets a user edit a book with new authors"""
|
||||||
view = views.EditBook.as_view()
|
view = views.EditBook.as_view()
|
||||||
|
@ -227,6 +267,7 @@ class EditBookViews(TestCase):
|
||||||
self.book.refresh_from_db()
|
self.book.refresh_from_db()
|
||||||
self.assertTrue(self.book.cover)
|
self.assertTrue(self.book.cover)
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
def test_add_authors_helper(self):
|
def test_add_authors_helper(self):
|
||||||
"""converts form input into author matches"""
|
"""converts form input into author matches"""
|
||||||
form = forms.EditionForm(instance=self.book)
|
form = forms.EditionForm(instance=self.book)
|
||||||
|
|
|
@ -15,6 +15,7 @@ from bookwyrm import models, views
|
||||||
class Inbox(TestCase):
|
class Inbox(TestCase):
|
||||||
"""readthrough tests"""
|
"""readthrough tests"""
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""basic user and book data"""
|
"""basic user and book data"""
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
|
@ -119,7 +120,7 @@ class Inbox(TestCase):
|
||||||
with patch("bookwyrm.views.inbox.has_valid_signature") as mock_valid:
|
with patch("bookwyrm.views.inbox.has_valid_signature") as mock_valid:
|
||||||
mock_valid.return_value = True
|
mock_valid.return_value = True
|
||||||
|
|
||||||
with patch("bookwyrm.views.inbox.activity_task.delay"):
|
with patch("bookwyrm.views.inbox.activity_task.apply_async"):
|
||||||
result = self.client.post(
|
result = self.client.post(
|
||||||
"/inbox", json.dumps(activity), content_type="application/json"
|
"/inbox", json.dumps(activity), content_type="application/json"
|
||||||
)
|
)
|
||||||
|
|
|
@ -85,6 +85,9 @@ def find_authors_by_name(name_string, description=False):
|
||||||
# build list of possible authors
|
# build list of possible authors
|
||||||
possible_authors = []
|
possible_authors = []
|
||||||
for element in root.iter("responseRecord"):
|
for element in root.iter("responseRecord"):
|
||||||
|
|
||||||
|
# TODO: we don't seem to do anything with the
|
||||||
|
# personal_name variable - is this code block needed?
|
||||||
personal_name = element.find(".//forename/..")
|
personal_name = element.find(".//forename/..")
|
||||||
if not personal_name:
|
if not personal_name:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -8,12 +8,7 @@ import redis
|
||||||
from celerywyrm import settings
|
from celerywyrm import settings
|
||||||
from bookwyrm.tasks import app as celery
|
from bookwyrm.tasks import app as celery
|
||||||
|
|
||||||
r = redis.Redis(
|
r = redis.from_url(settings.REDIS_BROKER_URL)
|
||||||
host=settings.REDIS_BROKER_HOST,
|
|
||||||
port=settings.REDIS_BROKER_PORT,
|
|
||||||
password=settings.REDIS_BROKER_PASSWORD,
|
|
||||||
db=settings.REDIS_BROKER_DB_INDEX,
|
|
||||||
)
|
|
||||||
|
|
||||||
# pylint: disable= no-self-use
|
# pylint: disable= no-self-use
|
||||||
@method_decorator(login_required, name="dispatch")
|
@method_decorator(login_required, name="dispatch")
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.views import View
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
from bookwyrm import activitypub, models
|
from bookwyrm import activitypub, models
|
||||||
from bookwyrm.tasks import app, MEDIUM
|
from bookwyrm.tasks import app, MEDIUM, HIGH
|
||||||
from bookwyrm.signatures import Signature
|
from bookwyrm.signatures import Signature
|
||||||
from bookwyrm.utils import regex
|
from bookwyrm.utils import regex
|
||||||
|
|
||||||
|
@ -60,7 +60,11 @@ class Inbox(View):
|
||||||
return HttpResponse()
|
return HttpResponse()
|
||||||
return HttpResponse(status=401)
|
return HttpResponse(status=401)
|
||||||
|
|
||||||
activity_task.delay(activity_json)
|
# Make activities relating to follow/unfollow a high priority
|
||||||
|
high = ["Follow", "Accept", "Reject", "Block", "Unblock", "Undo"]
|
||||||
|
|
||||||
|
priority = HIGH if activity_json["type"] in high else MEDIUM
|
||||||
|
activity_task.apply_async(args=(activity_json,), queue=priority)
|
||||||
return HttpResponse()
|
return HttpResponse()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,13 @@ REDIS_BROKER_PASSWORD = requests.utils.quote(env("REDIS_BROKER_PASSWORD", None))
|
||||||
REDIS_BROKER_HOST = env("REDIS_BROKER_HOST", "redis_broker")
|
REDIS_BROKER_HOST = env("REDIS_BROKER_HOST", "redis_broker")
|
||||||
REDIS_BROKER_PORT = env("REDIS_BROKER_PORT", 6379)
|
REDIS_BROKER_PORT = env("REDIS_BROKER_PORT", 6379)
|
||||||
REDIS_BROKER_DB_INDEX = env("REDIS_BROKER_DB_INDEX", 0)
|
REDIS_BROKER_DB_INDEX = env("REDIS_BROKER_DB_INDEX", 0)
|
||||||
|
REDIS_BROKER_URL = env(
|
||||||
|
"REDIS_BROKER_URL",
|
||||||
|
f"redis://:{REDIS_BROKER_PASSWORD}@{REDIS_BROKER_HOST}:{REDIS_BROKER_PORT}/{REDIS_BROKER_DB_INDEX}",
|
||||||
|
)
|
||||||
|
|
||||||
CELERY_BROKER_URL = f"redis://:{REDIS_BROKER_PASSWORD}@{REDIS_BROKER_HOST}:{REDIS_BROKER_PORT}/{REDIS_BROKER_DB_INDEX}"
|
CELERY_BROKER_URL = REDIS_BROKER_URL.replace("unix:", "redis+socket:")
|
||||||
CELERY_RESULT_BACKEND = f"redis://:{REDIS_BROKER_PASSWORD}@{REDIS_BROKER_HOST}:{REDIS_BROKER_PORT}/{REDIS_BROKER_DB_INDEX}"
|
CELERY_RESULT_BACKEND = REDIS_BROKER_URL.replace("unix:", "redis+socket:")
|
||||||
|
|
||||||
CELERY_DEFAULT_QUEUE = "low_priority"
|
CELERY_DEFAULT_QUEUE = "low_priority"
|
||||||
CELERY_CREATE_MISSING_QUEUES = True
|
CELERY_CREATE_MISSING_QUEUES = True
|
||||||
|
|
Loading…
Reference in a new issue