mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-23 00:26:33 +00:00
Fixes storage of remote statuses
This commit is contained in:
parent
3e48adad52
commit
a47f573b2b
6 changed files with 92 additions and 18 deletions
|
@ -13,8 +13,8 @@ import requests
|
||||||
from fedireads import activitypub
|
from fedireads import activitypub
|
||||||
from fedireads import models
|
from fedireads import models
|
||||||
from fedireads import outgoing
|
from fedireads import outgoing
|
||||||
from fedireads.status import create_review, create_status, create_tag, \
|
from fedireads.status import create_review_from_activity, \
|
||||||
create_notification
|
create_status_from_activity, create_tag, create_notification
|
||||||
from fedireads.remote_user import get_or_create_remote_user
|
from fedireads.remote_user import get_or_create_remote_user
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,25 +256,19 @@ def handle_incoming_create(activity):
|
||||||
# TODO: should only create notes if they are relevent to a book,
|
# TODO: should only create notes if they are relevent to a book,
|
||||||
# so, not every single thing someone posts on mastodon
|
# so, not every single thing someone posts on mastodon
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
content = activity['object'].get('content')
|
|
||||||
if activity['object'].get('fedireadsType') == 'Review' and \
|
if activity['object'].get('fedireadsType') == 'Review' and \
|
||||||
'inReplyToBook' in activity['object']:
|
'inReplyToBook' in activity['object']:
|
||||||
book = activity['object']['inReplyToBook']
|
|
||||||
book = book.split('/')[-1]
|
|
||||||
name = activity['object'].get('name')
|
|
||||||
rating = activity['object'].get('rating')
|
|
||||||
published = activity['object'].get('published')
|
|
||||||
if user.local:
|
if user.local:
|
||||||
review_id = activity['object']['id'].split('/')[-1]
|
review_id = activity['object']['id'].split('/')[-1]
|
||||||
models.Review.objects.get(id=review_id)
|
models.Review.objects.get(id=review_id)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
create_review(user, book, name, content, rating, published)
|
create_review_from_activity(user, activity['object'])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
elif not user.local:
|
elif not user.local:
|
||||||
try:
|
try:
|
||||||
status = create_status(user, content)
|
status = create_status_from_activity(user, activity['object'])
|
||||||
if status.reply_parent:
|
if status.reply_parent:
|
||||||
create_notification(
|
create_notification(
|
||||||
status.reply_parent.user,
|
status.reply_parent.user,
|
||||||
|
|
18
fedireads/migrations/0014_status_remote_id.py
Normal file
18
fedireads/migrations/0014_status_remote_id.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.0.3 on 2020-03-10 19:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('fedireads', '0013_user_manually_approves_followers'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='status',
|
||||||
|
name='remote_id',
|
||||||
|
field=models.CharField(max_length=255, null=True, unique=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -10,6 +10,7 @@ from fedireads.utils.models import FedireadsModel
|
||||||
|
|
||||||
class Status(FedireadsModel):
|
class Status(FedireadsModel):
|
||||||
''' any post, like a reply to a review, etc '''
|
''' any post, like a reply to a review, etc '''
|
||||||
|
remote_id = models.CharField(max_length=255, unique=True, null=True)
|
||||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||||
status_type = models.CharField(max_length=255, default='Note')
|
status_type = models.CharField(max_length=255, default='Note')
|
||||||
content = models.TextField(blank=True, null=True)
|
content = models.TextField(blank=True, null=True)
|
||||||
|
@ -35,6 +36,16 @@ class Status(FedireadsModel):
|
||||||
)
|
)
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def absolute_id(self):
|
||||||
|
''' constructs the absolute reference to any db object '''
|
||||||
|
if self.remote_id:
|
||||||
|
return self.remote_id
|
||||||
|
base_path = self.user.absolute_id
|
||||||
|
model_name = type(self).__name__.lower()
|
||||||
|
return '%s/%s/%d' % (base_path, model_name, self.id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Review(Status):
|
class Review(Status):
|
||||||
''' a book review '''
|
''' a book review '''
|
||||||
|
|
|
@ -151,7 +151,7 @@ def handle_unshelve(user, book, shelf):
|
||||||
def handle_review(user, book, name, content, rating):
|
def handle_review(user, book, name, content, rating):
|
||||||
''' post a review '''
|
''' post a review '''
|
||||||
# validated and saves the review in the database so it has an id
|
# validated and saves the review in the database so it has an id
|
||||||
review = create_review(user, book, name, content, rating, None)
|
review = create_review(user, book, name, content, rating)
|
||||||
|
|
||||||
review_activity = activitypub.get_review(review)
|
review_activity = activitypub.get_review(review)
|
||||||
review_create_activity = activitypub.get_create(user, review_activity)
|
review_create_activity = activitypub.get_create(user, review_activity)
|
||||||
|
|
|
@ -5,7 +5,24 @@ from fedireads.sanitize_html import InputHtmlParser
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
|
|
||||||
|
|
||||||
def create_review(user, possible_book, name, content, rating, published):
|
def create_review_from_activity(author, activity):
|
||||||
|
''' parse an activity json blob into a status '''
|
||||||
|
book = activity['inReplyToBook']
|
||||||
|
book = book.split('/')[-1]
|
||||||
|
name = activity.get('name')
|
||||||
|
rating = activity.get('rating')
|
||||||
|
content = activity.get('content')
|
||||||
|
published = activity.get('published')
|
||||||
|
remote_id = activity['id']
|
||||||
|
|
||||||
|
review = create_review(author, book, name, content, rating)
|
||||||
|
review.published_date = published
|
||||||
|
review.remote_id = remote_id
|
||||||
|
review.save()
|
||||||
|
return review
|
||||||
|
|
||||||
|
|
||||||
|
def create_review(user, possible_book, name, content, rating):
|
||||||
''' a book review has been added '''
|
''' a book review has been added '''
|
||||||
# throws a value error if the book is not found
|
# throws a value error if the book is not found
|
||||||
book = get_or_create_book(possible_book)
|
book = get_or_create_book(possible_book)
|
||||||
|
@ -15,17 +32,51 @@ def create_review(user, possible_book, name, content, rating, published):
|
||||||
# no ratings outside of 0-5
|
# no ratings outside of 0-5
|
||||||
rating = rating if 0 <= rating <= 5 else 0
|
rating = rating if 0 <= rating <= 5 else 0
|
||||||
|
|
||||||
review = models.Review(
|
return models.Review.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
book=book,
|
book=book,
|
||||||
name=name,
|
name=name,
|
||||||
rating=rating,
|
rating=rating,
|
||||||
content=content,
|
content=content,
|
||||||
)
|
)
|
||||||
if published:
|
|
||||||
review.published_date = published
|
|
||||||
review.save()
|
def create_status_from_activity(author, activity):
|
||||||
return review
|
''' parse a status object out of an activity json blob '''
|
||||||
|
content = activity.get('content')
|
||||||
|
reply_parent_id = activity.get('inReplyTo')
|
||||||
|
reply_parent = get_status(reply_parent_id)
|
||||||
|
|
||||||
|
remote_id = activity['id']
|
||||||
|
|
||||||
|
status = create_status(author, content, reply_parent=reply_parent)
|
||||||
|
status.remote_id = remote_id
|
||||||
|
status.published_date = activity.get('published')
|
||||||
|
status.save()
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
def get_status(absolute_id):
|
||||||
|
''' find a status in the database '''
|
||||||
|
# check if it's a remote status
|
||||||
|
try:
|
||||||
|
return models.Status.objects.get(remote_id=absolute_id)
|
||||||
|
except models.Status.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# try finding a local status with that id
|
||||||
|
local_id = absolute_id.split('/')[-1]
|
||||||
|
try:
|
||||||
|
possible_match = models.Status.objects.get(id=local_id)
|
||||||
|
except models.Status.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# make sure it's not actually a remote status with an id that
|
||||||
|
# clashes with a local id
|
||||||
|
if possible_match.absolute_id == absolute_id:
|
||||||
|
return possible_match
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_status(user, content, reply_parent=None, mention_books=None):
|
def create_status(user, content, reply_parent=None, mention_books=None):
|
||||||
|
|
|
@ -10,7 +10,7 @@ username_regex = r'(?P<username>[\w@\.-]+)'
|
||||||
localname_regex = r'(?P<username>[\w\.-]+)'
|
localname_regex = r'(?P<username>[\w\.-]+)'
|
||||||
user_path = r'^user/%s' % username_regex
|
user_path = r'^user/%s' % username_regex
|
||||||
local_user_path = r'^user/%s' % localname_regex
|
local_user_path = r'^user/%s' % localname_regex
|
||||||
status_path = r'%s/(status|review)/(?P<status_id>\d+)' % user_path
|
status_path = r'%s/(status|review)/(?P<status_id>\d+)' % local_user_path
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
|
Loading…
Reference in a new issue