From 2947e1d57ea3c9b7b1cd206cbb4c64532308f5db Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 21 Jan 2021 14:50:15 +0100 Subject: [PATCH] #204: Added app creator file upload possibility --- backend/go-app/codegen.go | 68 +++++++++++++++++++++----- backend/go-app/walkoff.go | 2 + frontend/src/views/AngularWorkflow.jsx | 5 +- frontend/src/views/AppCreator.jsx | 46 +++++++++++++++-- 4 files changed, 103 insertions(+), 18 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index ee182ef6..506019e4 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -244,7 +244,7 @@ func buildStructure(swagger *openapi3.Swagger, curHash string) (string, error) { // This function generates the python code that's being used. // This is really meta when you program it. Handling parameters is hard here. -func makePythoncode(swagger *openapi3.Swagger, name, url, method string, parameters, optionalQueries, headers []string) (string, string) { +func makePythoncode(swagger *openapi3.Swagger, name, url, method string, parameters, optionalQueries, headers []string, fileField string) (string, string) { method = strings.ToLower(method) queryString := "" queryData := "" @@ -368,17 +368,19 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet fileBalance := "" fileAdder := `` fileGrabber := `` - if method == "post" && strings.Contains(functionname, "filescan") { - fileGrabber = `filedata = self.get_file("63264006-5958-451a-bff1-1975495fb4d8")` + fileParameter := `` + if method == "post" && len(fileField) > 0 { + fileGrabber = `filedata = self.get_file(file_id)` //fileGrabber += "\n print(filedata)" - fileAdder = `files = {"file": (filedata["filename"], filedata["data"])}` + fileAdder = fmt.Sprintf(`files = {"%s": (filedata["filename"], filedata["data"])}`, fileField) fileBalance = ", files=files" + fileParameter = ", file_id" } // Extra param for url if it's changeable // Extra param for authentication scheme(s) // The last weird one is the body.. Tabs & spaces sucks. - data := fmt.Sprintf(` async def %s(self%s%s%s%s%s%s): + data := fmt.Sprintf(` async def %s(self%s%s%s%s%s%s%s): %s url=f"%s%s" %s @@ -392,6 +394,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet functionname, authenticationParameter, urlParameter, + fileParameter, parameterData, queryString, bodyParameter, @@ -412,7 +415,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet fileBalance, ) - if strings.Contains(functionname, "get_list_rulesssss") { + if strings.Contains(functionname, "filescan") { //log.Printf("FUNCTION: %s", data) log.Println(data) log.Printf("Queries: %s", queryString) @@ -1097,7 +1100,7 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "connect", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "connect", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname @@ -1232,7 +1235,7 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "get", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "get", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname @@ -1365,7 +1368,7 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "head", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "head", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname @@ -1499,7 +1502,7 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "delete", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "delete", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname @@ -1542,6 +1545,40 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo }, }) + fileField := "" + if path.Post.RequestBody != nil { + //log.Printf("DATA: %#v", + value := path.Post.RequestBody.Value + //log.Printf("VAL: %#v", value.Content) + if val, ok := value.Content["multipart/form-data"]; ok { + if val.Schema.Value != nil { + if innerval, ok := val.Schema.Value.Properties["fieldname"]; ok { + if extensionvalue, ok := innerval.Value.ExtensionProps.Extensions["value"]; ok { + fieldname := extensionvalue.(json.RawMessage) + newName := string(fmt.Sprintf("%s", string(fieldname))) + if newName[0] == 0x22 && newName[len(newName)-1] == 0x22 { + parsedName := newName[1 : len(newName)-1] + log.Printf("Parse name: %s", parsedName) + fileField = parsedName + + curParam := WorkflowAppActionParameter{ + Name: "file_id", + Description: "Files to be uploaded", + Multiline: false, + Required: true, + Schema: SchemaDefinition{ + Type: "string", + }, + } + + action.Parameters = append(action.Parameters, curParam) + } + } + } + } + } + } + headersFound := []string{} if len(path.Post.Parameters) > 0 { for counter, param := range path.Post.Parameters { @@ -1631,12 +1668,17 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "post", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "post", parameters, optionalQueries, headersFound, fileField) if len(functionname) > 0 { action.Name = functionname } + //log.Printf("PARAMS: %d", len(action.Parameters)) + //for _, param := range action.Parameters { + // log.Printf("%#v", param) + //} + return action, curCode } @@ -1764,7 +1806,7 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "patch", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "patch", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname @@ -1898,7 +1940,7 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor action.Parameters = append(action.Parameters, optionalParam) } - functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "put", parameters, optionalQueries, headersFound) + functionname, curCode := makePythoncode(swagger, functionName, baseUrl, "put", parameters, optionalQueries, headersFound, "") if len(functionname) > 0 { action.Name = functionname diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index b5c6b3f5..e18fe110 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -2718,6 +2718,8 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { Errors: workflow.Errors, } + cacheKey := fmt.Sprintf("workflowapps-sorted") + requestCache.Delete(cacheKey) log.Printf("Saved new version of workflow %s (%s) for org %s", workflow.Name, fileId, workflow.OrgId) resp.WriteHeader(200) newBody, err := json.Marshal(returndata) diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 6605e386..c7b17747 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -2611,7 +2611,7 @@ const AngularWorkflow = (props) => { const allitems = workflow.actions.concat(workflow.triggers) for (var key in allitems) { const item = allitems[key] - if (item.app_name === appName) { + if (item.app_name === appName && item.label !== undefined && item.label !== null) { var number = item.label.split("_") if (isNaN(number[-1]) && parseInt(number[number.length-1]) > highest) { highest = number[number.length-1] @@ -7108,6 +7108,9 @@ const AngularWorkflow = (props) => { } + //if (authenticationOption.label === null + // defaultValue={} + return (
diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 82c28446..6978dd08 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -19,6 +19,7 @@ import DialogActions from '@material-ui/core/DialogActions'; import TextField from '@material-ui/core/TextField'; import Tooltip from '@material-ui/core/Tooltip'; import CheckCircleIcon from '@material-ui/icons/CheckCircle'; +import AttachFileIcon from '@material-ui/icons/AttachFile'; import Breadcrumbs from '@material-ui/core/Breadcrumbs'; import AppsIcon from '@material-ui/icons/Apps'; import CircularProgress from '@material-ui/core/CircularProgress'; @@ -551,7 +552,19 @@ const AppCreator = (props) => { //JSON.stringify(tmpobject, null, 2) } } - console.log("NOT APPLICATION/JSON: ", methodvalue["requestBody"]["content"]) + + console.log(methodvalue["requestBody"]["content"]) + if (methodvalue["requestBody"]["content"]["multipart/form-data"] !== undefined) { + if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"] !== undefined) { + if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["type"] === "object") { + const fieldname = methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["properties"]["fieldname"] + if (fieldname !== undefined) { + console.log("FIELDNAME: ", fieldname) + newaction.file_field = fieldname["value"] + } + } + } + } } } } @@ -820,7 +833,12 @@ const AppCreator = (props) => { "summary": item.name, "operationId": item.name.split(" ").join("_"), "description": item.description, - "parameters": [] + "parameters": [], + "requestBody": { + "content": { + + } + }, } //console.log("ACTION: ", item) @@ -966,6 +984,20 @@ const AppCreator = (props) => { // https://swagger.io/docs/specification/describing-request-body/file-upload/ if (item.file_field !== undefined && item.file_field !== null && item.file_field.length > 0) { console.log("HANDLE FILEFIELD SAVE: ", item.file_field) + data.paths[item.url][item.method.toLowerCase()]["requestBody"]["content"]["multipart/form-data"] = { + + "schema": { + "type": "object", + "properties": { + "fieldname": { + "type": "string", + "value": item.file_field, + }, + }, + }, + } + + console.log(data.paths[item.url][item.method.toLowerCase()]["requestBody"]["content"]["multipart/form-data"]) } if (item.headers.length > 0) { @@ -1319,6 +1351,7 @@ const AppCreator = (props) => { } const url = data.url + const hasFile = data["file_field"] !== undefined && data["file_field"] !== null && data["file_field"].length > 0 return ( {error} @@ -1333,6 +1366,10 @@ const AppCreator = (props) => { if (data["body"] !== undefined && data["body"] !== null && data["body"].length > 0) { findBodyParams(data["body"]) } + + if (hasFile) { + setFileUploadEnabled(true) + } }}>
{ label={data.method} /> - {url} - {data.name} + {hasFile ? : null} {url} - {data.name} +
@@ -1819,7 +1857,7 @@ const AppCreator = (props) => { addPathQuery() }}>New query {currentActionMethod === "POST" ? -