hadrians-wall.py
Creators:
Sean Gillies
Copyright © The Contributors. Sharing and remixing permitted under terms of the Creative Commons Attribution 3.0 License (cc-by).
Last modified
Feb 07, 2012 03:19 PM
Script used to process the spreadsheet
hadrians-wall.py — Python Source, 9 KB (9409 bytes)
File contents
#!/usr/bin/python # -*- coding: utf-8 -*- from csv import DictReader import datetime import logging from optparse import OptionParser import re import sys from DateTime import DateTime from Products.CMFCore.utils import getToolByName from pleiades.bulkup import secure, setup_cmfuid root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")) root_logger.addHandler(handler) LOG = logging.getLogger('pleiades.scripts') MESSAGE = "Milecastles and Turrets from Scott Vanderbilt (sarcannon) in January 2012" def main(context, reader): catalog = getToolByName(context, 'portal_catalog') repo = getToolByName(context, 'portal_repository') wftool = getToolByName(context, 'portal_workflow') utils = getToolByName(context, 'plone_utils') import transaction savepoint = transaction.savepoint() try: # First we will sort locations by their parent place. records = {} for row in reader: ptype = row['type'] pid = str(row['pid']) if ptype == 'Place' and pid not in records: records[pid] = {'row': row.copy(), 'locations': []} elif ptype == 'Location': records[pid]['locations'].append(row.copy()) # Next, create content from this mapping. places = context['places'] for record in records.values(): prow = record['row'] locations = record['locations'] LOG.info( "Place: %s, locations: %s", record['row']['title'], list(r['title'] for r in locations) ) # Create the place. pid = places.invokeFactory( 'Place', places.generateId(prefix=''), title=prow['title'], description=prow['description'], placeType=['fort'], modernLocation=None, creators=['sarcanon'], contributors=['sgillies', 'thomase'], originalProvenance='Pleiades' ) place = places[pid] LOG.info( "Created place: %s, %s", place.Title(), place.Description() ) place.addReference(places['91358'], 'connectsWith') # Determine whether a Milecastle or Turret and add standard # citations accordingly. mcn = None m = re.search(r"(Milecastle\s+(\d+))", place.Title()) if m: mcn = m.group(2) if not mcn: m = re.search(r"(Turret\s+(\d+)[A|B])", place.Title()) if m: mcn = m.group(2) citations = [ dict( identifier="http://wikipedia.org/wiki/Hadrian%27s_Wall", range="Wikipedia, Hadrian's Wall", type="seeAlso") ] if mcn is not None: citations.extend([ dict( identifier="http://wikipedia.org/wiki/Milecastle", range="Wikipedia, Milecastle", type="seeAlso"), dict( identifier="http://wikipedia.org/wiki/Milecastle_%s" % mcn, range="Wikipedia, Milecastle %s" % mcn, type="seeFurther") ]) # Next look for Breeze citations. if prow['reference'].strip(): rvals = re.split(r"\]\s*,\s*\[", prow['reference']) refs = [ map( lambda s:s.strip(), rv.strip(" []").split(',') ) for rv in rvals ] prefs = dict([r[::-1] for r in refs]) else: prefs = {} def getBreeze(refs): r = None for k, v in refs.items(): if k.startswith("Breeze"): r = (k, v) break return r breeze_ref = getBreeze(prefs) if breeze_ref: citations.append( dict( identifier=breeze_ref[1], range=breeze_ref[0], type="seeFurther") ) field = place.getField('referenceCitations') field.resize(len(citations), place) place.update(referenceCitations=citations) LOG.info( "Citations: %s", [c['range'] for c in place.getReferenceCitations()] ) # Now we take care of the locations for lrow in locations: lid = place.invokeFactory( 'Location', utils.normalizeString(lrow['title']), title=lrow['title'], description=lrow['description'], geometry=lrow['geometry'], associationCertainty=lrow['certainty_Loc'].replace( " ", "-"), creators=['sarcanon'], contributors=['sgillies', 'thomase'], originalProvenance='Pleiades' ) location = place[lid] LOG.info( "Created location: %s", location.getId() ) metadataDoc = context['features']['metadata'][ "hadrians-wall-milecastles-and-turrets-2012"] location.addReference(metadataDoc, 'location_accuracy') # Look for EH citations. citations = [] if lrow['reference'].strip(): rvals = re.split(r"\]\s*,\s*\[", lrow['reference']) refs = [map( lambda s:s.strip(), rv.strip(" []").split(',')) for rv in rvals ] lrefs = dict([r[::-1] for r in refs]) else: lrefs = {} def getEH(refs): r = None for k, v in refs.items(): if k.startswith("English"): r = (k, v) break return r # Look for one locally... eh_ref = getEH(lrefs) if eh_ref is None: # Check in the parent place. eh_ref = getEH(prefs) if eh_ref: citations.append( dict( identifier=eh_ref[1], range=eh_ref[0], type="cites") ) field = place.getField('referenceCitations') field.resize(len(citations), location) location.update(referenceCitations=citations) LOG.info( "Citations: %s", [c['range'] for c in location.getReferenceCitations()] ) attestations = location.getAttestations() attestations = [ {'timePeriod': 'roman', 'confidence': 'confident'}, {'timePeriod': 'late-antique', 'confidence': 'confident'} ] field = location.getField('attestations') field.resize(len(attestations), location) location.update(attestations=attestations) now = DateTime(datetime.datetime.now().isoformat()) location.setModificationDate(now) repo.save(location, MESSAGE) wftool.doActionFor(location, action='submit') wftool.doActionFor(location, action='publish') location.reindexObject() place.setModificationDate(now) repo.save(place, MESSAGE) wftool.doActionFor(place, action='submit') wftool.doActionFor(place, action='publish') place.reindexObject() LOG.info("Finished place: %s", pid) # Bail # assert True == False except Exception, e: savepoint.rollback() LOG.exception("Rolled back after catching exception: %s" % e) transaction.commit() if __name__ == '__main__': # Zopectl doesn't handle command line arguments well, necessitating quoting # like this: # # $ instance run 'names.py -f names.csv -m "Set all descriptions from names-up2.csv again" -j description' parser = OptionParser() parser.add_option( "-f", "--file", dest="filename", help="Input filename", metavar="FILE") parser.add_option( "-u", "--user", dest="user", help="Run script as user") opts, args = parser.parse_args(sys.argv[1:]) filename = opts.filename f = open(filename, 'rb') reader = DictReader(f) site = app['plone'] setup_cmfuid(site) secure(site, opts.user or 'admin') main(site, reader) app._p_jar.sync()