Common browse functionality
Starting on oJob-common oPack version 20250415 it’s possible to use the common browse functionality to list the contents of a directory or a file. This functionality is generic enough to be applied to different scenarios like: browsing a local filesystem; browsing an object storage bucket; browsing an AWS ECR; browsing a Maven repository; etc.
To install oJob-common either refer to it on an oJob (ojob > opacks > oJob-common) or install it directly by executing
opack install ojob-common
``
There are different implementations and more can be built following similar options. Here are some examples.
Browse a local filesystem
The easiest way to try this one is to just execute:
ojob ojob.io/httpServers/EasyHTTPd port=8888 path=.
The if you open your browser on port 8888 (e.g. http://localhost:8888) you will get an interface similar to this one:
On this interface you can use the left arrow to download the corresponding file or, clicking on the filename, you will be able to see directly the content of the file (e.g. .html, .md (automatically rendered), .xml, .json (automatically rendered)) or a page with the content of the file (e.g. .js, .sh, .yaml, etc.):
Here the interface allows you to go back using breadcrumbs or download the file (down arrow) or go back (left arrow). You can also copy+paste the contents clicking on the clipboard icon.
How do I setup an oJob to browse a local filesystem?
Let’s see an example and the available options. Start by creating a file called myFileBrowser.yaml
with the following content:
ojob:
daemon: true # we want to run it as a daemon
opacks:
- oJob-common # we want to install/include oJob-common
include:
- oJobBrowse.yaml # we want to add the oJob common browse functionality
todo:
# First, let's start the web server
- (httpdStart): 8888
((mapList )): true # we want to include common javascript, css and fonts embeeded in OpenAF
# Second, we want anyone landing on / to be redirected to /browse
- (httpdRedirect): 8888
((uri )): /
((targetURI )): /browse
# Third, we want to include the common browse functionality in /browse
- (httpdBrowse): 8888
((uri )): /browse
((path )): ..
That’s it. Now execute:
ojob myFileBrowser.yaml
and browse to http://localhost:8888/browse. You will see the contents of the folder where you executed the command. You can also use the path
argument to point to a specific folder.
Arguments available generically for (httpdBrose)
Argument | Type | Description |
---|---|---|
uri | String | The URI where the browse functionality will be available. |
path | String | The path to the folder you want to browse. If not specified, it will use the current working directory. |
options | Map | A map with options to be passed to the browse functionality depending on implementation. |
fns | Map | When extending beyond the default local filesystem browsing functionality this is a list of functions to be used. |
Options available for (httpdBrowse) if implemented
Option | Type | Description |
---|---|---|
browse | Boolean | If true, the browse functionality will be available. Otherwise direct file access will be available. |
default | String | The default file to open if it exists on a folder instead of listing the contents (e.g. README.md) |
showURI | Boolean | If true, the URI (e.g. /browse) of the file will be shown on the interface otherwise it will be hidden. |
logo | String | The logo URL to be shown on the interface. If not specified, the default OpenAF logo will be used. |
footer | String | The footer text (in markdown) to be shown on the interface. If not specified, the default OpenAF footer will be used. |
sortTab | Boolean | Include hover buttons to sort the table by column. |
Other implementations
Implementing a custom browse functionality
If you want to implement a custom browse functionality, you can do it by implementing fns
functions. Currently there are 6 functions that you might need to rewrite (you don’t define them the default ones will be used). The default login to call them is:
var output
var list = getList(request, options)
if (list.isList) {
output = renderList(list, server, request, options)
} else {
if (list.isFile) {
var obj = getObj(request, options)
output = renderObj(obj, server, request, options)
} else {
output = renderEmpty(request, options)
}
}
Functions description:
“init” function
init()
The init function doesn’t take any arguments and is called when the browse functionality is initialized. You can use it to set up any variables or configurations you need.
“getList” function
getList(request, options) : Map
The getList function receives a map with the browser request (e.g. request.uri, request.params, etc…). It should return a map with the following structures:
If the request.uri should be interpreted as a file:
{
"file": true
}
If the file doesn’t exist or shouldn’t be accessible the value
false
should be returned.
If the request.uri should be interpreted as a directory:
{
"isList": true,
"fields": [ "Filename", "Last modified", "Size", "Size in bytes" ],
"alignFields": [ "left", "center", "right", "right" ],
"key": "Filename",
"list": [
"isDirectory": false,
"values": {
"Filename": "myFile.txt",
"Last modified": "2023-10-01 12:00:00",
"Size": "1 KB",
"Size in bytes": 1024
}
]
}
Description of the fields:
isList
: If true, the request.uri should be interpreted as a directory. Otherwise, it should be interpreted as a file and the “isFile” value should be defined.fields
: The fields to be shown on the interface. The order of the fields should be the same as the order of the values.alignFields
: The alignment of the fields. The order of the fields should be the same as the order of the values.key
: The key to be used to identify the file. It should be unique for each file.list
: The list of files to be shown on the interface. Each file should have the following structure:isDirectory
: If true, the file is a directory. Otherwise, it is a file.values
: The values to be shown on the interface. The order of the values should be the same as the order of the fields.
“getObj” function
getObj(request, options) : Map
The getObj function receives a map with the browser request (e.g. request.uri, request.params, etc…). It should return a map with one of the following structures:
{
"stream": aJavaStream,
"type": "json"
}
or
{
"file": "a/local/file.yaml",
"type": "yaml"
}
or
{
"data": "some data",
"type": "md"
}
The type value is the type of the file to be shown on the interface. The available types are: “md”, “yaml”, “css”, “sh”, “js”, “java”, “python”, “toml”, “handlebars”, “json”, “asciidoc”, etc. The data value is the data to be shown on the interface. The file value is the path of a local file to be shown on the interface. The stream value is a Java stream to be used to read the file.
“renderList” function
renderList(aList, server, request, options) : Map
The renderList function receives aList returned by the getList function and is responsible to render the list on the interface. The server value is the OpenAF http server variable. The request parameter contains the original request data, and the options parameter allows for additional configuration during rendering.
Of course, the data returned by getList can be customized to be shown in a different way. For example, you can use the renderList function to show the list in a different format (e.g. as a table, as a list, etc.). You can also use it to add additional functionality (e.g. sorting, filtering, etc.).
The function should return a suitable OpenAF httpd server response using the server.reply* methods or ow.server.httpd.reply* methods.
For consistency please observe the common options like
browse
,sortTab
, etc.
“renderObj” function
renderObj(aObj, server, request, options)
The renderObj function receives aObj returned by the getObj function and is responsible to render the object on the interface. The server value is the OpenAF http server variable. The request parameter contains the original request data, and the options parameter allows for additional configuration during rendering.
Of course, the data returned by getObj can be customized to be shown in a different way. For example, you can use the renderObj function to show the object in a different format (e.g. as a table, as a list, etc.). You can also use it to add additional functionality (e.g. sorting, filtering, etc.).
The function should return a suitable OpenAF httpd server response using the server.reply* methods or ow.server.httpd.reply* methods.
For consistency please observe the common possibilties like
stream
,file
,data
, etc.
“renderEmpty” function
renderEmpty(request, options) : String
The renderEmpty function receives a map with the browser request (e.g. request.uri, request.params, etc…). It should return a string with the content to be shown on the interface no object or list can be shown.