def queue_list(request): """Get a list of Queues.""" status = request.GET.get('status') sort = request.GET.get('sort') page = int(request.GET.get('page', 1)) count = int(request.GET.get('count', 10)) queues = QueueEntry.objects.all().order_by('queue_position') queues = queues.filter(status=status) if status else queues queues = queues.order_by('bytes') if sort == 'size' else queues paginator = Paginator(queues, count) try: atomFeed = makeObjectFeed( paginator=paginator, objectToXMLFunction=queueEntryToXML, feedId=request.path[1:], title='Queue Entry Feed', webRoot='http://{0}'.format(request.META['HTTP_HOST']), idAttr='ark', nameAttr='ark', request=request, page=page, author=APP_AUTHOR) except EmptyPage: return HttpResponseBadRequest('Page does not exist.') feedText = etree.tostring(atomFeed, pretty_print=True) feedText = '<?xml version="1.0"?>\n{0}'.format(feedText) return HttpResponse(feedText, content_type='application/atom+xml')
def app_agent(request, identifier=None): """ Return a representation of a given agent """ request_body = get_request_body(request) # full paginated ATOM PUB FEED if not identifier: # we just want to look at it. if request.method == 'GET': requestString = request.path if len(request.GET): requestString = "%s?%s" % ( request.path, request.GET.urlencode() ) page = request.GET.get('page') else: page = 1 try: atomFeed = makeObjectFeed( paginator=Paginator(Agent.objects.all(), 20), objectToXMLFunction=objectToAgentXML, feedId=requestString[1:], webRoot="http://%s" % request.META.get('HTTP_HOST'), title="Agent Entry Feed", idAttr="agent_identifier", nameAttr="agent_name", request=request, page=page, ) except EmptyPage: return HttpResponse( "That page doesn't exist.\n", status=400, content_type='text/plain' ) atomFeedText = XML_HEADER % etree.tostring( atomFeed, pretty_print=True ) resp = HttpResponse(atomFeedText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'POST': entry_etree = etree.XML(request_body) try: agent_object = premisAgentXMLgetObject(entry_etree) except Exception: pass else: return HttpResponse( "Conflict with already-existing resource.\n", status=409, content_type="text/plain" ) try: agent_object = premisAgentXMLToObject(request_body) except etree.XMLSyntaxError: return HttpResponse( "Invalid XML in request body.\n", status=400, content_type="text/plain" ) try: agent_object.save() except IntegrityError: return HttpResponse( "Conflict with already-existing resource.\n", status=409, content_type="text/plain" ) returnXML = objectToAgentXML(agent_object) returnEntry = wrapAtom( returnXML, agent_object.agent_name, agent_object.agent_name ) entryText = XML_HEADER % etree.tostring( returnEntry, pretty_print=True ) resp = HttpResponse(entryText, content_type="application/atom+xml") resp.status_code = 201 resp['Location'] = agent_object.agent_identifier + '/' return resp # This is here so clients can ping this endpoint to # test for availability. See codalib's waitForURL func # in util.py. elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml") else: return HttpResponseBadRequest("Invalid method for this URL.") # identifier supplied, will be a GET or DELETE else: try: agent_object = get_object_or_404( Agent, agent_identifier=identifier ) except Exception: return HttpResponseNotFound( "There is no agent for identifier \'%s\'.\n" % identifier ) if request.method == 'DELETE': agent_object.delete() resp = HttpResponse("Deleted %s.\n" % identifier) resp.status_code = 200 return resp elif request.method == 'PUT': agent_object = premisAgentXMLToObject(request_body) agent_object.save() returnXML = objectToAgentXML(agent_object) returnEntry = wrapAtom( returnXML, agent_object.agent_name, agent_object.agent_name ) entryText = XML_HEADER % etree.tostring( returnEntry, pretty_print=True ) resp = HttpResponse(entryText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'GET': returnXML = objectToAgentXML(agent_object) althref = request.build_absolute_uri( reverse('agent-detail', args=(identifier, )) ) returnEntry = wrapAtom( returnXML, agent_object.agent_name, agent_object.agent_name, alt=althref, author=CODALIB_APP_AUTHOR["name"], author_uri=CODALIB_APP_AUTHOR["uri"] ) entryText = XML_HEADER % etree.tostring( returnEntry, pretty_print=True ) resp = HttpResponse(entryText, content_type="application/atom+xml") resp.status_code = 200 return resp # This is here so clients can ping this endpoint to # test for availability. See codalib's waitForURL func # in util.py. elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml")
def app_event(request, identifier=None): """ This method handles the ATOMpub protocol for events """ DATE_FORMAT = "%m/%d/%Y" returnEvent = None request_body = get_request_body(request) # are we POSTing a new identifier here? if request.method == 'POST' and not identifier: xmlDoc = etree.fromstring(request_body) try: newEvent = addObjectFromXML( xmlDoc, premisEventXMLToObject, "event", "event_identifier", EVENT_UPDATE_TRANSLATION_DICT ) except DuplicateEventError as e: return HttpResponse( "An event with id='{}' exists.".format(e.message), status=409, content_type="text/plain" ) if type(newEvent) == HttpResponse: return newEvent eventObjectXML = objectToPremisEventXML(newEvent) atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], newEvent.event_identifier ), title=newEvent.event_identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 201 resp['Location'] = 'http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], newEvent.event_identifier ) return resp # if not, return a feed elif request.method == 'GET' and not identifier: # negotiate the details of our feed here events = Event.objects.all() # parse the request get variables and filter the search if request.GET.get('start_date'): start_date = datetime.strptime( request.GET.get('start_date'), DATE_FORMAT ) events = events.filter(event_date_time__gte=start_date) if request.GET.get('end_date'): end_date = datetime.strptime( request.GET.get('end_date'), DATE_FORMAT ) events = events.filter(event_date_time__lte=end_date) if request.GET.get('link_object_id'): linking_object_id = request.GET.get('link_object_id') events = events.filter( linking_objects__object_identifier=linking_object_id ) if request.GET.get('outcome'): outcome = request.GET.get('outcome') events = events.filter(event_outcome=outcome) if request.GET.get('type'): event_type = request.GET.get('type') events = events.filter(event_type=event_type) if request.GET.get('orderby'): order_field = request.GET.get('orderby') unordered_events = events if request.GET.get('orderdir'): if request.GET.get('orderdir') == 'descending': events = events.order_by(order_field).reverse() else: events = events.order_by(order_field) else: events = events.order_by(order_field) try: # Trigger QuerySet eval. if events: pass except FieldError: # If order_by fails, revert to natural order. events = unordered_events if request.GET: page = int(request.GET['page']) if request.GET.get('page') else 1 else: page = 1 try: atomFeed = makeObjectFeed( paginator=Paginator(events, EVENT_SEARCH_PER_PAGE), objectToXMLFunction=objectToPremisEventXML, feedId=request.path[1:], webRoot='http://%s' % request.META.get('HTTP_HOST'), title="Event Entry Feed", idAttr="event_identifier", nameAttr="event_identifier", dateAttr="event_date_time", request=request, page=page, ) except EmptyPage: return HttpResponse( "That page does not exist.\n", status=400, content_type='text/plain' ) atomFeedText = XML_HEADER % etree.tostring(atomFeed, pretty_print=True) resp = HttpResponse(atomFeedText, content_type="application/atom+xml") resp.status_code = 200 return resp # updating an existing record elif request.method == 'PUT' and identifier: try: xmlDoc = etree.fromstring(request_body) xmlDoc = xmlDoc.xpath('//premis:event', namespaces=PREMIS_NSMAP)[0] except etree.LxmlError: return HttpResponse( 'Invalid request XML.', content_type='text/plain', status=400 ) except IndexError: return HttpResponse( 'Event element missing in request body.', content_type='text/plain', status=400 ) event = Event.objects.get(event_identifier=identifier) if not event: return HttpResponse( 'Event not found', content_type='text/plain', status=404 ) updatedEvent = updateObjectFromXML(xmlDoc, event, EVENT_UPDATE_TRANSLATION_DICT) # If XML identifier and resource ID don't match, bail. if updatedEvent.event_identifier != identifier: return HttpResponse( 'URI-identifier mismatch ("{}" != "{}")'.format( updatedEvent.event_identifier, identifier ), content_type='text/plain', status=400 ) updatedEvent.event_date_time = xsDateTime_parse( updatedEvent.event_date_time ) returnEvent = updatedEvent updatedEvent.save() eventObjectXML = objectToPremisEventXML(returnEvent) atomXML = wrapAtom(eventObjectXML, identifier, identifier) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp if request.method == 'GET' and identifier: # attempt to retrieve record -- error if unable try: event_object = Event.objects.get(event_identifier=identifier) except Event.DoesNotExist: return HttpResponseNotFound( "There is no event for identifier %s.\n" % identifier ) returnEvent = event_object eventObjectXML = objectToPremisEventXML(returnEvent) althref = request.build_absolute_uri( reverse('event-detail', args=[identifier, ]) ) atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, alt=althref, updated=event_object.event_added, author=CODALIB_APP_AUTHOR["name"], author_uri=CODALIB_APP_AUTHOR["uri"] ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp # This is here so clients can ping this endpoint to # test for availability. See codalib's waitForURL func # in util.py. elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml") elif request.method == 'DELETE' and identifier: # attempt to retrieve record -- error if unable try: event_object = Event.objects.get(event_identifier=identifier) except Exception: return HttpResponseNotFound( "Unable to Delete. There is no event for identifier %s.\n" % identifier ) # grab the event, delete it, and inform the user. returnEvent = event_object eventObjectXML = objectToPremisEventXML(returnEvent) event_object.delete() atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp
def app_validate(request, identifier=None): """ This method handles the ATOMpub protocol for validate objects """ # are we POSTing a new identifier here? if request.method == 'POST' and not identifier: # to object validateObject = xmlToValidateObject(request.body) validateObject.save() # and back to xml validateObjectXML = validateToXML(validateObject) atomXML = wrapAtom( xml=validateObjectXML, id='http://%s/APP/validate/%s/' % ( request.META['HTTP_HOST'], validateObject.identifier ), title=validateObject.identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 201 resp['Location'] = 'http://%s/APP/validate/%s/' % \ (request.META['HTTP_HOST'], validateObject.identifier) elif request.method == 'HEAD': resp = HttpResponse(content_type="application/atom+xml") resp.status_code = 200 # if not, return a feed elif request.method == 'GET' and not identifier: # negotiate the details of our feed here validates = Validate.objects.all() page = int(request.GET['page']) if request.GET.get('page') else 1 atomFeed = makeObjectFeed( paginator=Paginator(validates, 20), objectToXMLFunction=validateToXML, feedId=request.path[1:], webRoot='http://%s' % request.META.get('HTTP_HOST'), title="validate Entry Feed", idAttr="identifier", nameAttr="identifier", dateAttr="added", request=request, page=page, author={ "name": APP_AUTHOR.get('name', None), "uri": APP_AUTHOR.get('uri', None) }, ) atomFeedText = XML_HEADER % etree.tostring(atomFeed, pretty_print=True) resp = HttpResponse(atomFeedText, content_type="application/atom+xml") resp.status_code = 200 # updating an existing record elif request.method == 'PUT' and identifier: returnValidate = xmlToUpdateValidateObject(request.body) validateObjectXML = validateToXML(returnValidate) atomXML = wrapAtom( xml=validateObjectXML, id='http://%s/APP/validate/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 elif request.method == 'GET' and identifier: # attempt to retrieve record -- error if unable try: validate_object = Validate.objects.get(identifier=identifier) except Validate.DoesNotExist: return HttpResponseNotFound( "There is no validate for identifier %s.\n" % identifier ) returnValidate = validate_object validateObjectXML = validateToXML(returnValidate) atomXML = wrapAtom( xml=validateObjectXML, id='http://%s/APP/validate/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, author=APP_AUTHOR.get('name', None), author_uri=APP_AUTHOR.get('uri', None) ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 elif request.method == 'DELETE' and identifier: # attempt to retrieve record -- error if unable try: validate_object = Validate.objects.get(identifier=identifier) except: return HttpResponseNotFound( "Unable to Delete. There is no identifier %s.\n" % identifier) # grab the validate, delete it, and inform the user. returnValidate = validate_object validateObjectXML = validateToXML(returnValidate) validate_object.delete() atomXML = wrapAtom( xml=validateObjectXML, id='http://%s/APP/validate/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp
def app_agent(request, identifier=None): """ Return a representation of a given agent """ request_body = get_request_body(request) # full paginated ATOM PUB FEED if not identifier: # we just want to look at it. if request.method == 'GET': requestString = request.path if len(request.GET): requestString = "%s?%s" % ( request.path, request.GET.urlencode() ) page = request.GET.get('page') else: page = 1 atomFeed = makeObjectFeed( paginator=Paginator(Agent.objects.all(), 20), objectToXMLFunction=objectToAgentXML, feedId=requestString[1:], webRoot="http://%s" % request.META.get('HTTP_HOST'), title="Agent Entry Feed", idAttr="agent_identifier", nameAttr="agent_name", request=request, page=page, ) atomFeedText = XML_HEADER % etree.tostring( atomFeed, pretty_print=True ) resp = HttpResponse(atomFeedText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'POST': agent_object = premisAgentXMLToObject(request_body) agent_object.save() returnXML = objectToAgentXML(agent_object) returnEntry = wrapAtom( returnXML, agent_object.agent_name, agent_object.agent_name ) entryText = XML_HEADER % etree.tostring( returnEntry, pretty_print=True ) resp = HttpResponse(entryText, content_type="application/atom+xml") resp.status_code = 201 resp['Location'] = agent_object.agent_identifier + '/' return resp elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml") else: return HttpResponseBadRequest("Invalid method for this URL.") # identifier supplied, will be a GET or DELETE else: try: agent_object = get_object_or_404( Agent, agent_identifier=identifier ) except Exception, e: return HttpResponseNotFound( "There is no agent for identifier \'%s\'.\n" % identifier ) if request.method == 'DELETE': agent_object.delete() resp = HttpResponse("Deleted %s.\n" % identifier) resp.status_code = 200 return resp elif request.method == 'PUT': agent_object = premisAgentXMLToObject(request_body) agent_object.save() returnXML = objectToAgentXML(agent_object) returnEntry = wrapAtom( returnXML, agent_object.agent_name, agent_object.agent_name ) entryText = XML_HEADER % etree.tostring( returnEntry, pretty_print=True ) resp = HttpResponse(entryText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'GET': returnXML = objectToAgentXML(agent_object) returnText = XML_HEADER % etree.tostring( returnXML, pretty_print=True ) resp = HttpResponse(returnText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml")
def app_event(request, identifier=None): """ This method handles the ATOMpub protocol for events """ returnEvent = None request_body = get_request_body(request) # are we POSTing a new identifier here? if request.method == 'POST' and not identifier: xmlDoc = etree.fromstring(request_body) newEvent = addObjectFromXML( xmlDoc, premisEventXMLToObject, "event", "event_identifier", EVENT_UPDATE_TRANSLATION_DICT ) if type(newEvent) == HttpResponse: return newEvent eventObjectXML = objectToPremisEventXML(newEvent) atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], newEvent.event_identifier ), title=newEvent.event_identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 201 resp['Location'] = 'http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], newEvent.event_identifier ) return resp # if not, return a feed elif request.method == 'GET' and not identifier: # negotiate the details of our feed here events = Event.objects.all() startTime = datetime.datetime.now() # parse the request get variables and filter the search if request.GET.get('start_date'): start_date = datetime.datetime.strptime( request.GET.get('start_date'), DATE_FORMAT ) events = events.filter(event_date_time__gte=start_date) if request.GET.get('end_date'): end_date = datetime.datetime.strptime( request.GET.get('end_date'), DATE_FORMAT ) events = events.filter(event_date_time__lte=end_date) if request.GET.get('link_object_id'): linking_object_id = request.GET.get('link_object_id') events = events.filter( linking_objects__object_identifier=linking_object_id ) if request.GET.get('outcome'): outcome = request.GET.get('outcome') events = events.filter(event_outcome=outcome) if request.GET.get('type'): event_type = request.GET.get('type') events = events.filter(event_type=event_type) if request.GET.get('orderby'): order_field = request.GET.get('orderby') if request.GET.get('orderdir'): if request.GET.get('orderdir') == 'descending': events = events.order_by(order_field).reverse() else: events = events.order_by(order_field) else: events = events.order_by(order_field) debug_list = [] endTime = datetime.datetime.now() requestString = request.path if request.GET: requestString = "%s?%s" % (request.path, request.GET.urlencode()) page = int(request.GET['page']) if request.GET.get('page') else 1 else: page = 1 atomFeed = makeObjectFeed( paginator=Paginator(events, 20), objectToXMLFunction=objectToPremisEventXML, feedId=request.path[1:], webRoot='http://%s' % request.META.get('HTTP_HOST'), title="Event Entry Feed", idAttr="event_identifier", nameAttr="event_identifier", dateAttr="event_date_time", request=request, page=page, ) comment = etree.Comment(\ "\n".join(debug_list) + \ "\nTime prior to filtering is %s, time after filtering is %s" % \ (startTime, endTime) ) atomFeed.append(comment) atomFeedText = XML_HEADER % etree.tostring(atomFeed, pretty_print=True) resp = HttpResponse(atomFeedText, content_type="application/atom+xml") resp.status_code = 200 return resp # updating an existing record elif request.method == 'PUT' and identifier: xmlDoc = etree.fromstring(request_body) updatedEvent = updateObjectFromXML( xmlObject=xmlDoc, XMLToObjectFunc=premisEventXMLgetObject, topLevelName="event", idKey="event_identifier", updateList=EVENT_UPDATE_TRANSLATION_DICT, ) returnEvent = updatedEvent updatedEvent.save() eventObjectXML = objectToPremisEventXML(returnEvent) atomXML = wrapAtom(eventObjectXML, identifier, identifier) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp if request.method == 'GET' and identifier: # attempt to retrieve record -- error if unable try: event_object = Event.objects.get(event_identifier=identifier) except Event.DoesNotExist: return HttpResponseNotFound( "There is no event for identifier %s.\n" % identifier ) returnEvent = event_object eventObjectXML = objectToPremisEventXML(returnEvent) atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp elif request.method == 'HEAD': return HttpResponse(content_type="application/atom+xml") elif request.method == 'DELETE' and identifier: # attempt to retrieve record -- error if unable try: event_object = Event.objects.get(event_identifier=identifier) except: return HttpResponseNotFound( "Unable to Delete. There is no event for identifier %s.\n" \ % identifier ) # grab the event, delete it, and inform the user. returnEvent = event_object eventObjectXML = objectToPremisEventXML(returnEvent) event_object.delete() atomXML = wrapAtom( xml=eventObjectXML, id='http://%s/APP/event/%s/' % ( request.META['HTTP_HOST'], identifier ), title=identifier, ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") resp.status_code = 200 return resp