diff --git a/ckanext/odsh/collection/plugin.py b/ckanext/odsh/collection/plugin.py index 7ac1d0f4461155075a071ac3a0f6493ae2ab32b3..0c8ccf0add71d68aa6a42eda97df4b4c8ecd8028 100644 --- a/ckanext/odsh/collection/plugin.py +++ b/ckanext/odsh/collection/plugin.py @@ -1,4 +1,4 @@ -from ckan.lib.plugins import DefaultTranslation, DefaultDatasetForm +from ckan.lib.plugins import DefaultDatasetForm import ckan.plugins as plugins import ckan.plugins.toolkit as toolkit from . import helpers as collection_helpers diff --git a/ckanext/odsh/controller.py b/ckanext/odsh/controller.py index 4c37023cd7bd3739e2c36e8beb73a7d567a95d7a..cd31360d9675761baba04c8edbca37a8b88569b3 100644 --- a/ckanext/odsh/controller.py +++ b/ckanext/odsh/controller.py @@ -28,73 +28,6 @@ render = base.render get_action = logic.get_action -class OdshRouteController(HomeController): - def info_page(self): - h.redirect_to('http://www.schleswig-holstein.de/odpinfo') - - def start(self): - h.redirect_to('/dataset') - - def not_found(self): - abort(404) - - -class OdshUserController(UserController): - def index(self): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).index() - - def me(self, locale=None): - if not c.user: - h.redirect_to(locale=locale, controller='user', action='login', - id=None) - user_ref = c.userobj.get_reference_preferred_for_uri() - h.redirect_to(locale=locale, controller='dataset', action='search') - - def dashboard(self, id=None, offset=0): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).dashboard(id, offset) - - def dashboard_datasets(self): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).dashboard_datasets(id) - - def read(self, id=None): - if not c.user: - h.redirect_to(controller='user', action='login') - return super(OdshUserController, self).read(id) - - def follow(self, id): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).follow(id) - - def unfollow(self, id): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).unfollow(id) - - def activity(self, id, offset=0): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).activity(id, offset) - - def register(self, data=None, errors=None, error_summary=None): - if not authz.is_sysadmin(c.user): - abort(404) - return super(OdshUserController, self).register(data, errors, error_summary) - - -class OdshPackageController(PackageController): - def edit_view(self, id, resource_id, view_id=None): - if not authz.is_sysadmin(c.user): - abort(403) - return super(OdshPackageController, self).edit_view(id, resource_id, view_id) - - class OdshGroupController(OrganizationController): def _action(self, name): diff --git a/ckanext/odsh/helpers.py b/ckanext/odsh/helpers.py index 4ef5d8fef1a5e972cc9ed7cd08011036014f2e53..43d6f09b3c7ee1b62fcf1a04d3d08fdc22e6d216 100644 --- a/ckanext/odsh/helpers.py +++ b/ckanext/odsh/helpers.py @@ -309,20 +309,20 @@ def odsh_group_id_selected(selected, group_id): return False -def odsh_remove_route(map, routename): - route = None - for i, r in enumerate(map.matchlist): - - if r.name == routename: - route = r - break - if route is not None: - map.matchlist.remove(route) - for key in map.maxkeys: - if key == route.maxkeys: - map.maxkeys.pop(key) - map._routenames.pop(route.name) - break +# def odsh_remove_route(map, routename): +# route = None +# for i, r in enumerate(map.matchlist): + +# if r.name == routename: +# route = r +# break +# if route is not None: +# map.matchlist.remove(route) +# for key in map.maxkeys: +# if key == route.maxkeys: +# map.maxkeys.pop(key) +# map._routenames.pop(route.name) +# break def is_within_last_month(date, date_ref=None): diff --git a/ckanext/odsh/plugin.py b/ckanext/odsh/plugin.py index 94d7ec5f7a96bd31eb4e8a6d9e2bee1a205c1831..79364d6f03ef0ff0b206c4509301e249d1364e1d 100644 --- a/ckanext/odsh/plugin.py +++ b/ckanext/odsh/plugin.py @@ -27,12 +27,17 @@ import ckanext.odsh.validation as validation import ckanext.odsh.search as search from ckanext.odsh.odsh_logger import OdshLogger import ckanext.odsh.tools as tools - +from ckanext.odsh.views import default +from ckanext.odsh.views import package +from ckanext.odsh.views import user +from ckanext.odsh.views import dashboard +from ckanext.dcat import blueprints as dcat_view log = logging.getLogger(__name__) _ = toolkit._ + class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm): plugins.implements(plugins.IActions) plugins.implements(plugins.IConfigurer) @@ -44,17 +49,62 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm plugins.implements(plugins.ITranslation) plugins.implements(plugins.IValidators) plugins.implements(plugins.IResourceController, inherit=True) + plugins.implements(plugins.IBlueprint) + + # IBlueprint + def get_blueprint(self): + log.info("OdshPlugin::get_blueprint") + + # Default + bp_default = default.blueprint + rules = [ + ('/info_page', 'info_page', default.info_page), + ('/home', 'start', default.start), + ('/not_found', 'not_found', default.not_found), ] + for rule in rules: + bp_default.add_url_rule(*rule) + + # DCAT + # if toolkit.asbool(toolkit.config.get('ckanext.dcat.enable_rdf_endpoints', True)): + # odsh_helpers.odsh_remove_route(map, 'dcat_catalog') + # bp_default.add_url_rule('/catalog.<any("xml", "rdf", "n3", "ttl", "jsonld"):_format>', view_func=dcat_view.read_catalog, defaults={'_format': 'xml'}, methods=['GET']) + + # Package + bp_package = package.blueprint + rules = [ + ('/dataset/<id>/resource/<resource_id>', 'redirect_dataset_resource', package.redirect_dataset_resource), ] + for rule in rules: + bp_package.add_url_rule(*rule) + + # User + bp_user = user.blueprint + bp_user.add_url_rule(u'/user', endpoint='user_index', + view_func=user.index, strict_slashes=False) + bp_user.add_url_rule(u'/user/register', view_func=user.register) + bp_user.add_url_rule(u'/user/activity/<id>', view_func=user.activity) + bp_user.add_url_rule(u'/user/activity/<id>/<int:offset>', view_func=user.activity) + + # Dashboard + bp_dashboard = dashboard.blueprint + bp_dashboard.add_url_rule( + u'/dashboard', view_func=dashboard.dashboard, strict_slashes=False, defaults={ + u'offset': 0 + }) + bp_dashboard.add_url_rule( + u'/dashboard/<int:offset>', view_func=dashboard.dashboard) + bp_dashboard.add_url_rule( + u'/dashboard/datasets', view_func=dashboard.dashboard_datasets) + + return [bp_default, bp_package, bp_user, bp_dashboard] - # IActions def get_actions(self): return {'package_create': action.odsh_package_create, - 'user_update':action.tpsh_user_update, + 'user_update': action.tpsh_user_update, 'user_create': action.odsh_user_create, - 'resource_create': action.odsh_resource_create,} + 'resource_create': action.odsh_resource_create, } - # IConfigurer def update_config(self, config_): @@ -62,7 +112,6 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm toolkit.add_public_directory(config_, 'public') toolkit.add_resource('fanstatic', 'ckanext-odsh') - # IDatasetForm def package_types(self): @@ -74,7 +123,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm # Return True to register this plugin as the default handler for # package types not handled by any other IDatasetForm plugin. return True - + def create_package_schema(self): schema = super(OdshPlugin, self).create_package_schema() self._update_schema(schema) @@ -95,14 +144,14 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm def _update_schema(self, schema): for field in ['title', 'license_id']: schema.update({field: [toolkit.get_converter('not_empty')]}) - + schema.update({ 'reference': [ toolkit.get_validator('ignore_missing'), toolkit.get_converter('convert_to_extras') ] }) - + for i, item in enumerate(schema['tags']['name']): if item == toolkit.get_validator('tag_name_validator'): schema['tags']['name'][i] = toolkit.get_validator( @@ -145,7 +194,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm ] }) return schema - + def _tpsh_update_show_package_schema(self, schema): schema.update({ 'language': [ @@ -167,15 +216,14 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm }) return schema - # IFacets - + def dataset_facets(self, facets_dict, package_type): return OrderedDict({'organization': _('Organizations'), 'groups': _('Category'), 'res_format': _('File format'), 'license_title': _('License'), -# 'tags': _('Tags'), + # 'tags': _('Tags'), 'openness': _('Open-Data-Eigenschaften') }) @@ -190,7 +238,6 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm 'res_format': _('File format'), 'license_title': _('License'), 'groups': _('Category')}) - # IPackageController @@ -205,7 +252,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm helpers_tpsh.get_pkg_relationships_from_model(pkg_dict) ) self._update_is_new_in_pkg_dict(pkg_dict) - + return pkg_dict def before_view(self, pkg_dict): @@ -215,7 +262,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm ''' self._update_is_new_in_pkg_dict(pkg_dict) return pkg_dict - + def after_create(self, context, resource): if resource.get('package_id'): tools.add_attributes_resources(context, resource) @@ -229,7 +276,6 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm is_new = HelperPgkDict(pkg_dict).is_package_new() pkg_dict.update({'is_new': is_new}) - def before_index(self, dict_pkg): # make special date fields solr conform fields = ["issued", "temporal_start", "temporal_end"] @@ -243,32 +289,17 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm self.map_qa_score(dict_pkg) return dict_pkg - # IRoutes - - def before_map(self, map): - map.connect( - 'info_page', - '/info_page', - controller='ckanext.odsh.controller:OdshRouteController', - action='info_page' - ) - map.connect( - 'home', - '/', - controller='ckanext.odsh.controller:OdshRouteController', - action='start' - ) map.redirect('/dataset/{id}/resource/{resource_id}', '/dataset/{id}') # /api ver 3 GET_POST = dict(method=['GET', 'POST']) with SubMapper( - map, - controller='ckanext.odsh.controller:OdshApiController', - path_prefix='/api{ver:/3|}', + map, + controller='ckanext.odsh.controller:OdshApiController', + path_prefix='/api{ver:/3|}', ver='/3' ) as m: m.connect('/action/{logic_function}', @@ -277,55 +308,49 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm with SubMapper(map, controller='ckanext.odsh.controller:OdshFeedController') as m: m.connect('/feeds/custom.atom', action='custom') - with SubMapper(map, controller='ckanext.odsh.controller:OdshPackageController') as m: - m.connect('new_view', '/dataset/{id}/resource/{resource_id}/new_view', - action='edit_view', ckan_icon='pencil-square-o') - with SubMapper(map, controller='ckanext.odsh.controller:OdshGroupController') as m: m.connect('organizations_index', '/organization', action='index') # redirect all user routes to custom controller - with SubMapper(map, controller='ckanext.odsh.controller:OdshUserController') as m: - m.connect('user_index', '/user', action='index') - m.connect('/user/edit', action='edit') - 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('/user/reset', action='request_reset') - m.connect('register', '/user/register', action='register') - m.connect('login', '/user/login', action='login') - m.connect('/user/_logout', action='logout') - m.connect('/user/logged_in', action='logged_in') - m.connect('/user/logged_out', action='logged_out') - m.connect('/user/logged_out_redirect', action='logged_out_page') - m.connect('user_datasets', '/user/{id:(?!(generate_key|activity)).*}', action='read', - ckan_icon='sitemap') + # with SubMapper(map, controller='ckanext.odsh.controller:OdshUserController') as m: + # m.connect('/user/edit', action='edit') + # 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('/user/reset', action='request_reset') + # m.connect('register', '/user/register', action='register') + # m.connect('login', '/user/login', action='login') + # m.connect('/user/_logout', action='logout') + # m.connect('/user/logged_in', action='logged_in') + # m.connect('/user/logged_out', action='logged_out') + # m.connect('/user/logged_out_redirect', action='logged_out_page') + # m.connect('user_datasets', '/user/{id:(?!(generate_key|activity)).*}', action='read', + # ckan_icon='sitemap') map.connect( - 'comment_datarequest', + 'comment_datarequest', '/datarequest/new', controller='ckanext.datarequests.controllers.ui_controller:DataRequestsUI', - action='new', - conditions=dict(method=['GET', 'POST']), + action='new', + conditions=dict(method=['GET', 'POST']), ckan_icon='comment' ) map.connect( - 'comment_datarequest', + 'comment_datarequest', '/datarequest/{id}', controller='ckanext.datarequests.controllers.ui_controller:DataRequestsUI', - action='comment', - conditions=dict(method=['GET', 'POST']), + action='comment', + conditions=dict(method=['GET', 'POST']), ckan_icon='comment' ) return map - + def after_map(self, map): return map - # ITemplateHelpers - + def get_helpers(self): # Template helper function names should begin with the name of the # extension they belong to, to avoid clashing with functions from @@ -371,7 +396,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm # IValidators - + def get_validators(self): return validation.get_validators() @@ -396,4 +421,3 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm score = s if score > 0: dict_pkg['openness'] = OdshPlugin.scores[score-1] - diff --git a/ckanext/odsh/views/dashboard.py b/ckanext/odsh/views/dashboard.py new file mode 100644 index 0000000000000000000000000000000000000000..78fe3b1b16f872df0994f18c9f6b76c0669a2ca2 --- /dev/null +++ b/ckanext/odsh/views/dashboard.py @@ -0,0 +1,31 @@ +import ckan.plugins.toolkit as toolkit +import ckan.authz as authz +import ckan.logic as logic +from ckan.common import g +from flask import Blueprint +from ckan.views.dashboard import index +import logging + +log = logging.getLogger(__name__) + +blueprint = Blueprint('odsh_dashboard', __name__) + + +def dashboard(offset=0): + log.info("views.dashboard::dashboard") + is_sysadmin = authz.is_sysadmin(g.user) + + if not is_sysadmin: + toolkit.abort(403) + + return index(offset) + + +def dashboard_datasets(): + log.info("views.dashboard::dashboard_datasets") + is_sysadmin = authz.is_sysadmin(g.user) + + if not is_sysadmin: + toolkit.abort(403) + + return index() diff --git a/ckanext/odsh/views/default.py b/ckanext/odsh/views/default.py new file mode 100644 index 0000000000000000000000000000000000000000..0058076e06e1e84903ca2320491edf6e53107ea7 --- /dev/null +++ b/ckanext/odsh/views/default.py @@ -0,0 +1,19 @@ +import ckan.plugins.toolkit as toolkit +from flask import Blueprint +import logging + +log = logging.getLogger(__name__) + +blueprint = Blueprint('odsh_default', __name__) + +def info_page(): + log.info("views.default::info_page") + return toolkit.redirect_to('http://www.schleswig-holstein.de/odpinfo') + +def start(): + log.info("views.default::start") + return toolkit.redirect_to('/dataset') + +def not_found(): + log.info("views.default::not_found") + toolkit.abort(404) diff --git a/ckanext/odsh/views/package.py b/ckanext/odsh/views/package.py new file mode 100644 index 0000000000000000000000000000000000000000..64199f6389a849657b4ec7a0d01a2a42ef5859bc --- /dev/null +++ b/ckanext/odsh/views/package.py @@ -0,0 +1,13 @@ +import ckan.plugins.toolkit as toolkit +import ckan.authz as authz + +from flask import Blueprint +import logging + +log = logging.getLogger(__name__) + +blueprint = Blueprint('odsh_package', __name__) + +def redirect_dataset_resource(id, resource_id): + log.info("views.package::redirect_dataset_resource") + return toolkit.redirect_to('/dataset/{}'.format(id)) diff --git a/ckanext/odsh/views/user.py b/ckanext/odsh/views/user.py new file mode 100644 index 0000000000000000000000000000000000000000..ad03408aa2b1a54a5cf23384004b625e4c4c838a --- /dev/null +++ b/ckanext/odsh/views/user.py @@ -0,0 +1,45 @@ +import ckan.plugins.toolkit as toolkit +import ckan.authz as authz +import ckan.logic as logic +from ckan.common import g +from flask import Blueprint +import ckan.views.user as ckan_user_view +import logging + +log = logging.getLogger(__name__) + +blueprint = Blueprint('odsh_user', __name__) + + +def index(): + log.info("views.user::index") + is_sysadmin = authz.is_sysadmin(g.user) + + if not is_sysadmin: + toolkit.abort(403) + return ckan_user_view.index() + + +def register(): + log.info("views.user::register") + is_sysadmin = authz.is_sysadmin(g.user) + + if not is_sysadmin: + toolkit.abort(403) + return ckan_user_view.RegisterView.as_view(str(u'register')) + + +def read(id=None): + log.info("views.user::read") + if not g.user: + return ckan_user_view.login() + return ckan_user_view.read(id) + + +def activity(id, offset=0): + log.info("views.user::activity") + is_sysadmin = authz.is_sysadmin(g.user) + + if not is_sysadmin: + toolkit.abort(403) + return ckan_user_view.activity(id, offset) diff --git a/setup.py b/setup.py index 4c717d157017d59b2cfb090ff2e9ad384244e5e5..260ce13ac5080cf9c11ac36d8595e26bf5b1dfa0 100755 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ setup( # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.8.10', ], @@ -89,6 +89,7 @@ setup( odsh_dcat_harvest=ckanext.odsh.plugin_odsh_dcat_harvest:OdshDCATHarvestPlugin odsh_collections=ckanext.odsh.collection.plugin:CollectionsPlugin thumbnail=ckanext.odsh.pdf_to_thumbnail.plugin:ThumbnailPlugin + [paste.paster_command] odsh_initialization = ckanext.odsh.commands.initialization:Initialization