mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2025-01-20 22:18:07 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
9ad369203f
5 changed files with 175 additions and 152 deletions
|
@ -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):
|
||||
|
|
|
@ -3,6 +3,12 @@ html {
|
|||
scroll-padding-top: 20%;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.image {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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, [])
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue