source: MILK/trunk/milk_server/milk_server/controllers/browse/retrieve.py @ 4984

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

Add new trackback controller and implement methods to allow
authenticated users to post comments on metadata docs. These comments
are then emailed to the metadata maintainer and added to the
corrections feed. Control then returns to the metadata document - in
non edit form - and, in the case of moles atom docs, a pop up informs
the user that the operation has completed successfully. Also add the
required genshi templates and template methods to enable this new
functionality.

Line 
1
2import logging
3from paste.request import parse_querystring
4from xml.parsers.expat import ExpatError
5from milk_server.lib.base import *
6from milk_server.lib import Utilities
7from milk_server.lib.ndgInterface import ndgInterface
8from ndg.common.src.lib.ETxmlView import et2text, et2html
9from ndg.common.src.models import stubB, DIF, ndgObject
10from ndg.common.src.models.ndgObject import ndgObject
11from ndg.common.src.models.Atom import Atom
12from ndg.common.src.models.vocabtermdata import VocabTermData as VTD
13from ndg.common.src.clients.xmldb.eXist.searchclient import SearchClient
14
15class RetrieveController(BaseController):
16    ''' Provides the pylons controller for retrieving NDG documents. The simple model
17    is now that an attempt to retrieve/uri will parse the uri, read the config file,
18    and if the local server name is not the same as the uri server name. '''
19   
20    def __setup(self,uri):
21        ''' Common setup stuff for all the actions on this controller '''
22        logging.info("Setting up RetrieveController")
23        self.cf=request.environ['ndgConfig']
24        try:
25            self.uri=ndgObject(uri, config=self.cf)
26        except ValueError,e:
27            return e
28
29        self.inputs=dict(parse_querystring(request.environ))
30
31        # NB: we could have two types of query string argument:
32        #   format= (raw,html) and
33        #   outputSchema=(original, someSchema)
34        self.format=''
35        if 'format' in self.inputs: 
36            self.format=self.inputs['format']
37        self.outputSchema=''
38        if 'outputSchema' in self.inputs: 
39            self.outputSchema=self.inputs['outputSchema']
40                             
41        logging.info("RetrieveController set up")
42        return 0
43       
44    def index(self,uri):
45        ''' Returns the document unadorned in anyway, i.e. the raw xml'''
46        status=self.__setup(uri)
47        if status:
48            c.xml='<p>%s</p>'%status
49            response.status_code = 400
50            return render('error')
51       
52        interface = ndgInterface()
53        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
54        if status:
55            #(the return object x is an ET object)
56            c.xml = et2text(x)
57            response.headers['Content-Type'] = 'application/xml'
58            response.write(c.xml)
59        else:
60            e=404
61            if x.startswith('<p> Access'): e=401
62            response.status_code = e
63            return render('error')
64
65    def viewAssociatedData(self, type, uri):
66        '''
67        Get the specified data associated with the uri
68        @param type: type of associated data to lookup - currently VTD.DEPLOYMENT_TERM
69        or VTD.DE_TERM
70        @param uri: valid ndg uri
71        @return rendered genshi deployments template
72        '''
73        logging.info("Getting %s data for '%s'" %(type, uri))
74        status=self.__setup(uri)
75        if status:
76            c.xml='<p>%s</p>'%status
77            response.status_code = 400
78            return render('error')
79
80        try:
81            # NB, we should have stored the current atom data - so look this up now
82            atom = session.get('currentAtom')
83            if atom:
84                c.atom = atom
85            else:
86                interface = ndgInterface()
87                status,x=interface.GetXML(uri,outputSchema=self.outputSchema, useCache=False)
88                c.xmlh=x
89                c.atom = Atom(xmlString=str(x), ndgObject = self.uri)
90           
91            # NB, there are two routes through here - if we're viewing a data entity,
92            # the deployment links are available directly from the atom; if not we
93            # need to look them up
94            lookupIndirectReferences = True
95            if c.atom.isDE():
96                lookupIndirectReferences = False
97           
98            searchClient = SearchClient(dbHostName = self.cf.get('NDG_EXIST','local'),
99                                        configFileName = self.cf.get('NDG_EXIST','passwordFile'))
100           
101            c.atom.lookupAssociatedData(type, searchClient, 
102                                        lookupIndirectReferences = lookupIndirectReferences)
103
104            template = 'atom_editor/deployments_data'
105            if type == VTD.DE_TERM:
106                template = 'atom_editor/data_entities_data'
107
108            # store the atom to retain the looked up info
109            session['currentAtom'] = c.atom
110            session.save()
111               
112            logging.info("- %s data retrieved - now rendering" %type)
113            return render('genshi', template)
114       
115        except ExpatError, e:
116            c.xml='XML content is not well formed'
117            c.doc=str(x)
118            response.status_code = 400
119            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
120            return render('error')
121
122        except Exception, e:
123            #we may be showing an xml document ... but it could go wrong if
124            #we have crap content ...
125            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
126            c.doc=''
127            response.status_code = 400
128            logging.error(c.xml)
129            return render('error')
130
131       
132       
133    def view(self,uri):
134        ''' Returns either an html marked up version of the xml, or a properly laid
135        out version of the document '''
136        c.doc=None
137        # NB, this sets up self.uri as an ndgObject
138        status=self.__setup(uri)
139        if status:
140            c.xml='<p>%s</p>'%status
141            response.status_code = 400
142            return render('error')
143
144        logging.info("Retrieving document to view")
145        useCache = True
146        viewFormat=self.uri.schema
147        # NB, don't use cache if we're looking up atoms as these can change quickly
148        # when using the atom editor
149        if viewFormat == ndgObject.ATOM_DOC_TYPE or \
150            viewFormat ==  ndgObject.ATOM_BACKUP_DOC_TYPE:
151            useCache = False
152           
153        interface = ndgInterface()
154        #(the return object x is an ET object)
155        status,x=interface.GetXML(uri,outputSchema=self.outputSchema, useCache=useCache)
156        c.title='Viewing [%s]'%self.uri
157       
158        # NB, legacy code uses kid templates - newer stuff should use genshi
159        templateType = "kid"
160        if status:
161            logging.debug("Document retrieved ok - now processing results")
162
163            if self.outputSchema!='': 
164                viewFormat=self.outputSchema
165
166            logging.debug("Doc format: %s, View format: %s" \
167                           %(self.format, viewFormat))
168
169            name=str(self.uri)
170            if self.format=='xml':
171                c.xml = et2html(x)
172                renderTemplate = 'content'
173                c.tab='Details'
174
175            elif self.format=='raw':
176                c.xml = et2text(x)
177                response.headers['Content-Type'] = 'application/xml'
178                return response.write(c.xml)
179               
180            elif viewFormat == ndgObject.ATOM_DOC_TYPE or \
181                viewFormat ==  ndgObject.ATOM_BACKUP_DOC_TYPE:
182                renderTemplate = 'atom_editor/atom_editor'
183                c.xmlh = x
184                c.atom = Atom(xmlString=x, ndgObject = self.uri)
185               
186                # get the current publication state
187                edc = Utilities.getExistClient(c.atom.ME.providerID)
188                c.atom.state = edc.getAtomPublicationState(c.atom.datasetID, 
189                                                           c.atom.ME.providerID)
190               
191                c.title = 'Viewing [%s]'%self.uri
192                c.deploymentsURL = h.url_for(controller='browse/retrieve', \
193                                             action='viewAssociatedData', \
194                                             type = VTD.DEPLOYMENT_TERM, \
195                                             uri = self.uri)
196                c.dataEntitiesURL = h.url_for(controller='browse/retrieve', \
197                                             action='viewAssociatedData', \
198                                             type = VTD.DE_TERM, \
199                                             uri = self.uri)
200                templateType = "genshi"
201                # store the atom for easy re-use by asynch calls
202                # - primarily for the viewAssociatedData() method here
203                session['currentAtom'] = c.atom
204                session.save()
205
206            elif viewFormat == ndgObject.MOLES_DOC_TYPE:
207                renderTemplate = 'browse/stubB'
208                c.doc=stubB.stubB(x, self.cf)
209                name=c.doc.abbreviation
210               
211            elif viewFormat == ndgObject.NDGA0_DOC_TYPE:
212                renderTemplate = 'content'
213                name=self.uri.localID
214                #for now we'll handle as pretty print xml
215                c.xml = et2html(x)
216                c.tab='Details'
217               
218            elif viewFormat == ndgObject.DIF_DOC_TYPE or viewFormat == ndgObject.BROWSE_DIF_DOC_TYPE:
219                renderTemplate = 'browse/dif'
220                c.doc=DIF.DIF(x, et=1, ndgObj=self.uri)
221                name=c.doc.name
222               
223            elif viewFormat == ndgObject.NUMSIM_DOC_TYPE:
224                renderTemplate = 'browse/numsim'
225                c.xmlh=x
226                name=x.findtext('NS_Name')
227                c.name=name
228               
229            else:
230                c.xml = et2html(x)
231                renderTemplate = 'content'
232           
233            needed=0
234            if 'lastViewed' not in session: 
235                needed=1
236               
237            session['lastViewed']=h.current_url()
238            if needed: 
239                c.pageTabs.append(('Details',session['lastViewed']))
240           
241            session.save()
242            code=200
243        else:
244            renderTemplate = 'error'
245            if x.startswith('<p> Access Denied'):
246                code=401
247            else: code=400
248            c.xml='%s'%x
249            logging.error(x)
250           
251        response.status_code = code
252        try:
253            return render(templateType, renderTemplate)
254       
255        except ExpatError, e:
256            c.xml='XML content is not well formed'
257            c.doc=str(x)
258            response.status_code = 400
259            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
260            return render('error')
261
262        except Exception, e:
263            #we may be showing an xml document ... but it could go wrong if
264            #we have crap content ...
265            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
266            c.doc=''
267            response.status_code = 400
268            logging.error(c.xml)
269            return render('error')
Note: See TracBrowser for help on using the repository browser.