Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refs #9424; Added data persistence and versioning for eea.sparql

  • Loading branch information...
commit 3f0f02e519fdaaf69741fe8c438d2d6a96769e9e 1 parent ef2e3b8
@zotya zotya authored
View
6 docs/HISTORY.txt
@@ -3,6 +3,12 @@ Changelog
2.4-dev - (unreleased)
----------------------
+* Upgrade step:
+ ZMI > portal_setup > profile "EEA Sparql" > import Diff tool & CMFEditions Repository Tool
+* Feature: Data persistence and versioning
+ - Added versioning for sparql results
+ - Possibility to select static & live queries
+ [szabozo0 refs #9424]
2.3 - (2013-01-18)
------------------
View
3  eea/sparql/browser/sparql.py
@@ -163,11 +163,10 @@ def sparql2csv(self, dialect='excel'):
header = '%s:%s' % (col, data['properties'][col]['valueType'])
row.append(header)
writter.writerow(row)
-
for item in data['items']:
row = []
for col in headers:
- row.append(unicode(item[col]))
+ row.append(unicode(item[col]).encode('utf'))
writter.writerow(row)
return ''
View
3  eea/sparql/browser/view.pt
@@ -36,7 +36,8 @@
</div>
<h3 i18n:translate="">Dataset preview</h3>
-
+ <h4 tal:condition="context/sparql_static">(Static Query)</h4>
+ <h4 tal:condition="not:context/sparql_static">(Live Query)</h4>
<div tal:define="data options/data">
<div class="eea-sparql-table" style="overflow: hidden">
<metal:table use-macro="here/@@sparql.preview/macros/table" />
View
11 eea/sparql/cache/browser.py
@@ -24,11 +24,14 @@ class CacheView(BrowserView):
""" Caching for sparql query results
"""
def __call__(self):
- if not "submit" in self.request.form:
- return self.index()
+ if "invalidate_cache" in self.request.form:
+ event.notify(ObjectModifiedEvent(self.context))
+ IStatusMessage(self.request).addStatusMessage("Cache invalidated")
+ if "invalidate_last_working_results" in self.request.form:
+ self.context.invalidateWorkingResult()
+ message = "Last working results invalidated"
+ IStatusMessage(self.request).addStatusMessage(message)
- event.notify(ObjectModifiedEvent(self.context))
- IStatusMessage(self.request).addStatusMessage("Cache invalidated")
return self.index()
def purgeRelatedItems(obj, evt):
View
5 eea/sparql/cache/caching.pt
@@ -12,7 +12,10 @@
<div metal:fill-slot="main" >
<form method="POST" action="" tal:attributes="action string:${context/absolute_url}/@@caching">
- <input type="submit" name="submit" value="Invalidate cache"
+ <input type="submit" name="invalidate_cache" value="Invalidate cache"
+ i18n:attributes="value" />
+ <br/>
+ <input type="submit" name="invalidate_last_working_results" value="Invalidate last working result"
i18n:attributes="value" />
</form>
View
108 eea/sparql/content/sparql.py
@@ -9,13 +9,14 @@
from Products.Archetypes.atapi import IntegerField
from Products.Archetypes.atapi import SelectionWidget
from Products.Archetypes.atapi import Schema
-from Products.Archetypes.atapi import StringField, StringWidget
+from Products.Archetypes.atapi import StringField, StringWidget, \
+ BooleanWidget, BooleanField
from Products.Archetypes.atapi import TextField, TextAreaWidget
from Products.ZSPARQLMethod.Method import ZSPARQLMethod, \
interpolate_query, \
run_with_timeout, \
- query_and_get_result, \
parse_arg_spec, \
+ query_and_get_result, \
map_arg_values
from AccessControl.Permissions import view
from eea.sparql.cache import ramcache, cacheSparqlKey
@@ -26,6 +27,14 @@
from zope.interface import implements
+from Products.CMFCore.utils import getToolByName
+from Products.CMFEditions.interfaces.IModifier import FileTooLargeToVersionError
+
+from AccessControl import SpecialUsers
+from AccessControl import getSecurityManager
+from AccessControl.SecurityManagement import newSecurityManager, \
+ setSecurityManager
+
SparqlBaseSchema = atapi.Schema((
StringField(
name='endpoint_url',
@@ -63,6 +72,24 @@
),
required=1
),
+ BooleanField(
+ name='sparql_static',
+ widget=BooleanWidget(
+ label='Static query',
+ description='The data will be fetched only once',
+ ),
+ default=False,
+ required=0
+ ),
+ TextField(
+ name='sparql_results',
+ widget=TextAreaWidget(
+ label="Results",
+ visible={'edit': 'invisible', 'view': 'invisible' }
+ ),
+ required=0,
+
+ ),
))
SparqlSchema = getattr(base.ATCTContent, 'schema', Schema(())).copy() + \
@@ -77,6 +104,8 @@
SparqlBaseSchema.copy()
SparqlBookmarksFolderSchema['sparql_query'].widget.description = \
'The query should return label, bookmark url, query'
+SparqlBookmarksFolderSchema['sparql_static'].widget.visible['edit'] = \
+ 'invisible'
class Sparql(base.ATCTContent, ZSPARQLMethod):
"""Sparql"""
@@ -127,25 +156,86 @@ def setTimeout(self, value):
except Exception:
self.timeout = 10
+ security.declareProtected(view, 'invalidateWorkingResult')
+ def invalidateWorkingResult(self):
+ """ invalidate working results"""
+ self.cached_result = {}
+ self.setSparql_results("")
+ pr = getToolByName(self, 'portal_repository')
+ comment = "Invalidated last working result"
+ comment = comment.encode('utf')
+ 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")
+
security.declareProtected(view, 'execute')
def execute(self, **arg_values):
"""
Override execute from ZSPARQLMethod in order to have a default timeout
"""
+ cached_result = getattr(self, 'cached_result', {})
cooked_query = interpolate_query(self.query, arg_values)
- cache_key = {'query': cooked_query}
- result = self.ZCacheable_get(keywords=cache_key)
- if result is None:
+ force_requery = False
+
+ if not self.getSparql_static():
+ force_requery = True
+
+ if cached_result == {}:
+ force_requery = True
+
+ if force_requery:
args = (self.endpoint_url, cooked_query)
- result = run_with_timeout(
+ new_result = run_with_timeout(
max(getattr(self, 'timeout', 10), 10),
query_and_get_result,
*args)
- self.ZCacheable_set(result, keywords=cache_key)
-
- return result
+ force_save = False
+
+ if new_result.get("result", {}) != {}:
+ if new_result != cached_result:
+ if len(new_result.get("result", {}).get("rows", {})) > 0:
+ force_save = True
+ else:
+ if len(cached_result.get('result', {}).\
+ get('rows', {})) == 0:
+ force_save = True
+
+ if force_save:
+ self.cached_result = new_result
+ new_sparql_results = u""
+ for row in self.cached_result.get('result', {}).get('rows', {}):
+ for val in row:
+ new_sparql_results = new_sparql_results + \
+ unicode(val) + " | "
+ 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 new_result.get('exception', None):
+ self.cached_result['exception'] = new_result['exception']
+ return self.cached_result
class SparqlBookmarksFolder(ATFolder, Sparql):
"""Sparql Bookmarks Folder"""

0 comments on commit 3f0f02e

Please sign in to comment.
Something went wrong with that request. Please try again.