mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-22 09:31:08 +00:00
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 '''
|
''' generates activitypub formatted objects '''
|
||||||
|
from uuid import uuid4
|
||||||
|
from fedireads.settings import DOMAIN
|
||||||
|
|
||||||
|
|
||||||
def shelve_action(user, book, shelf):
|
def shelve_action(user, book, shelf):
|
||||||
''' a user puts a book on a 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.settings import DOMAIN
|
||||||
from fedireads import models
|
from fedireads import models
|
||||||
from fedireads import openlibrary
|
from fedireads import openlibrary
|
||||||
|
import fedireads.activitypub_templates as templates
|
||||||
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
def webfinger(request):
|
def webfinger(request):
|
||||||
|
@ -52,13 +54,18 @@ def inbox(request, username):
|
||||||
# return a collection of something?
|
# return a collection of something?
|
||||||
pass
|
pass
|
||||||
|
|
||||||
activity = request.POST.dict()
|
activity = json.loads(request.body)
|
||||||
if activity['type'] == 'Add':
|
if activity['type'] == 'Add':
|
||||||
handle_add(activity)
|
handle_add(activity)
|
||||||
|
|
||||||
|
if activity['type'] == 'Follow':
|
||||||
|
response = handle_follow(activity)
|
||||||
|
return JsonResponse(response)
|
||||||
|
|
||||||
return HttpResponse()
|
return HttpResponse()
|
||||||
|
|
||||||
def handle_add(activity):
|
def handle_add(activity):
|
||||||
|
''' adding a book to a shelf '''
|
||||||
book_id = activity['object']['url']
|
book_id = activity['object']['url']
|
||||||
book = openlibrary.get_or_create_book(book_id)
|
book = openlibrary.get_or_create_book(book_id)
|
||||||
user_ap_id = activity['actor'].replace('https//:', '')
|
user_ap_id = activity['actor'].replace('https//:', '')
|
||||||
|
@ -70,6 +77,31 @@ def handle_add(activity):
|
||||||
added_by=user,
|
added_by=user,
|
||||||
).save()
|
).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
|
@csrf_exempt
|
||||||
def outbox(request, username):
|
def outbox(request, username):
|
||||||
user = models.User.objects.get(username=username)
|
user = models.User.objects.get(username=username)
|
||||||
|
@ -106,19 +138,16 @@ date: %s''' % (inbox_fragment, DOMAIN, now)
|
||||||
signature += 'signature="%s"' % b64encode(signed_message)
|
signature += 'signature="%s"' % b64encode(signed_message)
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
recipient,
|
recipient,
|
||||||
data=action,
|
body=action,
|
||||||
headers={
|
headers={
|
||||||
'Date': now,
|
'Date': now,
|
||||||
'Signature': signature,
|
'Signature': signature,
|
||||||
'Host': DOMAIN,
|
'Host': DOMAIN,
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
return response.raise_for_status()
|
return response.raise_for_status()
|
||||||
|
|
||||||
def handle_follow(data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_or_create_remote_user(activity):
|
def get_or_create_remote_user(activity):
|
||||||
pass
|
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
|
from django.conf import settings
|
||||||
import django.contrib.auth.models
|
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')),
|
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||||
('activitypub_id', models.CharField(max_length=255)),
|
('activitypub_id', models.CharField(max_length=255)),
|
||||||
('private_key', models.TextField(blank=True, null=True)),
|
('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)),
|
('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)),
|
('local', models.BooleanField(default=True)),
|
||||||
('created_date', models.DateTimeField(auto_now_add=True)),
|
('created_date', models.DateTimeField(auto_now_add=True)),
|
||||||
('updated_date', models.DateTimeField(auto_now=True)),
|
('updated_date', models.DateTimeField(auto_now=True)),
|
||||||
|
|
|
@ -12,9 +12,9 @@ class User(AbstractUser):
|
||||||
''' a user who wants to read books '''
|
''' a user who wants to read books '''
|
||||||
activitypub_id = models.CharField(max_length=255)
|
activitypub_id = models.CharField(max_length=255)
|
||||||
private_key = models.TextField(blank=True, null=True)
|
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)
|
api_key = models.CharField(max_length=255, blank=True, null=True)
|
||||||
actor = JSONField()
|
actor = JSONField(blank=True, null=True)
|
||||||
local = models.BooleanField(default=True)
|
local = models.BooleanField(default=True)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
updated_date = models.DateTimeField(auto_now=True)
|
updated_date = models.DateTimeField(auto_now=True)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div class="user-profile">
|
<div class="user-profile">
|
||||||
<img class="user-pic" src="/static/images/profile.jpg">
|
<img class="user-pic" src="/static/images/profile.jpg">
|
||||||
<h2>{{ user.username }}</h2>
|
<h1>{{ user.username }}</h1>
|
||||||
<p>Since {{ user.created_date }}</p>
|
<p>Since {{ user.created_date }}</p>
|
||||||
{% if not is_self %}
|
{% if not is_self %}
|
||||||
{% if not following %}
|
{% if not following %}
|
||||||
|
@ -19,11 +19,22 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Books</h2>
|
||||||
{% for book in books.all %}
|
{% for book in books.all %}
|
||||||
<div class="book">
|
<div class="book">
|
||||||
{{ book.data.title }} by {{ book.authors.first.data.name }}
|
{{ book.data.title }} by {{ book.authors.first.data.name }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Followers</h2>
|
||||||
|
{% for follower in user.followers.all %}
|
||||||
|
{{ follower.activitypub_id }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -57,12 +57,10 @@ def user_profile(request, username):
|
||||||
''' profile page for a user '''
|
''' profile page for a user '''
|
||||||
user = models.User.objects.get(username=username)
|
user = models.User.objects.get(username=username)
|
||||||
books = models.Book.objects.filter(shelves__user=user)
|
books = models.Book.objects.filter(shelves__user=user)
|
||||||
following = user.followers.filter(id=request.user.id).count() > 0
|
|
||||||
data = {
|
data = {
|
||||||
'user': user,
|
'user': user,
|
||||||
'books': books,
|
'books': books,
|
||||||
'is_self': request.user.id == user.id,
|
'is_self': request.user.id == user.id,
|
||||||
'following': following,
|
|
||||||
}
|
}
|
||||||
return TemplateResponse(request, 'user.html', data)
|
return TemplateResponse(request, 'user.html', data)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue