source: TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/model/providerinfocollection.py @ 5235

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/model/providerinfocollection.py@5235
Revision 5235, 7.9 KB checked in by cbyrom, 12 years ago (diff)

Add functionality to allow admin users to add new provider info +
restrict deletion of info to admin users + add basic input checking
to ensure provider name is specified as a minimum.

  • Property svn:executable set to *
Line 
1'''
2 Class representing a collection of ProviderInfo objects. 
3 This data is usually dumped out together - e.g. to a file, in XML
4 file to persist the data managed by the OAI Info Editor.
5 
6 @author: C Byrom, Tessella Apr 2009
7'''
8from xml.etree import cElementTree as ET
9import logging
10from ndg.common.src.models.abstractrecord import AbstractRecord
11from oai_info_editor.model.providerinfo import *
12
13# names for the various XML elements used to house the object field data
14PROVIDER_INFO_COLLECTION_EL_NAME = "providerInfoCollection"
15HARVEST_DIR_EL_NAME = 'harvestDir'
16SCN_EL_NAME = "version"
17
18def createProviderInfoCollectionWithData(fileName, harvestDir, providerInfos):
19    '''
20    Factory method to create ProviderInfoCollection object with set values
21    @param fileName: full path to file which represents the data on the filesystem
22    @param harvestDir: directory to which harvested files should be saved
23    @param providerInfos: an array of ProviderInfo objects making up the collection
24    '''
25    crc = ProviderInfoCollection(fileName)
26    crc.setData(harvestDir, providerInfos)
27    return crc
28
29
30class ProviderInfoCollection(AbstractRecord):
31
32
33    # define the expected object attributes
34    __slots__ = ['fileName', 'backupFiles', 'providerInfos', 'version',
35                 HARVEST_DIR_EL_NAME]
36
37    def __init__(self, fileName, et = None, xmlString = None):
38        '''
39        Constructor - initialise the ProviderInfoCollection object
40        @param fileName: full path to file which represents the data on the filesystem
41        @keyword et: elementtree entry representing a ProviderInfoCollection - to
42        ingest data from
43        @keyword xmlString: xml string representing a ProviderInfoCollection - to
44        ingest data from
45        '''
46        logging.debug("Initialising new ProviderInfoCollection object")
47
48        logging.debug("Initialising fields")
49        super(ProviderInfoCollection, self).__init__(et = et) 
50        if not self.version:
51            self.version = '1'
52
53        if not self.providerInfos:
54            self.providerInfos = []
55        logging.debug("Fields initialised")
56       
57        if xmlString:
58            self.fromXMLString(xmlString)
59
60        self.fileName = fileName
61       
62        # if the associated file, above, is backed up, keep a store on the name
63        # of this - mainly for convenience during testing
64        self.backupFile = ''
65        logging.debug("ProviderInfoCollection initialised")
66
67
68    def setData(self, harvestDir, providerInfos):
69        '''
70        Simple method to set data on object
71        @param harvestDir: directory to which harvested files should be saved
72        @param providerInfos: an array of ProviderInfo objects making up the collection
73        '''
74        logging.debug("Setting data on ProviderInfoCollection object")
75
76        self.harvestDir = harvestDir
77        for pi in providerInfos:
78            if not isinstance(pi, ProviderInfo):
79                raise ValueError("Input data [%s] is not a ProviderInfo object" %pi)
80           
81        self.providerInfos = providerInfos
82        logging.debug("ProviderInfoCollection data set")
83
84
85    def fromET(self, et):
86        '''
87        Extract data from an elementtree object and add to ProviderInfoCollection object
88        @param et: Elementtree object representing a ProviderInfoCollection
89        '''
90        logging.debug("Adding data from elementtree object")
91        if not ET.iselement(et):
92            raise ValueError("Input et [%s] is not an elementtree Element object" %et)
93       
94        self.version = et.findtext(SCN_EL_NAME)
95        self.harvestDir = et.findtext(HARVEST_DIR_EL_NAME)
96        providerInfos = et.findall(PI_ROOT_EL_NAME)
97       
98        self.providerInfos = []
99        if providerInfos:
100            for pi in providerInfos:
101                self.providerInfos.append(ProviderInfo(et = pi))
102       
103        logging.debug("Data added from elementtree")
104   
105   
106    def toET(self):
107        '''
108        Create an Elementtree representing the data held by the ProviderInfoCollection
109        object.
110        @return Elementree representing the ProviderInfoCollection data
111        '''
112        logging.debug("Creating Elementtree from ProviderInfoCollection data")
113        root = ET.Element(PROVIDER_INFO_COLLECTION_EL_NAME)
114
115        versionEl = ET.SubElement(root, SCN_EL_NAME)
116        versionEl.text = self.version
117        harvestDirEl = ET.SubElement(root, HARVEST_DIR_EL_NAME)
118        harvestDirEl.text = self.harvestDir
119       
120        if self.providerInfos:
121            for pi in self.providerInfos:
122                root.append(pi.toET())
123       
124        logging.debug("Returning the ProviderInfoCollection in Elementtree format")
125        return root
126   
127   
128    def addProviderInfo(self, providerInfo, raiseErrorIfNotFound = False):
129        '''
130        Add provider info to the collection; if this already exists in the
131        collection, replace the old request with the new one
132        @param providerInfo: a ProviderInfo to add to the collection
133        @keyword raiseErrorIfNotFound: if True raise a ValueError if the input
134        data is not found
135        '''
136        logging.debug("Adding change request, '%s', to collection" %providerInfo)
137        pis = []
138        isNew = True
139        piName = providerInfo.name
140        if providerInfo.oldName != piName:
141            piName = providerInfo.oldName
142           
143        for pi in self.providerInfos:
144            if pi.name == piName:
145                logging.debug("- updating existing provider info")
146               
147                pi = providerInfo
148                isNew = False
149
150            pis.append(pi)
151
152        self.providerInfos = pis
153        if isNew:
154            if raiseErrorIfNotFound:
155                raise ValueError("- could not find existing provider info with name, '%s'" %providerInfo.name
156                                 )
157            self.providerInfos.append(providerInfo)
158           
159        logging.debug("- provider info added")
160   
161   
162    def removeProviderInfo(self, providerName):
163        '''
164        Remove a change request from the collection
165        @param providerName: Name of provider to delete
166        '''
167        logging.debug("Removing provider '%s' from collection" %providerName)
168
169        pis = []
170        for pi in self.providerInfos:
171            # NB, just skip the pi to be removed
172            if pi.name == providerName:
173                logging.debug("- removing existing provider info")
174            else:
175                pis.append(pi)
176
177        self.providerInfos = pis
178        logging.debug("- provider info removed")
179
180
181    def getProviderInfoForUser(self, user):
182        '''
183        Return provider info records valid to the input user
184        @param user: a User object with user details
185        @return list of ProviderInfo objects which the user can update
186        '''
187        logging.debug("Retrieving provider info for user, '%s'" %user.userID)
188
189        pis = []
190        if user.isAdmin:
191            logging.debug(" - user has admin rights - returning all data")
192            return self.providerInfos
193       
194        for pi in self.providerInfos:
195            if pi.name in user.providerNames:
196                logging.debug("- adding appropriate info")
197                pis.append(pi)
198
199        if not pis:
200            logging.debug("- no valid provider data found for user")
201       
202        return pis
203
204
205    def getProviderInfoByName(self, providerInfoName):
206        '''
207        Return provider info record with the specified name
208        @param providerInfoName: name of provider info record to return
209        @raise ValueError: if name not found
210        @return ProviderInfo object with matching name
211        '''
212        logging.debug("Retrieving provider info with name, '%s'" %providerInfoName)
213
214        for pi in self.providerInfos:
215            if pi.name == providerInfoName:
216                logging.debug("- returning request with matching name")
217                return pi
218               
219        raise ValueError("Provider info with name, '%s' not found in collection" %providerInfoName)
220       
Note: See TracBrowser for help on using the repository browser.