1 | ''' |
---|
2 | Class representing pylons controller for the listing and searching of atom |
---|
3 | data |
---|
4 | |
---|
5 | @author: C Byrom, Tessella Sep 2008 |
---|
6 | ''' |
---|
7 | from milk_server.lib.base import * |
---|
8 | from ndgUtils import ndgObject |
---|
9 | from paste.request import parse_querystring |
---|
10 | from milk_server.lib.ndgInterface import interface |
---|
11 | from xml.parsers.expat import ExpatError |
---|
12 | import logging |
---|
13 | from ndgUtils.models.Atom import Atom |
---|
14 | from formencode import Schema, validators, Invalid |
---|
15 | from genshi.filters import HTMLFormFiller |
---|
16 | from genshi import HTML |
---|
17 | from ndgUtils import DocumentRetrieve |
---|
18 | from ndgUtils.eXistInterface import ndg_eXist |
---|
19 | import ndgUtils.models.existdbclient as edc |
---|
20 | from ndgUtils.models.MolesEntity import MolesEntity as ME |
---|
21 | from ndgUtils.vocabtermdata import VocabTermData as VTD, VocabTermItem as VTI |
---|
22 | import milk_server.lib.htmlUtilities as utils |
---|
23 | from editatom import EditatomController as ec |
---|
24 | from milk_server.lib.atomutilities import savePageAndRender |
---|
25 | |
---|
26 | |
---|
27 | class ListatomController(BaseController): |
---|
28 | ''' |
---|
29 | Provides the pylons controller for listing/searching NDG Atom documents. |
---|
30 | ''' |
---|
31 | def __setup(self,uri=None): |
---|
32 | ''' Common setup stuff for all the actions on this controller ''' |
---|
33 | logging.info("Setting up EditatomController") |
---|
34 | self.cf=request.environ['ndgConfig'] |
---|
35 | |
---|
36 | if uri: |
---|
37 | try: |
---|
38 | self.ndgObject = ndgObject(uri, config=self.cf.config) |
---|
39 | except ValueError,e: |
---|
40 | return e |
---|
41 | |
---|
42 | self.inputs=dict(parse_querystring(request.environ)) |
---|
43 | |
---|
44 | logging.info("EditatomController set up") |
---|
45 | return 0 |
---|
46 | |
---|
47 | |
---|
48 | def atomHome(self): |
---|
49 | ''' |
---|
50 | Render a simple home page for the atom editor |
---|
51 | ''' |
---|
52 | logging.info("Rendering atom home page") |
---|
53 | c.title = "Atom Editor Home Page" |
---|
54 | return savePageAndRender(self.pathInfo, "atom_editor/atom_home") |
---|
55 | |
---|
56 | |
---|
57 | def list(self, searchData=None, associatedAtomID=None, \ |
---|
58 | associatedAtomType=None, associationType=None): |
---|
59 | ''' |
---|
60 | Provide a simple search interface to the atoms data |
---|
61 | - display a filter + display any results + if an atomID is |
---|
62 | provided, allow atoms to be linked to this |
---|
63 | @keyword associatedAtomID: the ID of an atom to which other atoms |
---|
64 | should be linked - via deployments |
---|
65 | @keyword associatedAtomType: type of atom that the data is being |
---|
66 | associated with |
---|
67 | @keyword associationType: type of association to be done - NB, use |
---|
68 | the constants in htmlUtilities for these |
---|
69 | ''' |
---|
70 | try: |
---|
71 | inputs = request.params |
---|
72 | c.searchData = None |
---|
73 | if searchData and int(searchData) > 0: |
---|
74 | logging.info("Preparing atom search") |
---|
75 | c.searchData = searchData |
---|
76 | self.__setup() |
---|
77 | atomTypeID = inputs.get('atomTypeID') |
---|
78 | providerID = inputs.get('providerID') |
---|
79 | # NB, avoid page being reloaded in incorrect state - e.g. after |
---|
80 | # browser reload |
---|
81 | if not (atomTypeID and providerID): |
---|
82 | return self.list() |
---|
83 | |
---|
84 | atomTypeID = atomTypeID.split('--')[1] |
---|
85 | providerID = providerID.split('--')[1] |
---|
86 | c.results = self.searchAtoms(providerID, atomTypeID, inputs.get('title')) |
---|
87 | |
---|
88 | logging.info("Rendering atom listings page") |
---|
89 | c.errors = {} |
---|
90 | c.title='Browse atoms' |
---|
91 | c.assocAtomType = associatedAtomType |
---|
92 | c.associateLink = "" |
---|
93 | if associatedAtomID: |
---|
94 | c.associateLink = h.url_for(controller='atom_editor/editatom', action='saveAtom', \ |
---|
95 | uri = associatedAtomID, saveLevel = ec.ADD_ASSOCIATIONS) |
---|
96 | c.searchLink = h.url_for(controller = 'atom_editor/listatom', action='list', \ |
---|
97 | searchData='1', associatedAtomID = associatedAtomID) |
---|
98 | |
---|
99 | c.searchTerm = inputs.get('title') |
---|
100 | |
---|
101 | # set up the drop down content |
---|
102 | # NB, if we are here whilst doing an association, restrict the filter |
---|
103 | # appropriately |
---|
104 | listVals = [] |
---|
105 | defaultVal = None |
---|
106 | # set up a default 'all' value |
---|
107 | allVal = VTI(ndg_eXist.DEFAULT_ALL_VAL, ndg_eXist.DEFAULT_ALL_VAL) |
---|
108 | if associationType: |
---|
109 | val = int(associationType) |
---|
110 | if val == utils.GRANULE_ASSOCIATION: |
---|
111 | c.title += ' - to create associations with granule data' |
---|
112 | listVals = [g.vtd.TERM_DATA[g.vtd.GRANULE_TERM]] |
---|
113 | elif val == utils.DEPLOYMENT_ASSOCIATION: |
---|
114 | c.title += ' - to create associations with deployment data' |
---|
115 | listVals = [g.vtd.TERM_DATA[g.vtd.DEPLOYMENT_TERM]] |
---|
116 | elif val == utils.ENTITY_ASSOCIATION: |
---|
117 | c.title += ' - to create associations with activity/data production tool/observation station data' |
---|
118 | listVals = g.vtd.getValidTypes(g.vtd.DEPLOYABLE_ATOM_CATEGORY) |
---|
119 | defaultVal = allVal |
---|
120 | else: |
---|
121 | listVals = g.vtd.getValidTypes(g.vtd.ATOM_CATEGORY) |
---|
122 | defaultVal = allVal |
---|
123 | |
---|
124 | c.atomTypes = utils.getVocabTermDataDropdown(listVals, \ |
---|
125 | defaultVal = defaultVal, \ |
---|
126 | selected = inputs.get('atomTypeID')) |
---|
127 | c.providerIDs = utils.getVocabTermDataDropdown(g.vtd.getValidTypes(g.vtd.PROVIDER_CATEGORY), |
---|
128 | defaultVal = allVal, \ |
---|
129 | selected = inputs.get('providerID')) |
---|
130 | |
---|
131 | return savePageAndRender(self.pathInfo, 'atom_editor/atom_list') |
---|
132 | |
---|
133 | except Exception, e: |
---|
134 | #we may be showing an xml document ... but it could go wrong if |
---|
135 | #we have crap content ... |
---|
136 | c.xml='Unexpected error loading page [%s]' %str(e) |
---|
137 | c.doc='' |
---|
138 | logging.error(c.xml) |
---|
139 | |
---|
140 | response.status_code = 400 |
---|
141 | return render("genshi", 'atom_editor/error') |
---|
142 | |
---|
143 | |
---|
144 | def searchAtoms(self, providerID, atomTypeID, term): |
---|
145 | ''' |
---|
146 | Search for atoms with specified filter info |
---|
147 | @param providerID: provider ID of atom or 'all' for all |
---|
148 | @param atomTypeID: type of atom or 'all' for all |
---|
149 | @param term: text to search for in atom |
---|
150 | @return array of dicts with info for each doc found in search |
---|
151 | ''' |
---|
152 | logging.info("Search for atoms with the following filter: \ |
---|
153 | \nProviderID: '%s'\nAtom Type: '%s'\nText in title: '%s'" \ |
---|
154 | %(providerID, atomTypeID, term)) |
---|
155 | |
---|
156 | dr = DocumentRetrieve(self.cf.get('NDG_EXIST','local'), |
---|
157 | pwfile=self.cf.get('NDG_EXIST','passwordFile')) |
---|
158 | |
---|
159 | results = dr.search(term, |
---|
160 | start=1, |
---|
161 | howmany=10000, # NB, we want to get back everything! |
---|
162 | target=ndg_eXist.ATOM_TARGET, |
---|
163 | providerID = providerID, |
---|
164 | atomTypeID = atomTypeID) |
---|
165 | |
---|
166 | logging.info("Search completed") |
---|
167 | return results |
---|
168 | |
---|
169 | |
---|
170 | |
---|