Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • alexander.pace/server
  • geoffrey.mo/gracedb-server
  • deep.chatterjee/gracedb-server
  • cody.messick/server
  • sushant.sharma-chaudhary/server
  • michael-coughlin/server
  • daniel.wysocki/gracedb-server
  • roberto.depietri/gracedb
  • philippe.grassia/gracedb
  • tri.nguyen/gracedb
  • jonah-kanner/gracedb
  • brandon.piotrzkowski/gracedb
  • joseph-areeda/gracedb
  • duncanmmacleod/gracedb
  • thomas.downes/gracedb
  • tanner.prestegard/gracedb
  • leo-singer/gracedb
  • computing/gracedb/server
18 results
Show changes
Commits on Source (7)
Showing
with 206 additions and 28 deletions
......@@ -58,6 +58,11 @@ before_script:
libssl-dev
libxml2-dev
swig
pkg-config
libpng-dev
libfreetype6-dev
libmariadb-dev-compat
libxslt-dev
${PYTHON}-pip
# install everything else from pip
- ${PYTHON} -m pip install -r requirements.txt
......
......@@ -19,6 +19,11 @@ RUN apt-get update && \
libldap2-dev \
libsasl2-dev \
libxml2-dev \
pkg-config \
libpng-dev \
libfreetype6-dev \
libmariadb-dev-compat \
libxslt-dev \
libsqlite3-dev \
ligo-ca-certs \
mariadb-client \
......
from django.conf.urls import url, include
from django.urls import path
from django.views.decorators.cache import never_cache
from .views import *
......@@ -6,9 +7,8 @@ from .settings import SUPEREVENT_LOOKUP_REGEX
# URL kwarg for superevent detail and nested pages
SUPEREVENT_DETAIL_ROOT = '(?P<{lookup_url_kwarg}>{regex})'.format(
lookup_url_kwarg=SupereventViewSet.lookup_url_kwarg,
regex=SUPEREVENT_LOOKUP_REGEX)
SUPEREVENT_DETAIL_ROOT = '<{lookup_url_kwarg}>'.format(
lookup_url_kwarg=SupereventViewSet.lookup_url_kwarg)
# URLs which are nested below a single superevent detail
# These are included under a superevent's id URL prefix (see below)
......@@ -113,6 +113,6 @@ urlpatterns = [
name='superevent-list'),
# All sub-URLs for a single superevent
url(r'^{superevent_id}/'.format(superevent_id=SUPEREVENT_DETAIL_ROOT),
path('{superevent_id}/'.format(superevent_id=SUPEREVENT_DETAIL_ROOT),
include(suburlpatterns)),
]
......@@ -23,6 +23,7 @@ from superevents.models import Superevent, Log, Signoff, VOEvent
from superevents.utils import remove_tag_from_log, \
remove_event_from_superevent, remove_label_from_superevent, \
confirm_superevent_as_gw, get_superevent_by_date_id_or_404, \
get_superevent_by_sid_or_gwid_or_404, \
expose_superevent, hide_superevent, delete_signoff
from .filters import SupereventSearchFilter, SupereventOrderingFilter
from .paginators import CustomSupereventPagination
......@@ -76,6 +77,7 @@ class SupereventViewSet(SafeCreateMixin, InheritDefaultPermissionsMixin,
ordering_fields = ('created', 't_0', 't_start', 't_end',
'preferred_event__id', 't_0_date', 'is_gw', 'base_date_number',
'gw_date_number', 'category',
'default_superevent_id',
'time_coinc_far','space_coinc_far','em_type')
def get_serializer_class(self):
......@@ -88,9 +90,11 @@ class SupereventViewSet(SafeCreateMixin, InheritDefaultPermissionsMixin,
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
superevent_id = self.kwargs.get(self.lookup_url_kwarg)
#raise ValueError(self.lookup_url_kwarg, queryset)
# Get superevent by id
obj = get_superevent_by_date_id_or_404(superevent_id, queryset)
#obj = get_superevent_by_date_id_or_404(superevent_id, queryset)
obj = get_superevent_by_sid_or_gwid_or_404(superevent_id, queryset)
# Check permissions
self.check_object_permissions(self.request, obj)
......@@ -103,9 +107,12 @@ class SupereventViewSet(SafeCreateMixin, InheritDefaultPermissionsMixin,
# Get superevent
superevent = self.get_object()
# Get gw_id from request, if it exists:
gw_id = request.data.get('gw_id')
# If already a GW, return an error
if not superevent.is_gw:
confirm_superevent_as_gw(superevent, self.request.user)
confirm_superevent_as_gw(superevent, self.request.user, gw_id)
else:
return Response('Superevent is already confirmed as a GW',
status=status.HTTP_400_BAD_REQUEST)
......
......@@ -23,7 +23,7 @@ def remove_pipelines(apps, schema_editor):
Pipeline = apps.get_model('events', 'Pipeline')
# Delete pipelines
Pipeline.objects.filter(name__in=SEARCH_PIPELINES).delete()
Pipeline.objects.filter(name__in=NEW_GRB_PIPELINES).delete()
class Migration(migrations.Migration):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-10-25 19:16
from __future__ import unicode_literals
from django.db import migrations
# Creates initial search pipeline instances
# List of search pipeline names
NEW_PIPELINES = [
'MBTA',
]
def add_pipelines(apps, schema_editor):
Pipeline = apps.get_model('events', 'Pipeline')
# Create pipelines
for pipeline_name in NEW_PIPELINES:
pipeline, created = Pipeline.objects.get_or_create(name=pipeline_name)
def remove_pipelines(apps, schema_editor):
Pipeline = apps.get_model('events', 'Pipeline')
# Delete pipelines
Pipeline.objects.filter(name__in=NEW_PIPELINES).delete()
class Migration(migrations.Migration):
dependencies = [
('events', '0050_add_ew_voevent_type'),
]
operations = [
migrations.RunPython(add_pipelines, remove_pipelines),
]
......@@ -71,7 +71,7 @@ def handle_uploaded_data(event, datafilename,
pipeline = event.pipeline.name
if pipeline in [ 'gstlal', 'spiir', 'pycbc', ] or (pipeline=='MBTAOnline' and '.xml' in datafilename):
if pipeline in [ 'gstlal', 'spiir', 'pycbc', ] or (pipeline in ['MBTA', 'MBTAOnline'] and '.xml' in datafilename):
log_comment = "Log File Created"
# Wildly speculative wrt HM
......
......@@ -53,7 +53,7 @@ def _createEventFromForm(request, form):
else:
search = None
# Create Event
if pipeline.name in ['gstlal', 'spiir', 'MBTAOnline', 'pycbc',]:
if pipeline.name in ['gstlal', 'spiir', 'MBTAOnline', 'MBTA', 'pycbc',]:
event = CoincInspiralEvent()
elif pipeline.name in ['Fermi', 'Swift', 'SNEWS','INTEGRAL','AGILE']:
event = GrbEvent()
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-11-01 16:19
from __future__ import unicode_literals
from django.db import migrations
# populates "MBTA" uploaders from "MBTAOnline"
def add_permissions(apps, schema_editor):
User = apps.get_model('auth', 'User')
Permission = apps.get_model('auth', 'Permission')
UserObjectPermission = apps.get_model('guardian', 'UserObjectPermission')
Pipeline = apps.get_model('events', 'Pipeline')
ContentType = apps.get_model('contenttypes', 'ContentType')
perm = Permission.objects.get(codename='populate_pipeline')
ctype = ContentType.objects.get_for_model(Pipeline)
mbtaonline = Pipeline.objects.get(name='MBTAOnline')
mbta = Pipeline.objects.get(name='MBTA')
perms = UserObjectPermission.objects.filter(object_pk=mbtaonline.pk,
permission=perm,
content_type=ctype)
mbta_users = [p.user for p in perms]
for u in mbta_users:
uop, uop_created = UserObjectPermission.objects.get_or_create(
user=u, permission=perm, content_type=ctype,
object_pk=mbta.id)
def remove_permissions(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('guardian', '0011_auto_20200303_0151'),
('events', '0051_add_MBTA_pipeline'),
]
operations = [
migrations.RunPython(add_permissions, remove_permissions),
]
# Generated by Django 2.2.10 on 2020-08-21 01:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('superevents', '0010_superevent_space_coinc_far'),
]
operations = [
migrations.AddField(
model_name='superevent',
name='gw_id',
field=models.CharField(blank=True, max_length=25, null=True, unique=True),
),
]
# Generated by Django 2.2.10 on 2020-08-31 20:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('superevents', '0011_superevent_gw_id'),
]
operations = [
migrations.AddField(
model_name='superevent',
name='default_superevent_id',
field=models.CharField(editable=False, max_length=32, null=True),
),
migrations.AddField(
model_name='superevent',
name='superevent_id',
field=models.CharField(editable=False, max_length=32, null=True),
),
]
......@@ -30,6 +30,10 @@ from core.utils import int_to_letters, letters_to_int
from events.models import Event, SignoffBase, VOEventBase, EMObservationBase, \
EMFootprintBase
# AEP experimental: try computedfields stuff:
# https://django-computedfields.readthedocs.io/en/
from computedfields.models import ComputedFieldsModel, computed
# Other setup
UserModel = get_user_model()
logger = logging.getLogger(__name__)
......@@ -41,7 +45,7 @@ SUPEREVENT_DATE_END = datetime.datetime(2080, 1, 1, 0, 0, 0, 0, pytz.utc)
@python_2_unicode_compatible
class Superevent(CleanSaveModel, AutoIncrementModel):
class Superevent(CleanSaveModel, AutoIncrementModel, ComputedFieldsModel):
"""
Superevent date-based IDs:
Initially, a superevent has an ID like 'S180725a'
......@@ -112,6 +116,9 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
gw_letter_suffix = models.CharField(max_length=10, null=True,
editable=False)
# Cannibalizing gw_id field, putting into DB as a user-defined parameter.
gw_id = models.CharField(max_length=25, blank=True, null=True, unique=True)
# Booleans
is_gw = models.BooleanField(default=False)
# Because there are multiple actions/permissions involved with exposing a
......@@ -256,7 +263,7 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
def is_mdc(self):
return self.category == self.SUPEREVENT_CATEGORY_MDC
def confirm_as_gw(self):
def confirm_as_gw(self, gw_id=None):
"""
Sets is_gw to True, calculates the gw_date_number in the database, and
the gw_letter_suffix afterward.
......@@ -265,6 +272,10 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
self.is_gw = True
# Prep for custom autoincrement update
# Go through all the same steps for constructing a GW number. This will
# be the default, and will serve as a placeholder GW id, if nothing
# else is specified.
meta = self._meta
constraint_fields = ['t_0_date', 'is_gw', 'category']
......@@ -274,8 +285,15 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
# Update gw_letter_suffix from gw_date_number
self.gw_letter_suffix = int_to_letters(self.gw_date_number).upper()
# Update gw_id. If the user supplied one, use that. If not, then just
# put in the "default" (old) gw_id format.
if gw_id:
self.gw_id = gw_id
else:
self.gw_id = self.default_gw_id
# Save the fields which have changed
self.save(update_fields=['is_gw', 'gw_letter_suffix'])
self.save(update_fields=['is_gw', 'gw_letter_suffix', 'gw_id', 'superevent_id'])
def get_groups_with_groupobjectpermissions(self):
gops = self.supereventgroupobjectpermission_set.all()
......@@ -384,14 +402,15 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
nodes.append(hdf.read())
return os.path.join(settings.GRACEDB_DATA_DIR, *nodes)
@property
@computed(models.CharField(max_length=32, null=True), depends=[['self', ['default_superevent_id', 'gw_id']]])
def superevent_id(self):
if self.is_gw:
return self.gw_id
else:
return self.default_superevent_id
@property
@computed(models.CharField(max_length=32, null=True), depends=[['self', ['category', 'base_date_number', 'base_letter_suffix']]])
def default_superevent_id(self):
id_prefix = self.DEFAULT_ID_PREFIX
letter_suffix = self.base_letter_suffix
......@@ -405,11 +424,11 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
self.t_0_date.strftime(self.DATE_STR_FMT) + self.base_letter_suffix
@property
def gw_id(self):
def default_gw_id(self):
if not self.is_gw:
return None
# Prepend category prefix (if not production)
# Prepend category prefix (if not production)
pre_prefix = ""
if self.category != self.SUPEREVENT_CATEGORY_PRODUCTION:
pre_prefix = self.category
......
from django.conf.urls import url, include
from django.urls import path
from .models import Superevent
from . import views
......@@ -20,21 +21,21 @@ suburlpatterns = [
# convenience of users who may be accustomed to the legacy event URL patterns
legacy_urlpatterns = [
# Legacy URLs for superevent detail view
url(r'^(?P<superevent_id>{regex})/$'.format(
regex=Superevent.ID_REGEX), views.SupereventDetailView.as_view(),
path('<str:superevent_id>/',
views.SupereventDetailView.as_view(),
name="legacyview1"),
url(r'^view/(?P<superevent_id>{regex})/$'.format(
regex=Superevent.ID_REGEX), views.SupereventDetailView.as_view(),
path('view/<str:superevent_id>/',
views.SupereventDetailView.as_view(),
name="legacyview2"),
]
# Full urlpatterns: legacy urls plus suburlpatterns nested under
# superevent_id
urlpatterns = legacy_urlpatterns + [
url(r'^(?P<superevent_id>{regex})/'.format(regex=Superevent.ID_REGEX),
path('<str:superevent_id>/',
include(suburlpatterns)),
# View of all candidates
url(r'^public/O3/$', views.SupereventPublic.as_view(),
path('public/O3/', views.SupereventPublic.as_view(),
name="public-alerts-O3"),
]
......@@ -2,6 +2,7 @@ import logging
import os
from django.conf import settings
from django.db.models import Q
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import Group as DjangoGroup
......@@ -529,15 +530,33 @@ def get_superevent_by_date_id_or_404(superevent_id, queryset=None):
return get_object_or_404(queryset, **filter_kwargs)
def get_superevent_by_sid_or_gwid_or_404(superevent_id, queryset=None):
def confirm_superevent_as_gw(superevent, user, add_log_message=True,
if queryset is None:
queryset = Superevent.objects.all()
# Filter superevent_id, which is equal to the gw_id if is_gw is True,
# and equal to the default_superevent_id otherwise.
sid_filt = Q (superevent_id = superevent_id)
# Also filter by the default_superevent_id, in the case that there's a
# mixed query between gw's and non-gw's. This is an attempt to reproduce
# the previous behavior.
dsid_filt = Q(default_superevent_id = superevent_id)
return get_object_or_404(queryset, sid_filt | dsid_filt)
def confirm_superevent_as_gw(superevent, user, gw_id, add_log_message=True,
issue_alert=True):
# Save old ID temporarily
old_id = superevent.superevent_id
# Update superevent (mark as a GW, construct new ID, etc.)
superevent.confirm_as_gw()
superevent.confirm_as_gw(gw_id)
# Create log message
gw_log = None
......
......@@ -17,7 +17,8 @@ from ligoauth.decorators import public_if_public_access_allowed
from .mixins import ExposeHideMixin, OperatorSignoffMixin, \
AdvocateSignoffMixin, PermissionsFilterMixin, ConfirmGwFormMixin
from .models import Superevent, VOEvent
from .utils import get_superevent_by_date_id_or_404
from .utils import get_superevent_by_date_id_or_404, \
get_superevent_by_sid_or_gwid_or_404
# Set up logger
......@@ -49,7 +50,7 @@ class SupereventDetailView(OperatorSignoffMixin, AdvocateSignoffMixin,
if queryset is None:
queryset = self.get_queryset()
superevent_id = self.kwargs.get('superevent_id')
obj = get_superevent_by_date_id_or_404(superevent_id, queryset)
obj = get_superevent_by_sid_or_gwid_or_404(superevent_id, queryset)
return obj
def get_context_data(self, **kwargs):
......
ConcurrentLogHandler==0.9.1
Django==2.2.10
django-computedfields==0.1.3
django-debug-toolbar==1.9.1
django-extensions==2.2.9
django-guardian==2.2.0
......@@ -56,5 +57,3 @@ pyasn1==0.3.6
pyasn1-modules==0.1.5
# retry bandaid for efs errors:
retry==0.9.2
# pinning setuptools for compatibility with supervisor 3.3.0
setuptools==46.1.1