Fixed minor backend return bug and JSON in frontend
This commit is contained in:
@@ -2,6 +2,16 @@ import requests
|
||||
import yaml
|
||||
import json
|
||||
import os
|
||||
import io
|
||||
import base64
|
||||
from PIL import Image
|
||||
#import tkinter
|
||||
#import _tkinter
|
||||
#tkinter._test()
|
||||
|
||||
|
||||
#sudo apt-get install python-imaging-tk
|
||||
#sudo apt-get install python3-tk
|
||||
|
||||
# USAGE:
|
||||
# 1. Find the item here:
|
||||
@@ -194,54 +204,108 @@ def dump_data(filename, openapi, category):
|
||||
with open(generatedfile, "w+") as tmp:
|
||||
tmp.write(yaml.dump(openapi))
|
||||
except FileNotFoundError:
|
||||
os.mkdir("generated/%s" % category)
|
||||
try:
|
||||
os.mkdir("generated/%s" % category)
|
||||
with open(generatedfile, "w+") as tmp:
|
||||
tmp.write(yaml.dump(openapi))
|
||||
|
||||
with open(generatedfile, "w+") as tmp:
|
||||
tmp.write(yaml.dump(openapi))
|
||||
|
||||
print("Generated %s" % generatedfile)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
number = 1
|
||||
#https://apphub.swimlane.com/
|
||||
categories = [
|
||||
"Investigation",
|
||||
"Endpoint Security & Management",
|
||||
"Network Security & Management",
|
||||
"Communication",
|
||||
"SIEM & Log Management",
|
||||
"Governance & Risk Management",
|
||||
"Vulnerability & Patch Management",
|
||||
"Ticket Management",
|
||||
"DevOps & Application Security",
|
||||
"Identity & Access Management",
|
||||
"Infrastructure",
|
||||
"Miscellaneous",
|
||||
]
|
||||
|
||||
search_category = categories[2]
|
||||
total = 0
|
||||
while(True):
|
||||
url = "https://apphub.swimlane.io/api/search/swimbundles?page=%d" % number
|
||||
|
||||
json = {"fields": {"family": search_category}}
|
||||
ret = requests.post(
|
||||
url,
|
||||
json=json,
|
||||
)
|
||||
for search_category in categories:
|
||||
number = 1
|
||||
innertotal = 0
|
||||
|
||||
if ret.status_code != 201:
|
||||
print("RET NOT 201: %d" % ret.status_code)
|
||||
break
|
||||
while(True):
|
||||
url = "https://apphub.swimlane.io/api/search/swimbundles?page=%d" % number
|
||||
|
||||
json = {"fields": {"family": search_category}}
|
||||
ret = requests.post(
|
||||
url,
|
||||
json=json,
|
||||
)
|
||||
|
||||
parsed = ret.json()
|
||||
try:
|
||||
category = parsed["data"][0]["swimbundleMeta"]["family"][0]
|
||||
except KeyError:
|
||||
category = ""
|
||||
except IndexError:
|
||||
category = ""
|
||||
if ret.status_code != 201:
|
||||
print("RET NOT 201: %d" % ret.status_code)
|
||||
break
|
||||
|
||||
if category == "":
|
||||
break
|
||||
parsed = ret.json()
|
||||
try:
|
||||
category = parsed["data"][0]["swimbundleMeta"]["family"][0]
|
||||
except KeyError:
|
||||
category = ""
|
||||
except IndexError:
|
||||
category = ""
|
||||
|
||||
for data in parsed["data"]:
|
||||
filename, openapi = parse_data(data)
|
||||
openapi["tags"] = [category]
|
||||
dump_data(filename, openapi, category)
|
||||
total += 1
|
||||
if category == "":
|
||||
break
|
||||
|
||||
number += 1
|
||||
for data in parsed["data"]:
|
||||
try:
|
||||
filename, openapi = parse_data(data)
|
||||
except:
|
||||
try:
|
||||
print("Skipping %s %s because of an error" % (data["vendor"], data["product"]))
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
print("Created %d openapi specs from Swimlane with category %s" % (total, search_category))
|
||||
continue
|
||||
|
||||
openapi["tags"] = [
|
||||
{
|
||||
"name": category,
|
||||
}
|
||||
]
|
||||
|
||||
appid = data["swimbundleMeta"]["logo"]["id"]
|
||||
logoUrl = "https://apphub.swimlane.io/api/logos/%s" % appid
|
||||
logodata = requests.get(logoUrl)
|
||||
if logodata.status_code == 200:
|
||||
logojson = logodata.json()
|
||||
try:
|
||||
logobase64 = logojson["data"]["base64"]
|
||||
#.split(",")[1]
|
||||
|
||||
openapi["info"]["x-logo"] = logobase64
|
||||
#print(logobase64)
|
||||
#msg = base64.b64decode(logobase64)
|
||||
#with io.BytesIO(msg) as buf:
|
||||
# with Image.open(buf) as tempImg:
|
||||
# newWidth = 174 / tempImg.width # change this to what ever width you need.
|
||||
# newHeight = 174 / tempImg.height # change this to what ever height you need.
|
||||
# newSize = (int(newWidth * tempImg.width), int(newHeight * tempImg.height))
|
||||
# newImg1 = tempImg.resize(newSize)
|
||||
# lbl1.IMG = ImageTk.PhotoImage(image=newImg1)
|
||||
# lbl1.configure(image=lbl1.IMG)
|
||||
except KeyError:
|
||||
print("Failed logo parsing for %s" % appid)
|
||||
pass
|
||||
|
||||
dump_data(filename, openapi, category)
|
||||
innertotal += 1
|
||||
total += 1
|
||||
|
||||
number += 1
|
||||
|
||||
print("Created %d openapi specs from Swimlane with category %s" % (innertotal, search_category))
|
||||
|
||||
print("\nCreated %d TOTAL openapi specs from Swimlane" % (total))
|
||||
|
||||
@@ -6575,7 +6575,7 @@ func runInit(ctx context.Context) {
|
||||
log.Printf("Getting remote workflow apps")
|
||||
workflowapps, err := getAllWorkflowApps(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting apps: %s", err)
|
||||
log.Printf("Failed getting apps (runInit): %s", err)
|
||||
} else if err == nil && len(workflowapps) == 0 {
|
||||
log.Printf("Downloading default workflow apps")
|
||||
fs := memfs.New()
|
||||
|
||||
@@ -3991,7 +3991,7 @@ func getWorkflowApps(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
workflowapps, err := getAllWorkflowApps(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting apps: %s", err)
|
||||
log.Printf("Failed getting apps (getworkflowapps): %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
@@ -4554,8 +4554,9 @@ func handleAppHotloadRequest(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("Hotloading from %s", location)
|
||||
err = handleAppHotload(location, true)
|
||||
if err != nil {
|
||||
log.Printf("Failed app hotload: %s", err)
|
||||
resp.WriteHeader(500)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed loading apps: %s"}`)))
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed loading apps: %s"}`, err)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4720,7 +4721,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
|
||||
|
||||
//log.Printf("File: %s", filename)
|
||||
//log.Printf("Found file: %s", filename)
|
||||
log.Printf("OpenAPI app: %s", filename)
|
||||
//log.Printf("OpenAPI app: %s", filename)
|
||||
tmpExtra := fmt.Sprintf("%s%s/", extra, file.Name())
|
||||
|
||||
fileReader, err := fs.Open(tmpExtra)
|
||||
@@ -5307,7 +5308,7 @@ func getAllSchedules(ctx context.Context) ([]ScheduleOld, error) {
|
||||
|
||||
func getAllWorkflowApps(ctx context.Context) ([]WorkflowApp, error) {
|
||||
var allworkflowapps []WorkflowApp
|
||||
q := datastore.NewQuery("workflowapp")
|
||||
q := datastore.NewQuery("workflowapp").Limit(50)
|
||||
|
||||
_, err := dbclient.GetAll(ctx, q, &allworkflowapps)
|
||||
if err != nil {
|
||||
|
||||
@@ -2538,9 +2538,9 @@ const AngularWorkflow = (props) => {
|
||||
var jsonvalid = true
|
||||
try {
|
||||
const tmp = String(JSON.parse(foundResult.result))
|
||||
//if (!tmp.includes("{") && !tmp.includes("[")) {
|
||||
// jsonvalid = false
|
||||
//}
|
||||
if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) {
|
||||
jsonvalid = false
|
||||
}
|
||||
} catch (e) {
|
||||
jsonvalid = false
|
||||
}
|
||||
@@ -2627,9 +2627,9 @@ const AngularWorkflow = (props) => {
|
||||
var jsonvalid = true
|
||||
try {
|
||||
const tmp = String(JSON.parse(actionItem.example))
|
||||
//if (!tmp.includes("{") && !tmp.includes("[")) {
|
||||
// jsonvalid = false
|
||||
//}
|
||||
if (!actionItem.example.includes("{") && !actionItem.example.includes("[")) {
|
||||
jsonvalid = false
|
||||
}
|
||||
} catch (e) {
|
||||
jsonvalid = false
|
||||
}
|
||||
@@ -5352,9 +5352,9 @@ const AngularWorkflow = (props) => {
|
||||
var jsonvalid = true
|
||||
try {
|
||||
const tmp = String(JSON.parse(showResult))
|
||||
//if (!tmp.includes("{") && !tmp.includes("[")) {
|
||||
// jsonvalid = false
|
||||
//}
|
||||
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||
jsonvalid = false
|
||||
}
|
||||
} catch (e) {
|
||||
jsonvalid = false
|
||||
}
|
||||
@@ -5549,11 +5549,12 @@ const AngularWorkflow = (props) => {
|
||||
var jsonvalid = true
|
||||
try {
|
||||
const tmp = String(JSON.parse(showResult))
|
||||
//if (!tmp.includes("{") && !tmp.includes("[")) {
|
||||
// console.log("IN HERE")
|
||||
// jsonvalid = false
|
||||
//}
|
||||
if (!showResult.includes("{") && !showResult.includes("[")) {
|
||||
console.log("IN HERE: ", tmp)
|
||||
jsonvalid = false
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error: ", e)
|
||||
jsonvalid = false
|
||||
}
|
||||
|
||||
|
||||
@@ -618,8 +618,7 @@ const AppCreator = (props) => {
|
||||
"id": props.match.params.appid,
|
||||
}
|
||||
|
||||
|
||||
if (basedata.info.contact !== undefined) {
|
||||
if (basedata.info !== undefined && basedata.info.contact !== undefined) {
|
||||
data.info["contact"] = basedata.info.contact
|
||||
} else if (contact === "") {
|
||||
data.info["contact"] = {
|
||||
@@ -1739,7 +1738,7 @@ const AppCreator = (props) => {
|
||||
// <img src={file} id="logo" style={{width: "100%", height: "100%"}} />
|
||||
|
||||
const imageData = file.length > 0 ? file : fileBase64
|
||||
const imageInfo = <img src={imageData} alt="Click to upload an image (174x174)" id="logo" style={{maxWidth: 174, maxHeight: 174,}} />
|
||||
const imageInfo = <img src={imageData} alt="Click to upload an image (174x174)" id="logo" style={{maxWidth: 174, maxHeight: 174, minWidth: 174, minHeight: 174, objectFit: "contain",}} />
|
||||
|
||||
// Random names for type & autoComplete. Didn't research :^)
|
||||
const landingpageDataBrowser =
|
||||
|
||||
@@ -733,7 +733,7 @@ const Apps = (props) => {
|
||||
- <a href="https://apis.guru/browse-apis/" style={{textDecoration: "none", color: "#f85a3e"}} target="_blank">OpenAPI directory</a>
|
||||
- <a href="https://editor.swagger.io/" style={{textDecoration: "none", color: "#f85a3e"}} target="_blank">OpenAPI Validator</a>
|
||||
<div/>
|
||||
Apps interact with eachother in workflows. They are created with the app creator, using OpenAPI specification or manually in python. The links above are references to OpenAPI tools and other app repositories. There's ten thousands of them.
|
||||
Apps interact with eachother in workflows. They are created with the app creator, using OpenAPI specification or manually in python. The links above are references to OpenAPI tools and other app repositories. There's thousands of them.
|
||||
<div/>
|
||||
<Divider style={{height: 1, backgroundColor: dividerColor, marginTop: 20, marginBottom: 20}} />
|
||||
<div style={{}}>
|
||||
|
||||
@@ -694,15 +694,16 @@ func handleExecution(client *http.Client, req *http.Request, workflowExecution W
|
||||
// FIXME: Force killing a worker should result in a notification somewhere
|
||||
if len(nextActions) == 0 {
|
||||
log.Printf("No next action. Finished? Result vs Actions: %d - %d", len(workflowExecution.Results), len(workflowExecution.Workflow.Actions))
|
||||
//exit := true
|
||||
//for _, item := range workflowExecution.Results {
|
||||
// if item == "EXECUTING" {
|
||||
// exit = false
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
exit := true
|
||||
for _, item := range workflowExecution.Results {
|
||||
if item.Status == "EXECUTING" {
|
||||
exit = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if exit && len(workflowExecution.Results) == len(workflowExecution.Workflow.Actions) {
|
||||
log.Printf("Shutting down.")
|
||||
shutdown(workflowExecution.ExecutionId, workflowExecution.Workflow.ID)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user