diff --git a/dxr/app.py b/dxr/app.py index 293d2d32a..b3250a9f7 100644 --- a/dxr/app.py +++ b/dxr/app.py @@ -80,14 +80,14 @@ def search(): path, line = result # TODO: Does this escape qtext properly? return redirect( - '%s/%s/%s?from=%s#l%i' % + '%s/%s/source/%s?from=%s#l%i' % (config['WWW_ROOT'], tree, path, qtext, line)) # Return multiple results: template = 'search.html' start = time() try: - results = list(q.fetch_results(offset, limit)) + results = list(q.results(offset, limit)) except OperationalError as e: if e.message.startswith('REGEXP:'): # Malformed regex @@ -137,10 +137,10 @@ def search(): **arguments) -@dxr_blueprint.route('/') -def browse(tree_and_path): +@dxr_blueprint.route('//source/') +@dxr_blueprint.route('//source/') +def browse(tree, path=''): """Show a directory listing or a single file from one of the trees.""" - tree, _, path = tree_and_path.partition('/') tree_folder = os.path.join(current_app.instance_path, 'trees', tree) if isdir(os.path.join(tree_folder, path)): diff --git a/dxr/build.py b/dxr/build.py index 9c048ce20..97d34599f 100644 --- a/dxr/build.py +++ b/dxr/build.py @@ -236,12 +236,13 @@ def build_folder(tree, conn, folder, indexed_files, indexed_folders): # Generate list of folders and their mod dates: folders = [('folder', - f, - datetime.fromtimestamp(stat(os.path.join(tree.source_folder, - folder, - f)).st_mtime), - _join_url(tree.name, folder, f)) - for f in indexed_folders] + f, + datetime.fromtimestamp(stat(os.path.join(tree.source_folder, + folder, + f)).st_mtime), + # TODO: DRY with Flask route. Use url_for: + _join_url(tree.name, 'source', folder, f)) + for f in indexed_folders] # Generate list of files: files = [] @@ -250,10 +251,10 @@ def build_folder(tree, conn, folder, indexed_files, indexed_folders): path = os.path.join(tree.source_folder, folder, f) file_info = stat(path) files.append((dxr.mime.icon(path), - f, - datetime.fromtimestamp(file_info.st_mtime), - file_info.st_size, - _join_url(tree.name, folder, f))) + f, + datetime.fromtimestamp(file_info.st_mtime), + file_info.st_size, + _join_url(tree.name, 'source', folder, f))) # Lay down the HTML: jinja_env = load_template_env(tree.config.temp_folder, diff --git a/dxr/query.py b/dxr/query.py index 4e47db705..e2fc0d31f 100644 --- a/dxr/query.py +++ b/dxr/query.py @@ -121,9 +121,16 @@ def execute_sql(self, sql, *parameters): # Fetch results using a query, # See: queryparser.py for details in query specification - def fetch_results(self, - offset = 0, limit = 100, - markup = "", markdown = ""): + def results(self, + offset=0, limit=100, + markup='', markdown=''): + """Return search results as an iterable of these:: + + (icon, + path within tree, + (line_number, highlighted_line_of_code)), ... + + """ sql = """ SELECT files.path, files.icon, trg_index.text, files.id, extents(trg_index.contents) @@ -253,8 +260,11 @@ def number_lines(arr): def direct_result(self): - """ Get a direct result as tuple of (path, line) or None if not direct result - for query, ie. complex query + """Return a single search result that is an exact match for the query. + + If there is such a result, return a tuple of (path from root of tree, + line number). Otherwise, return None. + """ term = self.single_term() if not term: diff --git a/dxr/static/search.js b/dxr/static/search.js index 6e4b671be..22bdaa49d 100644 --- a/dxr/static/search.js +++ b/dxr/static/search.js @@ -13,7 +13,7 @@ var result_template = "" var lines_template = "" + "" + + " href=\"{{wwwroot}}/{{tree}}/source/{{path}}#l{{line_number}}\">" + "
" + "
{{line_number}}
" + "
" @@ -47,7 +47,7 @@ function format_results(data){ for(var j = 0; j < folders.length; j++){ var folder = folders[j]; var p = folders.slice(0, j + 1).join('/'); - var href = wwwroot + '/' + dxr.tree() + '/' + p; + var href = wwwroot + '/' + dxr.tree() + '/source/' + p; pathline += "
NameModifiedSize - Parent directory diff --git a/dxr/templates/layout.html b/dxr/templates/layout.html index 67ecdc9a5..360506935 100644 --- a/dxr/templates/layout.html +++ b/dxr/templates/layout.html @@ -81,7 +81,7 @@ {% elif not loop.first and trees|length > 1 -%} , {% endif -%} - {{ t }} + {{ t }} {%- endfor -%} . diff --git a/dxr/templates/search.html b/dxr/templates/search.html index ffa44fa48..daf55aeb4 100644 --- a/dxr/templates/search.html +++ b/dxr/templates/search.html @@ -101,7 +101,7 @@

Case Insensitive Suffix Matching

{%- set folders = path.split('/') -%} {%- for folder in folders -%} - Case Insensitive Suffix Matching {%- endfor -%}
{% for number, line in lines %} - -
-
{{ number }}
-
-
{{ line|safe }}
-
+ +
+
{{ number }}
+
+
{{ line|safe }}
+
{%- endfor %} {% else %} diff --git a/tests/test_ignores/test_ignores.py b/tests/test_ignores/test_ignores.py index e1f29e98d..dbee2885f 100644 --- a/tests/test_ignores/test_ignores.py +++ b/tests/test_ignores/test_ignores.py @@ -8,7 +8,7 @@ class IgnorePatternTests(DxrInstanceTestCase): def _top_level_index(self): """Return the HTML of the front browse page.""" - return self.client().get('/code').data + return self.client().get('/code/source/').data def test_non_path(self): """Test that non-path-based ignore patterns are obeyed."""