Merge branch 'main' into progress_update

This commit is contained in:
Joel Bradshaw
2020-11-28 11:06:01 -08:00
19 changed files with 299 additions and 174 deletions

View File

@ -5,15 +5,21 @@ import sys
from .book import Book, Work, Edition
from .author import Author
from .connector import Connector
from .relationship import UserFollows, UserFollowRequest, UserBlocks
from .shelf import Shelf, ShelfBook
from .status import Status, GeneratedNote, Review, Comment, Quotation
from .status import Attachment, Favorite, Boost, Notification, ReadThrough, ProgressMode, ProgressUpdate
from .status import Favorite, Boost, Notification, ReadThrough, ProgressMode, ProgressUpdate
from .attachment import Image
from .tag import Tag
from .user import User
from .relationship import UserFollows, UserFollowRequest, UserBlocks
from .federated_server import FederatedServer
from .import_job import ImportJob, ImportItem
from .site import SiteSettings, SiteInvite, PasswordReset
cls_members = inspect.getmembers(sys.modules[__name__], inspect.isclass)

View File

@ -0,0 +1,32 @@
''' media that is posted in the app '''
from django.db import models
from bookwyrm import activitypub
from .base_model import ActivitypubMixin
from .base_model import ActivityMapping, BookWyrmModel
class Attachment(ActivitypubMixin, BookWyrmModel):
''' an image (or, in the future, video etc) associated with a status '''
status = models.ForeignKey(
'Status',
on_delete=models.CASCADE,
related_name='attachments',
null=True
)
class Meta:
''' one day we'll have other types of attachments besides images '''
abstract = True
activity_mappings = [
ActivityMapping('id', 'remote_id'),
ActivityMapping('url', 'image'),
ActivityMapping('name', 'caption'),
]
class Image(Attachment):
''' an image attachment '''
image = models.ImageField(upload_to='status/', null=True, blank=True)
caption = models.TextField(null=True, blank=True)
activity_serializer = activitypub.Image

View File

@ -10,6 +10,7 @@ from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from django.db import models
from django.db.models.fields.files import ImageFieldFile
from django.dispatch import receiver
from bookwyrm import activitypub
@ -77,16 +78,18 @@ class ActivitypubMixin:
value = value.remote_id
elif isinstance(value, datetime):
value = value.isoformat()
elif isinstance(value, ImageFieldFile):
value = image_formatter(value)
# run the custom formatter function set in the model
result = mapping.activity_formatter(value)
formatted_value = mapping.activity_formatter(value)
if mapping.activity_key in fields and \
isinstance(fields[mapping.activity_key], list):
# there can be two database fields that map to the same AP list
# this happens in status tags, which combines user and book tags
fields[mapping.activity_key] += result
fields[mapping.activity_key] += formatted_value
else:
fields[mapping.activity_key] = result
fields[mapping.activity_key] = formatted_value
if pure:
return self.pure_activity_serializer(
@ -270,12 +273,10 @@ def tag_formatter(items, name_field, activity_type):
return tags
def image_formatter(image, default_path=None):
def image_formatter(image):
''' convert images into activitypub json '''
if image and hasattr(image, 'url'):
url = image.url
elif default_path:
url = default_path
else:
return None
url = 'https://%s%s' % (DOMAIN, url)

View File

@ -12,7 +12,6 @@ from bookwyrm.utils.fields import ArrayField
from .base_model import ActivityMapping, BookWyrmModel
from .base_model import ActivitypubMixin, OrderedCollectionPageMixin
from .base_model import image_attachments_formatter
class Book(ActivitypubMixin, BookWyrmModel):
''' a generic book, which can mean either an edition or a work '''
@ -61,11 +60,6 @@ class Book(ActivitypubMixin, BookWyrmModel):
''' the activitypub serialization should be a list of author ids '''
return [a.remote_id for a in self.authors.all()]
@property
def ap_parent_work(self):
''' reference the work via local id not remote '''
return self.parent_work.remote_id
@property
def latest_readthrough(self):
return self.readthrough_set.order_by('-updated_date').first()
@ -74,40 +68,35 @@ class Book(ActivitypubMixin, BookWyrmModel):
ActivityMapping('id', 'remote_id'),
ActivityMapping('authors', 'ap_authors'),
ActivityMapping('first_published_date', 'first_published_date'),
ActivityMapping('published_date', 'published_date'),
ActivityMapping('firstPublishedDate', 'firstpublished_date'),
ActivityMapping('publishedDate', 'published_date'),
ActivityMapping('title', 'title'),
ActivityMapping('sort_title', 'sort_title'),
ActivityMapping('sortTitle', 'sort_title'),
ActivityMapping('subtitle', 'subtitle'),
ActivityMapping('description', 'description'),
ActivityMapping('languages', 'languages'),
ActivityMapping('series', 'series'),
ActivityMapping('series_number', 'series_number'),
ActivityMapping('seriesNumber', 'series_number'),
ActivityMapping('subjects', 'subjects'),
ActivityMapping('subject_places', 'subject_places'),
ActivityMapping('subjectPlaces', 'subject_places'),
ActivityMapping('openlibrary_key', 'openlibrary_key'),
ActivityMapping('librarything_key', 'librarything_key'),
ActivityMapping('goodreads_key', 'goodreads_key'),
ActivityMapping('openlibraryKey', 'openlibrary_key'),
ActivityMapping('librarythingKey', 'librarything_key'),
ActivityMapping('goodreadsKey', 'goodreads_key'),
ActivityMapping('work', 'ap_parent_work'),
ActivityMapping('isbn_10', 'isbn_10'),
ActivityMapping('isbn_13', 'isbn_13'),
ActivityMapping('oclc_number', 'oclc_number'),
ActivityMapping('work', 'parent_work'),
ActivityMapping('isbn10', 'isbn_10'),
ActivityMapping('isbn13', 'isbn_13'),
ActivityMapping('oclcNumber', 'oclc_number'),
ActivityMapping('asin', 'asin'),
ActivityMapping('pages', 'pages'),
ActivityMapping('physical_format', 'physical_format'),
ActivityMapping('physicalFormat', 'physical_format'),
ActivityMapping('publishers', 'publishers'),
ActivityMapping('lccn', 'lccn'),
ActivityMapping('editions', 'editions_path'),
ActivityMapping(
'attachment', 'cover',
# this expects an iterable and the field is just an image
lambda x: image_attachments_formatter([x]),
activitypub.image_formatter
),
ActivityMapping('cover', 'cover'),
]
def save(self, *args, **kwargs):

View File

@ -90,7 +90,6 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
ActivityMapping(
'attachment', 'attachments',
lambda x: image_attachments_formatter(x.all()),
activitypub.image_attachments_formatter
)
]
@ -151,17 +150,6 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
return super().save(*args, **kwargs)
class Attachment(BookWyrmModel):
''' an image (or, in the future, video etc) associated with a status '''
status = models.ForeignKey(
'Status',
on_delete=models.CASCADE,
related_name='attachments'
)
image = models.ImageField(upload_to='status/', null=True, blank=True)
caption = models.TextField(null=True, blank=True)
class GeneratedNote(Status):
''' these are app-generated messages about user activity '''
@property

View File

@ -112,11 +112,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
activity_formatter=lambda x: {'sharedInbox': x},
model_formatter=lambda x: x.get('sharedInbox')
),
ActivityMapping(
'icon', 'avatar',
lambda x: image_formatter(x, '/static/images/default_avi.jpg'),
activitypub.image_formatter
),
ActivityMapping('icon', 'avatar'),
ActivityMapping(
'manuallyApprovesFollowers',
'manually_approves_followers'