예제 #1
0
파일: dataset.py 프로젝트: paulmueller/ckan
def search(package_type):
    extra_vars = {}

    try:
        context = {
            u'model': model,
            u'user': g.user,
            u'auth_user_obj': g.userobj
        }
        check_access(u'site_read', context)
    except NotAuthorized:
        base.abort(403, _(u'Not authorized to see this page'))

    # unicode format (decoded from utf8)
    extra_vars[u'q'] = q = request.args.get(u'q', u'')

    extra_vars['query_error'] = False
    page = h.get_page_number(request.args)

    limit = int(config.get(u'ckan.datasets_per_page', 20))

    # most search operations should reset the page counter:
    params_nopage = [(k, v) for k, v in request.args.items(multi=True)
                     if k != u'page']

    extra_vars[u'drill_down_url'] = drill_down_url
    extra_vars[u'remove_field'] = partial(remove_field, package_type)

    sort_by = request.args.get(u'sort', None)
    params_nosort = [(k, v) for k, v in params_nopage if k != u'sort']

    extra_vars[u'sort_by'] = partial(_sort_by, params_nosort, package_type)

    if not sort_by:
        sort_by_fields = []
    else:
        sort_by_fields = [field.split()[0] for field in sort_by.split(u',')]
    extra_vars[u'sort_by_fields'] = sort_by_fields

    pager_url = partial(_pager_url, params_nopage, package_type)

    search_url_params = urlencode(_encode_params(params_nopage))
    extra_vars[u'search_url_params'] = search_url_params

    details = _get_search_details()
    extra_vars[u'fields'] = details[u'fields']
    extra_vars[u'fields_grouped'] = details[u'fields_grouped']
    fq = details[u'fq']
    search_extras = details[u'search_extras']

    context = {
        u'model': model,
        u'session': model.Session,
        u'user': g.user,
        u'for_view': True,
        u'auth_user_obj': g.userobj
    }

    # Unless changed via config options, don't show other dataset
    # types any search page. Potential alternatives are do show them
    # on the default search page (dataset) or on one other search page
    search_all_type = config.get(u'ckan.search.show_all_types', u'dataset')
    search_all = False

    try:
        # If the "type" is set to True or False, convert to bool
        # and we know that no type was specified, so use traditional
        # behaviour of applying this only to dataset type
        search_all = asbool(search_all_type)
        search_all_type = u'dataset'
    # Otherwise we treat as a string representing a type
    except ValueError:
        search_all = True

    if not search_all or package_type != search_all_type:
        # Only show datasets of this particular type
        fq += u' +dataset_type:{type}'.format(type=package_type)

    facets = OrderedDict()

    org_label = h.humanize_entity_type(
        u'organization',
        h.default_group_type(u'organization'),
        u'facet label') or _(u'Organizations')

    group_label = h.humanize_entity_type(
        u'group',
        h.default_group_type(u'group'),
        u'facet label') or _(u'Groups')

    default_facet_titles = {
        u'organization': org_label,
        u'groups': group_label,
        u'tags': _(u'Tags'),
        u'res_format': _(u'Formats'),
        u'license_id': _(u'Licenses'),
    }

    for facet in h.facets():
        if facet in default_facet_titles:
            facets[facet] = default_facet_titles[facet]
        else:
            facets[facet] = facet

    # Facet titles
    for plugin in plugins.PluginImplementations(plugins.IFacets):
        facets = plugin.dataset_facets(facets, package_type)

    extra_vars[u'facet_titles'] = facets
    data_dict = {
        u'q': q,
        u'fq': fq.strip(),
        u'facet.field': list(facets.keys()),
        u'rows': limit,
        u'start': (page - 1) * limit,
        u'sort': sort_by,
        u'extras': search_extras,
        u'include_private': asbool(
            config.get(u'ckan.search.default_include_private', True)
        ),
    }
    try:
        query = get_action(u'package_search')(context, data_dict)

        extra_vars[u'sort_by_selected'] = query[u'sort']

        extra_vars[u'page'] = h.Page(
            collection=query[u'results'],
            page=page,
            url=pager_url,
            item_count=query[u'count'],
            items_per_page=limit
        )
        extra_vars[u'search_facets'] = query[u'search_facets']
        extra_vars[u'page'].items = query[u'results']
    except SearchQueryError as se:
        # User's search parameters are invalid, in such a way that is not
        # achievable with the web interface, so return a proper error to
        # discourage spiders which are the main cause of this.
        log.info(u'Dataset search query rejected: %r', se.args)
        base.abort(
            400,
            _(u'Invalid search query: {error_message}')
            .format(error_message=str(se))
        )
    except SearchError as se:
        # May be bad input from the user, but may also be more serious like
        # bad code causing a SOLR syntax error, or a problem connecting to
        # SOLR
        log.error(u'Dataset search error: %r', se.args)
        extra_vars[u'query_error'] = True
        extra_vars[u'search_facets'] = {}
        extra_vars[u'page'] = h.Page(collection=[])

    # FIXME: try to avoid using global variables
    g.search_facets_limits = {}
    for facet in extra_vars[u'search_facets'].keys():
        try:
            limit = int(
                request.args.get(
                    u'_%s_limit' % facet,
                    int(config.get(u'search.facets.default', 10))
                )
            )
        except ValueError:
            base.abort(
                400,
                _(u'Parameter u"{parameter_name}" is not '
                  u'an integer').format(parameter_name=u'_%s_limit' % facet)
            )

        g.search_facets_limits[facet] = limit

    _setup_template_variables(context, {}, package_type=package_type)

    extra_vars[u'dataset_type'] = package_type

    # TODO: remove
    for key, value in extra_vars.items():
        setattr(g, key, value)

    return base.render(
        _get_pkg_template(u'search_template', package_type), extra_vars
    )
예제 #2
0
    def index(self):
        group_type = self._guess_group_type()

        page = h.get_page_number(request.params) or 1
        items_per_page = 21

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
            'for_view': True,
            'with_private': False
        }

        q = c.q = request.params.get('q', '')
        sort_by = c.sort_by_selected = request.params.get('sort')
        try:
            self._check_access('site_read', context)
            self._check_access('group_list', context)
        except NotAuthorized:
            abort(403, _('Not authorized to see this page'))

        # pass user info to context as needed to view private datasets of
        # orgs correctly
        if c.userobj:
            context['user_id'] = c.userobj.id
            context['user_is_admin'] = c.userobj.sysadmin

        try:
            data_dict_global_results = {
                'all_fields': False,
                'q': q,
                'sort': sort_by,
                'type': group_type or 'group',
            }
            global_results = self._action('group_list')(
                context, data_dict_global_results)
        except ValidationError as e:
            if e.error_dict and e.error_dict.get('message'):
                msg = e.error_dict['message']
            else:
                msg = str(e)
            h.flash_error(msg)
            c.page = h.Page([], 0)
            return render(self._index_template(group_type),
                          extra_vars={'group_type': group_type})

        data_dict_page_results = {
            'all_fields': True,
            'q': q,
            'sort': sort_by,
            'type': group_type or 'group',
            'limit': items_per_page,
            'offset': items_per_page * (page - 1),
            'include_extras': True
        }
        page_results = self._action('group_list')(context,
                                                  data_dict_page_results)

        c.page = h.Page(
            collection=global_results,
            page=page,
            url=h.pager_url,
            items_per_page=items_per_page,
        )

        c.page.items = page_results
        return render(self._index_template(group_type),
                      extra_vars={'group_type': group_type})
예제 #3
0
    def index(self):
        context = {
            'model': model,
            'session': model.Session,
            'for_view': True,
            'with_private': False
        }

        try:
            self._check_access('site_read', context)
        except NotAuthorized:
            abort(403, _('Not authorized to see this page'))

        # pass user info to context as needed to view private datasets of
        # orgs correctly
        # if c.userobj:
        #     context['user_id'] = c.userobj.id
        #     context['user_is_admin'] = c.userobj.sysadmin
        #     context['auth_user_obj'] = c.userobj

        try:
            q = c.q = request.params.get('q', '')
            page = int(request.params.get('page', 1))
            limit = int(request.params.get('limit', 25))
            sort_option = request.params.get('sort', 'title asc')
        except ValueError:
            abort(404, 'Page not found')

        reset_thumbnails = request.params.get('reset_thumbnails', 'false')

        data_dict = {
            'all_fields': True,
            'sort': sort_option
            if sort_option in ['title asc', 'title desc'] else 'title asc',
            # Custom sorts will throw an error here
            'q': q,
            'reset_thumbnails': reset_thumbnails,
        }

        all_orgs = get_action('cached_organization_list')(context, data_dict)

        all_orgs = helper.filter_and_sort_results_case_insensitive(
            all_orgs, sort_option, q=q, has_datasets=True)

        # c.featured_orgs = helper.hdx_get_featured_orgs(context, data_dict)

        def pager_url(page=None):
            if sort_option:
                url = h.url_for('organizations_index',
                                q=q,
                                page=page,
                                sort=sort_option,
                                limit=limit) + '#organizationsSection'
            else:
                url = h.url_for(
                    'organizations_index', q=q, page=page,
                    limit=limit) + '#organizationsSection'
            return url

        c.page = h.Page(collection=all_orgs,
                        page=page,
                        url=pager_url,
                        items_per_page=limit)

        # displayed_orgs = c.featured_orgs + [o for o in c.page]
        displayed_orgs = [o for o in c.page]
        org_add_last_updated_field(displayed_orgs)

        return base.render('organization/index.html')
    def read(self, id):
        context = {
            'model': model,
            'session': model.Session,
            'user': tk.c.user,
            'for_view': True
        }
        page = tk.h.get_page_number(tk.request.params) or 1
        items_per_page = 21

        q = tk.c.q = tk.request.params.get('q', '')
        sort_by = tk.c.sort_by_selected = tk.request.params.get('sort')
        try:
            tk.check_access('site_read', context)
            tk.check_access('metadata_schema_list', context)
        except tk.NotAuthorized:
            tk.abort(403, tk._('Not authorized to see this page'))

        if tk.c.userobj:
            context['user_id'] = tk.c.userobj.id
            context['user_is_admin'] = tk.c.userobj.sysadmin

        tk.c.metadata_standard = tk.get_action('metadata_standard_show')(
            context, {
                'id': id
            })
        try:
            data_dict_global_results = {
                'metadata_standard_id': id,
                'all_fields': False,
                'q': q,
                'sort': sort_by,
                'type': 'metadata_schema',
            }
            global_results = tk.get_action('metadata_schema_list')(
                context, data_dict_global_results)
        except tk.ValidationError as e:
            if e.error_dict and e.error_dict.get('message'):
                msg = e.error_dict['message']
            else:
                msg = str(e)
            tk.h.flash_error(msg)
            tk.c.page = helpers.Page([], 0)
            return tk.render('metadata_standard/read.html')

        data_dict_page_results = {
            'metadata_standard_id': id,
            'all_fields': True,
            'q': q,
            'sort': sort_by,
            'limit': items_per_page,
            'offset': items_per_page * (page - 1),
        }
        page_results = tk.get_action('metadata_schema_list')(
            context, data_dict_page_results)

        tk.c.page = helpers.Page(
            collection=global_results,
            page=page,
            url=tk.h.pager_url,
            items_per_page=items_per_page,
        )

        tk.c.page.items = page_results
        return tk.render('metadata_standard/read.html')
예제 #5
0
파일: related.py 프로젝트: sirca/ckan
    def dashboard(self):
        """ List all related items regardless of dataset """
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'auth_user_obj': c.userobj,
            'for_view': True
        }
        data_dict = {
            'type_filter': base.request.params.get('type', ''),
            'sort': base.request.params.get('sort', ''),
            'featured': base.request.params.get('featured', '')
        }

        params_nopage = [(k, v) for k, v in base.request.params.items()
                         if k != 'page']
        try:
            page = int(base.request.params.get('page', 1))
        except ValueError:
            base.abort(400, ('"page" parameter must be an integer'))

        # Update ordering in the context
        related_list = logic.get_action('related_list')(context, data_dict)

        def search_url(params):
            url = h.url_for(controller='related', action='dashboard')
            params = [
                (k, v.encode('utf-8') if isinstance(v, basestring) else str(v))
                for k, v in params
            ]
            return url + u'?' + urllib.urlencode(params)

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        c.page = h.Page(collection=related_list,
                        page=page,
                        url=pager_url,
                        item_count=len(related_list),
                        items_per_page=9)

        c.filters = dict(params_nopage)

        c.type_options = self._type_options()
        c.sort_options = ({
            'value': '',
            'text': _('Most viewed')
        }, {
            'value': 'view_count_desc',
            'text': _('Most Viewed')
        }, {
            'value': 'view_count_asc',
            'text': _('Least Viewed')
        }, {
            'value': 'created_desc',
            'text': _('Newest')
        }, {
            'value': 'created_asc',
            'text': _('Oldest')
        })

        return base.render("related/dashboard.html")
예제 #6
0
파일: group.py 프로젝트: mediasuitenz/ckan
def index(group_type, is_organization):
    extra_vars = {}
    set_org(is_organization)
    page = h.get_page_number(request.params) or 1
    items_per_page = int(config.get(u'ckan.datasets_per_page', 20))

    context = {
        u'model': model,
        u'session': model.Session,
        u'user': g.user,
        u'for_view': True,
        u'with_private': False
    }

    try:
        _check_access(u'site_read', context)
        _check_access(u'group_list', context)
    except NotAuthorized:
        base.abort(403, _(u'Not authorized to see this page'))

    q = request.params.get(u'q', u'')
    sort_by = request.params.get(u'sort')

    # TODO: Remove
    # ckan 2.9: Adding variables that were removed from c object for
    # compatibility with templates in existing extensions
    g.q = q
    g.sort_by_selected = sort_by

    extra_vars["q"] = q
    extra_vars["sort_by_selected"] = sort_by

    # pass user info to context as needed to view private datasets of
    # orgs correctly
    if g.userobj:
        context['user_id'] = g.userobj.id
        context['user_is_admin'] = g.userobj.sysadmin

    try:
        data_dict_global_results = {
            u'all_fields': False,
            u'q': q,
            u'sort': sort_by,
            u'type': group_type or u'group',
        }
        global_results = _action(u'group_list')(context,
                                                data_dict_global_results)
    except ValidationError as e:
        if e.error_dict and e.error_dict.get(u'message'):
            msg = e.error_dict['message']
        else:
            msg = str(e)
        h.flash_error(msg)
        extra_vars["page"] = h.Page([], 0)
        extra_vars["group_type"] = group_type
        return base.render(_index_template(group_type), extra_vars)

    data_dict_page_results = {
        u'all_fields': True,
        u'q': q,
        u'sort': sort_by,
        u'type': group_type or u'group',
        u'limit': items_per_page,
        u'offset': items_per_page * (page - 1),
        u'include_extras': True
    }
    page_results = _action(u'group_list')(context, data_dict_page_results)

    extra_vars["page"] = h.Page(
        collection=global_results,
        page=page,
        url=h.pager_url,
        items_per_page=items_per_page,
    )

    extra_vars["page"].items = page_results
    extra_vars["group_type"] = group_type

    # TODO: Remove
    # ckan 2.9: Adding variables that were removed from c object for
    # compatibility with templates in existing extensions
    g.page = extra_vars["page"]
    return base.render(_index_template(group_type), extra_vars)
예제 #7
0
파일: user.py 프로젝트: jrods/ckanext-bcgov
class EDCUserController(UserController):

    def dashboard_unpublished(self):

        if not c.userobj :
            abort(401, _('You must be logged-in to access the dashboard.'))

        user_id = c.userobj.id 

        fq = ' +edc_state:("DRAFT" OR "PENDING PUBLISH" OR "REJECTED")'
            #Get the list of organizations that this user is the admin
        if not c.userobj.sysadmin :
            user_orgs = get_orgs_user_can_edit(c.userobj)#['"' + org + '"' for org in get_orgs_user_can_edit()]
            #user_orgs = ['"' + org.get('id') + '"' for org in get_user_orgs(user_id, 'admin')]
            #user_orgs += ['"' + org.get('id') + '"' for org in get_user_orgs(user_id, 'editor')]
            if len(user_orgs) > 0 :
                fq += ' +owner_org:(' + ' OR '.join(user_orgs) + ')'
        self._user_datasets('dashboard_unpublished', c.userobj.id, fq)
        return render('user/dashboard_unpublished.html')

    def dashboard_datasets(self):
        if not c.userobj :
            abort(401, _('You must be logged-in to access the dashboard.'))
        fq = ' +author:("%s")' % (c.userobj.id)
        self._user_datasets('dashboard_datasets', c.userobj.id, fq)
        return render('user/dashboard_datasets.html')


    def read(self, id=None):
        if c.userobj and c.userobj.sysadmin == True:
            fq = ''
        else:
            fq = ' +(edc_state:("PUBLISHED" OR "PENDING ARCHIVE")'
            if c.userobj:
                user_id = c.userobj.id
                user_orgs = get_orgs_user_can_edit(c.userobj)#['"' + org + '"' for org in get_orgs_user_can_edit()]
                #user_orgs = ['"' + org.get('id') + '"' for org in get_user_orgs(user_id, 'admin')]
                #user_orgs += ['"' + org.get('id') + '"' for org in get_user_orgs(user_id, 'editor')]
                if len(user_orgs) > 0:
                    fq += ' OR owner_org:(' + ' OR '.join(user_orgs) + ')'
            fq += ')'

        self._user_datasets('read',id, fq)
        return render('user/read.html')

    def _user_datasets(self, action, id=None, filter_query=None):
        from ckan.lib.search import SearchError

        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author, 'auth_user_obj': c.userobj,
                   'for_view': True}
        user_dict = {'id': id,
                     'user_obj': c.userobj,
                     'include_datasets': False}

        # unicode format (decoded from utf8)
        q = c.q = request.params.get('q', u'')

        context['return_query'] = True

        try:
            page = int(request.params.get('page', 1))
        except ValueError, e:
            abort(400, ('"page" parameter must be an integer'))

        limit = g.datasets_per_page

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']

        sort_by = request.params.get('sort', None)

        def search_url(params):
            base_url = config.get('ckan.site_url')
            if action == 'dashboard_datasets':
                url = base_url + '/dashboard/datasets'
            elif action == 'dashboard_unpublished':
                url = base_url + '/dashboard/unpublished'
            elif action == 'read':
                url = h.url_for(controller='user', action=action, id=id)
            else :
                url = h.url_for(controller='user', action=action)

            params = [(k, v.encode('utf-8') if isinstance(v, basestring)
                       else str(v)) for k, v in params]
            return url + u'?' + urlencode(params)

        def drill_down_url(alternative_url=None, **by):
            return h.add_url_param(alternative_url=alternative_url,
                                   controller='user', action=action,
                                   extras=dict(id=c.userobj.id),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key, value=value, replace=replace,
                                      controller='user', action=action,
                                      extras=dict(id=c.userobj.id))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            search_extras = {}
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        q += ' %s:"%s"' % (param, value)
                    else:
                        search_extras[param] = value

            facets = OrderedDict()

            default_facet_titles = {
                    'organization': _('Organizations'),
                    'edc_state': _('States'),
                    'tags': _('Tags'),
                    'res_format': _('Formats'),
                    }

            for facet in default_facet_titles:
                facets[facet] = default_facet_titles[facet]


            c.facet_titles = facets

            fq = filter_query or ''


            data_dict = {
                'q': q,
                'fq': fq.strip(),
                'facet.field': facets.keys(),
                'rows': limit,
                'start': (page - 1) * limit,
                'sort': sort_by,
                'extras': search_extras
            }

            query = get_action('package_search')(context, data_dict)

            c.page = h.Page(
                collection=query['results'],
                page=page,
                url=pager_url,
                item_count=query['count'],
                items_per_page=limit
            )
            user_dict['package_count'] = query['count']
            c.facets = query['facets']
            maintain.deprecate_context_item('facets',
                                            'Use `c.search_facets` instead.')

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.facets.keys():
                limit = int(request.params.get('_%s_limit' % facet,
                                                g.facets_default_number))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except SearchError, se:
            log.error('User search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.page = h.Page(collection=[])
예제 #8
0
    def _performing_search(self, q, fq, facet_keys, limit, page, sort_by,
                           search_extras, pager_url, context, fq_list=None, expand='false',
                           enable_update_status_facet=False):
        data_dict = {
            'q': q,
            'fq_list': fq_list if fq_list else [],
            'expand': expand,
            'expand.rows': 1,  # we anyway don't show the expanded datasets, but doesn't work with 0
            'fq': fq.strip(),
            'facet.field': facet_keys,
            # added for https://github.com/OCHA-DAP/hdx-ckan/issues/3340
            'facet.limit': 2000,
            'rows': limit,
            'start': (page - 1) * limit,
            'sort': sort_by,
            'extras': search_extras,
            'ext_compute_freshness': 'true'
        }

        if enable_update_status_facet:
            now_string = datetime.datetime.utcnow().isoformat() + 'Z'
            freshness_facet_extra = 'ex={},{}'.format(UPDATE_STATUS_URL_FILTER, 'batch')
            data_dict.update({
                'facet.range': '{{!{extra}}}due_date'.format(extra=freshness_facet_extra),
                'f.due_date.facet.range.start': now_string + '-100YEARS',
                'f.due_date.facet.range.end': now_string + '+100YEARS',
                'f.due_date.facet.range.gap': '+100YEARS',
                'f.due_date.facet.mincount': '0',
                'facet.query': '{{!key=unknown {extra}}}-due_date:[* TO *]'.format(extra=freshness_facet_extra),
            })

        include_private = context.pop('ignore_capacity_check', None)
        if include_private:
            data_dict['include_private'] = include_private

        query = get_action('package_search')(context, data_dict)

        if not query.get('results', None):
            log.warn('No query results found for data_dict: {}. Query dict is: {}. Query time {}'.format(
                str(data_dict), str(query), datetime.datetime.now()))

        c.facets = query['facets']
        c.search_facets = query['search_facets']

        # if we're using collapse/expand/batch then take total count from facet site_id
        if expand:
            site_id_items = query['search_facets'].get('site_id', {}).get('items', [])
            c.batch_total_items = sum((item.get('count', 0) for item in site_id_items))

        # get_action('populate_related_items_count')(
        #     context, {'pkg_dict_list': query['results']})

        get_action('populate_showcase_items_count')(context, {'pkg_dict_list': query['results']})

        c.page = h.Page(
            collection=query['results'],
            page=page,
            url=pager_url,
            item_count=query['count'],
            items_per_page=limit
        )

        for dataset in query['results']:
            downloads_list = (res['tracking_summary']['total'] for res in dataset.get('resources', []) if
                              res.get('tracking_summary', {}).get('total'))
            download_sum = sum(downloads_list)

            dataset['approx_total_downloads'] = find_approx_download(dataset.get('total_res_downloads', 0))

            dataset['batch_length'] = query['expanded'].get(dataset.get('batch',''), {}).get('numFound', 0)
            if dataset.get('organization'):
                dataset['batch_url'] = h.url_for('organization_read', id=dataset['organization'].get('name'),
                                             ext_batch=dataset.get('batch'))

        for dataset in query['results']:
            dataset['hdx_analytics'] = json.dumps(generate_analytics_data(dataset))

        c.page.items = query['results']
        c.sort_by_selected = query['sort']

        c.count = c.item_count = query['count']

        return query
    def search(self):
        package_type = self._guess_package_type()
        try:
            context = {
                'model': model,
                'user': c.user or c.author,
                'auth_user_obj': c.userobj
            }
            check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))
        q = c.q = request.params.get('q', u'')
        c.query_error = False
        page = h.get_page_number(request.params)
        limit = int(config.get('ckan.datasets_per_page', 20))
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']

        def drill_down_url(alternative_url=None, **by):
            return h.add_url_param(alternative_url=alternative_url,
                                   controller='package',
                                   action='search',
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key,
                                      value=value,
                                      replace=replace,
                                      controller='package',
                                      action='search')

        c.remove_field = remove_field

        sort_by = request.params.get('sort', None)
        params_nosort = [(k, v) for k, v in params_nopage if k != 'sort']

        def _sort_by(fields):
            params = params_nosort[:]
            if fields:
                sort_string = ', '.join('%s %s' % f for f in fields)
                params.append(('sort', sort_string))
            return search_url(params, package_type)

        c.sort_by = _sort_by
        if not sort_by:
            c.sort_by_fields = []
        else:
            c.sort_by_fields = [
                field.split()[0] for field in sort_by.split(',')
            ]

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params, package_type)

        c.search_url_params = urlencode(_encode_params(params_nopage))

        try:
            c.fields = []
            c.fields_grouped = {}
            search_extras = {}
            fq = ''
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and value and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        # Modificación para andino: usamos una función para buscar dependencias entre organizaciones
                        if param != 'organization':
                            fq += ' %s:"%s"' % (param, value)
                        else:
                            fq += custom_organization_filter(value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

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

            if package_type and package_type != 'dataset':
                fq += ' +dataset_type:{type}'.format(type=package_type)
            elif not asbool(config.get('ckan.search.show_all_types', 'False')):
                fq += ' +dataset_type:dataset'

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
                'groups': _('Groups'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses'),
            }

            for facet in h.facets():
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            for plugin in p.PluginImplementations(p.IFacets):
                facets = plugin.dataset_facets(facets, package_type)

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq.strip(),
                'facet.field': facets.keys(),
                'rows': limit,
                'start': (page - 1) * limit,
                'sort': sort_by,
                'extras': search_extras
            }

            query = logic.action.get.package_search(context, data_dict)
            c.sort_by_selected = query['sort']

            c.page = h.Page(collection=query['results'],
                            page=page,
                            url=pager_url,
                            item_count=query['count'],
                            items_per_page=limit)
            c.search_facets = query['search_facets']
            c.page.items = query['results']
        except SearchError, se:
            log.error('Dataset search error: %r', se.args)
            c.query_error = True
            c.search_facets = {}
            c.page = h.Page(collection=[])
예제 #10
0
    def index(self):
        group_type = self._guess_group_type()

        page = h.get_page_number(request.params) or 1
        items_per_page = 21

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

        q = c.q = request.params.get('q', '')

        # ****************** Modified part start (Anja 3.1.17)
        criteria = request.params.get('sort')

        if criteria != None:
            sort_by = c.sort_by_selected = request.params.get('sort')
        else:
            sort_by = c.sort_by_selected = 'package_count'
        # ****************** Modified part end (Anja 3.1.17)

        try:
            self._check_access('site_read', context)

        except NotAuthorized:
            abort(401, _('Not authorized to see this group'))

        # pass user info to context as needed to view private datasets of
        # orgs correctly
        if c.userobj:
            context['user_id'] = c.userobj.id
            context['user_is_admin'] = c.userobj.sysadmin

        data_dict_global_results = {
            'all_fields': False,
            'q': q,
            'sort': sort_by,
            'type': group_type or 'group',
        }
        global_results = self._action('group_list')(context,
                                                    data_dict_global_results)

        data_dict_page_results = {
            'all_fields': True,
            'q': q,
            'sort': sort_by,
            'type': group_type or 'group',
            'limit': items_per_page,
            'offset': items_per_page * (page - 1),
        }
        page_results = self._action('group_list')(context,
                                                  data_dict_page_results)

        c.page = h.Page(
            collection=global_results,
            page=page,
            url=h.pager_url,
            items_per_page=items_per_page,
        )

        c.page.items = page_results
        return render(self._index_template(group_type),
                      extra_vars={'group_type': group_type})
예제 #11
0
    def setup_template_variables(self, context, data_dict):
        """Setup variables available to templates"""

        self.datastore_fields = self._get_datastore_fields(
            data_dict['resource']['id'])

        field_separator = config.get("ckanext.recordviewer.field_separator",
                                     ';')
        records_per_page = config.get("ckanext.recordviewer.records_per_page",
                                      30)

        current_page = request.params.get('page', 1)

        record_field = data_dict['resource_view'].get('record_field')
        #gallery_title_field = data_dict['resource_view'].get('gallery_title_field', None)
        #modal_title_field = data_dict['resource_view'].get('modal_title_field', None)

        #thumbnail_params = data_dict['resource_view'].get('thumbnail_params', None)
        #thumbnail_field = data_dict['resource_view'].get('thumbnail_field', None)

        records_list = []
        records = []
        item_count = 0

        # for future condition to query data, (for example, if a new field will be mandatory)
        dummyif = True
        if dummyif:

            offset = (int(current_page) - 1) * records_per_page

            # We only want to get records that have both the image field populated
            # So add filters to the datastore search params
            params = {
                'resource_id': data_dict['resource']['id'],
                'limit': records_per_page,
                'offset': offset,
                #'filters': {
                #    record_field: IS_NOT_NULL
                #}
            }

            # Add filters from request
            filter_str = request.params.get('filters')
            if filter_str:
                for f in filter_str.split('|'):
                    try:
                        (name, value) = f.split(':')
                        params['filters'][name] = value

                    except ValueError:
                        pass

            # Full text filter
            fulltext = request.params.get('q')
            if fulltext:
                params['q'] = fulltext

            context = {
                'model': model,
                'session': model.Session,
                'user': c.user or c.author
            }
            data = toolkit.get_action('datastore_search')(context, params)

            item_count = data.get('total', 0)
            records = data['records']

            #POR AQUI REVISAR, CREO QUE SE ESTAN RECUPERANDO TODOS LOS DATOS, (tODOS LOS OTROS CAMPOS)
            #VERIFICAR PARA QUE ESOS DATOS TAMBIEN VAYAN AL FRONTEND

            for record in data['records']:
                record_title = record.get(record_field, None)
                records_list.append({
                    'record_title': record_title,
                    'record_id': record['_id'],
                    'record': record,
                })

        page_params = {
            'collection': records,
            'page': current_page,
            'url': self.pager_url,
            'items_per_page': records_per_page,
            'item_count': item_count,
        }

        # Add filter params to page links
        for key in ['q', 'filters']:
            value = request.params.get(key)
            if value:
                page_params[key] = value

        page = h.Page(**page_params)

        return {
            'records': records_list,
            'datastore_fields': self.datastore_fields,
            'defaults': {},
            'resource_id': data_dict['resource']['id'],
            'package_name': data_dict['package']['name'],
            'page': page,
            'total_items': item_count,
        }
예제 #12
0
class EDCOrganizationController(OrganizationController):
    def index(self):
        # FIXME: index copied from GroupController and modified to
        # show only parent groups
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'for_view': True,
            'with_private': False
        }

        data_dict = {'all_fields': False}
        try:
            self._check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # pass user info to context as needed to view private datasets of
        # orgs correctly
        if c.userobj:
            context['user_id'] = c.userobj.id
            context['user_is_admin'] = c.userobj.sysadmin

        search_result = self._action('organization_list')(context, data_dict)

        org_model = context['model']

        #Get the list of all groups of type "organization" that have no parents.
        top_level_orgs = org_model.Group.get_top_level_groups(
            type="organization")
        top_results = [
            org for org in top_level_orgs if org.name in search_result
        ]

        facets = OrderedDict()

        facets['organization'] = _('Organizations')

        data_dict = {
            'facet.field': facets.keys(),
        }

        query = get_action('package_search')(context, data_dict)
        c.org_pkg_count = query['facets'].get('organization')

        c.top_orgs_items = top_results
        return render('organization/index.html')

    def _read(self, id, limit, group_type='organization'):
        # FIXME: copied and modified from GroupController to collect
        # sub organizations, create c.fields_grouped and hard-code
        # search facets
        ''' This is common code used by both read and bulk_process'''

        #group_type = self._get_group_type(id.split('@')[0])
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'schema': self._db_to_form_schema(group_type=group_type),
            'for_view': True,
            'extras_as_string': True
        }

        # Get the subgorgs of this org
        org_id = c.group_dict.get('id')
        hide_desc = False

        q = c.q = request.params.get('q', '')

        # XXX: unfortunate hack, copy sort default behaviour from
        # before_search because we're using the q parameter below
        # even when no text query was submitted
        if not q and request.params.get('sort') in (None, 'rank'):
            sort_by = 'record_publish_date desc, metadata_modified desc'
        else:
            sort_by = request.params.get('sort', None)

        suborgs = ['"' + org + '"' for org in get_suborgs(org_id)]
        if suborgs != []:
            q += ' owner_org:("' + org_id + '" OR ' + ' OR '.join(
                suborgs) + ')'
        else:
            q += ' owner_org:"%s"' % org_id

        c.description_formatted = h.render_markdown(
            c.group_dict.get('description'))

        context['return_query'] = True

        try:
            page = int(request.params.get('page', 1))
        except ValueError, e:
            abort(400, ('"page" parameter must be an integer'))

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']

        def search_url(params):
            action = 'bulk_process' if c.action == 'bulk_process' else 'read'
            url = h.url_for(controller='organization', action=action, id=id)
            params = [
                (k, v.encode('utf-8') if isinstance(v, basestring) else str(v))
                for k, v in params
            ]
            return url + u'?' + urlencode(params)

        def drill_down_url(**by):
            return h.add_url_param(alternative_url=None,
                                   controller='organization',
                                   action='read',
                                   extras=dict(id=c.group_dict.get('name')),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key,
                                      value=value,
                                      replace=replace,
                                      controller='organization',
                                      action='read',
                                      extras=dict(id=c.group_dict.get('name')))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            search_extras = {}
            c.fields_grouped = {}
            for (param, value) in request.params.items():
                if not param in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        q += ' %s: "%s"' % (param, value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

            fq = 'capacity:"public"'
            user_member_of_orgs = [
                org['id'] for org in h.organizations_available('read')
            ]

            if (c.group and c.group.id in user_member_of_orgs):
                fq = ''
                context['ignore_capacity_check'] = True

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
                'edc_state': _('States'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses'),
                'type': _('Dataset types')
            }

            for facet in default_facet_titles:
                facets[facet] = default_facet_titles[facet]

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq,
                'facet.field': facets.keys(),
                'rows': limit,
                'sort': sort_by,
                'start': (page - 1) * limit,
                'extras': search_extras
            }

            query = get_action('package_search')(context, data_dict)

            c.page = h.Page(collection=query['results'],
                            page=page,
                            url=pager_url,
                            item_count=query['count'],
                            items_per_page=limit)

            c.group_dict['package_count'] = query['count']
            c.facets = query['facets']
            #maintain.deprecate_context_item('facets',
            #                                'Use `c.search_facets` instead.')

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.facets.keys():
                limit = int(
                    request.params.get(
                        '_%s_limit' % facet,
                        toolkit.config.get('search.facets.default', 10)))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except search.SearchError, se:
            log.error('Group search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.page = h.Page(collection=[])
예제 #13
0
    def _read(self, id, limit):
        ''' This is common code used by both read and bulk_process'''
        group_type = self._get_group_type(id.split('@')[0])
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'schema': self._db_to_form_schema(group_type=group_type),
            'for_view': True,
            'extras_as_string': True
        }

        q = c.q = request.params.get('q', '')
        # Search within group
        if c.group_dict.get('is_organization'):
            q += ' owner_org:"%s"' % c.group_dict.get('id')
        else:
            q += ' groups:"%s"' % c.group_dict.get('name')

        c.description_formatted = h.render_markdown(
            c.group_dict.get('description'))

        context['return_query'] = True

        # c.group_admins is used by CKAN's legacy (Genshi) templates only,
        # if we drop support for those then we can delete this line.
        c.group_admins = new_authz.get_group_or_org_admin_ids(c.group.id)

        page = self._get_page_number(request.params)

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']
        sort_by = request.params.get('sort', None)

        def search_url(params):
            if group_type == 'organization':
                if c.action == 'bulk_process':
                    url = self._url_for(controller='organization',
                                        action='bulk_process',
                                        id=id)
                else:
                    url = self._url_for(controller='organization',
                                        action='read',
                                        id=id)
            else:
                url = self._url_for(controller='group', action='read', id=id)
            params = [
                (k, v.encode('utf-8') if isinstance(v, basestring) else str(v))
                for k, v in params
            ]
            return url + u'?' + urlencode(params)

        def drill_down_url(**by):
            return h.add_url_param(alternative_url=None,
                                   controller='group',
                                   action='read',
                                   extras=dict(id=c.group_dict.get('name')),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key,
                                      value=value,
                                      replace=replace,
                                      controller='group',
                                      action='read',
                                      extras=dict(id=c.group_dict.get('name')))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            search_extras = {}
            for (param, value) in request.params.items():
                if not param in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        q += ' %s: "%s"' % (param, value)
                    else:
                        search_extras[param] = value

            fq = 'capacity:"public"'
            user_member_of_orgs = [
                org['id'] for org in h.organizations_available('read')
            ]

            if (c.group and c.group.id in user_member_of_orgs):
                fq = ''
                context['ignore_capacity_check'] = True

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
                'groups': _('Groups'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses')
            }

            for facet in g.facets:
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            for plugin in plugins.PluginImplementations(plugins.IFacets):
                if self.group_type == 'organization':
                    facets = plugin.organization_facets(
                        facets, self.group_type, None)
                else:
                    facets = plugin.group_facets(facets, self.group_type, None)

            if 'capacity' in facets and (self.group_type != 'organization'
                                         or not user_member_of_orgs):
                del facets['capacity']

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq,
                'facet.field': facets.keys(),
                'rows': limit,
                'sort': sort_by,
                'start': (page - 1) * limit,
                'extras': search_extras
            }

            context_ = dict(
                (k, v) for (k, v) in context.items() if k != 'schema')
            query = get_action('package_search')(context_, data_dict)

            c.page = h.Page(collection=query['results'],
                            page=page,
                            url=pager_url,
                            item_count=query['count'],
                            items_per_page=limit)

            c.group_dict['package_count'] = query['count']
            c.facets = query['facets']
            maintain.deprecate_context_item('facets',
                                            'Use `c.search_facets` instead.')

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.facets.keys():
                limit = int(
                    request.params.get('_%s_limit' % facet,
                                       g.facets_default_number))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except search.SearchError, se:
            log.error('Group search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.page = h.Page(collection=[])
예제 #14
0
    def _read(self, id, limit, group_type):
        ''' This is common code used by both read and bulk_process'''
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user,
            'schema': self._db_to_form_schema(group_type=group_type),
            'for_view': True,
            'extras_as_string': True
        }

        q = c.q = request.params.get('q', '')
        # Search within group
        if c.group_dict.get('is_organization'):
            q += ' owner_org:"%s"' % c.group_dict.get('id')
        else:
            q += ' groups:"%s"' % c.group_dict.get('name')

        c.description_formatted = \
            h.render_markdown(c.group_dict.get('description'))

        context['return_query'] = True

        page = h.get_page_number(request.params)

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']
        sort_by = request.params.get('sort', None)

        def search_url(params):
            controller = lookup_group_controller(group_type)
            action = 'bulk_process' if c.action == 'bulk_process' else 'read'
            url = h.url_for(controller=controller, action=action, id=id)
            params = [
                (k, v.encode('utf-8') if isinstance(v, basestring) else str(v))
                for k, v in params
            ]
            return url + u'?' + urlencode(params)

        def drill_down_url(**by):
            return h.add_url_param(alternative_url=None,
                                   controller='group',
                                   action='read',
                                   extras=dict(id=c.group_dict.get('name')),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            controller = lookup_group_controller(group_type)
            return h.remove_url_param(key,
                                      value=value,
                                      replace=replace,
                                      controller=controller,
                                      action='read',
                                      extras=dict(id=c.group_dict.get('name')))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            c.fields_grouped = {}
            search_extras = {}
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        q += ' %s: "%s"' % (param, value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
                'groups': _('Groups'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses')
            }

            for facet in h.facets():
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            self._update_facet_titles(facets, group_type)

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': '',
                'include_private': True,
                'facet.field': facets.keys(),
                'rows': limit,
                'sort': sort_by,
                'start': (page - 1) * limit,
                'extras': search_extras
            }

            context_ = dict(
                (k, v) for (k, v) in context.items() if k != 'schema')
            query = get_action('package_search')(context_, data_dict)

            c.page = h.Page(collection=query['results'],
                            page=page,
                            url=pager_url,
                            item_count=query['count'],
                            items_per_page=limit)

            c.group_dict['package_count'] = query['count']

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.search_facets.keys():
                limit = int(
                    request.params.get('_%s_limit' % facet,
                                       config.get('search.facets.default',
                                                  10)))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except search.SearchError, se:
            log.error('Group search error: %r', se.args)
            c.query_error = True
            c.page = h.Page(collection=[])
    def _read(self, id, limit, group_type):  # noqa
        """
        This controller replaces the GroupController controller
        from CKAN. It uses the filter query (fq) parameter to query
        facets in Solr instead of the query parameter (q). If the
        query parameter is used the search always returns "no results found"
        when combining a search term with facets.
        Unfortunately there are no clean extension points in the
        GroupController, so that the _read() method
        had to be overridden completely.

        This is common code used by both read and bulk_process
        """
        context = {'model': model, 'session': model.Session,
                   'user': c.user or c.author,
                   'schema': self._db_to_form_schema(group_type=group_type),
                   'for_view': True, 'extras_as_string': True}

        q = c.q = request.params.get('q', '')
        # Search within group
        if c.group_dict.get('is_organization'):
            fq = 'owner_org:"%s"' % c.group_dict.get('id')
        else:
            fq = 'groups:"%s"' % c.group_dict.get('name')

        c.description_formatted = \
            h.render_markdown(c.group_dict.get('description'))

        context['return_query'] = True

        # c.group_admins is used by CKAN's legacy (Genshi) templates only,
        # if we drop support for those then we can delete this line.
        c.group_admins = authz.get_group_or_org_admin_ids(c.group.id)

        page = h.get_page_number(request.params)

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']
        sort_by = request.params.get('sort', None)

        def search_url(params):
            controller = lookup_group_controller(group_type)
            action = 'bulk_process' if c.action == 'bulk_process' else 'read'
            url = h.url_for(controller=controller, action=action, id=id)
            params = [(k, v.encode('utf-8') if isinstance(v, string_types)
                       else str(v)) for k, v in params]
            return url + u'?' + urlencode(params)

        def drill_down_url(**by):
            return h.add_url_param(alternative_url=None,
                                   controller='group', action='read',
                                   extras=dict(id=c.group_dict.get('name')),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            controller = lookup_group_controller(group_type)
            return h.remove_url_param(key, value=value, replace=replace,
                                      controller=controller, action='read',
                                      extras=dict(id=c.group_dict.get('name')))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            c.fields_grouped = {}
            search_extras = {}
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        fq += ' %s: "%s"' % (param, value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

            facets = OrderedDict()

            default_facet_titles = {'organization': _('Organizations'),
                                    'groups': _('Groups'),
                                    'tags': _('Tags'),
                                    'res_format': _('Formats'),
                                    'license_id': _('Licenses')}

            for facet in h.facets():
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            self._update_facet_titles(facets, group_type)

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq,
                'include_private': True,
                'facet.field': facets.keys(),
                'rows': limit,
                'sort': sort_by,
                'start': (page - 1) * limit,
                'extras': search_extras
            }

            context_ = dict((k, v) for (k, v) in context.items()
                            if k != 'schema')
            query = get_action('package_search')(context_, data_dict)

            c.page = h.Page(
                collection=query['results'],
                page=page,
                url=pager_url,
                item_count=query['count'],
                items_per_page=limit
            )

            c.group_dict['package_count'] = query['count']

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.search_facets.keys():
                limit = int(request.params.get('_%s_limit' % facet,
                                               config.get(
                                                   'search.facets.default',
                                                   10)))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except search.SearchError as se:
            log.error('Group search error: %r', se.args)
            c.query_error = True
            c.search_facets = {}
            c.page = h.Page(collection=[])

        self._setup_template_variables(
            context,
            {'id': id},
            group_type=group_type
        )
예제 #16
0
    def _search(self, package_type, pager_url, additional_fq='', additional_facets=None,
                default_sort_by=DEFAULT_SORTING, num_of_items=NUM_OF_ITEMS,
                ignore_capacity_check=False, use_solr_collapse=False, enable_update_status_facet=False):

        from ckan.lib.search import SearchError

        # unicode format (decoded from utf8)
        q = c.q = request.params.get('q', u'')
        c.query_error = False

        page = self._page_number()

        # Commenting below parts as it doesn't seem to be used
        # def drill_down_url(alternative_url=None, **by):
        #     return h.add_url_param(alternative_url=alternative_url,
        #                            controller='package', action='search',
        #                            new_params=by)
        #
        # c.drill_down_url = drill_down_url

        # self._set_remove_field_function()
        req_sort_by = request.params.get('sort', None)
        if not req_sort_by and q:
            req_sort_by = 'score desc, ' + DEFAULT_SORTING

        if req_sort_by:
            sort_by = req_sort_by
            c.used_default_sort_by = False
        else:
            sort_by = default_sort_by
            c.used_default_sort_by = True
        # params_nosort = [(k, v) for k, v in params_nopage if k != 'sort']

        # The sort_by function seems to not be used anymore

        #  def _sort_by(fields):
        #     """
        #     Sort by the given list of fields.
        #
        #     Each entry in the list is a 2-tuple: (fieldname, sort_order)
        #
        #     eg - [('metadata_modified', 'desc'), ('name', 'asc')]
        #
        #     If fields is empty, then the default ordering is used.
        #     """
        #     params = params_nosort[:]
        #
        #     if fields:
        #         sort_string = ', '.join('%s %s' % f for f in fields)
        #         params.append(('sort', sort_string))
        #     return self._search_url(params, package_type)
        #
        # c.sort_by = _sort_by

        if not sort_by:
            c.sort_by_fields = []
        else:
            c.sort_by_fields = [field.split()[0]
                                for field in sort_by.split(',')]

        self._set_other_links()

        try:
            c.fields = []
            # c.fields_grouped will contain a dict of params containing
            # a list of values eg {'tags':['tag1', 'tag2']}
            c.fields_grouped = {}
            search_extras = {}
            # limit = g.datasets_per_page

            fq = additional_fq
            tagged_fq_dict = {}
            featured_filters_set = False

            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if param == 'fq':
                        fq += ' %s' % (value,)
                    elif not param.startswith('ext_'):
                        c.fields.append((param, value))
                        # fq += ' {!tag=%s}%s:"%s"' % (param, param, value)
                        if param not in tagged_fq_dict:
                            tagged_fq_dict[param] = []
                        tagged_fq_dict[param].append(u'{}:"{}"'.format(param, value))
                        self.append_selected_facet_to_group(c.fields_grouped, param, value)
                    elif param == UPDATE_STATUS_URL_FILTER:
                        self.append_selected_facet_to_group(c.fields_grouped, param, value)
                    else:
                        if param in ['ext_cod', 'ext_subnational', 'ext_quickcharts', 'ext_geodata', 'ext_requestdata',
                                     'ext_hxl', 'ext_showcases', 'ext_archived', 'ext_administrative_divisions']:
                            featured_filters_set = True
                        search_extras[param] = value


            if c.fields_grouped.get(UPDATE_STATUS_URL_FILTER):
                search_extras[UPDATE_STATUS_URL_FILTER] = c.fields_grouped[UPDATE_STATUS_URL_FILTER]

            self._set_filters_are_selected_flag()

            fq_list = [u'{{!tag={tag}}}{value}'.format(tag=key, category=key, value=' OR '.join(value_list))
                       for key, value_list in tagged_fq_dict.items()]

            # if the search is not filtered by query or facet group datasets
            solr_expand = 'false'
            if use_solr_collapse and not fq_list and not q and not featured_filters_set:
                fq_list = ['{!tag=batch}{!collapse field=batch nullPolicy=expand} ']
                solr_expand = 'true'

            try:
                limit = 1 if self._is_facet_only_request() else int(request.params.get('ext_page_size', num_of_items))
            except:
                limit = num_of_items

            c.ext_page_size = limit

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

            if ignore_capacity_check:
                context['ignore_capacity_check'] = ignore_capacity_check

            if package_type and package_type != 'dataset':
                # Only show datasets of this particular type
                fq += ' +dataset_type:{type}'.format(type=package_type)
            else:
                # Unless changed via config options, don't show non standard
                # dataset types on the default search page
                if not asbool(config.get('ckan.search.show_all_types', 'False')):
                    fq += ' +dataset_type:dataset'

            facets = OrderedDict()

            default_facet_titles = get_default_facet_titles()

            for facet in h.facets():
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            for plugin in p.PluginImplementations(p.IFacets):
                facets = plugin.dataset_facets(facets, package_type)

            if additional_facets:
                facets.update(additional_facets)

            c.facet_titles = facets

            # TODO Line below to be removed after refactoring
            c.tab = 'all'

            #adding site_id to facets to facilitate totals counts in case of batch/collapse
            facet_keys = ['{!ex=batch}site_id'] + facets.keys()
            self._performing_search(q, fq, facet_keys, limit, page, sort_by, search_extras, pager_url, context,
                                    fq_list=fq_list, expand=solr_expand,
                                    enable_update_status_facet=enable_update_status_facet)

        except SearchError, se:
            log.error('Dataset search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.search_facets = {}
            c.page = h.Page(collection=[])
    def read(self, id, limit=50, organization_id=None):
        context = {
            'model': model,
            'session': model.Session,
            'user': tk.c.user,
            'for_view': True
        }

        self._set_organization_context(organization_id)
        tk.c.group_dict = tk.get_action('metadata_collection_show')(context, {
            'id': id
        })

        page = tk.h.get_page_number(tk.request.params) or 1
        q = tk.c.q = tk.request.params.get('q', '')

        try:
            tk.check_access('site_read', context)
            tk.check_access('metadata_record_list', context)
        except tk.NotAuthorized:
            tk.abort(403, tk._('Not authorized to see this page'))

        if tk.c.userobj:
            context['user_id'] = tk.c.userobj.id
            context['user_is_admin'] = tk.c.userobj.sysadmin

        try:
            data_dict_global_results = {
                'owner_org': organization_id,
                'metadata_collection_id': id,
                'all_fields': False,
                'q': q,
                'type': 'metadata_record',
            }
            global_results = tk.get_action('metadata_record_list')(
                context, data_dict_global_results)
        except tk.ValidationError as e:
            if e.error_dict and e.error_dict.get('message'):
                msg = e.error_dict['message']
            else:
                msg = str(e)
            tk.h.flash_error(msg)
            tk.c.page = helpers.Page([], 0)
            return tk.render('metadata_collection/read.html')

        data_dict_page_results = {
            'owner_org': organization_id,
            'metadata_collection_id': id,
            'all_fields': True,
            'q': q,
            'limit': limit,
            'offset': limit * (page - 1),
        }
        page_results = tk.get_action('metadata_record_list')(
            context, data_dict_page_results)
        workflow_states = {
            ws['name']: ws['title']
            for ws in tk.get_action('workflow_state_list')(context, {
                'all_fields': True
            })
        }
        for record in page_results:
            record['workflow_state'] = workflow_states.get(
                record['workflow_state_id'], '')

        tk.c.page = helpers.Page(
            collection=global_results,
            page=page,
            url=tk.h.pager_url,
            items_per_page=limit,
        )

        tk.c.page.items = page_results
        return tk.render('metadata_collection/read.html')
예제 #18
0
class GroupController(base.BaseController):

    group_type = 'group'

    ## hooks for subclasses

    def _group_form(self, group_type=None):
        return lookup_group_plugin(group_type).group_form()

    def _form_to_db_schema(self, group_type=None):
        return 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)'''
        return lookup_group_plugin(group_type).db_to_form_schema()

    def _setup_template_variables(self, context, data_dict, group_type=None):
        return lookup_group_plugin(group_type).\
            setup_template_variables(context, data_dict)

    def _new_template(self, group_type):
        return lookup_group_plugin(group_type).new_template()

    def _index_template(self, group_type):
        return lookup_group_plugin(group_type).index_template()

    def _about_template(self, group_type):
        return lookup_group_plugin(group_type).about_template()

    def _read_template(self, group_type):
        return lookup_group_plugin(group_type).read_template()

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

    def _edit_template(self, group_type):
        return lookup_group_plugin(group_type).edit_template()

    def _activity_template(self, group_type):
        return lookup_group_plugin(group_type).activity_template()

    def _admins_template(self, group_type):
        return lookup_group_plugin(group_type).admins_template()

    def _bulk_process_template(self, group_type):
        return lookup_group_plugin(group_type).bulk_process_template()

    ## end hooks
    def _replace_group_org(self, string):
        ''' substitute organization for group if this is an org'''
        if self.group_type == 'organization':
            string = re.sub('^group', 'organization', string)
        return string

    def _action(self, action_name):
        ''' select the correct group/org action '''
        return get_action(self._replace_group_org(action_name))

    def _check_access(self, action_name, *args, **kw):
        ''' select the correct group/org check_access '''
        return check_access(self._replace_group_org(action_name), *args, **kw)

    def _render_template(self, template_name):
        ''' render the correct group/org template '''
        return render(self._replace_group_org(template_name))

    def _redirect_to(self, *args, **kw):
        ''' wrapper to ensue the correct controller is used '''
        if self.group_type == 'organization' and 'controller' in kw:
            kw['controller'] = 'organization'
        return h.redirect_to(*args, **kw)

    def _url_for(self, *args, **kw):
        ''' wrapper to ensue the correct controller is used '''
        if self.group_type == 'organization' and 'controller' in kw:
            kw['controller'] = 'organization'
        return h.url_for(*args, **kw)

    def _guess_group_type(self, expecting_name=False):
        """
            Guess the type of group from the URL handling the case
            where there is a prefix on the URL (such as /data/organization)
        """
        parts = [x for x in request.path.split('/') if x]

        idx = -1
        if expecting_name:
            idx = -2

        gt = parts[idx]
        if gt == 'group':
            gt = None

        return gt

    def index(self):
        group_type = self._guess_group_type()

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

        q = c.q = request.params.get('q', '')
        data_dict = {'all_fields': True, 'q': q}
        sort_by = c.sort_by_selected = request.params.get('sort')
        if sort_by:
            data_dict['sort'] = sort_by
        try:
            self._check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # pass user info to context as needed to view private datasets of
        # orgs correctly
        if c.userobj:
            context['user_id'] = c.userobj.id
            context['user_is_admin'] = c.userobj.sysadmin

        results = self._action('group_list')(context, data_dict)

        c.page = h.Page(collection=results,
                        page=request.params.get('page', 1),
                        url=h.pager_url,
                        items_per_page=21)
        return render(self._index_template(group_type))

    def read(self, id, limit=20):
        group_type = self._get_group_type(id.split('@')[0])
        if group_type != self.group_type:
            abort(404, _('Incorrect group type'))

        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'schema': self._db_to_form_schema(group_type=group_type),
            'for_view': True
        }
        data_dict = {'id': id}

        # unicode format (decoded from utf8)
        q = c.q = request.params.get('q', '')

        try:
            # Do not query for the group datasets when dictizing, as they will
            # be ignored and get requested on the controller anyway
            context['include_datasets'] = False
            c.group_dict = self._action('group_show')(context, data_dict)
            c.group = context['group']
        except NotFound:
            abort(404, _('Group not found'))
        except NotAuthorized:
            abort(401, _('Unauthorized to read group %s') % id)

        self._read(id, limit)
        return render(self._read_template(c.group_dict['type']))

    def _read(self, id, limit):
        ''' This is common code used by both read and bulk_process'''
        group_type = self._get_group_type(id.split('@')[0])
        context = {
            'model': model,
            'session': model.Session,
            'user': c.user or c.author,
            'schema': self._db_to_form_schema(group_type=group_type),
            'for_view': True,
            'extras_as_string': True
        }

        q = c.q = request.params.get('q', '')
        # Search within group
        if c.group_dict.get('is_organization'):
            q += ' owner_org:"%s"' % c.group_dict.get('id')
        else:
            q += ' groups:"%s"' % c.group_dict.get('name')

        c.description_formatted = h.render_markdown(
            c.group_dict.get('description'))

        context['return_query'] = True

        # c.group_admins is used by CKAN's legacy (Genshi) templates only,
        # if we drop support for those then we can delete this line.
        c.group_admins = new_authz.get_group_or_org_admin_ids(c.group.id)

        try:
            page = int(request.params.get('page', 1))
        except ValueError, e:
            abort(400, ('"page" parameter must be an integer'))

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']
        #sort_by = request.params.get('sort', 'name asc')
        sort_by = request.params.get('sort', None)

        def search_url(params):
            if group_type == 'organization':
                if c.action == 'bulk_process':
                    url = self._url_for(controller='organization',
                                        action='bulk_process',
                                        id=id)
                else:
                    url = self._url_for(controller='organization',
                                        action='read',
                                        id=id)
            else:
                url = self._url_for(controller='group', action='read', id=id)
            params = [
                (k, v.encode('utf-8') if isinstance(v, basestring) else str(v))
                for k, v in params
            ]
            return url + u'?' + urlencode(params)

        def drill_down_url(**by):
            return h.add_url_param(alternative_url=None,
                                   controller='group',
                                   action='read',
                                   extras=dict(id=c.group_dict.get('name')),
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key,
                                      value=value,
                                      replace=replace,
                                      controller='group',
                                      action='read',
                                      extras=dict(id=c.group_dict.get('name')))

        c.remove_field = remove_field

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params)

        try:
            c.fields = []
            search_extras = {}
            for (param, value) in request.params.items():
                if not param in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        q += ' %s: "%s"' % (param, value)
                    else:
                        search_extras[param] = value

            fq = 'capacity:"public"'
            user_member_of_orgs = [
                org['id'] for org in h.organizations_available('read')
            ]

            if (c.group and c.group.id in user_member_of_orgs):
                fq = ''
                context['ignore_capacity_check'] = True

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
                'groups': _('Groups'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses')
            }

            for facet in g.facets:
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            for plugin in plugins.PluginImplementations(plugins.IFacets):
                if self.group_type == 'organization':
                    facets = plugin.organization_facets(
                        facets, self.group_type, None)
                else:
                    facets = plugin.group_facets(facets, self.group_type, None)

            if 'capacity' in facets and (self.group_type != 'organization'
                                         or not user_member_of_orgs):
                del facets['capacity']

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq,
                'facet.field': facets.keys(),
                'rows': limit,
                'sort': sort_by,
                'start': (page - 1) * limit,
                'extras': search_extras
            }

            query = get_action('package_search')(context, data_dict)

            c.page = h.Page(collection=query['results'],
                            page=page,
                            url=pager_url,
                            item_count=query['count'],
                            items_per_page=limit)

            c.group_dict['package_count'] = query['count']
            c.facets = query['facets']
            maintain.deprecate_context_item('facets',
                                            'Use `c.search_facets` instead.')

            c.search_facets = query['search_facets']
            c.search_facets_limits = {}
            for facet in c.facets.keys():
                limit = int(
                    request.params.get('_%s_limit' % facet,
                                       g.facets_default_number))
                c.search_facets_limits[facet] = limit
            c.page.items = query['results']

            c.sort_by_selected = sort_by

        except search.SearchError, se:
            log.error('Group search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.page = h.Page(collection=[])
예제 #19
0
    def list(self):
        format = request.params.get('format', '')
        if format == 'atom':
            # Generate and return Atom 1.0 document.
            from webhelpers.feedgenerator import Atom1Feed
            feed = Atom1Feed(
                title=_(u'CKAN Repository Revision History'),
                link=h.url_for(controller='revision', action='list', id=''),
                description=_(u'Recent changes to the CKAN repository.'),
                language=text_type(get_lang()),
            )
            # TODO: make this configurable?
            # we do not want the system to fall over!
            maxresults = 200
            try:
                dayHorizon = int(request.params.get('days', 5))
            except:
                dayHorizon = 5
            ourtimedelta = timedelta(days=-dayHorizon)
            since_when = datetime.now() + ourtimedelta
            revision_query = model.repo.history()
            revision_query = revision_query.filter(
                model.Revision.timestamp >= since_when).filter(
                    model.Revision.id != None)
            revision_query = revision_query.limit(maxresults)
            for revision in revision_query:
                package_indications = []
                revision_changes = model.repo.list_changes(revision)
                resource_revisions = revision_changes[model.Resource]
                package_extra_revisions = revision_changes[model.PackageExtra]
                for package in revision.packages:
                    if not package:
                        # package is None sometimes - I don't know why,
                        # but in the meantime while that is fixed,
                        # avoid an exception here
                        continue
                    if package.private:
                        continue
                    number = len(package.all_revisions)
                    package_revision = None
                    count = 0
                    for pr in package.all_revisions:
                        count += 1
                        if pr.revision.id == revision.id:
                            package_revision = pr
                            break
                    if package_revision and package_revision.state == \
                            model.State.DELETED:
                        transition = 'deleted'
                    elif package_revision and count == number:
                        transition = 'created'
                    else:
                        transition = 'updated'
                        for resource_revision in resource_revisions:
                            if resource_revision.package_id == package.id:
                                transition += ':resources'
                                break
                        for package_extra_revision in package_extra_revisions:
                            if package_extra_revision.package_id == \
                                    package.id:
                                if package_extra_revision.key == \
                                        'date_updated':
                                    transition += ':date_updated'
                                    break
                    indication = "%s:%s" % (package.name, transition)
                    package_indications.append(indication)
                pkgs = u'[%s]' % ' '.join(package_indications)
                item_title = u'r%s ' % (revision.id)
                item_title += pkgs
                if revision.message:
                    item_title += ': %s' % (revision.message or '')
                item_link = h.url_for(controller='revision',
                                      action='read',
                                      id=revision.id)
                item_description = _('Datasets affected: %s.\n') % pkgs
                item_description += '%s' % (revision.message or '')
                item_author_name = revision.author
                item_pubdate = revision.timestamp
                feed.add_item(
                    title=item_title,
                    link=item_link,
                    description=item_description,
                    author_name=item_author_name,
                    pubdate=item_pubdate,
                )
            feed.content_type = 'application/atom+xml'
            return feed.writeString('utf-8')
        else:
            query = model.Session.query(model.Revision)
            revs = query.limit(20).all()
            filtered_revs = []
            for rev in list(revs):
                private_rev = False
                for pkg in rev.packages:
                    if pkg.private:
                        private_rev = True
                        break
                if not private_rev:
                    filtered_revs.append(rev)

            c.page = h.Page(collection=filtered_revs,
                            page=h.get_page_number(request.params),
                            url=h.pager_url,
                            items_per_page=20)
            return base.render('revision/list.html')
예제 #20
0
    def search(self):
        custom_base.g_analitics()
        from ckan.lib.search import SearchError

        package_type = self._guess_package_type()

        try:
            context = {'model': model, 'user': c.user or c.author,
                       'auth_user_obj': c.userobj}
            check_access('site_read', context)
        except NotAuthorized:
            abort(401, _('Not authorized to see this page'))

        # unicode format (decoded from utf8)
        q = c.q = request.params.get('q', u'')
        c.query_error = False
        page = self._get_page_number(request.params)

        limit = g.datasets_per_page

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']

        def drill_down_url(alternative_url=None, **by):
            return h.add_url_param(alternative_url=alternative_url,
                                   controller='package', action='search',
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key, value=value, replace=replace,
                                      controller='package', action='search')

        c.remove_field = remove_field

        sort_by = request.params.get('sort', None)
        params_nosort = [(k, v) for k, v in params_nopage if k != 'sort']

        def _sort_by(fields):
            """
            Sort by the given list of fields.

            Each entry in the list is a 2-tuple: (fieldname, sort_order)

            eg - [('metadata_modified', 'desc'), ('name', 'asc')]

            If fields is empty, then the default ordering is used.
            """
            params = params_nosort[:]

            if fields:
                sort_string = ', '.join('%s %s' % f for f in fields)
                params.append(('sort', sort_string))
            return search_url(params, package_type)

        c.sort_by = _sort_by
        if not sort_by:
            c.sort_by_fields = []
        else:
            c.sort_by_fields = [field.split()[0]
                                for field in sort_by.split(',')]

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return search_url(params, package_type)

        c.search_url_params = urlencode(_encode_params(params_nopage))

        try:
            c.fields = []
            # c.fields_grouped will contain a dict of params containing
            # a list of values eg {'tags':['tag1', 'tag2']}
            c.fields_grouped = {}
            search_extras = {}
            fq = ''
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        fq += ' %s:"%s"' % (param, value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

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

            if package_type and package_type != 'dataset':
                # Only show datasets of this particular type
                fq += ' +dataset_type:{type}'.format(type=package_type)
            else:
                # Unless changed via config options, don't show non standard
                # dataset types on the default search page
                if not asbool(
                        config.get('ckan.search.show_all_types', 'False')):
                    fq += ' +dataset_type:dataset'

            facets = OrderedDict()

            default_facet_titles = {
                'organization': _('Organizations'),
              #  'groups': _('Groups'),
                'tags': _('Tags'),
                'res_format': _('Formats'),
                'license_id': _('Licenses'),
                }

            #remove the group facet from search
            if 'groups' in g.facets:
                g.facets.remove('groups')

            for facet in g.facets:
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            for plugin in p.PluginImplementations(p.IFacets):
                facets = plugin.dataset_facets(facets, package_type)

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq.strip(),
                'facet.field': facets.keys(),
                'rows': limit,
                'start': (page - 1) * limit,
                'sort': sort_by,
                'extras': search_extras
            }

            query = get_action('package_search')(context, data_dict)
            c.sort_by_selected = query['sort']

            c.page = h.Page(
                collection=query['results'],
                page=page,
                url=pager_url,
                item_count=query['count'],
                items_per_page=limit
            )
            c.facets = query['facets']
            c.search_facets = query['search_facets']
            c.page.items = query['results']
        except SearchError, se:
            log.error('Dataset search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.search_facets = {}
            c.page = h.Page(collection=[])
예제 #21
0
    def _add_dataset_search(self, experience_id, experience_name):
        '''
        Search logic for discovering datasets to add to a experience.
        '''

        from ckan.lib.search import SearchError

        package_type = 'dataset'

        # unicode format (decoded from utf8)
        q = c.q = request.params.get('q', u'')
        c.query_error = False
        if p.toolkit.check_ckan_version(min_version='2.5.0', max_version='2.5.3'):
            page = self._get_page_number(request.params)
        else:
            page = h.get_page_number(request.params)

        limit = int(config.get('ckan.datasets_per_page', 20))

        # most search operations should reset the page counter:
        params_nopage = [(k, v) for k, v in request.params.items()
                         if k != 'page']

        def drill_down_url(alternative_url=None, **by):
            return h.add_url_param(alternative_url=alternative_url,
                                   controller='package', action='search',
                                   new_params=by)

        c.drill_down_url = drill_down_url

        def remove_field(key, value=None, replace=None):
            return h.remove_url_param(key, value=value, replace=replace,
                                      controller='package', action='search')

        c.remove_field = remove_field

        sort_by = request.params.get('sort', None)
        params_nosort = [(k, v) for k, v in params_nopage if k != 'sort']

        def _sort_by(fields):
            """
            Sort by the given list of fields.

            Each entry in the list is a 2-tuple: (fieldname, sort_order)

            eg - [('metadata_modified', 'desc'), ('name', 'asc')]

            If fields is empty, then the default ordering is used.
            """
            params = params_nosort[:]

            if fields:
                sort_string = ', '.join('%s %s' % f for f in fields)
                params.append(('sort', sort_string))
            return self._search_url(params, experience_name)

        c.sort_by = _sort_by
        if sort_by is None:
            c.sort_by_fields = []
        else:
            c.sort_by_fields = [field.split()[0]
                                for field in sort_by.split(',')]

        def pager_url(q=None, page=None):
            params = list(params_nopage)
            params.append(('page', page))
            return self._search_url(params, experience_name)

        c.search_url_params = urlencode(_encode_params(params_nopage))

        try:
            c.fields = []
            # c.fields_grouped will contain a dict of params containing
            # a list of values eg {'tags':['tag1', 'tag2']}
            c.fields_grouped = {}
            search_extras = {}
            fq = ''
            for (param, value) in request.params.items():
                if param not in ['q', 'page', 'sort'] \
                        and len(value) and not param.startswith('_'):
                    if not param.startswith('ext_'):
                        c.fields.append((param, value))
                        fq += ' %s:"%s"' % (param, value)
                        if param not in c.fields_grouped:
                            c.fields_grouped[param] = [value]
                        else:
                            c.fields_grouped[param].append(value)
                    else:
                        search_extras[param] = value

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

            if package_type and package_type != 'dataset':
                # Only show datasets of this particular type
                fq += ' +dataset_type:{type}'.format(type=package_type)
            else:
                # Unless changed via config options, don't show non standard
                # dataset types on the default search page
                if not tk.asbool(config.get('ckan.search.show_all_types',
                                            'False')):
                    fq += ' +dataset_type:dataset'

            # Only search for packages that aren't already associated with the
            # Experience
            associated_package_ids = ExperiencePackageAssociation.get_package_ids_for_experience(experience_id)
            # flatten resulting list to space separated string
            if associated_package_ids:
                associated_package_ids_str = \
                    ' OR '.join([id[0] for id in associated_package_ids])
                fq += ' !id:({0})'.format(associated_package_ids_str)

            facets = OrderedDict()

            default_facet_titles = {
                    'organization': _('Organizations'),
                    'groups': _('Groups'),
                    'tags': _('Tags'),
                    'res_format': _('Formats'),
                    'license_id': _('Licenses'),
                    }

            # for CKAN-Versions that do not provide the facets-method from
            # helper-context, import facets from ckan.common
            if hasattr(h, 'facets'):
                current_facets = h.facets()
            else:
                from ckan.common import g
                current_facets = g.facets

            for facet in current_facets:
                if facet in default_facet_titles:
                    facets[facet] = default_facet_titles[facet]
                else:
                    facets[facet] = facet

            # Facet titles
            for plugin in p.PluginImplementations(p.IFacets):
                facets = plugin.dataset_facets(facets, package_type)

            c.facet_titles = facets

            data_dict = {
                'q': q,
                'fq': fq.strip(),
                'facet.field': facets.keys(),
                'rows': limit,
                'start': (page - 1) * limit,
                'sort': sort_by,
                'extras': search_extras
            }

            query = get_action('package_search')(context, data_dict)
            c.sort_by_selected = query['sort']

            c.page = h.Page(
                collection=query['results'],
                page=page,
                url=pager_url,
                item_count=query['count'],
                items_per_page=limit
            )
            c.facets = query['facets']
            c.search_facets = query['search_facets']
            c.page.items = query['results']
        except SearchError, se:
            log.error('Dataset search error: %r', se.args)
            c.query_error = True
            c.facets = {}
            c.search_facets = {}
            c.page = h.Page(collection=[])
예제 #22
0
파일: group.py 프로젝트: mediasuitenz/ckan
def _read(id, limit, group_type):
    u''' This is common code used by both read and bulk_process'''
    extra_vars = {}
    context = {
        u'model': model,
        u'session': model.Session,
        u'user': g.user,
        u'schema': _db_to_form_schema(group_type=group_type),
        u'for_view': True,
        u'extras_as_string': True
    }

    q = request.params.get(u'q', u'')

    # TODO: Remove
    # ckan 2.9: Adding variables that were removed from c object for
    # compatibility with templates in existing extensions
    g.q = q

    # Search within group
    if g.group_dict.get(u'is_organization'):
        fq = u' owner_org:"%s"' % g.group_dict.get(u'id')
    else:
        fq = u' groups:"%s"' % g.group_dict.get(u'name')

    extra_vars["q"] = q

    g.description_formatted = \
        h.render_markdown(g.group_dict.get(u'description'))

    context['return_query'] = True

    page = h.get_page_number(request.params)

    # most search operations should reset the page counter:
    params_nopage = [(k, v) for k, v in request.params.items() if k != u'page']
    sort_by = request.params.get(u'sort', None)

    def search_url(params):
        controller = lookup_group_controller(group_type)
        action = u'bulk_process' if getattr(
            g, u'action', u'') == u'bulk_process' else u'read'
        url = h.url_for(u'.'.join([controller, action]), id=id)
        params = [
            (k, v.encode(u'utf-8') if isinstance(v, string_types) else str(v))
            for k, v in params
        ]
        return url + u'?' + urlencode(params)

    def drill_down_url(**by):
        return h.add_url_param(alternative_url=None,
                               controller=u'group',
                               action=u'read',
                               extras=dict(id=g.group_dict.get(u'name')),
                               new_params=by)

    extra_vars["drill_down_url"] = drill_down_url

    def remove_field(key, value=None, replace=None):
        controller = lookup_group_controller(group_type)
        return h.remove_url_param(key,
                                  value=value,
                                  replace=replace,
                                  controller=controller,
                                  action=u'read',
                                  extras=dict(id=g.group_dict.get(u'name')))

    extra_vars["remove_field"] = remove_field

    def pager_url(q=None, page=None):
        params = list(params_nopage)
        params.append((u'page', page))
        return search_url(params)

    details = _get_search_details()
    extra_vars[u'fields'] = details[u'fields']
    extra_vars[u'fields_grouped'] = details[u'fields_grouped']
    fq += details[u'fq']
    search_extras = details[u'search_extras']

    # TODO: Remove
    # ckan 2.9: Adding variables that were removed from c object for
    # compatibility with templates in existing extensions
    g.fields = extra_vars[u'fields']
    g.fields_grouped = extra_vars[u'fields_grouped']

    facets = OrderedDict()

    default_facet_titles = {
        u'organization': _(u'Organizations'),
        u'groups': _(u'Groups'),
        u'tags': _(u'Tags'),
        u'res_format': _(u'Formats'),
        u'license_id': _(u'Licenses')
    }

    for facet in h.facets():
        if facet in default_facet_titles:
            facets[facet] = default_facet_titles[facet]
        else:
            facets[facet] = facet

    # Facet titles
    facets = _update_facet_titles(facets, group_type)

    extra_vars["facet_titles"] = facets

    data_dict = {
        u'q': q,
        u'fq': fq,
        u'include_private': True,
        u'facet.field': list(facets.keys()),
        u'rows': limit,
        u'sort': sort_by,
        u'start': (page - 1) * limit,
        u'extras': search_extras
    }

    context_ = dict((k, v) for (k, v) in context.items() if k != u'schema')
    try:
        query = get_action(u'package_search')(context_, data_dict)
    except search.SearchError as se:
        log.error(u'Group search error: %r', se.args)
        extra_vars["query_error"] = True
        extra_vars["page"] = h.Page(collection=[])
    else:
        extra_vars["page"] = h.Page(collection=query['results'],
                                    page=page,
                                    url=pager_url,
                                    item_count=query['count'],
                                    items_per_page=limit)

        # TODO: Remove
        # ckan 2.9: Adding variables that were removed from c object for
        # compatibility with templates in existing extensions
        g.group_dict['package_count'] = query['count']

        extra_vars["search_facets"] = g.search_facets = query['search_facets']
        extra_vars["search_facets_limits"] = g.search_facets_limits = {}
        for facet in g.search_facets.keys():
            limit = int(
                request.params.get(u'_%s_limit' % facet,
                                   config.get(u'search.facets.default', 10)))
            g.search_facets_limits[facet] = limit
        extra_vars["page"].items = query['results']

        extra_vars["sort_by_selected"] = sort_by

    # TODO: Remove
    # ckan 2.9: Adding variables that were removed from c object for
    # compatibility with templates in existing extensions
    g.facet_titles = facets
    g.page = extra_vars["page"]

    extra_vars["group_type"] = group_type
    _setup_template_variables(context, {u'id': id}, group_type=group_type)
    return extra_vars
예제 #23
0
    def setup_template_variables(self, context, data_dict):
        """Setup variables available to templates"""

        self.datastore_fields = self._get_datastore_fields(
            data_dict['resource']['id'])

        field_separator = config.get("ckanext.gallery.field_separator", ';')
        records_per_page = config.get("ckanext.gallery.records_per_page", 30)

        current_page = request.params.get('page', 1)

        image_field = data_dict['resource_view'].get('image_field')
        gallery_title_field = data_dict['resource_view'].get(
            'gallery_title_field', None)
        modal_title_field = data_dict['resource_view'].get(
            'modal_title_field', None)

        thumbnail_params = data_dict['resource_view'].get(
            'thumbnail_params', None)
        thumbnail_field = data_dict['resource_view'].get(
            'thumbnail_field', None)

        image_list = []
        records = []
        item_count = 0

        # Only try and load images, if an image field has been selected
        if image_field:

            offset = (int(current_page) - 1) * records_per_page

            # We only want to get records that have both the image field populated
            # So add filters to the datastore search params
            params = {
                'resource_id': data_dict['resource']['id'],
                'limit': records_per_page,
                'offset': offset,
                'filters': {
                    image_field: IS_NOT_NULL
                }
            }

            # Add filters from request
            filter_str = request.params.get('filters')
            if filter_str:
                for f in filter_str.split('|'):
                    try:
                        (name, value) = f.split(':')
                        params['filters'][name] = value

                    except ValueError:
                        pass

            # Full text filter
            fulltext = request.params.get('q')
            if fulltext:
                params['q'] = fulltext

            context = {
                'model': model,
                'session': model.Session,
                'user': c.user or c.author
            }
            data = toolkit.get_action('datastore_search')(context, params)

            item_count = data.get('total', 0)
            records = data['records']

            for record in data['records']:

                try:
                    images = record.get(image_field,
                                        None).split(field_separator)
                except AttributeError:
                    pass
                else:
                    # Only add if we have an image
                    if images:

                        gallery_title = record.get(gallery_title_field, None)
                        modal_title = record.get(modal_title_field, None)
                        thumbnails = record.get(thumbnail_field,
                                                None).split(field_separator)

                        for i, image in enumerate(images):

                            image = image.strip()

                            if thumbnails:
                                try:
                                    thumbnail = thumbnails[i]
                                except IndexError:
                                    # If we don't have a thumbnail with the same index
                                    # Use the first thumbnail image
                                    thumbnail = thumbnails[0]

                                thumbnail = thumbnail.strip()

                                # If we have thumbnail params, add them here
                                if thumbnail_params:
                                    q = '&' if '?' in thumbnail else '?'
                                    thumbnail += q + thumbnail_params

                            image_list.append({
                                'url': image,
                                'thumbnail': thumbnail,
                                'gallery_title': gallery_title,
                                'modal_title': modal_title,
                                'record_id': record['_id']
                            })

        page_params = {
            'collection': records,
            'page': current_page,
            'url': self.pager_url,
            'items_per_page': records_per_page,
            'item_count': item_count,
        }

        # Add filter params to page links
        for key in ['q', 'filters']:
            value = request.params.get(key)
            if value:
                page_params[key] = value

        page = h.Page(**page_params)

        return {
            'images': image_list,
            'datastore_fields': self.datastore_fields,
            'defaults': {},
            'resource_id': data_dict['resource']['id'],
            'package_name': data_dict['package']['name'],
            'page': page
        }