diff --git a/ckan/controllers/user.py b/ckan/controllers/user.py index 4deaf17a1a8..7a0cf3389bb 100644 --- a/ckan/controllers/user.py +++ b/ckan/controllers/user.py @@ -103,8 +103,6 @@ def read(self, id=None): c.about_formatted = self._format_about(user_dict['about']) c.user_activity_stream = user_activity_list_html(context, {'id':c.user_dict['id']}) - - c.created_formatted = h.date_str_to_datetime(user_dict['created']).strftime('%b %d, %Y') return render('user/read.html') def me(self): diff --git a/ckan/lib/base.py b/ckan/lib/base.py index 501dc7f7233..753dcc2ffa4 100644 --- a/ckan/lib/base.py +++ b/ckan/lib/base.py @@ -87,6 +87,18 @@ def __before__(self, action, **params): i18n.handle_request(request, c) def _identify_user(self): + ''' + Identifies the user using two methods: + a) If he has logged into the web interface then repoze.who will + set REMOTE_USER. + b) For API calls he may set a header with his API key. + If the user is identified then: + c.user = user name (unicode) + c.author = user name + otherwise: + c.user = None + c.author = user\'s IP address (unicode) + ''' # see if it was proxied first c.remote_addr = request.environ.get('HTTP_X_FORWARDED_FOR', '') if not c.remote_addr: @@ -98,7 +110,7 @@ def _identify_user(self): c.user = c.user.decode('utf8') c.userobj = model.User.by_name(c.user) if c.userobj is None: - # This occurs when you are logged in with openid, clean db + # This occurs when you are logged in, clean db # and then restart i.e. only really for testers. There is no # user object, so even though repoze thinks you are logged in # and your cookie has ckan_display_name, we need to force user diff --git a/ckan/lib/dictization/model_save.py b/ckan/lib/dictization/model_save.py index aa121c0df6e..47a46b8b5a4 100644 --- a/ckan/lib/dictization/model_save.py +++ b/ckan/lib/dictization/model_save.py @@ -286,10 +286,14 @@ def package_dict_save(pkg_dict, context): package_tag_list_save(pkg_dict.get("tags", []), pkg, context) package_membership_list_save(pkg_dict.get("groups", []), pkg, context) - subjects = pkg_dict.get('relationships_as_subject', []) - relationship_list_save(subjects, pkg, 'relationships_as_subject', context) - objects = pkg_dict.get('relationships_as_object', []) - relationship_list_save(subjects, pkg, 'relationships_as_object', context) + # relationships are not considered 'part' of the package, so only + # process this if the key is provided + if 'relationships_as_subject' in pkg_dict: + subjects = pkg_dict.get('relationships_as_subject', []) + relationship_list_save(subjects, pkg, 'relationships_as_subject', context) + if 'relationships_as_object' in pkg_dict: + objects = pkg_dict.get('relationships_as_object', []) + relationship_list_save(objects, pkg, 'relationships_as_object', context) extras = package_extras_save(pkg_dict.get("extras", []), pkg, context) diff --git a/ckan/lib/hash.py b/ckan/lib/hash.py index 8aae27ae3b8..7fa52331912 100644 --- a/ckan/lib/hash.py +++ b/ckan/lib/hash.py @@ -12,7 +12,7 @@ def get_message_hash(value): # avoid getting config value at module scope since config may # not be read in yet secret = config['beaker.session.secret'] - return hmac.new(secret, value, hashlib.sha1).hexdigest() + return hmac.new(secret, value.encode('utf8'), hashlib.sha1).hexdigest() def get_redirect(): '''Checks the return_to value against the hash, and if it diff --git a/ckan/lib/helpers.py b/ckan/lib/helpers.py index 4f7fc53806a..80926f47e17 100644 --- a/ckan/lib/helpers.py +++ b/ckan/lib/helpers.py @@ -281,11 +281,15 @@ def pager(self, *args, **kwargs): ) return super(Page, self).pager(*args, **kwargs) -def render_datetime(datetime_, date_format='%Y-%m-%d %H:%M'): +def render_datetime(datetime_, date_format=None, with_hours=False): '''Render a datetime object or timestamp string as a pretty string (Y-m-d H:m). If timestamp is badly formatted, then a blank string is returned. ''' + if not date_format: + date_format = '%b %d, %Y' + if with_hours: + date_format += ', %H:%M' if isinstance(datetime_, datetime.datetime): return datetime_.strftime(date_format) elif isinstance(datetime_, basestring): diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 4f2392f8543..0101bc726c0 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -1,5 +1,6 @@ -import re import datetime +from itertools import count +import re from pylons.i18n import _, ungettext, N_, gettext from ckan.lib.navl.dictization_functions import Invalid, Missing, missing, unflatten from ckan.authz import Authorizer @@ -268,13 +269,17 @@ def tag_string_convert(key, data, errors, context): '''Takes a list of tags that is a comma-separated string (in data[key]) and parses tag names. These are added to the data dict, enumerated. They are also validated.''' - tag_string = data[key] - tags = [tag.strip() \ - for tag in tag_string.split(',') \ - if tag.strip()] + if isinstance(data[key], basestring): + tags = [tag.strip() \ + for tag in data[key].split(',') \ + if tag.strip()] + else: + tags = data[key] + + current_index = max( [int(k[1]) for k in data.keys() if len(k) == 3 and k[0] == 'tags'] + [-1] ) - for num, tag in enumerate(tags): + for num, tag in zip(count(current_index+1), tags): data[('tags', num, 'name')] = tag for tag in tags: diff --git a/ckan/public/css/style.css b/ckan/public/css/style.css index 140335ac9ff..33640224e24 100644 --- a/ckan/public/css/style.css +++ b/ckan/public/css/style.css @@ -1527,30 +1527,30 @@ body.authz form button { /* = Activity Streams = */ /* ==================== */ -.activity-stream-activity { +.activity-stream .activity { padding-bottom:1em; } -.activity-stream-activity a { +.activity-stream .activity a { font-weight:bold; } -.activity-stream-activity .actor { +.activity-stream .activity .actor { } -.activity-stream-activity .verb { +.activity-stream .activity .verb { background-color:PapayaWhip; padding:.25em; margin:.25em; } -.activity-stream-activity .object { +.activity-stream .activity .object { } -.activity-stream-activity .target { +.activity-stream .activity .target { } -.activity-stream-activity .date { +.activity-stream .activity .date { color:#999; } diff --git a/ckan/templates/_util.html b/ckan/templates/_util.html index 6142b80ceda..9e8a7fce367 100644 --- a/ckan/templates/_util.html +++ b/ckan/templates/_util.html @@ -384,7 +384,7 @@ -