def test_return_type(): """ Verify the return type of wrapAtom is an instance of etree._Element. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') assert isinstance(atom, etree._Element)
def nodeEntry(node, webRoot=None): """ Form an atom xml for a given node object. """ nodeXML = etree.Element("node") node_name = etree.SubElement(nodeXML, "name") node_name.text = node.node_name node_capacity = etree.SubElement(nodeXML, "capacity") node_capacity.text = str(node.node_capacity) node_size = etree.SubElement(nodeXML, "size") node_size.text = str(node.node_size) node_path = etree.SubElement(nodeXML, "path") node_path.text = node.node_path node_url = etree.SubElement(nodeXML, "url") node_url.text = node.node_url node_last_checked = etree.SubElement(nodeXML, "last_checked") node_last_checked.text = node.last_checked.strftime(TIME_FORMAT_STRING) atomXML = wrapAtom( xml=nodeXML, id='http://%s/node/%s/' % (webRoot, node.node_name), title=node.node_name, author=APP_AUTHOR['name'], author_uri=APP_AUTHOR['uri'], ) return atomXML
def findEvent(request, linked_identifier, event_type=None): resultSet = Event.objects.filter( linking_objects__object_identifier__contains=linked_identifier ) if event_type: resultSet = resultSet.filter(event_type__contains=event_type) if not resultSet.count(): return HttpResponseNotFound( "There is no event for matching those parameters" ) lateDate = resultSet[0].event_date_time lateEvent = resultSet[0] for singleEvent in resultSet: if singleEvent.event_date_time > lateDate: lateDate = singleEvent.event_date_time lateEvent = singleEvent eventXML = objectToPremisEventXML(lateEvent) althref = request.build_absolute_uri( reverse('event-detail', args=[lateEvent.event_identifier, ]) ) atomXML = wrapAtom( eventXML, lateEvent.event_identifier, lateEvent.event_identifier, alt=althref ) atomText = XML_HEADER % etree.tostring(atomXML, pretty_print=True) resp = HttpResponse(atomText, content_type="application/atom+xml") return resp
def test_content_is_preserved(): """ Verify that the content is preserved after it has been wrapped. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') content = atom.xpath( '/a:entry/a:content', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert xml.strip() in etree.tostring(content[0])
def test_has_alternate_relationship_link(): """ Verify the entry has an alternate link. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test', alt='http://example.com') link = atom.xpath( "/a:entry/a:link[@rel='alternate']", namespaces={'a': bagatom.ATOM_NAMESPACE}) assert link[0].get('href') == 'http://example.com'
def test_has_date(): """ Check the returned tree has an updated element by default. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') updated = atom.xpath( '/a:entry/a:updated', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(updated) == 1
def test_has_no_author_uri(): """ Verify the author_url element is not present if the author_uri_text kwarg is not set. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') author_uri = atom.xpath( '/a:entry/a:author/a:uri', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(author_uri) == 0
def test_has_no_author(): """ Verify the author element is not present if the author kwarg is not specified. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') author = atom.xpath( '/a:entry/a:author', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(author) == 0
def test_has_author_name(): """ Verify the author element is present. """ author_text = 'John Doe' root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test', author=author_text) author = atom.xpath( '/a:entry/a:author/a:name', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(author) == 1 assert author[0].text == author_text
def test_has_author_uri(): """ Verify the author_uri is present. """ author_uri_text = 'http://example.com/author' root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test', author_uri=author_uri_text) author_uri = atom.xpath( '/a:entry/a:author/a:uri', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(author_uri) == 1 assert author_uri[0].text == author_uri_text
def test_has_title(): """ Check that the title element is present. """ title = 'Test Title' root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', title) elements = atom.xpath( '/a:entry/a:title', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(elements) == 1 assert elements[0].text == title
def test_has_content(): """ Check that the content element is present and has a type attribute of `application/xml`. """ root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test') content = atom.xpath( '/a:entry/a:content', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(content) == 1 attributes = content[0].attrib assert attributes.get('type') == 'application/xml'
def test_has_id(): """ Check that the id element is present. """ title = 'Test Title' _id = '2910' root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, _id, title) elements = atom.xpath( '/a:entry/a:id', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(elements) == 1 assert elements[0].text == _id
def test_has_author_and_author_uri(): """ Verify that both the author and author_uri are present if both kwargs are given values. """ author_text = 'John Doe' author_uri_text = 'http://example.com/author' root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test', author=author_text, author_uri=author_uri_text) author = atom.xpath( '/a:entry/a:author', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(author[0].getchildren()) == 2
def test_uses_date(): """ Check the returned tree uses the `updated` kwarg text for the updated element. """ updated = datetime(2012, 12, 12) root = etree.fromstring(xml) atom = bagatom.wrapAtom(root, '934023', 'test', updated=updated) elements = atom.xpath( '/a:entry/a:updated', namespaces={'a': bagatom.ATOM_NAMESPACE} ) assert len(elements) == 1 date = xsDateTime_parse(elements[0].text) assert date == updated
def makeBagAtomFeed(bagObjectList, id, title): """ Given an iterable of bags, make an ATOM feed xml representation of it """ feedTag = etree.Element(ATOM + "feed", nsmap=ATOM_NSMAP) idTag = etree.SubElement(feedTag, ATOM + "id") idTag.text = id titleTag = etree.SubElement(feedTag, ATOM + "title") titleTag.text = title etree.SubElement(feedTag, ATOM + "updated") linkTag = etree.SubElement(feedTag, ATOM + "link") linkTag.set("rel", "self") linkTag.set("href", id) for bagObject in bagObjectList: entryTag = wrapAtom( objectsToXML(bagObject), bagObject.name, bagObject.name, alt="/bag/" + bagObject.name ) feedTag.append(entryTag) return feedTag
def agentXML(request, identifier): """ Return a representation of a given agent """ if 'premis' in request.path: identifier = identifier.replace('.premis', '') try: agentObject = Agent.objects.get(agent_identifier=identifier) except Agent.DoesNotExist: return HttpResponseNotFound( "There is no agent with the identifier %s" % identifier ) returnXML = objectToPremisAgentXML( agentObject, webRoot=request.get_host() + '/', ) returnText = XML_HEADER % etree.tostring(returnXML, pretty_print=True) content_type = "application/xml" else: try: agentObject = Agent.objects.get(agent_identifier=identifier) except Agent.DoesNotExist: return HttpResponseNotFound( "There is no agent with the identifier %s" % identifier ) agent_obj_xml = objectToAgentXML(agentObject) althref = request.build_absolute_uri( reverse('agent-detail', args=[identifier, ]) ) return_atom = wrapAtom( agent_obj_xml, identifier, identifier, alt=althref ) returnText = XML_HEADER % etree.tostring(return_atom, pretty_print=True) content_type = "application/atom+xml" return HttpResponse(returnText, content_type=content_type)
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
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_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_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 queue(request, identifier=None): """ Display the queue status for a given ark """ # respond to a delete request if request.method == 'DELETE' and identifier: try: queueObject = QueueEntry.objects.get(ark=identifier) except: return HttpResponseNotFound( "There is no Queue Entry for ark '%s'.\n" % identifier ) queueObject.delete() resp = HttpResponse( "Queue entry for ark %s deleted.\n" % identifier, status=200, content_type="text/plain" ) # respond to a POST request elif request.method == 'POST' and not identifier: try: queueObject = addQueueEntry(request.body) except IntegrityError as e: return HttpResponse( "Conflict with already-existing resource.\n", status=409 ) identifier = queueObject.ark queueObjectXML = queueEntryToXML(queueObject) loc = 'http://%s/%s/' % (request.META['HTTP_HOST'], queueObject.ark) atomXML = wrapAtom( xml=queueObjectXML, id=loc, title=queueObject.ark, ) atomText = '<?xml version="1.0"?>\n%s' % etree.tostring( atomXML, pretty_print=True ) resp = HttpResponse( atomText, content_type="application/atom+xml", status=201 ) resp['Location'] = loc # respond to PUT request elif request.method == 'PUT' and identifier: try: queueObject = updateQueueEntry( request.body, validate_ark=identifier ) except ObjectDoesNotExist as e: return HttpResponseNotFound(e.message, content_type="text/plain") except ValidationError as e: return HttpResponse( e.message, content_type="text/plain", status=409 ) queueObjectXML = queueEntryToXML(queueObject) atomXML = wrapAtom( xml=queueObjectXML, id='http://%s/%s/' % (request.META['HTTP_HOST'], queueObject.ark), title=queueObject.ark, ) atomText = '<?xml version="1.0"?>\n%s' % etree.tostring( atomXML, pretty_print=True ) resp = HttpResponse(atomText, content_type="application/atom+xml") # respond to GET request elif request.method == 'GET' and identifier: # if it's a GET, or if we've just PUT or POST'd try: queueObject = QueueEntry.objects.get(ark=identifier) except QueueEntry.DoesNotExist: return HttpResponseNotFound( "There is no queue entry for ark '%s'.\n" % identifier, content_type="text/plain" ) queueObjectXML = queueEntryToXML(queueObject) atomXML = wrapAtom( xml=queueObjectXML, id='http://%s/%s/' % (request.META['HTTP_HOST'], queueObject.ark), title=queueObject.ark, author=APP_AUTHOR.get('name', None), author_uri=APP_AUTHOR.get('uri', None) ) atomText = '<?xml version="1.0"?>\n%s' % etree.tostring( atomXML, pretty_print=True ) resp = HttpResponse(atomText, content_type="application/atom+xml") elif request.method == 'GET': return queue_list(request) else: if identifier: allow = ('GET', 'PUT', 'DELETE') else: allow = ('GET', 'POST') resp = HttpResponse( "Method not allowed.\n", status=405, content_type="text/plain" ) resp['Allow'] = ', '.join(allow) 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")