diff --git a/fedireads/activitypub/__init__.py b/fedireads/activitypub/__init__.py index 12fc36c13..22fd6afd0 100644 --- a/fedireads/activitypub/__init__.py +++ b/fedireads/activitypub/__init__.py @@ -1,7 +1,8 @@ ''' bring activitypub functions into the namespace ''' from .actor import get_actor 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 .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 diff --git a/fedireads/activitypub/status.py b/fedireads/activitypub/status.py index 81508daf2..b6ef1af3c 100644 --- a/fedireads/activitypub/status.py +++ b/fedireads/activitypub/status.py @@ -71,3 +71,14 @@ def get_replies(status, 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, + } diff --git a/fedireads/incoming.py b/fedireads/incoming.py index 5cc045c5b..f75fa7ef3 100644 --- a/fedireads/incoming.py +++ b/fedireads/incoming.py @@ -46,6 +46,9 @@ def shared_inbox(request): elif activity['type'] == 'Accept': response = handle_incoming_follow_accept(activity) + elif activity['type'] == 'Like': + response = handle_incoming_favorite(activity) + # TODO: Add, Undo, Remove, etc return response @@ -257,6 +260,20 @@ def handle_incoming_create(activity): 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): ''' someone is accepting a follow request ''' # our local user diff --git a/fedireads/migrations/0002_auto_20200219_0725.py b/fedireads/migrations/0002_auto_20200219_0804.py similarity index 92% rename from fedireads/migrations/0002_auto_20200219_0725.py rename to fedireads/migrations/0002_auto_20200219_0804.py index 93076b0f7..7288eff79 100644 --- a/fedireads/migrations/0002_auto_20200219_0725.py +++ b/fedireads/migrations/0002_auto_20200219_0804.py @@ -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.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')), ('content', models.TextField(blank=True, null=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')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ], diff --git a/fedireads/models/__init__.py b/fedireads/models/__init__.py index 0d619ef5c..ace5e08ba 100644 --- a/fedireads/models/__init__.py +++ b/fedireads/models/__init__.py @@ -1,5 +1,5 @@ ''' bring all the models into the app namespace ''' from .book import Shelf, ShelfBook, Book, Author from .user import User, UserRelationship, FederatedServer -from .activity import Status, Review +from .activity import Status, Review, Favorite diff --git a/fedireads/models/activity.py b/fedireads/models/activity.py index d8245472f..165151e5e 100644 --- a/fedireads/models/activity.py +++ b/fedireads/models/activity.py @@ -50,4 +50,3 @@ class Favorite(FedireadsModel): ''' fav'ing a post ''' user = models.ForeignKey('User', on_delete=models.PROTECT) status = models.ForeignKey('Status', on_delete=models.PROTECT) - relationship_id = models.CharField(max_length=100) diff --git a/fedireads/outgoing.py b/fedireads/outgoing.py index 38797f7a9..5b158d779 100644 --- a/fedireads/outgoing.py +++ b/fedireads/outgoing.py @@ -160,7 +160,7 @@ def handle_review(user, book, name, content, rating): 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 comment = create_status(user, content, reply_parent=review) comment_activity = activitypub.get_status(comment) @@ -169,3 +169,14 @@ def handle_comment(user, review, content): recipients = get_recipients(user, 'public') 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) + diff --git a/fedireads/templates/feed.html b/fedireads/templates/feed.html index f18e107a8..5350b54d2 100644 --- a/fedireads/templates/feed.html +++ b/fedireads/templates/feed.html @@ -67,7 +67,10 @@

{{ activity.content | safe }}

- +
+ {% csrf_token %} + +
{% csrf_token %} diff --git a/fedireads/urls.py b/fedireads/urls.py index b0ff24a55..506cb014c 100644 --- a/fedireads/urls.py +++ b/fedireads/urls.py @@ -51,6 +51,7 @@ urlpatterns = [ # internal action endpoints re_path(r'^review/?$', views.review), re_path(r'^comment/?$', views.comment), + re_path(r'^favorite/(?P\d+)/?$', views.favorite), re_path( r'^shelve/(?P\w+)/(?P[\w-]+)/(?P\d+)/?$', views.shelve diff --git a/fedireads/views.py b/fedireads/views.py index d4fe215fa..fed94f259 100644 --- a/fedireads/views.py +++ b/fedireads/views.py @@ -252,6 +252,7 @@ def review(request): return redirect('/book/%s' % book_identifier) +@login_required def comment(request): ''' respond to a book review ''' form = forms.CommentForm(request.POST) @@ -264,6 +265,14 @@ def comment(request): 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 def follow(request): ''' follow another user, here or abroad '''