source: mauRepo/MolesManager/trunk/src/libs/migration/processor/deployment.py @ 8425

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/MolesManager/trunk/src/libs/migration/processor/deployment.py@8425
Revision 8425, 35.1 KB checked in by mnagni, 9 years ago (diff)

Complete - # 22488: CEDA Observation Collection - Geographical Extent
 http://team.ceda.ac.uk/trac/ceda/ticket/22488
Complete - # 22513: Missing ValidTime? tag in the CedaSearch?
 http://team.ceda.ac.uk/trac/ceda/ticket/22513

Line 
1'''
2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29Created on 15 Nov 2011
30
31@author: Maurizio Nagni
32'''
33from libs.migration.processor.commons import findMolesLineage,\
34    createMO_ResponsiblePartyInfo,\
35    DO_BADC, DO_NEODC, findAuthorsInResource, \
36    createMD_Identifier, extractSummary, extractQuality, \
37    hasMOSameHash, getAtomDocumentHashByMO, extractTitle,\
38        createCEDA_Result,\
39    createEX_GeographicBoundingBox, extractGeographicExtentInMigrationDocument, findDownloadLinksInMigrationDocument,\
40    extractContent, createCI_Citation, createCI_Date, createDate,\
41    createTM_Position, createTM_Instant, extractMolesCreationDate,\
42    createDateTime, isoDateTimeStringToTimeDate, extractMolesProviderID,\
43    DO_UKSSDC, createMO_Organization,\
44    createCI_Contact, createCI_Address, createCI_OnlineResource,\
45    createCI_Telephone, extractMolesTemporalRange, isoDateStringToTimeDate,\
46    createTM_Period, findAccessLinksInMigrationDocument,\
47    findLinksInDeployment, createMD_LegalConstraints,\
48    createDQ_Element, createDQ_ConformanceResult, findUpdatedDate,\
49    createMD_Metadata, createMO_OnlineResource, createCEDA_Review, calculateHash,\
50    createCI_ResponsibleParty, extractUpdateFrequency,\
51    findLinksInMigrationDocument, findSubTypeInDPT, extractMolesPublishedDate,\
52    createMD_Keywords, hasMOBeenProcessed, createMO_Individual
53from libs.epb import EPB
54from libs.migration.processor.deployment_data import DeploymentDataProcessor
55from libs.migration.exception.exceptions import NoDataLineage,\
56    NoAssociatedAuthor, NoAssociatedDeployments
57from libs.migration.authors import authors
58from logging import StreamHandler
59import logging
60from datetime import date
61from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_onlinefunctioncode import CI_OnLineFunctionCode
62from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_datetypecode import CI_DateTypeCode
63from ea_model.iso_19115_2006_metadata_corrigendum.constraint_information.md_restrictioncode import MD_RestrictionCode
64from copy import deepcopy
65import datetime
66from MolesManager.ceda_guid import CedaGUID
67from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_rolecode import CI_RoleCode
68from ea_model.iso_19115_2006_metadata_corrigendum.maintenance_information.md_maintenancefrequencycode import MD_MaintenanceFrequencyCode
69from ea_model.moles3_4.utilities.ceda_rolevalue import CEDA_RoleValue
70from ea_model.moles3_4.observation.mo_observationpublicationstatevalue import MO_ObservationPublicationStateValue
71from MolesManager.codelist import MM_RoleValue,\
72    MM_ObservationPublicationStateValue, getCLValue
73from ea_model.ceda_metadatamodel.ceda_observation.ceda_observation import CEDA_Observation
74from ea_model.ceda_metadatamodel.ceda_result.ceda_curationvalue import CEDA_CurationValue
75from ea_model.ceda_metadatamodel.ceda_utilities.ceda_reviewstatusvalue import CEDA_ReviewStatusValue
76from ea_model.ceda_metadatamodel.ceda_utilities.ceda_reviewfrequencyvalue import CEDA_ReviewFrequencyValue
77
78MET_GEO_FEATURE = 'Meteorological geographical features'
79ORTHOIMAGERY = 'Orthoimagery'
80           
81class DeploymentProcessor(object):
82    '''
83        Migrates a deployment element in a CEDA_Observation entity
84    '''
85    publisherName = 'CEDA'
86   
87    log = logging.getLogger('DeploymentProcessor')
88    log.addHandler(StreamHandler())
89    log.setLevel(logging.INFO)   
90    def __init__(self, dataEntityMigration, deploymentMigration, epbRepo):
91        '''
92            Initializes the class
93            @param dataEntityMigration: a DataEntityMigration instance
94            @param deploymentMigration: the DeploymentMigration instance
95            @param epbRepo: an instance of EPBRepo             
96        '''             
97        self._dataEntityMigration = dataEntityMigration
98        self._deploymentMigration = deploymentMigration
99        self.epbRepo = epbRepo
100        self._dataEntityHasSameHash = hasMOSameHash(self._dataEntityMigration)
101        self._deploymentHasSameHash = hasMOSameHash(self._deploymentMigration)
102        self._deploymentHasBeenProcessed = hasMOBeenProcessed(self._deploymentMigration)
103
104    def _addResponsiblePartyInfo(self, oldResponsiblePartyInfos, newResponsiblePartyInfo):
105        opi = None
106        for oldPartyInfo in oldResponsiblePartyInfos:
107            if oldPartyInfo.role == newResponsiblePartyInfo.role:
108                opi = oldPartyInfo
109                break
110           
111        if len(oldResponsiblePartyInfos) == 0 or opi is None:
112            oldResponsiblePartyInfos.append(newResponsiblePartyInfo)
113       
114        if opi is not None: 
115            for np in newResponsiblePartyInfo.party:
116                opi.party.append(np)
117       
118
119
120
121    def _extractIndividualsAndOrganizations(self, tmp_auth, whereAreAuthors):
122        if whereAreAuthors is None:
123            raise NoAssociatedDeployments("migrationObject is None")
124        try:
125            if tmp_auth['author'] == 'unknown':
126                doc_authors = findAuthorsInResource(self._dataEntityMigration)
127                tmp_auth = authors[doc_authors['authors']]
128           
129            ret = {'ind': [], 'org': [], 'co_ind': [], 'co_org': []}
130            if tmp_auth['type'] == 'ind':
131                ret['ind'].append(tmp_auth['author'])
132            elif tmp_auth['type'] == 'org':
133                ret['org'].append(tmp_auth['author'])           
134               
135            if tmp_auth['author'] == 'unknown':
136                DeploymentProcessor.log.debug("%s %s %s has unknown author" \
137                                             % (whereAreAuthors.doc_status, whereAreAuthors.doc_owner, whereAreAuthors.doc_name))       
138
139            for item in tmp_auth['co_author_type']:           
140                if (tmp_auth['co_author'][tmp_auth['co_author_type'].index(item)] == 'unknown'):
141                    doc_authors = findAuthorsInResource(self._dataEntityMigration)
142                    tmp_auth = authors[doc_authors['contributors']]
143                    break
144                 
145            for index in range(len(tmp_auth['co_author_type'])): 
146                ptype = tmp_auth['co_author_type'][index]               
147                if ptype == 'ind':
148                    ret['co_ind'].append(tmp_auth['co_author'][index])
149                elif ptype == 'org':
150                    ret['co_org'].append(tmp_auth['co_author'][index])
151           
152                if (tmp_auth['co_author'][index] == 'unknown'):
153                    DeploymentProcessor.log.info("%s %s %s has unknown author" \
154                                                 % (whereAreAuthors.doc_status, whereAreAuthors.doc_owner, whereAreAuthors.doc_name))
155        except Exception as e:
156            print e
157        return ret
158       
159       
160    def updateObservation(self):
161        return EPB.searchOrCreate(CEDA_Observation, self._deploymentMigration.ceda_observation_id)
162
163    def assignDOI(self, observation, doi):
164        if doi and doi.has_key('href'):
165            doi = doi['href'][22:]           
166           
167            #Check if a doi has been already assigned
168            observation = self.epbRepo.moles3EPB.loadAttributes(observation, 'identifier')
169            obs_identifier = observation.identifier
170            if obs_identifier:
171                for ident in obs_identifier:
172                    if ident.code == doi:
173                        return
174           
175            py_date = None
176            cited_responsible = createCI_ResponsibleParty(role=getCLValue(CI_RoleCode.cl_publisher), \
177                                                              organizationName='NERC - British Atmospheric Data Centre')
178            if doi.upper() == '10.5285/E8F43A51-0198-4323-A926-FE69225D57DD':
179                py_date = date(2011, 4, 1)
180            elif doi.upper() == '10.5285/78114093-E2BD-4601-8AE5-3551E62AEF2B':
181                py_date = date(2011, 11, 29)               
182            elif doi.upper() == '10.5285/DB8D8981-1A51-4D6E-81C0-CCED9B921390':
183                py_date = date(2012, 4, 16)
184            elif doi.upper() == '10.5285/639A3714-BC74-46A6-9026-64931F355E07':
185                py_date = date(2012, 4, 16)               
186               
187            if py_date:   
188                dt = createDate(py_date)
189                ci_date = createCI_Date(getCLValue(CI_DateTypeCode.cl_publication), date = dt)
190                i_authority = createCI_Citation("DOI", date = ci_date)
191                identifier = createMD_Identifier(code = doi, authority=i_authority)
192                self.epbRepo.moles3EPB.updateCedaObject(observation, {'identifier': identifier})
193                DeploymentProcessor.log.info("DOI: %s" % (doi))                                 
194
195    def _assignKeywords(self, ceda_observation):
196        if self._deploymentHasSameHash:
197            return
198       
199        provider_id = extractMolesProviderID(self._deploymentMigration)
200        i_keywords = []
201        if provider_id == DO_BADC:
202            i_keywords.append(MET_GEO_FEATURE)
203        if provider_id == DO_NEODC:
204            i_keywords.append(ORTHOIMAGERY)
205        if len(i_keywords) > 0:
206            #Is a first time process?
207            if not self._deploymentHasBeenProcessed: 
208                ceda_observation.keywords.append(createMD_Keywords(i_keywords))
209            else:
210                ceda_observation.keywords.keyword = i_keywords         
211
212    def _assignLineage(self, observation):
213        if self._deploymentHasSameHash:
214            return
215       
216        data_lineage = findMolesLineage(self._dataEntityMigration)
217        if data_lineage is None:
218            raise NoDataLineage(self._dataEntityMigration)
219       
220        if data_lineage != observation.dataLineage:
221            observation.dataLineage = data_lineage 
222
223    def _assignResult(self, observation):
224        if self._deploymentHasSameHash and self._dataEntityHasSameHash:
225            return
226
227        i_sources = []               
228        download = findDownloadLinksInMigrationDocument(self._deploymentMigration)
229        content = None
230        if len(download) == 0:
231            download = findDownloadLinksInMigrationDocument(self._dataEntityMigration)
232            content = extractContent(self._dataEntityMigration)
233        else:
234            content = extractContent(self._deploymentMigration)
235        for dwn in download:
236            int_description = None
237            int_applicationProfile = None
238            if content.has_key('formats'):
239                #int_applicationProfile = content['formats']
240                pass
241            if dwn['href'].startswith('http://badc.nerc.ac.uk/browse') or dwn['href'].startswith('http://neodc.nerc.ac.uk/browse'):
242                int_description = "download directly from archive"   
243            i_sources.append(createMO_OnlineResource(linkage = dwn['href'], name = dwn['title'], \
244                                                   function = getCLValue(CI_OnLineFunctionCode.cl_download), \
245                                                   description = int_description, applicationProfile = int_applicationProfile))
246           
247        dataentity_id = '%s__ATOM__%s' % (self._dataEntityMigration.doc_owner, self._dataEntityMigration.doc_name)
248        dataentity_id = dataentity_id.replace('.atom', '')           
249        infodb_de = self.epbRepo.infodbEPB.getCedaInfoApp_dataentityByDE_ID(dataentity_id)
250        i_logical_path = '/dummy'
251        if infodb_de is None:
252            i_logical_path = dwn['href'][dwn['href'].index('/browse/') + 7:]
253       
254        if infodb_de and infodb_de.has_key('logical_path'):
255            i_logical_path = infodb_de['logical_path']
256               
257        i_category = getCLValue(CEDA_CurationValue.cl_a)                                 
258        if infodb_de and infodb_de.has_key('category') and infodb_de['category']:
259            i_category = getCLValue(CEDA_CurationValue.from_string(infodb_de['category'].lower()))     
260
261        if not self._deploymentHasBeenProcessed:                     
262            observation.result = createCEDA_Result(i_category, i_logical_path, source = i_sources)
263            return 
264       
265        if observation.result.internalPath != i_logical_path:
266            observation.result.internalPath = i_logical_path
267           
268        if observation.result.curationCategory != i_category:
269            observation.result.curationCategory = i_category
270                       
271        #Still have to update observation.result.source
272
273    def _assignPublisherCurator(self, observation):
274        if self._deploymentHasSameHash:
275            return
276           
277        provider_id = extractMolesProviderID(self._deploymentMigration)
278        party = None
279        if provider_id == DO_BADC:
280            i_linkage = 'http://badc.rl.ac.uk'
281            i_onlineResources = createCI_OnlineResource(linkage = i_linkage, name = 'British Atmospheric Data Centre Website')
282            i_address = createCI_Address(deliveryPoint = ['British Atmospheric Data Centre, STFC Rutherford Appleton Laboratory'], \
283                                         electronicMailAddress=['badc@rl.ac.uk'], postalCode='OX11 0QX', country='UK', city='Harwell Oxford')                                   
284            i_phone = createCI_Telephone(voice=['+44(0)1235 446432'])                                 
285            contact = createCI_Contact(phone=i_phone, address=i_address, onlineResource=i_onlineResources)                       
286            party = createMO_Organization(name = "NERC - British Atmospheric Data Centre", contactInfo = [contact])
287        elif provider_id == DO_NEODC:
288            i_linkage = 'http://www.neodc.rl.ac.uk'
289            i_onlineResources = createCI_OnlineResource(linkage = i_linkage, name = 'NERC Earth Observation Data Centre website')
290            i_address = createCI_Address(deliveryPoint = ['NERC - Earth Observation Data Centre, STFC Rutherford Appleton Laboratory'], \
291                                         electronicMailAddress=['neodc@rl.ac.uk'], postalCode='OX11 0QX', country='UK', city='Harwell Oxford')                                   
292            i_phone = createCI_Telephone(voice=['+44(0)1235 446432'])                                 
293            contact = createCI_Contact(phone=i_phone, address=i_address, onlineResource=i_onlineResources)                       
294            party = createMO_Organization(name = 'NERC - Earth Observation Data Centre', contactInfo = [contact])
295        elif provider_id == DO_UKSSDC:
296            i_linkage = 'http://www.ukssdc.rl.ac.uk'
297            i_onlineResources = createCI_OnlineResource(linkage = i_linkage, name = 'UK Solar System Data Centre website')
298            i_address = createCI_Address(deliveryPoint = ['UK Solar System Data Centre, STFC Rutherford Appleton Laboratory'], \
299                                         electronicMailAddress=['support@rl.ac.uk'], postalCode='OX11 0QX', country='UK', city='Harwell Oxford')                                   
300            i_phone = createCI_Telephone(voice=['+44(0)1235 445173'])                                 
301            contact = createCI_Contact(phone=i_phone, address=i_address, onlineResource=i_onlineResources)                       
302            party = createMO_Organization(name = 'NERC - UK Solar System Data Centre', contactInfo = [contact])
303       
304        if party and not self._deploymentHasBeenProcessed:
305            newrp = []
306            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_publisher), [party]))
307            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_custodian), deepcopy([party])))
308            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_distributor), deepcopy([party])))
309            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_pointofcontact), deepcopy([party])))
310            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_metadataowner), deepcopy([party])))
311            newrp.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_curator), deepcopy([party])))
312            self.epbRepo.moles3EPB.updateCedaObject(observation, {'relatedParty': newrp})           
313            return       
314        #Still have to update observation.result.source
315
316    def _assignQuality(self, observation):
317        if self._dataEntityHasSameHash:
318            return
319               
320        doc_quality = extractQuality(self._dataEntityMigration)
321        doc_date = findUpdatedDate(self._dataEntityMigration)
322        ci_dates = []           
323        if doc_date:
324            i_date = createDate(isoDateTimeStringToTimeDate(doc_date))               
325            ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_revision), date = i_date))           
326        else:
327            i_date = createDate(isoDateTimeStringToTimeDate(datetime.datetime.now()))
328            ci_dates.append(createCI_Date(getCLValue(CI_DateTypeCode.cl_creation), date = i_date))
329
330        i_specification = createCI_Citation(title = "CEDA Data Quality Statement", date=ci_dates)
331        i_dq_result = createDQ_ConformanceResult(doc_quality, True, i_specification)
332        i_quality_element = createDQ_Element(i_dq_result)
333       
334        if not self._deploymentHasBeenProcessed:     
335            observation.resultQuality.append(i_quality_element)
336            return               
337        #Still have to update observation.result.source
338
339    def _assignDescription(self, observation):
340        if self._dataEntityHasSameHash and self._deploymentHasSameHash:
341            return
342       
343        description = extractSummary(self._deploymentMigration)
344        if description is None:
345            description = extractSummary(self._dataEntityMigration)
346           
347        if description:
348            observation.description = description
349
350    def _assignTitle(self, observation): 
351        if self._dataEntityHasSameHash and self._deploymentHasSameHash:
352            return
353                     
354        doc_title = extractTitle(self._deploymentMigration)
355        if doc_title is None:
356            doc_title = extractTitle(self._dataEntityMigration)
357       
358        if doc_title.startswith('deployment_') or doc_title.startswith('Deployment_'):
359            links = findLinksInMigrationDocument(self._deploymentMigration)
360            dptList = links['DPT']
361            if links.has_key('DPT'):
362                doc_title = 'Data from ' + dptList[0]['title']
363                if len(dptList) > 2:
364                    for dpt in dptList[1:-2]:
365                        doc_title += ', ' + dpt['title']
366                    if len(dptList) > 1:
367                        doc_title += ' and ' + dptList[-1]
368                                                       
369            links = findLinksInDeployment(self._deploymentMigration)
370            if links.has_key('OBS'):
371                obsList = []
372                for obs in links['OBS']:
373                    observationStation = self.epbRepo.migrationEPB.getDeploymentDataMigrationByName(self._deploymentMigration, obs + '.atom')
374                    obsList.append((extractTitle(observationStation), findSubTypeInDPT(observationStation)))
375               
376                if obsList[0][1] in ['stationary platform' ,'moving platform', 'ship','aircraft','satellite','computer']:
377                    doc_title += ' on '
378                else : 
379                    doc_title += ' at '
380                    doc_title += obsList[0][0]
381                if len(obsList) > 2:
382                    for obs in obsList[1:-2]:
383                        doc_title += ', ' + obs[0]
384                    if len(obsList) > 1:
385                        doc_title += ' and ' + obsList[-1][0]
386           
387            if links.has_key('ACTIVITY'):             
388                for link in links['ACTIVITY']:
389                    activity = self.epbRepo.migrationEPB.getDeploymentDataMigrationByName(self._deploymentMigration, link + '.atom')                   
390     
391                    projSubType = findSubTypeInDPT(activity)
392                    doc_title += ' for the ' + extractTitle(activity)
393                    if projSubType[0:14] == 'dgActivityData':
394                        doc_title += ' ' + projSubType[14:]
395                    else :
396                        doc_title += ' ' + projSubType                                                   
397        else:             
398            if doc_title[0:10] != 'Data from' :
399                doc_title = "Data from " + doc_title           
400        auth = createCI_Citation(title = 'ceda_title')                 
401        identifier = createMD_Identifier(code = doc_title, authority = auth)
402       
403        if not self._deploymentHasBeenProcessed: 
404            observation.identifier.append(identifier)
405            return           
406        #Still have to update observation.identifier         
407
408    def _assignGeographicExtent(self, observation):
409        if self._dataEntityHasSameHash and self._deploymentHasSameHash:
410            return 
411       
412        ge = extractGeographicExtentInMigrationDocument(self._deploymentMigration)
413        if not ge:
414            ge = extractGeographicExtentInMigrationDocument(self._dataEntityMigration)
415            if ge:
416                geographicExtent = createEX_GeographicBoundingBox(ge['east'], ge['north'], ge['west'], ge['south'])
417                if self._deploymentHasBeenProcessed:
418                    DeploymentProcessor.log.warn('The _assignGeographicExtent update is skipped because not implemented')
419                observation.geographicExtent.append(geographicExtent)
420            else:
421                print "No Geographic Extent"
422            return         
423        #Still have to update observation.geographicExtent
424           
425    def _assignCreationDate(self, observation):
426        if self._deploymentHasSameHash:
427            return 
428       
429        creation_date = extractMolesPublishedDate(self._deploymentMigration)
430        if creation_date is None:
431            creation_date = extractMolesCreationDate(self._deploymentMigration)
432        py_datetime = isoDateTimeStringToTimeDate(creation_date)
433        date_time = createDateTime(py_datetime)   
434        tm_position = createTM_Position(dateTime8601 = date_time)
435       
436        if not self._deploymentHasBeenProcessed: 
437            observation.resultTime = createTM_Instant(tm_position)
438            return       
439        #Still have to update observation.geographicExtent
440
441    def _assignPhenomenonTime(self, observation): 
442        if self._deploymentHasSameHash:
443            return 
444             
445        doc_phenomenon_time = extractMolesTemporalRange(self._deploymentMigration)       
446        if doc_phenomenon_time:
447            pt = None
448            if '/' in doc_phenomenon_time:
449                period = doc_phenomenon_time.split('/')
450                begin_date = createDate(isoDateStringToTimeDate(period[0]))
451                begin_position = createTM_Position(date8601 = begin_date)
452                begin_tm_instant = createTM_Instant(begin_position)
453               
454                end_date = createDate(isoDateStringToTimeDate(period[1]))
455                end_position = createTM_Position(date8601 = end_date)
456                end_tm_instant = createTM_Instant(end_position)
457               
458                pt = createTM_Period(begin_tm_instant, end_tm_instant)
459            else:
460                pt = createTM_Position(date8601 = createDate(isoDateStringToTimeDate(doc_phenomenon_time)))
461           
462            if not self._deploymentHasBeenProcessed:
463                observation.phenomenonTime = pt
464        #Still have to update observation.phenomenonTime               
465               
466    def _assignPermission(self, observation):
467        if self._deploymentHasSameHash and self._dataEntityHasSameHash:
468            return 
469       
470        access_link = findAccessLinksInMigrationDocument(self._deploymentMigration)
471        dwn_link = findDownloadLinksInMigrationDocument(self._deploymentMigration)
472        if len(access_link) == 0:
473            access_link = findAccessLinksInMigrationDocument(self._dataEntityMigration) 
474
475        i_accessConstraints = []
476        i_use_limitation = []
477       
478        permission = None
479        if len(access_link) == 0:
480            if len(dwn_link) == 0:
481                dwn_link = findDownloadLinksInMigrationDocument(self._dataEntityMigration)
482                if dwn_link and len(dwn_link) == 1:               
483                    i_use_limitation.append("These data are open access and available through %s." % (dwn_link[0]['href']) )
484                    #i_accessConstraints.append(MD_RestrictionCode.cl_)
485                    observation.permission = createMD_LegalConstraints(useLimitation = i_use_limitation, accessConstrains = i_accessConstraints)
486        else:
487            if access_link and len(access_link) == 1:
488                i_use_limitation.append("Access to these data is restricted. To obtain access please apply for access at: %s" % (access_link[0]['href']))
489                i_accessConstraints.append(getCLValue(MD_RestrictionCode.cl_restricted))
490                observation.permission = createMD_LegalConstraints(useLimitation = i_use_limitation, accessConstrains = i_accessConstraints)
491               
492        if not self._deploymentHasBeenProcessed:
493            observation.permission = permission       
494        #Still have to update observation.permission
495                                   
496        '''                               
497        contentDict = extractContent(self._deploymentMigration)
498        if not contentDict.has_key('access-restricted'):
499            contentDict = extractContent(self._dataEntityMigration)
500        '''           
501
502    def _assignMoles2Link(self, ceda_observation):
503        if self._deploymentHasSameHash:
504            return 
505               
506        i_code = 'http://badc.nerc.ac.uk/view/%s__ATOM__%s' % (self._deploymentMigration.doc_owner, self._deploymentMigration.doc_name)
507        i_code = i_code.replace('.atom', '')
508        #i_code = buildExistDocPath(self._deploymentMigration.doc_status, DT_DEPLOYMENTS, self._deploymentMigration.doc_owner, self._deploymentMigration.doc_name)
509        i_authority = createCI_Citation('moles2url')
510        identifier = createMD_Identifier(code = i_code, authority = i_authority)
511        if not self._deploymentHasBeenProcessed:             
512            ceda_observation.identifier.append(identifier)
513        #Still have to update observation.permission           
514
515    def _assignInternalReview(self, ceda_observation):
516        if self._deploymentHasBeenProcessed:             
517            return
518               
519        i_party = createMO_Individual(name = 'Graham Parton')
520        i_reviewer = createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_processor), [i_party])
521        ceda_observation.metadataManagement.append( \
522            createCEDA_Review(reviewer=i_reviewer, reviewFrequency=getCLValue(CEDA_ReviewFrequencyValue.cl_yearly), \
523                              reviewStatus=getCLValue(CEDA_ReviewStatusValue.cl_required))) 
524
525    def _assignLanguage(self, ceda_observation):
526        if self._deploymentHasBeenProcessed:             
527            return
528       
529        i_date_stamp = createDate(datetime.datetime.now())
530        #i_contact = createCI_Citation("", date = i_date_stamp)
531        i_contact = createCI_ResponsibleParty(getCLValue(CI_RoleCode.cl_user))
532        ceda_observation.metadata = createMD_Metadata(date_stamp=i_date_stamp, contact = [i_contact], language = "English")
533                       
534    def _processResultAccumulation(self, ceda_observation): 
535        if self._dataEntityHasSameHash:             
536            return                     
537
538            updateFrequency = extractUpdateFrequency(self._dataEntityMigration)
539            if updateFrequency:
540                resultAccumulation = MD_MaintenanceFrequencyCode.from_string(updateFrequency)
541                if not self._deploymentHasBeenProcessed:
542                    self.epbRepo.moles3EPB.updateCedaObject(ceda_observation, {'resultAccumulation': resultAccumulation})             
543                    return
544        #Still have to update observation.permission
545                   
546    def _assignName(self, observation):       
547        '''
548            @param relatedPartyInfos: a MO_ResponsiblePartyInfo list
549            @return True if the documents changed, False otherwise
550        '''
551        if self._deploymentHasSameHash and self._dataEntityHasSameHash:
552            return 
553       
554        whereAreAuthors = self._deploymentMigration       
555        doc_authors = findAuthorsInResource(self._deploymentMigration)       
556        if doc_authors['authors'] in [DO_BADC, DO_NEODC]:
557            doc_authors = findAuthorsInResource(self._dataEntityMigration)
558            whereAreAuthors = self._dataEntityMigration
559               
560        ind_names = []
561        org_names = []
562        if authors.has_key(doc_authors['authors']):
563            tmp_auth = authors[doc_authors['authors']]
564            ret = self._extractIndividualsAndOrganizations(tmp_auth, whereAreAuthors)
565
566            if len(ret['ind']) > 0:
567                i_party = createMO_Individual(name = ret['ind'][0])
568                observation.relatedParty.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_author), [i_party]))                 
569            if len(ret['org']) > 0:
570                i_party = createMO_Organization(name = ret['org'][0])
571                observation.relatedParty.append(createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_author), [i_party]))
572           
573            if len(ret['ind']) > 1:
574                ind_names.extend(ret['ind'][1:])                                                       
575            if len(ret['org']) > 1:
576                org_names.extend(ret['org'][1:])
577            if len(ret['co_ind']) > 0:                               
578                ind_names.extend(ret['co_ind'])
579            if len(ret['co_org']) > 0:                               
580                org_names.extend(ret['co_org'])                   
581                       
582        else:
583            raise NoAssociatedAuthor(doc_authors['authors'], migrationObject = whereAreAuthors)
584                     
585        if doc_authors['contributors'] and authors.has_key(doc_authors['contributors']):
586            tmp_auth = authors[doc_authors['contributors']]           
587            ret = self._extractIndividualsAndOrganizations(tmp_auth, whereAreAuthors)
588            ind_names.extend(ret['ind'])
589            ind_names.extend(ret['co_ind'])
590            org_names.extend(ret['org'])
591            org_names.extend(ret['co_org'])
592           
593        i_party = []
594        for nm in ind_names:
595            i_party.append(createMO_Individual(name = nm))
596               
597        for nm in org_names:
598            i_party.append(createMO_Organization(name = nm))
599           
600        if i_party:
601            if not self._deploymentHasBeenProcessed:
602                rp = createMO_ResponsiblePartyInfo(getCLValue(MM_RoleValue.cl_coinvestigator), i_party)
603                self.epbRepo.moles3EPB.updateCedaObject(observation, {'relatedParty': rp})
604                return
605        #Still have to update observation.permission
606   
607    def _execute(self, ceda_observation):
608        self._assignKeywords(ceda_observation)
609        self._assignLineage(ceda_observation)
610        self._assignResult(ceda_observation)
611        self._assignPublisherCurator(ceda_observation)                       
612        self._assignQuality(ceda_observation)       
613        self._assignDescription(ceda_observation)
614        self._assignTitle(ceda_observation)   
615        self._assignGeographicExtent(ceda_observation)               
616        self._assignCreationDate(ceda_observation)       
617        self._assignPhenomenonTime(ceda_observation)       
618        self._assignPermission(ceda_observation)       
619        self._assignMoles2Link(ceda_observation)               
620        self._assignInternalReview(ceda_observation)       
621        self._assignLanguage(ceda_observation)
622        self._processResultAccumulation(ceda_observation)           
623        self._assignName(ceda_observation)
624        #self._assignDOI(ceda_observation)       
625       
626        #Is a first time process?
627        if not hasMOBeenProcessed(self._deploymentMigration):
628            ceda_observation.publicationState = getCLValue(MM_ObservationPublicationStateValue.cl_working)         
629            docHash = getAtomDocumentHashByMO(self._dataEntityMigration)
630            self.epbRepo.moles3EPB.persistInstance(ceda_observation)       
631            self.epbRepo.migrationEPB.updateMigrationObject(self._deploymentMigration, \
632                {'ceda_observation_id': ceda_observation.id,
633                 'doc_hash': docHash})               
634       
635        #Has a proper CEDAGUID?
636        if self.epbRepo.moles3EPB.retrieveGUIDFromInstance(ceda_observation) is None:       
637            ceda_guid = CedaGUID()
638            ceda_guid.id = calculateHash(self._deploymentMigration.depl_id)
639            ceda_guid.ceda_observation = ceda_observation.id
640            self.epbRepo.moles3EPB.persistInstance(ceda_guid)
641            DeploymentProcessor.log.info("GUID for this Observation: %s" % (ceda_guid.id))
642
643
644        if not self._deploymentHasBeenProcessed:               
645            deploymentDataProcessor = DeploymentDataProcessor(self._deploymentMigration, self.epbRepo)               
646            procedure = deploymentDataProcessor.createProcess()
647            project = deploymentDataProcessor.createProject() 
648            self.epbRepo.moles3EPB.updateCedaObject(ceda_observation, {'procedure': procedure, 'inSupportOf': project})
649
650        #Still have to update observation.procedure
651        #Still have to update observation.project
652       
653        return ceda_observation
654       
655    def process(self):
656        ceda_observation = None
657        #Moles3 object exists...
658        if self._deploymentMigration.ceda_observation_id:
659            ceda_observation = self.epbRepo.moles3EPB.search(CEDA_Observation, self._deploymentMigration.ceda_observation_id)
660        else:
661            #... does not exist so create it
662            ceda_observation =  ceda_observation = CEDA_Observation()
663   
664        self._execute(ceda_observation)   
665        return ceda_observation
Note: See TracBrowser for help on using the repository browser.