source: exist/trunk/python/ndgUtils/vocabtermdata.py @ 4295

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/exist/trunk/python/ndgUtils/vocabtermdata.py@4295
Revision 4295, 24.6 KB checked in by cbyrom, 11 years ago (diff)

Extend vocabtermdata module to provide utility methods to check if a
vocab data item is of the type deployable (i.e. usable as part of a
deployment) and is of the type deployment + expose method to retrieve
'pretty' title for subtypes + adjust search xqueries to retrieve the
full term urls for atom types and subtypes.

Line 
1#!/usr/bin/env python
2'''
3 Class to store and access the various vocab term data
4 
5 @author: C Byrom, Tessella Jul 2008
6'''
7import sys, logging, commands, string, os, time, re
8import urllib
9
10class VocabTermItem(object):
11    '''
12    Class representing single vocab term item
13    '''
14    def __init__(self, vocabURL, termID, title=None):
15        self.vocabURL = vocabURL
16        self.termID = termID
17        self.title = title
18
19
20class VocabTermDataError(ValueError):
21    """
22    Exception handling for VocabTermData class.
23    """
24    def __init__(self, msg):
25        logging.error(msg)
26        ValueError.__init__(self, msg)
27
28
29class VocabTermData(object):
30    '''
31    Class representing vocab term data - including
32    methods to look these up to ensure they are current
33    '''
34
35    OBJECT_PAGE_TERM = 'ObjectPage'
36    DATA_URL_TERM = 'DataURL'
37    DATA_PAGE_TERM = 'DataPage'
38    CURATOR_PAGE_TERM = 'CuratorPage'
39    EXT_METADATA_TERM = 'ExtMetadata'
40    METADATA_SOURCE_TERM = 'MetadataSource'
41    URI_TERM = 'URI'
42    LOGO_TERM = 'LOGO'
43    NUM_SIM_TERM = 'NumSim'
44    OPENDAP_TERM = 'OPENDAP'
45    THREDDS_TERM = 'THREDDS'
46    WMS_TERM = 'WMS'
47    WCS_TERM = 'WCS'
48    WFS_TERM = 'WFS'
49    LAS_TERM = 'LAS'
50    DATA_EXTRACTOR_TERM = 'DataExtractor' 
51    FILE_BROWSER_TERM = 'FileBrowser'   
52    CSML_TERM = 'CSML'
53   
54    ACTIVITY_TERM = 'ACTIVITY'
55    DPT_TERM = 'DPT'
56    OBS_TERM = 'OBS'
57    GRANULE_TERM = 'GRANULE'
58    DE_TERM = "DE"
59   
60    # dpt subtypes
61    LIDAR_TERM = "dgLidar"
62    RADAR_TERM = "dgRadar"
63    SONDE_TERM = "dgSonde"
64    NAVIGATION_TERM = "dgNavigation"
65    GAS_CHROMATOGRAPH_TERM = "dgGasChromatograph"
66    SPECTROMETER_TERM = "dgSpectrometer"
67    MASS_SPECTROMETER_TERM = "dgMassSpectrometer"
68    MET_SENSOR_TERM = "dgMetSensor"
69    DOAS_TERM = "dgDOAS"
70    ASOZ_TERM = "dgASOZ"
71    RADIOMETER_TERM = "dgRadiometer"
72    FAGE_TERM = "dgFAGE"
73    IMAGER_TERM = "dgImager"
74    FILTER_TERM = "dgFilter"
75    PARTICLE_COUNTER_TERM = "dgParticleCounter"
76    SAMPLER_TERM = "dgSampler"
77    OTHER_INSTRUMENT_TYPE_TERM = "dgOtherInstrumentType"
78    MODEL_TERM = "dgModel"
79    INSTRUMENT_TERM = "dgInstrument"
80   
81    # de subtypes
82    SIMULATION_TERM = "dgSimulation"
83    ANALYSIS_TERM = "dgAnalysis"
84    MEASUREMENT_TERM = "dgMeasurement"
85   
86    # activity subtypes
87    DATA_COLLECTION_TERM = "dgActivityDataCollection"
88    DATA_PROJECT_TERM = "dgActivityDataProject"
89    DATA_CAMPAIGN_TERM = "dgActivityDataCampaign"
90    DATA_INVESTIGATION_TERM = "dgActivityDataInvestigation"
91    FLIGHT_TERM = "dgFlight"
92    CRUISE_TERM = "dgCruise"
93    FUNDING_PROGRAM_TERM = "dgFundingProgram"
94    DEPLOYMENT_TERM = "Deployment"
95    # NB, this is a specialised activity with the subtype deployment pre-set
96    ACTIVITY_DEPLOYMENT_TERM = "ActivityDeployment"
97   
98    # obs subtypes
99    STATIONARY_PLATFORM_TERM = "dgStationaryPlatform"
100    MOVING_PLATFORM_TERM = "dgMovingPlatform"
101    LAND_STATION_TERM = "dgLandStation"
102    MOORING_TERM = "dgMooring"
103    STATION_GROUP_TERM = "dgStationGroup"
104    SHIP_TERM = "dgShip"
105    AIRCRAFT_TERM = "dgAircraft"
106    SATELLITE_TERM = "dgSatellite"
107    COMPUTER_TERM = "dgComputer"
108
109    # provider types
110    BADC_TERM = 'badc.nerc.ac.uk'
111    NEODC_TERM = 'neodc.nerc.ac.uk'
112   
113    TERM_DATA = {
114                 OBJECT_PAGE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '1', title = 'Object Home Page'),
115                 DATA_URL_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '2', title = 'Data URL'),
116                 DATA_PAGE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '3', title = 'Data Home Page'),
117                 CURATOR_PAGE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '4', title = 'Curator Home Page'),
118                 EXT_METADATA_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '5', title = 'Extended Metadata'),
119                 METADATA_SOURCE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '6', title = 'Original Metadata Source'),
120                 #URI_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '3URI', title = 'Data Home Page'),
121                 
122                 BADC_TERM:VocabTermItem('NOT YET SET UP', BADC_TERM, title = 'British Atmospheric Data Centre'),
123                 NEODC_TERM:VocabTermItem('NOT YET SET UP', NEODC_TERM, title = 'NERC Earth Observation Data Centre'),
124                 
125                 LOGO_TERM:VocabTermItem('LOGO', 'LOGO', title = 'Logo'),
126                 NUM_SIM_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '7', title = 'NumSim description'),
127                 OPENDAP_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU010', title = 'GET DATA > OPENDAP DATA (DODS)'),
128                 THREDDS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU013', title = 'GET DATA > THREDDS DATA'),
129                 WMS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU026', title = 'GET SERVICE > GET WEB MAP SERVICE (WMS)'),
130                 WCS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU024', title = 'GET SERVICE > GET WEB COVERAGE SERVICE (WCS)'),
131                 WFS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU025', title = 'GET SERVICE > GET WEB FEATURE SERVICE (WFS)'),
132                 LAS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/P201', 'GCMDU006', title = 'GET DATA > LAS'),
133                 DATA_EXTRACTOR_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '8', title = 'NDG DataExtractor'),
134                 FILE_BROWSER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N041', '9', title = 'File Browser'),
135                 CSML_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/N021', '1'),
136                 ACTIVITY_TERM:VocabTermItem('Activity - NOT YET SET UP', ACTIVITY_TERM, title = 'Activity'),
137                 ACTIVITY_DEPLOYMENT_TERM:VocabTermItem('Activity Deployment - NOT YET SET UP', ACTIVITY_DEPLOYMENT_TERM, title = 'Activity Deployment'),
138                 DPT_TERM:VocabTermItem('DPT - NOT YET SET UP', DPT_TERM, title = 'Data Production Tool'),
139                 OBS_TERM:VocabTermItem('OBS - NOT YET SET UP', OBS_TERM, title = 'Observation Station'),
140                 GRANULE_TERM:VocabTermItem('GRAN - NOT YET SET UP', GRANULE_TERM, title = 'Data Granule'),
141                 DE_TERM:VocabTermItem('DE - NOT YET SET UP', DE_TERM, title = 'Data Entity'),
142                 
143                 LIDAR_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG02', title = "Lidar"),
144                 RADAR_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG03', title = "Radar"),
145                 SONDE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG04', title = "Sonde"),
146                 NAVIGATION_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG05', title = "Navigation"),
147                 GAS_CHROMATOGRAPH_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG06', title = "Gas Chromatograph"),
148                 SPECTROMETER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG07', title = SPECTROMETER_TERM),
149                 MASS_SPECTROMETER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG08', title = MASS_SPECTROMETER_TERM),
150                 MET_SENSOR_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG09', title = MET_SENSOR_TERM),
151                 DOAS_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG10', title = DOAS_TERM),
152                 ASOZ_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG11', title = ASOZ_TERM),
153                 RADIOMETER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG12', title = RADIOMETER_TERM),
154                 FAGE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG13', title = FAGE_TERM),
155                 IMAGER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG14', title = IMAGER_TERM),
156                 FILTER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG15', title = FILTER_TERM),
157                 PARTICLE_COUNTER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG16', title = PARTICLE_COUNTER_TERM),
158                 SAMPLER_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG17', title = SAMPLER_TERM),
159                 OTHER_INSTRUMENT_TYPE_TERM:VocabTermItem('http://vocab.ndg.nerc.ac.uk/term/C330', 'NG99', title = OTHER_INSTRUMENT_TYPE_TERM),
160                 MODEL_TERM:VocabTermItem('dgModel - NOT YET SET UP', MODEL_TERM, title = MODEL_TERM),
161                 INSTRUMENT_TERM:VocabTermItem('dgInstrument - NOT YET SET UP', INSTRUMENT_TERM, title = INSTRUMENT_TERM),
162                 
163                 SIMULATION_TERM:VocabTermItem('NOT YET SET UP', SIMULATION_TERM, title = SIMULATION_TERM),
164                 ANALYSIS_TERM:VocabTermItem('NOT YET SET UP', ANALYSIS_TERM, title = ANALYSIS_TERM),
165                 MEASUREMENT_TERM:VocabTermItem('NOT YET SET UP', MEASUREMENT_TERM, title = MEASUREMENT_TERM),
166                 DATA_COLLECTION_TERM:VocabTermItem('NOT YET SET UP', DATA_COLLECTION_TERM, title = DATA_COLLECTION_TERM),
167                 DATA_PROJECT_TERM:VocabTermItem('NOT YET SET UP', DATA_PROJECT_TERM, title = DATA_PROJECT_TERM),
168                 DATA_CAMPAIGN_TERM:VocabTermItem('NOT YET SET UP', DATA_CAMPAIGN_TERM, title = DATA_CAMPAIGN_TERM),
169                 DATA_INVESTIGATION_TERM:VocabTermItem('NOT YET SET UP', DATA_INVESTIGATION_TERM, title = DATA_INVESTIGATION_TERM),
170                 FLIGHT_TERM:VocabTermItem('NOT YET SET UP', FLIGHT_TERM, title = FLIGHT_TERM),
171                 CRUISE_TERM:VocabTermItem('NOT YET SET UP', CRUISE_TERM, title = CRUISE_TERM),
172                 FUNDING_PROGRAM_TERM:VocabTermItem('NOT YET SET UP', FUNDING_PROGRAM_TERM, title = FUNDING_PROGRAM_TERM),
173                 DEPLOYMENT_TERM:VocabTermItem('NOT YET SET UP', DEPLOYMENT_TERM, title = DEPLOYMENT_TERM),
174                 
175                 STATIONARY_PLATFORM_TERM:VocabTermItem('NOT YET SET UP', STATIONARY_PLATFORM_TERM, title = STATIONARY_PLATFORM_TERM),
176                 MOVING_PLATFORM_TERM:VocabTermItem('NOT YET SET UP', MOVING_PLATFORM_TERM, title = MOVING_PLATFORM_TERM),
177                 LAND_STATION_TERM:VocabTermItem('NOT YET SET UP', LAND_STATION_TERM, title = LAND_STATION_TERM),
178                 MOORING_TERM:VocabTermItem('NOT YET SET UP', MOORING_TERM, title = MOORING_TERM),
179                 STATION_GROUP_TERM:VocabTermItem('NOT YET SET UP', STATION_GROUP_TERM, title = STATION_GROUP_TERM),
180                 SHIP_TERM:VocabTermItem('NOT YET SET UP', SHIP_TERM, title = SHIP_TERM),
181                 AIRCRAFT_TERM:VocabTermItem('NOT YET SET UP', AIRCRAFT_TERM, title = AIRCRAFT_TERM),
182                 SATELLITE_TERM:VocabTermItem('NOT YET SET UP', SATELLITE_TERM, title = SATELLITE_TERM),
183                 COMPUTER_TERM:VocabTermItem('NOT YET SET UP', COMPUTER_TERM, title = COMPUTER_TERM)
184                 }
185
186    ATOM_TYPES = [ACTIVITY_TERM, DE_TERM, DPT_TERM, GRANULE_TERM, OBS_TERM]
187
188    PROVIDER_TYPES = [BADC_TERM, NEODC_TERM]
189
190    ONLINE_REF_TYPES = [ OBJECT_PAGE_TERM, DATA_URL_TERM, DATA_PAGE_TERM, \
191                         CURATOR_PAGE_TERM, EXT_METADATA_TERM, METADATA_SOURCE_TERM, \
192                         NUM_SIM_TERM, \
193                         OPENDAP_TERM, THREDDS_TERM, WMS_TERM, WCS_TERM, WFS_TERM, \
194                         DATA_EXTRACTOR_TERM, FILE_BROWSER_TERM, LAS_TERM, LOGO_TERM]
195#URI_TERM, \
196
197    ATOM_CATEGORY = "atom"
198    ONLINE_REF_CATEGORY = "onlineref"
199    PROVIDER_CATEGORY = "provider"
200   
201    # A dictionary to group the various valid subtypes of atoms - grouped by their
202    # main type
203    SUBTYPE_TERMS = {
204                     DPT_TERM: [
205                        LIDAR_TERM, RADAR_TERM, \
206                        SONDE_TERM, NAVIGATION_TERM, \
207                        GAS_CHROMATOGRAPH_TERM, SPECTROMETER_TERM, \
208                        MASS_SPECTROMETER_TERM,
209                        MET_SENSOR_TERM, DOAS_TERM,
210                        ASOZ_TERM, RADIOMETER_TERM,
211                        FAGE_TERM, IMAGER_TERM,
212                        FILTER_TERM, PARTICLE_COUNTER_TERM,
213                        SAMPLER_TERM, OTHER_INSTRUMENT_TYPE_TERM,
214                        MODEL_TERM, INSTRUMENT_TERM
215                        ],
216                     DE_TERM: [
217                        SIMULATION_TERM, ANALYSIS_TERM, \
218                        MEASUREMENT_TERM       
219                        ],
220                     ACTIVITY_TERM: [
221                        DATA_COLLECTION_TERM, DATA_PROJECT_TERM, \
222                        DATA_CAMPAIGN_TERM, DATA_INVESTIGATION_TERM, \
223                        FLIGHT_TERM, CRUISE_TERM, \
224                        FUNDING_PROGRAM_TERM, DEPLOYMENT_TERM
225                        ],
226                     OBS_TERM: [
227                        STATIONARY_PLATFORM_TERM, MOVING_PLATFORM_TERM, \
228                        LAND_STATION_TERM, MOORING_TERM, \
229                        STATION_GROUP_TERM, SHIP_TERM, \
230                        AIRCRAFT_TERM, SATELLITE_TERM, \
231                        COMPUTER_TERM
232                        ]
233                     }
234   
235    ONE_HOUR = 3600.0
236   
237    VOCAB_SERVER_URL = 'http://vocab.ndg.nerc.ac.uk/clients/whatLists'
238
239    BROWSE_ROOT_URL = "http://localhost:5000/view/"
240
241    def __init__(self):
242        logging.info("Setting up VocabTermData object")
243        self.VOCAB_DATA_PAGE = None
244        # introduce slight delay here
245        self.REFRESH_TIME = time.time() - 2.0
246        self.latestTermVersion = {}
247        logging.info("VocabTermData object set up")
248
249
250    def isValidSubType(self, mainType, subType):
251        '''
252        Determine whether a specified subtype is valid for a particular
253        main type
254        @param mainType: term ID of the main type of the data
255        @param subType: term ID of the subtype of the data
256        @return: True if the subtype is valid
257        @raise ValueError: if the mainType is not recognised or the subType is not valid
258        '''
259        if not self.SUBTYPE_TERMS.has_key(mainType):
260            errorMessage = "Error: unrecognised data type: '%s'" %mainType
261            logging.error(errorMessage)
262            raise ValueError(errorMessage)
263
264        if subType in self.SUBTYPE_TERMS[mainType]:
265            return True
266           
267        errorMessage = "Error: subtype, '%s' is not valid for data type, '%s'" \
268            %(subType, mainType)
269        logging.error(errorMessage)
270        raise ValueError(errorMessage)
271
272
273    def getValidTypes(self, category):
274        '''
275        Return a list of the valid types available for a particular data category
276        @param category: type of term info to look up - e.g. atoms or providers
277        - this should be specified using the ..._CATEGORY instance variables
278        defined above
279        @return list of VocabTermInfo objects for the specified category
280        '''
281        logging.debug("Lookup up list of valid %s types" %category)
282        catList = []
283        if category == self.ATOM_CATEGORY:
284            catList = self.ATOM_TYPES
285        elif category == self.PROVIDER_CATEGORY:
286            catList = self.PROVIDER_TYPES
287        elif category == self.ONLINE_REF_CATEGORY:
288            catList = self.ONLINE_REF_TYPES
289        else:
290            errorMessage = "Unrecognised data category, '%s'" %category
291            logging.info(errorMessage)
292            raise ValueError(errorMessage)
293           
294        types = []
295        for st in catList:
296            types.append(self.TERM_DATA[st])
297        return types
298
299
300    def tidySubTypeTitle(self, title):
301        '''
302        Tidy up the title of subtypes slightly, if need be
303        - NB, these are inherited from original moles format so are
304        not really 'human readable'
305        '''
306        if title and title.startswith('dg'):
307            title = title[2:]
308            # and fix any camelcase - putting into words
309            title = re.sub('([A-Z])', r" \1", title).strip()
310
311        return title
312
313    def getValidSubTypes(self, atomType):
314        '''
315        Get list of subtypes that are valid wrt a specified atom type
316        @param atomType: term ID for the atom type whose subtypes need to
317        be looked up
318        @return: list of valid subtypes
319        '''
320        logging.debug("Lookup up subtypes for atom type, '%s'" %atomType)
321        subTypes = self.SUBTYPE_TERMS.get(atomType) or []
322        types = []
323        for st in subTypes:
324            item = self.TERM_DATA[st]
325            item.title = self.tidySubTypeTitle(item.title)
326            types.append(item)
327        logging.debug("Found subtypes: %s" %subTypes)
328        return types
329
330       
331    def getTermFromTitle(self, title):
332        '''
333        Given a term title/label, get back the related term id
334        @param title: title/label of term id to retrieve
335        @raise ValueError: if more than one title or no title is returned 
336        '''
337        termID = []
338        for val in self.TERM_DATA.itervalues():
339            if val.title == title:
340                termID.append(val.termID)
341       
342        if len(termID) != 1:
343            errorMessage = "Error: could not accurately determine the vocab term \
344                ID for the label, '%s' - %s values returned" %(title, len(termID))
345            logging.error(errorMessage)
346            raise ValueError(errorMessage)
347
348        return termID[0]
349       
350
351    def _getVocabDataPage(self):
352        '''
353        Getter method to allow regular refreshing of data
354        '''
355        if self.REFRESH_TIME < time.time():
356            self.getVocabServerData()
357       
358        return self.VOCAB_DATA_PAGE
359
360   
361    def getVocabServerData(self):
362        '''
363        Retrieve the web page containing the versioning info for the various vocab terms
364        '''
365        logging.info("Retrieving vocab server data page")
366        f = urllib.urlopen(self.VOCAB_SERVER_URL)
367        self.VOCAB_DATA_PAGE = f.read()
368        f.close()
369        self.REFRESH_TIME = time.time() + self.ONE_HOUR
370        logging.info("Vocab server data retrieved")
371
372
373    def getLatestTermVersions(self):
374        '''
375        Retrieve the latest versions of the vocab terms required
376        - NB, refreshes the data on an hourly basis, if necessary
377        '''
378        # now need to parse the returned data to get the current version number
379        for termName in self.TERM_DATA:
380            if termName not in self.latestTermVersion:
381                self.getLatestTermVersion(termName)
382
383                   
384    def getLatestTermVersion(self, termName):
385        '''
386        Parse the vocab server data and determine the latest version number of the term with the specified name
387        @param termName: name of term whose current version needs to be established
388        '''
389        logging.info("Getting latest term version for term, '%s'" %termName)
390        # check for recent data - NB, the term will probably share a base url with other terms
391        # so may have already have the correct URL set up
392        if termName not in self.latestTermVersion or self.REFRESH_TIME < time.time():
393   
394            uri = self.TERM_DATA[termName].vocabURL
395            currentVersion = self._getURIVersion(uri)
396   
397            self.latestTermVersion[termName] = str(currentVersion)
398        logging.info("Latest term version for term, '%s' retrieved" %termName)
399
400
401    def _getURIVersion(self, uri):
402        '''
403        Parse the server data for a specified uri and return the latest version number of it
404        @param uri: uri to look for
405        @raise ValueError: if specified uri not found in vocab server
406        @return version of vocab uri, '' if uri contains latest version and None if uri not found
407        '''
408        # allow the data to be refreshed on an hourly basis
409        pageData = self._getVocabDataPage()
410       
411        uri = uri.replace('/term/','/list/')
412        if uri.endswith('/'):
413            uri = uri.rstrip('/')
414        # NB, the uri may already have a version number included in it - so allow this in the search
415        regExp = re.compile(r'(' + uri + '(/(\d{1,}))?)')
416        currentVersion = None
417        foundTerm = False
418        for termVals in regExp.findall(pageData):
419            foundTerm = True
420            version = termVals[2]
421            # version number must be included in original uri, if match found without a version number
422            # being split out - so ignore this - since the original uri is already specified in full
423            if not version:
424                currentVersion = ''
425                break
426
427            # TODO: check how the versioning system will be done - i.e. 3.2.4 type versioning will cause this to break
428            if not currentVersion:
429                currentVersion = int(version)
430            elif int(version) > currentVersion:
431                currentVersion = int(version)
432
433        if currentVersion == None:
434            errorMessage = "Could not find information in vocab server for uri, '%s' - exiting" %uri
435            logging.error(errorMessage)
436            # TODO: uncomment the ValueError once all the vocab terms have been defined
437            #raise ValueError(errorMessage)
438
439        return currentVersion
440
441       
442    def getTermCurrentVocabURL(self, termName):
443        '''
444        Get the current URL on the vocab server to the specified term
445        @param termName: name of term whose URL to return
446        '''
447        logging.debug("Looking up vocab data for term: '%s'" %termName)
448       
449        if termName not in self.TERM_DATA:
450            errorMessage = "Could not find term, '%s' in defined list of valid vocab terms - exiting" %termName
451            logging.error(errorMessage)
452            raise ValueError(errorMessage)
453       
454        if termName not in self.latestTermVersion:
455            self.getLatestTermVersion(termName)
456
457        uri = self.TERM_DATA[termName].vocabURL + \
458            "/" + self.latestTermVersion[termName] + "/" + \
459            self.TERM_DATA[termName].termID
460        logging.debug("Returning vocab URL: '%s'" %uri)
461        return  uri
462   
463   
464    def getCurrentVocabURI(self, uri):
465        '''
466        Look up a specified URI and return the current version of it
467        '''
468        logging.debug("Looking up current version of uri: '%s'" %uri)
469        currentVersion = self._getURIVersion(uri)
470        logging.debug("URI version looked up")
471        if currentVersion is not None:
472            if not uri.endswith('/'):
473                uri += '/'
474            return uri + str(currentVersion)
475        return uri
476   
477    def getVTI(self, term):
478        '''
479        Return the vocab term item for the specified term
480        @param term: term ID - one of the constants defined above
481        @return VocabTermItem corresponding to term
482        @raise VocabTermDataError if term not found
483        '''
484        vti = self.TERM_DATA.get(term)
485        if not vti:
486            raise VocabTermDataError("No info for term, '%s', found" %term)
487   
488        return vti
489   
490   
491    def getTermItemfromFullVocabURI(self, uri):
492        '''
493        Given a full term id - i.e. with vocab uri + version + term ID
494        determine the correct vocab data term item
495        @param uri: full term ID with version + vocab uri
496        @return vocab term item corresponding to the input uri
497        @raise ValueError if term ID not found
498        '''
499        logging.debug("Determining term ID for uri, '%s'" %uri)
500        termID = uri.split('/')[-1]
501        vti = None
502        if self.TERM_DATA.get(termID) and uri.startswith(self.TERM_DATA[termID].vocabURL):
503            vti = self.TERM_DATA[termID]
504        else:
505            for item in self.TERM_DATA.itervalues():
506                if item.termID == termID and uri.startswith(item.vocabURL):
507                    vti = item
508                    break
509       
510        if not vti:
511            raise VocabTermDataError("Unrecognised term URI: '%s'" %uri)
512
513        logging.debug("Found matching term - '%s'" %vti.termID)
514        return vti
515   
516   
517    def isDeployable(self, vti):
518        '''
519        Determines whether a vocab term item can be used as part of a deployment
520        @param vti: vocab term item to check
521        @return True if allowed as part of deployment, false otherwise
522        '''
523        logging.debug("Checking if item is deployable")
524        if vti:
525            if vti.termID == self.ACTIVITY_TERM or \
526                vti.termID == self.DPT_TERM or \
527                vti.termID == self.OBS_TERM:
528                logging.debug("- item is deployable")
529                return True
530       
531        logging.debug("- item is not deployable")
532        return False
533   
534   
535    def isDeployment(self, vti):
536        '''
537        Determines whether a vocab term item is a deployment item
538        @param vti: vocab term item to check
539        @return True if a deployment, false otherwise
540        '''
541        logging.debug("Checking if item is a deployment")
542        if vti:
543            if vti.termID == self.DEPLOYMENT_TERM:
544                logging.debug("- item is a deployment")
545                return True
546       
547        logging.debug("- item is not a deployment")
548        return False
549               
Note: See TracBrowser for help on using the repository browser.