Skip to content

Instantly share code, notes, and snippets.

@tomkralidis
Created September 23, 2012 13:28
Show Gist options
  • Save tomkralidis/3770957 to your computer and use it in GitHub Desktop.
Save tomkralidis/3770957 to your computer and use it in GitHub Desktop.
GeoNode update_metadata
def update_metadata(layer_uuid, xml, saved_layer):
"""Update metadata XML document with GeoNode specific values"""
# check if document is XML
try:
exml = etree.fromstring(xml)
except Exception, err:
raise GeoNodeException('Uploaded XML document is not XML: %s' % str(err))
# check if document is an accepted XML metadata format
try:
tagname = exml.tag.split('}')[1]
except:
tagname = exml.tag
# update relevant XML
layer_updated = saved_layer.date.strftime('%Y-%m-%d')
if tagname == 'Record': # Dublin Core
dc_ns = '{http://purl.org/dc/elements/1.1/}'
dct_ns ='{http://purl.org/dc/terms/}'
children = exml.getchildren()
# set/update identifier
xname = exml.find('%sidentifier' % dc_ns)
if xname is None: # doesn't exist, insert it
value = etree.Element('%sidentifier' % dc_ns)
value.text = layer_uuid
children.insert(0, value)
else: # exists, update it
xname.text = layer_uuid
xname = exml.find('%smodified' % dct_ns)
if xname is None: # doesn't exist, insert it
value = etree.Element('%smodified' % dct_ns)
value.text = layer_updated
children.insert(3, value)
else: # exists, update it
xname.text = layer_updated
# set/update URLs
http_link = etree.Element('%sreferences' % dct_ns, scheme='WWW:LINK-1.0-http--link')
http_link.text = '%s%s' % (settings.SITEURL, saved_layer.get_absolute_url())
children.insert(-2, http_link)
for link in saved_layer.link_set.all():
http_link = etree.Element('%sreferences' % dct_ns, scheme='WWW:DOWNLOAD-1.0-http--download')
http_link.text = link.url
children.insert(-2, http_link)
elif tagname == 'MD_Metadata':
gmd_ns = 'http://www.isotc211.org/2005/gmd'
gco_ns = 'http://www.isotc211.org/2005/gco'
# set/update gmd:fileIdentifier
xname = exml.find('{%s}fileIdentifier' % gmd_ns)
if xname is None: # doesn't exist, insert it
children = exml.getchildren()
fileid = etree.Element('{%s}fileIdentifier' % gmd_ns)
etree.SubElement(fileid, '{%s}CharacterString' % gco_ns).text = layer_uuid
children.insert(0, fileid)
else: # gmd:fileIdentifier exists, check for gco:CharacterString
value = xname.find('{%s}CharacterString' % gco_ns)
if value is None:
etree.SubElement(xname, '{%s}CharacterString' % gco_ns).text = layer_uuid
else:
value.text = layer_uuid
# set/update gmd:dateStamp
xname = exml.find('{%s}dateStamp' % gmd_ns)
if xname is None: # doesn't exist, insert it
children = exml.getchildren()
datestamp = etree.Element('{%s}dateStamp' % gmd_ns)
etree.SubElement(datestamp, '{%s}DateTime' % gco_ns).text = layer_updated
children.insert(4, datestamp)
else: # gmd:dateStamp exists, check for gco:Date or gco:DateTime
value = xname.find('{%s}Date' % gco_ns)
value2 = xname.find('{%s}DateTime' % gco_ns)
if value is None and value2 is not None: # set gco:DateTime
value2.text = layer_updated
elif value is not None and value2 is None: # set gco:Date
value.text = saved_layer.date.strftime('%Y-%m-%d')
elif value is None and value2 is None:
etree.SubElement(xname, '{%s}DateTime' % gco_ns).text = layer_updated
# set/update URLs
children = exml.getchildren()
distinfo = etree.Element('{%s}distributionInfo' % gmd_ns)
distinfo2 = etree.SubElement(distinfo, '{%s}MD_Distribution' % gmd_ns)
transopts = etree.SubElement(distinfo2, '{%s}transferOptions' % gmd_ns)
transopts2 = etree.SubElement(transopts, '{%s}MD_DigitalTransferOptions' % gmd_ns)
online = etree.SubElement(transopts2, '{%s}onLine' % gmd_ns)
online2 = etree.SubElement(online, '{%s}CI_OnlineResource' % gmd_ns)
linkage = etree.SubElement(online2, '{%s}linkage' % gmd_ns)
etree.SubElement(linkage, '{%s}URL' % gmd_ns).text = '%s%s' % (settings.SITEURL, saved_layer.get_absolute_url())
protocol = etree.SubElement(online2, '{%s}protocol' % gmd_ns)
etree.SubElement(protocol, '{%s}CharacterString' % gco_ns).text = 'WWW:LINK-1.0-http--link'
for extension, dformat, dprotocol, link in saved_layer.download_links():
online = etree.SubElement(transopts2, '{%s}onLine' % gmd_ns)
online2 = etree.SubElement(online, '{%s}CI_OnlineResource' % gmd_ns)
linkage = etree.SubElement(online2, '{%s}linkage' % gmd_ns)
etree.SubElement(linkage, '{%s}URL' % gmd_ns).text = link or ''
protocol = etree.SubElement(online2, '{%s}protocol' % gmd_ns)
etree.SubElement(protocol, '{%s}CharacterString' % gco_ns).text = dprotocol
lname = etree.SubElement(online2, '{%s}name' % gmd_ns)
etree.SubElement(lname, '{%s}CharacterString' % gco_ns).text = extension or ''
ldesc = etree.SubElement(online2, '{%s}description' % gmd_ns)
etree.SubElement(ldesc, '{%s}CharacterString' % gco_ns).text = dformat or ''
children.insert(-2, distinfo)
elif tagname == 'metadata': # FGDC
# set/update identifier
xname = exml.find('idinfo/datasetid')
if xname is None: # doesn't exist, insert it
children = exml.find('idinfo').getchildren()
value = etree.Element('datasetid')
value.text = layer_uuid
children.insert(0, value)
else: # exists, update it
xname.text = layer_uuid
xname = exml.find('metainfo/metd')
if xname is None: # doesn't exist, insert it
value = etree.Element('metd')
value.text = layer_updated
exml.find('metainfo').append(value)
else: # exists, update it
xname.text = layer_updated
# set/update URLs
citeinfo = exml.find('idinfo/citation/citeinfo')
http_link = etree.Element('onlink')
http_link.attrib['type'] = 'WWW:LINK-1.0-http--link'
http_link.text = '%s%s' % (settings.SITEURL, saved_layer.get_absolute_url())
citeinfo.append(http_link)
for extension, dformat, protocol, link in saved_layer.download_links():
http_link = etree.Element('onlink')
http_link.attrib['type'] = protocol
http_link.text = link
citeinfo.append(http_link)
else:
raise GeoNodeException('Unsupported metadata format')
return etree.tostring(exml)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment