示例#1
0
    def _add_or_reply(self, dataset_name):
        """
        Allows the user to add a comment to an existing dataset
        """
        context = {'model': model, 'user': c.user}

        # Auth check to make sure the user can see this package
        ctx = context
        ctx['id'] = dataset_name
        check_access('package_show', ctx)

        try:
            c.pkg_dict = get_action('package_show')(context, {
                'id': dataset_name
            })
            c.pkg = context['package']
        except:
            abort(403)

        errors = {}

        if request.method == 'POST':
            data_dict = clean_dict(
                unflatten(tuplize_dict(parse_params(request.POST))))
            data_dict['parent_id'] = c.parent.id if c.parent else None
            data_dict['url'] = '/dataset/%s' % c.pkg.name

            success = False
            try:
                res = get_action('comment_create')(context, data_dict)
                success = True
            except ValidationError, ve:
                errors = ve.error_dict
            except Exception, e:
                abort(403)
示例#2
0
    def delete(self, id):
        """Provide a delete action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        pkg_dict = get_action('package_show')(context, {
            'id': id
        })  # has side-effect of populating context.get('package')

        if request.params:  # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id': id})
                    h.flash_success(_('Successfully deleted package.'))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500,
                          _(u'Unable to update search index.') + repr(e.args))
示例#3
0
def enqueue_document(user, filename, publisher):
    """
    Uses the provided data to send a job to the priority celery queue so that
    the spreadsheet is processed. We should create a job_started message header_row
    to ensure that the user sees immediately that something is happening.
    """
    from pylons import config
    from ckan import model
    from ckan.model.types import make_uuid
    from ckan.lib.celery_app import celery

    site_user = get_action('get_site_user')({
        'model': model,
        'ignore_auth': True,
        'defer_commit': True
    }, {})

    task_id = make_uuid()

    # Create the task for the queue
    context = json.dumps({
        'username':
        user.name,
        'site_url':
        config.get('ckan.site_url_internally') or config.get('ckan.site_url'),
        'apikey':
        user.apikey,
        'site_user_apikey':
        site_user['apikey']
    })
    data = json.dumps({
        'file': filename,
        'publisher': publisher.name,
        'publisher_id': publisher.id,
        'jobid': task_id
    })
    celery.send_task("inventory.process",
                     args=[context, data],
                     task_id=task_id,
                     queue='priority')

    # Create a task status.... and update it so that the user knows it has been started.
    inventory_task_status = {
        'entity_id': task_id,
        'entity_type': u'inventory',
        'task_type': u'inventory',
        'key': u'celery_task_id',
        'value': task_id,
        'error': u'',
        'state': 'Started',
        'last_updated': datetime.datetime.now().isoformat()
    }
    inventory_task_context = {
        'model': model,
        'user': user.name,
        'ignore_auth': True
    }
    res = get_action('task_status_update')(inventory_task_context,
                                           inventory_task_status)
    return res['id'], inventory_task_status['last_updated']
示例#4
0
    def add_field__openness(cls, pkg_dict):
        '''Add the openness score (stars) to the search index'''
        import ckan
        from ckanext.dgu.plugins_toolkit import get_action
        context = {'model': ckan.model, 'session': ckan.model.Session,
                   'ignore_auth': True}
        data_dict = {'id': pkg_dict['id']}
        try:
            qa_openness = get_action('qa_package_openness_show')(context, data_dict)
        except ObjectNotFound:
            log.warning('No QA info for package %s', pkg_dict['name'])
            return
        except KeyError:
            # occurs during tests or if you've not install ckanext-qa
            log.warning('QA not installed - not indexing it.')
            return
        pkg_dict['openness_score'] = qa_openness.get('openness_score')
        log.debug('Openness score %s: %s', pkg_dict['openness_score'], pkg_dict['name'])

        try:
            qa_broken = get_action('qa_package_broken_show')(context, data_dict)
        except ObjectNotFound:
            log.warning('No brokenness info for package %s', pkg_dict['name'])
            return
        if not hasattr(cls, 'broken_links_map'):
            cls.broken_links_map = {
                    True: 'Broken',
                    'some': 'Partially broken',
                    False: 'OK',
                    None: 'TBC'
                    }
        pkg_dict['broken_links'] = cls.broken_links_map[qa_broken.get('archival_is_broken')]
        log.debug('Broken links %s: %s', pkg_dict['broken_links'], pkg_dict['name'])
示例#5
0
    def edit_item(self, id, data=None, errors=None, error_summary=None):
        """
        Allows for the editing of a single item
        """
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'extras_as_string': True,
                   'save': 'save' in request.params}

        if context['save'] and not data:
            return self._save_edit(id, context)

        try:
            c.pkg_dict = get_action('package_show')(context, {'id': id})
            context['for_edit'] = True

            old_data = get_action('package_show')(context, {'id': id})
            # old data is from the database and data is passed from the
            # user if there is a validation error. Use users data if there.
            data = data or old_data
        except NotAuthorized:
            abort(401, _('Unauthorized to read package %s') % '')
        except ObjectNotFound:
            abort(404, _('Dataset not found'))

        c.pkg = context.get("package")

        try:
            check_access('package_update',context)
        except NotAuthorized, e:
            abort(401, _('User %r not authorized to edit %s') % (c.user, id))
示例#6
0
    def delete(self, id):
        """Provide a delete action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package')

        if request.params: # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id':id})
                    h.flash_success(_('Successfully deleted package.'))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500, _(u'Unable to update search index.') + repr(e.args))
示例#7
0
    def index(self):
        c.q = request.params.get('q', '')

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True
        }

        # This is the one difference from ckan core.
        # No need for all vocab / translation stuff, so save the massive
        # effort of dictizing every tag. This improves page load from
        # 60s to 10s.
        data_dict = {'all_fields': False}

        if c.q:
            try:
                page = int(request.params.get('page', 1))
            except ValueError:
                abort(404, _('Not found'))
            data_dict['q'] = c.q
            data_dict['limit'] = LIMIT
            data_dict['offset'] = (page - 1) * LIMIT
            data_dict['return_objects'] = True

            result_dict = get_action('tag_search')(context, data_dict)

            def pager_url(q=None, page=None):
                return h.url_for(
                    controller='ckanext.dgu.controllers.tag:TagController',
                    action='index',
                    q=request.params['q'],
                    page=page)

            c.page = h.Page(
                collection=result_dict['results'],
                page=page,
                item_count=result_dict['count'],
                items_per_page=LIMIT,
                url=pager_url,
            )
            c.page.items = [
                tag_dict['name'] for tag_dict in result_dict['results']
            ]
        else:
            results = get_action('tag_list')(context, data_dict)

            c.page = AlphaPageLarge(
                collection=results,
                page=request.params.get('page', 'A'),
                alpha_attribute='name',
                other_text=_('Other'),
                controller_name='ckanext.dgu.controllers.tag:TagController',
            )

        return render('tag/index.html')
示例#8
0
    def index(self):
        c.q = request.params.get("q", "")

        context = {"model": model, "session": model.Session, "user": c.user or c.author, "for_view": True}

        # This is the one difference from ckan core.
        # No need for all vocab / translation stuff, so save the massive
        # effort of dictizing every tag. This improves page load from
        # 60s to 10s.
        data_dict = {"all_fields": False}

        if c.q:
            try:
                page = int(request.params.get("page", 1))
            except ValueError:
                abort(404, _("Not found"))
            data_dict["q"] = c.q
            data_dict["limit"] = LIMIT
            data_dict["offset"] = (page - 1) * LIMIT
            data_dict["return_objects"] = True

            result_dict = get_action("tag_search")(context, data_dict)

            def pager_url(q=None, page=None):
                return h.url_for(
                    controller="ckanext.dgu.controllers.tag:TagController",
                    action="index",
                    q=request.params["q"],
                    page=page,
                )

            c.page = h.Page(
                collection=result_dict["results"],
                page=page,
                item_count=result_dict["count"],
                items_per_page=LIMIT,
                url=pager_url,
            )
            c.page.items = [tag_dict["name"] for tag_dict in result_dict["results"]]
        else:
            results = get_action("tag_list")(context, data_dict)

            c.page = AlphaPageLarge(
                collection=results,
                page=request.params.get("page", "A"),
                alpha_attribute="name",
                other_text=_("Other"),
                controller_name="ckanext.dgu.controllers.tag:TagController",
            )

        return render("tag/index.html")
示例#9
0
def enqueue_document(user, filename, publisher):
    """
    Uses the provided data to send a job to the priority celery queue so that
    the spreadsheet is processed. We should create a job_started message header_row
    to ensure that the user sees immediately that something is happening.
    """
    from pylons import config
    from ckan import model
    from ckan.model.types import make_uuid
    from ckan.lib.celery_app import celery

    site_user = get_action('get_site_user')(
        {'model': model, 'ignore_auth': True, 'defer_commit': True}, {})

    task_id = make_uuid()

    # Create the task for the queue
    context = json.dumps({
        'username': user.name,
        'site_url': config.get('ckan.site_url_internally') or config.get('ckan.site_url'),
        'apikey': user.apikey,
        'site_user_apikey': site_user['apikey']
    })
    data = json.dumps({
        'file': filename,
        'publisher': publisher.name,
        'publisher_id': publisher.id,
        'jobid': task_id
    })
    celery.send_task("inventory.process", args=[context, data], task_id=task_id, queue='priority')

    # Create a task status.... and update it so that the user knows it has been started.
    inventory_task_status = {
        'entity_id': task_id,
        'entity_type': u'inventory',
        'task_type': u'inventory',
        'key': u'celery_task_id',
        'value': task_id,
        'error': u'',
        'state': 'Started',
        'last_updated': datetime.datetime.now().isoformat()
    }
    inventory_task_context = {
        'model': model,
        'user': user.name,
        'ignore_auth': True
    }
    res = get_action('task_status_update')(inventory_task_context, inventory_task_status)
    return res['id'], inventory_task_status['last_updated']
示例#10
0
    def latest_datasets(self, published_only=True):
        """Designed for the dgu home page, shows lists the latest datasets
        that got changed (exluding extra, group and tag changes) with lots
        of details about each dataset.
        """
        try:
            limit = int(request.params.get("limit", default_limit))
        except ValueError:
            limit = default_limit

        limit = min(100, limit)  # max value

        from ckan.lib.search import SearchError

        fq = 'capacity:"public"'
        if published_only:
            fq = fq + " unpublished:false"

        try:
            # package search
            context = {"model": model, "session": model.Session, "user": "******"}
            data_dict = {
                "q": "",
                "fq": fq,
                "facet": "false",
                "start": 0,
                "rows": limit,
                "sort": "metadata_modified desc",
            }
            query = get_action("package_search")(context, data_dict)
        except SearchError, se:
            log.error("Search error: %s", se)
示例#11
0
    def setup(self):
        """
        Creates a harvested UKLP dataset.
        """
        _drop_sysadmin()
        self.admin = _create_sysadmin()

        CreateTestData.create_test_user()
        self.tester = "tester"

        CreateTestData.create_groups(_EXAMPLE_GROUPS, admin_user_name=self.tester, auth_profile="publisher")
        CreateTestData.flag_for_deletion(group_names=[g["name"] for g in _EXAMPLE_GROUPS])

        context = {
            "model": ckan.model,
            "session": ckan.model.Session,
            "user": self.admin,
            "api_version": 2,
            "schema": ckan.logic.schema.default_package_schema(),
        }
        package_dict = _UKLP_DATASET.copy()

        self.uklp_dataset = get_action("package_create_rest")(context, package_dict)

        CreateTestData.flag_for_deletion(pkg_names=[self.uklp_dataset["name"]])
示例#12
0
    def home(self):
        extra_vars = {}

        # Get the dataset count using search
        # (shouldn't cache, as it makes it more likely to be out of sync with
        # the data page)
        from ckan.lib.search import SearchError, SearchQueryError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True,
            'auth_user_obj': c.userobj
        }
        data_dict = {
            'q': '*:*',
            'fq': '+dataset_type:dataset',
            #'facet.field': facets.keys(),
            'rows': 0,
        }
        query = get_action('package_search')(context, data_dict)
        extra_vars['num_datasets'] = query['count']

        extra_vars['themes'] = get_themes()

        return render('data/home.html', extra_vars=extra_vars)
示例#13
0
    def index(self):
        from ckan.lib.search import SearchError
        try:
            # package search
            context = {'model': model, 'session': model.Session,
                       'user': c.user or c.author}
            fq = 'capacity:"public"'
            data_dict = {
                'q':'',
                'fq':fq,
                'facet.field':g.facets,
                'rows':0,
                'start':0,
            }
            query = get_action('package_search')(context,data_dict)
            c.package_count = query['count']
            c.facets = query['facets']
            c.search_facets = query['search_facets']

            # group search
            #data_dict = {'order_by': 'packages', 'all_fields': 1}
            #c.groups = get_action('group_list')(context, data_dict)
        except SearchError, se:
            log.error('Search error: %s', se)
            c.package_count = 0
            c.groups = []
示例#14
0
 def _search(self,
             theme='',
             q='',
             rows=5,
             sort_string='last_major_modification desc'):
     """
     Helper for retrieving just a handful of popular/recent datasets for the 
     current theme. 
     """
     raise NotImplementedError('Cannot view theme pages yet.')
     from ckan.lib.search import SearchError
     packages = []
     try:
         # package search
         context = {
             'model': model,
             'session': model.Session,
             'user': '******'
         }
         data_dict = {
             'q': q,
             'fq': 'theme-primary:"%s"' % theme,
             'facet': 'true',
             'rows': rows,
             'start': 0,
             'sort': sort_string,
         }
         query = get_action('package_search')(context, data_dict)
         packages = query['results']
     except SearchError, se:
         log.error('Search error: %s', se)
示例#15
0
    def latest_datasets(self, published_only=True):
        '''Designed for the dgu home page, shows lists the latest datasets
        that got changed (exluding extra, group and tag changes) with lots
        of details about each dataset.
        '''
        try:
            limit = int(request.params.get('limit', default_limit))
        except ValueError:
            limit = default_limit

        limit = min(100, limit) # max value

        from ckan.lib.search import SearchError
        fq = 'capacity:"public"'
        if published_only:
             fq = fq + ' unpublished:false'

        try:
            # package search
            context = {'model': model, 'session': model.Session,
                       'user': '******'}
            data_dict = {
                'q':'',
                'fq': fq,
                'facet':'false',
                'start':0,
                'rows': limit,
                'sort': 'last_major_modification desc'
            }
            query = get_action('package_search')(context,data_dict)
        except SearchError, se:
            log.error('Search error: %s', se)
            count = 0
示例#16
0
    def commitments(self, id):
        """
        Shows all of the commitments for the specified publisher
        """
        from ckanext.dgu.model.commitment import Commitment

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'extras_as_string': True,
            'save': 'save' in request.params
        }

        try:
            c.publisher_dict = get_action('organization_show')(context, {
                'id': id
            })
        except NotAuthorized:
            abort(401, _('Unauthorized to read commitments'))
        except ObjectNotFound:
            abort(404, _('Publisher not found'))

        c.publisher = context.get('group')
        c.commitments = Commitment.get_for_publisher(c.publisher.name)\
            .order_by('commitment.dataset_name').all()

        return render('commitment/read.html')
示例#17
0
    def edit(self, id):
        """
        The edit homepage to allow department admins to download and
        upload their inventories
        """

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True
        }

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Organisation not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(
                401, 'User %r not authorized to view internal unpublished' %
                (c.user))
示例#18
0
    def add_field__harvest_document(cls, pkg_dict):
        '''Index a harvested dataset\'s XML content
           (Given a low priority when searching)'''
        if pkg_dict.get('UKLP', '') == 'True':
            import ckan
            from ckanext.dgu.plugins_toolkit import get_action

            context = {
                'model': ckan.model,
                'session': ckan.model.Session,
                'ignore_auth': True
            }

            data_dict = {'id': pkg_dict.get('harvest_object_id', '')}

            try:
                harvest_object = get_action('harvest_object_show')(context,
                                                                   data_dict)
                pkg_dict[
                    'extras_harvest_document_content'] = harvest_object.get(
                        'content', '')
            except ObjectNotFound:
                log.warning(
                    'Unable to find harvest object "%s" '
                    'referenced by dataset "%s"', data_dict['id'],
                    pkg_dict['id'])
示例#19
0
    def index(self):
        from ckan.lib.search import SearchError
        try:
            # package search
            context = {
                'model': model,
                'session': model.Session,
                'user': c.user or c.author
            }
            fq = 'capacity:"public"'
            data_dict = {
                'q': '',
                'fq': fq,
                'facet.field': g.facets,
                'rows': 0,
                'start': 0,
            }
            query = get_action('package_search')(context, data_dict)
            c.package_count = query['count']
            c.facets = query['facets']
            c.search_facets = query['search_facets']

            # group search
            #data_dict = {'order_by': 'packages', 'all_fields': 1}
            #c.groups = get_action('group_list')(context, data_dict)
        except SearchError, se:
            log.error('Search error: %s', se)
            c.package_count = 0
            c.groups = []
示例#20
0
    def download(self, id):
        """
        Downloads all of the current datasets for a given publisher as a read-only
        CSV file.
        """
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True,
            'group': id
        }

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Organization not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read Organization %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(401,
                  'User %r not authorized to download unpublished ' % (c.user))
示例#21
0
    def upload(self, id):
        """
        Upload of an unpublished file, accepts a POST request with a file and
        then renders the result of the import to the user.
        """
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True
        }

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Organization not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to upload inventory' % (c.user))
示例#22
0
    def latest_datasets(self, published_only=True):
        '''Designed for the dgu home page, shows lists the latest datasets
        that got changed (exluding extra, group and tag changes) with lots
        of details about each dataset.
        '''
        try:
            limit = int(request.params.get('limit', default_limit))
        except ValueError:
            limit = default_limit

        limit = min(100, limit) # max value

        from ckan.lib.search import SearchError
        fq = 'capacity:"public"'
        if published_only:
             fq = fq + ' unpublished:false'

        try:
            # package search
            context = {'model': model, 'session': model.Session,
                       'user': '******'}
            data_dict = {
                'q':'',
                'fq': fq,
                'facet':'false',
                'start':0,
                'rows': limit,
                'sort': 'metadata_modified desc'
            }
            query = get_action('package_search')(context,data_dict)
        except SearchError, se:
            log.error('Search error: %s', se)
示例#23
0
    def setup(self):
        """
        Creates a harvested UKLP dataset.
        """
        _drop_sysadmin()
        self.admin = _create_sysadmin()

        CreateTestData.create_test_user()
        self.tester = 'tester'

        CreateTestData.create_groups(_EXAMPLE_GROUPS, admin_user_name=self.tester, auth_profile='publisher')
        CreateTestData.flag_for_deletion(group_names=[g['name'] for g in _EXAMPLE_GROUPS])

        context = {
            'model': ckan.model,
            'session': ckan.model.Session,
            'user': self.admin,
            'api_version': 2,
            'schema': ckan.logic.schema.default_package_schema(),
        }
        package_dict = _UKLP_DATASET.copy()

        self.uklp_dataset = get_action('package_create_rest')(context, package_dict)

        CreateTestData.flag_for_deletion(pkg_names=[self.uklp_dataset['name']])
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        try:
            pkg_dict = get_action('package_show')(context, {
                'id': id
            })  # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, 'Not authorized to delete package')
        except ObjectNotFound:
            abort(404, 'Dataset not found')

        if request.params:  # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id': id})
                    is_uklp = get_from_flat_dict(pkg_dict['extras'],
                                                 'UKLP') == 'True'
                    if is_uklp:
                        action = 'withdrawn'
                        resource_type = get_from_flat_dict(
                            pkg_dict['extras'], 'resource-type') + ' record'
                    else:
                        action = 'deleted'
                        resource_type = 'dataset'
                    h.flash_success('Successfully %s %s.' \
                                    % (action, resource_type))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500,
                          _(u'Unable to update search index.') + repr(e.args))
示例#25
0
    def moderation(self):
        context = {'model': model, 'user': c.user}
        check_access('moderation_queue_show', context)

        try:
            res = get_action('moderation_queue_show')(context, {})
        except Exception, e:
            abort(403)
示例#26
0
    def flag(self, dataset_name, id):
        context = {'model': model, 'user': c.user}

        try:
            c.pkg_dict = get_action('package_show')(context, {
                'id': dataset_name
            })
            c.pkg = context['package']
        except Exception, e:
            abort(403)
示例#27
0
    def test_view_system_user(self):
        # created on the API
        user_dict = get_action('get_site_user')({'model': model, 'ignore_auth': True}, {})
        user = user_dict['name']

        c.is_an_official = False
        assert_equal(str(dgu_linked_user(user)), 'System Process')

        c.is_an_official = True
        assert_equal(str(dgu_linked_user(user, maxlength=100)),
                '<a href="/data/user/test.ckan.net">System Process (Site user)</a>')
示例#28
0
    def test_view_system_user(self):
        # created on the API
        user_dict = get_action('get_site_user')({'model': model, 'ignore_auth': True}, {})
        user = user_dict['name']

        c.is_an_official = False
        assert_equal(str(dgu_linked_user(user)), 'System Process')

        c.is_an_official = True
        assert_equal(str(dgu_linked_user(user, maxlength=100)),
                '<a href="/data/user/test.ckan.net">System Process (Site user)</a>')
示例#29
0
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
        }

        try:
            pkg_dict = get_action('package_show')(context, {'id':id}) # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, 'Not authorized to delete package')
        except ObjectNotFound:
            abort(404, 'Dataset not found')

        if request.params: # POST
            if 'cancel' in request.params:
                h.redirect_to(controller='package', action='read', id=id)
            elif 'delete' in request.params:
                try:
                    package_name = pkg_dict['name']
                    get_action('package_delete')(context, {'id':id})
                    is_uklp = get_from_flat_dict(pkg_dict['extras'], 'UKLP') == 'True'
                    if is_uklp:
                        action = 'withdrawn'
                        resource_type = get_from_flat_dict(pkg_dict['extras'], 'resource-type') + ' record'
                    else:
                        action = 'deleted'
                        resource_type = 'dataset'
                    h.flash_success('Successfully %s %s.' \
                                    % (action, resource_type))
                    self._form_save_redirect(package_name, 'edit')
                except NotAuthorized:
                    abort(401, _('Unauthorized to delete package %s') % id)
                except ObjectNotFound, e:
                    abort(404, _('Package not found'))
                except DataError:
                    abort(400, _(u'Integrity Error'))
                except SearchIndexError, e:
                    abort(500, _(u'Unable to update search index.') + repr(e.args))
示例#30
0
    def add_field__openness(cls, pkg_dict):
        '''Add the openness score (stars) to the search index'''
        import ckan
        from ckanext.dgu.plugins_toolkit import get_action
        context = {
            'model': ckan.model,
            'session': ckan.model.Session,
            'ignore_auth': True
        }
        data_dict = {'id': pkg_dict['id']}
        try:
            qa_openness = get_action('qa_package_openness_show')(context,
                                                                 data_dict)
        except ObjectNotFound:
            log.warning('No QA info for package %s', pkg_dict['name'])
            return
        except KeyError:
            # occurs during tests or if you've not install ckanext-qa
            log.warning('QA not installed - not indexing it.')
            return
        pkg_dict['openness_score'] = qa_openness.get('openness_score')
        log.debug('Openness score %s: %s', pkg_dict['openness_score'],
                  pkg_dict['name'])

        try:
            qa_broken = get_action('qa_package_broken_show')(context,
                                                             data_dict)
        except ObjectNotFound:
            log.warning('No brokenness info for package %s', pkg_dict['name'])
            return
        if not hasattr(cls, 'broken_links_map'):
            cls.broken_links_map = {
                True: 'Broken',
                'some': 'Partially broken',
                False: 'OK',
                None: 'TBC'
            }
        pkg_dict['broken_links'] = cls.broken_links_map[qa_broken.get(
            'archival_is_broken')]
        log.debug('Broken links %s: %s', pkg_dict['broken_links'],
                  pkg_dict['name'])
示例#31
0
    def all_packages(self):

        ctx = {'model': model, 'session': model.Session}
        package_list = get_action("package_list")(ctx, {})

        def linkify_packages(pkgs):
            x = 0
            for pkg in pkgs:
                yield '<a href="/dataset/{p}">{p}</a><br/>'.format(p=pkg)

        c.datasets = linkify_packages(package_list)
        return render("package/all_datasets.html")
示例#32
0
    def all_packages(self):

        ctx = {'model': model, 'session': model.Session}
        package_list = get_action("package_list")(ctx, {})

        def linkify_packages(pkgs):
            x = 0
            for pkg in pkgs:
                yield '<a href="/dataset/{p}">{p}</a><br/>'.format(p=pkg)

        c.datasets = linkify_packages(package_list)
        return render("package/all_datasets.html")
示例#33
0
    def test_view_system_user(self):
        # created on the API
        user_dict = get_action("get_site_user")({"model": model, "ignore_auth": True}, {})
        user = user_dict["name"]

        c.is_an_official = False
        assert_equal(str(dgu_linked_user(user)), "System Process")

        c.is_an_official = True
        assert_equal(
            str(dgu_linked_user(user, maxlength=100)),
            '<a href="/data/user/test.ckan.net">System Process (Site user)</a>',
        )
示例#34
0
    def dataset_count(self):
        from ckan.lib.search import SearchError

        try:
            # package search
            context = {"model": model, "session": model.Session, "user": "******"}
            fq = 'capacity:"public" unpublished:false'
            data_dict = {"q": "", "fq": fq, "facet": "false", "rows": 0, "start": 0}
            query = get_action("package_search")(context, data_dict)
            count = query["count"]
        except SearchError, se:
            log.error("Search error: %s", se)
            count = 0
示例#35
0
    def reply(self, dataset_name, parent_id):
        c.action = 'reply'

        try:
            data = {'id': parent_id}
            c.parent_dict = get_action("comment_show")({
                'model': model,
                'user': c.user
            }, data)
            c.parent = data['comment']
        except:
            abort(404)

        return self._add_or_reply(dataset_name)
示例#36
0
def get_themes():
    '''
    Get the themes from ckanext-taxonomy
    '''
    context = {'model': model}
    try:
        log.debug('Refreshing home page themes')
        terms = get_action('taxonomy_term_list')(
            context, {'name': 'dgu-themes'})
    except sqlalchemy.exc.OperationalError, e:
        if 'no such table: taxonomy' in str(e):
            model.Session.remove()  # clear the erroring transaction
            raise ImportError('ckanext-taxonomy tables not setup')
        raise
示例#37
0
    def delete(self, id):
        """Provide a delete ('withdraw') action, but only for UKLP datasets"""
        from ckan.lib.search import SearchIndexError

        context = {"model": model, "session": model.Session, "user": c.user}

        try:
            pkg_dict = get_action("package_show")(
                context, {"id": id}
            )  # has side-effect of populating context.get('package')
        except NotAuthorized:
            abort(401, "Not authorized to delete package")

        if request.params:  # POST
            if "cancel" in request.params:
                h.redirect_to(controller="package", action="read", id=id)
            elif "delete" in request.params:
                try:
                    package_name = pkg_dict["name"]
                    get_action("package_delete")(context, {"id": id})
                    is_uklp = get_from_flat_dict(pkg_dict["extras"], "UKLP") == "True"
                    if is_uklp:
                        action = "withdrawn"
                        resource_type = get_from_flat_dict(pkg_dict["extras"], "resource-type") + " record"
                    else:
                        action = "deleted"
                        resource_type = "dataset"
                    h.flash_success("Successfully %s %s." % (action, resource_type))
                    self._form_save_redirect(package_name, "edit")
                except NotAuthorized:
                    abort(401, _("Unauthorized to delete package %s") % id)
                except ObjectNotFound, e:
                    abort(404, _("Package not found"))
                except DataError:
                    abort(400, _(u"Integrity Error"))
                except SearchIndexError, e:
                    abort(500, _(u"Unable to update search index.") + repr(e.args))
示例#38
0
    def _save_edit(self, name_or_id, context):
        try:
            data_dict = clean_dict(
                unflatten(tuplize_dict(parse_params(request.POST))))
            context['message'] = data_dict.get('log_message', '')
            data_dict['id'] = name_or_id

            pkg = get_action('package_update')(context, data_dict)
            c.pkg = context['package']
            c.pkg_dict = pkg
            h.redirect_to(controller='package', action='read', id=pkg['name'])
        except NotAuthorized:
            abort(401, 'Not authorized to save package')
        except ObjectNotFound, e:
            abort(404, _('Dataset not found'))
示例#39
0
    def test_view_system_user(self):
        # created on the API
        user_dict = get_action('get_site_user')({'model': model, 'ignore_auth': True}, {})
        user = user_dict['name']

        with regular_user():
            assert_equal(str(dgu_linked_user(user)), 'System Process')

        with publisher_user():
            assert_equal(str(dgu_linked_user(user, maxlength=100)),
                '<a href="/data/user/test.ckan.net">System Process (Site user)</a>')

        with sysadmin_user():
            assert_equal(str(dgu_linked_user(user, maxlength=100)),
                '<a href="/data/user/test.ckan.net">System Process (Site user)</a>')
示例#40
0
def get_themes():
    '''
    Get the themes from ckanext-taxonomy
    '''
    context = {'model': model}
    try:
        log.debug('Refreshing home page themes')
        terms = get_action('taxonomy_term_list')(context, {
            'name': 'dgu-themes'
        })
    except sqlalchemy.exc.OperationalError, e:
        if 'no such table: taxonomy' in str(e):
            model.Session.remove()  # clear the erroring transaction
            raise ImportError('ckanext-taxonomy tables not setup')
        raise
示例#41
0
    def _save_edit(self, name_or_id, context):
        try:
            data_dict = clean_dict(unflatten(
                tuplize_dict(parse_params(request.POST))))
            context['message'] = data_dict.get('log_message', '')
            data_dict['id'] = name_or_id

            pkg = get_action('package_update')(context, data_dict)
            c.pkg = context['package']
            c.pkg_dict = pkg
            h.redirect_to(controller='package', action='read', id=pkg['name'])
        except NotAuthorized:
            abort(401, 'Not authorized to save package')
        except ObjectNotFound, e:
            abort(404, _('Dataset not found'))
示例#42
0
    def __init__(self):
        self.data = {}
        self.topic_words = {}  # topic:theme_name
        self.topic_bigrams = {} # (topicword1, topicword2):theme_name
        self.topic_trigrams = {} # (topicword1, topicword2, topicword3):theme_name
        self.gemet = {}  # gemet_keyword:theme_name
        self.ons = {}  # ons_keyword:theme_name
        self.la_function = {} # LA functions extra
        self.la_service = {}  # LA services extra
        self.odc = {}  # OpenDataCommunities.org theme extra

        context = {'model': model}
        terms = get_action('taxonomy_term_list')(context, {'name': 'dgu-themes'})
        for term in terms:
            theme_dict = term['extras']
            theme_dict['title'] = name = term['label']
            theme_dict['description'] = term['description']

            for key in ('topics', 'gemet', 'nscl', 'ons', 'la_function', 'la_service',
                        'odc'):
                if key in theme_dict:
                    assert isinstance(theme_dict[key], list), (name, key)

            for topic in theme_dict['topics']:
                words = [normalize_token(word) for word in split_words(topic)]
                if len(words) == 1:
                    self.topic_words[words[0]] = name
                elif len(words) == 2:
                    self.topic_bigrams[tuple(words)] = name
                elif len(words) == 3:
                    self.topic_trigrams[tuple(words)] = name
                else:
                    assert 0, 'Too many words in topic: %s' % topic

            for gemet_keyword in theme_dict.get('gemet', []):
                self.gemet[normalize_keyword(gemet_keyword)] = name
            for ons_keyword in theme_dict.get('nscl', []) + theme_dict.get('ons', []):
                self.ons[tag_munge(ons_keyword)] = name
            for function_id in theme_dict.get('la_functions', []):
                self.la_function[function_id] = name
            for service_id in theme_dict.get('la_service', []):
                self.la_service[service_id] = name
            for keyword in theme_dict.get('odc', []):
                self.odc[keyword] = name
            self.data[name] = theme_dict
        self.topic_words_set = self.topic_words.viewkeys() # can do set-like operations on it
        self.topic_bigrams_set = self.topic_bigrams.viewkeys()
        self.topic_trigrams_set = self.topic_trigrams.viewkeys()
示例#43
0
    def upload_complete(self, id):
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'for_view': True}

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Group not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to upload unpublished' % (c.user))
示例#44
0
    def _get_package(self, id):
        """
        Given an ID use the logic layer to fetch the Package and a
        dict representation of it as well as adding formatted notes
        and the publisher to the template context (c).
        """
        import ckan.misc
        import genshi

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'extras_as_string': True,
            'for_view': True
        }

        try:
            c.pkg_dict = get_action('package_show')(context, {'id': id})
            c.pkg = context['package']
        except ObjectNotFound:
            abort(404, _('Dataset not found'))
        except NotAuthorized:
            abort(401, _('Unauthorized to read package %s') % id)

        groups = c.pkg.get_groups('publisher')
        if groups:
            c.publisher = groups[0]
        else:
            log.warning("Package {0} is not a member of any group!".format(id))

        # Try and render the notes as markdown for display on the page.  Most
        # unpublished items *won't* be markdown if they've come directly from the
        # CSV - unless they've been edited.
        try:
            notes_formatted = ckan.misc.MarkdownFormat().to_html(c.pkg.notes)
            c.pkg_notes_formatted = genshi.HTML(notes_formatted)
            c.release_notes_formatted = None

            notes = unpublished_release_notes(c.pkg_dict)
            if notes and notes.strip():
                c.release_notes_formatted = genshi.HTML(
                    ckan.misc.MarkdownFormat().to_html(notes))
        except Exception:
            c.pkg_notes_formatted = c.pkg.notes
示例#45
0
    def add_field__harvest_document(cls, pkg_dict):
        """Index a harvested dataset\'s XML content
           (Given a low priority when searching)"""
        if pkg_dict.get("UKLP", "") == "True":
            import ckan
            from ckanext.dgu.plugins_toolkit import get_action

            context = {"model": ckan.model, "session": ckan.model.Session, "ignore_auth": True}

            data_dict = {"id": pkg_dict.get("harvest_object_id", "")}

            try:
                harvest_object = get_action("harvest_object_show")(context, data_dict)
                pkg_dict["extras_harvest_document_content"] = harvest_object.get("content", "")
            except ObjectNotFound:
                log.warning(
                    'Unable to find harvest object "%s" ' 'referenced by dataset "%s"', data_dict["id"], pkg_dict["id"]
                )
示例#46
0
    def upload_status(self, id, upload_id):
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'for_view': True}

        try:
            c.group_dict = get_action('group_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            self._redirect_if_previous_name(id)
            abort(404, 'Group not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('group_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to view internal inventory' % (c.user))
示例#47
0
    def upload_status(self, id, upload_id):
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'for_view': True}

        try:
            c.group_dict = get_action('group_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            self._redirect_if_previous_name(id)
            abort(404, 'Group not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('group_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to view internal inventory' % (c.user))
示例#48
0
 def dataset_count(self):
     from ckan.lib.search import SearchError
     try:
         # package search
         context = {'model': model, 'session': model.Session,
                    'user': '******'}
         fq = 'capacity:"public" unpublished:false'
         data_dict = {
             'q':'',
             'fq':fq,
             'facet':'false',
             'rows':0,
             'start':0,
         }
         query = get_action('package_search')(context,data_dict)
         count = query['count']
     except SearchError, se:
         log.error('Search error: %s', se)
         count = 0
示例#49
0
 def dataset_count(self):
     from ckan.lib.search import SearchError
     try:
         # package search
         context = {'model': model, 'session': model.Session,
                    'user': '******'}
         fq = 'capacity:"public" unpublished:false'
         data_dict = {
             'q':'',
             'fq':fq,
             'facet':'false',
             'rows':0,
             'start':0,
         }
         query = get_action('package_search')(context,data_dict)
         count = query['count']
     except SearchError, se:
         log.error('Search error: %s', se)
         count = 0
    def contact(self, name=None):
        """
        This action allows users to create an issue by filling in a contact
        form.
        """
        import ckan.model as model
        from ckanext.redmine.client import RedmineClient

        print name
        extra_vars = {"data": {}, "errors": {}}

        client = RedmineClient(name)
        c.categories = client.load_categories()
        c.name = name

        if request.method == 'POST':
            data = clean_dict(
                unflatten(tuplize_dict(parse_params(request.POST))))
            context = {
                'model': model,
                'session': model.Session,
                'user': c.user
            }

            # Create the issue with the data we were passed.
            try:
                newid = get_action('issue_create')(context, data)
                if newid is None:
                    self._save_on_fail(data)
                    h.flash_success(
                        _('Thank you for contacting us'.format(newid)))
                else:
                    h.flash_success(
                        _('Thank you for contacting us, please quote #{0} in future correspondence'
                          .format(newid)))

                h.redirect_to(str(data.get('referer', '/')))
            except ValidationError, e:
                extra_vars["errors"] = e.error_dict
                extra_vars["error_summary"] = e.error_summary
                extra_vars["data"] = data
                c.category_id = data.get('category', '')
示例#51
0
    def add_field__harvest_document(cls, pkg_dict):
        '''Index a harvested dataset\'s XML content
           (Given a low priority when searching)'''
        if pkg_dict.get('UKLP', '') == 'True':
            import ckan
            from ckanext.dgu.plugins_toolkit import get_action

            context = {'model': ckan.model,
                       'session': ckan.model.Session,
                       'ignore_auth': True}

            data_dict = {'id': pkg_dict.get('harvest_object_id', '')}

            try:
                harvest_object = get_action('harvest_object_show')(context, data_dict)
                pkg_dict['extras_harvest_document_content'] = harvest_object.get('content', '')
            except ObjectNotFound:
                log.warning('Unable to find harvest object "%s" '
                            'referenced by dataset "%s"',
                            data_dict['id'], pkg_dict['id'])
示例#52
0
    def __init__(self):
        self.data = {}
        self.topic_words = {}  # topic:[theme_name]
        self.topic_bigrams = {} # (topicword1, topicword2):[theme_name]
        self.topic_trigrams = {} # (topicword1, topicword2, topicword3):[theme_name]
        self.gemet = {}  # gemet_keyword:theme_name
        self.ons = {}  # ons_keyword:theme_name
        self.la_function = {} # LA functions extra
        self.la_service = {}  # LA services extra
        self.odc = {}  # OpenDataCommunities.org theme extra

        context = {'model': model}
        # Get the themes from ckanext-taxonomy
        try:
            terms = get_action('taxonomy_term_list')(context, {'name': 'dgu-themes'})
        except sqlalchemy.exc.OperationalError, e:
            if 'no such table: taxonomy' in str(e):
                model.Session.remove()  # clear the erroring transaction
                raise ImportError('ckanext-taxonomy tables not setup')
            raise
示例#53
0
    def commitments(self, id):
        """
        Shows all of the commitments for the specified publisher
        """
        from ckanext.dgu.model.commitment import Commitment

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'extras_as_string': True,
                   'save': 'save' in request.params}

        try:
            c.publisher_dict = get_action('organization_show')(context, {'id': id})
        except NotAuthorized:
            abort(401, _('Unauthorized to read commitments'))
        except ObjectNotFound:
            abort(404, _('Publisher not found'))

        c.publisher = context.get('group')
        c.commitments = Commitment.get_for_publisher(c.publisher.name).order_by('commitment.dataset_name').all()

        return render('commitment/read.html')
示例#54
0
    def upload(self, id):
        """
        Upload of an unpublished file, accepts a POST request with a file and
        then renders the result of the import to the user.
        """
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'for_view': True}

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Organization not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read group %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to upload inventory' % (c.user))
示例#55
0
    def _get_package(self, id):
        """
        Given an ID use the logic layer to fetch the Package and a
        dict representation of it as well as adding formatted notes
        and the publisher to the template context (c).
        """
        import genshi

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'extras_as_string': True,
                   'for_view': True}

        try:
            c.pkg_dict = get_action('package_show')(context, {'id': id})
            c.pkg = context['package']
        except ObjectNotFound:
            abort(404, _('Dataset not found'))
        except NotAuthorized:
            abort(401, _('Unauthorized to read package %s') % id)

        groups = c.pkg.get_groups('organization')
        if groups:
            c.publisher = groups[0]
        else:
            log.warning("Package {0} is not a member of any group!".format(id))

        # Try and render the notes as markdown for display on the page.  Most
        # unpublished items *won't* be markdown if they've come directly from the
        # CSV - unless they've been edited.
        try:
            notes_formatted = render_markdown(c.pkg.notes)
            c.pkg_notes_formatted = unicode(genshi.HTML(notes_formatted))
            c.release_notes_formatted = None

            notes = unpublished_release_notes(c.pkg_dict)
            if notes and notes.strip():
                c.release_notes_formatted = unicode(genshi.HTML(
                                    render_markdown(notes)))
        except Exception:
            c.pkg_notes_formatted = c.pkg.notes
示例#56
0
    def edit(self, id):
        """
        Allows editing of commitments for a specific publisher
        """
        from ckanext.dgu.model.commitment import Commitment
        from ckanext.dgu.lib import helpers as dgu_helpers

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'extras_as_string': True,
                   'save': 'save' in request.params}

        if not dgu_helpers.is_sysadmin():
            abort(401, "You are not allowed to edit the commitments for this publisher")

        try:
            c.publisher_dict = get_action('organization_show')(context, {'id': id})
        except NotAuthorized:
            abort(401, _('Unauthorized to read commitments'))
        except ObjectNotFound:
            abort(404, _('Publisher not found'))

        c.publisher = context.get('group')
        c.publishers = model.Session.query(model.Group).filter(model.Group.state=='active')\
            .order_by(model.Group.title).all()

        c.errors = {}

        if request.method == "POST":
            # need to flatten the request into some commitments, if there is an ID then
            # we should update them, if there isn't then add them.
            # TODO: Work out how to remove them. Perhaps get the current IDs and do a diff
            # If successful redirect to read()

            h.redirect_to(h.url_for(controller='ckanext.dgu.controllers.commitment:CommitmentController',
                action='commitments', id=c.publisher.name))


        c.commitments = Commitment.get_for_publisher(c.publisher.name).order_by('commitment.commitment_text')

        return render('commitment/edit.html')
示例#57
0
    def download(self, id):
        """
        Downloads all of the current datasets for a given publisher as a read-only
        CSV file.
        """
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'for_view': True,
                   'group': id}

        try:
            c.group_dict = get_action('organization_show')(context, {"id": id})
            c.group = context['group']
        except ObjectNotFound:
            abort(404, 'Organization not found')
        except NotAuthorized:
            abort(401, 'Unauthorized to read Organization %s' % id)

        try:
            context['group'] = c.group
            check_access('organization_update', context)
        except NotAuthorized, e:
            abort(401, 'User %r not authorized to download unpublished '% (c.user))