diff --git a/ckan/config/routing.py b/ckan/config/routing.py index 3e79662c807..436942b6283 100644 --- a/ckan/config/routing.py +++ b/ckan/config/routing.py @@ -257,6 +257,7 @@ def make_map(): # Note: openid users have slashes in their ids, so need the wildcard # in the route. m.connect('/user/dashboard', action='dashboard') + m.connect('/user/follow/{id}', action='follow') m.connect('/user/followers/{id:.*}', action='followers') m.connect('/user/edit/{id:.*}', action='edit') m.connect('/user/reset/{id:.*}', action='perform_reset') diff --git a/ckan/controllers/user.py b/ckan/controllers/user.py index f59273b92bb..122a45d3089 100644 --- a/ckan/controllers/user.py +++ b/ckan/controllers/user.py @@ -481,3 +481,20 @@ def dashboard(self, id=None): 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) diff --git a/ckan/logic/action/create.py b/ckan/logic/action/create.py index 05068ac95ba..279d980836b 100644 --- a/ckan/logic/action/create.py +++ b/ckan/logic/action/create.py @@ -893,51 +893,53 @@ def follow_user(context, data_dict): :rtype: dictionary ''' - if not context.has_key('user'): - raise logic.NotAuthorized + if 'user' not in context: + raise logic.NotAuthorized(_("You must be logged in to follow users")) model = context['model'] session = context['session'] userobj = model.User.get(context['user']) if not userobj: - raise logic.NotAuthorized + raise logic.NotAuthorized(_("You must be logged in to follow users")) schema = (context.get('schema') or ckan.logic.schema.default_follow_user_schema()) - data_dict, errors = _validate(data_dict, schema, context) + validated_data_dict, errors = _validate(data_dict, schema, context) if errors: model.Session.rollback() raise ValidationError(errors) # Don't let a user follow herself. - if userobj.id == data_dict['id']: + if userobj.id == validated_data_dict['id']: message = _('You cannot follow yourself') - raise ValidationError({'message': message}) + raise ValidationError({'message': message}, error_summary=message) # Don't let a user follow someone she is already following. - if model.UserFollowingUser.get(userobj.id, data_dict['id']) is not None: + if model.UserFollowingUser.is_following(userobj.id, + validated_data_dict['id']): message = _( - 'You are already following {id}').format(id=data_dict['id']) - raise ValidationError({'message': message}) + 'You are already following {0}').format(data_dict['id']) + raise ValidationError({'message': message}, error_summary=message) - follower = model_save.user_following_user_dict_save(data_dict, context) + follower = model_save.user_following_user_dict_save(validated_data_dict, + context) activity_dict = { 'user_id': userobj.id, - 'object_id': data_dict['id'], + 'object_id': validated_data_dict['id'], 'activity_type': 'follow user', } activity_dict['data'] = { 'user': ckan.lib.dictization.table_dictize( - model.User.get(data_dict['id']), context), + model.User.get(validated_data_dict['id']), context), } activity_create_context = { 'model': model, 'user': userobj, - 'defer_commit':True, + 'defer_commit': True, 'session': session } logic.get_action('activity_create')(activity_create_context, diff --git a/ckan/logic/schema.py b/ckan/logic/schema.py index 97425021c5a..975d6009fe4 100644 --- a/ckan/logic/schema.py +++ b/ckan/logic/schema.py @@ -40,6 +40,7 @@ activity_type_exists, tag_not_in_vocabulary, url_validator) +from ckan.logic.converters import (convert_user_name_or_id_to_id,) from formencode.validators import OneOf import ckan.model @@ -418,7 +419,8 @@ def default_create_activity_schema(): return schema def default_follow_user_schema(): - schema = {'id': [not_missing, not_empty, unicode, user_id_or_name_exists]} + schema = {'id': [not_missing, not_empty, unicode, + convert_user_name_or_id_to_id]} return schema def default_follow_dataset_schema():