forked from mirrors/bookwyrm
Accept follow requests
This commit is contained in:
parent
6b85d8838f
commit
19f6ebb9a7
6 changed files with 70 additions and 17 deletions
|
@ -1,4 +1,7 @@
|
|||
''' generates activitypub formatted objects '''
|
||||
from uuid import uuid4
|
||||
from fedireads.settings import DOMAIN
|
||||
|
||||
|
||||
def shelve_action(user, book, shelf):
|
||||
''' a user puts a book on a shelf.
|
||||
|
@ -27,3 +30,15 @@ def shelve_action(user, book, shelf):
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
def accept_follow(activity, user):
|
||||
''' say YES! to a user '''
|
||||
uuid = uuid4()
|
||||
return {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': 'https://%s/%s' % (DOMAIN, uuid),
|
||||
'type': 'Accept',
|
||||
'actor': user.actor['id'],
|
||||
'object': activity,
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from fedireads.settings import DOMAIN
|
||||
from fedireads import models
|
||||
from fedireads import openlibrary
|
||||
import fedireads.activitypub_templates as templates
|
||||
import json
|
||||
import requests
|
||||
|
||||
def webfinger(request):
|
||||
|
@ -52,13 +54,18 @@ def inbox(request, username):
|
|||
# return a collection of something?
|
||||
pass
|
||||
|
||||
activity = request.POST.dict()
|
||||
activity = json.loads(request.body)
|
||||
if activity['type'] == 'Add':
|
||||
handle_add(activity)
|
||||
|
||||
if activity['type'] == 'Follow':
|
||||
response = handle_follow(activity)
|
||||
return JsonResponse(response)
|
||||
|
||||
return HttpResponse()
|
||||
|
||||
def handle_add(activity):
|
||||
''' adding a book to a shelf '''
|
||||
book_id = activity['object']['url']
|
||||
book = openlibrary.get_or_create_book(book_id)
|
||||
user_ap_id = activity['actor'].replace('https//:', '')
|
||||
|
@ -70,6 +77,31 @@ def handle_add(activity):
|
|||
added_by=user,
|
||||
).save()
|
||||
|
||||
|
||||
def handle_follow(activity):
|
||||
'''
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://friend.camp/768222ce-a1c7-479c-a544-c93b8b67fb54",
|
||||
"type": "Follow",
|
||||
"actor": "https://friend.camp/users/tripofmice",
|
||||
"object": "https://ff2cb3e9.ngrok.io/api/u/mouse"
|
||||
}
|
||||
'''
|
||||
# figure out who they want to follow
|
||||
following = activity['object'].replace('https://%s/api/u/' % DOMAIN, '')
|
||||
following = models.User.objects.get(username=following)
|
||||
# figure out who they are
|
||||
ap_id = activity['actor']
|
||||
try:
|
||||
user = models.User.objects.get(activitypub_id=ap_id)
|
||||
except models.User.DoesNotExist:
|
||||
user = models.User(activitypub_id=ap_id, local=False).save()
|
||||
following.followers.add(user)
|
||||
# accept the request
|
||||
return templates.accept_follow(activity, following)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def outbox(request, username):
|
||||
user = models.User.objects.get(username=username)
|
||||
|
@ -106,19 +138,16 @@ date: %s''' % (inbox_fragment, DOMAIN, now)
|
|||
signature += 'signature="%s"' % b64encode(signed_message)
|
||||
response = requests.post(
|
||||
recipient,
|
||||
data=action,
|
||||
body=action,
|
||||
headers={
|
||||
'Date': now,
|
||||
'Signature': signature,
|
||||
'Host': DOMAIN,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
if not response.ok:
|
||||
return response.raise_for_status()
|
||||
|
||||
def handle_follow(data):
|
||||
pass
|
||||
|
||||
def get_or_create_remote_user(activity):
|
||||
pass
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 2.0.13 on 2020-01-27 01:47
|
||||
# Generated by Django 2.0.13 on 2020-01-27 02:41
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.auth.models
|
||||
|
@ -34,9 +34,9 @@ class Migration(migrations.Migration):
|
|||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('activitypub_id', models.CharField(max_length=255)),
|
||||
('private_key', models.TextField(blank=True, null=True)),
|
||||
('public_key', models.TextField()),
|
||||
('public_key', models.TextField(blank=True, null=True)),
|
||||
('api_key', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('actor', django.contrib.postgres.fields.jsonb.JSONField()),
|
||||
('actor', django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True)),
|
||||
('local', models.BooleanField(default=True)),
|
||||
('created_date', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_date', models.DateTimeField(auto_now=True)),
|
||||
|
|
|
@ -12,9 +12,9 @@ class User(AbstractUser):
|
|||
''' a user who wants to read books '''
|
||||
activitypub_id = models.CharField(max_length=255)
|
||||
private_key = models.TextField(blank=True, null=True)
|
||||
public_key = models.TextField()
|
||||
public_key = models.TextField(blank=True, null=True)
|
||||
api_key = models.CharField(max_length=255, blank=True, null=True)
|
||||
actor = JSONField()
|
||||
actor = JSONField(blank=True, null=True)
|
||||
local = models.BooleanField(default=True)
|
||||
created_date = models.DateTimeField(auto_now_add=True)
|
||||
updated_date = models.DateTimeField(auto_now=True)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div id="main">
|
||||
<div class="user-profile">
|
||||
<img class="user-pic" src="/static/images/profile.jpg">
|
||||
<h2>{{ user.username }}</h2>
|
||||
<h1>{{ user.username }}</h1>
|
||||
<p>Since {{ user.created_date }}</p>
|
||||
{% if not is_self %}
|
||||
{% if not following %}
|
||||
|
@ -19,11 +19,22 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Books</h2>
|
||||
{% for book in books.all %}
|
||||
<div class="book">
|
||||
{{ book.data.title }} by {{ book.authors.first.data.name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Followers</h2>
|
||||
{% for follower in user.followers.all %}
|
||||
{{ follower.activitypub_id }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -57,12 +57,10 @@ def user_profile(request, username):
|
|||
''' profile page for a user '''
|
||||
user = models.User.objects.get(username=username)
|
||||
books = models.Book.objects.filter(shelves__user=user)
|
||||
following = user.followers.filter(id=request.user.id).count() > 0
|
||||
data = {
|
||||
'user': user,
|
||||
'books': books,
|
||||
'is_self': request.user.id == user.id,
|
||||
'following': following,
|
||||
}
|
||||
return TemplateResponse(request, 'user.html', data)
|
||||
|
||||
|
|
Loading…
Reference in a new issue