Skip to content

Commit

Permalink
Merge branch 'master' into 2939-orgs
Browse files Browse the repository at this point in the history
Conflicts:
	ckan/config/routing.py

        trivial merge

	ckan/controllers/group.py

        activity list html no longer added to c

	ckan/logic/action/delete.py

        schema now passed to _unfollow

	ckan/templates/package/read.html

        help text is now added to sidebar

	ckan/tests/functional/api/test_activity.py

        fix test to run as sysadmin due to package_show rights
  • Loading branch information
tobes committed Nov 8, 2012
2 parents 21eabce + c59b304 commit 430ba1d
Show file tree
Hide file tree
Showing 123 changed files with 12,825 additions and 9,082 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -42,3 +42,6 @@ htmlcov/*
ckan.log
ckan_deb/DEBIAN/control
ckan_deb/DEBIAN/prerm

# node.js
node_modules/
125 changes: 77 additions & 48 deletions CHANGELOG.txt
Expand Up @@ -11,64 +11,93 @@ v2.0
check_access() instead.
* [#2257] Removed deprecated datetime_to_datestr() template helper function.

v1.8
====
v1.8 2012-10-19
===============

* [#2592,#2428] Ubuntu 12.04 Precise is now supported with CKAN source install.
The source install instructions have been updated and simplified.
Some of CKAN's dependencies have been updated and some removed.
* Requirements have been updated see doc/install-from-source.rst
users will need to do a new pip install (#2592)
* [#2304] New 'follow' feature. You'll now see a 'Followers' tab on user and
dataset pages, where you can see how many users are following that user or
dataset. If you're logged in, you'll see a 'Follow' button on the pages of
datasets and other users that you can click to follow them. There are also
API calls for the follow features, see the Action API reference
documentation.
* [#2305] New user dashboards, implemented by Sven R. Kunze
(https://github.com/kunsv) as part of his Masters thesis. When logged in, if
you go to your own user page you'll see a new 'Dashboard' tab where you can
see an activity stream from of all the users and datasets that you're
following.
* [#2345] New action API reference docs. The documentation for CKAN's Action
API has been rewritten, with each function and its arguments and return
values now individually documented.
* Template helper functions are now restricted by default. This is
part of a process of refactoring the CKAN code. By default only
those helper functions listed in lib.helpers.__allowed_functions__
are available to templates. The full functions can still be made
available by `setting ckan.restrict_template_vars = false` in your
.ini config file. Only restricted functions will be allowed in
future versions of CKAN.
* [#2842] Allow sort ordering of dataset listings on group pages
Note: This version requires a requirements upgrade on source installations
Note: This version requires a database upgrade
Note: This version does not require a Solr schema upgrade

Major
* New 'follow' feature that allows logged in users to follow other users or
datasets (#2304)
* New user dashboard that shows an activity stream of all the datasets and
users you are following. Thanks to Sven R. Kunze for his work on this (#2305)
* New version of the Datastore. It has been completely rewritten to use
PostgreSQL as backend, it is more stable and fast and supports SQL queries
(#2733)
* Clean up and simplifyng of CKAN's dependencies and source install
instructions. Ubuntu 12.04 is now supported for source installs (#2428,#2592)
* Big speed improvements when indexing datasets (#2788)
* New action API reference docs, which individually document each function and
its arguments and return values (#2345)
* Updated translations, added Japanese and Korean translations

Minor
* Add source install upgrade docs (#2757)
* Mark more strings for translation (#2770)
* Allow sort ordering of dataset listings on group pages (#2842)
* Reenable simple search option (#2844)
* Editing organization removes all datasets (#2845)
* Accessibility enhancements on templates

Bug fixes
* Fix for relative url being used when doing file upload to local storage
* Various fixes on IGroupFrom (#2750)
* Fix group dataset sort (#2722)
* Fix adding existing datasets to organizations (#2843)
* Fix 500 error in related controller (#2856)
* Fix for non-open licenses appearing open
* Editing organization removes all datasets (#2845)

API changes and deprecation:
* [#2313] Deprecated functions related to the old faceting data structure have
been removed: `helpers.py:facet_items()`, `facets.html:facet_sidebar()`,
`facets.html:facet_list_items()`.
Internal use of the old facets datastructure (attached to the context,
`c.facets`) has been superseded by use of the improved facet data structure,
`c.search_facets`. The old data structure is still available on `c.facets`,
but is deprecated, and will be removed in v1.9.
* Template helper functions are now restricted by default. By default only
those helper functions listed in lib.helpers.__allowed_functions__
are available to templates. The full functions can still be made
available by setting `ckan.restrict_template_vars = false` in your ini file.
Only restricted functions will be allowed in future versions of CKAN.
* Deprecated functions related to the old faceting data structure have
been removed: `helpers.py:facet_items()`, `facets.html:facet_sidebar()`,
`facets.html:facet_list_items()`.
Internal use of the old facets datastructure (attached to the context,
`c.facets`) has been superseded by use of the improved facet data structure,
`c.search_facets`. The old data structure is still available on `c.facets`,
but is deprecated, and will be removed in future versions. (#2313)


v1.7.2 2012-10-19
=================

Minor:
* Documentation enhancements regarding file uploads

Bug fixes:
* Fixes for lincences i18n
* Remove sensitive data from user dict (#2784)
* Fix bug in feeds controller (#2869)
* Show dataset author and maintainer names even if they have no emails
* Fix URLs for some Amazon buckets
* Other minor fixes


v1.7.1 2012-06-20
=================

Minor:
* Documentation enhancements regarding install and extensions (#2505)
* Home page and search results speed improvements (#2402,#2403)
* I18n: Added Greek translation and updated other ones (#2506)
* Documentation enhancements regarding install and extensions (#2505)
* Home page and search results speed improvements (#2402,#2403)
* I18n: Added Greek translation and updated other ones (#2506)

Bug fixes:
* UI fixes (#2507)
* Fixes for i18n login and logout issues (#2497)
* Date on add/edit resource breaks if offset is specified (#2383)
* Fix in organizations read page (#2509)
* Add synchronous_search plugin to deployment.ini template (#2521)
* Inconsistent language on license dropdown (#2575)
* Fix bug in translating lists in multilingual plugin
* Group autocomplete doesn't work with multiple words (#2373)
* Other minor fixes
* UI fixes (#2507)
* Fixes for i18n login and logout issues (#2497)
* Date on add/edit resource breaks if offset is specified (#2383)
* Fix in organizations read page (#2509)
* Add synchronous_search plugin to deployment.ini template (#2521)
* Inconsistent language on license dropdown (#2575)
* Fix bug in translating lists in multilingual plugin
* Group autocomplete doesn't work with multiple words (#2373)
* Other minor fixes


v1.7 2012-05-09
Expand Down
8 changes: 7 additions & 1 deletion ckan/config/routing.py
Expand Up @@ -189,6 +189,8 @@ def make_map():
'read_ajax',
'history_ajax',
'followers',
'follow',
'unfollow',
'delete',
'api_data',
]))
Expand Down Expand Up @@ -231,7 +233,8 @@ def make_map():
'members',
'member_new',
'member_delete',
'history'
'history',
'activity',
]))
)
m.connect('group_read', '/group/{id}', action='read')
Expand Down Expand Up @@ -268,7 +271,10 @@ def make_map():
m.connect('/user/edit', action='edit')
# Note: openid users have slashes in their ids, so need the wildcard
# in the route.
m.connect('/user/activity/{id}', action='activity')
m.connect('/user/dashboard', action='dashboard')
m.connect('/user/follow/{id}', action='follow')
m.connect('/user/unfollow/{id}', action='unfollow')
m.connect('/user/followers/{id:.*}', action='followers')
m.connect('/user/edit/{id:.*}', action='edit')
m.connect('/user/reset/{id:.*}', action='perform_reset')
Expand Down
30 changes: 24 additions & 6 deletions ckan/controllers/group.py
Expand Up @@ -271,12 +271,6 @@ def pager_url(q=None, page=None):
c.facets = {}
c.page = h.Page(collection=[])

# Add the group's activity stream (already rendered to HTML) to the
# template context for the group/read.html template to retrieve later.
c.group_activity_stream = \
self._action('group_activity_list_html')(context,
{'id': c.group_dict['id']})

return render(self._read_template(c.group_dict['type']))

def new(self, data=None, errors=None, error_summary=None):
Expand Down Expand Up @@ -602,6 +596,30 @@ def history(self, id):
return feed.writeString('utf-8')
return render(self._history_template(c.group_dict['type']))

def activity(self, id):
'''Render this group's public activity stream page.'''

context = {'model': model, 'session': model.Session,
'user': c.user or c.author, 'for_view': True}
data_dict = {'id': id}

try:
c.group_dict = get_action('group_show')(context, data_dict)
c.group = context['group']
except NotFound:
abort(404, _('Group not found'))
except NotAuthorized:
abort(401,
_('Unauthorized to read group {group_id}').format(
group_id=id))

# Add the group's activity stream (already rendered to HTML) to the
# template context for the group/read.html template to retrieve later.
c.group_activity_stream = get_action('group_activity_list_html')(
context, {'id': c.group_dict['id']})

return render('group/activity_stream.html')

def _render_edit_form(self, fs):
# errors arrive in c.error and fs.errors
c.fieldset = fs
Expand Down
35 changes: 35 additions & 0 deletions ckan/controllers/package.py
Expand Up @@ -1186,6 +1186,41 @@ def api_data(self, id=None):
url = h.url_for('datastore_read', id=id, qualified=True)
return render('package/resource_api_data.html', {'datastore_root_url': url})

def follow(self, id):
'''Start following this dataset.'''
context = {'model': model,
'session': model.Session,
'user': c.user or c.author}
data_dict = {'id': id}
try:
get_action('follow_dataset')(context, data_dict)
h.flash_success(_("You are now following {0}").format(id))
except ValidationError as e:
error_message = (e.extra_msg or e.message or e.error_summary
or e.error_dict)
h.flash_error(error_message)
except NotAuthorized as e:
h.flash_error(e.extra_msg)
h.redirect_to(controller='package', action='read', id=id)

def unfollow(self, id):
'''Stop following this dataset.'''
context = {'model': model,
'session': model.Session,
'user': c.user or c.author}
data_dict = {'id': id}
try:
get_action('unfollow_dataset')(context, data_dict)
h.flash_success(_("You are no longer following {0}").format(id))
except ValidationError as e:
error_message = (e.extra_msg or e.message or e.error_summary
or e.error_dict)
h.flash_error(error_message)
except (NotFound, NotAuthorized) as e:
error_message = e.extra_msg or e.message
h.flash_error(error_message)
h.redirect_to(controller='package', action='read', id=id)

def followers(self, id=None):
context = {'model': model, 'session': model.Session,
'user': c.user or c.author, 'for_view': True}
Expand Down
75 changes: 65 additions & 10 deletions ckan/controllers/user.py
Expand Up @@ -58,6 +58,7 @@ def _setup_template_variables(self, context, data_dict):
abort(401, _('Not authorized to see this page'))
c.user_dict = user_dict
c.is_myself = user_dict['name'] == c.user
c.about_formatted = self._format_about(user_dict['about'])

## end hooks

Expand Down Expand Up @@ -110,20 +111,21 @@ def read(self, id=None):

self._setup_template_variables(context, data_dict)

c.about_formatted = self._format_about(c.user_dict['about'])
c.user_activity_stream = get_action('user_activity_list_html')(
context, {'id': c.user_dict['id']})
# The legacy templates have the user's activity stream on the user
# profile page, new templates do not.
if asbool(config.get('ckan.legacy_templates', False)):
c.user_activity_stream = get_action('user_activity_list_html')(
context, {'id': c.user_dict['id']})

return render('user/read.html')

def me(self, locale=None):
if not c.user:
h.redirect_to(locale=locale, controller='user',
action='login', id=None)
h.redirect_to(locale=locale, controller='user', action='login',
id=None)
user_ref = c.userobj.get_reference_preferred_for_uri()
if asbool(config.get('ckan.legacy_templates', 'false')):
h.redirect_to(locale=locale, controller='user',
action='dashboard', id=user_ref)
return self.read(id=c.username)
h.redirect_to(locale=locale, controller='user', action='dashboard',
id=user_ref)

def register(self, data=None, errors=None, error_summary=None):
return self.new(data, errors, error_summary)
Expand Down Expand Up @@ -317,7 +319,7 @@ def logged_in(self):
user_dict['display_name'])
if came_from:
return h.redirect_to(str(came_from))
return self.me(locale=lang)
return self.me()
else:
err = _('Login failed. Bad username or password.')
if g.openid_enabled:
Expand Down Expand Up @@ -475,9 +477,62 @@ def followers(self, id=None):
c.followers = f(context, {'id': c.user_dict['id']})
return render('user/followers.html')

def activity(self, id):
'''Render this user's public activity stream page.'''

context = {'model': model, 'session': model.Session,
'user': c.user or c.author, 'for_view': True}
data_dict = {'id': id, 'user_obj': c.userobj}
try:
check_access('user_show', context, data_dict)
except NotAuthorized:
abort(401, _('Not authorized to see this page'))

self._setup_template_variables(context, data_dict)

c.user_activity_stream = get_action('user_activity_list_html')(
context, {'id': c.user_dict['id']})

return render('user/activity_stream.html')

def dashboard(self, id=None):
context = {'model': model, 'session': model.Session,
'user': c.user or c.author, 'for_view': True}
data_dict = {'id': id, 'user_obj': c.userobj}
self._setup_template_variables(context, data_dict)
return render('user/dashboard.html')

def follow(self, id):
'''Start following this user.'''
context = {'model': model,
'session': model.Session,
'user': c.user or c.author}
data_dict = {'id': id}
try:
get_action('follow_user')(context, data_dict)
h.flash_success(_("You are now following {0}").format(id))
except ValidationError as e:
error_message = (e.extra_msg or e.message or e.error_summary
or e.error_dict)
h.flash_error(error_message)
except NotAuthorized as e:
h.flash_error(e.extra_msg)
h.redirect_to(controller='user', action='read', id=id)

def unfollow(self, id):
'''Stop following this user.'''
context = {'model': model,
'session': model.Session,
'user': c.user or c.author}
data_dict = {'id': id}
try:
get_action('unfollow_user')(context, data_dict)
h.flash_success(_("You are no longer following {0}").format(id))
except (NotFound, NotAuthorized) as e:
error_message = e.extra_msg or e.message
h.flash_error(error_message)
except ValidationError as e:
error_message = (e.error_summary or e.message or e.extra_msg
or e.error_dict)
h.flash_error(error_message)
h.redirect_to(controller='user', action='read', id=id)

0 comments on commit 430ba1d

Please sign in to comment.