Example #1
0
	def purgeConstituents(self):

		# purge children
		for page in self.pages_from_rels:
			page = self.pages_from_rels[page]
			print "purging:",page.label
			fedora_handle.purge_object(page)

		return True
Example #2
0
	def purgeReaduxVirtualObjects(self):

		sparql_response = fedora_handle.risearch.sparql_query('select $virtobj where  {{ $virtobj <http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/isVirtualFor> <info:fedora/%s> . }}' % (self.pid))

		for obj in sparql_response:
			print "Purging virtual object: %s" % obj['virtobj']
			fedora_handle.purge_object( obj['virtobj'].split("info:fedora/")[-1] )

		return True
Example #3
0
	def ingest(self, book_obj, page_num):

		# set book_obj to self
		self.book_obj = book_obj

		# using parent book, get datastreams from objMeta
		page_dict = self.book_obj.pages_from_objMeta[page_num]

		# new pid
		npid = "wayne:%s_Page_%s" % (self.book_obj.pid.split(":")[1], page_num)

		# creating new self	
		self.ohandle = fedora_handle.get_object(npid)
		if self.ohandle.exists:
			fedora_handle.purge_object(self.ohandle)
		self.ohandle = fedora_handle.get_object(npid, create=True)
		self.ohandle.save()

		# label
		self.ohandle.label = "%s - Page %s" % (self.book_obj.ohandle.label, page_num)

		# write POLICY datastream
		# NOTE: 'E' management type required, not 'R'
		print "Using policy:",self.book_obj.objMeta['policy']
		policy_suffix = self.book_obj.objMeta['policy'].split("info:fedora/")[1]
		policy_handle = eulfedora.models.DatastreamObject(self.ohandle, "POLICY", "POLICY", mimetype="text/xml", control_group="E")
		policy_handle.ds_location = "http://localhost/fedora/objects/%s/datastreams/POLICY_XML/content" % (policy_suffix)
		policy_handle.label = "POLICY"
		policy_handle.save()				

		# generic hash of target ids
		target_ids = {
			'IMAGE':'IMAGE_%d' % page_num,
			'HTML':'HTML_%d' % page_num,
			'ALTOXML':'ALTOXML_%d' % page_num
		}

		# for each file type in pages dict, pass page obj and process
		for ds in page_dict:

			if ds['ds_id'].startswith('IMAGE'):
				self.processImage(ds)
			if ds['ds_id'].startswith('HTML'):
				self.processHTML(ds)
			if ds['ds_id'].startswith('ALTOXML'):
				self.processALTOXML(ds)

		# write RDF relationships
		self.ohandle.add_relationship("info:fedora/fedora-system:def/relations-external#hasContentModel", "info:fedora/CM:WSUebook_Page")
		self.ohandle.add_relationship("info:fedora/fedora-system:def/relations-external#isConstituentOf", "info:fedora/%s" % self.book_obj.ohandle.pid)
		self.ohandle.add_relationship("http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/pageOrder", page_num)

		# save page object
		return self.ohandle.save()
Example #4
0
	def ingestMissingPage(self, book_obj, page_num, from_bag=True):

		# set book_obj to self
		self.book_obj = book_obj

		# new pid
		npid = "wayne:%s_Page_%s" % (self.book_obj.pid.split(":")[1], page_num)

		# creating new self	
		self.ohandle = fedora_handle.get_object(npid)
		if self.ohandle.exists:
			fedora_handle.purge_object(self.ohandle)
		self.ohandle = fedora_handle.get_object(npid, create=True)
		self.ohandle.save()

		# label
		self.ohandle.label = "%s - Page %s" % (self.book_obj.ohandle.label, page_num)

		# write POLICY datastream
		# NOTE: 'E' management type required, not 'R'
		print "Using policy:",self.book_obj.objMeta['policy']
		policy_suffix = self.book_obj.objMeta['policy'].split("info:fedora/")[1]
		policy_handle = eulfedora.models.DatastreamObject(self.ohandle, "POLICY", "POLICY", mimetype="text/xml", control_group="E")
		policy_handle.ds_location = "http://localhost/fedora/objects/%s/datastreams/POLICY_XML/content" % (policy_suffix)
		policy_handle.label = "POLICY"
		policy_handle.save()				

		print "Processing HTML placeholder"
		generic_handle = eulfedora.models.FileDatastreamObject(self.ohandle, "HTML", "HTML", mimetype="text/html", control_group='M')
		generic_handle.label = "HTML"
		generic_handle.content = "<p>[Page %s Intentionally Left Blank]</p>" % (page_num)
		generic_handle.save()

		print "Processing IMAGE placeholder"
		# passes 'from_bag' param		
		self.processImage(None, exists=False, page_num=page_num, from_bag=from_bag)

		# write RDF relationships
		self.ohandle.add_relationship("info:fedora/fedora-system:def/relations-external#hasContentModel", "info:fedora/CM:WSUebook_Page")
		self.ohandle.add_relationship("info:fedora/fedora-system:def/relations-external#isConstituentOf", "info:fedora/%s" % self.book_obj.ohandle.pid)
		self.ohandle.add_relationship("http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/pageOrder", page_num)
		self.ohandle.add_relationship("http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/pageExists", False)

		# create IMAGE, HTML, ALTOXML for missing page
		print "Processing ALTOXML placeholder"
		generic_handle = eulfedora.models.FileDatastreamObject(self.ohandle, 'ALTOXML', 'ALTOXML', mimetype="text/xml", control_group='M')
		generic_handle.label = 'ALTOXML'
		generic_handle.content = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><alto xmlns="http://www.loc.gov/standards/alto/ns-v2#" xmlns:xlink="http://www.w3.org/1999/xlink"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v2# http://www.loc.gov/standards/alto/alto-v2.0.xsd">    <Description>        <MeasurementUnit>pixel</MeasurementUnit>        <OCRProcessing ID="IdOcr">            <ocrProcessingStep>                <processingSoftware>                    <softwareCreator>ABBYY</softwareCreator>                    <softwareName>ABBYY Recognition Server</softwareName>                    <softwareVersion>4.0</softwareVersion>                </processingSoftware>            </ocrProcessingStep>        </OCRProcessing>    </Description>    <Styles>        <ParagraphStyle ID="StyleId-FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF-" ALIGN="Left" LEFT="0"            RIGHT="0" FIRSTLINE="0"/>    </Styles>    <Layout>        <Page ID="Page1" PHYSICAL_IMG_NR="1">            <PrintSpace HEIGHT="%s" WIDTH="%s" VPOS="0" HPOS="0"/>        </Page>    </Layout></alto>' % (self.faux_width, self.faux_height)
		generic_handle.save()

		# save page object
		return self.ohandle.save()
Example #5
0
	def purgeReaduxVirtualObjects(self):

		readux_solr_handle = solrHandles.onDemand('readux')

		sparql_response = fedora_handle.risearch.sparql_query('select $virtobj where  {{ $virtobj <http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/isVirtualFor> <info:fedora/%s> . }}' % (self.pid))

		for obj in sparql_response:
			print "Purging virtual object: %s" % obj['virtobj']
			fedora_handle.purge_object( obj['virtobj'].split("info:fedora/")[-1] )
			print "Removing from Readux solr core..."
			readux_solr_handle.delete_by_key(obj['virtobj'].split("info:fedora/")[-1], commit=False)

		# commit solr purges
		readux_solr_handle.commit()


		return True
Example #6
0
	def reingestBag(self, removeExportTar = False):
		
		# get PID
		PID = self.pid

		print "Roundrip Ingesting:",PID

		# export bag, returning the file structure location of tar file
		export_tar = self.exportBag(returnTargetDir=True)
		print "Location of export tar file:",export_tar

		# purge self
		fedora_handle.purge_object(PID)

		# reingest exported tar file
		actions.bagIngest.ingestBag(actions.bagIngest.payloadExtractor(export_tar,'single'))

		# delete exported tar
		if removeExportTar == True:
			print "Removing export tar..."
			os.remove(export_tar)

		# return 
		return PID,"Reingested."
Example #7
0
def ingestBagAndPush(bag_dir, dest_repo, refresh_remote=True, overwrite=False, export_context='migrate'):

	# DEBUG
	print dir(localConfig)

	# load bag_handle and ingest	
	print "Working on:",bag_dir
	bag_handle = WSUDOR_ContentTypes.WSUDOR_Object(object_type="bag", payload=bag_dir)
	if bag_dir == 'Could not load WSUDOR or Bag object.':
		print "Aborting, bag_handle initiziation was unsuccessful."
		return False
	
	# validate bag for WSUDOR ingest	
	valid_results = bag_handle.validIngestBag()
	if valid_results['verdict'] != True:
		print "Bag is not valid for the following reasons, aborting.", valid_results
		return False

	# ingest bag & skip indexing
	ingest_bag = bag_handle.ingestBag(indexObject=False)

	# push to remote repo
	print "sending object..."

	# Use object method
	obj_handle = WSUDOR_ContentTypes.WSUDOR_Object(bag_handle.pid)
	obj_handle.sendObject(dest_repo, refresh_remote=refresh_remote, overwrite=overwrite, export_context=export_context)	

	# delete local object
	print "finally, removing object"
	fedora_handle.purge_object(bag_handle.pid)

	# remove from Solr	
	solr_handle.delete_by_key(bag_handle.pid)

	return json.dumps({"Ingest Results for {bag_label}, PID: {bag_pid}".format(bag_label=bag_handle.label.encode('utf-8'),bag_pid=bag_handle.pid):True})
Example #8
0
def purgeObject_worker(job_package):	

	form_data = job_package['form_data']
	pid = job_package['PID']

	# get obj_handle
	obj_handle = WSUDOR_ContentTypes.WSUDOR_Object(pid)

	# check object state
	print obj_handle.ohandle.state
	if obj_handle.ohandle.state != "D":
		return "Skipping, object state not 'Deleted (D)'"

	print "purging Constituents if present"
	if getattr(obj_handle, 'purgeConstituents', None):
		obj_handle.purgeConstituents()
	
	# else, purge object from Fedora (object will be pulled via Messenging service)
	result = fedora_handle.purge_object(obj_handle.pid)
	return "%s purge result: %s" % (obj_handle.pid, result)

	# remove from Solr
	solr_handle.delete_by_key(obj_handle.pid)
Example #9
0
def createObj_worker():

    form_data = request.form
    print form_data

    # instantiate object with quick variables
    known_values = {
        "id": form_data["pid"],
        "identifier": form_data["pid"].split(":")[-1],
        "label": form_data["label"],
        "content_type": "WSUDOR_%s" % (form_data["CM"]),
        "policy": "%s" % (form_data["policy"]),
    }

    # instantiate ObjMeta object
    om_handle = ObjMeta(**known_values)

    # show relationships
    om_handle.object_relationships = [
        {
            "predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasSecurityPolicy",
            "object": "info:fedora/%s" % (form_data["policy"]),
        },
        {
            "predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasSecurityPolicy",
            "object": "info:fedora/%s" % (form_data["policy"]),
        },
    ]

    # prepare new working dir & recall original
    working_dir = "/tmp/Ouroboros/" + str(uuid.uuid4())
    print "creating working dir at", working_dir
    # create if doesn't exist
    if not os.path.exists(working_dir):
        os.mkdir(working_dir)
    os.system("mkdir %s/datastreams" % (working_dir))

    # write objMeta
    print "writing:", om_handle.toJSON()
    om_handle.writeToFile("%s/objMeta.json" % (working_dir))

    if "bagify" in form_data:
        # bagify
        print "bagifying"
        bag = bagit.make_bag("%s" % (working_dir), {"Object PID": form_data["pid"]})

        # ingest
    if "ingest" in form_data:

        # purge if already exists
        if "purge" in form_data:
            try:
                print "purging object"
                fedora_handle.purge_object(form_data["pid"])
            except:
                print "object not found, skipping purge"

                # bagify
        if "bagify" not in form_data:
            print "bagifying"
            bag = bagit.make_bag("%s" % (working_dir), {"Object PID": form_data["pid"]})

            # open new handle
        bag_handle = WSUDOR_ContentTypes.WSUDOR_GenObject(payload=working_dir, object_type="bag")
        ingest_result = bag_handle.ingestBag()

        # render
        return render_template(
            "createBag_confirm.html", status="result for %s was %s" % (form_data["pid"], ingest_result)
        )

    else:
        return render_template("createBag_confirm.html", status=working_dir)
Example #10
0
def bagIngest_worker(job_package):
	
	bag_dir = job_package['bag_dir']

	# load bag_handle and ingest	
	print "Working on:",bag_dir
	bag_handle = WSUDOR_ContentTypes.WSUDOR_Object(bag_dir, object_type="bag")
	if bag_dir == 'Could not load WSUDOR or Bag object.':
		print "Aborting, bag_handle initiziation was unsuccessful."
		return False

	# validate bag for WSUDOR ingest	
	valid_results = bag_handle.validIngestBag()
	if valid_results['verdict'] != True:
		print "Bag is not valid for the following reasons, aborting.", valid_results
		return False

	# optional flags
	###########################################################################################
	# overwrite
	if 'overwrite' in job_package['form_data']:
		print "purging object if exists"
		if fedora_handle.get_object(bag_handle.pid).exists:
			fedora_handle.purge_object(bag_handle.pid)

	# push to remote
	if 'push_remote' in job_package['form_data']:

		# get options
		# set destination repo
		dest_repo = job_package['form_data']['dest_repo']

		# get export context
		export_context = job_package['form_data']['export_context']

		# overwrite
		if 'overwrite' in job_package['form_data']:
			overwrite = True
		else:
			overwrite = False

		# refresh remote
		if 'refresh_remote' in job_package['form_data']:
			refresh_remote = True
		else:
			refresh_remote = False

		# omit checksums
		if 'omit_checksums' in job_package['form_data']:
			omit_checksums = True
		else:
			omit_checksums = False

		# ingest bag
		try:
			# because we're sending remotely, not indexing locally
			ingest_bag = bag_handle.ingestBag(indexObject=False)
		except Exception, e:
			raise Exception(e)
			return False

		# push to remote repo
		print "sending object..."

		# Use object method
		obj_handle = WSUDOR_ContentTypes.WSUDOR_Object(bag_handle.pid)
		obj_handle.sendObject(dest_repo, refresh_remote=refresh_remote, overwrite=overwrite, export_context=export_context, omit_checksums=omit_checksums)	

		# delete local object (and constituent objects)
		print "purging Constituents if present"
		if getattr(obj_handle, 'purgeConstituents', None):
			obj_handle.purgeConstituents()

		print "finally, removing object"
		fedora_handle.purge_object(obj_handle.pid)

		# remove from Solr	
		solr_handle.delete_by_key(obj_handle.pid)

		# fire ingestWorkspace callback if checked
		if 'origin' in job_package['form_data'] and job_package['form_data']['origin'] == 'ingestWorkspace' and ingest_bag == True:
			print "firing ingest callback"			
			actions.actions.ingestBag_callback.apply_async(kwargs={'job_package':job_package}, queue=job_package['username'])

		return json.dumps({"Ingest Results for %s, PID: %s" % (bag_handle.label.encode('utf-8'), bag_handle.pid):ingest_bag})
Example #11
0
def createContainer_worker():
	
	form_data = request.form
	print form_data

	unique_identifier = "LearningObject_%s" % str(uuid.uuid4())
	pid = "wayne:"+unique_identifier

	# instantiate object with quick variables
	known_values = {
		"id":pid,
		"identifier":unique_identifier,
		"label":form_data['label'],
		"description":form_data['description'],
		"creator":form_data['creator'],
		"date":form_data['date'],
		"content_type":"WSUDOR_LearningObject", 
		"policy":"info:fedora/wayne:WSUDORSecurity-permit-apia-unrestricted",
	}

	# instantiate ObjMeta object
	om_handle = ObjMeta(**known_values)

	# show relationships
	om_handle.object_relationships = [		
		{
			"predicate": "info:fedora/fedora-system:def/relations-external#isMemberOfCollection",
			"object": form_data['collection']
		},
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasParent",
			"object": form_data['collection']
		},		
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/isDiscoverable",
			"object": "info:fedora/True"
		},
		{
			"predicate": "info:fedora/fedora-system:def/relations-external#hasContentModel",
			"object": "info:fedora/CM:LearningObject"
		},
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/preferredContentModel",
			"object": "info:fedora/CM:Container"
		},
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasSecurityPolicy",
			"object": "info:fedora/wayne:WSUDORSecurity-permit-apia-unrestricted"
		}
	]

	# add optional associated objects
	if "associated_objects" in form_data:
		print "writing associated object relationships"
		associated_objects = [obj.strip() for obj in form_data['associated_objects'].split(',')]
		for obj in associated_objects:
			if obj != '':
				om_handle.object_relationships.append({
					"predicate":"http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/learningObjectFor",
					"object": "info:fedora/%s" % obj
				})

	# prepare new working dir & recall original
	working_dir = "/tmp/Ouroboros/"+str(uuid.uuid4())
	print "creating working dir at", working_dir
	# create if doesn't exist
	if not os.path.exists(working_dir):
		os.mkdir(working_dir)			
	os.system("mkdir %s/datastreams" % (working_dir))

	# write custom MODS
	
	# prepare subjects
	subjects = [subject.strip() for subject in form_data['subjects'].split(",")]
	subject_string = ''
	for subject in subjects:
		if subject != '':
			subject_string += '<mods:subject authority="lcsh"><mods:topic>%s</mods:topic></mods:subject>' % subject

	raw_MODS = '''<?xml version="1.0" encoding="utf-8"?>
<mods:mods xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.4" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
  <mods:titleInfo>
	<mods:title>%(label)s</mods:title>
  </mods:titleInfo>
  <mods:abstract>%(description)s</mods:abstract>
  %(subject_string)s
  <mods:name authority="local" type="person">
	<mods:namePart>%(creator)s</mods:namePart>
	<mods:role>
	  <mods:roleTerm authority="marcrelator" type="text">creator</mods:roleTerm>
	</mods:role>
  </mods:name>
  <mods:originInfo>
	<mods:dateIssued encoding="w3cdtf" keyDate="yes">%(date)s</mods:dateIssued>
  </mods:originInfo>
  <mods:identifier type="local">%(identifier)s</mods:identifier>
  <mods:extension>
	<PID>%(id)s</PID>
  </mods:extension>
  <mods:accessCondition type="useAndReproduction">%(rights)s</mods:accessCondition>
</mods:mods>
	''' % {
			'label':om_handle.label,
			'description':om_handle.description,
			'creator':om_handle.creator,
			'date':om_handle.date,
			'id':om_handle.id,
			'identifier':om_handle.identifier,
			'subject_string':subject_string,
			'rights':form_data['rights']
		}
	print raw_MODS
	with open('%s/MODS.xml' % working_dir,'w') as f:
		f.write(raw_MODS)

	# write objMeta
	print "writing:",om_handle.toJSON()
	om_handle.writeToFile('%s/objMeta.json' % (working_dir))

	# bagify
	print 'bagifying'	
	bag = WSUDOR_bagger.make_bag(working_dir, {
		'Object PID' : pid
	})

	# ingest
	# purge if already exists
	if 'purge' in form_data:
		try:
			print "purging object"
			fedora_handle.purge_object(form_data['pid'])
		except:
			print "object not found, skipping purge"

	# open new handle
	bag_handle = WSUDOR_ContentTypes.WSUDOR_Object(payload=working_dir, object_type='bag')
	ingest_result = bag_handle.ingestBag()

	# cleanup
	shutil.rmtree(working_dir)

	# render
	time.sleep(3)
	return redirect('tasks/learningObj/container/%s' % pid)
Example #12
0
def createDocument_worker(parent_PID):

	form_data = request.form
	print form_data

	# open parent handle
	obj = WSUDOR_ContentTypes.WSUDOR_Object(parent_PID)

	unique_identifier = "LearningObject_File_%s" % str(uuid.uuid4())
	pid = "wayne:"+unique_identifier

	# instantiate object with quick variables
	known_values = {
		"id":pid,
		"identifier":unique_identifier,
		"label":form_data['label'],
		"description":form_data['description'],
		"creator":form_data['creator'],
		"date":form_data['date'],
		"content_type":"WSUDOR_%s" % form_data['CM'], 
		"policy":"info:fedora/wayne:WSUDORSecurity-permit-apia-unrestricted"
	}
	print known_values

	# instantiate ObjMeta object
	om_handle = ObjMeta(**known_values)

	# show relationships
	om_handle.object_relationships = [
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasParent",
			"object": "info:fedora/%s" % parent_PID
		},
		{
			"predicate": "info:fedora/fedora-system:def/relations-external#isConstituentOf",
			"object": "info:fedora/%s" % parent_PID
		},
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/isDiscoverable",
			"object": "info:fedora/False"
		},		
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/preferredContentModel",
			"object": "info:fedora/CM:%s" % form_data['CM']
		},
		{
			"predicate": "http://digital.library.wayne.edu/fedora/objects/wayne:WSUDOR-Fedora-Relations/datastreams/RELATIONS/content/hasSecurityPolicy",
			"object": "info:fedora/wayne:WSUDORSecurity-permit-apia-unrestricted"
		}
	]

	# prepare new working dir & recall original
	working_dir = "/tmp/Ouroboros/"+str(uuid.uuid4())
	print "creating working dir at", working_dir
	# create if doesn't exist
	if not os.path.exists(working_dir):
		os.mkdir(working_dir)			
	os.system("mkdir %s/datastreams" % (working_dir))

	# write custom MODS

	# prepare subjects
	subjects = [subject.strip() for subject in form_data['subjects'].split(",")]
	subject_string = ''
	for subject in subjects:
		if subject != '':
			subject_string += '<mods:subject authority="lcsh"><mods:topic>%s</mods:topic></mods:subject>' % subject

	raw_MODS = '''<?xml version="1.0" encoding="utf-8"?>
<mods:mods xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.4" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
  <mods:titleInfo>
	<mods:title>%(label)s</mods:title>
  </mods:titleInfo>
  <mods:abstract>%(description)s</mods:abstract>
  %(subject_string)s
  <mods:name authority="local" type="person">
	<mods:namePart>%(creator)s</mods:namePart>
	<mods:role>
	  <mods:roleTerm authority="marcrelator" type="text">creator</mods:roleTerm>
	</mods:role>
  </mods:name>
  <mods:originInfo>
	<mods:dateCreated>%(date)s</mods:dateCreated>
  </mods:originInfo>
  <mods:identifier type="local">%(identifier)s</mods:identifier>
  <mods:extension>
	<PID>%(id)s</PID>
  </mods:extension>
  <mods:accessCondition type="useAndReproduction">%(rights)s</mods:accessCondition>
</mods:mods>
	''' % {
			'label':om_handle.label,
			'description':om_handle.description,
			'creator':om_handle.creator,
			'date':om_handle.date,
			'id':om_handle.id,
			'identifier':om_handle.identifier,
			'subject_string':subject_string,
			'rights':form_data['rights']
		}
	print raw_MODS
	with open('%s/MODS.xml' % working_dir,'w') as f:
		f.write(raw_MODS)

	# write datastream
	# Identify datastreams folder
	datastreams_dir = working_dir + "/datastreams"
	target_filename = '%s/%s' % (datastreams_dir,form_data['filename'])

	# retrieve uploaded / pasted / content and write to disk
	if form_data['dataType'] == 'dsLocation':
		file_data = requests.get(form_data['dsLocation'])
		with open(target_filename) as f:
			f.write(file_data.content)

	elif form_data['dataType'] == 'upload':
		# writes to temp file in /tmp/Ouroboros
		if 'upload' in request.files and request.files['upload'].filename != '':
			print "Form provided file, uploading and reading file to variable"
			with open(target_filename,'w') as fhand:
				fhand.write(request.files['upload'].read())

	else:
		print "file could not be found"
		return False

	filename = form_data['filename']
	label = form_data['label']
	order = 1

	# get extension, ds_id
	mimetypes.init()
	ds_id, ext = filename.split(".")

	# create datastream dictionary
	ds_dict = {
		"filename": filename,
		"ds_id": ds_id,
		"mimetype": mimetypes.types_map[".%s" % ext],
		"label": label,
		"internal_relationships": {},
		'order': order
	}

	om_handle.datastreams.append(ds_dict)
	
	om_handle.isRepresentedBy = ds_id

	# write objMeta
	print "writing:",om_handle.toJSON()
	om_handle.writeToFile('%s/objMeta.json' % (working_dir))

	# bagify
	print 'bagifying'	
	bag = WSUDOR_bagger.make_bag(working_dir, {
		'Object PID' : pid
	})

	# ingest
	# purge if already exists
	if 'purge' in form_data:
		try:
			print "purging object"
			fedora_handle.purge_object(form_data['pid'])
		except:
			print "object not found, skipping purge"

	# open new handle
	bag_handle = WSUDOR_ContentTypes.WSUDOR_Object(payload=working_dir, object_type='bag')
	ingest_result = bag_handle.ingestBag()

	# cleanup
	# shutil.rmtree(working_dir)

	# render
	time.sleep(3)
	return redirect('tasks/learningObj/container/%s' % parent_PID)