Beispiel #1
0
def search(tree):
    """Normalize params, and dispatch between JSON- and HTML-returning
    searches, based on Accept header.

    """
    # Normalize querystring params:
    config = current_app.dxr_config
    frozen = frozen_config(tree)
    req = request.values
    query_text = req.get('q', '')
    offset = non_negative_int(req.get('offset'), 0)
    limit = min(non_negative_int(req.get('limit'), 100), 1000)

    # Make a Query:
    query = Query(partial(current_app.es.search, index=frozen['es_alias']),
                  query_text, plugins_named(frozen['enabled_plugins']))

    # Fire off one of the two search routines:
    searcher = _search_json if _request_wants_json() else _search_html
    return searcher(query, tree, query_text, offset, limit, config)
Beispiel #2
0
 def direct_result_eq(self, query_text, line_num):
     conn = connect_db(os.path.join(self._config_dir_path, 'target', 'trees', 'code'))
     if line_num is None:
         eq_(Query(conn, query_text).direct_result(), None)
     else:
         eq_(Query(conn, query_text).direct_result(), ('main.cpp', line_num))
Beispiel #3
0
Datei: app.py Projekt: imclab/dxr
def search(tree):
    """Search by regex, caller, superclass, or whatever."""
    # TODO: This function still does too much.
    querystring = request.values

    offset = non_negative_int(querystring.get('offset'), 0)
    limit = min(non_negative_int(querystring.get('limit'), 100), 1000)

    config = current_app.config
    www_root = config['WWW_ROOT']
    trees = config['TREES']

    # Arguments for the template:
    arguments = {
        # Common template variables
        'wwwroot': www_root,
        'generated_date': config['GENERATED_DATE']}

    error = warning = ''
    status_code = None

    if tree in trees:
        arguments['tree'] = tree

        # Connect to database
        conn = connect_db(tree, current_app.instance_path)
        if conn:
            # Parse the search query
            qtext = querystring.get('q', '')
            is_case_sensitive = querystring.get('case') == 'true'
            q = Query(conn,
                      qtext,
                      should_explain='explain' in querystring,
                      is_case_sensitive=is_case_sensitive)

            # Try for a direct result:
            if querystring.get('redirect') == 'true':
                result = q.direct_result()
                if result:
                    path, line = result
                    # TODO: Does this escape qtext properly?
                    return redirect(
                        '%s/%s/source/%s?from=%s%s#%i' %
                        (www_root,
                         tree,
                         path,
                         qtext,
                         '&case=true' if is_case_sensitive else '', line))

            # Return multiple results:
            template = 'search.html'
            start = time()
            try:
                results = list(q.results(offset, limit))
            except sqlite3.OperationalError as e:
                if e.message.startswith('REGEXP:'):
                    # Malformed regex
                    warning = e.message[7:]
                    results = []
                elif e.message.startswith('QUERY:'):
                    warning = e.message[6:]
                    results = []
                else:
                    error = 'Database error: %s' % e.message
            if not error:
                # Search template variables:
                arguments['time'] = time() - start
                arguments['query'] = qtext
                arguments['search_url'] = search_url(www_root,
                                                     arguments['tree'],
                                                     qtext,
                                                     redirect=False)
                arguments['results'] = results
                arguments['offset'] = offset
                arguments['limit'] = limit
                arguments['is_case_sensitive'] = is_case_sensitive
                arguments['tree_tuples'] = [
                        (t,
                         search_url(www_root,
                                    t,
                                    qtext,
                                    case=True if is_case_sensitive else None),
                         description)
                        for t, description in trees.iteritems()]
        else:
            error = 'Failed to establish database connection.'
    else:
        arguments['tree'] = trees.keys()[0]
        error = "Tree '%s' is not a valid tree." % tree
        status_code = 404

    if warning or error:
        arguments['error'] = error or warning

    if querystring.get('format') == 'json':
        if error:
            # Return a non-OK code so the live search doesn't try to replace
            # the results with our empty ones:
            return jsonify(arguments), status_code or 500

        # Tuples are encoded as lists in JSON, and these are not real
        # easy to unpack or read in Javascript. So for ease of use, we
        # convert to dictionaries before returning the json results.
        # If further discrepancies are introduced, please document them in
        # templating.mkd.
        arguments['results'] = [
            {'icon': icon,
             'path': path,
             'lines': [{'line_number': nb, 'line': l} for nb, l in lines]}
                for icon, path, lines in arguments['results']]
        return jsonify(arguments)

    if error:
        return render_template('error.html', **arguments), status_code or 500
    else:
        arguments['filters'] = filter_menu_items()
        return render_template('search.html', **arguments)
Beispiel #4
0
 def direct_result_eq(self, query_text, line_num):
     conn = connect_db('code', os.path.join(self._config_dir_path,
                                            'target'))
     eq_(Query(conn, query_text).direct_result(), ('main.cpp', line_num))
Beispiel #5
0
def search(tree):
    """Search by regex, caller, superclass, or whatever."""
    # TODO: This function still does too much.
    querystring = request.values

    offset = non_negative_int(querystring.get("offset"), 0)
    limit = min(non_negative_int(querystring.get("limit"), 100), 1000)

    config = current_app.config
    www_root = config["WWW_ROOT"]
    trees = config["TREES"]
    google_analytics_key = config["GOOGLE_ANALYTICS_KEY"]

    # Arguments for the template:
    arguments = {
        # Common template variables
        "wwwroot": www_root,
        "google_analytics_key": google_analytics_key,
        "generated_date": config["GENERATED_DATE"],
    }

    error = warning = ""
    status_code = None

    if tree in trees:
        arguments["tree"] = tree

        # Connect to database
        try:
            conn = connect_db(join(current_app.instance_path, "trees", tree))
        except sqlite3.Error:
            error = "Failed to establish database connection."
        else:
            # Parse the search query
            qtext = querystring.get("q", "")
            is_case_sensitive = querystring.get("case") == "true"
            q = Query(conn, qtext, should_explain="explain" in querystring, is_case_sensitive=is_case_sensitive)

            # Try for a direct result:
            if querystring.get("redirect") == "true":
                result = q.direct_result()
                if result:
                    path, line = result
                    # TODO: Does this escape qtext properly?
                    return redirect(
                        "%s/%s/source/%s?from=%s%s#%i"
                        % (www_root, tree, path, qtext, "&case=true" if is_case_sensitive else "", line)
                    )

            # Return multiple results:
            template = "search.html"
            start = time()
            try:
                results = list(q.results(offset, limit))
            except sqlite3.OperationalError as e:
                if e.message.startswith("REGEXP:"):
                    # Malformed regex
                    warning = e.message[7:]
                    results = []
                elif e.message.startswith("QUERY:"):
                    warning = e.message[6:]
                    results = []
                else:
                    error = "Database error: %s" % e.message
            if not error:
                # Search template variables:
                arguments["time"] = time() - start
                arguments["query"] = qtext
                arguments["search_url"] = search_url(www_root, arguments["tree"], qtext, redirect=False)
                arguments["results"] = results
                arguments["offset"] = offset
                arguments["limit"] = limit
                arguments["is_case_sensitive"] = is_case_sensitive
                arguments["tree_tuples"] = [
                    (t, search_url(www_root, t, qtext, case=True if is_case_sensitive else None), description)
                    for t, description in trees.iteritems()
                ]
    else:
        arguments["tree"] = trees.keys()[0]
        error = "Tree '%s' is not a valid tree." % tree
        status_code = 404

    if warning or error:
        arguments["error"] = error or warning

    if querystring.get("format") == "json":
        if error:
            # Return a non-OK code so the live search doesn't try to replace
            # the results with our empty ones:
            return jsonify(arguments), status_code or 500

        # Tuples are encoded as lists in JSON, and these are not real
        # easy to unpack or read in Javascript. So for ease of use, we
        # convert to dictionaries before returning the json results.
        # If further discrepancies are introduced, please document them in
        # templating.mkd.
        arguments["results"] = [
            {"icon": icon, "path": path, "lines": [{"line_number": nb, "line": l} for nb, l in lines]}
            for icon, path, lines in arguments["results"]
        ]
        return jsonify(arguments)

    if error:
        return render_template("error.html", **arguments), status_code or 500
    else:
        arguments["filters"] = filter_menu_items(config["FILTER_LANGUAGE"])
        return render_template("search.html", **arguments)
Beispiel #6
0
def search(tree):
    """Search by regex, caller, superclass, or whatever."""
    # TODO: This function still does too much.
    querystring = request.values

    offset = non_negative_int(querystring.get('offset'), 0)
    limit = min(non_negative_int(querystring.get('limit'), 100), 1000)

    config = current_app.config
    www_root = config['WWW_ROOT']
    trees = config['TREES']

    # Arguments for the template:
    arguments = {
        # Common template variables
        'wwwroot': www_root,
        'generated_date': config['GENERATED_DATE']}

    error = warning = ''
    status_code = None

    if tree in trees:
        arguments['tree'] = tree

        # Connect to database
        try:
            conn = connect_db(join(current_app.instance_path, 'trees', tree))
        except sqlite3.Error:
            error = 'Failed to establish database connection.'
        else:
            # Parse the search query
            qtext = querystring.get('q', '')
            is_case_sensitive = querystring.get('case') == 'true'
            q = Query(conn,
                      qtext,
                      should_explain='explain' in querystring,
                      is_case_sensitive=is_case_sensitive)

            # Try for a direct result:
            if querystring.get('redirect') == 'true':
                result = q.direct_result()
                if result:
                    path, line = result
                    # TODO: Does this escape qtext properly?
                    return redirect(
                        '%s/%s/source/%s?from=%s%s#%i' %
                        (www_root,
                         tree,
                         path,
                         qtext,
                         '&case=true' if is_case_sensitive else '', line))

            # Return multiple results:
            template = 'search.html'
            start = time()
            try:
                results = list(q.results(offset, limit))
            except sqlite3.OperationalError as e:
                if e.message.startswith('REGEXP:'):
                    # Malformed regex
                    warning = e.message[7:]
                    results = []
                elif e.message.startswith('QUERY:'):
                    warning = e.message[6:]
                    results = []
                else:
                    error = 'Database error: %s' % e.message
            if not error:
                # Search template variables:
                arguments['time'] = time() - start
                arguments['query'] = qtext
                arguments['search_url'] = search_url(www_root,
                                                     arguments['tree'],
                                                     qtext,
                                                     redirect=False)
                arguments['results'] = results
                arguments['offset'] = offset
                arguments['limit'] = limit
                arguments['is_case_sensitive'] = is_case_sensitive
                arguments['tree_tuples'] = [
                        (t,
                         search_url(www_root,
                                    t,
                                    qtext,
                                    case=True if is_case_sensitive else None),
                         description)
                        for t, description in trees.iteritems()]
    else:
        arguments['tree'] = trees.keys()[0]
        error = "Tree '%s' is not a valid tree." % tree
        status_code = 404

    if warning or error:
        arguments['error'] = error or warning

    if querystring.get('format') == 'json':
        if error:
            # Return a non-OK code so the live search doesn't try to replace
            # the results with our empty ones:
            return jsonify(arguments), status_code or 500

        # Tuples are encoded as lists in JSON, and these are not real
        # easy to unpack or read in Javascript. So for ease of use, we
        # convert to dictionaries before returning the json results.
        # If further discrepancies are introduced, please document them in
        # templating.mkd.
        arguments['results'] = [
            {'icon': icon,
             'path': path,
             'lines': [{'line_number': nb, 'line': l} for nb, l in lines]}
                for icon, path, lines in arguments['results']]
        return jsonify(arguments)

    if error:
        return render_template('error.html', **arguments), status_code or 500
    else:
        arguments['filters'] = filter_menu_items(config['FILTER_LANGUAGE'])
        return render_template('search.html', **arguments)