source: MILK/trunk/milk_server/milk_server/controllers/atom_editor/listatom.py @ 4668

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/MILK/trunk/milk_server/milk_server/controllers/atom_editor/listatom.py@4668
Revision 4668, 8.0 KB checked in by cbyrom, 11 years ago (diff)

Refactor to reflect updates to ndgUtils structure.
Pull out various constants from controllers to separate file - so these
can be referenced easily by tests.
Implement test_listatom.py - to test the listatom controller.

Line 
1'''
2 Class representing pylons controller for the listing and searching of atom
3 data
4 
5 @author: C Byrom, Tessella Sep 2008
6'''
7import logging, xmlrpclib
8from paste.request import parse_querystring
9from ndgUtils import ndgObject
10from ndgUtils.models.Atom import Atom
11from ndgUtils import DocumentRetrieve
12from ndgUtils.eXistInterface import ndg_eXist
13import ndgUtils.lib.existdbclient as edc
14from ndgUtils.models.MolesEntity import MolesEntity as ME
15from ndgUtils.models.vocabtermdata import VocabTermData as VTD, VocabTermItem as VTI
16from milk_server.lib.base import *
17from editorconstants import *
18import milk_server.lib.htmlUtilities as utils
19from milk_server.lib.atomutilities import savePageAndRender
20from editatom import EditatomController as ec
21
22   
23class ListatomController(BaseController):
24    '''
25    Provides the pylons controller for listing/searching NDG Atom documents.
26    '''
27    def __setup(self,uri=None):
28        ''' Common setup stuff for all the actions on this controller '''
29        logging.info("Setting up EditatomController")
30        self.cf=request.environ['ndgConfig']
31       
32        if uri:
33            try:
34                self.ndgObject = ndgObject(uri, config=self.cf)
35            except ValueError,e:
36                return e
37
38        self.inputs=dict(parse_querystring(request.environ))
39
40        logging.info("EditatomController set up")
41        return 0
42
43
44    def atomHome(self):
45        '''
46        Render a simple home page for the atom editor
47        '''
48        logging.info("Rendering atom home page")
49        c.title = ATOM_HOME_TITLE
50        return savePageAndRender(self.pathInfo, "atom_editor/atom_home")
51
52
53    def showExampleGranulite(self):
54        '''
55        Show an example granulite file
56        '''
57        logging.info("Rendering example granulite file page")
58        c.title = EXAMPLE_GRANULITE_TITLE
59        return savePageAndRender(self.pathInfo, "atom_editor/granulite_example")
60   
61   
62    def list(self, searchData=None, associatedAtomID=None, \
63             associatedAtomType=None, associationType=None):
64        '''
65        Provide a simple search interface to the atoms data
66        - display a filter + display any results + if an atomID is
67        provided, allow atoms to be linked to this
68        @keyword searchData: if '1' do a search, if '0' just display search filter
69        @keyword associatedAtomID: the ID of an atom to which other atoms
70        should be linked - via deployments
71        @keyword associatedAtomType: type of atom that the data is being
72        associated with
73        @keyword associationType: type of association to be done - NB, use
74        the constants in htmlUtilities for these
75        '''
76        try:
77            inputs = request.params
78            c.searchData = None
79            if searchData and int(searchData) > 0:
80                logging.info("Preparing atom search")
81                c.searchData = searchData
82                self.__setup()
83                atomTypeID = inputs.get('atomTypeID')
84                providerID = inputs.get('providerID')
85                # NB, avoid page being reloaded in incorrect state - e.g. after
86                # browser reload
87                if not (atomTypeID and providerID):
88                    return self.list()
89                   
90                atomTypeID = atomTypeID.split('--')[1]
91                providerID = providerID.split('--')[1]
92               
93                # if we're dealing with activity deployments, substitute the typeID
94                # for the subType Deployments term
95                if atomTypeID == VTD.ACTIVITY_DEPLOYMENT_TERM:
96                    atomTypeID = VTD.DEPLOYMENT_TERM
97                   
98                c.results = self.searchAtoms(providerID, atomTypeID, inputs.get('title'))
99               
100            logging.info("Rendering atom listings page")
101            c.errors = {}
102            c.title = LIST_ATOM_TITLE
103            c.assocAtomType = associatedAtomType
104            c.associateLink = ""
105            if associatedAtomID:
106                c.associateLink = h.url_for(controller='atom_editor/editatom', action='saveAtom', \
107                    uri = associatedAtomID, saveLevel = ec.ADD_ASSOCIATIONS)
108            c.searchLink = h.url_for(controller = 'atom_editor/listatom', action='list', \
109                                     searchData='1', associatedAtomID = associatedAtomID)
110           
111            c.searchTerm = inputs.get('title')
112           
113            # set up the drop down content
114            # NB, if we are here whilst doing an association, restrict the filter
115            # appropriately
116            listVals = []
117            defaultVal = None
118            # set up a default 'all' value
119            allVal = VTI(ndg_eXist.DEFAULT_ALL_VAL, ndg_eXist.DEFAULT_ALL_VAL)
120            if associationType:
121                val = int(associationType)
122                if val == utils.GRANULE_ASSOCIATION:
123                    c.title += GRANULE_ASSOCIATION_TITLE
124                    listVals = [g.vtd.TERM_DATA[g.vtd.GRANULE_TERM]]
125                elif val == utils.DEPLOYMENT_ASSOCIATION:
126                    c.title += DEPLOYMENTS_ASSOCIATION_TITLE
127                    listVals = [g.vtd.TERM_DATA[g.vtd.DEPLOYMENT_TERM]]
128                elif val == utils.ENTITY_ASSOCIATION:
129                    c.title += DEPLOYMENTS_DATA_ASSOCIATION_TITLE
130                    listVals = g.vtd.getValidTypes(g.vtd.DEPLOYABLE_ATOM_CATEGORY)
131                    defaultVal = allVal
132            else:
133                listVals = g.vtd.getValidTypes(g.vtd.ATOM_CATEGORY)
134                defaultVal = allVal
135           
136            c.atomTypes = utils.getVocabTermDataDropdown(listVals, \
137                                                   defaultVal = defaultVal, \
138                                                   selected = inputs.get('atomTypeID'))
139            c.providerIDs = utils.getVocabTermDataDropdown(g.vtd.getValidTypes(g.vtd.PROVIDER_CATEGORY), 
140                                                     defaultVal = allVal, \
141                                                     selected = inputs.get('providerID'))
142
143            return savePageAndRender(self.pathInfo, 'atom_editor/atom_list')
144
145        except Exception, e:
146            c.xml='Unexpected error loading page [%s]' %str(e)
147            c.doc=''
148            logging.error(c.xml)
149       
150        response.status_code = 400
151        return render("genshi", 'atom_editor/error')
152   
153   
154    def searchAtoms(self, providerID, atomTypeID, term):
155        '''
156        Search for atoms with specified filter info
157        @param providerID: provider ID of atom or 'all' for all
158        @param atomTypeID: type of atom or 'all' for all
159        @param term: text to search for in atom
160        @return array of dicts with info for each doc found in search
161        '''
162        logging.info("Search for atoms with the following filter: \
163            \nProviderID: '%s'\nAtom Type: '%s'\nText in title: '%s'" \
164            %(providerID, atomTypeID, term))
165       
166        dr = DocumentRetrieve(self.cf.get('NDG_EXIST','local'),
167                              pwfile=self.cf.get('NDG_EXIST','passwordFile'))
168       
169        # NB, for some reason, the xmlrpc call to eXist sometimes results in a spurious
170        # 'java.lang.IndexOutOfBoundsException' - retry a couple of times, if so
171        attempt = 0
172        results = None
173        while results is None:
174            try:
175                results = dr.search(term,
176                            start=1,
177                            howmany=10000, # NB, we want to get back everything!
178                            target=ndg_eXist.ATOM_TARGET,
179                            providerID = providerID, 
180                            atomTypeID = atomTypeID)
181            except xmlrpclib.Fault, e:
182                logging.info("Error caught whilst calling eXist: %s" %e.faultString)
183                attempt += 1
184                if attempt < 3:
185                    logging.info("- retrying eXist call")
186                else:
187                    raise e
188
189        logging.info("Search completed")
190        return results
191
192           
193       
Note: See TracBrowser for help on using the repository browser.