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

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

Major refactoring about migration (now handles better create/update, even if the single updates have to be quite fully implemented)
Added the connection pool from SQLAlchemy

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