Fixed openapi3 config download bugs
This commit is contained in:
+15
-15
@@ -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"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user