widget py working + fix jsdoc build

This commit is contained in:
Jordan Blasenhauer 2024-08-02 16:53:48 +02:00
parent f01f916b3f
commit e3da25e221
18 changed files with 4094 additions and 192 deletions

View file

@ -97,8 +97,7 @@ def formatMd():
"""Format each markdown file to remove useless data and format some data like params"""
# Get all files from the output folder
files = list(Path(outputFolder).rglob("*"))
# Create order using the tag title path of each file
order = []
for file in files:
# Get the title from first line
data = file.read_text()
@ -117,6 +116,9 @@ def formatMd():
# remove space (so &#x20 or &#32)
line = line.replace("&#x20", "").replace("&#32", "")
if line.startswith("#") and ".vue" in line and "\.vue" in line:
line = line.replace("\.vue", ".vue")
# Case not a param, keep the line as is
if not line.startswith("*"):
line_result.append(line)

View file

@ -9,7 +9,7 @@ import ButtonGroup from "@components/Widget/ButtonGroup.vue";
import { useEqualStr } from "@utils/global.js";
/**
* @name Builder/Raw.vue
* @name Builder/RawMode.vue
* @description This component is lightweight builder containing only the necessary components to create the raw page.
* @example
* [
@ -33,7 +33,7 @@ import { useEqualStr } from "@utils/global.js";
* ],
* },
* ];
** @param {array} builder - Array of containers and widgets
* @param {array} builder - Array of containers and widgets
*/
const props = defineProps({

View file

@ -5,8 +5,8 @@ import { feedbackIndex } from "@utils/tabindex.js";
import { useBannerStore } from "@store/global.js";
import { onBeforeMount } from "vue";
/**
** @name Dashboard/Feedback.vue
** @description This component will display server feedbacks from the user.
* @name Dashboard/Feedback.vue
* @description This component will display server feedbacks from the user.
* This component is working with flash messages under the hood.
* This will display an ephemeral on the bottom right of the page and a sidebar with all the feedbacks.
*/

View file

@ -4,8 +4,8 @@ import { newsIndex } from "@utils/tabindex.js";
import { useBannerStore } from "@store/global.js";
/**
** @name Dashboard/News.vue
** @description This component will display news from BunkerWeb blog and allow users to subscribe to the newsletter.
* @name Dashboard/News.vue
* @description This component will display news from BunkerWeb blog and allow users to subscribe to the newsletter.
* Case the news API is not available, it will display a message.
*/
@ -20,7 +20,7 @@ const news = reactive({
/**
* @name loadNews
** @description Retrieve blog news from storage or fetch from the API.
* @description Retrieve blog news from storage or fetch from the API.
* @returns {void}
*/
function loadNews() {

View file

@ -7,9 +7,9 @@ import Datepicker from "@components/Forms/Field/Datepicker.vue";
import Editor from "@components/Forms/Field/Editor.vue";
import { contentIndex } from "@utils/tabindex.js";
/**
** @name Form/Fields.vue
** @description This component wraps all available fields for a form.
** @example
* @name Form/Fields.vue
* @description This component wraps all available fields for a form.
* @example
* {
* columns : {"pc": 6, "tablet": 12, "mobile": 12},
* id:"test-check",
@ -27,7 +27,7 @@ import { contentIndex } from "@utils/tabindex.js";
* },
* ]
* }
** @param {object} setting - Setting needed to render a field.
* @param {object} setting - Setting needed to render a field.
*/
const props = defineProps({

View file

@ -10,9 +10,9 @@ import { v4 as uuidv4 } from "uuid";
import { useRawForm } from "@store/form.js";
/**
** @name Form/Raw.vue
** @description This component is used to create a complete raw form with settings as JSON format.
** @example
* @name Form/Raw.vue
* @description This component is used to create a complete raw form with settings as JSON format.
* @example
* {
* "IS_LOADING": "no",
* "NGINX_PREFIX": "/etc/nginx/",
@ -20,9 +20,9 @@ import { useRawForm } from "@store/form.js";
* "HTTPS_PORT": "8443",
* "MULTISITE": "yes"
* }
** @param {object} template - Template object with plugin and settings data.
** @param {string} containerClass - Container
** @param {object} columns - Columns object.
* @param {object} template - Template object with plugin and settings data.
* @param {string} containerClass - Container
* @param {object} columns - Columns object.
*/
const rawForm = useRawForm();
@ -51,10 +51,10 @@ const data = reactive({
});
/**
** @name updateRaw
** @description Get the raw data from editor, update the raw store with it and check if it is valid JSON.
** @param {string} v - The raw data to update.
** @returns {void}
* @name updateRaw
* @description Get the raw data from editor, update the raw store with it and check if it is valid JSON.
* @param {string} v - The raw data to update.
* @returns {void}
*/
function updateRaw(v) {
// Transform to a possible valid JSON
@ -95,12 +95,12 @@ function updateRaw(v) {
}
/**
** @name json2raw
** @description Convert a JSON object to a raw string that can be passed to the editor.
* @name json2raw
* @description Convert a JSON object to a raw string that can be passed to the editor.
* This will convert JSON to key value pairs (format key=value).
* This is only used at first mount when there is no raw data.
** @param {string} json - The template json to convert
** @returns {string} - The raw string
* @param {string} json - The template json to convert
* @returns {string} - The raw string
*/
function json2raw(json) {
let dataStr = JSON.stringify(json);

View file

@ -10,9 +10,9 @@ import Easy from "@components/Form/Easy.vue";
import { v4 as uuidv4 } from "uuid";
/**
** @name Form/Templates.vue
** @description This component is used to create a complete settings form with all modes (advanced, raw, easy).
** @example
* @name Form/Templates.vue
* @description This component is used to create a complete settings form with all modes (advanced, raw, easy).
* @example
* {
* advanced : {
* default : [{SETTING_1}, {SETTING_2}...],
@ -23,7 +23,7 @@ import { v4 as uuidv4 } from "uuid";
* low : [...],
* }
* }
** @param {object} templates - List of advanced templates that contains settings. Must be a dict with mode as key, then the template name as key with a list of data (different for each modes).
* @param {object} templates - List of advanced templates that contains settings. Must be a dict with mode as key, then the template name as key with a list of data (different for each modes).
*/
const props = defineProps({
@ -78,18 +78,18 @@ const data = reactive({
});
/**
** @name getFirstTemplateName
** @description Get the first template name from the first mode.
** @returns {string} - The first template name
* @name getFirstTemplateName
* @description Get the first template name from the first mode.
* @returns {string} - The first template name
*/
function getFirstTemplateName() {
return Object.keys(props.templates[data.currModeName])[0];
}
/**
** @name getFirstTemplateName
** @description Get the first mode name from the first key in props.templates dict.
** @returns {string} - The first mode name
* @name getFirstTemplateName
* @description Get the first mode name from the first key in props.templates dict.
* @returns {string} - The first mode name
*/
function getFirstModeName() {
// Get first key in props.templates dict

View file

@ -38,7 +38,7 @@ import { useUUID } from "@utils/global.js";
* @param {string} [inpType="checkbox"] - The type of the field, useful when we have multiple fields in the same container to display the right field
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [hideLabel=false]
* @param {string} [containerClass=""]
* @param {string} [headerClass=""]

View file

@ -51,7 +51,7 @@ import { useUUID } from "@utils/global.js";
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {array} [requiredValues=[]] - values that need to be selected to be valid, works only if required is true
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [hideLabel=false]
* @param {boolean} [onlyDown=false] - If the dropdown should check the bottom of the
* @param {boolean} [overflowAttrEl=""] - Attribut to select the container the element has to check for overflow

View file

@ -52,7 +52,7 @@ import "@assets/css/flatpickr.dark.min.css";
* @param {number<timestamp>} [maxDate=""] - Impossible to pick a date after this date.
* @param {boolean} [isClipboard=true] - allow to copy the timestamp value
* @param {boolean} [hideLabel=false]
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {string} [headerClass=""]

View file

@ -43,7 +43,7 @@ import "@assets/script/editor/theme-dawn.js";
* @param {object} [attrs={}] - Additional attributes to add to the field
* @param {array} [popovers] - List of popovers to display more information
* @param {string} [inpType="editor"] - The type of the field, useful when we have multiple fields in the same container to display the right field
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {string} [pattern=""]
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]

View file

@ -47,7 +47,7 @@ import { useUUID } from "@utils/global.js";
* @param {object} [attrs={}] - Additional attributes to add to the field
* @param {array} [popovers] - List of popovers to display more information
* @param {string} [inpType="input"] - The type of the field, useful when we have multiple fields in the same container to display the right field
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {string} [placeholder=""]

View file

@ -46,7 +46,7 @@ import ErrorDropdown from "@components/Forms/Error/Dropdown.vue";
* @param {string} [inpType="list"] - The type of the field, useful when we have multiple fields in the same container to display the right field
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [hideLabel=false]
* @param {boolean} [onlyDown=false] - If the dropdown should stay down
* @param {boolean} [overflowAttrEl=""] - Attribute the element has to check for overflow

View file

@ -50,7 +50,7 @@ import { useUUID } from "@utils/global";
* @param {boolean} [disabled=false]
* @param {boolean} [required=false]
* @param {array} [requiredValues=[]] - values that need to be selected to be valid, works only if required is true
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {boolean} [hideLabel=false]
* @param {boolean} [onlyDown=false] - If the dropdown should check the bottom of the container
* @param {boolean} [overflowAttrEl=""] - Attribut to select the container the element has to check for overflow

View file

@ -147,7 +147,7 @@ import Container from "@components/Widget/Container.vue";
* }
* },
* @param {object<object>} multiples - The multiples settings to display. This needs to be a dict of settings using default field format.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12"}] - Field has a grid system. This allow to get multiple field in the same row if needed.
* @param {string} [containerClass=""] - Additionnal class to add to the container
* @param {string} [tadId=contentIndex] - The tabindex of the field, by default it is the contentIndex
*/

View file

@ -1,14 +1,14 @@
<script setup>
import { reactive, onBeforeMount, onMounted } from "vue";
import DashboardLayout from "@components/Dashboard/Layout.vue";
import BuilderRaw from "@components/Builder/Raw.vue";
import BuilderRaw from "@components/Builder/RawMode.vue";
import { useGlobal } from "@utils/global";
/**
* @name Page/Raw.vue
* @description This component is the raw page.
This page displays the raw form and additionnal actions to manage or create a service.
*/
* @name Page/Raw.vue
* @description This component is the raw page.
* This page displays the raw form and additionnal actions to manage or create a service.
*/
const raw = reactive({
builder: "",

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@ from subprocess import Popen, PIPE
from typing import List
from shutil import rmtree
from re import search, sub
from typing import Union
# We want to get path of the folder where our components are
# The path is "../src/client/dashboard/src/components" from here
@ -11,6 +12,7 @@ from re import search, sub
inputFolder = abspath("../client/dashboard/components")
outputFolderMd = abspath("../client/.widgets-md")
outputFolderPy = abspath("../client/.widgets")
outputFolderWidgets = abspath("../client/widgets")
def run_command(command: List[str]) -> int:
@ -48,6 +50,8 @@ def reset():
rmtree(outputFolderMd, ignore_errors=True)
# Remove all files from the output folder
rmtree(outputFolderPy, ignore_errors=True)
# remove outputfilename
rmtree(outputFolderWidgets, ignore_errors=True)
def vue2js():
@ -62,6 +66,13 @@ def vue2js():
data = folder.read_text()
# Get only the content between <script setup> and </script> tag
script = data.split("<script setup>")[1].split("</script>")[0]
# Get index of jsdoc comments
first_doc_index_start = script.index("/**")
first_doc_index_end = script.index("*/")
if first_doc_index_start != -1 and first_doc_index_end != -1:
# get content before first_doc_index_end
script = script[first_doc_index_start : first_doc_index_end + 2]
# Create a file on the output folder with the same name but with .js extension
fileName = folder.name.replace(".vue", ".js")
dest = Path(outputFolderMd) / fileName
@ -97,46 +108,53 @@ def formatMd():
# Create order using the tag title path of each file
order = []
for file in files:
# Get the title from first line
data = file.read_text()
# Remove everything after a [1]: tag
data = data.split("[1]:")[0]
# Remove ### Table of contents
data = data.replace("### Table of Contents", "")
# Remove everything before the first ## tag
index = data.index("## ")
data = data[index:]
try:
# Get the title from first line
data = file.read_text()
# Remove everything after a [1]: tag
data = data.split("[1]:")[0]
# Remove ### Table of contents
data = data.replace("### Table of Contents", "")
# Remove everything before the first ## tag
index = data.index("## ")
data = data[index:]
# I want to loop on each line
lines = data.split("\n")
line_result = []
for line in lines:
# remove space (so &#x20 or &#32)
line = line.replace("&#x20", "").replace("&#32", "")
# I want to loop on each line
lines = data.split("\n")
line_result = []
for line in lines:
# remove space (so &#x20 or &#32)
line = line.replace("&#x20", "").replace("&#32", "")
if line.startswith("#") and ".vue" in line and "\.vue" in line:
line = line.replace("\.vue", ".vue")
# Case not a param, keep the line as is
if not line.startswith("*"):
line_result.append(line)
continue
# get line without first char
line = "-" + line[1:]
# remove each **[string][num]** pattern in a param by **string**
reg = r"\[\w+\]\[\d+\]"
while search(reg, line):
# get data of the pattern
pattern = search(reg, line).group()
# get content of first bracket
content = pattern.split("][")[0].replace("[", "")
line = line.replace(pattern, f"{content}")
# Case not a param, keep the line as is
if not line.startswith("*"):
line_result.append(line)
continue
# get line without first char
line = "-" + line[1:]
# remove each **[string][num]** pattern in a param by **string**
reg = r"\[\w+\]\[\d+\]"
while search(reg, line):
# get data of the pattern
pattern = search(reg, line).group()
# get content of first bracket
content = pattern.split("][")[0].replace("[", "")
line = line.replace(pattern, f"{content}")
line_result.append(line)
# I can merge the lines
data = "\n".join(line_result)
# update the file with the new content
file.write_text(data)
# I can merge the lines
data = "\n".join(line_result)
# update the file with the new content
file.write_text(data)
except:
print("Error while parsing file", str(file.name))
continue
def md2py():
@ -151,16 +169,21 @@ def md2py():
try:
title = get_py_title(data)
desc = get_py_desc(data)
params = convert_params(get_py_params(data))
params = get_py_params(data)
# Case not params, we don't need to generate the widget
if not params:
continue
params = convert_params(params)
widget = create_widget(title, desc, params)
Path(f"{outputFolderPy}/{title.capitalize()}.py").write_text(widget)
except:
except BaseException as e:
print(e)
print("Error while parsing file", str(file.name))
continue
# Remove widgets-md
rmtree(outputFolderMd, ignore_errors=True)
# rmtree(outputFolderMd, ignore_errors=True)
def get_py_title(data: str) -> str:
@ -175,7 +198,7 @@ def get_py_title(data: str) -> str:
def get_py_desc(data: str) -> str:
# remove first line
desc = "RESUME\n" + "\n".join(data.split("\n")[1:])
desc = "\n".join(data.split("\n")[1:])
# Get line where Parameters string is with at least one # tag before
lines = desc.split("\n")
new_lines = []
@ -198,38 +221,44 @@ def get_py_desc(data: str) -> str:
return desc
def get_py_params(data: str) -> str:
# params will be between ### Parameters and ### Examples
params = data.split("### Parameters")[1].split("### Examples")[0]
list_params = []
lines = params.split("\n")
for line in lines:
if not line.startswith("-"):
continue
# Get first and second ` index
first = line.find("`")
second = line.find("`", first + 1)
param_name = line[first + 1 : second] or None
# Get first and second ** index
first = line.find("**")
second = line.find("**", first + 1)
param_type = line[first + 2 : second] or None
def get_py_params(data: str) -> Union[str, bool]:
try:
# params will be between ### Parameters and ### Examples
if not "### Parameters" in data:
return False
params = data.split("### Parameters")[1].split("### Examples")[0]
list_params = []
lines = params.split("\n")
for line in lines:
if not line.startswith("-"):
continue
# Get first and second ` index
first = line.find("`")
second = line.find("`", first + 1)
param_name = line[first + 1 : second] or None
# Get first and second ** index
first = line.find("**")
second = line.find("**", first + 1)
param_type = line[first + 2 : second] or None
# Check if (optional is in line
default = None
if "(optional, default" in line:
first = line.find("(optional, default")
# get substring starting from the first index
opt_sub = line[first + len("(optional, default") :]
# get the first ` index
first = opt_sub.find("`")
# get the second ` index
default = opt_sub[first + 1 : opt_sub.find("`", first + 1)]
# Check if (optional is in line
default = None
if "(optional, default" in line:
first = line.find("(optional, default")
# get substring starting from the first index
opt_sub = line[first + len("(optional, default") :]
# get the first ` index
first = opt_sub.find("`")
# get the second ` index
default = opt_sub[first + 1 : opt_sub.find("`", first + 1)]
list_params.append({"name": param_name, "type": param_type, "default": default})
list_params.append({"name": param_name, "type": param_type, "default": default})
# remove default key if None
return list_params
# remove default key if None
return list_params
except BaseException as e:
print(e)
print("Error while parsing params")
def convert_params(params: List[dict]) -> List[dict]:
@ -246,105 +275,150 @@ def convert_params(params: List[dict]) -> List[dict]:
"true": "True",
"null": "None",
"undefined": "None",
"uuidv4()": "",
"uuidv4": "",
"contentindex": "",
"contentIndex": "",
}
try:
convert_params = []
for param in params:
if not param.get("name") or not param.get("type"):
continue
convert_params = []
for param in params:
if not param.get("name") or not param.get("type"):
continue
param_type = param.get("type").lower().strip()
param_type = param.get("type").lower().strip()
convert_type = None
if param_type and param_type in convert_types:
convert_type = convert_types[param_type]
convert_type = None
# Case we have only one type
if param_type and param_type and not "(" in param_type and param_type in convert_types:
convert_type = convert_types[param_type]
default = param.get("default")
if default and default in convert_values:
default = convert_values[default]
# Case we have multiple types
if param_type and param_type and "(" in param_type and "|" in param_type:
is_union = True
# We need to remove parenthesis
param_type = param_type.replace("(", "").replace(")", "")
# We need to split by |
param_types = param_type.split("|")
convert_type = "Union["
for param_value in param_types:
if param_value.strip() in convert_types:
convert_type += convert_types[param_value.strip()] + ", "
convert_params.append({"name": param.get("name"), "type": convert_type, "default": default})
# remove last ','
convert_type = convert_type[:-2]
convert_type += "]"
convert_params = [{k: v for k, v in d.items() if v is not None} for d in convert_params]
default = param.get("default")
if default and default in convert_values:
default = convert_values[default]
# order to get first params without "default"
convert_params = sorted(convert_params, key=lambda x: x.get("default") is not None)
convert_params.append({"name": param.get("name"), "type": convert_type, "default": default})
return convert_params
# remove None values
convert_params = [{k: v for k, v in d.items() if v is not None} for d in convert_params]
# sort to get first params without default or type, then params with type but without default, then others
convert_params = sorted(convert_params, key=lambda x: x.get("default") is not None)
convert_params = sorted(convert_params, key=lambda x: x.get("type") is not None)
return convert_params
except BaseException as e:
print(e)
print("Error while converting params")
def create_widget(title: str, desc: str, params: List[dict]):
# Add indentation to desc
desc_lines = desc.split("\n")
desc_indent = []
for line in desc_lines:
desc_indent.append(f" {line}")
desc = "\n".join(desc_indent)
desc = '\n """\n' + desc + '\n """\n'
try:
# Add indentation to desc
desc_lines = desc.split("\n")
desc_indent = []
for line in desc_lines:
desc_indent.append(f" {line}")
desc = "\n".join(desc_indent)
desc = ' """' + desc + ' """\n'
# Create function params with type and optional value if exists
params_str = ""
for param in params:
param_name = param.get("name")
param_type = param.get("type")
param_default = '""' if param.get("default") == "" else param.get("default")
params_str += (
f" {param_name}: {param_type} = {param_default},\n"
if "type" in param and "default" in param
else (f" {param_name}: {param_type},\n" if "type" in param else f" {param_name},\n")
)
# Create function params with type and optional value if exists
params_str = ""
for param in params:
param_name = param.get("name")
param_type = param.get("type")
param_default = '""' if param.get("default") == "" else param.get("default")
params_str += (
f" {param_name}: {param_type} = {param_default},\n"
if "type" in param and "default" in param
else (f" {param_name}: {param_type},\n" if "type" in param else f" {param_name},\n")
)
# remove last ',' in params_str
params_str = params_str[:-2]
# remove last ',' in params_str
params_str = params_str[:-2]
# By default, we set on data dict the values without default value (means value are needed)
data = " data = {\n"
for param in params:
if "default" in param:
continue
param_name = param.get("name")
data += f""" "{param_name}" : {param_name},\n"""
data += " }\n"
# By default, we set on data dict the values without default value (means value are needed)
data = " data = {\n"
for param in params:
if "default" in param:
continue
param_name = param.get("name")
data += f""" "{param_name}" : {param_name},\n"""
data += " }\n"
# Check to add keys if value is not default value
add_keys_not_default = ""
for param in params:
if not "default" in param:
continue
param_name = param.get("name")
param_default = '""' if param.get("default") == "" else param.get("default")
add_keys_not_default += f""" add_key_value("{param_name}", {param_name}, {param_default})\n"""
# Check to add keys if value is not default value
add_keys_not_default = ""
for param in params:
if not "default" in param:
continue
param_name = param.get("name")
param_default = '""' if param.get("default") == "" else param.get("default")
add_keys_not_default += f""" add_key_value(data, "{param_name}", {param_name}, {param_default})\n"""
add_keys_not_default_function = ""
if add_keys_not_default:
add_keys_not_default = " # List of params that will be add only if not default value\n" + add_keys_not_default
if add_keys_not_default:
add_keys_not_default = " # List of params that will be add only if not default value\n" + add_keys_not_default
# Utils function to add key value to data dict if not default value
add_keys_not_default_function = """
# Add params to data dict only if value is not the default one
def add_key_value(key, value, default):
if value == default:
return
data[key] = value
"""
widget_function = f"""
widget_function = f"""
def {title}_widget(
{params_str}
):
{desc}
{data}
{add_keys_not_default_function}
{add_keys_not_default}
return {{ "type" : "{title.capitalize()}", "data" : data }}
"""
return widget_function
return {{
"type" : "{title.capitalize()}",
"data" : data
}}
except BaseException as e:
print(e)
print("Error while creating widget")
"""
return widget_function
def merge_widgets():
# Create widgets.py file
Path(outputFolderWidgets).mkdir(parents=True, exist_ok=True)
# Create widgets.py
Path(f"{outputFolderWidgets}/widgets.py").write_text("")
content = """
from typing import Union
# Add params to data dict only if value is not the default one
def add_key_value(data, key, value, default):
if value == default:
return
data[key] = value
"""
# get all files from the output folder
files = list(Path(outputFolderPy).rglob("*"))
for file in files:
data = file.read_text()
content += data
content += "\n"
# Utils function to add key value to data dict if not default value
Path(f"{outputFolderWidgets}/widgets.py").write_text(content)
# Remove py folder
rmtree(outputFolderPy, ignore_errors=True)
# Remove md folder
rmtree(outputFolderMd, ignore_errors=True)
# install_npm_packages()
@ -353,3 +427,4 @@ vue2js()
js2md()
formatMd()
md2py()
merge_widgets()