1
0
Fork 0

Use custom model fields in user model

This commit is contained in:
Mouse Reeve 2020-11-30 10:32:13 -08:00
parent 96563598bf
commit 74a58e5267
8 changed files with 429 additions and 124 deletions

View file

@ -17,6 +17,7 @@ from django.dispatch import receiver
from bookwyrm import activitypub
from bookwyrm.settings import DOMAIN
from .fields import RemoteIdField
PrivacyLevels = models.TextChoices('Privacy', [
@ -30,7 +31,7 @@ class BookWyrmModel(models.Model):
''' shared fields '''
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
remote_id = models.CharField(max_length=255, null=True)
remote_id = RemoteIdField(null=True, activitypub_field='id')
def get_remote_id(self):
''' generate a url that resolves to the local object '''
@ -61,49 +62,18 @@ class ActivitypubMixin:
def to_activity(self, pure=False):
''' convert from a model to an activity '''
if pure:
# works around bookwyrm-specific fields for vanilla AP services
mappings = self.pure_activity_mappings
else:
# may include custom fields that bookwyrm instances will understand
mappings = self.activity_mappings
activity = {}
for field in self.__class__._meta.fields:
key, value = field.to_activity(getattr(self, field.name))
activity[key] = value
for related_object in self.__class__.meta.related_objects:
# TODO: check if it's serializable
related_model = related_object.related_model
key = related_object.name
related_values = getattr(self, key)
activity[key] = [i.remote_id for i in related_values]
fields = {}
for mapping in mappings:
if not hasattr(self, mapping.model_key) or not mapping.activity_key:
# this field on the model isn't serialized
continue
value = getattr(self, mapping.model_key)
model_field = getattr(self.__class__, mapping.model_key)
if hasattr(value, 'remote_id'):
# this is probably a foreign key field, which we want to
# serialize as just the remote_id url reference
value = value.remote_id
elif isinstance(model_field, \
(ManyToManyDescriptor, ReverseManyToOneDescriptor)):
value = [i.remote_id for i in value.all()]
elif isinstance(value, datetime):
value = value.isoformat()
elif isinstance(model_field, ImageFileDescriptor):
value = image_formatter(value)
# run the custom formatter function set in the model
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] += formatted_value
else:
fields[mapping.activity_key] = formatted_value
if pure:
return self.pure_activity_serializer(
**fields
).serialize()
return self.activity_serializer(
**fields
).serialize()
return self.activity_serializer(**activity_json).serialize()
def to_create_activity(self, user, pure=False):