diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-04-24 11:51:32 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-04-24 12:03:09 +0200 |
commit | 5615498846307cb8f08e5485e5091cda7969d502 (patch) | |
tree | 9d22a6a8e51170f53d9941abe333c21d329ee2cb | |
parent | 52002f63955ec211d1b1508eb5b9f9dd195d5ebf (diff) | |
download | justbuild-5615498846307cb8f08e5485e5091cda7969d502.tar.gz |
Invocation server: support download of all blobs
For many text files it is useful to read them directly in the browser.
However, many files that are better analysed by machines (like large
repository configurations) also come as plain-text files. Therefore,
always offer to download a file currently being viewed. Use the URL
scheme in such a way that the name to download the file as can be
specified; in this way, we are prepared if we decide to also log
the artifacts to be built and offer those to be downloaded.
-rwxr-xr-x | doc/invocations-http-server/server.py | 18 | ||||
-rw-r--r-- | doc/invocations-http-server/templates/blob.html | 2 |
2 files changed, 17 insertions, 3 deletions
diff --git a/doc/invocations-http-server/server.py b/doc/invocations-http-server/server.py index 940e03a1..68955841 100755 --- a/doc/invocations-http-server/server.py +++ b/doc/invocations-http-server/server.py @@ -36,6 +36,9 @@ class HashIdentifierConverter(werkzeug.routing.BaseConverter): class InvocationIdentifierConverter(werkzeug.routing.BaseConverter): regex = '[-:_a-zA-Z0-9]{1,200}' +class FileIdentifierConverter(werkzeug.routing.BaseConverter): + regex = '[-:_.a-zA-Z0-9]{3,200}' + class InvocationServer: def __init__(self, logsdir, *, just_mr = None, @@ -59,6 +62,9 @@ class InvocationServer: rule("/blob/<hashidentifier:blob>", methods=("GET",), endpoint="get_blob"), + rule("/blob/<hashidentifier:blob>/<fileidentifier:name>", + methods=("GET",), + endpoint="get_blob_as"), rule("/tree/<hashidentifier:tree>", methods=("GET",), endpoint="get_tree"), @@ -68,6 +74,7 @@ class InvocationServer: ], converters=dict( invocationidentifier=InvocationIdentifierConverter, hashidentifier=HashIdentifierConverter, + fileidentifier=FileIdentifierConverter, )) @Request.application @@ -132,7 +139,7 @@ class InvocationServer: pass return self.render("failure.html", params) - def do_get_blob(self, blob): + def do_get_blob(self, blob, *, download_as=None): cmd = self.just_mr + ["install-cas", "--remember", blob] blob_data = subprocess.run(cmd, stdout=subprocess.PIPE, @@ -142,17 +149,22 @@ class InvocationServer: try: blob_content = blob_data.stdout.decode('utf-8') except: - # Not utf-8, so return as binary file + # Not utf-8, so return as binary file to download separately + download_as = download_as or blob + if download_as: response = Response() response.content_type = "application/octet-stream" response.data = blob_data.stdout response.headers['Content-Disposition'] = \ - "attachement; filename=%s" %(blob,) + "attachement; filename=%s" %(download_as,) return response return self.render("blob.html", {"name": blob, "data": blob_content}) + def do_get_blob_as(self, blob, name): + return self.do_get_blob(blob, download_as=name) + def do_get_tree(self, tree): cmd = self.just_mr + ["install-cas", "%s::t" % (tree,)] tree_data = subprocess.run(cmd, diff --git a/doc/invocations-http-server/templates/blob.html b/doc/invocations-http-server/templates/blob.html index 2a64d064..d88368fe 100644 --- a/doc/invocations-http-server/templates/blob.html +++ b/doc/invocations-http-server/templates/blob.html @@ -6,5 +6,7 @@ Blob {{ name | e }} {% block content %} <h1>Blob {{ name | e }}</h1> +<a href="/blob/{{ name | e }}/{{ name | e}}">download</a> + <pre>{{ data | e}}</pre> {% endblock %} |