Delete statuses

This commit is contained in:
Mouse Reeve 2020-10-08 12:32:45 -07:00
parent 1705a550d4
commit 704e1092c4
8 changed files with 71 additions and 2 deletions

View file

@ -4,6 +4,7 @@ import sys
from .base_activity import ActivityEncoder, Image, PublicKey, Signature
from .note import Note, GeneratedNote, Article, Comment, Review, Quotation
from .note import Tombstone
from .interaction import Boost, Like
from .ordered_collection import OrderedCollection, OrderedCollectionPage
from .person import Person

View file

@ -4,6 +4,14 @@ from typing import Dict, List
from .base_activity import ActivityObject, Image
@dataclass(init=False)
class Tombstone(ActivityObject):
url: str
published: str
deleted: str
type: str = 'Tombstone'
@dataclass(init=False)
class Note(ActivityObject):
''' Note activity '''

View file

@ -22,6 +22,8 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
sensitive = models.BooleanField(default=False)
# the created date can't be this, because of receiving federated posts
published_date = models.DateTimeField(default=timezone.now)
deleted = models.BooleanField(default=False)
deleted_date = models.DateTimeField(default=timezone.now)
favorites = models.ManyToManyField(
'User',
symmetrical=False,
@ -104,6 +106,18 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
**kwargs
)
def to_activity(self, **kwargs):
''' return tombstone if the status is deleted '''
if self.deleted:
return activitypub.Tombstone(
id=self.remote_id,
url=self.remote_id,
deleted=http_date(self.deleted_date.timestamp()),
published=http_date(self.deleted_date.timestamp()),
).serialize()
return ActivitypubMixin.to_activity(self, **kwargs)
class GeneratedStatus(Status):
''' these are app-generated messages about user activity '''
@property
@ -112,7 +126,7 @@ class GeneratedStatus(Status):
message = self.content
books = ', '.join(
'<a href="%s">"%s"</a>' % (self.book.local_id, self.book.title) \
for book in self.mention_books
for book in self.mention_books.all()
)
return '%s %s' % (message, books)

View file

@ -13,6 +13,7 @@ from bookwyrm.status import create_review, create_status
from bookwyrm.status import create_quotation, create_comment
from bookwyrm.status import create_tag, create_notification, create_rating
from bookwyrm.status import create_generated_note
from bookwyrm.status import delete_status
from bookwyrm.remote_user import get_or_create_remote_user
@ -197,6 +198,12 @@ def handle_import_books(user, items):
return None
def handle_delete_status(user, status):
''' delete a status and broadcast deletion to other servers '''
delete_status(status)
broadcast(user, status.to_activity())
def handle_rate(user, book, rating):
''' a review that's just a rating '''
builder = create_rating

View file

@ -6,6 +6,11 @@ from bookwyrm.books_manager import get_or_create_book
from bookwyrm.sanitize_html import InputHtmlParser
def delete_status(status):
''' replace the status with a tombstone '''
status.deleted = True
status.save()
def create_rating(user, book, rating):
''' a review that's just a rating '''
if not rating or rating < 1 or rating > 5:

View file

@ -25,6 +25,17 @@
<span class="icon icon-public">
<span class="is-sr-only">Public post</span>
</span>
{% if status.user == request.user %}
<form name="delete-{{status.id}}" action="/delete-status" method="post">
{% csrf_token %}
<input type="hidden" name="status" value="{{ status.id }}">
<button type="submit">
<span class="icon icon-cancel">
<span class="is-sr-only">Delete post</span>
</span>
</button>
</form>
{% endif %}
<a href="{{ status.remote_id }}">{{ status.published_date | naturaltime }}</a>
</div>
</footer>

View file

@ -11,7 +11,7 @@ localname_regex = r'(?P<username>[\w\-_]+)'
user_path = r'^user/%s' % username_regex
local_user_path = r'^user/%s' % localname_regex
status_types = ['status', 'review', 'comment', 'quotation', 'boost']
status_types = ['status', 'review', 'comment', 'quotation', 'boost', 'generatedstatus']
status_path = r'%s/(%s)/(?P<status_id>\d+)' % \
(local_user_path, '|'.join(status_types))
@ -107,6 +107,8 @@ urlpatterns = [
re_path(r'^unfavorite/(?P<status_id>\d+)/?$', actions.unfavorite),
re_path(r'^boost/(?P<status_id>\d+)/?$', actions.boost),
re_path(r'^delete-status/?$', actions.delete_status),
re_path(r'^shelve/?$', actions.shelve),
re_path(r'^follow/?$', actions.follow),

View file

@ -418,6 +418,27 @@ def boost(request, status_id):
outgoing.handle_boost(request.user, status)
return redirect(request.headers.get('Referer', '/'))
@login_required
def delete_status(request):
''' delete and tombstone a status '''
status_id = request.POST.get('status')
if not status_id:
return HttpResponseBadRequest()
try:
status = models.Status.objects.get(id=status_id)
except models.Status.DoesNotExist:
return HttpResponseBadRequest()
# don't let people delete other people's statuses
if status.user != request.user:
return HttpResponseBadRequest()
# perform deletion
outgoing.handle_delete_status(request.user, status)
return redirect(request.headers.get('Referer', '/'))
@login_required
def follow(request):
''' follow another user, here or abroad '''