diff --git a/gracedb/api.py b/gracedb/api.py index 286ef63177de4d689cf27c5ebb1b80d2760ea80e..d203986b0fb73363816c8ed846f6b636457b567a 100644 --- a/gracedb/api.py +++ b/gracedb/api.py @@ -1,26 +1,41 @@ from django.http import HttpResponse, HttpResponseNotFound +from django.core.urlresolvers import reverse + +import simplejson from gracedb.models import Event import os -def download(request, graceid, filename=None): - #response = HttpResponse(buildVOEvent(event), content_type="application/xml") - if not filename: - response = HttpResponseNotFound("Not Implemented.") - response.status_code = 404 +def download(request, graceid, filename=""): + # Do not filename to be None. That messes up later os.path.join + filename = filename or "" + try: event = Event.getByGraceid(graceid) - filepath = os.path.join(event.datadir(), filename) - if not os.path.exists(filepath): - response = HttpResponseNotFound("File does not exist") - elif not os.access(filepath, os.R_OK): - response = HttpResponseNotFound("File not readable") - else: - response = HttpResponse(open(filepath, "r"), content_type="application/octet-stream") - response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(filename) except Event.DoesNotExist: - response = HttpResponseNotFound("Event does not exist") + return HttpResponseNotFound("Event not found") + + filepath = os.path.join(event.datadir(), filename) + + if not os.path.exists(filepath): + response = HttpResponseNotFound("File does not exist") + elif not os.access(filepath, os.R_OK): + response = HttpResponseNotFound("File not readable") + elif not filename: + # Get list of files w/urls. + rv = {} + for dirname, dirnames, filenames in os.walk(filepath): + dirname = dirname[len(filepath):] # cut off base event dir path + for filename in filenames: + # relative path from root of event data dir + filename = os.path.join(dirname, filename) + rv[filename] = reverse(download, args=[graceid, filename]) + response = HttpResponse(simplejson.dumps(rv), content_type="application/json") + else: + # get an actual file. + response = HttpResponse(open(filepath, "r"), content_type="application/octet-stream") + response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(filename) return response diff --git a/gracedb/urls.py b/gracedb/urls.py index 7a2046701d5ad3322e183e7ddb93590143cd486f..3505e42abd1ab3b461832aa1b58123d40051fdf4 100644 --- a/gracedb/urls.py +++ b/gracedb/urls.py @@ -3,6 +3,8 @@ from django.conf.urls.defaults import * #import django.views.generic.list_detail +from gracedb.api import download + urlpatterns = patterns('gracedb.views', url (r'^$', 'index', name="home"), url (r'^create/$', 'create', name="create"), @@ -10,6 +12,8 @@ urlpatterns = patterns('gracedb.views', url (r'^view/(?P<graceid>[\w\d]+)', 'view', name="view"), url (r'^voevent/(?P<graceid>[\w\d]+)', 'voevent', name="voevent"), url (r'^skyalert/(?P<graceid>[\w\d]+)', 'skyalert', name="skyalert"), + url (r'^(?P<graceid>[\w\d]+)$', 'view', name="view2"), + url (r'^(?P<graceid>[\w\d]+)/files/(?P<filename>.+)$', download, name="file"), # (r'^view/(?P<uid>[\w\d]+)', 'view'), diff --git a/gracedb/views.py b/gracedb/views.py index 99cfdf81249f0178a47d836ca8b9f2a834c4df23..3e840dd805e3498d883f25ec1907d1fb2506063c 100644 --- a/gracedb/views.py +++ b/gracedb/views.py @@ -1,6 +1,6 @@ from django.http import HttpResponse -from django.http import HttpResponseRedirect, HttpResponseNotFound, Http404 +from django.http import HttpResponseRedirect, HttpResponseNotFound, HttpResponseBadRequest, Http404 from django.template import RequestContext from django.core.urlresolvers import reverse, get_script_prefix from django.shortcuts import render_to_response @@ -504,7 +504,17 @@ def cli_search(request): if form.is_valid(): query = form.cleaned_data['query'] objects = Event.objects.filter(query).distinct() - # Assemble the output... should be able to choose format. + + if 'ligolw' in request.POST or 'ligolw' in request.GET: + from glue.ligolw import utils + if objects.count() > 1000: + return HttpResponseBadRequest("Too many events.") + xmldoc = assembleLigoLw(objects) + response = HttpResponse(mimetype='application/xml') + response['Content-Disposition'] = 'attachment; filename=gracedb-query.xml' + utils.write_fileobj(xmldoc, response) + return response + accessFun = { "labels" : lambda e: \ ",".join([labelling.label.name for labelling in e.labelling_set.all()]), @@ -539,6 +549,25 @@ def cli_search(request): response.write(msg) return response + +def assembleLigoLw(objects): + from glue.ligolw import ligolw + # lsctables MUST be loaded before utils. + from glue.ligolw import lsctables + from glue.ligolw import utils + from glue.ligolw.utils import ligolw_add + + xmldoc = ligolw.Document() + for obj in objects: + fname = os.path.join(GRACEDB_DATA_DIR, obj.graceid(), "private", "coinc.xml") + utils.load_filename(fname, xmldoc=xmldoc) + + ligolw_add.reassign_ids(xmldoc) + ligolw_add.merge_ligolws(xmldoc) + ligolw_add.merge_compatible_tables(xmldoc) + return xmldoc + + def search(request, format=""): assert request.ligouser # XXX DO NOT HARDCODE THIS @@ -602,25 +631,12 @@ def search(request, format=""): return jqgridResponse(request, objects) elif 'ligolw' in request.POST or 'ligolw' in request.GET: + from glue.ligolw import utils if objects.count() > 1000: # XXX Make this -- Better. return HttpResponse("Sorry -- no more than 1000 events currently allowed.") - from glue.ligolw import ligolw - # lsctables MUST be loaded before utils. - from glue.ligolw import lsctables - from glue.ligolw import utils - from glue.ligolw.utils import ligolw_add - from settings import GRACEDB_DATA_DIR - - xmldoc = ligolw.Document() - for obj in objects: - fname = os.path.join(GRACEDB_DATA_DIR, obj.graceid(), "private", "coinc.xml") - utils.load_filename(fname, xmldoc=xmldoc) - - ligolw_add.reassign_ids(xmldoc) - ligolw_add.merge_ligolws(xmldoc) - ligolw_add.merge_compatible_tables(xmldoc) + xmldoc = assembleLigoLw(objects) response = HttpResponse(mimetype='application/xml') response['Content-Disposition'] = 'attachment; filename=gracedb-query.xml'