Exemplo n.º 1
0
 def query_cancelled_error(self, info, query, err, err_title, template,
                           template_kwds):
     ctx = ctx_proc_userdata()
     flash_error(
         'The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.'
         % ctx['feedbackpage'])
     info['err'] = str(err)
     info['query'] = dict(query)
     return render_template(template,
                            info=info,
                            title=self.err_title,
                            **template_kwds)
Exemplo n.º 2
0
def search(info):
    """ query processing for Sato-Tate groups -- returns rendered results page """
    if 'jump' in info:
        return redirect(url_for('.by_label', label=info['jump']), 301)
    if 'label' in info:
        return redirect(url_for('.by_label', label=info['label']), 301)
    search_type = info.get("search_type", info.get("hst", "List"))
    template_kwds = {
        'bread': [('Sato-Tate Groups', url_for('.index')),
                  ('Search Results', '.')],
        'credit': credit_string,
        'learnmore': learnmore_list()
    }
    title = 'Sato-Tate Group Search Results'
    err_title = 'Sato-Tate Groups Search Input Error'
    count = parse_count(info, 50)
    start = parse_start(info)
    # if user clicked refine search always restart at 0
    if 'refine' in info:
        start = 0
    ratonly = (info.get('include_irrational', 'no').strip().lower() == 'no')
    if search_type == "Random" and not ratonly:
        info['err'] = err = 'Cannot select random irrational Sato-Tate group'
        flash_error(err)
        return render_template('st_results.html',
                               info=info,
                               title=err_title,
                               **template_kwds)
    query = {'rational': True} if ratonly else {}
    try:
        parse_ints(info, query, 'weight', 'weight')
        if 'weight' in query:
            weight_list = parse_ints_to_list_flash(info.get('weight'),
                                                   'weight')
        parse_ints(info, query, 'degree', 'degree')
        if 'degree' in query:
            degree_list = parse_ints_to_list_flash(info.get('degree'),
                                                   'degree')
        if info.get('identity_component'):
            query['identity_component'] = info['identity_component']
        parse_ints(info, query, 'components', 'components')
        if 'components' in query:
            components_list = parse_ints_to_list_flash(info.get('components'),
                                                       'components')
        parse_rational(info, query, 'trace_zero_density', 'trace zero density')
    except ValueError as err:
        info['err'] = str(err)
        return render_template('st_results.html',
                               info=info,
                               title=err_title,
                               **template_kwds)

    # Check mu(n) groups first (these are not stored in the database)
    results = []
    if ((not 'weight' in query or 0 in weight_list)
            and (not 'degree' in query or 1 in degree_list)
            and (not 'identity_component' in query
                 or query['identity_component'] == 'SO(1)')
            and (not 'trace_zero_density' in query
                 or query['trace_zero_density'] == '0')):
        if not 'components' in query:
            components_list = range(1, 3 if ratonly else start + count + 1)
        elif ratonly:
            components_list = [n for n in range(1, 3) if n in components_list]
        nres = len(
            components_list) if 'components' in query or ratonly else INFINITY
        if search_type == "Random" and nres > 0:
            # Need to return mu(1) and mu(2) sometimes
            otherlen = db.gps_sato_tate.count(query)
            r = ZZ.random_element(nres + otherlen)
            if r < nres:
                return redirect(
                    url_for(".by_label", label="0.1.%d" % components_list[r]),
                    307)
        for n in itertools.islice(components_list, start, start + count):
            results.append(mu_info(n))
    else:
        nres = 0

    if 'result_count' in info:
        nres += db.gps_sato_tate.count(query)
        return jsonify({"nres": str(nres)})
    if search_type == "Random":
        label = db.gps_sato_tate.random(query, "label")
        if label is not None:
            return redirect(url_for(".by_label", label=label), 307)

    # Now lookup other (rational) ST groups in database
    if nres != INFINITY:
        start2 = start - nres if start > nres else 0
        proj = [
            'label', 'weight', 'degree', 'real_dimension',
            'identity_component', 'name', 'pretty', 'components',
            'component_group', 'trace_zero_density', 'moments'
        ]
        try:
            res = db.gps_sato_tate.search(query,
                                          proj,
                                          limit=max(count - len(results), 0),
                                          offset=start2,
                                          info=info)
        except QueryCanceledError as err:
            ctx = ctx_proc_userdata()
            flash_error(
                'The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.'
                % ctx['feedbackpage'])
            info['err'] = str(err)
            return render_template('st_results.html',
                                   info=info,
                                   title=err_title,
                                   **template_kwds)
        info['number'] += nres
        if start < info['number'] and len(results) < count:
            for v in res:
                v['identity_component'] = st0_pretty(v['identity_component'])
                v['component_group'] = sg_pretty(v['component_group'])
                v['trace_moments'] = trace_moments(v['moments'])
                results.append(v)
    else:
        info['number'] = 'infinity'
    info['start'] = start
    info['count'] = count

    info['st0_list'] = st0_list
    info['st0_dict'] = st0_dict
    info['results'] = results
    info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label'])
    return render_template('st_results.html',
                           info=info,
                           title=title,
                           **template_kwds)
Exemplo n.º 3
0
def search(**args):
    """ query processing for Sato-Tate groups -- returns rendered results page """
    info = to_dict(args)
    if 'jump' in info:
        return redirect(url_for('.by_label', label=info['jump']), 301)
    if 'label' in info:
        return redirect(url_for('.by_label', label=info['label']), 301)
    template_kwds = {'bread':[('Sato-Tate Groups', url_for('.index')),('Search Results', '.')],
                     'credit':credit_string,
                     'learnmore':learnmore_list()}
    title = 'Sato-Tate Group Search Results'
    err_title = 'Sato-Tate Groups Search Input Error'
    count = parse_count(info, 25)
    start = parse_start(info)
    # if user clicked refine search always restart at 0
    if 'refine' in info:
        start = 0
    ratonly = True if info.get('rational_only','no').strip().lower() == 'yes' else False
    query = {'rational':True} if ratonly else {}
    try:
        parse_ints(info,query,'weight','weight')
        if 'weight' in query:
            weight_list = parse_ints_to_list_flash(info.get('weight'),'weight')
        parse_ints(info,query,'degree','degree')
        if 'degree' in query:
            degree_list = parse_ints_to_list_flash(info.get('degree'),'degree')
        if info.get('identity_component'):
            query['identity_component'] = info['identity_component']
        parse_ints(info,query,'components','components')
        if 'components' in query:
            components_list = parse_ints_to_list_flash(info.get('components'), 'components')
        parse_rational(info,query,'trace_zero_density','trace zero density')
    except ValueError as err:
        info['err'] = str(err)
        return render_template('st_results.html', info=info, title=err_title, **template_kwds)

    # Check mu(n) groups first (these are not stored in the database)
    results = []
    if (not 'weight' in query or 0 in weight_list) and \
       (not 'degree' in query or 1 in degree_list) and \
       (not 'identity_component' in query or query['identity_component'] == 'SO(1)') and \
       (not 'trace_zero_density' in query or query['trace_zero_density'] == '0'):
        if not 'components' in query:
            components_list = xrange(1,3 if ratonly else start+count+1)
        elif ratonly:
            components_list = [n for n in range(1,3) if n in components_list]
        nres = len(components_list) if 'components' in query or ratonly else INFINITY
        for n in itertools.islice(components_list,start,start+count):
            results.append(mu_info(n))
    else:
        nres = 0

    if 'result_count' in info:
        nres += db.gps_sato_tate.count(query)
        return jsonify({"nres":str(nres)})

    # Now lookup other (rational) ST groups in database
    if nres != INFINITY:
        start2 = start - nres if start > nres else 0
        proj = ['label','weight','degree','real_dimension','identity_component','name','pretty','components','component_group','trace_zero_density','moments']
        try:
            res = db.gps_sato_tate.search(query, proj, limit=max(count - len(results), 0), offset=start2, info=info)
        except QueryCanceledError as err:
            ctx = ctx_proc_userdata()
            flash_error('The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage'])
            info['err'] = str(err)
            return render_template('st_results.html', info=info, title=err_title, **template_kwds)
        info['number'] += nres
        if start < info['number'] and len(results) < count:
            for v in res:
                v['identity_component'] = st0_pretty(v['identity_component'])
                v['component_group'] = sg_pretty(v['component_group'])
                v['trace_moments'] = trace_moments(v['moments'])
                results.append(v)
    else:
        info['number'] = 'infinity'
        info['start'] = start
        info['count'] = count

    info['st0_list'] = st0_list
    info['st0_dict'] = st0_dict
    info['results'] = results
    info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label'])
    return render_template('st_results.html', info=info, title=title, **template_kwds)
Exemplo n.º 4
0
def search(info):
    """ query processing for Sato-Tate groups -- returns rendered results page """
    if 'jump' in info:
        return redirect(url_for('.by_label', label=info['jump']), 301)
    if 'label' in info:
        return redirect(url_for('.by_label', label=info['label']), 301)
    search_type = info.get("search_type", info.get("hst", "List"))
    template_kwds = {
        'bread': get_bread("Search results"),
        'credit': credit_string,
        'learnmore': learnmore_list()
    }
    title = 'Sato-Tate group search results'
    err_title = 'Sato-Tate group search input error'
    count = parse_count(info, 50)
    start = parse_start(info)
    # if user clicked refine search always restart at 0
    if 'refine' in info:
        start = 0
    ratonly = (info.get('include_irrational', 'no').strip().lower() == 'no')
    if search_type == "Random" and not ratonly:
        info['err'] = err = 'Cannot select random irrational Sato-Tate group'
        flash_error(err)
        return render_template('st_results.html',
                               info=info,
                               title=err_title,
                               **template_kwds)
    query = {'rational': True} if ratonly else {}
    try:
        parse_ints(info, query, 'weight', 'weight')
        if 'weight' in query:
            weight_list = parse_ints_to_list_flash(info.get('weight'),
                                                   'weight')
        parse_ints(info, query, 'degree', 'degree')
        if 'degree' in query:
            degree_list = parse_ints_to_list_flash(info.get('degree'),
                                                   'degree')
        if info.get('identity_component'):
            query['identity_component'] = info['identity_component']
        parse_ints(info, query, 'components', 'components')

        def refine_components(current, condition):
            if current is None:
                return condition
            return [x for x in condition if x in current]

        # The following are used to constraint which mu(n) will show up in search results
        components_list = None
        ommitted = set()
        if 'components' in query:
            components_list = parse_ints_to_list_flash(info.get('components'),
                                                       'components')
        parse_component_group(info, query)
        gps = query.get("component_group")
        if gps:
            if isinstance(gps, dict):
                gps = gps["$in"]
            else:
                gps = [gps]
            if not ratonly:
                cyclic_labels = set(
                    db.gps_small.search({"cyclic": True}, "label"))
            irrat = []
            for code in gps:
                if code in cyclics:
                    irrat.append(cyclics[code])
                elif re.match(cyclicre, code):
                    irrat.append(int(code[1:]))
                elif not ratonly and code in cyclic_labels:
                    irrat.append(int(code.split(".")[0]))
            components_list = refine_components(components_list, irrat)
        parse_rational(info, query, 'trace_zero_density', 'trace zero density')
        parse_ints(info, query, 'second_trace_moment')
        parse_ints(info, query, 'fourth_trace_moment')
        for name, ones in [('second_trace_moment', [1, 2]),
                           ('fourth_trace_moment', [1, 2, 4])]:
            if name in query:
                # E(x^2) for mu(1) and mu(2) are 1; others are 0
                # E(x^4) for mu(1), mu(2) and mu(4) are 1; others are 0
                E = parse_ints_to_list_flash(info.get(name),
                                             name.replace("_", " "))
                if 0 not in E:
                    components_list = refine_components(components_list, ones)
                if 1 not in E:
                    ommitted.update(ones)
        parse_ints(info, query, 'first_a2_moment')
        parse_bool(info, query, 'maximal')
        if "first_a2_moment" in query or query.get("maximal"):
            # mu(n) do not have a2 moments and none are maximal
            components_list = []
    except ValueError as err:
        info['err'] = str(err)
        return render_template('st_results.html',
                               info=info,
                               title=err_title,
                               **template_kwds)

    # Check mu(n) groups first (these are not stored in the database)
    results = []
    if ((not 'weight' in query or 0 in weight_list)
            and (not 'degree' in query or 1 in degree_list)
            and (not 'identity_component' in query
                 or query['identity_component'] == 'SO(1)')
            and (not 'trace_zero_density' in query
                 or query['trace_zero_density'] == '0')):
        nres = None
        if components_list is None:
            components_list = range(
                1, 3 if ratonly else (start + count + 1 + len(ommitted)))
            nres = None if ratonly else INFINITY
        elif ratonly:
            components_list = [n for n in range(1, 3) if n in components_list]
        components_list = [n for n in components_list if n not in ommitted]
        if nres is None:
            nres = len(components_list)
        if search_type == "Random" and nres > 0:
            # Need to return mu(1), mu(2) or mu(4) sometimes
            otherlen = db.gps_sato_tate.count(query)
            r = ZZ.random_element(nres + otherlen)
            if r < nres:
                return redirect(
                    url_for(".by_label", label="0.1.%d" % components_list[r]),
                    307)
        for n in itertools.islice(components_list, start, start + count):
            results.append(mu_info(n))
    else:
        nres = 0

    if 'result_count' in info:
        nres += db.gps_sato_tate.count(query)
        return jsonify({"nres": str(nres)})
    if search_type == "Random":
        label = db.gps_sato_tate.random(query, "label")
        if label is not None:
            return redirect(url_for(".by_label", label=label), 307)

    # Now lookup other (rational) ST groups in database
    if nres != INFINITY:
        start2 = start - nres if start > nres else 0
        proj = [
            'label', 'weight', 'degree', 'real_dimension',
            'identity_component', 'name', 'pretty', 'components',
            'component_group', 'trace_zero_density', 'moments'
        ]
        try:
            res = db.gps_sato_tate.search(query,
                                          proj,
                                          limit=max(count - len(results), 0),
                                          offset=start2,
                                          info=info)
        except QueryCanceledError as err:
            ctx = ctx_proc_userdata()
            flash_error(
                'The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.'
                % ctx['feedbackpage'])
            info['err'] = str(err)
            return render_template('st_results.html',
                                   info=info,
                                   title=err_title,
                                   **template_kwds)
        info['number'] += nres
        if start < info['number'] and len(results) < count:
            for v in res:
                v['identity_component'] = st0_pretty(v['identity_component'])
                v['component_group'] = sg_pretty(v['component_group'])
                v['trace_moments'] = trace_moments(v['moments'])
                results.append(v)
    else:
        info['number'] = 'infinity'
    info['start'] = start
    info['count'] = count

    info['st0_list'] = st0_list
    info['st0_dict'] = st0_dict
    info['results'] = results
    info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label'])
    return render_template('st_results.html',
                           info=info,
                           title=title,
                           **template_kwds)
Exemplo n.º 5
0
 def __call__(self, info, random=False):
     # If random is True, returns a random label
     info = to_dict(info,
                    exclude=['bread'
                             ])  # I'm not sure why this is required...
     for key, func in self.shortcuts.items():
         if info.get(key, '').strip():
             return func(info)
     query = {}
     template_kwds = {}
     for key in self.kwds:
         template_kwds[key] = info.get(key, self.kwds[key]())
     try:
         errpage = self.f(info, query)
     except ValueError as err:
         # Errors raised in parsing
         info['err'] = str(err)
         err_title = query.pop('__err_title__', self.err_title)
         return render_template(self.template,
                                info=info,
                                title=err_title,
                                **template_kwds)
     else:
         err_title = query.pop('__err_title__', self.err_title)
     if errpage is not None:
         return errpage
     sort = query.pop('__sort__', None)
     table = query.pop('__table__', self.table)
     # We want to pop __title__ even if overridden by info.
     title = query.pop('__title__', self.title)
     title = info.get('title', title)
     template = query.pop('__template__', self.template)
     if random:
         query.pop('__projection__', None)
     proj = query.pop('__projection__', self.projection)
     if 'result_count' in info:
         nres = table.count(query)
         return jsonify({"nres": str(nres)})
     count = parse_count(info, self.per_page)
     start = parse_start(info)
     try:
         if random:
             # Ignore __projection__: it's intended for searches
             label = table.random(query, projection=0)
             if label is None:
                 res = []
                 # ugh; we have to set these manually
                 info['query'] = dict(query)
                 info['number'] = 0
                 info['count'] = count
                 info['start'] = start
                 info['exact_count'] = True
             else:
                 return redirect(self.url_for_label(label), 307)
         else:
             res = table.search(query,
                                proj,
                                limit=count,
                                offset=start,
                                sort=sort,
                                info=info)
     except QueryCanceledError as err:
         ctx = ctx_proc_userdata()
         flash_error(
             'The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.'
             % ctx['feedbackpage'])
         info['err'] = str(err)
         info['query'] = dict(query)
         return render_template(self.template,
                                info=info,
                                title=self.err_title,
                                **template_kwds)
     else:
         try:
             if self.cleaners:
                 for v in res:
                     for name, func in self.cleaners.items():
                         v[name] = func(v)
             if self.postprocess is not None:
                 res = self.postprocess(res, info, query)
         except ValueError as err:
             # Errors raised in postprocessing
             flash_error(str(err))
             info['err'] = str(err)
             return render_template(self.template,
                                    info=info,
                                    title=err_title,
                                    **template_kwds)
         for key, func in self.longcuts.items():
             if info.get(key, '').strip():
                 return func(res, info, query)
         info['results'] = res
         return render_template(template,
                                info=info,
                                title=title,
                                **template_kwds)
Exemplo n.º 6
0
 def __call__(self, info, random=False):
     # If random is True, returns a random label
     info = to_dict(info,
                    exclude=['bread'
                             ])  # I'm not sure why this is required...
     for key, func in self.shortcuts.items():
         if info.get(key, '').strip():
             return func(info)
     query = {}
     template_kwds = {}
     for key in self.kwds:
         template_kwds[key] = info.get(key, self.kwds[key]())
     try:
         errpage = self.f(info, query)
     except ValueError as err:
         # Errors raised in parsing
         info['err'] = str(err)
         err_title = query.pop('__err_title__', self.err_title)
         return render_template(self.template,
                                info=info,
                                title=err_title,
                                **template_kwds)
     else:
         err_title = query.pop('__err_title__', self.err_title)
     if errpage is not None:
         return errpage
     sort = query.pop('__sort__', None)
     table = query.pop('__table__', self.table)
     # We want to pop __title__ even if overridden by info.
     title = query.pop('__title__', self.title)
     title = info.get('title', title)
     template = query.pop('__template__', self.template)
     if random:
         query.pop('__projection__', None)
     proj = query.pop('__projection__', self.projection)
     if 'result_count' in info:
         nres = table.count(query)
         return jsonify({"nres": str(nres)})
     count = parse_count(info, self.per_page)
     start = parse_start(info)
     try:
         split_ors = use_split_ors(info, query, self.split_ors, start,
                                   table)
         if random:
             # Ignore __projection__: it's intended for searches
             if split_ors:
                 queries = table._split_ors(query)
             else:
                 queries = [query]
             if len(queries) > 1:
                 # The following method won't produce a uniform distribution
                 # if there's overlap between queries.  But it's simple,
                 # and in many use cases (e.g. galois group for number fields)
                 # the subqueries are disjoint.
                 counts = [table.count(Q) for Q in queries]
                 pick = randrange(sum(counts))
                 accum = 0
                 for Q, cnt in zip(queries, counts):
                     accum += cnt
                     if pick < accum:
                         query = Q
                         break
             label = table.random(query, projection=0)
             if label is None:
                 res = []
                 # ugh; we have to set these manually
                 info['query'] = dict(query)
                 info['number'] = 0
                 info['count'] = count
                 info['start'] = start
                 info['exact_count'] = True
             else:
                 return redirect(self.url_for_label(label), 307)
         else:
             res = table.search(query,
                                proj,
                                limit=count,
                                offset=start,
                                sort=sort,
                                info=info,
                                split_ors=split_ors)
     except QueryCanceledError as err:
         ctx = ctx_proc_userdata()
         flash_error(
             'The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.'
             % ctx['feedbackpage'])
         info['err'] = str(err)
         info['query'] = dict(query)
         return render_template(self.template,
                                info=info,
                                title=self.err_title,
                                **template_kwds)
     else:
         try:
             if self.cleaners:
                 for v in res:
                     for name, func in self.cleaners.items():
                         v[name] = func(v)
             if self.postprocess is not None:
                 res = self.postprocess(res, info, query)
         except ValueError as err:
             # Errors raised in postprocessing
             flash_error(str(err))
             info['err'] = str(err)
             return render_template(self.template,
                                    info=info,
                                    title=err_title,
                                    **template_kwds)
         for key, func in self.longcuts.items():
             if info.get(key, '').strip():
                 return func(res, info, query)
         info['results'] = res
         return render_template(template,
                                info=info,
                                title=title,
                                **template_kwds)
Exemplo n.º 7
0
 def __call__(self, info, random=False):
     # If random is True, returns a random label
     info = to_dict(info, exclude =['bread']) # I'm not sure why this is required...
     for key, func in self.shortcuts.items():
         if info.get(key,'').strip():
             return func(info)
     query = {}
     template_kwds = {}
     for key in self.kwds:
         template_kwds[key] = info.get(key, self.kwds[key]())
     try:
         errpage = self.f(info, query)
     except ValueError as err:
         # Errors raised in parsing
         info['err'] = str(err)
         err_title = query.pop('__err_title__', self.err_title)
         return render_template(self.template, info=info, title=err_title, **template_kwds)
     else:
         err_title = query.pop('__err_title__', self.err_title)
     if errpage is not None:
         return errpage
     sort = query.pop('__sort__', None)
     table = query.pop('__table__', self.table)
     # We want to pop __title__ even if overridden by info.
     title = query.pop('__title__', self.title)
     title = info.get('title', title)
     template = query.pop('__template__', self.template)
     if random:
         query.pop('__projection__', None)
     proj = query.pop('__projection__', self.projection)
     if 'result_count' in info:
         nres = table.count(query)
         return jsonify({"nres":str(nres)})
     count = parse_count(info, self.per_page)
     start = parse_start(info)
     try:
         if random:
             # Ignore __projection__: it's intended for searches
             label = table.random(query, projection=0)
             if label is None:
                 res = []
                 # ugh; we have to set these manually
                 info['query'] = dict(query)
                 info['number'] = 0
                 info['count'] = count
                 info['start'] = start
                 info['exact_count'] = True
             else:
                 return redirect(self.url_for_label(label), 307)
         else:
             res = table.search(query, proj, limit=count, offset=start, sort=sort, info=info)
     except QueryCanceledError as err:
         ctx = ctx_proc_userdata()
         flash_error('The search query took longer than expected! Please help us improve by reporting this error  <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage'])
         info['err'] = str(err)
         info['query'] = dict(query)
         return render_template(self.template, info=info, title=self.err_title, **template_kwds)
     else:
         try:
             if self.cleaners:
                 for v in res:
                     for name, func in self.cleaners.items():
                         v[name] = func(v)
             if self.postprocess is not None:
                 res = self.postprocess(res, info, query)
         except ValueError as err:
             # Errors raised in postprocessing
             flash_error(str(err))
             info['err'] = str(err)
             return render_template(self.template, info=info, title=err_title, **template_kwds)
         for key, func in self.longcuts.items():
             if info.get(key,'').strip():
                 return func(res, info, query)
         info['results'] = res
         return render_template(template, info=info, title=title, **template_kwds)