forked from mirrors/bookwyrm
Unfavorite statuses
This commit is contained in:
parent
e0bd8200ad
commit
7455467c40
10 changed files with 143 additions and 19 deletions
|
@ -5,4 +5,4 @@ from .collection import get_outbox, get_outbox_page, get_add, get_remove, \
|
|||
from .create import get_create
|
||||
from .follow import get_follow_request, get_unfollow, get_accept, get_reject
|
||||
from .status import get_review, get_review_article, get_status, get_replies, \
|
||||
get_favorite, get_add_tag, get_remove_tag, get_replies_page
|
||||
get_favorite, get_unfavorite, get_add_tag, get_remove_tag, get_replies_page
|
||||
|
|
|
@ -77,6 +77,7 @@ def get_replies(status, replies):
|
|||
|
||||
|
||||
def get_replies_page(status, replies):
|
||||
''' actual reply list content '''
|
||||
id_slug = status.absolute_id + '/replies?page=true&only_other_accounts=true'
|
||||
items = []
|
||||
for reply in replies:
|
||||
|
@ -105,6 +106,22 @@ def get_favorite(favorite):
|
|||
}
|
||||
|
||||
|
||||
def get_unfavorite(favorite):
|
||||
''' like a post '''
|
||||
return {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': '%s/undo' % favorite.absolute_id,
|
||||
'type': 'Undo',
|
||||
'actor': favorite.user.actor,
|
||||
'object': {
|
||||
'id': favorite.absolute_id,
|
||||
'type': 'Like',
|
||||
'actor': favorite.user.actor,
|
||||
'object': favorite.status.absolute_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def get_add_tag(tag):
|
||||
''' add activity for tagging a book '''
|
||||
uuid = uuid4()
|
||||
|
|
|
@ -12,8 +12,7 @@ import requests
|
|||
|
||||
from fedireads import models
|
||||
from fedireads import outgoing
|
||||
from fedireads.status import create_review_from_activity, \
|
||||
create_status_from_activity, create_tag, create_notification
|
||||
from fedireads import status as status_builder
|
||||
from fedireads.remote_user import get_or_create_remote_user
|
||||
|
||||
|
||||
|
@ -39,7 +38,14 @@ def shared_inbox(request):
|
|||
response = handle_incoming_follow(activity)
|
||||
|
||||
elif activity['type'] == 'Undo':
|
||||
response = handle_incoming_undo(activity)
|
||||
if not 'object' in activity:
|
||||
return HttpResponseNotFound()
|
||||
if activity['object']['type'] == 'Follow':
|
||||
response = handle_incoming_undo(activity)
|
||||
elif activity['object']['type'] == 'Like':
|
||||
response = handle_incoming_unfavorite(activity)
|
||||
else:
|
||||
return HttpResponseNotFound()
|
||||
|
||||
elif activity['type'] == 'Create':
|
||||
response = handle_incoming_create(activity)
|
||||
|
@ -141,10 +147,18 @@ def handle_incoming_follow(activity):
|
|||
return HttpResponse()
|
||||
|
||||
if not to_follow.manually_approves_followers:
|
||||
create_notification(to_follow, 'FOLLOW', related_user=user)
|
||||
status_builder.create_notification(
|
||||
to_follow,
|
||||
'FOLLOW',
|
||||
related_user=user
|
||||
)
|
||||
outgoing.handle_outgoing_accept(user, to_follow, request)
|
||||
else:
|
||||
create_notification(to_follow, 'FOLLOW_REQUEST', related_user=user)
|
||||
status_builder.create_notification(
|
||||
to_follow,
|
||||
'FOLLOW_REQUEST',
|
||||
related_user=user
|
||||
)
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
|
@ -216,14 +230,20 @@ def handle_incoming_create(activity):
|
|||
models.Review.objects.get(id=review_id)
|
||||
else:
|
||||
try:
|
||||
create_review_from_activity(user, activity['object'])
|
||||
status_builder.create_review_from_activity(
|
||||
user,
|
||||
activity['object']
|
||||
)
|
||||
except ValueError:
|
||||
return HttpResponseBadRequest()
|
||||
elif not user.local:
|
||||
try:
|
||||
status = create_status_from_activity(user, activity['object'])
|
||||
status = status_builder.create_status_from_activity(
|
||||
user,
|
||||
activity['object']
|
||||
)
|
||||
if status and status.reply_parent:
|
||||
create_notification(
|
||||
status_builder.create_notification(
|
||||
status.reply_parent.user,
|
||||
'REPLY',
|
||||
related_user=status.user,
|
||||
|
@ -245,9 +265,9 @@ def handle_incoming_favorite(activity):
|
|||
return HttpResponseNotFound()
|
||||
|
||||
if not liker.local:
|
||||
status.favorites.add(liker)
|
||||
status_builder.create_favorite_from_activity(liker, activity)
|
||||
|
||||
create_notification(
|
||||
status_builder.create_notification(
|
||||
status.user,
|
||||
'FAVORITE',
|
||||
related_user=liker,
|
||||
|
@ -256,13 +276,26 @@ def handle_incoming_favorite(activity):
|
|||
return HttpResponse()
|
||||
|
||||
|
||||
def handle_incoming_unfavorite(activity):
|
||||
''' approval of your good good post '''
|
||||
try:
|
||||
favorite_id = activity['object']['id']
|
||||
fav = status_builder.get_favorite(favorite_id)
|
||||
except models.Favorite.DoesNotExist:
|
||||
return HttpResponseNotFound()
|
||||
|
||||
fav.delete()
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def handle_incoming_add(activity):
|
||||
''' someone is tagging or shelving a book '''
|
||||
if activity['object']['type'] == 'Tag':
|
||||
user = get_or_create_remote_user(activity['actor'])
|
||||
if not user.local:
|
||||
book = activity['target']['id'].split('/')[-1]
|
||||
create_tag(user, book, activity['object']['name'])
|
||||
status_builder.create_tag(user, book, activity['object']['name'])
|
||||
return HttpResponse()
|
||||
return HttpResponse()
|
||||
return HttpResponseNotFound()
|
||||
|
||||
|
|
18
fedireads/migrations/0018_favorite_remote_id.py
Normal file
18
fedireads/migrations/0018_favorite_remote_id.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.3 on 2020-03-21 21:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fedireads', '0017_auto_20200314_2152'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='favorite',
|
||||
name='remote_id',
|
||||
field=models.CharField(max_length=255, null=True, unique=True),
|
||||
),
|
||||
]
|
|
@ -65,6 +65,14 @@ class Favorite(FedireadsModel):
|
|||
''' fav'ing a post '''
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
status = models.ForeignKey('Status', on_delete=models.PROTECT)
|
||||
remote_id = models.CharField(max_length=255, unique=True, null=True)
|
||||
|
||||
@property
|
||||
def absolute_id(self):
|
||||
''' constructs the absolute reference to any db object '''
|
||||
if self.remote_id:
|
||||
return self.remote_id
|
||||
return super().absolute_id
|
||||
|
||||
class Meta:
|
||||
unique_together = ('user', 'status')
|
||||
|
|
|
@ -228,3 +228,19 @@ def handle_outgoing_favorite(user, status):
|
|||
recipients = get_recipients(user, 'direct', [status.user])
|
||||
broadcast(user, fav_activity, recipients)
|
||||
|
||||
|
||||
def handle_outgoing_unfavorite(user, status):
|
||||
''' a user likes a status '''
|
||||
try:
|
||||
favorite = models.Favorite.objects.get(
|
||||
status=status,
|
||||
user=user
|
||||
)
|
||||
except models.Favorite.DoesNotExist:
|
||||
# can't find that status, idk
|
||||
return
|
||||
|
||||
fav_activity = activitypub.get_unfavorite(favorite)
|
||||
recipients = get_recipients(user, 'direct', [status.user])
|
||||
broadcast(user, fav_activity, recipients)
|
||||
|
||||
|
|
|
@ -57,20 +57,44 @@ def create_status_from_activity(author, activity):
|
|||
return status
|
||||
|
||||
|
||||
def create_favorite_from_activity(user, activity):
|
||||
status = get_status(activity['object'])
|
||||
remote_id = activity['id']
|
||||
try:
|
||||
return models.Favorite.objects.create(
|
||||
status=status,
|
||||
user=user,
|
||||
remote_id=remote_id,
|
||||
)
|
||||
except IntegrityError:
|
||||
return models.Favorite.objects.get(status=status, user=user)
|
||||
|
||||
|
||||
def get_status(absolute_id):
|
||||
''' find a status in the database '''
|
||||
return get_by_absolute_id(absolute_id, models.Status)
|
||||
|
||||
|
||||
def get_favorite(absolute_id):
|
||||
''' find a status in the database '''
|
||||
return get_by_absolute_id(absolute_id, models.Favorite)
|
||||
|
||||
|
||||
def get_by_absolute_id(absolute_id, model):
|
||||
# check if it's a remote status
|
||||
try:
|
||||
return models.Status.objects.get(remote_id=absolute_id)
|
||||
except models.Status.DoesNotExist:
|
||||
return model.objects.get(remote_id=absolute_id)
|
||||
except model.DoesNotExist:
|
||||
pass
|
||||
|
||||
# try finding a local status with that id
|
||||
local_id = absolute_id.split('/')[-1]
|
||||
try:
|
||||
possible_match = models.Status.objects.select_subclasses() \
|
||||
.get(id=local_id)
|
||||
except models.Status.DoesNotExist:
|
||||
if hasattr(model.objects, 'select_subclasses'):
|
||||
possible_match = model.objects.select_subclasses().get(id=local_id)
|
||||
else:
|
||||
possible_match = model.objects.get(id=local_id)
|
||||
except model.DoesNotExist:
|
||||
return None
|
||||
|
||||
# make sure it's not actually a remote status with an id that
|
||||
|
@ -80,7 +104,6 @@ def get_status(absolute_id):
|
|||
return None
|
||||
|
||||
|
||||
|
||||
def create_status(user, content, reply_parent=None, mention_books=None,
|
||||
remote_id=None):
|
||||
''' a status update '''
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
</span>
|
||||
</button>
|
||||
</form>
|
||||
<form name="favorite" action="/favorite/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="fav-{{ status.id }} active {% if not request.user|liked:status %}hidden{% endif %}" data-id="fav-{{ status.id }}">
|
||||
<form name="unfavorite" action="/unfavorite/{{ activity.id }}" method="POST" onsubmit="return interact(event)" class="fav-{{ status.id }} active {% if not request.user|liked:status %}hidden{% endif %}" data-id="fav-{{ status.id }}">
|
||||
{% csrf_token %}
|
||||
<button type="submit">
|
||||
<span class="icon icon-heart">
|
||||
|
|
|
@ -69,6 +69,7 @@ urlpatterns = [
|
|||
re_path(r'^untag/?$', actions.untag),
|
||||
re_path(r'^comment/?$', actions.comment),
|
||||
re_path(r'^favorite/(?P<status_id>\d+)/?$', actions.favorite),
|
||||
re_path(r'^unfavorite/(?P<status_id>\d+)/?$', actions.unfavorite),
|
||||
re_path(r'^shelve/?$', actions.shelve),
|
||||
re_path(r'^follow/?$', actions.follow),
|
||||
re_path(r'^unfollow/?$', actions.unfollow),
|
||||
|
|
|
@ -159,6 +159,14 @@ def favorite(request, status_id):
|
|||
return redirect(request.headers.get('Referer', '/'))
|
||||
|
||||
|
||||
@login_required
|
||||
def unfavorite(request, status_id):
|
||||
''' like a status '''
|
||||
status = models.Status.objects.get(id=status_id)
|
||||
outgoing.handle_outgoing_unfavorite(request.user, status)
|
||||
return redirect(request.headers.get('Referer', '/'))
|
||||
|
||||
|
||||
@login_required
|
||||
def follow(request):
|
||||
''' follow another user, here or abroad '''
|
||||
|
|
Loading…
Reference in a new issue