diff --git a/index.html b/index.html index fdc87bd..d2d8aa2 100644 --- a/index.html +++ b/index.html @@ -4,8 +4,9 @@ - + + Scriptor v1.0 diff --git a/public/icon-scriptor.ico b/public/icon-scriptor.ico new file mode 100644 index 0000000..0c1c415 Binary files /dev/null and b/public/icon-scriptor.ico differ diff --git a/src/App.vue b/src/App.vue index 7695b37..342963e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -41,6 +41,8 @@ export default { setup(){ + const checkLoginInterval = ref(); + const globalStore = useGlobalStore(); let isLoggedIn = ref(false); let isLoading = ref(true); @@ -60,21 +62,31 @@ export default { isLoading.value = false; } - onBeforeMount(async () => { - try { + async function checkLogin(allowInit = false) { + try { let resp = await Request.get("/vi/user/view/self"); let data = await resp.json(); isLoggedIn.value = true; global.user = data.values; - await init(); + + if (allowInit) + await init(); //messageStore.addMessage("debug", "Text-Nachricht", "Ich bin ein Text"); + } catch (error) { isLoggedIn.value = false; messageStore.addMessage("error", t("error.title.login"), t("error.text.login")); } + } + + onBeforeMount(async () => { + await checkLogin(true); + setInterval(async () => { + await checkLogin(); + }, 1000 * 60 * 5) }); return {isLoggedIn, isLoading, globalStore} diff --git a/src/assets/scriptor/__init__.py b/src/assets/scriptor/__init__.py index cca291b..042f906 100644 --- a/src/assets/scriptor/__init__.py +++ b/src/assets/scriptor/__init__.py @@ -39,6 +39,17 @@ class prototypes: tree = TreeModule + +def params(): + params = {} + if is_pyodide_context(): + from manager import params + + params = params.to_py() + + return params + + viur.prototypes = prototypes() try: @@ -49,5 +60,3 @@ class prototypes: async def init(): resp = await viur.request.get("/config", renderer="vi") viur.modules = resp["modules"] - if is_pyodide_context(): - console.log("response = ", resp) diff --git a/src/assets/scriptor/csvwriter.py b/src/assets/scriptor/csvwriter.py index b53efa2..5819884 100644 --- a/src/assets/scriptor/csvwriter.py +++ b/src/assets/scriptor/csvwriter.py @@ -1,4 +1,4 @@ -from .writer import MemoryWriter, DirectoryPickerWriter +from .writer import MemoryWriter, FilePickerWriter from .utils import is_pyodide_context if is_pyodide_context(): @@ -7,6 +7,8 @@ import csv import json +from .logger import Logging as logging + class MemoryCsvWriter(MemoryWriter): """ @@ -18,7 +20,6 @@ class MemoryCsvWriter(MemoryWriter): def __init__(self, *args, delimiter=";", formatter: callable = None): super().__init__() self._content.write("\ufeff") # excel needs this for right utf-8 decoding - if args: self._writer = csv.DictWriter( self._content, @@ -39,7 +40,6 @@ def __init__(self, *args, delimiter=";", formatter: callable = None): self._formatter: callable = formatter - @property def writer(self): return self._writer @@ -56,10 +56,6 @@ def fmt(self, value): if isinstance(value, list): ret = ", ".join([self.fmt(v) for v in value]) - if is_pyodide_context(): - console.log(ret) - else: - print(ret) return ret elif isinstance(value, dict): return json.dumps(value, sort_keys=True) @@ -85,47 +81,52 @@ async def write(self, values: object): def __str__(self): return self._content.getvalue() -class FileSystemCsvWriter(MemoryCsvWriter): +class FileSystemCsvWriter(FilePickerWriter): """ Writer for CSV exports """ DEFAULT_FILE_NAME = "export.csv" - def __init__(self, *args, delimiter=";", formatter: callable = None, on_startup: callable = None): - super().__init__(*args, delimiter=delimiter, formatter=formatter) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._columns = [] + self._writer: MemoryWriter = None + self._delimiter = ";" + self._formatter = None + + def set_formatter(self, formatter: callable): + self._formatter = formatter - if len(args) > 0: - self.clear() + def set_columns(self, columns: list[str]): + self._columns = columns + + def set_delimiter(self, delimiter: str): + self._delimiter = delimiter - self._directory_writer = None - self._on_startup = on_startup - self._file = None - + async def flush(self): + if self._writer is None: + return + + content = str(self._writer) + if content: + ## Flushing the header + await super().write(content) - async def init(self): - await DirectoryPickerWriter.from_dialog(self.startup) - async def startup(self, handle): - await self._on_startup(handle) + self._writer.clear() - async def write(self, values: object): - if isinstance(values, dict): - assert isinstance(self._writer, csv.DictWriter) - self._writer.writerow({k: self.fmt(v) for k, v in values.items() if k in self._writer.fieldnames}) - self.clear() - self._line_count += 1 - elif isinstance(values, list): - if isinstance(self._writer, csv.DictWriter): - for row in values: - self.write(row) - else: - self._writer.writerow([self.fmt(v) for v in values]) + async def __aenter__(self): + self._writer = MemoryCsvWriter(*self._columns, delimiter=self._delimiter, formatter=self._formatter) + await super().__aenter__() - if self._file: - self._file.write(str(self)) + async def __aexit__(self, *args): + await self.flush() + await super().__aexit__(*args) - self.clear() - self._line_count += 1 - else: - raise NotImplementedError(f"Don't know what to do with {repr(values)}") + async def write(self, values: object, should_flush: bool = False): + if self._writer is not None: + await self._writer.write(values) + + if should_flush: + await self.flush() diff --git a/src/assets/scriptor/dialog.py b/src/assets/scriptor/dialog.py index b0d455d..b4ef922 100644 --- a/src/assets/scriptor/dialog.py +++ b/src/assets/scriptor/dialog.py @@ -81,7 +81,6 @@ async def input(text: str, *, title: str = "Input", type: str = "input", use_tim manager.resultValue = None if type == "date": - js.console.error(tmp) return datetime.datetime.fromtimestamp(math.floor(tmp/1000.0)) return tmp diff --git a/src/assets/scriptor/readers.py b/src/assets/scriptor/readers.py index 952a48d..e196da8 100644 --- a/src/assets/scriptor/readers.py +++ b/src/assets/scriptor/readers.py @@ -11,7 +11,6 @@ class FilePickerReader(Picker): async def on_startup(self): if is_pyodide_context(): self._content = await (await self._file.getFile()).text() - console.log(f"content_type:{type(self._content)}") else: self._content = self._file.read() diff --git a/src/assets/scriptor/writer.py b/src/assets/scriptor/writer.py index d1df64c..49ae057 100644 --- a/src/assets/scriptor/writer.py +++ b/src/assets/scriptor/writer.py @@ -70,7 +70,7 @@ def __str__(self) -> str: return self._content.getvalue() def clear(self): - self._content.truncate() + self._content.truncate(0) def download(self, name: str = ""): diff --git a/src/components/CodeEditor.vue b/src/components/CodeEditor.vue index a8a7de2..56fc5ca 100644 --- a/src/components/CodeEditor.vue +++ b/src/components/CodeEditor.vue @@ -56,7 +56,6 @@ function editorFromTextArea(textarea: HTMLTextAreaElement, extensions: any) tabStore.updateCode(props.keyValue, currentCode.value) - console.log("currentCode.value", currentCode.value, "initialCode.value", initialCode.value) }; diff --git a/src/components/CodeTab.vue b/src/components/CodeTab.vue index 7181aac..0f38955 100644 --- a/src/components/CodeTab.vue +++ b/src/components/CodeTab.vue @@ -92,37 +92,28 @@ import { ProgressbarDetails } from '@/usepython/dist/interfaces'; const error = ref(""); function acceptAlert() { - console.log("alert!"); pythonStore.py.sendDialogResult("alert", {}).then(() => { - console.log("sended succesfully!!"); }); } function confirmSelect(value: boolean) { - console.log("alert!"); pythonStore.py.sendDialogResult("alert", value).then(() => { - console.log("value succesfully!!"); }); } function sendInput(value: any) { - console.log("alert!"); pythonStore.py.sendDialogResult("input", value).then(() => { - console.log("value succesfully!!"); }); } function sendSelect(value: any) { - console.log("alert!"); pythonStore.py.sendDialogResult("select", value).then(() => { - console.log("value sendSelect!!"); }); } function getThemeByLevel(level: string) { - console.log("level", level); switch (level) { case "debug": return "neutral"; diff --git a/src/components/Dialogs/Dialog.vue b/src/components/Dialogs/Dialog.vue index 2f36e1d..ebaaf10 100644 --- a/src/components/Dialogs/Dialog.vue +++ b/src/components/Dialogs/Dialog.vue @@ -59,8 +59,6 @@ if (!props.data.prefix) { props.data.prefix = ""; } -console.log(`Props id: ${props.data.id}`) - const dialog = ref(); const inputText = ref(props.data.initialText ? props.data.initialText : ""); const inputTextColorClass = ref(""); @@ -69,11 +67,6 @@ onMounted(() => { dialog.value.show(); }) -watch(inputText, (a, b) => { - console.log(inputText.value); -}) - - const dialogStore = useDialogStore(); function destroyDialog() { dialogStore.close(props.data.id); diff --git a/src/components/FileExplorer/FileTree.vue b/src/components/FileExplorer/FileTree.vue index 502d329..3a3d2a1 100644 --- a/src/components/FileExplorer/FileTree.vue +++ b/src/components/FileExplorer/FileTree.vue @@ -78,9 +78,7 @@ export default { let showList = []; for (let child in children) { - console.log(children[child].renderElement) if (text) { - console.log("label:", children[child].label, "includes: ", children[child].label.includes(text)) children[child].renderElement = children[child].label.toLowerCase().includes(text.toLowerCase()); if (children[child].renderElement) showList.push(children[child].parentObject) @@ -374,18 +372,13 @@ export default { // Select a item from children (left click) selectItem: function(element: HTMLDivElement, key: string, skipSave: boolean = false, callback: Function = null) { - console.log("Select ", element, " key", key) let _entry = tree.find(key); if (_entry === null) { - console.log(tree.data.value, " value ", key) console.error("Cannot find element ", element, " key", key) return; } - - console.log("Select ", element, " key", key) - if (!_entry.parent) { globalStore.setLoading(true); @@ -398,12 +391,9 @@ export default { props.onSelectItem(); props.manager.showMirror(); - console.log("view", res); tabStore.addTab(key, res.values.name, res.values.script); - console.log("tabStore.tabMap", tabStore.tabMap); - globalStore.setLoading(false); if (callback) @@ -420,6 +410,7 @@ export default { }, create: async function () { + const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); async function perform() { @@ -429,7 +420,6 @@ export default { for (let i in parents) { let parent = parents[i]; if (!tree.isExistingLabel(parent.name, iter.children)) { - console.log("Creating Parent with plugin: ", parent.name, " plugin state:", parent.plugin) let new_children = { label: parent.name, key: parent.key, @@ -464,15 +454,12 @@ export default { } - - console.log("parents:", parents, "Abc children: ", new_children) iter.children.push(new_children); iter = new_children; } else { let children = iter.children; iter = tree.getChildrenByLabel(parent.name, children); - console.log("iter is ", iter) } } @@ -482,7 +469,9 @@ export default { await Request.get("/json/script/listRootNodes").then(async (answer: Response) => { let res = await answer.json(); let rootNode = res[0]; - console.log("rootNode", res); + if (route.query.rkey) + rootNode = {key: route.query.rkey} + tree.data.value.key = rootNode.key; async function create() { @@ -497,11 +486,9 @@ export default { }); const data = await resp.json(); - console.log("abc!!!", data); for (let index in data["skellist"]) { const skel: any = data["skellist"][index]; - console.log("SKel data!!!", skel); tree.data.value.children.push({ label: skel.name, @@ -525,7 +512,6 @@ export default { for (let index in res["skellist"]) { let entry = res["skellist"][index]; - console.log("wdwdwdwdw:", entry) let resolveChildrenLeaf = async function (parents = [], parentkey) { let resp_leaf = await Request.list("script", { @@ -540,7 +526,6 @@ export default { if (iter) { - console.log("iter is ", iter); let path = "/"; let isPlugin = false; @@ -569,7 +554,6 @@ export default { if (isPlugin) { if (path && _entry) { let file_path = path + _entry.name; - console.log("file_path_", file_path); await pythonStore.py.write(path, "/" + _entry.name, _entry.script); } } @@ -579,7 +563,6 @@ export default { } else { - console.error("Iter is no defined.") } }; @@ -603,7 +586,6 @@ export default { parents_copy.push(_entry); //console.log("lOG SCRIPT:", _entry) - console.log("Parent:", parents_copy, "entry", _entry) createParents(parents_copy); @@ -652,7 +634,6 @@ export default { await create(); } - console.log(tree.data); }); @@ -704,10 +685,8 @@ export default { move: async function(node_key: string, leaf_key: string){ let node = tree.find(node_key); let leaf = tree.find(leaf_key); - console.log("tree", tree.data.value.children) if (node === null || leaf === null) { console.error("Failed to move unknown node key: ", node_key, " or unknown leaf key:", leaf_key); - console.log("node: ", node, "leaf: ", leaf) return; } @@ -785,7 +764,7 @@ export default { group: "leaf" }).then (async (res) => { let data = await res.json(); - const code = data.values.script.length <= 0 ? "#### scriptor ####" : data.values.script; + const code = data.values.script.length <= 0 ? pythonStore.defaultCode : data.values.script; await this.add(parentKey, "leaf", name, "", code); messageStore.addMessage("success", t("tree.action.clone.success.title"), "") @@ -793,14 +772,13 @@ export default { messageStore.addMessage("error", t("tree.action.clone.failed.title"), "") globalStore.setLoading(false); - console.log(e); }) }, - add: function (parentKey: string, type: string, name: string, path: string, code: string = "#### scriptor ####"){ + add: function (parentKey: string, type: string, name: string, path: string, code: string = pythonStore.defaultCode){ globalStore.setLoading(true); Request.securePost(`/vi/script/add/${type}/${parentKey}`, { @@ -812,7 +790,6 @@ export default { path: path } }).then(async (res) => { - console.log("added:", res, res.ok); let data = await res.json(); if (data.action === "addSuccess") { @@ -851,7 +828,6 @@ export default { }, group: type }).then(async (res) => { - console.log("edit:", res, res.ok); let data = await res.json(); if (data.action === "editSuccess") { @@ -917,7 +893,6 @@ export default { remove: function(key: string){ let entry = tree.find(key); if (entry === null) { - console.log(`There is no node by key ${entry}`); return; } @@ -930,30 +905,21 @@ export default { Request.delete("script", key, { group: entry.parent ? "node" : "leaf" }).then(async (res) => { - console.log("delete:", res, res.ok); if (res.ok) { - console.log("I'm here!") if (tree.isPluginItem(key)) { - console.log("I'm here 1!") let path = tree.getPath(key); - console.log("I'm here 2!") let element = tree.find(key); - console.log("I'm here [6] SEARCHING!!") if (entry.parent === "node") { - console.log("I'm here REMOVE DIR!") await pythonStore.py.removeDir("/" + path + element.label); - console.log("I'm here 2!") } else { - console.log("I'm here REMOVE file!") await pythonStore.py.removeFile("/" + path, element.label); } - console.log("I'm here 3!") } @@ -985,7 +951,6 @@ export default { getMyPath: tree.getMyPath, getPath: tree.getPath, saveCode: function(key: string, code: string, callback: Function = null){ - console.log( "saved length:", code.split(/\r\n|\r|\n/).length) //const key = tree.selectedFile.value; globalStore.setLoading(true); Request.edit("script", key, { @@ -996,11 +961,9 @@ export default { }).then(async (resp) => { const data = await resp.json(); if (data.action === 'editSuccess') { - console.log("Saved properly!") if (tree.isPluginItem(key)) { let element = tree.find(key); let path = tree.getPath(key); - console.log("LOG_SAVE:", "path: ", path, " element.name: ", element.label) await pythonStore.py.write("/" + path, element.label, code); } props.manager.save(); diff --git a/src/components/FileExplorer/FileTreeItem.vue b/src/components/FileExplorer/FileTreeItem.vue index b9c0024..52560d7 100644 --- a/src/components/FileExplorer/FileTreeItem.vue +++ b/src/components/FileExplorer/FileTreeItem.vue @@ -122,10 +122,7 @@ export default { }) const classList = ref<[]>(["item-inner-wrap"]); - console.log("mymodel", props.model) - function toggle(event: UIEvent) { - console.log("Toggle!!"); if (props.model.parent) { // eslint-disable-next-line vue/no-mutating-props props.model.state.toggle(); @@ -135,7 +132,6 @@ export default { } function click(event: UIEvent) { - console.log("detail:", event.detail) if(event.detail === 1) { @@ -150,7 +146,6 @@ export default { event.dataTransfer.dropEffect = 'move' event.dataTransfer.effectAllowed = 'move' event.dataTransfer.setData('key', props.model.key); - console.log("key: ", props.model.key) } function dragLeave(event) { @@ -166,7 +161,6 @@ export default { if (key !== props.model.key) { props.helper.move(props.model.key, key); - console.log("recv key", key); } } @@ -175,7 +169,6 @@ export default { // console.log("is parent", props.model.parent) element.value.ondragover = (event) => { - console.log("on drag over", event.dataTransfer.getData('key')); if (event.dataTransfer.getData('key') !== props.model.key) { if (!classList.value.includes("accept-drop")) classList.value.push("accept-drop"); @@ -200,14 +193,12 @@ export default { watch(() => props.model.parent, (first, second) => { if (props.model.parent) { - console.log("Before Mount: !!!") props.model.state.init(); } }); onBeforeMount(function(){ if (props.model.parent) { - console.log("Before Mount: !!!") if (props.model.state) { props.model.state.init(); } @@ -224,7 +215,6 @@ export default { // Download-File Request.view("script", props.model.key, {group:"leaf"}).then(async function(response) { const data = (await response.json()).values; - console.log(data); const blob1 = new Blob([data["script"]], { type: "text/plain" }); const url = window.URL.createObjectURL(blob1); @@ -327,7 +317,6 @@ export default { }); } - console.log(item.value); } diff --git a/src/components/Home.vue b/src/components/Home.vue index dd49a7f..c2b29f5 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -3,7 +3,16 @@
-

Script0r

+ + +
+ +

Script0r

+ +
+
@@ -81,6 +90,11 @@ {{ t("safe") }} + + {{ t("share") }} + + + {{ t("run") }} @@ -133,8 +147,6 @@ export default { const tabStore = useTabStore(); const route = useRoute(); - console.log("params:", route.query) - const { t } = useI18n() // call `useI18n`, and spread `t` from `useI18n` returning @@ -200,6 +212,22 @@ export default { } } + function shareScript(){ + if (!route.query.key) { + console.error("Cant share without an opened tab!"); + return; + } + + let _url = window.location.origin+"/#"+"/runner/"+route.query.key; + + console.log(import.meta.env.MODE) + if (import.meta.env.MODE === "production") + _url = window.location.origin+"/scriptor/index.html"+"#"+"/runner/"+route.query.key; + + messageStore.addMessage("success", "The shared link got copied into the clipboard.", "") + navigator.clipboard.writeText(_url); + } + function runScript(){ if (tabStore.selectedTab) { let content = tabStore.tabMap[tabStore.selectedTab]; @@ -225,7 +253,6 @@ export default { for (let index in data.modules) { let moduleEntry = data.modules[index]; - console.log("index", index, "moduleEntry", moduleEntry) modules.value.push( { name: index, @@ -254,6 +281,7 @@ export default { onChangeCode, manager, saveScript, + shareScript, runScript, tree, isLoading, @@ -267,6 +295,9 @@ export default { interruptCode, showGeneralLogs, pythonStore, + canShare: computed(function(){ + return route.query.key; + }), t } } @@ -304,6 +335,7 @@ export default { font-weight: 700; z-index: 1; padding: 10px 15px 15px 15px; + display: flex } .log-format { @@ -605,4 +637,11 @@ div.cm-content { } +.logo { + width: 55px; + height: 55px; + background-color: transparent !important; +} + + diff --git a/src/components/Interaction/Alert.vue b/src/components/Interaction/Alert.vue index ef1470b..f45bcbf 100644 --- a/src/components/Interaction/Alert.vue +++ b/src/components/Interaction/Alert.vue @@ -2,7 +2,7 @@
- {{ t('Alert') }} + {{ t('alert') }}

diff --git a/src/components/Interaction/Confirm.vue b/src/components/Interaction/Confirm.vue index b02b294..cead519 100644 --- a/src/components/Interaction/Confirm.vue +++ b/src/components/Interaction/Confirm.vue @@ -13,7 +13,7 @@ {{ t('no')}} {{ t('cancel') }} + size="small" v-if="props.cancel" variant="neutral" :class="'accept-button ' + ((selectedValue != -1 && selectedValue !== undefined) ? 'selected-button' : '')" @click="() => confirm(-1)">{{ t('cancel') }} {{ t('yes') }}

diff --git a/src/components/Interaction/Input.vue b/src/components/Interaction/Input.vue index b3c6865..a8c5558 100644 --- a/src/components/Interaction/Input.vue +++ b/src/components/Interaction/Input.vue @@ -9,7 +9,8 @@ {{ props.text }}

- {{ error }} + {{ error }} + @@ -102,5 +103,8 @@ function send() { font-size: var(--sl-font-size-medium); } +.error-message { + margin-bottom: 15px; +} diff --git a/src/components/Interaction/Select.vue b/src/components/Interaction/Select.vue index 8b5027f..d976440 100644 --- a/src/components/Interaction/Select.vue +++ b/src/components/Interaction/Select.vue @@ -9,7 +9,7 @@

- + {{ props.options[option] }}
@@ -50,7 +50,9 @@ const {t} = useI18n(); const entries = []; -function selectOption(index: number) { +const selectedOption = ref(-1); + +function selectOption(index: number, _index: number) { if (!render.value) return; @@ -58,6 +60,8 @@ function selectOption(index: number) { render.value = false; props.select(index); + + selectedOption.value = _index; } function selectRadioButton(event: UIEvent, index: string) { diff --git a/src/components/Messaging/MessageDrawer.vue b/src/components/Messaging/MessageDrawer.vue index d172c64..8e401d8 100644 --- a/src/components/Messaging/MessageDrawer.vue +++ b/src/components/Messaging/MessageDrawer.vue @@ -15,7 +15,7 @@
- tag.startsWith('sl-'); app.provide("global", global) diff --git a/src/router/index.js b/src/router/index.js index ab08c4b..9a704cb 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,5 +1,7 @@ import { createRouter, createWebHashHistory } from 'vue-router' import Home from '../components/Home.vue' +import Runner from '../views/Runner.vue' + import Interactions from '../views/Interactions.vue'; const routes = [ @@ -14,6 +16,12 @@ const routes = [ component: Home }, + { + path: '/runner/:key', + name: 'Runner', + component: Runner + }, + { path: '/interactions', name: 'Interactions', diff --git a/src/stores/PythonStore.ts b/src/stores/PythonStore.ts index 6148c0a..4a9808b 100644 --- a/src/stores/PythonStore.ts +++ b/src/stores/PythonStore.ts @@ -3,6 +3,7 @@ import { ref } from 'vue'; import { defineStore } from 'pinia' import { usePython} from "usepython"; import { useTabStore } from './TabStore'; +import { useRoute } from 'vue-router'; interface PyEvents @@ -28,12 +29,10 @@ export const usePythonStore = defineStore('python', () => { onLog(val.stdOut[entry]); } } - console.log("LOG", val.stdOut); // val.stdErr is also available } else { - console.log("Exception:", val.exception) if (scriptRunnerTab.value) { @@ -73,7 +72,6 @@ export const usePythonStore = defineStore('python', () => { async function init(key: string, onLogCallback: Function, onErrorCallback: Function, onRunCallback: Function) { - console.log("on init!") eventMap.value[key] = { logCallback: onLogCallback, errorCallback: onErrorCallback, @@ -88,8 +86,9 @@ export const usePythonStore = defineStore('python', () => { } const timer = ref(); + const defaultCode = "#### scriptor ####\nfrom scriptor import dialog\n\nasync def main():\n await dialog.alert(\"Hello World\")"; - let runScript = function (code: string){ + let runScript = function (code: string, name: string = undefined, key: string = undefined){ let extraCode = "from scriptor import print, init as __scriptor__init\nawait __scriptor__init()\n"; if (code.includes("async def main():")) code += "\nawait main()" @@ -97,8 +96,14 @@ export const usePythonStore = defineStore('python', () => { if (py.isExecuting.get() === true) return; - let tabName = tabStore.tabMap[tabStore.selectedTab].name; - + + let tabName = ""; + + if (name) + tabName = name; + else + tabName = tabStore.tabMap[tabStore.selectedTab].name; + runningText.value = "Running " + tabName + " "; if (timer.value) @@ -116,11 +121,14 @@ export const usePythonStore = defineStore('python', () => { } }, 150) - scriptRunnerTab.value = tabStore.selectedTab; + if (key) + scriptRunnerTab.value = key; + else + scriptRunnerTab.value = tabStore.selectedTab; + isExecuting.value = true; if (scriptRunnerTab.value) { - console.log(eventMap.value, scriptRunnerTab.value) let onRun = eventMap.value[scriptRunnerTab.value].runCallback; if (onRun) onRun(); @@ -136,6 +144,8 @@ export const usePythonStore = defineStore('python', () => { }); }; + const route = useRoute(); + async function loadPython() { isLoading.value = true; @@ -151,8 +161,6 @@ export const usePythonStore = defineStore('python', () => { const zipUrl = new URL('../assets/scriptor.zip', import.meta.url).href - console.log("zipUrl:", zipUrl); - // Loading scriptor library await py.run(` from pyodide.http import pyfetch @@ -160,6 +168,29 @@ export const usePythonStore = defineStore('python', () => { await response.unpack_archive() `) + let object = {}; + + + if (route.query["scriptor_params"]) { + + if (typeof route.query.scriptor_params === 'string') + { + try { + let _string = route.query.scriptor_params.replace(/'/g, '"');; + object = JSON.parse(_string) + } + catch(error) { + console.error(error) + } + } + else + { + object = route.query.scriptor_params; + } + } + + await py.sendParams(object) + isLoading.value = false; } @@ -186,5 +217,5 @@ export const usePythonStore = defineStore('python', () => { } - return { py, run, setCode, getCode, init, runScript, loadPython, reloadPyodide, isLoading, scriptRunnerTab, isExecuting, runningText } + return { py, run, setCode, getCode, init, runScript, loadPython, reloadPyodide, isLoading, scriptRunnerTab, isExecuting, runningText, defaultCode } }) diff --git a/src/stores/TabStore.ts b/src/stores/TabStore.ts index b9604d5..c42753f 100644 --- a/src/stores/TabStore.ts +++ b/src/stores/TabStore.ts @@ -47,7 +47,7 @@ export const useTabStore = defineStore('tab', () => { let getTabCode = (key: string) => { let code = tabMap.value[key].code; - if (code.length > 1) + if (code.length > 1 && code[code.length-1] === '\n') code = code.substring(0, code.length - 1); return code; @@ -64,13 +64,10 @@ export const useTabStore = defineStore('tab', () => { let index = tabList.value.indexOf(item); if (index-1>=0) { item.leftNode = tabList.value[index-1]; - console.log("Adding index ", index, " leftNode ", index-1); } if (index + 1 < tabList.value.length){ item.rightNode = tabList.value[index+1]; - console.log("Adding index ", index, " rightNode ", index+1); - console.log("Right node = ", item.rightNode); } }); } @@ -82,7 +79,6 @@ export const useTabStore = defineStore('tab', () => { return item.key !== key; }); - console.log("Adding code", code) tabMap.value[key] = { name: name, code: code, @@ -106,7 +102,6 @@ export const useTabStore = defineStore('tab', () => { }, 200); - console.log("TabGroup SHow: ", key) } } @@ -120,7 +115,6 @@ export const useTabStore = defineStore('tab', () => { } ) - console.log("Calling selectTab Tab", selectedTab.value); } } @@ -140,7 +134,6 @@ export const useTabStore = defineStore('tab', () => { }, 200); - console.log("TabGroup SHow: ", key) } return true; @@ -173,11 +166,9 @@ export const useTabStore = defineStore('tab', () => { if (tabInstance.leftNode !== undefined) { nextIndex = _keys.indexOf(tabInstance.leftNode.key); - console.log("left node instance:", tabInstance.leftNode); } if (tabInstance.rightNode !== undefined) { - console.log("right node instance:", tabInstance.rightNode); if (nextIndex === -1) nextIndex = _keys.indexOf(tabInstance.rightNode.key); } @@ -188,10 +179,6 @@ export const useTabStore = defineStore('tab', () => { nextIndex = indexOfTab; } - console.log("NextIndex: ", nextIndex) - - console.log(tabMap.value); - selectedTab.value = ""; if (_keys.length > 0) { if (nextIndex === -1) @@ -209,6 +196,9 @@ export const useTabStore = defineStore('tab', () => { } }, 250); } + else { + router.push({}) + } } diff --git a/src/stores/log.ts b/src/stores/log.ts index 11b99c6..a17a0a0 100644 --- a/src/stores/log.ts +++ b/src/stores/log.ts @@ -19,7 +19,6 @@ export const useLogStore = defineStore("log", () => { function getThemeByLevel(level: string) { - console.log("level", level); switch (level) { case "debug": return "neutral"; @@ -50,18 +49,13 @@ export const useLogStore = defineStore("log", () => { if (!(pythonStore.scriptRunnerTab in logMap.value)) logMap.value[pythonStore.scriptRunnerTab] = ref([]); - //console.log("Notify: python logging", val) - //console.log("pythonStore.scriptRunnerTab:", pythonStore.scriptRunnerTab, " props.keyValue: ", props.keyValue); { - console.error("pythonStore.py.pyLogging"); for (let i = 0; i { async function _dispatchEvent(id: string, data: Record) { - console.log("Python process id recv", id, " data ", data); switch (data.type) { case "end": { @@ -466,13 +465,22 @@ const usePython = () => { return new Promise((onSuccess) => { //_callback = onSuccess; - console.log("IM HERE!"); _pyodideWorker.postMessage({ id: "_sendDialogSignal", ...context, }); }); } + + function sendParams(params: object) { + return new Promise((onSuccess) => { + _callback = onSuccess; + _pyodideWorker.postMessage({ + id: "setParams", + params + }); + }); + } @@ -499,7 +507,8 @@ const usePython = () => { interruptExecution, destroyAndCreateWorker, restoreFS, - sendDialogResult + sendDialogResult, + sendParams } } diff --git a/src/usepython/src/webworker.js b/src/usepython/src/webworker.js index 5d828fe..2021c60 100644 --- a/src/usepython/src/webworker.js +++ b/src/usepython/src/webworker.js @@ -37,6 +37,7 @@ let manager = { allocId: 0, currentProcessId: 0, tasks: {}, + params: {}, resultValue: null, copyResult: function() { return structuredClone(this.resultValue); @@ -105,12 +106,10 @@ async function runScript(python, id) { //console.log("Load imports") await self.pyodide.loadPackagesFromImports(python); let empty_dict = await self.pyodide.runPythonAsync("{}"); - console.log("abc!!!"); //let results = await self.pyodide.globals.get("pyeval")(python, empty_dict) //empty_dict.destroy(); manager.currentProcessId = ++manager.allocId; - console.log("Ich bin hier!!!"); manager.tasks[manager.currentProcessId] = { "promise": self.pyodide.globals.get("pyeval")(python, empty_dict), "dict": empty_dict, @@ -122,7 +121,6 @@ async function runScript(python, id) { manager.tasks[processId]["promise"].then(() => { manager.tasks[processId]["done"] = true; manager.tasks[processId]["dict"].destroy(); - console.log("Task done!"); run_end(id); }).catch((error) => { @@ -134,8 +132,6 @@ async function runScript(python, id) { err(id, error.message) }) - console.log("End of file!"); - } catch (error) { console.log("PY RUN ERR", error) err(id, error.message) @@ -146,7 +142,6 @@ self.onmessageerror = e => { } self.onmessage = async (event) => { const { id, python, ...context } = event.data; - console.log("Recv message ", id, " python: ", python, " context:", context); if (id === "_pyinstaller") { await loadPyodideAndPackages(id, context.pyoPackages, context.packages, context.initCode, context.transformCode); run_end(id) @@ -156,9 +151,6 @@ self.onmessage = async (event) => { if (context === undefined) return; - console.log("Starting ! name", context.name, " path:", context.path, " python: ", python) - - let _path = context.path.substring(1); let _dirs = _path.split("/"); let value = {}; @@ -170,34 +162,27 @@ self.onmessage = async (event) => { value = self.pyodide.FS.analyzePath(_tmp_path); _tmp_path.replaceAll("//", "/"); - console.log("Temp Path:", _tmp_path) if (!value.exists) { self.pyodide.FS.mkdir(_tmp_path); } } - console.log("I'm here! Write!", context.name, python, "FileSystem:", self.pyodide.FS) value = self.pyodide.FS.analyzePath(context.path); if (!value.exists) { self.pyodide.FS.mkdir(context.path); - console.log("I'm here2! Creating Path:", context.path) } let file_path = context.path+context.name; file_path.replaceAll("//", "/"); - console.log(`Path for writing! ${file_path}`) value = self.pyodide.FS.analyzePath(file_path); if (value.exists) { self.pyodide.FS.unlink(file_path); //self.pyodide.FS.ftruncate(file_path, 0); - console.log(`[SEARCHING] Path exists: ${file_path}`) } self.pyodide.FS.writeFile(file_path, python, {encoding: "utf-8"}) - console.log("I'm here3! Write!", context.name, python) - console.log("I'm here4! Write!", context.name, python) end(id); } @@ -272,13 +257,14 @@ self.onmessage = async (event) => { { manager.resultValue = context.handle; } - else if (id === "_sendDialogSignal") { - - manager.resultValue = context.data; - console.log("_sendDialogSignal recv", manager.resultValue); - end(id); - -} + else if (id === "_sendDialogSignal") { + manager.resultValue = context.data; + end(id); + } + else if (id === "setParams") { + manager.params = context.params; + end(id); + } else { // The worker copies the context in its own "memory" (an object mapping name to values) @@ -292,8 +278,6 @@ self.onmessage = async (event) => { throw new Error("Python is not loaded") } - console.log("Functions:", context.showSaveFilePicker, " other", context.showDirectoryPicker) - manager.resultValue = null; await self.pyodide.registerJsModule("manager", manager); diff --git a/src/views/Interactions.vue b/src/views/Interactions.vue index d3e34f5..00ad404 100644 --- a/src/views/Interactions.vue +++ b/src/views/Interactions.vue @@ -13,7 +13,7 @@ -
{{ "result = await alert('Hey')" }}
+
{{ "await alert('Das ist eine Nachricht')" }}
@@ -25,18 +25,18 @@

Confirm

- + -
result = await confirm("Artikel löschen", "Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.", cancel=True)
+
result = await confirm("Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.", allow_cancel=True)
- + -
result = await confirm("Artikel löschen", "Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.")
+
result = await confirm("Willst du wirklich alle Einträge löschen? Das Löschen kann nicht wieder rückgängig gemacht werden.")
@@ -46,41 +46,41 @@

Inputs

- + -
result = await input.string("Zeichenkette", "type='string'", empty=False)
+
result = await input.string("type='string'", empty=False)
- + -
result = await input.date("Datum", "type='date'", empty=False)
+
result = await input.date("type='date'", empty=False)
- + -
result = await input.number("Nummer", "type='number'", empty=False)
+
result = await input.number("type='number'", empty=False)
- + -
result = await input.text("Text", "type='text'", empty=False)
+
result = await input.text("type='text'", empty=False)
- + -
result = await input.date("Datum", "type='date'", use_time=True, empty=False)
+
result = await input.date("type='date'", use_time=True, empty=False)
@@ -91,21 +91,21 @@

Selects

- +
{{ 'choices = ["A", "B"]\n' 
-		+ 'ret = await select("Select (not multiple)", "A oder B", choices)'}}
+		+ 'ret = await select("Select (not multiple)", choices) '}}
 
- +
{{ "choices = ['A', 'B', 'C', 'D', 'E', 'T', 'G']\n"
-		+ 'ret = await select("Select (multiple)", "A, B, C, D, ....", choices)'}}
+		+ 'ret = await select("Select (multiple)", choices)'}}
 
@@ -121,7 +121,7 @@ import Input from "../components/Interaction/Input.vue"; import Select from "../components/Interaction/Select.vue"; function confirmValue(value: String) { - console.log("confirmValue:", value) + } diff --git a/src/views/Runner.vue b/src/views/Runner.vue new file mode 100644 index 0000000..b7c0736 --- /dev/null +++ b/src/views/Runner.vue @@ -0,0 +1,123 @@ + + + + \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 5365c74..b8ae9aa 100644 --- a/vite.config.js +++ b/vite.config.js @@ -9,11 +9,6 @@ import mv from "rollup-plugin-mv"; // https://vitejs.dev/config/ const APPNAME = "scriptor" -console.log( path.join(__dirname, 'html')) -console.log( path.join(__dirname, "scriptor.html")) -console.log( path.join(path.dirname(require.resolve('@viur/viur-shoelace/dist/shoelace.js')), "assets")) -console.log( path.join("..","..","deploy",'static',APPNAME,"*")) -console.log( path.join(__dirname, 'public', "../", 'static', APPNAME, "viur-shoelace")) export default defineConfig(({command, mode})=>{ let conf = { css: {