diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py
index 837a26c6..fffef6c3 100644
--- a/backend/app_sdk/app_base.py
+++ b/backend/app_sdk/app_base.py
@@ -57,47 +57,68 @@ class AppBase:
# - How can you download / stream a file?
# - Can you decide if you want a stream or the files directly?
def get_file(self, value):
- print("INSIDE GET_FILE")
-
full_execution = self.full_execution
org_id = full_execution["workflow"]["execution_org"]["id"]
print("SHOULD GET FILES BASED ON ORG %s, workflow %s and value(s) %s" % (org_id, full_execution["workflow"]["id"], value))
- get_path = "/api/v1/files/%s?execution_id=%s" % (value, full_execution["execution_id"])
- headers = {
- "Content-Type": "application/json",
- "Authorization": "Bearer %s" % self.authorization
- }
+ if isinstance(value, list):
+ print("IS LIST!")
+ #if len(value) == 1:
+ # value = value[0]
+ else:
+ value = [value]
- ret1 = requests.get("%s%s" % (self.url, get_path), headers=headers)
- print("RET1: %s" % ret1.text)
- if ret1.status_code != 200:
+ returns = []
+ for item in value:
+ print("VALUE: %s" % item)
+ if len(item) != 36:
+ print("Bad length for value")
+ continue
+ #return {
+ # "filename": "",
+ # "data": "",
+ # "success": False,
+ #}
+
+ get_path = "/api/v1/files/%s?execution_id=%s" % (item, full_execution["execution_id"])
+ headers = {
+ "Content-Type": "application/json",
+ "Authorization": "Bearer %s" % self.authorization
+ }
+
+ ret1 = requests.get("%s%s" % (self.url, get_path), headers=headers)
+ print("RET1: %s" % ret1.text)
+ if ret1.status_code != 200:
+ returns.append({
+ "filename": "",
+ "data": "",
+ "success": False,
+ })
+ continue
+
+ content_path = "/api/v1/files/%s/content?execution_id=%s" % (item, full_execution["execution_id"])
+ ret2 = requests.get("%s%s" % (self.url, content_path), headers=headers)
+ print("Ret2: %s" % ret2.text)
+ if ret2.status_code == 200:
+ tmpdata = ret1.json()
+ returndata = {
+ "success": True,
+ "filename": tmpdata["filename"],
+ "data": ret2.content,
+ }
+ returns.append(returndata)
+
+ if len(returns) == 0:
return {
- "filename": "",
- "data": "",
"success": False,
+ "filename": "",
+ "data": b"",
}
-
- content_path = "/api/v1/files/%s/content?execution_id=%s" % (value, full_execution["execution_id"])
- ret2 = requests.get("%s%s" % (self.url, content_path), headers=headers)
- print("Ret2: %s" % ret2.text)
- if ret2.status_code == 200:
- tmpdata = ret1.json()
- returndata = {
- "success": True,
- "filename": tmpdata["filename"],
- "data": ret2.content,
- }
- # open('facebook.ico', 'wb').write(r.content)
-
- return returndata
-
- return {
- "success": False,
- "filename": "",
- "data": b"",
- }
+ elif len(returns) == 1:
+ return returns[0]
+ else:
+ return returns
# Sets files in the backend
def set_files(self, infiles):
@@ -522,6 +543,7 @@ class AppBase:
# Magical way of returning which makes app sdk identify
# it as multi execution
return newvalue, True
+
elif len(actualitem) > 0:
# FIXME: This is absolutely not perfect.
print("In recursion v2: ", actualitem)
@@ -704,7 +726,7 @@ class AppBase:
print("SET DATA WRAPPER TO %s!" % parsersplit[-1])
parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data))
- print("Before last return")
+ print("Before last return with %s" % appendresult)
return str(parseditem)+str(appendresult), is_loop
# Parses parameters sent to it and returns whether it did it successfully with the values found
@@ -1205,15 +1227,22 @@ class AppBase:
if listitem in filteredlist:
continue
- filteredlist.append(listitem)
+ # FIXME: Subsub required?. Recursion!
+ # Basically multiply what we have with the outer loop?
+ #
+ if isinstance(listitem, list):
+ for subitem in listitem:
+ filteredlist.append(subitem)
+ else:
+ filteredlist.append(listitem)
#print("New list length: %d" % len(filteredlist))
if len(filteredlist) > 1:
print("Calculating new multi-loop length with %d lists" % len(filteredlist))
tmplength = 1
for innerlist in filteredlist:
- print("List length: %d. %d*%d" % (len(innerlist), len(innerlist), tmplength))
tmplength = len(innerlist)*tmplength
+ print("List length: %d. %d*%d" % (tmplength, len(innerlist), tmplength))
minlength = tmplength
@@ -1257,6 +1286,7 @@ class AppBase:
except ValueError:
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
print("Can't handle type %s value from function" % (type(newres)))
+
print("POST NEWRES RESULT: ", result)
else:
print("APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters))
@@ -1286,7 +1316,6 @@ class AppBase:
if isinstance(value, list):
try:
newvalue = value[i]
- print("NEWVALUE: %s" % newvalue)
except IndexError:
pass
diff --git a/backend/go-app/files.go b/backend/go-app/files.go
index 026c8e26..a2856e2b 100644
--- a/backend/go-app/files.go
+++ b/backend/go-app/files.go
@@ -1,7 +1,7 @@
package main
/*
- Handles files within Workflows.
+ Handles files within Workflows.of Shuffle
*/
import (
diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index 403a2920..742d3b65 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -6813,7 +6813,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
respBody, err := ioutil.ReadAll(newresp.Body)
if err != nil {
- log.Printf("Failed body read in job sync: %s", err)
+ log.Printf("[ERROR] Failed body read in job sync: %s", err)
return err
}
@@ -6821,7 +6821,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
err = remoteOrgJobController(org, respBody)
if err != nil {
- log.Printf("Failed job controller run: %s", err)
+ log.Printf("[ERROR] Failed job controller run for %s: %s", respBody, err)
return err
}
return nil
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index bf28ebe1..70307a82 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -5765,7 +5765,7 @@ func getWorkflowExecutions(resp http.ResponseWriter, request *http.Request) {
}
// Query for the specifci workflowId
- q := datastore.NewQuery("workflowexecution").Filter("workflow_id =", fileId).Order("-started_at").Limit(20)
+ q := datastore.NewQuery("workflowexecution").Filter("workflow_id =", fileId).Order("-started_at").Limit(30)
var workflowExecutions []WorkflowExecution
_, err = dbclient.GetAll(ctx, q, &workflowExecutions)
if err != nil {
diff --git a/docker-compose.yml b/docker-compose.yml
index c496eb65..014798f3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3'
services:
frontend:
#build: ./frontend
- image: ghcr.io/frikky/shuffle-frontend:0.8.0
+ image: ghcr.io/frikky/shuffle-frontend:0.8.3
container_name: shuffle-frontend
hostname: shuffle-frontend
ports:
@@ -17,7 +17,7 @@ services:
- backend
backend:
build: ./backend
- image: ghcr.io/frikky/shuffle-backend:0.8.11
+ image: ghcr.io/frikky/shuffle-backend:0.8.3
container_name: shuffle-backend
hostname: ${BACKEND_HOSTNAME}
# Here for debugging:
diff --git a/frontend/src/views/Apps.jsx b/frontend/src/views/Apps.jsx
index 9bb8dda4..69ed1dc1 100644
--- a/frontend/src/views/Apps.jsx
+++ b/frontend/src/views/Apps.jsx
@@ -116,7 +116,7 @@ const Apps = (props) => {
const [apps, setApps] = React.useState([])
const [filteredApps, setFilteredApps] = React.useState([])
const [validation, setValidation] = React.useState(false)
- const [isLoading, setIsLoading] = React.useState(false)
+ const [isLoading, setIsLoading] = React.useState(true)
const [appSearchLoading, setAppSearchLoading] = React.useState(false)
const [selectedAction, setSelectedAction] = React.useState({})
const [searchBackend, setSearchBackend] = React.useState(false)
@@ -207,6 +207,7 @@ const Apps = (props) => {
credentials: "include",
})
.then((response) => {
+ setIsLoading(false)
if (response.status !== 200) {
console.log("Status not 200 for apps :O!")
}
@@ -231,6 +232,7 @@ const Apps = (props) => {
})
.catch(error => {
alert.error(error.toString())
+ setIsLoading(false)
});
}
@@ -742,7 +744,7 @@ const Apps = (props) => {
+ Shuffle is a flexible, easy to use, automation platform allowing users to integrate their services and devices freely. It's made to significantly reduce the amount of manual labor, and is focused on security applications. Click here to learn more. +
+- Shuffle is a flexible, easy to use, automation platform allowing users to integrate their services and devices freely. It's made to significantly reduce the amount of manual labor, and is focused on security applications. Click here to learn more. -
-