web/views/sparql.py
changeset 2426 0209d9bc45a8
parent 2424 70f85df651a5
child 2444 4e61d9e4befb
equal deleted inserted replaced
2425:ba898e4ba09a 2426:0209d9bc45a8
     3 :organization: Logilab
     3 :organization: Logilab
     4 :copyright: 2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     4 :copyright: 2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     7 """
     7 """
     8 __docformat__ = "restructuredtext en"
     8 v__docformat__ = "restructuredtext en"
     9 
     9 
    10 import rql
    10 import rql
    11 from yams import xy
    11 from yams import xy
    12 
    12 
    13 from lxml import etree
    13 from lxml import etree
    14 from lxml.builder import E
    14 from lxml.builder import E
    15 
    15 
    16 from cubicweb.view import StartupView, AnyRsetView
    16 from cubicweb.view import StartupView, AnyRsetView
    17 from cubicweb.web import form, formfields, formwidgets as fwdgs
    17 from cubicweb.web import Redirect, form, formfields, formwidgets as fwdgs
    18 from cubicweb.web.views import forms, urlrewrite
    18 from cubicweb.web.views import forms, urlrewrite
    19 from cubicweb.spa2rql import Sparql2rqlTranslator
    19 from cubicweb.spa2rql import Sparql2rqlTranslator
    20 
    20 
    21 
    21 
    22 class SparqlForm(forms.FieldsForm):
    22 class SparqlForm(forms.FieldsForm):
    23     id = 'sparql'
    23     id = 'sparql'
    24     sparql = formfields.StringField(help=_('type here a sparql qyery'))
    24     sparql = formfields.StringField(help=_('type here a sparql qyery'))
    25     vid = formfields.StringField(initial='sparql', widget=fwdgs.HiddenInput)
    25     resultvid = formfields.StringField(choices=((_('table'), 'table'),
       
    26                                                 (_('sparql xml'), 'sparqlxml')),
       
    27                                        widget=fwdgs.Radio,
       
    28                                        initial='table')
    26     form_buttons = [fwdgs.SubmitButton()]
    29     form_buttons = [fwdgs.SubmitButton()]
    27     @property
    30     @property
    28     def action(self):
    31     def action(self):
    29         return self.req.url()
    32         return self.req.url()
    30 
    33 
    33     id = 'sparql'
    36     id = 'sparql'
    34     def call(self):
    37     def call(self):
    35         form = self.vreg.select('forms', 'sparql', self.req)
    38         form = self.vreg.select('forms', 'sparql', self.req)
    36         self.w(form.form_render())
    39         self.w(form.form_render())
    37         sparql = self.req.form.get('sparql')
    40         sparql = self.req.form.get('sparql')
       
    41         vid = self.req.form.get('resultvid', 'table')
    38         if sparql:
    42         if sparql:
    39             try:
    43             try:
    40                 qi = Sparql2rqlTranslator(self.schema).translate(sparql)
    44                 qinfo = Sparql2rqlTranslator(self.schema).translate(sparql)
    41                 rset = self.req.execute(qi.finalize())
       
    42             except rql.TypeResolverException, ex:
    45             except rql.TypeResolverException, ex:
    43                 self.w(self.req._('can not resolve entity types:') + u' ' + unicode('ex'))
    46                 self.w(self.req._('can not resolve entity types:') + u' ' + unicode('ex'))
    44             except UnsupportedQuery:
    47             except UnsupportedQuery:
    45                 self.w(self.req._('we are not yet ready to handle this query'))
    48                 self.w(self.req._('we are not yet ready to handle this query'))
    46             except xy.UnsupportedVocabulary, ex:
    49             except xy.UnsupportedVocabulary, ex:
    47                 self.w(self.req._('unknown vocabulary:') + u' ' + unicode('ex'))
    50                 self.w(self.req._('unknown vocabulary:') + u' ' + unicode('ex'))
    48             self.wview('table', rset, 'null')
    51             if vid == 'sparqlxml':
       
    52                 url = self.build_url('view', rql=qinfo.finalize(), vid=vid)
       
    53                 raise Redirect(url)
       
    54             rset = self.req.execute(qinfo.finalize())
       
    55             self.wview(vid, rset, 'null')
       
    56 
    49 
    57 
    50 ## sparql resultset views #####################################################
    58 ## sparql resultset views #####################################################
    51 
    59 
    52 YAMS_XMLSCHEMA_MAPPING = {
    60 YAMS_XMLSCHEMA_MAPPING = {
    53     'String': 'string',
    61     'String': 'string',
    68     return 'http://www.w3.org/2001/XMLSchema#%s' % YAMS_XMLSCHEMA_MAPPING[yamstype]
    76     return 'http://www.w3.org/2001/XMLSchema#%s' % YAMS_XMLSCHEMA_MAPPING[yamstype]
    69 
    77 
    70 class SparqlResultXmlView(AnyRsetView):
    78 class SparqlResultXmlView(AnyRsetView):
    71     """The spec can be found here: http://www.w3.org/TR/rdf-sparql-XMLres/
    79     """The spec can be found here: http://www.w3.org/TR/rdf-sparql-XMLres/
    72     """
    80     """
    73     id = 'sparql'
    81     id = 'sparqlxml'
    74     content_type = 'application/sparql-results+xml'
    82     content_type = 'application/sparql-results+xml'
    75     templatable = False
    83     templatable = False
    76     # XXX use accept-headers-selectors to choose among the sparql result views
       
    77 
    84 
    78     def call(self):
    85     def call(self):
    79         # XXX handle UNION
    86         # XXX handle UNION
    80         rqlst = self.rset.syntax_tree().children[0]
    87         rqlst = self.rset.syntax_tree().children[0]
    81         varnames = [var.name for var in rqlst.selection]
    88         varnames = [var.name for var in rqlst.selection]
    86                 result.append(self.cell_binding(rowidx, colidx, varname))
    93                 result.append(self.cell_binding(rowidx, colidx, varname))
    87             results.append(result)
    94             results.append(result)
    88         sparql = E.sparql(E.head(*(E.variable(name=name) for name in varnames)),
    95         sparql = E.sparql(E.head(*(E.variable(name=name) for name in varnames)),
    89                           results)
    96                           results)
    90         self.w(u'<?xml version="1.0"?>\n')
    97         self.w(u'<?xml version="1.0"?>\n')
    91         self.w(etree.tostring(sparql, encoding=unicode))
    98         self.w(etree.tostring(sparql, encoding=unicode, pretty_print=True))
    92 
    99 
    93     def cell_binding(self, row, col, varname):
   100     def cell_binding(self, row, col, varname):
    94         celltype = self.rset.description[row][col]
   101         celltype = self.rset.description[row][col]
    95         if self.schema.eschema(celltype).is_final():
   102         if self.schema.eschema(celltype).is_final():
    96             cellcontent = self.view('cell', self.rset, row=row, col=col)
   103             cellcontent = self.view('cell', self.rset, row=row, col=col)
    98                                        datatype=xmlschema(celltype)),
   105                                        datatype=xmlschema(celltype)),
    99                              name=varname)
   106                              name=varname)
   100         else:
   107         else:
   101             entity = self.entity(row, col)
   108             entity = self.entity(row, col)
   102             return E.binding(E.uri(entity.absolute_url()), name=varname)
   109             return E.binding(E.uri(entity.absolute_url()), name=varname)
       
   110 
       
   111     def set_request_content_type(self):
       
   112         """overriden to set the correct filetype and filename"""
       
   113         self.req.set_content_type(self.content_type,
       
   114                                   filename='sparql.xml',
       
   115                                   encoding=self.req.encoding)