mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
widget py working + fix jsdoc build
This commit is contained in:
parent
f01f916b3f
commit
e3da25e221
18 changed files with 4094 additions and 192 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=""]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=""]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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=""]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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: "",
|
||||
|
|
|
|||
3825
src/ui/client/widgets/widgets.py
Normal file
3825
src/ui/client/widgets/widgets.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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   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()
|
||||
|
|
|
|||
Loading…
Reference in a new issue