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

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

Generalise existing methods to allow data entities to be looked up with
the same code as associated deployments data + add new templates to
display the DEs + extend the javascript to allow multiple callbacks
to retrieve the info + various tidy ups and fixes.

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.models.existdbclient as edc
14from ndgUtils.models.MolesEntity import MolesEntity as ME
15from ndgUtils.vocabtermdata import VocabTermData as VTD, VocabTermItem as VTI
16from milk_server.lib.base import *
17from milk_server.lib.ndgInterface import interface
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 Editor Home Page"
50        return savePageAndRender(self.pathInfo, "atom_editor/atom_home")
51
52   
53    def list(self, searchData=None, associatedAtomID=None, \
54             associatedAtomType=None, associationType=None):
55        '''
56        Provide a simple search interface to the atoms data
57        - display a filter + display any results + if an atomID is
58        provided, allow atoms to be linked to this
59        @keyword associatedAtomID: the ID of an atom to which other atoms
60        should be linked - via deployments
61        @keyword associatedAtomType: type of atom that the data is being
62        associated with
63        @keyword associationType: type of association to be done - NB, use
64        the constants in htmlUtilities for these
65        '''
66        try:
67            inputs = request.params
68            c.searchData = None
69            if searchData and int(searchData) > 0:
70                logging.info("Preparing atom search")
71                c.searchData = searchData
72                self.__setup()
73                atomTypeID = inputs.get('atomTypeID')
74                providerID = inputs.get('providerID')
75                # NB, avoid page being reloaded in incorrect state - e.g. after
76                # browser reload
77                if not (atomTypeID and providerID):
78                    return self.list()
79                   
80                atomTypeID = atomTypeID.split('--')[1]
81                providerID = providerID.split('--')[1]
82               
83                # if we're dealing with activity deployments, substitute the typeID
84                # for the subType Deployments term
85                if atomTypeID == VTD.ACTIVITY_DEPLOYMENT_TERM:
86                    atomTypeID = VTD.DEPLOYMENT_TERM
87                   
88                c.results = self.searchAtoms(providerID, atomTypeID, inputs.get('title'))
89               
90            logging.info("Rendering atom listings page")
91            c.errors = {}
92            c.title='Browse atoms'
93            c.assocAtomType = associatedAtomType
94            c.associateLink = ""
95            if associatedAtomID:
96                c.associateLink = h.url_for(controller='atom_editor/editatom', action='saveAtom', \
97                    uri = associatedAtomID, saveLevel = ec.ADD_ASSOCIATIONS)
98            c.searchLink = h.url_for(controller = 'atom_editor/listatom', action='list', \
99                                     searchData='1', associatedAtomID = associatedAtomID)
100           
101            c.searchTerm = inputs.get('title')
102           
103            # set up the drop down content
104            # NB, if we are here whilst doing an association, restrict the filter
105            # appropriately
106            listVals = []
107            defaultVal = None
108            # set up a default 'all' value
109            allVal = VTI(ndg_eXist.DEFAULT_ALL_VAL, ndg_eXist.DEFAULT_ALL_VAL)
110            if associationType:
111                val = int(associationType)
112                if val == utils.GRANULE_ASSOCIATION:
113                    c.title += ' - to create associations with granule data'
114                    listVals = [g.vtd.TERM_DATA[g.vtd.GRANULE_TERM]]
115                elif val == utils.DEPLOYMENT_ASSOCIATION:
116                    c.title += ' - to create associations with deployment data'
117                    listVals = [g.vtd.TERM_DATA[g.vtd.DEPLOYMENT_TERM]]
118                elif val == utils.ENTITY_ASSOCIATION:
119                    c.title += ' - to create associations with activity/data production tool/observation station data'
120                    listVals = g.vtd.getValidTypes(g.vtd.DEPLOYABLE_ATOM_CATEGORY)
121                    defaultVal = allVal
122            else:
123                listVals = g.vtd.getValidTypes(g.vtd.ATOM_CATEGORY)
124                defaultVal = allVal
125           
126            c.atomTypes = utils.getVocabTermDataDropdown(listVals, \
127                                                   defaultVal = defaultVal, \
128                                                   selected = inputs.get('atomTypeID'))
129            c.providerIDs = utils.getVocabTermDataDropdown(g.vtd.getValidTypes(g.vtd.PROVIDER_CATEGORY), 
130                                                     defaultVal = allVal, \
131                                                     selected = inputs.get('providerID'))
132
133            return savePageAndRender(self.pathInfo, 'atom_editor/atom_list')
134
135        except Exception, e:
136            #we may be showing an xml document ... but it could go wrong if
137            #we have crap content ...
138            c.xml='Unexpected error loading page [%s]' %str(e)
139            c.doc=''
140            logging.error(c.xml)
141       
142        response.status_code = 400
143        return render("genshi", 'atom_editor/error')
144   
145   
146    def searchAtoms(self, providerID, atomTypeID, term):
147        '''
148        Search for atoms with specified filter info
149        @param providerID: provider ID of atom or 'all' for all
150        @param atomTypeID: type of atom or 'all' for all
151        @param term: text to search for in atom
152        @return array of dicts with info for each doc found in search
153        '''
154        logging.info("Search for atoms with the following filter: \
155            \nProviderID: '%s'\nAtom Type: '%s'\nText in title: '%s'" \
156            %(providerID, atomTypeID, term))
157       
158        dr = DocumentRetrieve(self.cf.get('NDG_EXIST','local'),
159                              pwfile=self.cf.get('NDG_EXIST','passwordFile'))
160       
161        # NB, for some reason, this sometimes results in a spurious
162        # 'java.lang.IndexOutOfBoundsException' - retry a couple of times, if so
163        attempt = 0
164        results = None
165        while results is None:
166            try:
167                results = dr.search(term,
168                            start=1,
169                            howmany=10000, # NB, we want to get back everything!
170                            target=ndg_eXist.ATOM_TARGET,
171                            providerID = providerID, 
172                            atomTypeID = atomTypeID)
173            except xmlrpclib.Fault, e:
174                logging.info("Error caught whilst calling eXist: %s" %e.faultString)
175                attempt += 1
176                if attempt < 3:
177                    logging.info("- retrying eXist call")
178                else:
179                    raise e
180
181        logging.info("Search completed")
182        return results
183
184           
185       
Note: See TracBrowser for help on using the repository browser.