Source code for gws.common.search.runner

import gws
import gws.types as t

from . import provider


class _LimitExceeded(Exception):
    pass

_DEFAULT_LIMIT = 10 * 1000


[docs]def run(req, args: t.SearchArgs) -> t.List[t.IFeature]: total_limit = args.limit or _DEFAULT_LIMIT used_layer_ids = set() features: t.List[t.IFeature] = [] prov: provider.Object dbg = [ f'SEARCH ARGS', f"axis={args.axis}", f"bounds={args.bounds}", f"filter={args.filter}", f"keyword={args.keyword}", f"layers={[p.uid for p in args.layers]}", f"limit={args.limit}", f"params={args.params}", f"project={args.project.uid if args.project else None}", f"resolution={args.resolution}", f"shapes={[p.props for p in (args.shapes or [])]}", f"tolerance={args.tolerance}", ] gws.p(dbg) try: if args.layers: for layer in args.layers: used_layer_ids.add(layer.uid) for prov in layer.get_children('gws.ext.search.provider'): _run(req, layer, prov, args, total_limit, features) for layer in args.layers: for par in _parents(layer): if par.uid not in used_layer_ids: used_layer_ids.add(par.uid) gws.log.debug(f'search parent={par.uid} for={layer.uid}') for prov in par.get_children('gws.ext.search.provider'): _run(req, par, prov, args, total_limit, features) if args.project: for prov in args.project.get_children('gws.ext.search.provider'): _run(req, None, prov, args, total_limit, features) except _LimitExceeded: pass return features[:total_limit]
def _parents(layer: t.ILayer) -> t.List[t.ILayer]: ps = [] p = layer.parent while p.is_a('gws.ext.layer'): ps.append(t.cast(t.ILayer, p)) p = p.parent return ps def _run(req, layer: t.Optional[t.ILayer], prov: provider.Object, args: t.SearchArgs, total_limit, features): args.limit = total_limit - len(features) if args.limit <= 0: raise _LimitExceeded() gws.log.debug( 'SEARCH_BEGIN: prov=%r layer=%r limit=%d' % (gws.get(prov, 'uid'), gws.get(layer, 'uid'), args.limit)) if not req.user.can_use(prov): gws.log.debug('SEARCH_END: NO_ACCESS') return if not prov.can_run(args): gws.log.debug(f'SEARCH_END: N_A') return try: fs: t.List[t.IFeature] = prov.run(layer, args) or [] except Exception: gws.log.exception() gws.log.debug('SEARCH_FAILED') return tt = prov.templates or (layer.templates if layer else None) dm = prov.data_model or (layer.data_model if layer else None) for f in fs: f.layer = layer f.templates = tt f.data_model = dm gws.log.debug('SEARCH_END, found=%r', len(fs)) features.extend(fs)