diff --git a/ckan/logic/action/get.py b/ckan/logic/action/get.py
index 27b20e1d372..a948db0b732 100644
--- a/ckan/logic/action/get.py
+++ b/ckan/logic/action/get.py
@@ -915,6 +915,10 @@ def render_new_package_activity(context, activity):
return render('activity_streams/new_package.html',
extra_vars = {'activity': activity})
+def render_deleted_package_activity(context, activity):
+ return render('activity_streams/deleted_package.html',
+ extra_vars = {'activity': activity})
+
def render_new_resource_activity(context, activity, detail):
return render('activity_streams/new_resource.html',
extra_vars = {'activity': activity, 'detail': detail})
@@ -977,6 +981,7 @@ def render_changed_group_activity(context, activity):
activity_renderers = {
'new package' : render_new_package_activity,
'changed package' : render_changed_package_activity,
+ 'deleted package' : render_deleted_package_activity,
'new user' : render_new_user_activity,
'changed user' : render_changed_user_activity,
'new group' : render_new_group_activity,
diff --git a/ckan/model/package.py b/ckan/model/package.py
index 083ae5d48df..714c74adda4 100644
--- a/ckan/model/package.py
+++ b/ckan/model/package.py
@@ -544,8 +544,24 @@ def activity_stream_item(self, activity_type, revision, user_id):
import ckan.model
import ckan.lib.dictization
import ckan.logic
- assert activity_type in ("new", "changed", "deleted"), (
+ assert activity_type in ("new", "changed"), (
str(activity_type))
+
+ # Handle 'deleted' objects.
+ # When the user marks a package as deleted this comes through here as
+ # a 'changed' package activity. We detect this and change it to a
+ # 'deleted' activity.
+ if activity_type == 'changed' and self.state == u'deleted':
+ if ckan.model.Session.query(ckan.model.Activity).filter_by(
+ object_id=self.id, activity_type='deleted').all():
+ # A 'deleted' activity for this object has already been emitted
+ # FIXME: What if the object was deleted and then activated
+ # again?
+ return None
+ else:
+ # Emit a 'deleted' activity for this object.
+ activity_type = 'deleted'
+
try:
d = {'package': ckan.lib.dictization.table_dictize(self,
context={'model': ckan.model})}
@@ -561,6 +577,14 @@ def activity_stream_item(self, activity_type, revision, user_id):
def activity_stream_detail(self, activity_id, activity_type):
import ckan.model
import ckan.lib.dictization
+
+ # Handle 'deleted' objects.
+ # When the user marks a package as deleted this comes through here as
+ # a 'changed' package activity. We detect this and change it to a
+ # 'deleted' activity.
+ if activity_type == 'changed' and self.state == u'deleted':
+ activity_type = 'deleted'
+
package_dict = ckan.lib.dictization.table_dictize(self,
context={'model':ckan.model})
return ActivityDetail(activity_id, self.id, u"Package", activity_type,
diff --git a/ckan/templates/activity_streams/deleted_package.html b/ckan/templates/activity_streams/deleted_package.html
new file mode 100644
index 00000000000..2bdcf300df1
--- /dev/null
+++ b/ckan/templates/activity_streams/deleted_package.html
@@ -0,0 +1,21 @@
+
+