mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-16 13:16:33 +00:00
commit
c59abdc89a
10 changed files with 176 additions and 16 deletions
93
bookwyrm/migrations/0112_auto_20211022_0844.py
Normal file
93
bookwyrm/migrations/0112_auto_20211022_0844.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# Generated by Django 3.2.5 on 2021-10-22 08:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("bookwyrm", "0111_merge_0107_auto_20211016_0639_0110_auto_20211015_1734"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveConstraint(
|
||||||
|
model_name="notification",
|
||||||
|
name="notification_type_valid",
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="notification",
|
||||||
|
name="notification_type",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("FAVORITE", "Favorite"),
|
||||||
|
("REPLY", "Reply"),
|
||||||
|
("MENTION", "Mention"),
|
||||||
|
("TAG", "Tag"),
|
||||||
|
("FOLLOW", "Follow"),
|
||||||
|
("FOLLOW_REQUEST", "Follow Request"),
|
||||||
|
("BOOST", "Boost"),
|
||||||
|
("IMPORT", "Import"),
|
||||||
|
("ADD", "Add"),
|
||||||
|
("REPORT", "Report"),
|
||||||
|
("INVITE", "Invite"),
|
||||||
|
("ACCEPT", "Accept"),
|
||||||
|
("JOIN", "Join"),
|
||||||
|
("LEAVE", "Leave"),
|
||||||
|
("REMOVE", "Remove"),
|
||||||
|
("GROUP_PRIVACY", "Group Privacy"),
|
||||||
|
("GROUP_NAME", "Group Name"),
|
||||||
|
("GROUP_DESCRIPTION", "Group Description"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="user",
|
||||||
|
name="preferred_language",
|
||||||
|
field=models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("en-us", "English"),
|
||||||
|
("de-de", "Deutsch (German)"),
|
||||||
|
("es-es", "Español (Spanish)"),
|
||||||
|
("fr-fr", "Français (French)"),
|
||||||
|
("pt-br", "Português - Brasil (Brazilian Portuguese)"),
|
||||||
|
("zh-hans", "简体中文 (Simplified Chinese)"),
|
||||||
|
("zh-hant", "繁體中文 (Traditional Chinese)"),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name="notification",
|
||||||
|
constraint=models.CheckConstraint(
|
||||||
|
check=models.Q(
|
||||||
|
(
|
||||||
|
"notification_type__in",
|
||||||
|
[
|
||||||
|
"FAVORITE",
|
||||||
|
"REPLY",
|
||||||
|
"MENTION",
|
||||||
|
"TAG",
|
||||||
|
"FOLLOW",
|
||||||
|
"FOLLOW_REQUEST",
|
||||||
|
"BOOST",
|
||||||
|
"IMPORT",
|
||||||
|
"ADD",
|
||||||
|
"REPORT",
|
||||||
|
"INVITE",
|
||||||
|
"ACCEPT",
|
||||||
|
"JOIN",
|
||||||
|
"LEAVE",
|
||||||
|
"REMOVE",
|
||||||
|
"GROUP_PRIVACY",
|
||||||
|
"GROUP_NAME",
|
||||||
|
"GROUP_DESCRIPTION",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
name="notification_type_valid",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -23,7 +23,7 @@ class Group(BookWyrmModel):
|
||||||
@classmethod
|
@classmethod
|
||||||
def followers_filter(cls, queryset, viewer):
|
def followers_filter(cls, queryset, viewer):
|
||||||
"""Override filter for "followers" privacy level to allow non-following
|
"""Override filter for "followers" privacy level to allow non-following
|
||||||
group members to see the existence of groups and group lists"""
|
group members to see the existence of group-curated lists"""
|
||||||
|
|
||||||
return queryset.exclude(
|
return queryset.exclude(
|
||||||
~Q( # user is not a group member
|
~Q( # user is not a group member
|
||||||
|
|
|
@ -7,7 +7,7 @@ from . import Boost, Favorite, ImportJob, Report, Status, User
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
NotificationType = models.TextChoices(
|
NotificationType = models.TextChoices(
|
||||||
"NotificationType",
|
"NotificationType",
|
||||||
"FAVORITE REPLY MENTION TAG FOLLOW FOLLOW_REQUEST BOOST IMPORT ADD REPORT INVITE ACCEPT JOIN LEAVE REMOVE",
|
"FAVORITE REPLY MENTION TAG FOLLOW FOLLOW_REQUEST BOOST IMPORT ADD REPORT INVITE ACCEPT JOIN LEAVE REMOVE GROUP_PRIVACY GROUP_NAME GROUP_DESCRIPTION",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column is-two-thirds">
|
<div class="column is-two-thirds">
|
||||||
<input type="hidden" name="user" value="{{ request.user.id }}" />
|
<input type="hidden" name="user" value="{{ request.user.id }}" />
|
||||||
<input type="hidden" name="privacy" value="public" />
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="id_name">{% trans "Group Name:" %}</label>
|
<label class="label" for="id_name">{% trans "Group Name:" %}</label>
|
||||||
{{ group_form.name }}
|
{{ group_form.name }}
|
||||||
|
@ -19,7 +18,7 @@
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
{% include 'snippets/privacy_select.html' with current=group.privacy %}
|
{% include 'snippets/privacy_select_no_followers.html' with current=group.privacy %}
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button type="submit" class="button is-primary">{% trans "Save" %}</button>
|
<button type="submit" class="button is-primary">{% trans "Save" %}</button>
|
||||||
|
|
|
@ -27,4 +27,10 @@
|
||||||
{% include 'notifications/items/leave.html' %}
|
{% include 'notifications/items/leave.html' %}
|
||||||
{% elif notification.notification_type == 'REMOVE' %}
|
{% elif notification.notification_type == 'REMOVE' %}
|
||||||
{% include 'notifications/items/remove.html' %}
|
{% include 'notifications/items/remove.html' %}
|
||||||
|
{% elif notification.notification_type == 'GROUP_PRIVACY' %}
|
||||||
|
{% include 'notifications/items/update.html' %}
|
||||||
|
{% elif notification.notification_type == 'GROUP_NAME' %}
|
||||||
|
{% include 'notifications/items/update.html' %}
|
||||||
|
{% elif notification.notification_type == 'GROUP_DESCRIPTION' %}
|
||||||
|
{% include 'notifications/items/update.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -18,6 +18,3 @@ has joined your group "<a href="{{ group_path }}">{{ group_name }}</a>"
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
28
bookwyrm/templates/notifications/items/update.html
Normal file
28
bookwyrm/templates/notifications/items/update.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends 'notifications/items/item_layout.html' %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
{% load utilities %}
|
||||||
|
|
||||||
|
{% block primary_link %}{% spaceless %}
|
||||||
|
{{ notification.related_group.local_path }}
|
||||||
|
{% endspaceless %}{% endblock %}
|
||||||
|
|
||||||
|
{% block icon %}
|
||||||
|
<span class="icon icon-local"></span>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block description %}
|
||||||
|
{% if notification.notification_type == 'GROUP_PRIVACY' %}
|
||||||
|
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
|
||||||
|
has changed the privacy level for <a href="{{ group_path }}">{{ group_name }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% elif notification.notification_type == 'GROUP_NAME' %}
|
||||||
|
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
|
||||||
|
has changed the name of <a href="{{ group_path }}">{{ group_name }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% else %}
|
||||||
|
{% blocktrans with group_name=notification.related_group.name group_path=notification.related_group.local_path %}
|
||||||
|
has changed the description of <a href="{{ group_path }}">{{ group_name }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
21
bookwyrm/templates/snippets/privacy_select_no_followers.html
Normal file
21
bookwyrm/templates/snippets/privacy_select_no_followers.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{% load i18n %}
|
||||||
|
{% load utilities %}
|
||||||
|
<div class="select {{ class }}">
|
||||||
|
{% firstof privacy_uuid 0|uuid as uuid %}
|
||||||
|
{% if not no_label %}
|
||||||
|
<label class="is-sr-only" for="privacy_{{ uuid }}">{% trans "Post privacy" %}</label>
|
||||||
|
{% endif %}
|
||||||
|
{% firstof current user.default_post_privacy "public" as privacy %}
|
||||||
|
<select name="privacy" id="privacy_{{ uuid }}">
|
||||||
|
<option value="public" {% if privacy == 'public' %}selected{% endif %}>
|
||||||
|
{% trans "Public" %}
|
||||||
|
</option>
|
||||||
|
<option value="unlisted" {% if privacy == 'unlisted' %}selected{% endif %}>
|
||||||
|
{% trans "Unlisted" %}
|
||||||
|
</option>
|
||||||
|
<option value="direct" {% if privacy == 'direct' %}selected{% endif %}>
|
||||||
|
{% trans "Private" %}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
|
@ -75,15 +75,6 @@ class Group(TestCase):
|
||||||
)
|
)
|
||||||
models.GroupMember.objects.create(group=self.public_group, user=self.capybara)
|
models.GroupMember.objects.create(group=self.public_group, user=self.capybara)
|
||||||
|
|
||||||
def test_group_members_can_see_followers_only_groups(self, _):
|
|
||||||
"""follower-only group should not be excluded from group listings for group members viewing"""
|
|
||||||
|
|
||||||
rat_groups = models.Group.privacy_filter(self.rat).all()
|
|
||||||
badger_groups = models.Group.privacy_filter(self.badger).all()
|
|
||||||
|
|
||||||
self.assertFalse(self.followers_only_group in rat_groups)
|
|
||||||
self.assertTrue(self.followers_only_group in badger_groups)
|
|
||||||
|
|
||||||
def test_group_members_can_see_private_groups(self, _):
|
def test_group_members_can_see_private_groups(self, _):
|
||||||
"""direct privacy group should not be excluded from group listings for group members viewing"""
|
"""direct privacy group should not be excluded from group listings for group members viewing"""
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,31 @@ class Group(View):
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return redirect("group", user_group.id)
|
return redirect("group", user_group.id)
|
||||||
user_group = form.save()
|
user_group = form.save()
|
||||||
|
|
||||||
|
# let the other members know something about the group changed
|
||||||
|
memberships = models.GroupMember.objects.filter(group=user_group)
|
||||||
|
model = apps.get_model("bookwyrm.Notification", require_ready=True)
|
||||||
|
for field in form.changed_data:
|
||||||
|
notification_type = (
|
||||||
|
"GROUP_PRIVACY"
|
||||||
|
if field == "privacy"
|
||||||
|
else "GROUP_NAME"
|
||||||
|
if field == "name"
|
||||||
|
else "GROUP_DESCRIPTION"
|
||||||
|
if field == "description"
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
if notification_type:
|
||||||
|
for membership in memberships:
|
||||||
|
member = membership.user
|
||||||
|
if member != request.user:
|
||||||
|
model.objects.create(
|
||||||
|
user=member,
|
||||||
|
related_user=request.user,
|
||||||
|
related_group=user_group,
|
||||||
|
notification_type=notification_type,
|
||||||
|
)
|
||||||
|
|
||||||
return redirect("group", user_group.id)
|
return redirect("group", user_group.id)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue