Skip to content

Commit

Permalink
[#1038] merge confilcts
Browse files Browse the repository at this point in the history
  • Loading branch information
kindly committed Nov 4, 2013
2 parents 399a6a4 + 5fd8b7a commit b95ef59
Show file tree
Hide file tree
Showing 235 changed files with 7,118 additions and 5,848 deletions.
3 changes: 3 additions & 0 deletions .coveragerc
@@ -0,0 +1,3 @@
[run]
omit = /ckan/migration/*, /ckan/tests/*, */tests/*
source = ckan, ckanext
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -14,3 +14,5 @@ notifications:
on_failure: change
template:
- "%{repository} %{branch} %{commit} %{build_url} %{author}: %{message}"
after_success:
- coveralls
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Expand Up @@ -93,7 +93,7 @@ Deprecated and removed:
one. Please update your config files if using it. (#226)

Known issues:
* Under certain authorization setups the forntend for the groups functionality
* Under certain authorization setups the frontend for the groups functionality
may not work as expected (See #1176 #1175).


Expand Down
14 changes: 8 additions & 6 deletions CONTRIBUTING.rst
Expand Up @@ -60,12 +60,14 @@ When writing code for CKAN, try to respect our coding standards:
html-coding-standards
css-coding-standards
javascript-coding-standards

* `CKAN Coding Standards <http://docs.ckan.org/en/latest/ckan-coding-standards.html>`_
* `Python Coding Standards <http://docs.ckan.org/en/latest/python-coding-standards.html>`_
* `HTML Coding Standards <http://docs.ckan.org/en/latest/html-coding-standards.html>`_
* `CSS Coding Standards <http://docs.ckan.org/en/latest/css-coding-standards.html>`_
* `JavaScript Coding Standards <http://docs.ckan.org/en/latest/javascript-coding-standards.html>`_
testing-coding-standards

* `CKAN coding standards <http://docs.ckan.org/en/latest/ckan-coding-standards.html>`_
* `Python coding standards <http://docs.ckan.org/en/latest/python-coding-standards.html>`_
* `HTML coding standards <http://docs.ckan.org/en/latest/html-coding-standards.html>`_
* `CSS coding standards <http://docs.ckan.org/en/latest/css-coding-standards.html>`_
* `JavaScript coding standards <http://docs.ckan.org/en/latest/javascript-coding-standards.html>`_
* `Testing coding standards <http://docs.ckan.org/en/latest/testing-coding-standards.html>`_


---------------
Expand Down
4 changes: 4 additions & 0 deletions README.rst
Expand Up @@ -5,6 +5,10 @@ CKAN: The Open Source Data Portal Software
:target: http://travis-ci.org/okfn/ckan
:alt: Build Status

.. image:: https://coveralls.io/repos/okfn/ckan/badge.png
:target: https://coveralls.io/r/okfn/ckan
:alt: Test coverage

**CKAN is the world’s leading open-source data portal platform**.
CKAN makes it easy to publish, share and work with data. It's a data management
system that provides a powerful platform for cataloging, storing and accessing
Expand Down
2 changes: 1 addition & 1 deletion bin/travis-build
Expand Up @@ -63,7 +63,7 @@ MOCHA_ERROR=$?
killall paster

# And finally, run the nosetests
nosetests --ckan --with-pylons=test-core.ini --nologcapture ckan ckanext
nosetests --ckan --with-pylons=test-core.ini --nologcapture ckan ckanext --with-coverage --cover-package=ckanext --cover-package=ckan
# Did an error occur?
NOSE_ERROR=$?

Expand Down
6 changes: 5 additions & 1 deletion ckan/ckan_nose_plugin.py
Expand Up @@ -17,6 +17,10 @@ def startContext(self, ctx):
# import needs to be here or setup happens too early
import ckan.model as model

if 'new_tests' in repr(ctx):
# We don't want to do the stuff below for new-style tests.
return

if isclass(ctx):
if hasattr(ctx, "no_db") and ctx.no_db:
return
Expand All @@ -38,7 +42,7 @@ def startContext(self, ctx):
from ckan.plugins.interfaces import IConfigurable
for plugin in PluginImplementations(IConfigurable):
plugin.configure(config)

model.repo.init_db()

def options(self, parser, env):
Expand Down
5 changes: 3 additions & 2 deletions ckan/config/deployment.ini_tmpl
Expand Up @@ -79,6 +79,7 @@ ckan.site_id = default
## Plugins Settings

# Note: Add ``datastore`` to enable the CKAN DataStore
# Add ``datapusher`` to enable DataPusher
# Add ``pdf_preview`` to enable the resource preview for PDFs
# Add ``resource_proxy`` to enable resorce proxying and get around the
# same origin policy
Expand Down Expand Up @@ -146,8 +147,8 @@ ckan.feeds.author_link =

# Make sure you have set up the DataStore

datapusher.formats = csv
datapusher.url = http://datapusher.ckan.org/
ckan.datapusher.formats = csv
ckan.datapusher.url = http://datapusher.ckan.org/

## Activity Streams Settings

Expand Down
10 changes: 7 additions & 3 deletions ckan/config/routing.py
Expand Up @@ -222,7 +222,6 @@ def make_map():
])))
m.connect('/dataset/{action}/{id}',
requirements=dict(action='|'.join([
'edit',
'new_metadata',
'new_resource',
'history',
Expand All @@ -234,20 +233,24 @@ def make_map():
'delete',
'api_data',
])))
m.connect('dataset_edit', '/dataset/edit/{id}', action='edit',
ckan_icon='edit')
m.connect('dataset_followers', '/dataset/followers/{id}',
action='followers', ckan_icon='group')
m.connect('dataset_activity', '/dataset/activity/{id}',
action='activity', ckan_icon='time')
m.connect('/dataset/activity/{id}/{offset}', action='activity')
m.connect('/dataset/{id}.{format}', action='read')
m.connect('dataset_resources', '/dataset/resources/{id}',
action='resources', ckan_icon='reorder')
m.connect('dataset_read', '/dataset/{id}', action='read',
ckan_icon='sitemap')
m.connect('/dataset/{id}/resource/{resource_id}',
action='resource_read')
m.connect('/dataset/{id}/resource_delete/{resource_id}',
action='resource_delete')
m.connect('/dataset/{id}/resource_edit/{resource_id}',
action='resource_edit')
m.connect('resource_edit', '/dataset/{id}/resource_edit/{resource_id}',
action='resource_edit', ckan_icon='edit')
m.connect('/dataset/{id}/resource/{resource_id}/download',
action='resource_download')
m.connect('/dataset/{id}/resource/{resource_id}/embed',
Expand Down Expand Up @@ -359,6 +362,7 @@ def make_map():
action='followers', ckan_icon='group')
m.connect('user_edit', '/user/edit/{id:.*}', action='edit',
ckan_icon='cog')
m.connect('user_delete', '/user/delete/{id}', action='delete')
m.connect('/user/reset/{id:.*}', action='perform_reset')
m.connect('register', '/user/register', action='register')
m.connect('login', '/user/login', action='login')
Expand Down
8 changes: 7 additions & 1 deletion ckan/controllers/admin.py
Expand Up @@ -34,6 +34,11 @@ def _get_config_form_items(self):
{'text': 'Green', 'value': '/base/css/green.css'},
{'text': 'Maroon', 'value': '/base/css/maroon.css'},
{'text': 'Fuchsia', 'value': '/base/css/fuchsia.css'}]

homepages = [{'value': '1', 'text': 'Introductory area, search, featured group and featured organization'},
{'value': '2', 'text': 'Search, stats, introductory area, featured organization and featured group'},
{'value': '3', 'text': 'Search, introductory area and stats'}]

items = [
{'name': 'ckan.site_title', 'control': 'input', 'label': _('Site Title'), 'placeholder': ''},
{'name': 'ckan.main_css', 'control': 'select', 'options': styles, 'label': _('Style'), 'placeholder': ''},
Expand All @@ -42,6 +47,7 @@ def _get_config_form_items(self):
{'name': 'ckan.site_about', 'control': 'markdown', 'label': _('About'), 'placeholder': _('About page text')},
{'name': 'ckan.site_intro_text', 'control': 'markdown', 'label': _('Intro Text'), 'placeholder': _('Text on home page')},
{'name': 'ckan.site_custom_css', 'control': 'textarea', 'label': _('Custom CSS'), 'placeholder': _('Customisable css inserted into the page header')},
{'name': 'ckan.homepage_style', 'control': 'select', 'options': homepages, 'label': _('Homepage'), 'placeholder': ''},
]
return items

Expand Down Expand Up @@ -152,4 +158,4 @@ def trash(self):

for msg in msgs:
h.flash_error(msg)
h.redirect_to(h.url_for('ckanadmin', action='trash'))
h.redirect_to(controller='admin', action='trash')
35 changes: 23 additions & 12 deletions ckan/controllers/api.py
Expand Up @@ -114,8 +114,10 @@ def _finish_ok(self, response_data=None,

return self._finish(status_int, response_data, content_type)

def _finish_not_authz(self):
def _finish_not_authz(self, extra_msg=None):
response_data = _('Access denied')
if extra_msg:
response_data = '%s - %s' % (response_data, extra_msg)
return self._finish(403, response_data, 'json')

def _finish_not_found(self, extra_msg=None):
Expand Down Expand Up @@ -194,10 +196,14 @@ def action(self, logic_function, ver=None):
'data': request_data}
return_dict['success'] = False
return self._finish(400, return_dict, content_type='json')
except NotAuthorized:
except NotAuthorized, e:
return_dict['error'] = {'__type': 'Authorization Error',
'message': _('Access denied')}
return_dict['success'] = False

if e.extra_msg:
return_dict['error']['message'] += ': %s' % e.extra_msg

return self._finish(403, return_dict, content_type='json')
except NotFound, e:
return_dict['error'] = {'__type': 'Not Found Error',
Expand Down Expand Up @@ -277,8 +283,9 @@ def list(self, ver=None, register=None, subregister=None, id=None):
except NotFound, e:
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
except NotAuthorized:
return self._finish_not_authz()
except NotAuthorized, e:
extra_msg = e.extra_msg
return self._finish_not_authz(extra_msg)

def show(self, ver=None, register=None, subregister=None,
id=None, id2=None):
Expand Down Expand Up @@ -308,8 +315,9 @@ def show(self, ver=None, register=None, subregister=None,
except NotFound, e:
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
except NotAuthorized:
return self._finish_not_authz()
except NotAuthorized, e:
extra_msg = e.extra_msg
return self._finish_not_authz(extra_msg)

def _represent_package(self, package):
return package.as_dict(ref_package_by=self.ref_package_by,
Expand Down Expand Up @@ -354,8 +362,9 @@ def create(self, ver=None, register=None, subregister=None,
data_dict.get("id")))
return self._finish_ok(response_data,
resource_location=location)
except NotAuthorized:
return self._finish_not_authz()
except NotAuthorized, e:
extra_msg = e.extra_msg
return self._finish_not_authz(extra_msg)
except NotFound, e:
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
Expand Down Expand Up @@ -410,8 +419,9 @@ def update(self, ver=None, register=None, subregister=None,
try:
response_data = action(context, data_dict)
return self._finish_ok(response_data)
except NotAuthorized:
return self._finish_not_authz()
except NotAuthorized, e:
extra_msg = e.extra_msg
return self._finish_not_authz(extra_msg)
except NotFound, e:
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
Expand Down Expand Up @@ -458,8 +468,9 @@ def delete(self, ver=None, register=None, subregister=None,
try:
response_data = action(context, data_dict)
return self._finish_ok(response_data)
except NotAuthorized:
return self._finish_not_authz()
except NotAuthorized, e:
extra_msg = e.extra_msg
return self._finish_not_authz(extra_msg)
except NotFound, e:
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
Expand Down
23 changes: 21 additions & 2 deletions ckan/controllers/group.py
Expand Up @@ -278,7 +278,8 @@ def pager_url(q=None, page=None):

facets = OrderedDict()

default_facet_titles = {'groups': _('Groups'),
default_facet_titles = {'organization': _('Organizations'),
'groups': _('Groups'),
'tags': _('Tags'),
'res_format': _('Formats'),
'license_id': _('License')}
Expand Down Expand Up @@ -344,6 +345,9 @@ def pager_url(q=None, page=None):
c.facets = {}
c.page = h.Page(collection=[])

self._setup_template_variables(context, {'id':id},
group_type=group_type)

def bulk_process(self, id):
''' Allow bulk processing of datasets for an organization. Make
private/public or delete. For organization admins.'''
Expand Down Expand Up @@ -612,6 +616,19 @@ def member_new(self, id):
data_dict = clean_dict(dict_fns.unflatten(
tuplize_dict(parse_params(request.params))))
data_dict['id'] = id

email = data_dict.get('email')
if email:
user_data_dict = {
'email': email,
'group_id': data_dict['id'],
'role': data_dict['role']
}
del data_dict['email']
user_dict = self._action('user_invite')(context,
user_data_dict)
data_dict['username'] = user_dict['name']

c.group_dict = self._action('group_member_create')(context, data_dict)
self._redirect_to(controller='group', action='members', id=id)
else:
Expand Down Expand Up @@ -815,7 +832,9 @@ def admins(self, id):

def about(self, id):
c.group_dict = self._get_group_dict(id)
return render(self._about_template(c.group_dict['type']))
group_type = c.group_dict['type']
self._setup_template_variables({}, {'id': id}, group_type=group_type)
return render(self._about_template(group_type))

def _get_group_dict(self, id):
''' returns the result of group_show action or aborts if there is a
Expand Down
1 change: 1 addition & 0 deletions ckan/controllers/home.py
Expand Up @@ -67,6 +67,7 @@ def index(self):
c.search_facets = query['search_facets']

c.facet_titles = {
'organization': _('Organizations'),
'groups': _('Groups'),
'tags': _('Tags'),
'res_format': _('Formats'),
Expand Down
43 changes: 0 additions & 43 deletions ckan/controllers/organization.py
Expand Up @@ -15,48 +15,5 @@ class OrganizationController(group.GroupController):
# this makes us use organization actions
group_type = 'organization'

def _group_form(self, group_type=None):
return 'organization/new_organization_form.html'

def _form_to_db_schema(self, group_type=None):
return group.lookup_group_plugin(group_type).form_to_db_schema()

def _db_to_form_schema(self, group_type=None):
'''This is an interface to manipulate data from the database
into a format suitable for the form (optional)'''
pass

# This is commented so that the Group controller method runs instead,
# allowing a group plugins to setup template variables.
#def _setup_template_variables(self, context, data_dict, group_type=None):
# pass

def _new_template(self, group_type):
return 'organization/new.html'

def _about_template(self, group_type):
return 'organization/about.html'

def _index_template(self, group_type):
return 'organization/index.html'

def _admins_template(self, group_type):
return 'organization/admins.html'

def _bulk_process_template(self, group_type):
return 'organization/bulk_process.html'

def _read_template(self, group_type):
return 'organization/read.html'

def _history_template(self, group_type):
return group.lookup_group_plugin(group_type).history_template()

def _edit_template(self, group_type):
return 'organization/edit.html'

def _activity_template(self, group_type):
return 'organization/activity_stream.html'

def _guess_group_type(self, expecting_name=False):
return 'organization'

0 comments on commit b95ef59

Please sign in to comment.