Skip to content
Snippets Groups Projects
Commit 44df0e02 authored by Branson Stephens's avatar Branson Stephens Committed by Brian Moe
Browse files

initial slot implementation (models and api)

parent 5ca8ee41
No related branches found
No related tags found
No related merge requests found
from models import Event, EventLog, User, Group from models import Event, EventLog, User, Group
from models import Label, Labelling from models import Label, Labelling, Slot
from django.contrib import admin from django.contrib import admin
class EventAdmin(admin.ModelAdmin): class EventAdmin(admin.ModelAdmin):
...@@ -30,10 +30,13 @@ class LabellingAdmin(admin.ModelAdmin): ...@@ -30,10 +30,13 @@ class LabellingAdmin(admin.ModelAdmin):
list_display = [ 'event', 'label', 'creator' ] list_display = [ 'event', 'label', 'creator' ]
search_fields = [ 'event__id', 'label__name', 'creator__name' ] search_fields = [ 'event__id', 'label__name', 'creator__name' ]
class SlotAdmin(admin.ModelAdmin):
list_display = [ 'event', 'name', 'value' ]
admin.site.register(Event, EventAdmin) admin.site.register(Event, EventAdmin)
admin.site.register(EventLog, EventLogAdmin) admin.site.register(EventLog, EventLogAdmin)
admin.site.register(User, UserAdmin) admin.site.register(User, UserAdmin)
admin.site.register(Group) admin.site.register(Group)
admin.site.register(Label, LabelAdmin) admin.site.register(Label, LabelAdmin)
admin.site.register(Labelling, LabellingAdmin) admin.site.register(Labelling, LabellingAdmin)
admin.site.register(Slot, SlotAdmin)
...@@ -8,7 +8,7 @@ from django.conf import settings ...@@ -8,7 +8,7 @@ from django.conf import settings
import json import json
from gracedb.models import Event, Group, EventLog from gracedb.models import Event, Group, EventLog, Slot
from gracedb.views import create_label from gracedb.views import create_label
from translator import handle_uploaded_data from translator import handle_uploaded_data
...@@ -574,12 +574,17 @@ class GracedbRoot(APIView): ...@@ -574,12 +574,17 @@ class GracedbRoot(APIView):
labels = labels.replace("G1200", "{graceid}") labels = labels.replace("G1200", "{graceid}")
labels = labels.replace("thelabel", "{label}") labels = labels.replace("thelabel", "{label}")
slot = reverse("slot", args=["G1200", "slotname"], request=request)
slot = slot.replace("G1200", "{graceid}")
slot = slot.replace("slotname", "{slotname}")
templates = { templates = {
"event-detail-template" : detail, "event-detail-template" : detail,
"event-log-template" : log, "event-log-template" : log,
"event-label-template" : labels, "event-label-template" : labels,
"files-template" : files, "files-template" : files,
"filemeta-template" : filemeta, "filemeta-template" : filemeta,
"slot-template" : slot,
} }
return Response({ return Response({
...@@ -793,3 +798,80 @@ class FileMeta(APIView): ...@@ -793,3 +798,80 @@ class FileMeta(APIView):
authentication_classes = (LigoAuthentication,) authentication_classes = (LigoAuthentication,)
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
pass pass
#==================================================================
# Slots
class EventSlot(APIView):
"""A slot associated with an event.
"""
# Get the value of a slot. This will be a filename.
def get(self, request, graceid, slotname):
try:
event = Event.getByGraceid(graceid)
except Event.DoesNotExist:
# XXX Real error message.
return Response("Event does not exist.",
status=status.HTTP_404_NOT_FOUND)
try:
slot = Slot.objects.filter(event=event).filter(name=slotname)[0]
except Slot.DoesNotExist:
# Okay, no slot yet. Probably want an error message.
# Try looking for files that contain the slot name.
return Response("No slot. Search based on slotname not implemented yet.",
status=status.HTTP_404_NOT_FOUND)
filename = slot.value
dirPrefix = settings.GRACEDB_DATA_DIR
eventDir = os.path.join(dirPrefix, event.graceid())
filename = os.path.join(eventDir, "private", filename)
rv = {}
rv['filename'] = filename
return Response(rv)
# Create a slot. The slot's value will be a filename.
# This can refer to the name of a file uploaded when the slot
# is created, or to the name of an already existing file. The
# latter will be assumed if there is no uploaded file in the
# request object.
def put(self, request, graceid, slotname):
try:
event = Event.getByGraceid(graceid)
except Event.DoesNotExist:
# XXX Real error message.
return Response("Event does not exist.",
status=status.HTTP_404_NOT_FOUND)
dirPrefix = settings.GRACEDB_DATA_DIR
eventDir = os.path.join(dirPrefix, event.graceid())
# XXX handle duplicate file names.
try:
f = request.FILES['slotFile']
filename = f.name
uploadDestination = os.path.join(eventDir, "private", filename)
fdest = open(uploadDestination, 'w')
# Save uploaded file into user private area.
shutil.copyfileobj(f, fdest)
fdest.close()
except:
# No file, huh?
# Maybe the body contained the name of an already existing file.
filename = request.DATA.get('filename')
# Interestingly, the None object seems to be converted to a string
# when encoded in the HTTP request body. Hence the 'None' string
# below. If somebody intentionally named a file 'None', then
# they deserve to get this error message.
if filename=='' or filename=='None' or filename=None:
return Response("Please submit a filename or upload a file.",
status=status.HTTP_400_BAD_REQUEST)
# Check for existence of the file.
filePath = os.path.join(eventDir, "private", filename)
if not os.path.exists(filePath):
return Response("No slot created because file does not exist and no file uploaded",
status=status.HTTP_404_NOT_FOUND)
# Create the slot.
slot = Slot(event=event,name=slotname,value=filename)
slot.save()
return Response("Slot created.",status=status.HTTP_201_CREATED)
...@@ -206,7 +206,6 @@ class Approval(models.Model): ...@@ -206,7 +206,6 @@ class Approval(models.Model):
approvedEvent = models.ForeignKey(Event, null=False) approvedEvent = models.ForeignKey(Event, null=False)
approvingCollaboration = models.CharField(max_length=1, choices=COLLABORATION_CHOICES) approvingCollaboration = models.CharField(max_length=1, choices=COLLABORATION_CHOICES)
## Analysis Specific Attributes. ## Analysis Specific Attributes.
class CoincInspiralEvent(Event): class CoincInspiralEvent(Event):
...@@ -239,3 +238,11 @@ class MultiBurstEvent(Event): ...@@ -239,3 +238,11 @@ class MultiBurstEvent(Event):
ligo_angle = models.FloatField(null=True) ligo_angle = models.FloatField(null=True)
ligo_angle_sig = models.FloatField(null=True) ligo_angle_sig = models.FloatField(null=True)
## Slots (user-defined event attributes)
class Slot(models.Model):
"""Slot Model"""
# Does the slot need to have a submitter column?
event = models.ForeignKey(Event)
name = models.CharField(max_length=100)
value = models.CharField(max_length=100)
...@@ -5,6 +5,7 @@ from django.conf.urls.defaults import patterns, url ...@@ -5,6 +5,7 @@ from django.conf.urls.defaults import patterns, url
from gracedb.api import GracedbRoot from gracedb.api import GracedbRoot
from gracedb.api import EventList, EventDetail from gracedb.api import EventList, EventDetail
from gracedb.api import EventLogList, EventLogDetail from gracedb.api import EventLogList, EventLogDetail
from gracedb.api import EventSlot
from gracedb.api import Files, FileMeta from gracedb.api import Files, FileMeta
from gracedb.api import EventNeighbors, EventLabel from gracedb.api import EventNeighbors, EventLabel
...@@ -40,7 +41,9 @@ urlpatterns = patterns('gracedb.api', ...@@ -40,7 +41,9 @@ urlpatterns = patterns('gracedb.api',
EventLabel.as_view(), name="labels"), EventLabel.as_view(), name="labels"),
# Event Slots # Event Slots
# events/{graceid}/slots/[{slotid}] # events/{graceid}/slot/[{slotname}]
url (r'^events/(?P<graceid>[GEHT]\d+)/slot/(?P<slotname>.+)?$',
EventSlot.as_view(), name="slot"),
# Event Neighbors # Event Neighbors
# events/{graceid}/neighbors/[?delta=(N|(N,N))] # events/{graceid}/neighbors/[?delta=(N|(N,N))]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment