Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2021-03-25 11:14:37 -07:00
commit 6f37a43d33
9 changed files with 80 additions and 12 deletions

View file

@ -23,7 +23,8 @@ POSTGRES_USER=fedireads
POSTGRES_DB=fedireads
POSTGRES_HOST=db
# Redis as activitystreams manager
# Redis activity stream manager
MAX_STREAM_LENGTH=200
REDIS_ACTIVITY_HOST=redis_activity
REDIS_ACTIVITY_PORT=6379
REDIS_ACTIVITY_PASSWORD=redispassword345

View file

@ -248,7 +248,9 @@ def get_model_from_type(activity_type):
return model[0]
def resolve_remote_id(remote_id, model=None, refresh=False, save=True):
def resolve_remote_id(
remote_id, model=None, refresh=False, save=True, get_activity=False
):
""" take a remote_id and return an instance, creating if necessary """
if model: # a bonus check we can do if we already know the model
result = model.find_existing_by_remote_id(remote_id)
@ -272,5 +274,8 @@ def resolve_remote_id(remote_id, model=None, refresh=False, save=True):
return result if not get_activity else result.to_activity_dataclass()
item = model.activity_serializer(**data)
if get_activity:
return item
# if we're refreshing, "result" will be set and we'll update it
return item.to_model(model=model, instance=result, save=save)

View file

@ -0,0 +1,17 @@
# Generated by Django 3.1.6 on 2021-03-24 15:36
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0057_user_discoverable"),
]
operations = [
migrations.AlterModelOptions(
name="status",
options={"ordering": ("-published_date",)},
),
]

View file

@ -58,6 +58,11 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
serialize_reverse_fields = [("attachments", "attachment", "id")]
deserialize_reverse_fields = [("attachments", "attachment")]
class Meta:
""" default sorting """
ordering = ("-published_date",)
def save(self, *args, **kwargs):
""" save and notify """
super().save(*args, **kwargs)
@ -118,12 +123,14 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
""" keep notes if they are replies to existing statuses """
if activity.type == "Announce":
try:
boosted = activitypub.resolve_remote_id(activity.object, save=False)
boosted = activitypub.resolve_remote_id(
activity.object, get_activity=True
)
except activitypub.ActivitySerializerError:
# if we can't load the status, definitely ignore it
return True
# keep the boost if we would keep the status
return cls.ignore_activity(boosted.to_activity_dataclass())
return cls.ignore_activity(boosted)
# keep if it if it's a custom type
if activity.type != "Note":
@ -344,7 +351,7 @@ class Boost(ActivityMixin, Status):
def save(self, *args, **kwargs):
""" save and notify """
super().save(*args, **kwargs)
if not self.boosted_status.user.local:
if not self.boosted_status.user.local or self.boosted_status.user == self.user:
return
notification_model = apps.get_model("bookwyrm.Notification", require_ready=True)

View file

@ -97,7 +97,7 @@ REDIS_ACTIVITY_HOST = env("REDIS_ACTIVITY_HOST", "localhost")
REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379)
REDIS_ACTIVITY_PASSWORD = env("REDIS_ACTIVITY_PASSWORD")
MAX_STREAM_LENGTH = env("MAX_STREAM_LENGTH", 200)
MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200))
STREAMS = ["home", "local", "federated"]
# Database

View file

@ -34,6 +34,29 @@ html {
.hidden {
display: none !important;
}
.hidden.transition-y, .hidden.transition-x {
display: block !important;
visibility: hidden !important;
height: 0;
width: 0;
margin: 0;
padding: 0;
}
.transition-y {
transition-property: height, margin-top, margin-bottom, padding-top, padding-bottom;
transition-duration: 0.5s;
transition-timing-function: ease;
}
.transition-x {
transition-property: width, margin-left, margin-right, padding-left, padding-right;
transition-duration: 0.5s;
transition-timing-function: ease;
}
@media (prefers-reduced-motion: reduce) {
.transition-x, .transition-y {
transition-duration: 0.001ms !important;
}
}
/* --- STARS --- */
.rate-stars button.icon {

View file

@ -28,7 +28,7 @@
{# announcements and system messages #}
{% if not activities.number > 1 %}
<a href="{{ request.path }}" class="hidden notification is-primary is-block" data-poll-wrapper>
<a href="{{ request.path }}" class="transition-y hidden notification is-primary is-block" data-poll-wrapper>
{% blocktrans %}load <span data-poll="stream/{{ tab }}">0</span> unread status(es){% endblocktrans %}
</a>

View file

@ -139,7 +139,7 @@
<span class="is-sr-only">{% trans "Notifications" %}</span>
</span>
</span>
<span class="{% if not request.user|notification_count %}hidden {% endif %}tag is-danger is-medium" data-poll-wrapper>
<span class="{% if not request.user|notification_count %}hidden {% endif %}tag is-danger is-medium transition-x" data-poll-wrapper>
<span data-poll="notifications">{{ request.user | notification_count }}</span>
</span>
</a>

View file

@ -95,6 +95,23 @@ class InteractionViews(TestCase):
self.assertEqual(notification.related_user, self.remote_user)
self.assertEqual(notification.related_status, status)
def test_handle_self_boost(self, _):
""" boost your own status """
view = views.Boost.as_view()
request = self.factory.post("")
request.user = self.local_user
with patch("bookwyrm.activitystreams.ActivityStream.add_status"):
status = models.Status.objects.create(user=self.local_user, content="hi")
view(request, status.id)
boost = models.Boost.objects.get()
self.assertEqual(boost.boosted_status, status)
self.assertEqual(boost.user, self.local_user)
self.assertEqual(boost.privacy, "public")
self.assertFalse(models.Notification.objects.exists())
def test_handle_boost_unlisted(self, _):
""" boost a status """
view = views.Boost.as_view()
@ -135,23 +152,21 @@ class InteractionViews(TestCase):
view(request, status.id)
self.assertEqual(models.Boost.objects.count(), 1)
def test_handle_unboost(self, broadcast_mock):
def test_handle_unboost(self, _):
""" undo a boost """
view = views.Unboost.as_view()
request = self.factory.post("")
request.user = self.local_user
request.user = self.remote_user
with patch("bookwyrm.activitystreams.ActivityStream.add_status"):
status = models.Status.objects.create(user=self.local_user, content="hi")
views.Boost.as_view()(request, status.id)
self.assertEqual(models.Boost.objects.count(), 1)
self.assertEqual(models.Notification.objects.count(), 1)
broadcast_mock.call_count = 0
with patch(
"bookwyrm.activitystreams.ActivityStream.remove_status"
) as redis_mock:
view(request, status.id)
self.assertEqual(broadcast_mock.call_count, 1)
self.assertTrue(redis_mock.called)
self.assertEqual(models.Boost.objects.count(), 0)
self.assertEqual(models.Notification.objects.count(), 0)