Merge pull request #83 from cthulahoops/approval_table_split

Approval table split
This commit is contained in:
Mouse Reeve 2020-03-11 12:12:17 -07:00 committed by GitHub
commit 943b793f58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 171 additions and 18 deletions

View file

@ -201,10 +201,9 @@ def handle_incoming_follow(activity):
user = get_or_create_remote_user(activity['actor'])
# TODO: allow users to manually approve requests
try:
models.UserRelationship.objects.create(
models.UserFollowRequest.objects.create(
user_subject=user,
user_object=to_follow,
status='follow_request',
relationship_id=activity['id']
)
except django.db.utils.IntegrityError:

View file

@ -0,0 +1,115 @@
# Generated by Django 3.0.3 on 2020-03-11 12:12
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('fedireads', '0014_status_remote_id'),
]
operations = [
migrations.CreateModel(
name='UserBlocks',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateTimeField(auto_now_add=True)),
('updated_date', models.DateTimeField(auto_now=True)),
('relationship_id', models.CharField(max_length=100)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='UserFollowRequest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateTimeField(auto_now_add=True)),
('updated_date', models.DateTimeField(auto_now=True)),
('relationship_id', models.CharField(max_length=100)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='UserFollows',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateTimeField(auto_now_add=True)),
('updated_date', models.DateTimeField(auto_now=True)),
('relationship_id', models.CharField(max_length=100)),
],
options={
'abstract': False,
},
),
migrations.RemoveField(
model_name='user',
name='followers',
),
migrations.DeleteModel(
name='UserRelationship',
),
migrations.AddField(
model_name='userfollows',
name='user_object',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userfollows_user_object', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userfollows',
name='user_subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userfollows_user_subject', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userfollowrequest',
name='user_object',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userfollowrequest_user_object', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userfollowrequest',
name='user_subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userfollowrequest_user_subject', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userblocks',
name='user_object',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userblocks_user_object', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='userblocks',
name='user_subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='userblocks_user_subject', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='blocks',
field=models.ManyToManyField(related_name='blocked_by', through='fedireads.UserBlocks', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='follow_requests',
field=models.ManyToManyField(related_name='follower_requests', through='fedireads.UserFollowRequest', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='following',
field=models.ManyToManyField(related_name='followers', through='fedireads.UserFollows', to=settings.AUTH_USER_MODEL),
),
migrations.AddConstraint(
model_name='userfollows',
constraint=models.UniqueConstraint(fields=('user_subject', 'user_object'), name='userfollows_unique'),
),
migrations.AddConstraint(
model_name='userfollowrequest',
constraint=models.UniqueConstraint(fields=('user_subject', 'user_object'), name='userfollowrequest_unique'),
),
migrations.AddConstraint(
model_name='userblocks',
constraint=models.UniqueConstraint(fields=('user_subject', 'user_object'), name='userblocks_unique'),
),
]

View file

@ -2,4 +2,4 @@
from .book import Book, Work, Edition, Author
from .shelf import Shelf, ShelfBook
from .status import Status, Review, Favorite, Tag, Notification
from .user import User, UserRelationship, FederatedServer
from .user import User, FederatedServer, UserFollows, UserFollowRequest, UserBlocks

View file

@ -34,12 +34,26 @@ class User(AbstractUser):
# name is your display name, which you can change at will
name = models.CharField(max_length=100, blank=True, null=True)
avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)
followers = models.ManyToManyField(
following = models.ManyToManyField(
'self',
symmetrical=False,
through='UserRelationship',
through_fields=('user_object', 'user_subject'),
related_name='following'
through='UserFollows',
through_fields=('user_subject', 'user_object'),
related_name='followers'
)
follow_requests = models.ManyToManyField(
'self',
symmetrical=False,
through='UserFollowRequest',
through_fields=('user_subject', 'user_object'),
related_name='follower_requests'
)
blocks = models.ManyToManyField(
'self',
symmetrical=False,
through='UserBlocks',
through_fields=('user_subject', 'user_object'),
related_name='blocked_by'
)
favorites = models.ManyToManyField(
'Status',
@ -65,22 +79,22 @@ class UserRelationship(FedireadsModel):
user_subject = models.ForeignKey(
'User',
on_delete=models.PROTECT,
related_name='user_subject'
related_name='%(class)s_user_subject'
)
user_object = models.ForeignKey(
'User',
on_delete=models.PROTECT,
related_name='user_object'
related_name='%(class)s_user_object'
)
# follow or follow_request for pending TODO: blocking?
status = models.CharField(max_length=100, default='follows', null=True)
relationship_id = models.CharField(max_length=100)
class Meta:
abstract = True
constraints = [
models.UniqueConstraint(
fields=['user_subject', 'user_object'],
name='followers_unique'
name='%(class)s_unique'
)
]
@ -90,6 +104,28 @@ class UserRelationship(FedireadsModel):
base_path = self.user_subject.absolute_id
return '%s#%s/%d' % (base_path, self.status, self.id)
class UserFollows(UserRelationship):
@property
def status(self):
return 'follows'
@classmethod
def from_request(cls, follow_request):
return cls(
user_subject=follow_request.user_subject,
user_object=follow_request.user_object,
relationship_id=follow_request.relationship_id,
)
class UserFollowRequest(UserRelationship):
@property
def status(self):
return 'follow_request'
class UserBlocks(UserRelationship):
@property
def status(self):
return 'blocks'
class FederatedServer(FedireadsModel):
''' store which server's we federate with '''

View file

@ -1,5 +1,5 @@
''' handles all the activity coming out of the server '''
from django.db import IntegrityError
from django.db import IntegrityError, transaction
from django.http import HttpResponseNotFound, JsonResponse
from django.views.decorators.csrf import csrf_exempt
import requests
@ -88,7 +88,7 @@ def handle_outgoing_follow(user, to_follow):
def handle_outgoing_unfollow(user, to_unfollow):
''' someone local wants to follow someone '''
relationship = models.UserRelationship.objects.get(
relationship = models.UserFollows.objects.get(
user_subject=user,
user_object=to_unfollow
)
@ -101,11 +101,14 @@ def handle_outgoing_unfollow(user, to_unfollow):
def handle_outgoing_accept(user, to_follow, request_activity):
''' send an acceptance message to a follow request '''
relationship = models.UserRelationship.objects.get(
relationship_id=request_activity['id']
)
relationship.status = 'follow'
relationship.save()
with transaction.atomic():
follow_request = models.UserFollowRequest.objects.get(
relationship_id=request_activity['id']
)
relationship = models.UserFollows.from_request(follow_request)
follow_request.delete()
relationship.save()
activity = activitypub.get_accept(to_follow, request_activity)
recipient = get_recipients(to_follow, 'direct', direct_recipients=[user])
broadcast(to_follow, activity, recipient)