Partial checkin. Trying to generate the Create activity automatically when a Note (etc) is saved.

2019-08-17
Marnanel Thurman 2019-04-25 01:13:10 +01:00
rodzic 488770e5ba
commit e73a34f10b
8 zmienionych plików z 162 dodań i 15 usunięć

Wyświetl plik

@ -170,7 +170,8 @@ class Activity(models.Model):
def activity_type(self):
return self.f_type
def activity_form(self, *args, **kwargs):
@property
def activity_form(self):
result = {
'id': self.identifier,
'type': self.get_f_type_display(),
@ -287,11 +288,17 @@ class Activity(models.Model):
raise ValueError("Remote activities must have an id")
fields = {
'identifier': value.get('id', None),
'f_type': value['type'],
'active': True,
}
for f,v in value.items():
fields['f_'+f] = v
# XXX nasty temporary hack which will go away soon
for name in ['f_to', 'f_cc']:
if name in fields:
del fields[name]
try:
need_actor, need_object, need_target = cls.TYPES[value['type']]
except KeyError:

Wyświetl plik

@ -0,0 +1,19 @@
# Generated by Django 2.1.5 on 2019-04-23 13:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('django_kepi', '0011_auto_20190418_1328'),
]
operations = [
migrations.CreateModel(
name='ActivityModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
]

Wyświetl plik

@ -3,7 +3,54 @@ from django_kepi import object_type_registry
from django_kepi.cache_model import Cache
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django_kepi.models import Activity
import logging
logger = logging.getLogger(name='django_kepi')
#######################
class ActivityModel(models.Model):
def save(self, *args, **kwargs):
we_are_new = self.pk is None
super().save(*args, **kwargs)
if we_are_new:
logger.debug('New activity: %s',
str(self.activity_form))
logger.debug('We must create a Create wrapper for it.')
wrapper = Activity.create({
'type': 'Create',
'actor': self.activity_actor,
'to': self.activity_to,
'cc': self.activity_cc,
'object': self.activity_id,
})
wrapper.save()
logger.debug('Created wrapper %s',
str(wrapper.activity_form))
# XXX We copy "to" and "cc" per
# https://www.w3.org/TR/activitypub/#object-without-create
# which also requires us to copy
# the two blind versions, and "audience".
# We don't support those (atm), but
# we should probably copy them anyway.
@property
def activity_to(self):
# FIXME
return ["https://www.w3.org/ns/activitystreams#Public"]
@property
def activity_cc(self):
# FIXME
return ["https://marnanel.org/users/marnanel/followers"]
#######################
class SomethingManager(models.Manager):

Wyświetl plik

@ -1,11 +1,15 @@
from django.test import TestCase
from django_kepi.models import Activity
from things_for_testing.models import ThingArticle, ThingUser
from things_for_testing.models import ThingNote, ThingUser
FRED_URL = 'https://users.example.com/user/fred'
class TestActivity(TestCase):
def test_parameters(self):
return # XXX
with self.assertRaisesMessage(ValueError, "is not an Activity type"):
Activity.create({
"id": "https://example.com/id/1",
@ -17,7 +21,7 @@ class TestActivity(TestCase):
"type": "Create",
"actor": "https://example.com/user/fred",
"object": {
"type": "Article",
"type": "Note",
},
},
sender="https://remote.example.com")
@ -30,3 +34,11 @@ class TestActivity(TestCase):
fred = ThingUser(name="fred")
fred.save()
def test_note_creation(self):
note = ThingNote(
title='Hello world',
owner=FRED_URL,
)
note.save()

Wyświetl plik

@ -0,0 +1,17 @@
# Generated by Django 2.1.5 on 2019-04-23 13:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('things_for_testing', '0005_auto_20181029_0852'),
]
operations = [
migrations.RenameModel(
old_name='ThingArticle',
new_name='ThingNote',
),
]

Wyświetl plik

@ -0,0 +1,25 @@
# Generated by Django 2.1.5 on 2019-04-23 13:33
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('django_kepi', '0012_activitymodel'),
('things_for_testing', '0006_auto_20190423_1308'),
]
operations = [
migrations.RemoveField(
model_name='thingnote',
name='id',
),
migrations.AddField(
model_name='thingnote',
name='activitymodel_ptr',
field=models.OneToOneField(auto_created=True, default=0, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='django_kepi.ActivityModel'),
preserve_default=False,
),
]

Wyświetl plik

@ -0,0 +1,19 @@
# Generated by Django 2.1.5 on 2019-04-23 14:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('things_for_testing', '0007_auto_20190423_1333'),
]
operations = [
migrations.AddField(
model_name='thingnote',
name='owner',
field=models.URLField(default=0, max_length=256),
preserve_default=False,
),
]

Wyświetl plik

@ -32,10 +32,6 @@ class ThingUser(models.Model):
'favourite_colour': self.favourite_colour,
}
@property
def implements_activity_type(self):
return 'Person'
@property
def activity_id(self):
return self.url
@ -60,27 +56,33 @@ class ThingUser(models.Model):
result.save()
return result
@implements_activity_type('Article')
class ThingArticle(models.Model):
@implements_activity_type('Note')
class ThingNote(kepi_models.ActivityModel):
title = models.CharField(max_length=256)
ftype = 'Article'
ftype = 'Note'
remote_url = models.URLField(max_length=256,
null=True, default=None)
owner = models.URLField(max_length=256)
@property
def activity_actor(self):
return self.owner
@property
def activity_form(self):
return {
'id': self.activity_id,
'type': 'Article',
'type': 'Note',
'title': self.title,
}
@property
def activity_id(self):
return 'https://articles.example.com/{}'.format(
self.title,
self.title.replace(' ','-').lower(),
)
@classmethod
@ -100,4 +102,3 @@ class ThingArticle(models.Model):
)
result.save()
return result