Fixed openapi3 config download bugs

This commit is contained in:
frikky
2020-06-01 15:57:06 +02:00
parent acb4b3da8c
commit e11d58c239
6 changed files with 97 additions and 60 deletions
+15 -15
View File
@@ -247,8 +247,6 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
queryString := "" queryString := ""
queryData := "" queryData := ""
log.Printf("URL START: %s", url)
// FIXME - this might break - need to check if ? or & should be set as query // FIXME - this might break - need to check if ? or & should be set as query
parameterData := "" parameterData := ""
if len(optionalQueries) > 0 { if len(optionalQueries) > 0 {
@@ -337,7 +335,6 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
// Extra param for url if it's changeable // Extra param for url if it's changeable
// Extra param for authentication scheme(s) // Extra param for authentication scheme(s)
log.Printf("URL OTHER: %s", url)
data := fmt.Sprintf(` async def %s(self%s%s%s%s%s): data := fmt.Sprintf(` async def %s(self%s%s%s%s%s):
headers={} headers={}
url=f"%s%s" url=f"%s%s"
@@ -362,23 +359,21 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet
bodyAddin, bodyAddin,
) )
log.Printf("DATA: %s", data)
//log.Println(data) //log.Println(data)
//log.Println(functionname) //log.Println(functionname)
return functionname, data return functionname, data
} }
func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []string, error) { func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, WorkflowApp, []string, error) {
api := WorkflowApp{} api := WorkflowApp{}
//log.Printf("%#v", swagger.Info) //log.Printf("%#v", swagger.Info)
if len(swagger.Info.Title) == 0 { if len(swagger.Info.Title) == 0 {
return WorkflowApp{}, []string{}, errors.New("Swagger.Info.Title can't be empty.") return swagger, WorkflowApp{}, []string{}, errors.New("Swagger.Info.Title can't be empty.")
} }
if len(swagger.Servers) == 0 { if len(swagger.Servers) == 0 {
return WorkflowApp{}, []string{}, errors.New("Swagger.Servers can't be empty. Add 'servers':[{'url':'hostname.com'}'") return swagger, WorkflowApp{}, []string{}, errors.New("Swagger.Servers can't be empty. Add 'servers':[{'url':'hostname.com'}'")
} }
api.Name = swagger.Info.Title api.Name = swagger.Info.Title
@@ -512,12 +507,7 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri
// This is the python code to be generated // This is the python code to be generated
// Could just as well be go at this point lol // Could just as well be go at this point lol
pythonFunctions := []string{} pythonFunctions := []string{}
for actualPath, path := range swagger.Paths { for actualPath, path := range swagger.Paths {
//log.Printf("%#v", path)
//log.Printf("%#v", actualPath)
// FIXME: Add everything from here: // FIXME: Add everything from here:
// https://godoc.org/github.com/getkin/kin-openapi/openapi3#PathItem // https://godoc.org/github.com/getkin/kin-openapi/openapi3#PathItem
firstQuery := true firstQuery := true
@@ -556,9 +546,19 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri
api.Actions = append(api.Actions, action) api.Actions = append(api.Actions, action)
pythonFunctions = append(pythonFunctions, curCode) pythonFunctions = append(pythonFunctions, curCode)
} }
// Has to be here because its used differently above.
// FIXING this is done during export instead?
//log.Printf("OLDPATH: %s", actualPath)
//if strings.Contains(actualPath, "?") {
// actualPath = strings.Split(actualPath, "?")[0]
//}
//log.Printf("NEWPATH: %s", actualPath)
//newPaths[actualPath] = path
} }
return api, pythonFunctions, nil return swagger, api, pythonFunctions, nil
} }
// FIXME - have this give a real version? // FIXME - have this give a real version?
@@ -1184,7 +1184,7 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo
} }
if path.Post.RequestBody != nil { if path.Post.RequestBody != nil {
log.Printf("FUNCTION: %#v", path.Post.RequestBody) log.Printf("RequestBody: %#v", path.Post.RequestBody)
} }
action.Returns.Schema.Type = "string" action.Returns.Schema.Type = "string"
+5 -3
View File
@@ -5528,7 +5528,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
} }
//log.Printf("Should generate yaml") //log.Printf("Should generate yaml")
api, pythonfunctions, err := generateYaml(swagger, newmd5) swagger, api, pythonfunctions, err := generateYaml(swagger, newmd5)
if err != nil { if err != nil {
log.Printf("Failed building and generating yaml: %s", err) log.Printf("Failed building and generating yaml: %s", err)
resp.WriteHeader(500) resp.WriteHeader(500)
@@ -5536,8 +5536,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
return return
} }
log.Printf("PATHS: %#v", swagger.Paths["/comments/put"]) log.Printf("Functions: %d", swagger.Paths)
log.Printf("Functions: %d", len(swagger.Paths))
log.Printf("Actions: %d", len(api.Actions)) log.Printf("Actions: %d", len(api.Actions))
api.Owner = user.Id api.Owner = user.Id
@@ -5694,6 +5693,9 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err))) resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err)))
} }
// Backup every single one
setOpenApiDatastore(ctx, api.ID, parsed)
err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1) err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1)
if err != nil { if err != nil {
log.Printf("Failed to increase success execution stats: %s", err) log.Printf("Failed to increase success execution stats: %s", err)
+7 -6
View File
@@ -1355,15 +1355,16 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
curapp := WorkflowApp{} curapp := WorkflowApp{}
// FIXME - can this work with ONLY AppID? // FIXME - can this work with ONLY AppID?
for _, app := range workflowApps { for _, app := range workflowApps {
log.Printf("Name Version: %s_%s, other: %s_%s", app.Name, app.AppVersion, action.AppName, action.AppVersion)
if app.ID == action.AppID { if app.ID == action.AppID {
curapp = app curapp = app
break break
} }
if app.Name == action.AppName && app.AppVersion == action.AppVersion { //if app.Name == action.AppName && app.AppVersion == action.AppVersion {
curapp = app // curapp = app
break // break
} //}
} }
// Check to see if the whole app is valid // Check to see if the whole app is valid
@@ -1377,11 +1378,11 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
// Check tosee if the appaction is valid // Check tosee if the appaction is valid
curappaction := WorkflowAppAction{} curappaction := WorkflowAppAction{}
for _, curAction := range curapp.Actions { for _, curAction := range curapp.Actions {
log.Printf("Same? %s - %s", action.Name, curAction.Name)
if action.Name == curAction.Name { if action.Name == curAction.Name {
curappaction = curAction curappaction = curAction
break break
} }
log.Println(action.Name, curAction.Name)
} }
// Check to see if the action is valid // Check to see if the action is valid
@@ -3376,7 +3377,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
} }
//log.Printf("Should generate yaml") //log.Printf("Should generate yaml")
api, _, err := generateYaml(swagger, parsedOpenApi.ID) swagger, api, _, err := generateYaml(swagger, parsedOpenApi.ID)
if err != nil { if err != nil {
log.Printf("Failed building and generating yaml in loop (%s): %s", filename, err) log.Printf("Failed building and generating yaml in loop (%s): %s", filename, err)
continue continue
+18 -17
View File
@@ -2639,27 +2639,28 @@ const AngularWorkflow = (props) => {
SelectDisplayProps={{ SelectDisplayProps={{
style: { style: {
marginLeft: 10, marginLeft: 10,
maxHeight: 200,
} }
}} }}
> >
{selectedApp.actions.map(data => { {selectedApp.actions.map(data => {
var newActionname = data.name var newActionname = data.name
if (data.label !== undefined && data.label !== null && data.label.length > 0) { if (data.label !== undefined && data.label !== null && data.label.length > 0) {
newActionname = data.label newActionname = data.label
} }
// ROFL FIXME - loop // ROFL FIXME - loop
newActionname = newActionname.replace("_", " ") newActionname = newActionname.replace("_", " ")
newActionname = newActionname.replace("_", " ") newActionname = newActionname.replace("_", " ")
newActionname = newActionname.replace("_", " ") newActionname = newActionname.replace("_", " ")
newActionname = newActionname.replace("_", " ") newActionname = newActionname.replace("_", " ")
newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1)
return ( return (
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}> <MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data.name}>
{newActionname} {newActionname}
</MenuItem> </MenuItem>
) )
})} })}
</Select> </Select>
<div style={{marginTop: "10px", borderColor: "white", borderWidth: "2px", marginBottom: 200}}> <div style={{marginTop: "10px", borderColor: "white", borderWidth: "2px", marginBottom: 200}}>
<AppActionArguments key={selectedAction.id} selectedAction={selectedAction} /> <AppActionArguments key={selectedAction.id} selectedAction={selectedAction} />
+14 -1
View File
@@ -16,6 +16,8 @@ import DialogActions from '@material-ui/core/DialogActions';
import TextField from '@material-ui/core/TextField'; import TextField from '@material-ui/core/TextField';
import Tooltip from '@material-ui/core/Tooltip'; import Tooltip from '@material-ui/core/Tooltip';
import CheckCircleIcon from '@material-ui/icons/CheckCircle'; import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import Breadcrumbs from '@material-ui/core/Breadcrumbs';
import AppsIcon from '@material-ui/icons/Apps';
import ErrorOutline from '@material-ui/icons/ErrorOutline'; import ErrorOutline from '@material-ui/icons/ErrorOutline';
import { useAlert } from "react-alert"; import { useAlert } from "react-alert";
@@ -587,7 +589,7 @@ const AppCreator = (props) => {
"required": required, "required": required,
"content": { "content": {
"example": { "example": {
"example": "test", "example": item.body,
}, },
}, },
} }
@@ -1426,6 +1428,17 @@ const AppCreator = (props) => {
// Random names for type & autoComplete. Didn't research :^) // Random names for type & autoComplete. Didn't research :^)
const landingpageDataBrowser = const landingpageDataBrowser =
<div style={{paddingBottom: 100, color: "white",}}> <div style={{paddingBottom: 100, color: "white",}}>
<Breadcrumbs aria-label="breadcrumb" separator="" style={{color: "white",}}>
<Link to="/apps" style={{textDecoration: "none", color: "inherit",}}>
<h2 style={{color: "rgba(255,255,255,0.5)"}}>
<AppsIcon style={{marginRight: 10}} />
Apps
</h2>
</Link>
<h2>
{name}
</h2>
</Breadcrumbs>
<Paper style={boxStyle}> <Paper style={boxStyle}>
<h2 style={{marginBottom: "10px", color: "white"}}>General information</h2> <h2 style={{marginBottom: "10px", color: "white"}}>General information</h2>
<Link target="_blank" to="/docs/apps#create_openapi_app" style={{textDecoration: "none", color: "#f85a3e"}}>Click here to learn more about app creation</Link> <Link target="_blank" to="/docs/apps#create_openapi_app" style={{textDecoration: "none", color: "#f85a3e"}}>Click here to learn more about app creation</Link>
+38 -18
View File
@@ -2,6 +2,7 @@ import React, { useEffect} from 'react';
import { useInterval } from 'react-powerhooks'; import { useInterval } from 'react-powerhooks';
import AppsIcon from '@material-ui/icons/Apps';
import Grid from '@material-ui/core/Grid'; import Grid from '@material-ui/core/Grid';
import Select from '@material-ui/core/Select'; import Select from '@material-ui/core/Select';
import Paper from '@material-ui/core/Paper'; import Paper from '@material-ui/core/Paper';
@@ -17,6 +18,7 @@ import Switch from '@material-ui/core/Switch';
import Input from '@material-ui/core/Input'; import Input from '@material-ui/core/Input';
import YAML from 'yaml' import YAML from 'yaml'
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import Breadcrumbs from '@material-ui/core/Breadcrumbs';
import CloudDownload from '@material-ui/icons/CloudDownload'; import CloudDownload from '@material-ui/icons/CloudDownload';
import EditIcon from '@material-ui/icons/Edit'; import EditIcon from '@material-ui/icons/Edit';
@@ -137,13 +139,13 @@ const Apps = (props) => {
alert.info("Downloading..") alert.info("Downloading..")
fetch(globalUrl+"/api/v1/apps/"+id+"/config", { fetch(globalUrl+"/api/v1/apps/"+id+"/config", {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
}, },
credentials: "include", credentials: "include",
}) })
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status !== 200) {
window.location.pathname = "/apps" window.location.pathname = "/apps"
@@ -155,12 +157,22 @@ const Apps = (props) => {
if (!responseJson.success) { if (!responseJson.success) {
alert.error("Failed to download file") alert.error("Failed to download file")
} else { } else {
const data = YAML.stringify(YAML.parse(responseJson.body)) const inputdata = YAML.parse(responseJson.body)
const newpaths = {}
Object.keys(inputdata["paths"]).forEach(function(key) {
newpaths[key.split("?")[0]] = inputdata.paths[key]
})
var name = inputdata.name inputdata.paths = newpaths
console.log("INPUT: ", inputdata)
var name = inputdata.info.title
name = name.replace(/ /g, "_", -1) name = name.replace(/ /g, "_", -1)
name = name.toLowerCase() name = name.toLowerCase()
delete inputdata.id
delete inputdata.editing
const data = YAML.stringify(inputdata)
var blob = new Blob( [ data ], { var blob = new Blob( [ data ], {
type: 'application/octet-stream' type: 'application/octet-stream'
}) })
@@ -193,7 +205,6 @@ const Apps = (props) => {
boxColor = "green" boxColor = "green"
} }
console.log("IMG: ", data.large_image)
var imageline = data.large_image.length === 0 ? var imageline = data.large_image.length === 0 ?
<img alt={data.title} style={{width: 100, height: 100}} /> <img alt={data.title} style={{width: 100, height: 100}} />
: :
@@ -498,9 +509,22 @@ const Apps = (props) => {
const appView = isLoggedIn ? const appView = isLoggedIn ?
<div style={{maxWidth: 1366, margin: "auto",}}> <div style={{maxWidth: 1366, margin: "auto",}}>
<div style={appViewStyle}> <div style={appViewStyle}>
<div style={{flex: "1", marginLeft: 10, marginRight: 10}}> <div>
<h2>Upload</h2> <Breadcrumbs aria-label="breadcrumb" separator="" style={{color: "white",}}>
<div style={{marginTop: 20}}/> <Link to="/apps" style={{textDecoration: "none", color: "inherit",}}>
<h2 style={{color: "rgba(255,255,255,0.5)"}}>
<AppsIcon style={{marginRight: 10}} />
App upload
</h2>
</Link>
{selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ?
<Link to={`/apps/edit/${selectedApp.id}`} style={{textDecoration: "none", color: "inherit",}}>
<h2>
{selectedApp.name}
</h2>
</Link>
: null}
</Breadcrumbs>
<UploadView/> <UploadView/>
</div> </div>
<Divider style={{marginBottom: "10px", marginTop: "10px", height: "100%", width: "1px", backgroundColor: dividerColor}}/> <Divider style={{marginBottom: "10px", marginTop: "10px", height: "100%", width: "1px", backgroundColor: dividerColor}}/>
@@ -988,11 +1012,7 @@ const Apps = (props) => {
</div> </div>
// Maybe use gridview or something, idk // Maybe use gridview or something, idk
return ( return loadedCheck
<div>
{loadedCheck}
</div>
)
} }
export default Apps export default Apps