[ckan-changes] commit/ckan: 4 new changesets
Bitbucket
commits-noreply at bitbucket.org
Tue Aug 2 18:24:53 UTC 2011
4 new changesets in ckan:
http://bitbucket.org/okfn/ckan/changeset/540e85756422/
changeset: 540e85756422
branch: feature-1258-purge-revision-in-repo
user: kindly
date: 2011-08-02 17:18:54
summary: [model] override purge revision in ckan repo
affected #: 1 file (2.6 KB)
--- a/ckan/model/__init__.py Fri Jul 29 19:04:17 2011 +0200
+++ b/ckan/model/__init__.py Tue Aug 02 16:18:54 2011 +0100
@@ -23,6 +23,7 @@
from changeset import Changeset, Change, Changemask
import ckan.migration
from ckan.lib.helpers import OrderedDict
+from vdm.sqlalchemy.base import SQLAlchemySession
# set up in init_model after metadata is bound
version_table = None
@@ -180,6 +181,63 @@
metadata.reflect()
return bool(metadata.tables)
+ def purge_revision(self, revision, leave_record=False):
+ '''Purge all changes associated with a revision.
+
+ @param leave_record: if True leave revision in existence but change message
+ to "PURGED: {date-time-of-purge}". If false delete revision object as
+ well.
+
+ Summary of the Algorithm
+ ------------------------
+
+ 1. list all RevisionObjects affected by this revision
+ 2. check continuity objects and cascade on everything else ?
+ 1. crudely get all object revisions associated with this
+ 2. then check whether this is the only revision and delete the
+ continuity object
+
+ 3. ALTERNATIVELY delete all associated object revisions then do a
+ select on continutity to check which have zero associated revisions
+ (should only be these ...)
+ '''
+ to_purge = []
+ SQLAlchemySession.setattr(self.session, 'revisioning_disabled', True)
+ self.session.autoflush = False
+ for o in self.versioned_objects:
+ revobj = o.__revision_class__
+ items = self.session.query(revobj).filter_by(revision=revision).all()
+ for item in items:
+ continuity = item.continuity
+
+ if continuity.revision == revision: # need to change continuity
+ trevobjs = self.session.query(revobj).join('revision'). filter(
+ revobj.continuity==continuity
+ ).order_by(Revision.timestamp.desc()).all()
+ if len(trevobjs) == 0:
+ raise Exception('Should have at least one revision.')
+ if len(trevobjs) == 1:
+ to_purge.append(continuity)
+ else:
+ self.revert(continuity, trevobjs[1])
+ for num, obj in enumerate(trevobjs):
+ if num == 0:
+ continue
+ if 'pending' not in obj.state:
+ obj.current = True
+ self.session.add(obj)
+ break
+ # now delete revision object
+ self.session.delete(item)
+ for cont in to_purge:
+ self.session.delete(cont)
+ if leave_record:
+ import datetime
+ revision.message = u'PURGED: %s' % datetime.datetime.now()
+ else:
+ self.session.delete(revision)
+ self.commit_and_remove()
+
repo = Repository(metadata, Session,
versioned_objects=[Package, PackageTag, Resource, ResourceGroup, PackageExtra, PackageGroup, Group]
http://bitbucket.org/okfn/ckan/changeset/1740c5e66214/
changeset: 1740c5e66214
branch: feature-1258-purge-revision-in-repo
user: kindly
date: 2011-08-02 17:20:50
summary: [model] fix domain modification so that purging works
affected #: 2 files (170 bytes)
--- a/ckan/lib/search/worker.py Tue Aug 02 16:18:54 2011 +0100
+++ b/ckan/lib/search/worker.py Tue Aug 02 16:20:50 2011 +0100
@@ -1,7 +1,9 @@
import logging
+import ckan.model as model
from ckan.model import DomainObjectOperation
from ckan.plugins import SingletonPlugin, implements, IDomainObjectModification
+from ckan.lib.dictization.model_dictize import package_to_api1
from common import SearchError
log = logging.getLogger(__name__)
@@ -31,10 +33,11 @@
implements(IDomainObjectModification, inherit=True)
def notify(self, entity, operation):
-
- if hasattr(entity, 'as_dict') and operation != DomainObjectOperation.deleted:
+
+ if operation != DomainObjectOperation.deleted:
dispatch_by_operation(entity.__class__.__name__,
- entity.as_dict(), operation)
+ package_to_api1(entity, {'model': model}),
+ operation)
elif operation == DomainObjectOperation.deleted:
dispatch_by_operation(entity.__class__.__name__,
{'id': entity.id}, operation)
--- a/ckan/model/modification.py Tue Aug 02 16:18:54 2011 +0100
+++ b/ckan/model/modification.py Tue Aug 02 16:20:50 2011 +0100
@@ -52,12 +52,10 @@
related_packages = obj.related_packages()
except AttributeError:
continue
- if 'pending' in obj.state:
- continue
# this is needed to sort out vdm bug where pkg.as_dict does not
# work when the package is deleted.
for package in related_packages:
- if package not in deleted | new:
+ if package and package not in deleted | new:
changed_pkgs.add(package)
for obj in changed_pkgs:
self.notify(obj, DomainObjectOperation.changed)
http://bitbucket.org/okfn/ckan/changeset/e22d4e385fc8/
changeset: e22d4e385fc8
branch: feature-1258-purge-revision-in-repo
user: kindly
date: 2011-08-02 20:23:20
summary: [merge] default
affected #: 4 files (1.6 KB)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/public/scripts/formatautocomplete.js Tue Aug 02 19:23:20 2011 +0100
@@ -0,0 +1,37 @@
+(function($){
+ var url = "";
+
+ function extractDataAttributes(){
+ var el = $(this);
+ $.each(this.attributes, function(){
+ // get the autocomplete API URL
+ if(this.name === 'data-format-autocomplete-url'){
+ url = this.value;
+ }
+ });
+ }
+
+ function autoCompleteList(request, response){
+ var requestData = {'incomplete': request.term};
+
+ $.ajax({
+ url: url,
+ data: requestData,
+ dataType: 'jsonp',
+ type: 'get',
+ jsonpCallback: 'callback',
+ success: function(json){
+ var formats = [];
+ $.each(json["ResultSet"]["Result"], function(){
+ formats.push(this["Format"]);
+ });
+ response(formats);
+ },
+ });
+ }
+
+ $(document).ready(function(){
+ $('.format-autocomplete').focus(extractDataAttributes)
+ .autocomplete({source: autoCompleteList});
+ });
+})(jQuery);
--- a/ckan/templates/package/edit.html Tue Aug 02 16:20:50 2011 +0100
+++ b/ckan/templates/package/edit.html Tue Aug 02 19:23:20 2011 +0100
@@ -17,6 +17,9 @@
<!-- Tagcomplete --><script type="text/javascript" src="${g.site_url}/scripts/tagcomplete.js"></script><link rel="stylesheet" href="${g.site_url}/css/tagcomplete.css" />
+
+ <!-- Format field autocomplete -->
+ <script type="text/javascript" src="${g.site_url}/scripts/formatautocomplete.js"></script></py:def><div py:match="content" class="package">
--- a/ckan/templates/package/new_package_form.html Tue Aug 02 16:20:50 2011 +0100
+++ b/ckan/templates/package/new_package_form.html Tue Aug 02 19:23:20 2011 +0100
@@ -78,8 +78,11 @@
<py:for each="num, res in enumerate(data.get('resources', []) + [{}])"><tr><py:for each="col in c.resource_columns">
- <td class="resource-${col}">
- <input name="resources__${num}__${col}" type="text" value="${res.get(col, '')}" class="${'medium-width' if col=='description' else 'short'}" />
+ <td py:choose="" class="resource-${col}">
+ <input py:when="col == 'format'" name="resources__${num}__${col}"
+ type="text" value="${res.get(col, '')}" class="format-autocomplete short"
+ data-format-autocomplete-url="/api/2/util/resource/format_autocomplete" />
+ <input py:otherwise="" name="resources__${num}__${col}" type="text" value="${res.get(col, '')}" class="${'medium-width' if col=='description' else 'short'}" /></td></py:for><td class="resource-id"><input name="resources__${num}__id" type="hidden" value="${res.get('id', '')}" /></td>
--- a/doc/api.rst Tue Aug 02 16:20:50 2011 +0100
+++ b/doc/api.rst Tue Aug 02 19:23:20 2011 +0100
@@ -535,3 +535,16 @@
::
{"ResultSet": {"Result": [{"Name": "russian"}]}}
+
+Similarly, there is an autocomplete API for the resource format field
+which is available at:
+
+::
+
+ /api/2/util/resource/format_autocomplete?incomplete=cs
+
+This returns:
+
+::
+
+ {"ResultSet": {"Result": [{"Format": "csv"}]}}
http://bitbucket.org/okfn/ckan/changeset/973b4e87d461/
changeset: 973b4e87d461
user: kindly
date: 2011-08-02 20:24:18
summary: [merge] feature-1258-purge-revision-in-repo
affected #: 3 files (2.7 KB)
--- a/ckan/lib/search/worker.py Tue Aug 02 15:50:13 2011 +0100
+++ b/ckan/lib/search/worker.py Tue Aug 02 19:24:18 2011 +0100
@@ -1,7 +1,9 @@
import logging
+import ckan.model as model
from ckan.model import DomainObjectOperation
from ckan.plugins import SingletonPlugin, implements, IDomainObjectModification
+from ckan.lib.dictization.model_dictize import package_to_api1
from common import SearchError
log = logging.getLogger(__name__)
@@ -31,10 +33,11 @@
implements(IDomainObjectModification, inherit=True)
def notify(self, entity, operation):
-
- if hasattr(entity, 'as_dict') and operation != DomainObjectOperation.deleted:
+
+ if operation != DomainObjectOperation.deleted:
dispatch_by_operation(entity.__class__.__name__,
- entity.as_dict(), operation)
+ package_to_api1(entity, {'model': model}),
+ operation)
elif operation == DomainObjectOperation.deleted:
dispatch_by_operation(entity.__class__.__name__,
{'id': entity.id}, operation)
--- a/ckan/model/__init__.py Tue Aug 02 15:50:13 2011 +0100
+++ b/ckan/model/__init__.py Tue Aug 02 19:24:18 2011 +0100
@@ -23,6 +23,7 @@
from changeset import Changeset, Change, Changemask
import ckan.migration
from ckan.lib.helpers import OrderedDict
+from vdm.sqlalchemy.base import SQLAlchemySession
# set up in init_model after metadata is bound
version_table = None
@@ -180,6 +181,63 @@
metadata.reflect()
return bool(metadata.tables)
+ def purge_revision(self, revision, leave_record=False):
+ '''Purge all changes associated with a revision.
+
+ @param leave_record: if True leave revision in existence but change message
+ to "PURGED: {date-time-of-purge}". If false delete revision object as
+ well.
+
+ Summary of the Algorithm
+ ------------------------
+
+ 1. list all RevisionObjects affected by this revision
+ 2. check continuity objects and cascade on everything else ?
+ 1. crudely get all object revisions associated with this
+ 2. then check whether this is the only revision and delete the
+ continuity object
+
+ 3. ALTERNATIVELY delete all associated object revisions then do a
+ select on continutity to check which have zero associated revisions
+ (should only be these ...)
+ '''
+ to_purge = []
+ SQLAlchemySession.setattr(self.session, 'revisioning_disabled', True)
+ self.session.autoflush = False
+ for o in self.versioned_objects:
+ revobj = o.__revision_class__
+ items = self.session.query(revobj).filter_by(revision=revision).all()
+ for item in items:
+ continuity = item.continuity
+
+ if continuity.revision == revision: # need to change continuity
+ trevobjs = self.session.query(revobj).join('revision'). filter(
+ revobj.continuity==continuity
+ ).order_by(Revision.timestamp.desc()).all()
+ if len(trevobjs) == 0:
+ raise Exception('Should have at least one revision.')
+ if len(trevobjs) == 1:
+ to_purge.append(continuity)
+ else:
+ self.revert(continuity, trevobjs[1])
+ for num, obj in enumerate(trevobjs):
+ if num == 0:
+ continue
+ if 'pending' not in obj.state:
+ obj.current = True
+ self.session.add(obj)
+ break
+ # now delete revision object
+ self.session.delete(item)
+ for cont in to_purge:
+ self.session.delete(cont)
+ if leave_record:
+ import datetime
+ revision.message = u'PURGED: %s' % datetime.datetime.now()
+ else:
+ self.session.delete(revision)
+ self.commit_and_remove()
+
repo = Repository(metadata, Session,
versioned_objects=[Package, PackageTag, Resource, ResourceGroup, PackageExtra, PackageGroup, Group]
--- a/ckan/model/modification.py Tue Aug 02 15:50:13 2011 +0100
+++ b/ckan/model/modification.py Tue Aug 02 19:24:18 2011 +0100
@@ -52,12 +52,10 @@
related_packages = obj.related_packages()
except AttributeError:
continue
- if 'pending' in obj.state:
- continue
# this is needed to sort out vdm bug where pkg.as_dict does not
# work when the package is deleted.
for package in related_packages:
- if package not in deleted | new:
+ if package and package not in deleted | new:
changed_pkgs.add(package)
for obj in changed_pkgs:
self.notify(obj, DomainObjectOperation.changed)
Repository URL: https://bitbucket.org/okfn/ckan/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the ckan-changes
mailing list