Fix error on json5 lint fail and add AdminLTE theme generated templates

This commit is contained in:
2025-09-06 08:23:59 +01:00
parent c3fba3a7d5
commit 29f8de63fd
17 changed files with 1116 additions and 146 deletions

286
sm2gen.py
View File

@@ -204,9 +204,8 @@ def lint_json5(filename):
json5.loads(data)
logger.info(f"{filename} as JSON5 data is valid")
except Exception as e:
logger.warning(f"{filename} as JSON5 data is invalid")
logger.warning("Error:", str(e))
sys.exit()
logger.error(f"{filename} as JSON5 data is invalid {e}")
quit(1)
def flatten_hash_of_lists(hash_of_lists):
@@ -631,20 +630,11 @@ if __name__ == "__main__":
directory_path = Path("Targets/" + hl("PackageName"))
# Create the directory if it doesn't exist
directory_path.mkdir(parents=True, exist_ok=True)
target_directory_path = "Targets/" + hl("PackageName") + "/"
base_target_directory_path = "Targets/" + hl("PackageName") + "/"
target_directory_path = base_target_directory_path
controller_file = check_file_version(target_directory_path + hl("PackageName") + ".pm",force_Files)
custom_controller_file = check_file_version(target_directory_path + hl("PackageName") + "-Custom.pm",force_Files)
#logger.info(custom_controller_file)
layout_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".html.ep",force_Files)
css_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".css",force_Files)
js_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".js",force_Files)
partial_files = list()
for panel in routes:
partial_files.append(check_file_version(
target_directory_path + '_' + hl("prefix") + "_" + panel + ".html.ep",force_Files)
)
logger.debug(f"Partial files to be created:{partial_files}")
lex_file = check_file_version(target_directory_path + hl("PackageName").lower() + "_en.lex",force_Files)
logger.info(lex_file)
tablecontrols = extract_tables(json5_dict)
@@ -703,153 +693,167 @@ if __name__ == "__main__":
except Exception as e:
logger.info(f"A Chameleon custom controller *template* error occurred: {e} {traceback.format_exc()}")
# generate Layout file
layout_template = PageTemplateFile("Templates/layout.html.ep.tem")
try:
try:
layout_mojo = layout_template.render(
version=strVersion, **json5_dict, conditions=routes,
lcPackageName=json5_dict["PackageName"].lower()
for theme_name in ["","AdminLTE_"]: #the _ is important!!
target_directory_path = base_target_directory_path;
if theme_name:
theme_directory = theme_name.replace("_","") #Take out the trailing _
target_directory_path = target_directory_path + theme_directory + "/"
Path(target_directory_path).mkdir(parents=True, exist_ok=True)
layout_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".html.ep",force_Files)
css_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".css",force_Files)
js_file = check_file_version(target_directory_path + hl("PackageName").lower() + ".js",force_Files)
partial_files = list()
for panel in routes:
partial_files.append(check_file_version(
target_directory_path + '_' + hl("prefix") + "_" + panel + ".html.ep",force_Files)
)
with open(layout_file, "w") as file:
file.write(layout_mojo)
logger.info(f"{highlight_occurrences(layout_file)} mojo template layout file generated ok")
except Exception as e:
logger.info(f"A Chameleon *render* on layout file error occurred: {e}")
except Exception as e:
logger.info(f"A Chameleon *template* layout file error occurred: {e}")
# Generate a partial file for each of the entries in the html list
# Pull in the template code for each of the input types
# html_controls = json5_to_dict('Templates/html_controls.html.ep.tem')
html_controls = parse_xml_to_dict("Templates/html_controls.html.ep.xml")
i = 0
acc_css_entries = ""; #One entry for each class created for html entries
for html in json5_html_list:
# Generate a mojo template file, and then add in the controls
# main file first
logger.debug(f"Partial files to be created:{partial_files}")
# generate Layout file
layout_template = PageTemplateFile(f"Templates/{theme_name}layout.html.ep.tem")
try:
partial_template = PageTemplateFile("Templates/partial.html.ep.tem")
partial_mojo_context = {**json5_dict, **html}
try:
partial_mojo_template = partial_template.render(
version=strVersion, **partial_mojo_context,
layout_mojo = layout_template.render(
version=strVersion, **json5_dict, conditions=routes,
lcPackageName=json5_dict["PackageName"].lower()
)
with open(partial_files[i], "w") as file:
file.write(partial_mojo_template)
logger.info(f"{highlight_occurrences(partial_files[i])} mojo template generated ok - phase 1")
with open(layout_file, "w") as file:
file.write(layout_mojo)
logger.info(f"{highlight_occurrences(layout_file)} mojo template layout file generated ok")
except Exception as e:
logger.info(
f"A Chameleon render error on partial file {html['route']} occurred: {e}"
)
logger.info(f"A Chameleon *render* on layout file error occurred: {e}")
except Exception as e:
logger.info(f"A Chameleon html {html['route']} error occurred: {e}")
# Now generate the controls from the rest of the entries in the dict.
all_controls_html = ""
for html_control in html:
inner_html = html[html_control]
if isinstance(inner_html, dict):
# input or table
html_Type = inner_html['Type']
type_serial = "".join(char for char in html_control if char.isdigit())
class_name = html_Type.lower()[:4]+type_serial
acc_css_entries += f".{class_name} {{}}\n"
OptionsInPerl = python_to_perl_structure(inner_html.get("Options", ""))
#if html_Type == "Select":
# example_function(**inner_html)
# quit(1)
if html_Type == "Table":
acc_css_entries += f"thead .{class_name} {{}}\n"
acc_css_entries += f"tbody .{class_name} {{}}\n"
logger.info(f"A Chameleon *template* layout file error occurred: {e}")
# Generate a partial file for each of the entries in the html list
# Pull in the template code for each of the input types
# html_controls = json5_to_dict('Templates/html_controls.html.ep.tem')
html_controls = parse_xml_to_dict(f"Templates/{theme_name}html_controls.html.ep.xml")
i = 0
acc_css_entries = ""; #One entry for each class created for html entries
for html in json5_html_list:
# Generate a mojo template file, and then add in the controls
# main file first
try:
partial_template = PageTemplateFile(f"Templates/{theme_name}partial.html.ep.tem")
partial_mojo_context = {**json5_dict, **html}
try:
control_template = PageTemplate(html_controls[inner_html["Type"]])
try:
control_html = control_template.render(
version=strVersion, **inner_html, prefix=prefix_is,
classname=class_name,
type_serial=type_serial,
OptionsInPerl=OptionsInPerl
)
all_controls_html = all_controls_html + control_html
except Exception as e:
logger.info(
f"A Chameleon *render* on partial file control {html_control} error occurred: {e}"
)
partial_mojo_template = partial_template.render(
version=strVersion, **partial_mojo_context,
lcPackageName=json5_dict["PackageName"].lower()
)
with open(partial_files[i], "w") as file:
file.write(partial_mojo_template)
logger.info(f"{highlight_occurrences(partial_files[i])} mojo template generated ok - phase 1")
except Exception as e:
logger.info(
f"A Chameleon *template* on partial file control {html_control} error occurred: {e}"
f"A Chameleon render error on partial file {html['route']} occurred: {e}"
)
else:
# just a simple entry - name less numerics is type
# If the html does not include any Chameleon / TAL symbols, then do not run the Template extraction, just
# insert the result of the html directly. This avoids Chameleon aborting things when a closing tag is on its own
# such as the "Endgroup" token.
html_Type = "".join(char for char in html_control if not char.isdigit())
type_serial = "".join(char for char in html_control if char.isdigit())
class_name = html_Type.lower()[:4]+type_serial
acc_css_entries += f".{class_name} {{}}\n"
simple_control_html = ""
logger.debug(f"Partial ep generation html type:{html_Type}")
if not type_serial == "":
logger.debug(f"{html_control},{html_Type},{type_serial}")
if html_Type in html_controls:
if contains_chameleon_code(html_controls[html_Type]):
except Exception as e:
logger.info(f"A Chameleon html {html['route']} error occurred: {e}")
# Now generate the controls from the rest of the entries in the dict.
all_controls_html = ""
for html_control in html:
inner_html = html[html_control]
if isinstance(inner_html, dict):
# input or table
html_Type = inner_html['Type']
type_serial = "".join(char for char in html_control if char.isdigit())
class_name = html_Type.lower()[:4]+type_serial
acc_css_entries += f".{class_name} {{}}\n"
OptionsInPerl = python_to_perl_structure(inner_html.get("Options", ""))
#if html_Type == "Select":
# example_function(**inner_html)
# quit(1)
if html_Type == "Table":
acc_css_entries += f"thead .{class_name} {{}}\n"
acc_css_entries += f"tbody .{class_name} {{}}\n"
try:
control_template = PageTemplate(html_controls[inner_html["Type"]])
try:
simple_control_template = PageTemplate(html_controls[html_Type])
control_html = control_template.render(
version=strVersion, **inner_html, prefix=prefix_is,
classname=class_name,
type_serial=type_serial,
OptionsInPerl=OptionsInPerl
)
all_controls_html = all_controls_html + control_html
except Exception as e:
logger.info(
f"A Chameleon *render* on partial file control {html_control} error occurred: {e}"
)
except Exception as e:
logger.info(
f"A Chameleon *template* on partial file control {html_control} error occurred: {e}"
)
else:
# just a simple entry - name less numerics is type
# If the html does not include any Chameleon / TAL symbols, then do not run the Template extraction, just
# insert the result of the html directly. This avoids Chameleon aborting things when a closing tag is on its own
# such as the "Endgroup" token.
html_Type = "".join(char for char in html_control if not char.isdigit())
type_serial = "".join(char for char in html_control if char.isdigit())
class_name = html_Type.lower()[:4]+type_serial
acc_css_entries += f".{class_name} {{}}\n"
simple_control_html = ""
logger.debug(f"Partial ep generation html type:{html_Type}")
if not type_serial == "":
logger.debug(f"{html_control},{html_Type},{type_serial}")
if html_Type in html_controls:
if contains_chameleon_code(html_controls[html_Type]):
try:
simple_control_html = simple_control_template.render(
version=strVersion, Value=inner_html, prefix=prefix_is,
type_serial=type_serial
)
simple_control_template = PageTemplate(html_controls[html_Type])
try:
simple_control_html = simple_control_template.render(
version=strVersion, Value=inner_html, prefix=prefix_is,
type_serial=type_serial
)
except Exception as e:
logger.warning(
f"A Chameleon *render* on partial file control {html_control} error occurred: {e}"
)
except Exception as e:
logger.warning(
f"A Chameleon *render* on partial file control {html_control} error occurred: {e}"
f"A Chameleon *template* partial file control {html_control} error occurred: {e}"
)
except Exception as e:
logger.warning(
f"A Chameleon *template* partial file control {html_control} error occurred: {e}"
)
else:
logger.debug(f"Skipping Chameleon expansion for {html_control}")
simple_control_html = html_controls[html_Type]
all_controls_html = all_controls_html + simple_control_html
else:
logger.debug(f"Skipping Chameleon expansion for {html_control}")
simple_control_html = html_controls[html_Type]
all_controls_html = all_controls_html + simple_control_html
else:
logger.debug(f"{html_Type} not found in html_controls xml")
# Now insert it into the partial file in the correct place.
# Read in the text file and split at "%# Inputs etc in here."
with open(partial_files[i], "r") as file:
lines = file.readlines()
index = next(
(i for i, line in enumerate(lines) if "%# Inputs etc in here." in line),
len(lines),
)
logger.debug(f"{html_Type} not found in html_controls xml")
# Now insert it into the partial file in the correct place.
# Read in the text file and split at "%# Inputs etc in here."
with open(partial_files[i], "r") as file:
lines = file.readlines()
index = next(
(i for i, line in enumerate(lines) if "%# Inputs etc in here." in line),
len(lines),
)
# Insert the string at the specified index
lines.insert(index + 1, all_controls_html + "\n")
# Insert the string at the specified index
lines.insert(index + 1, all_controls_html + "\n")
# Write the modified content back to the file
with open(partial_files[i], "w") as file:
file.writelines(lines)
logger.info(f"Content modified and saved to {highlight_occurrences(partial_files[i])}")
i += 1
# Write the modified content back to the file
with open(partial_files[i], "w") as file:
file.writelines(lines)
logger.info(f"Content modified and saved to {highlight_occurrences(partial_files[i])}")
i += 1
# Create the css file (the header, followed by a dummy entry for each class created/used above)
with open(css_file, "w") as file:
file.write(f"/*\nGenerated by: {strVersion}\n*/\n")
file.write(f".{hl('PackageName')}-panel {{}}\n")
file.write(acc_css_entries);
logger.info(f"Css generated and saved to {highlight_occurrences(css_file)}")
# and create a js file (empty))
with open(js_file, "w") as file:
file.write(f"//\n//Generated by: {strVersion}\n//\n")
file.write("$(document).ready(function() {\n")
file.write("});\n");
logger.info(f"js generated and saved to {highlight_occurrences(js_file)}")
# Create the css file (the header, followed by a dummy entry for each class created/used above)
with open(css_file, "w") as file:
file.write(f"/*\nGenerated by: {strVersion}\n*/\n")
file.write(f".{hl('PackageName')}-panel {{}}\n")
file.write(acc_css_entries);
logger.info(f"Css generated and saved to {highlight_occurrences(css_file)}")
# and create a js file (empty))
with open(js_file, "w") as file:
file.write(f"//\n//Generated by: {strVersion}\n//\n")
file.write("$(document).ready(function() {\n")
file.write("});\n");
logger.info(f"js generated and saved to {highlight_occurrences(js_file)}")
# Now generate the <name>.en file
# Look through the generated files for the /l[\s|(]['|"](.*)['|"]\)/ strings.