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)
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))
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)
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))
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)
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)