Skip to content

Commit

Permalink
Remove target input from form if its fixed, add ability to share targ…
Browse files Browse the repository at this point in the history
…et and its existing data when creating a persistent share, remove download from the destinations list, and bold the service portion of destination string
  • Loading branch information
Jon committed Dec 19, 2024
1 parent 820fa5d commit a62799a
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 54 deletions.
2 changes: 1 addition & 1 deletion docs/managing_data/continuous_sharing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ sharing after you have bulk created the `ReducedDatums`:

.. code:: python
from tom_dataproducts.sharing import continuous_share_data
from tom_targets.sharing import continuous_share_data
# After all your logic to bulk_create ReducedDatums
# Trigger any sharing you may have set to occur when new data comes in
# Encapsulate this in a try/catch so sharing failure doesn't prevent dataproduct ingestion
Expand Down
2 changes: 1 addition & 1 deletion tom_dataproducts/data_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from importlib import import_module

from tom_dataproducts.models import ReducedDatum
from tom_dataproducts.sharing import continuous_share_data
from tom_targets.sharing import continuous_share_data

logger = logging.getLogger(__name__)

Expand Down
38 changes: 7 additions & 31 deletions tom_dataproducts/sharing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,13 @@
from django.http import StreamingHttpResponse
from django.utils.text import slugify

from tom_targets.models import Target, PersistentShare
from tom_targets.models import Target

from tom_dataproducts.models import DataProduct, ReducedDatum
from tom_dataproducts.alertstreams.hermes import publish_to_hermes, BuildHermesMessage, get_hermes_topics
from tom_dataproducts.serializers import DataProductSerializer, ReducedDatumSerializer


def continuous_share_data(target, reduced_datums):
"""
Triggered when new ReducedDatums are created.
Shares those ReducedDatums to the sharing destination of any PersistentShares on the target.
:param target: Target instance that these reduced_datums belong to
:param reduced_datums: list of ReducedDatum instances to share
"""
persistentshares = PersistentShare.objects.filter(target=target)
for persistentshare in persistentshares:
share_destination = persistentshare.destination
reduced_datum_pks = [rd.pk for rd in reduced_datums]
if 'HERMES' in share_destination.upper():
hermes_topic = share_destination.split(':')[1]
destination = share_destination.split(':')[0]
filtered_reduced_datums = check_for_share_safe_datums(
destination, ReducedDatum.objects.filter(pk__in=reduced_datum_pks), topic=hermes_topic)
sharing = getattr(settings, "DATA_SHARING", {})
message = BuildHermesMessage(title=f"Updated data for {target.name} from "
f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.",
authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None),
message=None,
topic=hermes_topic
)
publish_to_hermes(message, filtered_reduced_datums)
else:
share_data_with_tom(share_destination, None, None, None, selected_data=reduced_datum_pks)


def share_target_list_with_hermes(share_destination, form_data, selected_targets=None, include_all_data=False):
"""
Serialize and share a set of selected targets and their data with Hermes
Expand Down Expand Up @@ -273,13 +246,16 @@ def check_for_save_safe_datums():
return


def get_sharing_destination_options():
def get_sharing_destination_options(include_download=True):
"""
Build the Display options and headers for the dropdown form for choosing sharing topics.
Customize for a different selection experience.
:return: Tuple: Possible Destinations and their Display Names
"""
choices = [('download', 'download')]
if include_download:
choices = [('download', 'download')]
else:
choices = []
try:
for destination, details in settings.DATA_SHARING.items():
new_destination = [details.get('DISPLAY_NAME', destination)]
Expand Down
3 changes: 2 additions & 1 deletion tom_targets/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,12 @@ class Meta:

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['destination'].choices = get_sharing_destination_options()
self.fields['destination'].choices = get_sharing_destination_options(include_download=False)


class PersistentShareForm(AdminPersistentShareForm):
target = forms.IntegerField(label='Target ID', initial=0, required=True)
share_existing_data = forms.BooleanField(label='Share existing data immediately', required=False, initial=False)

def __init__(self, *args, **kwargs):
try:
Expand Down
21 changes: 21 additions & 0 deletions tom_targets/persistent_sharing_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from rest_framework import serializers
from tom_dataproducts.sharing import get_sharing_destination_options
from tom_targets.sharing import share_target_and_all_data
from tom_targets.fields import TargetFilteredPrimaryKeyRelatedField
from tom_targets.models import PersistentShare, Target


class PersistentShareSerializer(serializers.ModelSerializer):
destination = serializers.ChoiceField(choices=get_sharing_destination_options(include_download=False), required=True)
target = TargetFilteredPrimaryKeyRelatedField(queryset=Target.objects.all(), required=True)
share_existing_data = serializers.BooleanField(default=False, required=False, write_only=True)

class Meta:
model = PersistentShare
fields = ('id', 'target', 'destination', 'user', 'created', 'share_existing_data')

def create(self, validated_data):
shared_existing_data = validated_data.pop('share_existing_data', None)
if shared_existing_data:
share_target_and_all_data(validated_data['destination'], validated_data['target'])
return super().create(validated_data)
13 changes: 1 addition & 12 deletions tom_targets/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
from rest_framework import serializers

from tom_common.serializers import GroupSerializer
from tom_targets.models import Target, TargetExtra, TargetName, TargetList, PersistentShare
from tom_targets.models import Target, TargetExtra, TargetName, TargetList
from tom_targets.validators import RequiredFieldsTogetherValidator
from tom_targets.fields import TargetFilteredPrimaryKeyRelatedField
from tom_dataproducts.sharing import get_sharing_destination_options


class TargetNameSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -181,12 +179,3 @@ def update(self, instance, validated_data):
instance.save()

return instance


class PersistentShareSerializer(serializers.ModelSerializer):
destination = serializers.ChoiceField(choices=get_sharing_destination_options(), required=True)
target = TargetFilteredPrimaryKeyRelatedField(queryset=Target.objects.all(), required=True)

class Meta:
model = PersistentShare
fields = ('id', 'target', 'destination', 'user', 'created')
61 changes: 60 additions & 1 deletion tom_targets/sharing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,66 @@
from django.core.exceptions import ImproperlyConfigured

from tom_targets.serializers import TargetSerializer
from tom_dataproducts.sharing import get_destination_target
from tom_targets.models import PersistentShare
from tom_dataproducts.sharing import check_for_share_safe_datums, share_data_with_tom, get_destination_target
from tom_dataproducts.models import ReducedDatum
from tom_dataproducts.alertstreams.hermes import publish_to_hermes, BuildHermesMessage


def share_target_and_all_data(share_destination, target):
"""
Given a sharing destination, shares the target and all its current dataproducts
with that destination. Will raise an Exception is any portion of sharing fails.
:param share_destination: String sharing destination from the DATA_SHARING setting
:param target: Target instance that should be shared with all its data
"""
if 'HERMES' in share_destination.upper():
hermes_topic = share_destination.split(':')[1]
destination = share_destination.split(':')[0]
filtered_reduced_datums = check_for_share_safe_datums(
destination, ReducedDatum.objects.filter(target=target), topic=hermes_topic)
sharing = getattr(settings, "DATA_SHARING", {})
message = BuildHermesMessage(title=f"Setting up continuous sharing for {target.name} from "
f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.",
authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None),
message=None,
topic=hermes_topic
)
response = publish_to_hermes(message, filtered_reduced_datums)
response.raise_for_status()
else:
response = share_target_with_tom(share_destination, {'target': target})
response.raise_for_status()
response = share_data_with_tom(share_destination, None, target_id=target.id)
response.raise_for_status()


def continuous_share_data(target, reduced_datums):
"""
Triggered when new ReducedDatums are created.
Shares those ReducedDatums to the sharing destination of any PersistentShares on the target.
:param target: Target instance that these reduced_datums belong to
:param reduced_datums: list of ReducedDatum instances to share
"""
persistentshares = PersistentShare.objects.filter(target=target)
for persistentshare in persistentshares:
share_destination = persistentshare.destination
reduced_datum_pks = [rd.pk for rd in reduced_datums]
if 'HERMES' in share_destination.upper():
hermes_topic = share_destination.split(':')[1]
destination = share_destination.split(':')[0]
filtered_reduced_datums = check_for_share_safe_datums(
destination, ReducedDatum.objects.filter(pk__in=reduced_datum_pks), topic=hermes_topic)
sharing = getattr(settings, "DATA_SHARING", {})
message = BuildHermesMessage(title=f"Updated data for {target.name} from "
f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.",
authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None),
message=None,
topic=hermes_topic
)
publish_to_hermes(message, filtered_reduced_datums)
else:
share_data_with_tom(share_destination, None, None, None, selected_data=reduced_datum_pks)


def share_target_with_tom(share_destination, form_data, target_lists=()):
Expand Down
2 changes: 1 addition & 1 deletion tom_targets/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.db.models.signals import post_save

from tom_dataproducts.models import ReducedDatum
from tom_dataproducts.sharing import continuous_share_data
from tom_targets.sharing import continuous_share_data


@receiver(post_save, sender=ReducedDatum)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
<form method="post" class="form" id='target-persistent-share-create-form'>
{% csrf_token %}
<div class="form-row" style="padding-inline:1rem">
<div class="col-sm-3">
<div class="col-sm-4">
{% bootstrap_field form.destination %}
</div>
<div class="col-sm-5">
{% if not target %}
<div class="col-sm-2">
{% bootstrap_field form.target %}
</div>
{% endif %}
<div class="col-sm-4 offset-sm-1" style="align-content:end;">
{% bootstrap_field form.share_existing_data %}
</div>
<div class="col-sm-1">
{% if target %}
<input type="button" class="btn btn-primary" value="Create" onclick="createPersistentShare('{% url 'targets:persistent-share' %}', '{% url 'targets:target-persistent-share-manage-table' target.pk %}')" style="position:absolute; bottom:1rem"/>
Expand Down Expand Up @@ -43,9 +48,11 @@
async function createPersistentShare(createUrl, updateUrl) {
var target_id = document.getElementById('id_target').value;
var destination = document.getElementById('id_destination').value;
var share_existing = document.getElementById('id_share_existing_data').checked;
var payload = {
"destination": destination,
"target": target_id
"target": target_id,
"share_existing_data": share_existing
}
const response = await fetch(createUrl, {
method: 'POST',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% load targets_extras %}
<table class="table table-hover">
<thead>
<tr>
Expand All @@ -15,7 +16,7 @@
<td>
<a href="{% url 'targets:detail' persistentshare.target.id %}" title="{{ persistentshare.target.name }}">{{ persistentshare.target.names|join:", " }}</a>
</td>
<td>{{ persistentshare.destination }}</td>
<td>{{ persistentshare.destination|bold_sharing_source }}</td>
<td>{{ persistentshare.user.username }}</td>
{% if can_delete %}
<td>
Expand Down
9 changes: 9 additions & 0 deletions tom_targets/templatetags/targets_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from astropy.coordinates import Angle, get_body, SkyCoord
from astropy.time import Time
from django import template
from django.utils.safestring import mark_safe
from django.conf import settings
from django.db.models import Q
from django.apps import apps
Expand All @@ -24,6 +25,14 @@
logger.setLevel(logging.DEBUG)


@register.filter(name='bold_sharing_source')
def bold_sharing_source(value):
pieces = value.split(':')
if len(pieces) > 1:
return mark_safe(f"<strong>{pieces[0]}</strong>:{':'.join(pieces[1:])}")
return value


@register.inclusion_tag('tom_targets/partials/recent_targets.html', takes_context=True)
def recent_targets(context, limit=10):
"""
Expand Down
2 changes: 1 addition & 1 deletion tom_targets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
)
from tom_targets.merge import (merge_error_message)
from tom_targets.models import Target, TargetList
from tom_targets.serializers import PersistentShareSerializer
from tom_targets.persistent_sharing_serializers import PersistentShareSerializer
from tom_targets.templatetags.targets_extras import target_merge_fields, persistent_share_table
from tom_targets.utils import import_targets, export_targets
from tom_dataproducts.alertstreams.hermes import BuildHermesMessage, preload_to_hermes
Expand Down
2 changes: 1 addition & 1 deletion tom_targets/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework import viewsets, permissions

from tom_targets.models import Target, PersistentShare
from tom_targets.serializers import PersistentShareSerializer
from tom_targets.persistent_sharing_serializers import PersistentShareSerializer


class PSModelPermission(permissions.DjangoModelPermissions):
Expand Down

0 comments on commit a62799a

Please sign in to comment.