Changeset 1107

Show
Ignore:
Timestamp:
08/28/07 23:08:02 (1 year ago)
Author:
sgillies
Message:

Improved load_place with use of transaction savepoints

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • PleiadesEntity/trunk/Extensions/loader.py

    r1088 r1107  
    3535import lxml.etree as etree 
    3636 
     37import transaction 
     38 
    3739from Products.CMFCore.utils import getToolByName 
    3840 
     
    4345 
    4446batlas_pattern = re.compile(r'batlas-(\w+)-(\w+)-(\w+)') 
     47 
    4548 
    4649def baident(identifier): 
     
    136139    appropriate temporalAttestation children of the object at  
    137140    portalcontext.""" 
    138      
     141    
     142    wftool = getToolByName(portalcontext, 'portal_workflow') 
     143 
    139144    for tp in  xmlcontext.findall("{%s}timePeriod" % ADLGAZ): 
    140145        tpn = tp.xpath("*[local-name()='timePeriodName']") 
     
    158163        period=periods[tpnstr] 
    159164        id=period_ids[tpnstr] 
     165         
    160166        try: 
    161167            portalcontext.invokeFactory('TemporalAttestation', 
     
    167173            raise EntityLoadError, "There is already a TemporalAttestation with id=%s in portal context = %s" % (id, portalcontext.Title()) 
    168174 
    169 def parse_secondary_references(xmlcontext, portalcontext, ptool): 
     175        wftool.doActionFor(getattr(portalcontext, id), "publish") 
     176 
     177 
     178def parse_secondary_references(xmlcontext, portalcontext, ptool, wftool): 
    170179    srs =  xmlcontext.find("{%s}secondaryReferences" % AWMC) 
    171180    if srs: 
     
    199208                    raise 
    200209                    #raise EntityLoadError, "There is already a SecondaryReference with id=%s in portal context" % id 
    201              
     210                 
     211                wftool.doActionFor(getattr(portalcontext, id), "publish") 
     212 
    202213import sys 
    203214 
    204 def load_place(site, file): 
    205     """Create a new Place in plonefolder and populate it with 
    206     the data found in the xml file at sourcepath.""" 
    207  
    208     root = etree.parse(file).getroot() 
    209     ptool = getToolByName(site, 'plone_utils') 
    210  
    211     places = site.places 
    212     names = site.names 
    213     locations = site.locations 
    214  
    215     # Authorship 
     215def parse_attrib_rights(xmlcontext): 
     216    root = xmlcontext 
    216217    creators = [e.text for e in root.findall("{%s}creator" % DC)] 
    217218    contributors = [e.text for e in root.findall("{%s}contributor" % DC)] 
    218      
    219     # Rights 
    220219    e = root.findall("{%s}rights" % DC) 
    221220    if e: 
     
    223222    else: 
    224223        rights = None 
    225          
    226     # lists of location and name ids 
    227     lids = [] 
     224    return (creators, contributors, rights) 
     225 
     226def parse_names(xmlcontext, portalcontext, ptool, wftool): 
     227    root = xmlcontext 
     228    names = portalcontext 
    228229    nids = [] 
    229230    association_certainties = [] 
    230231 
    231     # Names 
     232    creators, contributors, rights = parse_attrib_rights(root) 
     233 
    232234    for e in root.findall("{%s}featureName" % ADLGAZ): 
    233235        transliteration = e.findall("{%s}transliteration" % AWMC)[0].text 
     
    326328            name = getattr(names.duplicates, nid) 
    327329 
     330        wftool.doActionFor(name, "publish") 
     331          
    328332        nids.append(nid) 
    329333        association_certainties.append(certainty) 
     
    333337         
    334338        # SecondaryReferences associated with the name 
    335         parse_secondary_references(e, name, ptool) 
    336         name.reindexObject() 
    337          
    338     # Locations 
     339        parse_secondary_references(e, name, ptool, wftool) 
     340        #name.reindexObject() 
     341         
     342    return (nids, association_certainties) 
     343 
     344def parse_locations(xmlcontext, portalcontext, ptool, wftool): 
     345    root = xmlcontext 
     346    lids = [] 
     347 
     348    # Attribution and rights 
     349    creators, contributors, rights = parse_attrib_rights(root) 
     350 
    339351    for e in root.findall("{%s}spatialLocation" % ADLGAZ): 
    340352        coords = e.findall("{%s}point" % GEORSS)[0].text 
    341353 
    342         lid = locations.invokeFactory('Location', 
     354        lid = portalcontext.invokeFactory('Location', 
    343355                    geometryType='Point', 
    344356                    spatialCoordinates=str(coords), 
     
    348360                    ) 
    349361         
     362        wftool.doActionFor(getattr(portalcontext, lid), "publish") 
    350363        lids.append(lid) 
    351364         
    352365        # Time Periods associated with the location 
    353         parse_periods(root, getattr(locations, lid)) 
    354          
    355         getattr(locations, lid).reindexObject() 
    356  
    357     # Place 
    358     e = root.findall("{%s}modernLocation" % AWMC) 
    359     if e: 
    360         modernLocation = str(e[0].text.encode('utf-8')) 
    361     else: 
    362         modernLocation = 'None' 
    363  
    364     e = root.findall("{%s}classificationSection/{%s}classificationTerm" \ 
    365                      % (ADLGAZ, ADLGAZ)) 
    366     if e: 
    367         placeType = str(e[0].text) 
    368     else: 
    369         placeType = 'unknown' 
    370     legaltypes = ['aqueduct', 'bath', 'bay', 'bridge', 'canal', 'cape', 'cave', 'cemetery', 'centuriation', 'church', 'coast', 'dam', 'estate', 'estuary', 'false', 'findspot', 'forest', 'fort', 'hill', 'island', 'lighthouse', 'mine', 'mountain', 'oasis', 'pass', 'people', 'plain', 'port', 'production', 'region', 'reservoir', 'ridge', 'river', 'road', 'salt-marsh', 'settlement', 'settlement-modern', 'spring', 'station', 'temple', 'tumulus', 'undefined', 'unknown', 'unlocated', 'valley', 'villa', 'wall', 'water-inland', 'water-open', 'well', 'wheel', 'whirlpool'] 
     366        parse_periods(root, getattr(portalcontext, lid)) 
     367         
     368        #getattr(locations, lid).reindexObject() 
     369 
     370    return lids 
     371 
     372def load_place(site, file): 
     373    """Create a new Place in plonefolder and populate it with 
     374    the data found in the xml file at sourcepath.""" 
     375 
     376    ptool = getToolByName(site, 'plone_utils') 
     377    wftool = getToolByName(site, 'portal_workflow') 
     378 
     379    places = site.places 
     380    names = site.names 
     381    locations = site.locations 
     382 
     383    savepoint = transaction.savepoint() 
     384     
    371385    try: 
    372         ptidx = legaltypes.index(placeType
    373     except: 
    374         raise EntityLoadError, "Invalid placeType  = %s" % placeType 
     386        root = etree.parse(file).getroot(
     387        
     388        creators, contributors, rights = parse_attrib_rights(root) 
    375389             
    376     e = root.findall("{%s}description" % DC) 
    377     if e: 
    378         description = e[0].text.encode('utf-8') 
    379     else: 
    380         description = '' 
    381  
    382     # Get the legacy BA identifier 
    383     e = root.findall("{%s}featureID" % ADLGAZ) 
    384     fid = str(e[0].text) 
    385     if fid.startswith('batlas'): 
    386         id = baident(fid) 
    387     else: 
    388         id = None 
    389  
    390     placeNames = [getattr(names, nid) for nid in nids] 
    391     computedTitle = '/'.join([n.Title() for n in placeNames]) 
    392      
    393     # Catch attribute errors from the case of pre-existing content and 
    394     # move on. This lets us run loads again over previously loaded data. 
    395     try: 
     390        # Names 
     391        nids, association_certainties = parse_names(root, names, ptool, wftool) 
     392 
     393        # Locations 
     394        lids = parse_locations(root, locations, ptool, wftool) 
     395     
     396        # Place 
     397        e = root.findall("{%s}modernLocation" % AWMC) 
     398        if e: 
     399            modernLocation = str(e[0].text.encode('utf-8')) 
     400        else: 
     401            modernLocation = 'None' 
     402     
     403        e = root.findall("{%s}classificationSection/{%s}classificationTerm" \ 
     404                         % (ADLGAZ, ADLGAZ)) 
     405        if e: 
     406            placeType = str(e[0].text) 
     407        else: 
     408            placeType = 'unknown' 
     409        legaltypes = ['aqueduct', 'bath', 'bay', 'bridge', 'canal', 'cape', 'cave', 'cemetery', 'centuriation', 'church', 'coast', 'dam', 'estate', 'estuary', 'false', 'findspot', 'forest', 'fort', 'hill', 'island', 'lighthouse', 'mine', 'mountain', 'oasis', 'pass', 'people', 'plain', 'port', 'production', 'region', 'reservoir', 'ridge', 'river', 'road', 'salt-marsh', 'settlement', 'settlement-modern', 'spring', 'station', 'temple', 'tumulus', 'undefined', 'unknown', 'unlocated', 'valley', 'villa', 'wall', 'water-inland', 'water-open', 'well', 'wheel', 'whirlpool'] 
     410        try: 
     411            ptidx = legaltypes.index(placeType) 
     412        except: 
     413            raise EntityLoadError, "Invalid placeType  = %s" % placeType 
     414                 
     415        e = root.findall("{%s}description" % DC) 
     416        if e: 
     417            description = e[0].text.encode('utf-8') 
     418        else: 
     419            description = '' 
     420     
     421        # Get the legacy BA identifier 
     422        e = root.findall("{%s}featureID" % ADLGAZ) 
     423        fid = str(e[0].text) 
     424        if fid.startswith('batlas'): 
     425            id = baident(fid) 
     426        else: 
     427            id = None 
     428     
     429        placeNames = [getattr(names, nid) for nid in nids] 
     430        computedTitle = '/'.join([n.Title() for n in placeNames]) 
     431         
    396432        pid = places.invokeFactory('Place', 
    397433                    id=id, 
     
    404440                    ) 
    405441        p = getattr(places, pid) 
    406         p.reindexObject() 
    407     except AttributeError: 
    408         return {'place_id': None, 'location_ids': None, 'name_ids': None} 
    409  
    410     # Iterate over locations 
    411     for lid in lids: 
    412         # Handle the unnamed case 
    413         if len(nids) == 0: 
    414             aid = p.invokeFactory('PlacefulAssociation', 
    415                 id="unnamed-%s" % lid, 
    416                 placeType=placeType, 
    417                 associationCertainty='certain', 
    418                 ) 
    419             a = getattr(p, aid) 
    420             a.addReference(getattr(locations, lid), 'hasLocation') 
    421          
    422             # Secondary references for the place 
    423             parse_secondary_references(root, a, ptool) 
    424             a.reindexObject() 
    425          
    426         else: 
    427             for i, nid in enumerate(nids): 
    428                 # Get association certainty from XML 
    429                 certainty = association_certainties[i] 
    430              
     442        wftool.doActionFor(p, "publish") 
     443        #p.reindexObject() 
     444     
     445        # Iterate over locations 
     446        for lid in lids: 
     447            # Handle the unnamed case 
     448            if len(nids) == 0: 
    431449                aid = p.invokeFactory('PlacefulAssociation', 
    432                     id="%s-%s" % (nid,lid)
     450                    id="unnamed-%s" % lid
    433451                    placeType=placeType, 
    434                     associationCertainty=certainty
     452                    associationCertainty='certain'
    435453                    ) 
    436454                a = getattr(p, aid) 
    437455                a.addReference(getattr(locations, lid), 'hasLocation') 
     456                wftool.doActionFor(a, "publish") 
     457             
     458                # Secondary references for the place 
     459                parse_secondary_references(root, a, ptool, wftool) 
     460                #a.reindexObject() 
     461             
     462            else: 
     463                for i, nid in enumerate(nids): 
     464                    # Get association certainty from XML 
     465                    certainty = association_certainties[i] 
     466                 
     467                    aid = p.invokeFactory('PlacefulAssociation', 
     468                        id="%s-%s" % (nid,lid), 
     469                        placeType=placeType, 
     470                        associationCertainty=certainty, 
     471                        ) 
     472                    a = getattr(p, aid) 
     473                    a.addReference(getattr(locations, lid), 'hasLocation') 
     474                    a.addReference(getattr(names, nid), 'hasName') 
     475                    wftool.doActionFor(a, "publish") 
     476             
     477                    # Secondary references for the place 
     478                    parse_secondary_references(root, a, ptool, wftool) 
     479                    #a.reindexObject() 
     480     
     481        # If there are no locations, iterate over the names 
     482        if len(lids) == 0: 
     483            for nid in nids: 
     484                aid = p.invokeFactory('PlacefulAssociation', 
     485                        id="%s-unlocated" % nid, 
     486                        placeType=placeType, 
     487                        associationCertainty='certain', 
     488                        ) 
     489                a = getattr(p, aid) 
    438490                a.addReference(getattr(names, nid), 'hasName') 
    439          
     491                wftool.doActionFor(a, "publish") 
    440492                # Secondary references for the place 
    441                 parse_secondary_references(root, a, ptool) 
    442                 a.reindexObject() 
    443  
    444     # If there are no locations, iterate over the names 
    445     if len(lids) == 0: 
    446         for nid in nids: 
    447             aid = p.invokeFactory('PlacefulAssociation', 
    448                     id="%s-unlocated" % nid, 
    449                     placeType=placeType, 
    450                     associationCertainty='certain', 
    451                     ) 
    452             a = getattr(p, aid) 
    453             a.addReference(getattr(names, nid), 'hasName') 
    454             # Secondary references for the place 
    455             parse_secondary_references(root, a, ptool) 
    456             a.reindexObject() 
    457  
     493                parse_secondary_references(root, a, ptool, wftool) 
     494                #a.reindexObject() 
     495 
     496    except: 
     497        savepoint.rollback() 
     498        raise 
     499 
     500    transaction.commit() 
    458501    return {'place_id': pid, 'location_ids': lids, 'name_ids': nids} 
    459502 
  • PleiadesEntity/trunk/tests/LoadEntity.txt

    r1072 r1107  
    1010Setup 
    1111----- 
     12 
     13    >>> import transaction 
     14    >>> self.setRoles(('Manager',)) 
    1215 
    1316    Enable types 
     
    2831 
    2932    >>> _ = folder.invokeFactory('Large Plone Folder', id='names') 
     33    >>> _ = folder.names.invokeFactory('Large Plone Folder', id='duplicates') 
    3034    >>> _ = folder.invokeFactory('LocationContainer', id='locations') 
    3135    >>> _ = folder.invokeFactory('PlaceContainer', id='places') 
     36 
     37    >>> transaction.commit() 
    3238 
    3339Load one entity 
     
    7177    4 
    7278    >>> [s.id for s in srs] 
    73     ['65-a2-aphrodisias-ninoe', 'aphrodisias-2', 'aphrodisias-1', 'ninoe'] 
     79    ['batlas-65-a2-aphrodisias-ninoe', 're-aphrodisias-2', 'npauly-aphrodisias-1', 're-ninoe'] 
    7480    >>> [s.Title for s in srs] 
    7581    ['BAtlas 65 A2 Aphrodisias/Ninoe', 'RE Aphrodisias 2', 'NPauly Aphrodisias 1', 'RE Ninoe'] 
     
    123129    2 
    124130    >>> [s.id for s in srs] 
    125     ['aphrodisias-2', 'aphrodisias-1'] 
     131    ['re-aphrodisias-2', 'npauly-aphrodisias-1'] 
    126132    >>> [s.Title for s in srs] 
    127133    ['RE Aphrodisias 2', 'NPauly Aphrodisias 1'] 
     
    291297    {'description': 'An ancient fort, attested during the Roman period (modern location: Emeriye). Its ancient name is not known.', 'spatialCoordinates': '37.1751 31.7324 0.0', 'url': 'http://nohost/plone/Members/test_user_1_/places/638830', 'title': '638830', 'srs': 'EPSG:4326', 'geometryType': 'point', 'id': '638830'} 
    292298 
     299 
     300Reload that entity 
     301------------------ 
     302 
     303Reloading that entity should result in an error 
     304 
     305    >>> load_place(folder, "%s/batlas-65-2-24-frank.xml" % TEST_DATA) 
     306    Traceback (most recent call last): 
     307    ... 
     308    BadRequest: The id ... is invalid - it is already in use. 
     309 
     310 
    293311Load one unlocated entity 
    294312-------------------------