diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 4ed95b03..5e859c06 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -12,6 +12,8 @@ import urllib3 import hashlib from liquid import Liquid import liquid +import zipfile +from io import BytesIO class AppBase: __version__ = None @@ -615,7 +617,23 @@ class AppBase: print("\nLOOP: %s\nRESULTS: %s" % (loop_wrapper, results)) return results + # Downloads all files from a namespace + # Currently only working on local version of Shuffle + def get_file_namespace(self, namespace): + org_id = self.full_execution["workflow"]["execution_org"]["id"] + get_path = "/api/v1/files/namespaces/%s?execution_id=%s" % (namespace, self.full_execution["execution_id"]) + headers = { + "Authorization": "Bearer %s" % self.authorization + } + + ret1 = requests.get("%s%s" % (self.url, get_path), headers=headers) + if ret1.status_code != 200: + return None + + filebytes = BytesIO(ret1.content) + myzipfile = zipfile.ZipFile(filebytes) + return myzipfile # Things to consider for files: # - How can you download / stream a file? @@ -2656,6 +2674,19 @@ class AppBase: action_result["status"] = "FAILURE" action_result["result"] = "Function %s is not callable." % actionname + # https://ptb.discord.com/channels/747075026288902237/882017498550112286/882043773138382890 + except (requests.exceptions.RequestException, TimeoutError) as e: + print(f"Failed to execute request: {e}") + self.logger.exception(f"Failed to execute {e}-{action['id']}") + action_result["status"] = "SUCCESS" + try: + action_result["result"] = json.dumps({ + "success": False, + "reason": f"Request error - failing silently. Details: {e}" + }) + except json.decoder.JSONDecodeError as e: + action_result["result"] = f"Request error: {e}" + except Exception as e: print(f"Failed to execute: {e}") self.logger.exception(f"Failed to execute {e}-{action['id']}") diff --git a/backend/app_sdk/build.sh b/backend/app_sdk/build.sh index 4dfe2531..623458b8 100644 --- a/backend/app_sdk/build.sh +++ b/backend/app_sdk/build.sh @@ -3,7 +3,7 @@ ### DEFAULT NAME=shuffle-app_sdk -VERSION=0.9.10 +VERSION=0.9.11 docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force docker build . -f Dockerfile -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index 7bae11dd..d70ee5b6 100644 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -341,7 +341,7 @@ const ParsedAction = (props) => { }) const changeActionParameter = (event, count, data) => { - console.log(event) + //console.log(event) if (data.name.startsWith("${") && data.name.endsWith("}")) { // PARAM FIX - Gonna use the ID field, even though it's a hack const paramcheck = selectedAction.parameters.find(param => param.name === "body") @@ -833,12 +833,12 @@ const ParsedAction = (props) => { } const clickedFieldId = "rightside_field_"+count + // { maxWidth: "95%", fontSize: "1em", }, - // endAdornment: ( - // hideExtraTypes ? null : - // - // - // { - // setMenuPosition({ - // top: event.pageY+10, - // left: event.pageX+10, - // }) - // setShowDropdownNumber(count) - // setShowDropdown(true) - // setShowAutocomplete(true) - // }}/> - // - // - - // ) + endAdornment: ( + hideExtraTypes ? null : + + + { + setMenuPosition({ + top: event.pageY+10, + left: event.pageX+10, + }) + setShowDropdownNumber(count) + setShowDropdown(true) + setShowAutocomplete(true) + }}/> + + + + ) }} fullWidth multiline={multiline} @@ -879,20 +879,20 @@ const ParsedAction = (props) => { rows={rows} color="primary" defaultValue={data.value} - - value={data.value} - options={{ - theme: 'gruvbox-dark', - keyMap: 'sublime', - mode: 'python', - }} - height = {200} + //value={data.value} + //options={{ + // theme: 'gruvbox-dark', + // keyMap: 'sublime', + // mode: 'python', + //}} + //height={multiline ? 50 : 150} type={placeholder.includes("***") || (data.configuration && (data.name.toLowerCase().includes("api") || data.name.toLowerCase().includes("key") || data.name.toLowerCase().includes("pass"))) ? "password" : "text"} placeholder={placeholder} onChange={(event) => { - changeActionParameterCodemirror(event, count, data) + //changeActionParameterCodemirror(event, count, data) + changeActionParameter(event, count, data) }} helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ? diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index daacc7c8..be3abe91 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -1612,7 +1612,7 @@ const AngularWorkflow = (props) => { var hiddenNodes = [] const onNodeDragStop = (event, selectedAction) => { const nodedata = event.target.data() - console.log("IN NODE DRAG STOP: ", nodedata) + //console.log("IN NODE DRAG STOP: ", nodedata) if (nodedata.id === selectedAction.id) { return } diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index 26a0baf7..d30bbde0 100644 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -89,7 +89,7 @@ export const GetIconInfo = (action) => { {"key": "cache_get", "values": ["get_cache"]}, {"key": "filter", "values": ["filter", "route", "router",]}, {"key": "merge", "values": ["join", "merge"]}, - {"key": "search", "values": ["search", "find", "locate", "index",]}, + {"key": "search", "values": ["search", "find", "locate", "index", "analyze", "anal",]}, {"key": "list", "values": ["list", "head", "options"]}, {"key": "download", "values": ["capture", "get", "download", "return", "hello_world", "curl",]}, {"key": "add", "values": ["add"]},