Added HTTP catch-all failures and file namespace downloads
This commit is contained in:
@@ -12,6 +12,8 @@ import urllib3
|
|||||||
import hashlib
|
import hashlib
|
||||||
from liquid import Liquid
|
from liquid import Liquid
|
||||||
import liquid
|
import liquid
|
||||||
|
import zipfile
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
class AppBase:
|
class AppBase:
|
||||||
__version__ = None
|
__version__ = None
|
||||||
@@ -615,7 +617,23 @@ class AppBase:
|
|||||||
print("\nLOOP: %s\nRESULTS: %s" % (loop_wrapper, results))
|
print("\nLOOP: %s\nRESULTS: %s" % (loop_wrapper, results))
|
||||||
return 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:
|
# Things to consider for files:
|
||||||
# - How can you download / stream a file?
|
# - How can you download / stream a file?
|
||||||
@@ -2656,6 +2674,19 @@ class AppBase:
|
|||||||
action_result["status"] = "FAILURE"
|
action_result["status"] = "FAILURE"
|
||||||
action_result["result"] = "Function %s is not callable." % actionname
|
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:
|
except Exception as e:
|
||||||
print(f"Failed to execute: {e}")
|
print(f"Failed to execute: {e}")
|
||||||
self.logger.exception(f"Failed to execute {e}-{action['id']}")
|
self.logger.exception(f"Failed to execute {e}-{action['id']}")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
### DEFAULT
|
### DEFAULT
|
||||||
NAME=shuffle-app_sdk
|
NAME=shuffle-app_sdk
|
||||||
VERSION=0.9.10
|
VERSION=0.9.11
|
||||||
|
|
||||||
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
|
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
|
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
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ const ParsedAction = (props) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const changeActionParameter = (event, count, data) => {
|
const changeActionParameter = (event, count, data) => {
|
||||||
console.log(event)
|
//console.log(event)
|
||||||
if (data.name.startsWith("${") && data.name.endsWith("}")) {
|
if (data.name.startsWith("${") && data.name.endsWith("}")) {
|
||||||
// PARAM FIX - Gonna use the ID field, even though it's a hack
|
// PARAM FIX - Gonna use the ID field, even though it's a hack
|
||||||
const paramcheck = selectedAction.parameters.find(param => param.name === "body")
|
const paramcheck = selectedAction.parameters.find(param => param.name === "body")
|
||||||
@@ -833,12 +833,12 @@ const ParsedAction = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const clickedFieldId = "rightside_field_"+count
|
const clickedFieldId = "rightside_field_"+count
|
||||||
|
//<TextareaAutosize
|
||||||
|
// <CodeMirror
|
||||||
var datafield =
|
var datafield =
|
||||||
//<TextareaAutosize
|
<TextField
|
||||||
|
|
||||||
<CodeMirror
|
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
style={{backgroundColor: theme.palette.inputColor, borderRadius: theme.palette.borderRadius, border: selectedActionParameters[count].required || selectedActionParameters[count].configuration ? "2px solid #f85a3e" : "", color: "white", width: "100%", fontSize: "1em",}}
|
style={{backgroundColor: theme.palette.inputColor, borderRadius: theme.palette.borderRadius, border: selectedActionParameters[count].required || selectedActionParameters[count].configuration ? "2px solid #f85a3e" : "", color: "white", width: "100%", fontSize: "1em", }}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style:{
|
style:{
|
||||||
color: "white",
|
color: "white",
|
||||||
@@ -847,23 +847,23 @@ const ParsedAction = (props) => {
|
|||||||
maxWidth: "95%",
|
maxWidth: "95%",
|
||||||
fontSize: "1em",
|
fontSize: "1em",
|
||||||
},
|
},
|
||||||
// endAdornment: (
|
endAdornment: (
|
||||||
// hideExtraTypes ? null :
|
hideExtraTypes ? null :
|
||||||
// <InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
// <Tooltip title="Autocomplete the text" placement="top">
|
<Tooltip title="Autocomplete the text" placement="top">
|
||||||
// <AddCircleOutlineIcon style={{cursor: "pointer"}} onClick={(event) => {
|
<AddCircleOutlineIcon style={{cursor: "pointer"}} onClick={(event) => {
|
||||||
// setMenuPosition({
|
setMenuPosition({
|
||||||
// top: event.pageY+10,
|
top: event.pageY+10,
|
||||||
// left: event.pageX+10,
|
left: event.pageX+10,
|
||||||
// })
|
})
|
||||||
// setShowDropdownNumber(count)
|
setShowDropdownNumber(count)
|
||||||
// setShowDropdown(true)
|
setShowDropdown(true)
|
||||||
// setShowAutocomplete(true)
|
setShowAutocomplete(true)
|
||||||
// }}/>
|
}}/>
|
||||||
// </Tooltip>
|
</Tooltip>
|
||||||
// </InputAdornment>
|
</InputAdornment>
|
||||||
|
|
||||||
// )
|
)
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
multiline={multiline}
|
multiline={multiline}
|
||||||
@@ -879,20 +879,20 @@ const ParsedAction = (props) => {
|
|||||||
rows={rows}
|
rows={rows}
|
||||||
color="primary"
|
color="primary"
|
||||||
defaultValue={data.value}
|
defaultValue={data.value}
|
||||||
|
//value={data.value}
|
||||||
value={data.value}
|
//options={{
|
||||||
options={{
|
// theme: 'gruvbox-dark',
|
||||||
theme: 'gruvbox-dark',
|
// keyMap: 'sublime',
|
||||||
keyMap: 'sublime',
|
// mode: 'python',
|
||||||
mode: 'python',
|
//}}
|
||||||
}}
|
//height={multiline ? 50 : 150}
|
||||||
height = {200}
|
|
||||||
|
|
||||||
type={placeholder.includes("***") || (data.configuration && (data.name.toLowerCase().includes("api") || data.name.toLowerCase().includes("key") || data.name.toLowerCase().includes("pass"))) ? "password" : "text"}
|
type={placeholder.includes("***") || (data.configuration && (data.name.toLowerCase().includes("api") || data.name.toLowerCase().includes("key") || data.name.toLowerCase().includes("pass"))) ? "password" : "text"}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
changeActionParameterCodemirror(event, count, data)
|
//changeActionParameterCodemirror(event, count, data)
|
||||||
|
changeActionParameter(event, count, data)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ?
|
helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ?
|
||||||
|
|||||||
@@ -1612,7 +1612,7 @@ const AngularWorkflow = (props) => {
|
|||||||
var hiddenNodes = []
|
var hiddenNodes = []
|
||||||
const onNodeDragStop = (event, selectedAction) => {
|
const onNodeDragStop = (event, selectedAction) => {
|
||||||
const nodedata = event.target.data()
|
const nodedata = event.target.data()
|
||||||
console.log("IN NODE DRAG STOP: ", nodedata)
|
//console.log("IN NODE DRAG STOP: ", nodedata)
|
||||||
if (nodedata.id === selectedAction.id) {
|
if (nodedata.id === selectedAction.id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export const GetIconInfo = (action) => {
|
|||||||
{"key": "cache_get", "values": ["get_cache"]},
|
{"key": "cache_get", "values": ["get_cache"]},
|
||||||
{"key": "filter", "values": ["filter", "route", "router",]},
|
{"key": "filter", "values": ["filter", "route", "router",]},
|
||||||
{"key": "merge", "values": ["join", "merge"]},
|
{"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": "list", "values": ["list", "head", "options"]},
|
||||||
{"key": "download", "values": ["capture", "get", "download", "return", "hello_world", "curl",]},
|
{"key": "download", "values": ["capture", "get", "download", "return", "hello_world", "curl",]},
|
||||||
{"key": "add", "values": ["add"]},
|
{"key": "add", "values": ["add"]},
|
||||||
|
|||||||
Reference in New Issue
Block a user