source: mauRepo/MolesManager/trunk/cedaMoles/libs/migration/processor/deployment.py @ 8517

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

Incomplete - # 22534: Add versiojn number to the gui page
 http://team.ceda.ac.uk/trac/ceda/ticket/22534
New classes for the moles2gui library

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