diff --git a/docs/vue2md.py b/docs/vue2md.py index d9331ef8d..3cef076e8 100644 --- a/docs/vue2md.py +++ b/docs/vue2md.py @@ -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 or ) line = line.replace(" ", "").replace(" ", "") + 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) diff --git a/src/ui/client/dashboard/components/Builder/Raw.vue b/src/ui/client/dashboard/components/Builder/RawMode.vue similarity index 96% rename from src/ui/client/dashboard/components/Builder/Raw.vue rename to src/ui/client/dashboard/components/Builder/RawMode.vue index 5178a50a4..9f36186aa 100644 --- a/src/ui/client/dashboard/components/Builder/Raw.vue +++ b/src/ui/client/dashboard/components/Builder/RawMode.vue @@ -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({ diff --git a/src/ui/client/dashboard/components/Dashboard/Feedback.vue b/src/ui/client/dashboard/components/Dashboard/Feedback.vue index 90f0eb975..5d6f4e385 100644 --- a/src/ui/client/dashboard/components/Dashboard/Feedback.vue +++ b/src/ui/client/dashboard/components/Dashboard/Feedback.vue @@ -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. */ diff --git a/src/ui/client/dashboard/components/Dashboard/News.vue b/src/ui/client/dashboard/components/Dashboard/News.vue index 553755e06..3ee5d4dde 100644 --- a/src/ui/client/dashboard/components/Dashboard/News.vue +++ b/src/ui/client/dashboard/components/Dashboard/News.vue @@ -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() { diff --git a/src/ui/client/dashboard/components/Form/Fields.vue b/src/ui/client/dashboard/components/Form/Fields.vue index 34189dd72..861ee965a 100644 --- a/src/ui/client/dashboard/components/Form/Fields.vue +++ b/src/ui/client/dashboard/components/Form/Fields.vue @@ -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({ diff --git a/src/ui/client/dashboard/components/Form/Raw.vue b/src/ui/client/dashboard/components/Form/Raw.vue index 5a3f68911..0253c3bfc 100644 --- a/src/ui/client/dashboard/components/Form/Raw.vue +++ b/src/ui/client/dashboard/components/Form/Raw.vue @@ -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); diff --git a/src/ui/client/dashboard/components/Form/Templates.vue b/src/ui/client/dashboard/components/Form/Templates.vue index b62ada126..0b3531a67 100644 --- a/src/ui/client/dashboard/components/Form/Templates.vue +++ b/src/ui/client/dashboard/components/Form/Templates.vue @@ -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 diff --git a/src/ui/client/dashboard/components/Forms/Field/Checkbox.vue b/src/ui/client/dashboard/components/Forms/Field/Checkbox.vue index 6eec37f5f..95d14829e 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Checkbox.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Checkbox.vue @@ -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=""] diff --git a/src/ui/client/dashboard/components/Forms/Field/Combobox.vue b/src/ui/client/dashboard/components/Forms/Field/Combobox.vue index b939fc89b..0f10a7642 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Combobox.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Combobox.vue @@ -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 diff --git a/src/ui/client/dashboard/components/Forms/Field/Datepicker.vue b/src/ui/client/dashboard/components/Forms/Field/Datepicker.vue index 141cf495e..de4b8a44d 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Datepicker.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Datepicker.vue @@ -52,7 +52,7 @@ import "@assets/css/flatpickr.dark.min.css"; * @param {number} [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=""] diff --git a/src/ui/client/dashboard/components/Forms/Field/Editor.vue b/src/ui/client/dashboard/components/Forms/Field/Editor.vue index f32abe309..23ba58e9b 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Editor.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Editor.vue @@ -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] diff --git a/src/ui/client/dashboard/components/Forms/Field/Input.vue b/src/ui/client/dashboard/components/Forms/Field/Input.vue index 03aafd373..fbc226120 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Input.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Input.vue @@ -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=""] diff --git a/src/ui/client/dashboard/components/Forms/Field/List.vue b/src/ui/client/dashboard/components/Forms/Field/List.vue index 16b9613df..95811743d 100644 --- a/src/ui/client/dashboard/components/Forms/Field/List.vue +++ b/src/ui/client/dashboard/components/Forms/Field/List.vue @@ -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 diff --git a/src/ui/client/dashboard/components/Forms/Field/Select.vue b/src/ui/client/dashboard/components/Forms/Field/Select.vue index b2b0a126d..e729379a8 100644 --- a/src/ui/client/dashboard/components/Forms/Field/Select.vue +++ b/src/ui/client/dashboard/components/Forms/Field/Select.vue @@ -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 diff --git a/src/ui/client/dashboard/components/Forms/Group/Multiple.vue b/src/ui/client/dashboard/components/Forms/Group/Multiple.vue index bed1406c8..14cb2e483 100644 --- a/src/ui/client/dashboard/components/Forms/Group/Multiple.vue +++ b/src/ui/client/dashboard/components/Forms/Group/Multiple.vue @@ -147,7 +147,7 @@ import Container from "@components/Widget/Container.vue"; * } * }, * @param {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 */ diff --git a/src/ui/client/dashboard/pages/raw/Raw.vue b/src/ui/client/dashboard/pages/raw/Raw.vue index ff68cd5ed..3d2de77a9 100644 --- a/src/ui/client/dashboard/pages/raw/Raw.vue +++ b/src/ui/client/dashboard/pages/raw/Raw.vue @@ -1,14 +1,14 @@ tag script = data.split("")[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 or ) - line = line.replace(" ", "").replace(" ", "") + # I want to loop on each line + lines = data.split("\n") + line_result = [] + for line in lines: + # remove space (so or ) + line = line.replace(" ", "").replace(" ", "") + + 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()