Skip to content

Commit

Permalink
Refs #9424 #9608; Added quick preview for sparql queries; improved sp…
Browse files Browse the repository at this point in the history
…arql edit for versioning
  • Loading branch information
zotya committed Jan 30, 2013
1 parent a4b8afe commit da83388
Show file tree
Hide file tree
Showing 11 changed files with 391 additions and 16 deletions.
4 changes: 3 additions & 1 deletion docs/HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ Changelog
2.4-dev - (unreleased)
----------------------
* Upgrade step:
ZMI > portal_setup > profile "EEA Sparql" > import Diff tool & CMFEditions Repository Tool
ZMI > portal_setup > profile "EEA Sparql" > import Skins & Diff tool & CMFEditions Repository Tool
* Feature: Added quick preview for sparql queries
[szabozo0 refs #9608]
* Feature: Data persistence and versioning
- Added versioning for sparql results
- Possibility to select static & live queries
Expand Down
16 changes: 16 additions & 0 deletions eea/sparql/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,20 @@
permission="cmf.ModifyPortalContent"
/>

<browser:page
name="sparql.quick_preview"
for="*"
class=".sparql.QuickPreview"
attribute="preview"
permission="zope2.View"
/>

<browser:page
name="sparql.related_items"
for="*"
class=".sparql.Sparql"
attribute="relatedItems"
permission="zope2.View"
/>

</configure>
68 changes: 68 additions & 0 deletions eea/sparql/browser/sparql.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from Products.ZSPARQLMethod.Method import interpolate_query_html
from Products.ZSPARQLMethod.Method import map_arg_values
from Products.ZSPARQLMethod.Method import parse_arg_spec
from Products.ZSPARQLMethod.Method import interpolate_query
from Products.ZSPARQLMethod.Method import run_with_timeout
from Products.ZSPARQLMethod.Method import query_and_get_result

from eea.sparql.converter.sparql2json import sparql2json
from eea.sparql.converter.sparql2json import sortProperties
from eea.versions import versions
Expand All @@ -14,6 +18,7 @@
import json
import urllib2
import contextlib
import cgi

logger = logging.getLogger('eea.sparql')

Expand Down Expand Up @@ -239,6 +244,11 @@ def isDavizInstalled(self):

return has_daviz

def relatedItems(self):
""" Items what are back related to this query
"""
return json.dumps([[x.title, x.absolute_url()]
for x in self.context.getBRefs()])

class SparqlBookmarksFolder(Sparql):
"""SparqlBookmarksFolder view"""
Expand Down Expand Up @@ -311,3 +321,61 @@ def __call__(self):
except Exception, err:
logger.exception(err)
return "Sync done"

class QuickPreview(BrowserView):
""" Quick Preview For Query
"""

def preview(self):
"""preview"""
tmp_query = self.request.get("sparql_query", "")
tmp_arg_spec = self.request.get("arg_spec", "")
tmp_endpoint = self.request.get("endpoint", "")
tmp_timeout = int(self.request.get("timeout", "0"))

arg_spec = parse_arg_spec(tmp_arg_spec)
missing, arg_values = map_arg_values(arg_spec, self.request.form)
error = None
if missing:
error = ""
for missing_arg in missing:
error = error + "<div>Argument '%s' missing</div>" % missing_arg
else:
result = {}
data = []
error = None
cooked_query = interpolate_query(tmp_query, arg_values)
args = (tmp_endpoint, cooked_query)
try:
result, error = {}, None
result = run_with_timeout(tmp_timeout,
query_and_get_result,
*args)
data = result.get('result')
error = error or result.get('exception')
except Exception:
import traceback
error = traceback.format_exc()

if error:
return "<blockquote class='sparql-error'> %s </blockquote>" % error

result = []
result.append(u"<table class='sparql-results'>")
result.append(u"<thead>")
result.append(u"<tr>")
for var_name in data.get('var_names', []):
result.append(u"<th> %s </th>" %var_name)
result.append(u"</tr>")
result.append(u"</thead>")
result.append(u"<tbody>")
for row in data.get('rows', []):
result.append(u"<tr class='row_0'>")
for value in row:
result.append(u"<td> %s </td>" %cgi.escape(value.n3()))
result.append(u"</tr>")
result.append(u"</tbody>")
result.append(u"</table>")
return "\n".join(result)


1 change: 1 addition & 0 deletions eea/sparql/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<include file="profiles.zcml" />
<include file="permissions.zcml" />
<include file="skins.zcml" />

<include package=".browser" />
<include package=".cache" />
Expand Down
33 changes: 18 additions & 15 deletions eea/sparql/content/sparql.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
allowable_content_types = ('text/plain',),

widget=TextAreaWidget(
macro="sparql_textfield_with_preview",
helper_js=("sparql_textfield_with_preview.js",),
helper_css=("sparql_textfield_with_preview.css",),
label="Query",
),
required=1
Expand Down Expand Up @@ -217,21 +220,21 @@ def execute(self, **arg_values):
new_sparql_results = new_sparql_results[0:-3] + "\n"
self.setSparql_results(new_sparql_results)
pr = getToolByName(self, 'portal_repository')

comment = "Result changed"
comment = comment.encode('utf')

oldSecurityManager = getSecurityManager()
newSecurityManager(self.REQUEST, SpecialUsers.system)
try:
pr.save(obj=self, comment=comment)
except FileTooLargeToVersionError:
commands = view.getCommandSet('plone')
commands.issuePortalMessage(
"""Changes Saved. Versioning for this file
has been disabled because it is too large.""",
msgtype="warn")
setSecurityManager(oldSecurityManager)
if self.portal_type in pr.getVersionableContentTypes():
comment = "Result changed"
comment = comment.encode('utf')

oldSecurityManager = getSecurityManager()
newSecurityManager(self.REQUEST, SpecialUsers.system)
try:
pr.save(obj=self, comment=comment)
except FileTooLargeToVersionError:
commands = view.getCommandSet('plone')
commands.issuePortalMessage(
"""Changes Saved. Versioning for this file
has been disabled because it is too large.""",
msgtype="warn")
setSecurityManager(oldSecurityManager)

if new_result.get('exception', None):
self.cached_result['exception'] = new_result['exception']
Expand Down
10 changes: 10 additions & 0 deletions eea/sparql/profiles/default/skins.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<object name="portal_skins">
<object name="sparql_templates"
meta_type="Filesystem Directory View"
directory="eea.sparql:skins/sparql_templates"/>

<skin-path name="*">
<layer insert-after="custom" name="sparql_templates"/>
</skin-path>
</object>
7 changes: 7 additions & 0 deletions eea/sparql/skins.zcml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<configure
xmlns:cmf="http://namespaces.zope.org/cmf"
i18n_domain="eea">

<cmf:registerDirectory name="sparql_templates" />

</configure>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.sparql-preview-div {
background-color:#DDD;
float:left;
}

.sparql-preview-label {
font-size:14px;
}

.sparql-readonly-field {
background-color:#DDD;
}
91 changes: 91 additions & 0 deletions eea/sparql/skins/sparql_templates/sparql_textfield_with_preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
function preview_sparql(){
var ajax_data = {
"endpoint" : jQuery("#endpoint_url").attr("value"),
"timeout" : jQuery("#timeout").attr("value"),
"arg_spec" : jQuery("#arg_spec").attr("value"),
"sparql_query" : jQuery("#sparql_query").attr("value")
};
var preview_arguments = jQuery(".sparql-preview-arguments").attr("value");
var args_list = preview_arguments.split("&");
jQuery.each(args_list, function(idx, arg){
ajax_data[arg.split("=")[0]] = arg.split("=")[1];
});
jQuery.ajax({
url:portal_url + "/sparql.quick_preview",
type:"POST",
data: ajax_data,
success:function(data){
var sparql_preview = jQuery("<div class='sparql_preview'></div>");
jQuery(data).appendTo(sparql_preview);
sparql_preview.dialog({
title:"Preview for " + jQuery("#title").attr("value"),
modal:true,
width:'auto',
create: function() {
$(this).css("maxHeight", 600);
$(this).css("maxWidth", 800);
}
});
}
});
}

function sparql_setstatic(){
if (jQuery("#sparql_static").attr("checked")){
jQuery("#endpoint_url").attr("readonly", true);
jQuery("#timeout").attr("disabled", true);
jQuery("#arg_spec").attr("readonly", true);
jQuery("#sparql_query").attr("readonly", true);

jQuery("#endpoint_url").addClass("sparql-readonly-field");
jQuery("#arg_spec").addClass("sparql-readonly-field");
jQuery("#sparql_query").addClass("sparql-readonly-field");
}
else{
jQuery("#endpoint_url").attr("readonly", false);
jQuery("#timeout").attr("disabled", false);
jQuery("#arg_spec").attr("readonly", false);
jQuery("#sparql_query").attr("readonly", false);
jQuery(".sparql-readonly-field").removeClass("sparql-readonly-field");
}
}

function check_relations(){
if (window.location.href.indexOf("portal_factory") !== -1){
return;
}
jQuery.ajax({
url:absolute_url + "/sparql.related_items",
type:"GET",
success:function(data){
var back_rels = JSON.parse(data);
if (back_rels.length !== 0){
var warningMessage = jQuery(
'<dl class="portalMessage">'+
'<dt>Warning</dt>'+
'<div style="clear:both"></div'+
'<dd>' +
'The result of this query is used by:' +
'<ul class="sparql-back-relations"></ul>' +
'Modifying the query may cause problems in them.' +
'</dd>'+
'</dl>');
jQuery("#sparql-base-edit").prepend(warningMessage);
jQuery.each(back_rels, function(idx, rel){
var rel_msg = jQuery(
'<li><a href="'+rel[1]+'">'+rel[0]+'</a></li>'
);
rel_msg.appendTo(".sparql-back-relations");
});
}
}
});

// jQuery("<div>XXX</div>").after(".documentFirstHeading");
}
jQuery(document).ready(function($) {
jQuery(".sparql-query-results-preview").click(preview_sparql);
jQuery("#sparql_static").click(sparql_setstatic);
sparql_setstatic();
check_relations();
});
Loading

0 comments on commit da83388

Please sign in to comment.