kopia lustrzana https://gitlab.com/marnanel/chapeau
103 wiersze
2.6 KiB
Python
103 wiersze
2.6 KiB
Python
import django_kepi.types as types
|
|
import logging
|
|
|
|
logger = logging.getLogger(name='django_kepi')
|
|
|
|
def create(
|
|
is_local_user=True,
|
|
run_side_effects=True,
|
|
run_delivery=True,
|
|
value=None,
|
|
**kwargs):
|
|
|
|
from django_kepi.delivery import deliver
|
|
|
|
logger.info("Create begins: source is %s; local? %s; run side effects? %s",
|
|
value, is_local_user, run_side_effects)
|
|
|
|
if value is None:
|
|
value = kwargs.copy()
|
|
|
|
# Remove the "f_" prefix, which exists so that we can write
|
|
# things like f_type or f_object without using reserved keywords.
|
|
for k,v in kwargs.copy().items():
|
|
if k.startswith('f_'):
|
|
value[k[2:]] = v
|
|
del value[k]
|
|
|
|
# Now, let's fix the types of keys and values.
|
|
|
|
for k,v in value.copy().items():
|
|
if not isinstance(k, str):
|
|
logger.warn('Things can only have keys which are strings: %s',
|
|
str(k))
|
|
continue
|
|
|
|
if 'type' not in value:
|
|
logger.warn("Things must have a type; dropping message")
|
|
return
|
|
|
|
value['type'] = value['type'].title()
|
|
|
|
if 'id' in value:
|
|
if is_local_user:
|
|
logger.warn('Removing "id" field at Thing creation')
|
|
del value['id']
|
|
else:
|
|
if not is_local_user:
|
|
logger.warn("Remote things must have an id; dropping message")
|
|
return
|
|
|
|
try:
|
|
type_spec = types.ACTIVITYPUB_TYPES[value['type']]
|
|
except KeyError:
|
|
logger.info('Unknown thing type: %s; dropping message',
|
|
value['type'])
|
|
return None
|
|
|
|
if 'class' not in type_spec:
|
|
logger.info('Type %s can\'t be instantiated',
|
|
value['type'])
|
|
return None
|
|
|
|
try:
|
|
import django_kepi.models as kepi_models
|
|
cls = getattr(locals()['kepi_models'], type_spec['class'])
|
|
except KeyError:
|
|
# shouldn't happen!
|
|
logger.warn("The class '%s' wasn't exported properly",
|
|
type_spec['class'])
|
|
return None
|
|
|
|
logger.debug('Class for %s is %s', value['type'], cls)
|
|
|
|
########################
|
|
|
|
# XXX Check what fields we need, based on type_spec.
|
|
# XXX implement this.
|
|
|
|
########################
|
|
|
|
# Right, we need to create an object.
|
|
|
|
result = cls()
|
|
|
|
if 'id' in value:
|
|
result.remote_url = value['id']
|
|
del value['id']
|
|
|
|
for f,v in value.items():
|
|
result[f] = v
|
|
|
|
result.save()
|
|
|
|
if run_side_effects:
|
|
result.run_side_effects()
|
|
|
|
if run_delivery:
|
|
deliver(result.number,
|
|
incoming = True)
|
|
|
|
return result
|
|
|