Skip to content

Commit

Permalink
Merge branch 'master' of github.com:okfn/ckan into 252-related-item-b…
Browse files Browse the repository at this point in the history
…utton-fix
  • Loading branch information
Sean Hammond committed Feb 6, 2013
2 parents fc7dc1e + 27b7753 commit f3544a8
Show file tree
Hide file tree
Showing 38 changed files with 539 additions and 510 deletions.
5 changes: 0 additions & 5 deletions .gitignore
Expand Up @@ -6,8 +6,6 @@ syntax: glob
.DS_Store
ckan.egg-info/*
sandbox/*
theme/*
theme
dist

# pylons
Expand All @@ -28,9 +26,6 @@ fl_notes.txt
.noseids
*~

# local symlinks
ckan/public/scripts/ckanjs.js

# custom style
ckan/public/base/less/custom.less

Expand Down
13 changes: 5 additions & 8 deletions README.rst
Expand Up @@ -22,20 +22,17 @@ Community
---------

* Developer mailing list: `ckan-dev@lists.okfn.org <http://lists.okfn.org/mailman/listinfo/ckan-dev>`_
* Developer IRC channel: #ckan on `irc.freenode.net <http://freenode.net/>`_
* Issue tracker: `trac.ckan.org <http://trac.ckan.org/>`_
* Developer IRC channel: `#ckan on irc.freenode.net <http://webchat.freenode.net/?channels=ckan>`_
* `Issue tracker <https://github.com/okfn/ckan/issues>`_
* `CKAN tag on StackOverflow <http://stackoverflow.com/questions/tagged/ckan>`_
* `Wiki <https://github.com/okfn/ckan/wiki>`_


Contributing to CKAN
--------------------

CKAN is a free software project and code contributions are welcome.
The `For CKAN Developers <http://docs.ckan.org/en/latest/index.html#for-ckan-developers>`_
section of the documentation explains how to contribute to CKAN or its documentation,
including our **coding standards**.

The `CKAN Wiki <https://github.com/okfn/ckan/wiki>`_ is also open fo contributions.
For contributing to CKAN or its documentation, see
`CONTRIBUTING <https://github.com/okfn/ckan/blob/master/CONTRIBUTING.rst>`_.


Copying and License
Expand Down
102 changes: 98 additions & 4 deletions ckan/controllers/api.py
Expand Up @@ -3,6 +3,7 @@
import cgi
import datetime
import glob
import urllib

from pylons import c, request, response
from pylons.i18n import _, gettext
Expand Down Expand Up @@ -545,7 +546,7 @@ def search(self, ver=None, register=None):
def _get_search_params(cls, request_params):
if 'qjson' in request_params:
try:
qjson_param = request_params['qjson'].replace('\\\\u','\\u')
qjson_param = request_params['qjson'].replace('\\\\u', '\\u')
params = h.json.loads(qjson_param, encoding='utf8')
except ValueError, e:
raise ValueError(gettext('Malformed qjson value') + ': %r'
Expand Down Expand Up @@ -668,9 +669,8 @@ def group_exists(val):

def dataset_autocomplete(self):
q = request.params.get('incomplete', '')
q_lower = q.lower()
limit = request.params.get('limit', 10)
tag_names = []
package_dicts = []
if q:
context = {'model': model, 'session': model.Session,
'user': c.user or c.author}
Expand Down Expand Up @@ -752,9 +752,103 @@ def i18n_js_translations(self, lang):
''' translation strings for front end '''
ckan_path = os.path.join(os.path.dirname(__file__), '..')
source = os.path.abspath(os.path.join(ckan_path, 'public',
'base', 'i18n', '%s.js' % lang))
'base', 'i18n', '%s.js' % lang))
response.headers['Content-Type'] = CONTENT_TYPES['json']
if not os.path.exists(source):
return '{}'
f = open(source, 'r')
return(f)

@classmethod
def _get_request_data(cls, try_url_params=False):
'''Returns a dictionary, extracted from a request.
If there is no data, None or "" is returned.
ValueError will be raised if the data is not a JSON-formatted dict.
The data is retrieved as a JSON-encoded dictionary from the request
body. Or, if the `try_url_params` argument is True and the request is
a GET request, then an attempt is made to read the data from the url
parameters of the request.
try_url_params
If try_url_params is False, then the data_dict is read from the
request body.
If try_url_params is True and the request is a GET request then the
data is read from the url parameters. The resulting dict will only
be 1 level deep, with the url-param fields being the keys. If a
single key has more than one value specified, then the value will
be a list of strings, otherwise just a string.
'''
def make_unicode(entity):
'''Cast bare strings and strings in lists or dicts to Unicode. '''
if isinstance(entity, str):
return unicode(entity)
elif isinstance(entity, list):
new_items = []
for item in entity:
new_items.append(make_unicode(item))
return new_items
elif isinstance(entity, dict):
new_dict = {}
for key, val in entity.items():
new_dict[key] = make_unicode(val)
return new_dict
else:
return entity

cls.log.debug('Retrieving request params: %r' % request.params)
cls.log.debug('Retrieving request POST: %r' % request.POST)
cls.log.debug('Retrieving request GET: %r' % request.GET)
request_data = None
if request.POST:
try:
keys = request.POST.keys()
# Parsing breaks if there is a = in the value, so for now
# we will check if the data is actually all in a single key
if keys and request.POST[keys[0]] in [u'1', u'']:
request_data = keys[0]
else:
request_data = urllib.unquote_plus(request.body)
except Exception, inst:
msg = "Could not find the POST data: %r : %s" % \
(request.POST, inst)
raise ValueError(msg)

elif try_url_params and request.GET:
return request.GET.mixed()

else:
try:
if request.method in ['POST', 'PUT']:
request_data = request.body
else:
request_data = None
except Exception, inst:
msg = "Could not extract request body data: %s" % \
(inst)
raise ValueError(msg)
cls.log.debug('Retrieved request body: %r' % request.body)
if not request_data:
msg = "No request body data"
raise ValueError(msg)
if request_data:
try:
request_data = h.json.loads(request_data, encoding='utf8')
except ValueError, e:
raise ValueError('Error decoding JSON data. '
'Error: %r '
'JSON data extracted from the request: %r' %
(e, request_data))
if not isinstance(request_data, dict):
raise ValueError('Request data JSON decoded to %r but '
'it needs to be a dictionary.' % request_data)
# ensure unicode values
for key, val in request_data.items():
# if val is str then assume it is ascii, since json converts
# utf8 encoded JSON to unicode
request_data[key] = make_unicode(val)
cls.log.debug('Request data extracted: %r' % request_data)
return request_data
6 changes: 5 additions & 1 deletion ckan/controllers/group.py
Expand Up @@ -673,7 +673,11 @@ def followers(self, id):
context = {'model': model, 'session': model.Session,
'user': c.user or c.author}
c.group_dict = self._get_group_dict(id)
c.followers = get_action('group_follower_list')(context, {'id': id})
try:
c.followers = get_action('group_follower_list')(context,
{'id': id})
except NotAuthorized:
abort(401, _('Unauthorized to view followers %s') % '')
return render('group/followers.html')

def admins(self, id):
Expand Down
1 change: 1 addition & 0 deletions ckan/controllers/home.py
Expand Up @@ -125,6 +125,7 @@ def db_to_form_schema(group_type=None):
'ignore_auth': True,
'user': c.user or c.author,
'schema': db_to_form_schema(group_type=group_type),
'limits': {'packages': 2},
'for_view': True}
data_dict = {'id': id}

Expand Down
7 changes: 5 additions & 2 deletions ckan/controllers/revision.py
Expand Up @@ -69,6 +69,8 @@ def list(self):
# but in the meantime while that is fixed,
# avoid an exception here
continue
if package.private:
continue
number = len(package.all_revisions)
package_revision = None
count = 0
Expand Down Expand Up @@ -142,10 +144,11 @@ def read(self, id=None):

pkgs = model.Session.query(model.PackageRevision).\
filter_by(revision=c.revision)
c.packages = [pkg.continuity for pkg in pkgs]
c.packages = [pkg.continuity for pkg in pkgs if not pkg.private]
pkgtags = model.Session.query(model.PackageTagRevision).\
filter_by(revision=c.revision)
c.pkgtags = [pkgtag.continuity for pkgtag in pkgtags]
c.pkgtags = [pkgtag.continuity for pkgtag in pkgtags
if not pkgtag.package.private]
grps = model.Session.query(model.GroupRevision).\
filter_by(revision=c.revision)
c.groups = [grp.continuity for grp in grps]
Expand Down
5 changes: 4 additions & 1 deletion ckan/controllers/user.py
Expand Up @@ -479,7 +479,10 @@ def followers(self, id=None):
data_dict = {'id': id, 'user_obj': c.userobj}
self._setup_template_variables(context, data_dict)
f = get_action('user_follower_list')
c.followers = f(context, {'id': c.user_dict['id']})
try:
c.followers = f(context, {'id': c.user_dict['id']})
except NotAuthorized:
abort(401, _('Unauthorized to view followers %s') % '')
return render('user/followers.html')

def activity(self, id, offset=0):
Expand Down
9 changes: 9 additions & 0 deletions ckan/lib/activity_streams_session_extension.py
Expand Up @@ -79,6 +79,11 @@ def before_commit(self, session):
# object is a package.
logger.debug("Looks like this object is a package")
logger.debug("activity: %s" % activity)

# Don't create activities for private datasets.
if obj.private:
continue

activities[obj.id] = activity

activity_detail = activity_stream_detail(obj, activity.id, "new")
Expand Down Expand Up @@ -114,6 +119,10 @@ def before_commit(self, session):
for package in related_packages:
if package is None: continue

# Don't create activities for private datasets.
if package.private:
continue

if package.id in activities:
activity = activities[package.id]
else:
Expand Down

0 comments on commit f3544a8

Please sign in to comment.