Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2021-04-15 16:41:50 -07:00
commit 9ad369203f
5 changed files with 175 additions and 152 deletions

View file

@ -359,6 +359,10 @@ class CollectionItemMixin(ActivitypubMixin):
activity_serializer = activitypub.CollectionItem
def broadcast(self, activity, sender, software="bookwyrm"):
""" only send book collection updates to other bookwyrm instances """
super().broadcast(activity, sender, software=software)
@property
def privacy(self):
""" inherit the privacy of the list, or direct if pending """
@ -371,6 +375,9 @@ class CollectionItemMixin(ActivitypubMixin):
def recipients(self):
""" the owner of the list is a direct recipient """
collection_field = getattr(self, self.collection_field)
if collection_field.user.local:
# don't broadcast to yourself
return []
return [collection_field.user]
def save(self, *args, broadcast=True, **kwargs):

View file

@ -3,6 +3,12 @@ html {
scroll-padding-top: 20%;
}
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.image {
overflow: hidden;
}

View file

@ -22,165 +22,169 @@
<meta name="twitter:image:alt" content="BookWyrm Logo">
</head>
<body>
<nav class="navbar container" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<img class="image logo" src="{% if site.logo_small %}/images/{{ site.logo_small }}{% else %}/static/images/logo-small.png{% endif %}" alt="Home page">
</a>
<form class="navbar-item column" action="/search/">
<div class="field has-addons">
<div class="control">
<input aria-label="{% trans 'Search for a book or user' %}" id="search-input" class="input" type="text" name="q" placeholder="{% trans 'Search for a book or user' %}" value="{{ query }}">
</div>
<div class="control">
<button class="button" type="submit">
<span class="icon icon-search" title="{% trans 'Search' %}">
<span class="is-sr-only">{% trans "Search" %}</span>
</span>
</button>
</div>
</div>
</form>
<div role="button" tabindex="0" class="navbar-burger pulldown-menu" data-controls="main-nav" aria-expanded="false">
<div class="navbar-item mt-3">
<div class="icon icon-dots-three-vertical" title="{% trans 'Main navigation menu' %}">
<span class="is-sr-only">{% trans "Main navigation menu" %}</span>
</div>
</div>
</div>
</div>
<div class="navbar-menu" id="main-nav">
<div class="navbar-start">
{% if request.user.is_authenticated %}
<a href="{% url 'user-shelves' request.user.localname %}" class="navbar-item">
{% trans "Your books" %}
<nav class="navbar" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<img class="image logo" src="{% if site.logo_small %}/images/{{ site.logo_small }}{% else %}/static/images/logo-small.png{% endif %}" alt="Home page">
</a>
<a href="/#feed" class="navbar-item">
{% trans "Feed" %}
</a>
<a href="{% url 'lists' %}" class="navbar-item">
{% trans "Lists" %}
</a>
{% endif %}
</div>
<div class="navbar-end">
{% if request.user.is_authenticated %}
<div class="navbar-item has-dropdown is-hoverable">
<a
href="{{ request.user.local_path }}"
class="navbar-link pulldown-menu"
role="button"
aria-expanded="false"
tabindex="0"
aria-haspopup="true"
aria-controls="navbar-dropdown"
>
{% include 'snippets/avatar.html' with user=request.user %}
<span class="ml-2">{{ request.user.display_name }}</span>
</a>
<ul class="navbar-dropdown" id="navbar-dropdown">
<li>
<a href="{% url 'direct-messages' %}" class="navbar-item">
{% trans "Direct Messages" %}
</a>
</li>
<li>
<a href="{% url 'directory' %}" class="navbar-item">
{% trans 'Directory' %}
</a>
</li>
<li>
<a href="/import" class="navbar-item">
{% trans 'Import Books' %}
</a>
</li>
<li>
<a href="/preferences/profile" class="navbar-item">
{% trans 'Settings' %}
</a>
</li>
{% if perms.bookwyrm.create_invites or perms.moderate_users %}
<li class="navbar-divider" role="presentation"></li>
{% endif %}
{% if perms.bookwyrm.create_invites %}
<li>
<a href="{% url 'settings-invite-requests' %}" class="navbar-item">
{% trans 'Invites' %}
</a>
</li>
{% endif %}
{% if perms.bookwyrm.moderate_users %}
<li>
<a href="{% url 'settings-users' %}" class="navbar-item">
{% trans 'Admin' %}
</a>
</li>
{% endif %}
<li class="navbar-divider" role="presentation"></li>
<li>
<a href="/logout" class="navbar-item">
{% trans 'Log out' %}
</a>
</li>
</ul>
</div>
<div class="navbar-item">
<a href="/notifications" class="tags has-addons">
<span class="tag is-medium">
<span class="icon icon-bell" title="{% trans 'Notifications' %}">
<span class="is-sr-only">{% trans "Notifications" %}</span>
</span>
</span>
<span class="{% if not request.user|notification_count %}is-hidden {% endif %}tag is-danger is-medium transition-x" data-poll-wrapper>
<span data-poll="notifications">{{ request.user | notification_count }}</span>
</span>
</a>
</div>
{% else %}
<div class="navbar-item">
{% if request.path != '/login' and request.path != '/login/' %}
<div class="columns">
<div class="column">
<form name="login" method="post" action="/login">
{% csrf_token %}
<div class="columns is-variable is-1">
<div class="column">
<label class="is-sr-only" for="id_localname">{% trans "Username:" %}</label>
<input type="text" name="localname" maxlength="150" class="input" required="" id="id_localname" placeholder="{% trans 'username' %}">
</div>
<div class="column">
<label class="is-sr-only" for="id_password">{% trans "Username:" %}</label>
<input type="password" name="password" maxlength="128" class="input" required="" id="id_password" placeholder="{% trans 'password' %}">
<p class="help"><a href="/password-reset">{% trans "Forgot your password?" %}</a></p>
</div>
<div class="column is-narrow">
<button class="button is-primary" type="submit">{% trans "Log in" %}</button>
</div>
</div>
</form>
<form class="navbar-item column" action="/search/">
<div class="field has-addons">
<div class="control">
<input aria-label="{% trans 'Search for a book or user' %}" id="search-input" class="input" type="text" name="q" placeholder="{% trans 'Search for a book or user' %}" value="{{ query }}">
</div>
{% if site.allow_registration and request.path != '' and request.path != '/' %}
<div class="column is-narrow">
<a href="/" class="button is-link">
{% trans "Join" %}
</a>
<div class="control">
<button class="button" type="submit">
<span class="icon icon-search" title="{% trans 'Search' %}">
<span class="is-sr-only">{% trans "Search" %}</span>
</span>
</button>
</div>
</div>
</form>
<div role="button" tabindex="0" class="navbar-burger pulldown-menu" data-controls="main-nav" aria-expanded="false">
<div class="navbar-item mt-3">
<div class="icon icon-dots-three-vertical" title="{% trans 'Main navigation menu' %}">
<span class="is-sr-only">{% trans "Main navigation menu" %}</span>
</div>
</div>
</div>
</div>
<div class="navbar-menu" id="main-nav">
<div class="navbar-start">
{% if request.user.is_authenticated %}
<a href="{% url 'user-shelves' request.user.localname %}" class="navbar-item">
{% trans "Your books" %}
</a>
<a href="/#feed" class="navbar-item">
{% trans "Feed" %}
</a>
<a href="{% url 'lists' %}" class="navbar-item">
{% trans "Lists" %}
</a>
{% endif %}
</div>
<div class="navbar-end">
{% if request.user.is_authenticated %}
<div class="navbar-item has-dropdown is-hoverable">
<a
href="{{ request.user.local_path }}"
class="navbar-link pulldown-menu"
role="button"
aria-expanded="false"
tabindex="0"
aria-haspopup="true"
aria-controls="navbar-dropdown"
>
{% include 'snippets/avatar.html' with user=request.user %}
<span class="ml-2">{{ request.user.display_name }}</span>
</a>
<ul class="navbar-dropdown" id="navbar-dropdown">
<li>
<a href="{% url 'direct-messages' %}" class="navbar-item">
{% trans "Direct Messages" %}
</a>
</li>
<li>
<a href="{% url 'directory' %}" class="navbar-item">
{% trans 'Directory' %}
</a>
</li>
<li>
<a href="/import" class="navbar-item">
{% trans 'Import Books' %}
</a>
</li>
<li>
<a href="/preferences/profile" class="navbar-item">
{% trans 'Settings' %}
</a>
</li>
{% if perms.bookwyrm.create_invites or perms.moderate_users %}
<li class="navbar-divider" role="presentation"></li>
{% endif %}
{% if perms.bookwyrm.create_invites %}
<li>
<a href="{% url 'settings-invite-requests' %}" class="navbar-item">
{% trans 'Invites' %}
</a>
</li>
{% endif %}
{% if perms.bookwyrm.moderate_users %}
<li>
<a href="{% url 'settings-users' %}" class="navbar-item">
{% trans 'Admin' %}
</a>
</li>
{% endif %}
<li class="navbar-divider" role="presentation"></li>
<li>
<a href="/logout" class="navbar-item">
{% trans 'Log out' %}
</a>
</li>
</ul>
</div>
<div class="navbar-item">
<a href="/notifications" class="tags has-addons">
<span class="tag is-medium">
<span class="icon icon-bell" title="{% trans 'Notifications' %}">
<span class="is-sr-only">{% trans "Notifications" %}</span>
</span>
</span>
<span class="{% if not request.user|notification_count %}is-hidden {% endif %}tag is-danger is-medium transition-x" data-poll-wrapper>
<span data-poll="notifications">{{ request.user | notification_count }}</span>
</span>
</a>
</div>
{% else %}
<div class="navbar-item">
{% if request.path != '/login' and request.path != '/login/' %}
<div class="columns">
<div class="column">
<form name="login" method="post" action="/login">
{% csrf_token %}
<div class="columns is-variable is-1">
<div class="column">
<label class="is-sr-only" for="id_localname">{% trans "Username:" %}</label>
<input type="text" name="localname" maxlength="150" class="input" required="" id="id_localname" placeholder="{% trans 'username' %}">
</div>
<div class="column">
<label class="is-sr-only" for="id_password">{% trans "Username:" %}</label>
<input type="password" name="password" maxlength="128" class="input" required="" id="id_password" placeholder="{% trans 'password' %}">
<p class="help"><a href="/password-reset">{% trans "Forgot your password?" %}</a></p>
</div>
<div class="column is-narrow">
<button class="button is-primary" type="submit">{% trans "Log in" %}</button>
</div>
</div>
</form>
</div>
{% if site.allow_registration and request.path != '' and request.path != '/' %}
<div class="column is-narrow">
<a href="/" class="button is-link">
{% trans "Join" %}
</a>
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
</nav>
<div class="section container">
{% block content %}
{% endblock %}
<div class="section is-flex-grow-1">
<div class="container">
{% block content %}
{% endblock %}
</div>
</div>
<footer class="footer">

View file

@ -55,7 +55,7 @@ class List(TestCase):
self.assertTrue(item.approved)
self.assertEqual(item.privacy, "unlisted")
self.assertEqual(item.recipients, [self.local_user])
self.assertEqual(item.recipients, [])
def test_list_item_pending(self, _):
""" a list entry """
@ -71,4 +71,4 @@ class List(TestCase):
self.assertFalse(item.approved)
self.assertEqual(item.book_list.privacy, "public")
self.assertEqual(item.privacy, "direct")
self.assertEqual(item.recipients, [self.local_user])
self.assertEqual(item.recipients, [])

View file

@ -53,7 +53,7 @@ services:
- 8000:8000
redis_activity:
image: redis
command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD}
command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD} --appendonly yes
volumes:
- ./redis.conf:/etc/redis/redis.conf
env_file: .env
@ -62,9 +62,11 @@ services:
networks:
- main
restart: on-failure
volumes:
- redis_activity_data:/data
redis_broker:
image: redis
command: redis-server --requirepass ${REDIS_BROKER_PASSWORD}
command: redis-server --requirepass ${REDIS_BROKER_PASSWORD} --appendonly yes
volumes:
- ./redis.conf:/etc/redis/redis.conf
env_file: .env
@ -73,6 +75,8 @@ services:
networks:
- main
restart: on-failure
volumes:
- redis_broker_data:/data
celery_worker:
env_file: .env
build: .
@ -100,11 +104,13 @@ services:
- redis_broker
restart: on-failure
ports:
- 8888:8888
- 8888:8888
volumes:
pgdata:
backups:
static_volume:
media_volume:
redis_broker_data:
redis_activity_data:
networks:
main: