Skip to content

Commit 0e0cacb

Browse files
Add viewer index.html to top level of results directory (#927)
* Fix logic generating index.html for prov dir * Make viewer html links open in new tabs
1 parent df39bf4 commit 0e0cacb

File tree

5 files changed

+89
-31
lines changed

5 files changed

+89
-31
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[#]
2+
sets = ["polar"]
3+
case_id = "GPCP_v3.2"
4+
variables = ["PRECT"]
5+
ref_name = "GPCP_v3.2"
6+
reference_name = "GPCP v2.2"
7+
seasons = ["ANN", "DJF", "MAM", "JJA", "SON"]
8+
regions = ["polar_S"]
9+
test_colormap = "WhiteBlueGreenYellowRed.rgb"
10+
reference_colormap = "WhiteBlueGreenYellowRed.rgb"
11+
diff_colormap = "BrBG"
12+
contour_levels = [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]
13+
diff_levels = [-2, -1.5, -1, -0.75, -0.5, -0.25, 0.25, 0.5, 0.75, 1, 1.5, 2]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# python -m auxiliary_tools.cdat_regression_testing.792-lat-lon-run-script.792_lat_lon_run_script
2+
from auxiliary_tools.cdat_regression_testing.base_run_script import run_set
3+
4+
SET_NAME = "polar"
5+
SET_DIR = "562-index-html"
6+
# CFG_PATH: str | None = None
7+
CFG_PATH: str | None = "auxiliary_tools/cdat_regression_testing/562-index-html/562_index_html.cfg"
8+
MULTIPROCESSING = False
9+
10+
# %%
11+
run_set(SET_NAME, SET_DIR, CFG_PATH, MULTIPROCESSING)

e3sm_diags/e3sm_diags_driver.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,23 @@ def save_provenance(results_dir, parser):
141141
if not os.path.exists(results_dir):
142142
os.makedirs(results_dir, 0o755)
143143

144-
# Create a PHP file to list the contents of the prov dir.
145-
php_path = os.path.join(results_dir, "index.php")
146-
with open(php_path, "w") as f:
147-
contents = """
148-
<?php
149-
# Taken from:
150-
# https://stackoverflow.com/questions/3785055/how-can-i-create-a-simple-index-html-file-which-lists-all-files-directories
151-
$path = ".";
152-
$dh = opendir($path);
153-
$i=1;
154-
while (($file = readdir($dh)) !== false) {
155-
if($file != "." && $file != ".." && $file != "index.php" && $file != ".htaccess" && $file != "error_log" && $file != "cgi-bin") {
156-
echo "<a href='$path/$file'>$file</a><br /><br />";
157-
$i++;
158-
}
159-
}
160-
closedir($dh);
161-
?>
162-
"""
163-
f.write(contents)
144+
# Create an HTML file to list the contents of the prov dir.
145+
index_html_path = os.path.join(results_dir, "index.html")
146+
147+
with open(index_html_path, "w") as f:
148+
f.write("<html><body><h1>Provenance Files</h1><ul>")
149+
150+
for file_name in os.listdir(results_dir):
151+
file_path = os.path.join(results_dir, file_name)
152+
if os.path.isfile(file_path):
153+
f.write(
154+
f'<li><a href="{file_name}" target="_blank">{file_name}</a></li>'
155+
)
156+
157+
f.write("</ul></body></html>")
158+
159+
logger.info("Created provenance index HTML file at: {}".format(index_html_path))
160+
164161
try:
165162
_save_env_yml(results_dir)
166163
except Exception:
@@ -388,11 +385,7 @@ def main(parameters=[]) -> List[CoreParameter]: # noqa B006
388385
if parameters_results[0].no_viewer:
389386
logger.info("Viewer not created because the no_viewer parameter is True.")
390387
else:
391-
path = os.path.join(parameters_results[0].results_dir, "viewer")
392-
if not os.path.exists(path):
393-
os.makedirs(path)
394-
395-
index_path = create_viewer(path, parameters_results)
388+
index_path = create_viewer(parameters_results)
396389
logger.info("Viewer HTML generated at {}".format(index_path))
397390

398391
# Validate actual and expected parameters are aligned

e3sm_diags/viewer/core_viewer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def generate_page(self):
100100
)
101101
return url
102102

103-
raise RuntimeError("Error geneating the page.")
103+
raise RuntimeError("Error generating the page.")
104104

105105
def generate_viewer(self, prompt_user=True):
106106
"""Generate the webpage and ask the user if they want to see it."""

e3sm_diags/viewer/main.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import collections
22
import os
3+
from typing import List
34

45
from bs4 import BeautifulSoup
56

67
import e3sm_diags
78
from e3sm_diags.logger import custom_logger
9+
from e3sm_diags.parameter.core_parameter import CoreParameter
810

911
from . import (
1012
aerosol_budget_viewer,
@@ -72,6 +74,7 @@ def insert_data_in_row(row_obj, name, url):
7274
td = soup.new_tag("td")
7375
a = soup.new_tag("a")
7476
a["href"] = url
77+
a["target"] = "_blank" # Open link in a new tab
7578
a.string = name
7679
td.append(a)
7780
row_obj.append(td)
@@ -113,11 +116,17 @@ def insert_data_in_row(row_obj, name, url):
113116
return output
114117

115118

116-
def create_viewer(root_dir, parameters):
119+
def create_viewer(parameters: List[CoreParameter]) -> str:
117120
"""
118121
Based of the parameters, find the files with the
119122
certain extension and create the viewer in root_dir.
120123
"""
124+
root_dir = parameters[0].results_dir
125+
viewer_dir = os.path.join(root_dir, "viewer")
126+
127+
if not os.path.exists(viewer_dir):
128+
os.makedirs(viewer_dir)
129+
121130
# Group each parameter object based on the `sets` parameter.
122131
set_to_parameters = collections.defaultdict(list)
123132
for param in parameters:
@@ -127,19 +136,51 @@ def create_viewer(root_dir, parameters):
127136
# A list of (title, url) tuples that each viewer generates.
128137
# This is used to create the main index.
129138
title_and_url_list = []
139+
130140
# Now call the viewers with the list of parameters as the arguments.
131141
for set_name, parameters in set_to_parameters.items():
132-
logger.info(f"{set_name} {root_dir}")
142+
logger.info(f"{set_name} {viewer_dir}")
133143
viewer_function = SET_TO_VIEWER[set_name]
134-
result = viewer_function(root_dir, parameters)
144+
result = viewer_function(viewer_dir, parameters)
135145
logger.info(result)
136146
title_and_url_list.append(result)
137147

138148
# Add the provenance in the index as well.
139149
prov_tuple = ("Provenance", "../prov")
140150
title_and_url_list.append(prov_tuple)
141151

142-
index_url = create_index(root_dir, title_and_url_list)
143-
utils.add_header(root_dir, index_url, parameters)
152+
index_url = create_index(viewer_dir, title_and_url_list)
153+
_create_root_index(root_dir, index_url)
154+
155+
utils.add_header(viewer_dir, index_url, parameters)
144156

145157
return index_url
158+
159+
160+
def _create_root_index(root_dir: str, viewer_index_url: str):
161+
"""Create a root level `index.html` file that redirects to the viewer index.
162+
163+
Parameters
164+
----------
165+
root_dir : str
166+
The root directory.
167+
index_url : str
168+
The url to the viewer index.html file.
169+
"""
170+
root_index_path = os.path.join(root_dir, "index.html")
171+
relative_viewer_index_url = os.path.relpath(viewer_index_url, root_dir)
172+
root_soup = BeautifulSoup(
173+
f"""
174+
<html>
175+
<head>
176+
<meta http-equiv='refresh' content='0; url={relative_viewer_index_url}' />
177+
</head>
178+
<body></body>
179+
</html>
180+
""",
181+
"lxml",
182+
)
183+
184+
# Write the root index file
185+
with open(root_index_path, "wb") as f:
186+
f.write(root_soup.prettify("utf-8"))

0 commit comments

Comments
 (0)