Adds favorit handling

This commit is contained in:
Mouse Reeve 2020-02-19 00:13:06 -08:00
parent 27b9326dd9
commit a664ad3328
10 changed files with 59 additions and 8 deletions

View file

@ -1,7 +1,8 @@
''' bring activitypub functions into the namespace ''' ''' bring activitypub functions into the namespace '''
from .actor import get_actor from .actor import get_actor
from .collection import get_outbox, get_outbox_page, get_add, get_remove, \ from .collection import get_outbox, get_outbox_page, get_add, get_remove, \
get_following, get_followers get_following, get_followers
from .create import get_create from .create import get_create
from .follow import get_follow_request, get_unfollow, get_accept from .follow import get_follow_request, get_unfollow, get_accept
from .status import get_review, get_review_article, get_status, get_replies from .status import get_review, get_review_article, get_status, get_replies, \
get_favorite

View file

@ -71,3 +71,14 @@ def get_replies(status, replies):
'items': [get_status(r) for r in replies] 'items': [get_status(r) for r in replies]
} }
} }
def get_favorite(favorite):
''' like a post '''
return {
"@context": "https://www.w3.org/ns/activitystreams",
"id": favorite.absolute_id,
"type": "Like",
"actor": favorite.user.actor,
"object": favorite.status.absolute_id,
}

View file

@ -46,6 +46,9 @@ def shared_inbox(request):
elif activity['type'] == 'Accept': elif activity['type'] == 'Accept':
response = handle_incoming_follow_accept(activity) response = handle_incoming_follow_accept(activity)
elif activity['type'] == 'Like':
response = handle_incoming_favorite(activity)
# TODO: Add, Undo, Remove, etc # TODO: Add, Undo, Remove, etc
return response return response
@ -257,6 +260,20 @@ def handle_incoming_create(activity):
return response return response
def handle_incoming_favorite(activity):
''' approval of your good good post '''
try:
status_id = activity['object'].split('/')[-1]
status = models.Status.objects.get(id=status_id)
liker = get_or_create_remote_user(activity['actor'])
except (models.Status.DoesNotExist, models.User.DoesNotExist):
return HttpResponseNotFound()
if not liker.local:
status.favorites.add(liker)
return HttpResponse()
def handle_incoming_accept(activity): def handle_incoming_accept(activity):
''' someone is accepting a follow request ''' ''' someone is accepting a follow request '''
# our local user # our local user

View file

@ -1,4 +1,4 @@
# Generated by Django 3.0.3 on 2020-02-19 07:25 # Generated by Django 3.0.3 on 2020-02-19 08:04
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -18,7 +18,6 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField(blank=True, null=True)), ('content', models.TextField(blank=True, null=True)),
('created_date', models.DateTimeField(auto_now_add=True)), ('created_date', models.DateTimeField(auto_now_add=True)),
('relationship_id', models.CharField(max_length=100)),
('status', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Status')), ('status', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Status')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
], ],

View file

@ -1,5 +1,5 @@
''' bring all the models into the app namespace ''' ''' bring all the models into the app namespace '''
from .book import Shelf, ShelfBook, Book, Author from .book import Shelf, ShelfBook, Book, Author
from .user import User, UserRelationship, FederatedServer from .user import User, UserRelationship, FederatedServer
from .activity import Status, Review from .activity import Status, Review, Favorite

View file

@ -50,4 +50,3 @@ class Favorite(FedireadsModel):
''' fav'ing a post ''' ''' fav'ing a post '''
user = models.ForeignKey('User', on_delete=models.PROTECT) user = models.ForeignKey('User', on_delete=models.PROTECT)
status = models.ForeignKey('Status', on_delete=models.PROTECT) status = models.ForeignKey('Status', on_delete=models.PROTECT)
relationship_id = models.CharField(max_length=100)

View file

@ -160,7 +160,7 @@ def handle_review(user, book, name, content, rating):
def handle_comment(user, review, content): def handle_comment(user, review, content):
''' post a review ''' ''' respond to a review or status '''
# validated and saves the comment in the database so it has an id # validated and saves the comment in the database so it has an id
comment = create_status(user, content, reply_parent=review) comment = create_status(user, content, reply_parent=review)
comment_activity = activitypub.get_status(comment) comment_activity = activitypub.get_status(comment)
@ -169,3 +169,14 @@ def handle_comment(user, review, content):
recipients = get_recipients(user, 'public') recipients = get_recipients(user, 'public')
broadcast(user, create_activity, recipients) broadcast(user, create_activity, recipients)
def handle_outgoing_favorite(user, status):
''' a user likes a status '''
favorite = models.Favorite.objects.create(
status=status,
user=user
)
fav_activity = activitypub.get_favorite(favorite)
recipients = get_recipients(user, 'direct', [status.user])
broadcast(user, fav_activity, recipients)

View file

@ -67,7 +67,10 @@
<p>{{ activity.content | safe }}</p> <p>{{ activity.content | safe }}</p>
</div> </div>
<div class="interaction"> <div class="interaction">
<button>⭐️ Like</button> <form name="favorite" action="/favorite/{{ activity.id }}" method="post">
{% csrf_token %}
<button>⭐️ Like</button>
</form>
<form name="comment" action="/comment" method="post"> <form name="comment" action="/comment" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="review" value="{{ activity.id }}"></input> <input type="hidden" name="review" value="{{ activity.id }}"></input>

View file

@ -51,6 +51,7 @@ urlpatterns = [
# internal action endpoints # internal action endpoints
re_path(r'^review/?$', views.review), re_path(r'^review/?$', views.review),
re_path(r'^comment/?$', views.comment), re_path(r'^comment/?$', views.comment),
re_path(r'^favorite/(?P<status_id>\d+)/?$', views.favorite),
re_path( re_path(
r'^shelve/(?P<username>\w+)/(?P<shelf_id>[\w-]+)/(?P<book_id>\d+)/?$', r'^shelve/(?P<username>\w+)/(?P<shelf_id>[\w-]+)/(?P<book_id>\d+)/?$',
views.shelve views.shelve

View file

@ -252,6 +252,7 @@ def review(request):
return redirect('/book/%s' % book_identifier) return redirect('/book/%s' % book_identifier)
@login_required
def comment(request): def comment(request):
''' respond to a book review ''' ''' respond to a book review '''
form = forms.CommentForm(request.POST) form = forms.CommentForm(request.POST)
@ -264,6 +265,14 @@ def comment(request):
return redirect('/') return redirect('/')
@login_required
def favorite(request, status_id):
''' like a status '''
status = models.Status.objects.get(id=status_id)
outgoing.handle_outgoing_favorite(request.user, status)
return redirect(request.headers.get('Referer', '/'))
@login_required @login_required
def follow(request): def follow(request):
''' follow another user, here or abroad ''' ''' follow another user, here or abroad '''