From 581f97be8029da91ecd43c64abe1359ca1cb5a29 Mon Sep 17 00:00:00 2001 From: frikky Date: Sun, 16 Jan 2022 04:36:49 +0100 Subject: [PATCH] Added download as file option to app creator and OpenAPI as a whole --- backend/app_sdk/app_base.py | 1 + backend/go-app/docker.go | 2 +- backend/go-app/go.mod | 2 +- backend/go-app/main.go | 6 +- backend/go-app/walkoff.go | 10 +-- frontend/src/views/AngularWorkflow.jsx | 16 ++-- frontend/src/views/AppCreator.jsx | 118 ++++++++++++++++++------- 7 files changed, 106 insertions(+), 49 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index b907f5ed..e7604c5e 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -2820,6 +2820,7 @@ class AppBase: self.logger.info("[INFO] NO FILES TO HANDLE") tmp_result = { + "success": True, "result": newres[0], "file_ids": file_ids } diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go index f5a74fc7..9b535c72 100644 --- a/backend/go-app/docker.go +++ b/backend/go-app/docker.go @@ -699,7 +699,7 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) { // REBUILDS THE APP if len(img.ID) == 0 { if len(img2.ID) == 0 { - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 0) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 0, 0) log.Printf("[INFO] Getting workflowapps for a rebuild. Got %d with err %#v", len(workflowapps), err) if err == nil { imageName := "" diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index cb72bcbb..0eb5e3b3 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -2,7 +2,7 @@ module main go 1.15 -//replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared +replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi //replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch diff --git a/backend/go-app/main.go b/backend/go-app/main.go index e34d2c91..2eef7eb3 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -4075,7 +4075,7 @@ func runInitEs(ctx context.Context) { // Getting apps to see if we should initialize a test // FIXME: Isn't this a little backwards? - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) log.Printf("[INFO] Getting and validating workflowapps. Got %d with err %#v", len(workflowapps), err) // accept any certificate (might be useful for testing) @@ -4727,7 +4727,7 @@ func runInit(ctx context.Context) { } // Getting apps to see if we should initialize a test - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) log.Printf("[INFO] Getting and validating workflowapps. Got %d with err %s", len(workflowapps), err) if err != nil && len(workflowapps) == 0 { log.Printf("[WARNING] Failed getting apps (runInit): %s", err) @@ -5342,7 +5342,7 @@ func migrateDatabase(resp http.ResponseWriter, request *http.Request) { log.Printf("[DEBUG] Found %d workflows(s) to be migrated", len(workflows)) } - apps, err := shuffle.GetAllWorkflowApps(ctx, 0) + apps, err := shuffle.GetAllWorkflowApps(ctx, 0, 0) if err != nil { log.Printf("[ERROR] Failed getting apps: %#v", err) } else { diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 390187e0..c05c380d 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1655,7 +1655,7 @@ func getWorkflowApps(resp http.ResponseWriter, request *http.Request) { return } - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) if err != nil { log.Printf("{WARNING] Failed getting apps (getworkflowapps): %s", err) resp.WriteHeader(401) @@ -1753,7 +1753,7 @@ func getSpecificApps(resp http.ResponseWriter, request *http.Request) { // FIXME - continue the search here with github repos etc. // Caching might be smart :D ctx := context.Background() - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) if err != nil { log.Printf("Error: Failed getting workflowapps: %s", err) resp.WriteHeader(401) @@ -2030,7 +2030,7 @@ func handleAppHotloadRequest(resp http.ResponseWriter, request *http.Request) { func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string) error { ctx := context.Background() - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) appCounter := 0 if err != nil { log.Printf("Failed to get existing generated apps") @@ -2329,7 +2329,7 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - allapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + allapps, err := shuffle.GetAllWorkflowApps(ctx, 1000, 0) if err != nil { log.Printf("Failed getting apps to verify: %s", err) resp.WriteHeader(401) @@ -2797,7 +2797,7 @@ func IterateAppGithubFolders(ctx context.Context, fs billy.Filesystem, dir []os. } if len(allapps) == 0 { - allapps, err = shuffle.GetAllWorkflowApps(ctx, 0) + allapps, err = shuffle.GetAllWorkflowApps(ctx, 0, 0) if err != nil { log.Printf("[WARNING] Failed getting apps to verify: %s", err) continue diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index eb1debea..764be831 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -1434,7 +1434,7 @@ const AngularWorkflow = (defaultprops) => { //); var tmpFiltered = responseJson.filter((app) => !internalIds.includes(app.name)) - tmpFiltered = sortByKey(tmpFiltered, "activated") + //tmpFiltered = sortByKey(tmpFiltered, "activated") setFilteredApps(tmpFiltered) //!(!app.activated && app.generated) @@ -1806,8 +1806,6 @@ const AngularWorkflow = (defaultprops) => { currentedge.style('control-point-distance', edgeCurve.distance) currentedge.style('control-point-weight', edgeCurve.weight) } - - } if (styledElements.length === 1) { @@ -4028,8 +4026,8 @@ const AngularWorkflow = (defaultprops) => { const destinationnode = actions.find(node => node.data._id === branch.destination_id) if (sourcenode !== undefined && destinationnode !== undefined && branch.source_id !== branch.destination_id) { //node.data._id = action["id"] - console.log("SOURCE: ", sourcenode.position) - console.log("DESTINATIONNODE: ", destinationnode.position) + //console.log("SOURCE: ", sourcenode.position) + //console.log("DESTINATIONNODE: ", destinationnode.position) const edgeCurve = calculateEdgeCurve(sourcenode, destinationnode) edge.style = { @@ -5184,11 +5182,15 @@ const AngularWorkflow = (defaultprops) => { const image = app.large_image; const newAppStyle = JSON.parse(JSON.stringify(paperAppStyle)); const pixelSize = !hover ? "2px" : "4px"; - //) && !(!app.activated && app.generated) - newAppStyle.borderLeft = app.is_valid && app.actions !== null && app.actions !== undefined && app.actions.length > 0 && !(app.activated && app.generated) + //newAppStyle.borderLeft = app.is_valid && app.actions !== null && app.actions !== undefined && app.actions.length > 0 && !(app.activated && app.generated) + newAppStyle.borderLeft = app.is_valid && app.actions !== null && app.actions !== undefined && app.actions.length > 0 ? `${pixelSize} solid ${green}` : `${pixelSize} solid ${yellow}`; + if (!app.activated && app.generated) { + newAppStyle.borderLeft = `${pixelSize} solid ${yellow}`; + } + return ( { diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 17ffeb09..21707116 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -283,6 +283,7 @@ const AppCreator = (defaultprops) => { const [appBuilding, setAppBuilding] = useState(false); const [extraBodyFields, setExtraBodyFields] = useState([]); const [fileUploadEnabled, setFileUploadEnabled] = useState(false); + const [fileDownloadEnabled, setFileDownloadEnabled] = useState(false); const [actionAmount, setActionAmount] = useState(increaseAmount); const defaultAuth = { name: "", @@ -954,6 +955,7 @@ const AppCreator = (defaultprops) => { methodvalue.responses.default.content["text/plain"] !== undefined ) { + console.log("RESP: ", path, methodvalue.responses.default.content["text/plain"]) if ( methodvalue.responses.default.content["text/plain"][ "schema" @@ -967,8 +969,13 @@ const AppCreator = (defaultprops) => { newaction.example_response = methodvalue.responses.default.content["text/plain"][ "schema" - ]["example"]; + ]["example"] + } + + if (methodvalue.responses.default.content["text/plain"]["schema"]["format"] === "binary" && methodvalue.responses.default.content["text/plain"]["schema"]["type"] === "string") { + newaction.example_response = "shuffle_file_download" + } } } } @@ -1636,6 +1643,7 @@ const AppCreator = (defaultprops) => { item.name = item.description; } + // Basic way to allow multiple of the same path var pathjoin = item.url+"_"+item.method.toLowerCase() if (handledPaths.includes(pathjoin)) { @@ -1699,38 +1707,60 @@ const AppCreator = (defaultprops) => { if ( item.example_response !== undefined && + item.example_response !== null && item.example_response.length > 0 ) { - // FIXME: Shallow copy of the string - var showResult = Object.assign("", item.example_response).trim(); - showResult = showResult.split(" None").join(' "None"'); - showResult = showResult.split("'").join('"'); - showResult = showResult.split(" False").join(" false"); - showResult = showResult.split(" True").join(" true"); - var jsonvalid = true; - try { - const tmp = String(JSON.parse(showResult)); - if (!showResult.includes("{") && !showResult.includes("[")) { - jsonvalid = false; - } - } catch (e) { - jsonvalid = false; - } + if (item["example_response"] === "shuffle_file_download") { + console.log("Download as file: ", item) - data.paths[item.url][item.method.toLowerCase()].responses["default"][ - "content" - ]["text/plain"].schema.type = "string"; - if (jsonvalid) { - // FIXME: Add a JSON parser here - don't run it as a string. - data.paths[item.url][item.method.toLowerCase()].responses["default"][ - "content" - ]["text/plain"].schema.example = showResult; - } else { - data.paths[item.url][item.method.toLowerCase()].responses["default"][ - "content" - ]["text/plain"].schema.example = item.example_response; - } + data.paths[item.url][item.method.toLowerCase()].responses["default"]["content"]["text/plain"].schema.type = "string" + data.paths[item.url][item.method.toLowerCase()].responses["default"]["content"]["text/plain"].schema.format = "binary" + + /* + schema: + type: object + properties: + username: + type: string + avatar: # <-- image embedded into JSON + type: string + format: byte + description: Base64-encoded contents of the avatar image + */ + + } else { + // FIXME: Shallow copy of the string + var showResult = Object.assign("", item.example_response).trim(); + showResult = showResult.split(" None").join(' "None"'); + showResult = showResult.split("'").join('"'); + showResult = showResult.split(" False").join(" false"); + showResult = showResult.split(" True").join(" true"); + + var jsonvalid = true; + try { + const tmp = String(JSON.parse(showResult)); + if (!showResult.includes("{") && !showResult.includes("[")) { + jsonvalid = false; + } + } catch (e) { + jsonvalid = false; + } + + data.paths[item.url][item.method.toLowerCase()].responses["default"][ + "content" + ]["text/plain"].schema.type = "string"; + if (jsonvalid) { + // FIXME: Add a JSON parser here - don't run it as a string. + data.paths[item.url][item.method.toLowerCase()].responses["default"][ + "content" + ]["text/plain"].schema.example = showResult; + } else { + data.paths[item.url][item.method.toLowerCase()].responses["default"][ + "content" + ]["text/plain"].schema.example = item.example_response; + } + } } if (item.queries.length > 0) { @@ -2915,9 +2945,10 @@ const AppCreator = (defaultprops) => { const url = data.url; const hasFile = - data["file_field"] !== undefined && + (data["file_field"] !== undefined && data["file_field"] !== null && - data["file_field"].length > 0; + data["file_field"].length > 0) || data["example_response"] === "shuffle_file_download" + return ( {error} @@ -3135,7 +3166,7 @@ const AppCreator = (defaultprops) => { ) : null; - const exampleResponse = ( + const exampleResponse = fileDownloadEnabled ? null : (
Example success response { Enable Fileupload ) : null} + {currentActionMethod === "GET" ? ( + + ) : null} {fileUploadEnabled ? (