124 lines
4.2 KiB
Python
124 lines
4.2 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
"""Hooks for shots & assets.
|
|
|
|
These two node types have very similar use, which is why they are covered by the same code.
|
|
"""
|
|
|
|
import itertools
|
|
import logging
|
|
|
|
from attract.node_types.shot import node_type_shot, human_readable_properties
|
|
from attract.node_types.asset import node_type_asset
|
|
from pillar.api.nodes.eve_hooks import only_for_node_type_decorator
|
|
import pillar.api.activities
|
|
import pillar.api.utils.authentication
|
|
import pillar.api.utils
|
|
import pillar.web.jinja
|
|
|
|
log = logging.getLogger(__name__)
|
|
only_for_shot = only_for_node_type_decorator(node_type_shot['name'])
|
|
for_shot_asset = only_for_node_type_decorator(node_type_shot['name'],
|
|
node_type_asset['name'])
|
|
|
|
typenames = {
|
|
node_type_shot['name']: 'shot',
|
|
node_type_asset['name']: 'asset',
|
|
}
|
|
|
|
|
|
def register_shot_asset_activity(shot, descr):
|
|
user_id = pillar.api.utils.authentication.current_user_id()
|
|
pillar.api.activities.register_activity(
|
|
user_id,
|
|
descr,
|
|
'node', shot['_id'],
|
|
'project', shot['project'],
|
|
shot['project'],
|
|
node_type=shot['node_type'],
|
|
)
|
|
|
|
|
|
@for_shot_asset
|
|
def activity_after_replacing_shot_asset(shot_or_asset, original):
|
|
"""
|
|
Note: this is also used on PATCH, since our custom shot PATCH handler
|
|
performs a PUT-internal to run the patched node through Eve for
|
|
validation.
|
|
"""
|
|
|
|
typename = typenames[shot_or_asset['node_type']]
|
|
|
|
# Compare to original, and either mention the things that changed,
|
|
# or (if they are equal) don't log an activity at all.
|
|
changes = list(itertools.islice(pillar.api.utils.doc_diff(shot_or_asset, original), 2))
|
|
if not changes:
|
|
log.info('Not registering replacement of %s %s, as it is identical '
|
|
'in non-private fields.', typename, shot_or_asset['_id'])
|
|
return
|
|
|
|
if len(changes) == 1:
|
|
(key, val_shot, _) = changes[0]
|
|
try:
|
|
human_key = human_readable_properties[key]
|
|
except KeyError:
|
|
human_key = pillar.web.jinja.format_undertitle(key.rsplit('.', 1)[-1])
|
|
descr = None
|
|
|
|
# Some key- and value-specific overrides
|
|
if val_shot is pillar.api.utils.DoesNotExist:
|
|
descr = 'removed "%s" from shot "%s"' % (human_key, shot_or_asset['name'])
|
|
if key == 'picture':
|
|
descr = 'changed the thumbnail of %s "%s"' % (typename, shot_or_asset['name'])
|
|
elif key == 'properties.status':
|
|
val_shot = pillar.web.jinja.format_undertitle(val_shot)
|
|
elif isinstance(val_shot, str) and len(val_shot) > 80:
|
|
val_shot = val_shot[:80] + '…'
|
|
|
|
if descr is None:
|
|
# A name change activity contains both the old and the new name.
|
|
descr = 'changed "%s" to "%s" in %s "%s"' % \
|
|
(human_key, val_shot, typename, original['name'])
|
|
else:
|
|
descr = 'edited %s "%s"' % (typename, shot_or_asset['name'])
|
|
|
|
register_shot_asset_activity(shot_or_asset, descr)
|
|
|
|
|
|
@for_shot_asset
|
|
def activity_after_creating_shot_asset(shot_or_asset):
|
|
typename = typenames[shot_or_asset['node_type']]
|
|
register_shot_asset_activity(shot_or_asset, 'created a new %s "%s"' % (
|
|
typename, shot_or_asset['name']))
|
|
|
|
|
|
def activity_after_creating_shots_assets(nodes):
|
|
for node in nodes:
|
|
activity_after_creating_shot_asset(node)
|
|
|
|
|
|
@only_for_shot
|
|
def set_default_used_in_edit(shot):
|
|
"""Ensures that used_in_edit is always set."""
|
|
shot.setdefault('properties', {}).setdefault('used_in_edit', True)
|
|
|
|
|
|
def nodes_set_default_used_in_edit(nodes):
|
|
for node in nodes:
|
|
set_default_used_in_edit(node)
|
|
|
|
|
|
@for_shot_asset
|
|
def activity_after_deleting_shot_asset(shot_or_asset):
|
|
typename = typenames[shot_or_asset['node_type']]
|
|
register_shot_asset_activity(shot_or_asset, 'deleted %s "%s"' % (
|
|
typename, shot_or_asset['name']))
|
|
|
|
|
|
def setup_app(app):
|
|
app.on_replaced_nodes += activity_after_replacing_shot_asset
|
|
app.on_insert_nodes += nodes_set_default_used_in_edit
|
|
app.on_inserted_nodes += activity_after_creating_shots_assets
|
|
app.on_deleted_item_nodes += activity_after_deleting_shot_asset
|
|
app.on_deleted_resource_nodes += activity_after_deleting_shot_asset
|