@@ -6626,8 +6626,8 @@ func diffWorkflows(oldWorkflow Workflow, parentWorkflow Workflow, update bool) {
66266626 }
66276627 }
66286628 } else if trigger.TriggerType == "SUBFLOW" {
6629- // params: workflow, argument, user_apikey, startnode,
6630- // check_result and auth_override
6629+ // // params: workflow, argument, user_apikey, startnode,
6630+ // // check_result and auth_override
66316631
66326632 for paramIndex, param := range trigger.Parameters {
66336633 // since this is an added subflow, the workflow being referred
@@ -6639,6 +6639,8 @@ func diffWorkflows(oldWorkflow Workflow, parentWorkflow Workflow, update bool) {
66396639 continue
66406640 }
66416641
6642+ ctx := context.Background()
6643+
66426644 // propagate reference workflow to child org
66436645 // check first if the workflow has been propagated before
66446646 // to the suborg (ParentWorkflowId is this workflow's ID)
@@ -6648,7 +6650,14 @@ func diffWorkflows(oldWorkflow Workflow, parentWorkflow Workflow, update bool) {
66486650 continue
66496651 }
66506652
6651- childOrgWorkflows, err := GetAllWorkflowsByQuery(ctx, childOrg, 0, "")
6653+ user := User{
6654+ Role: "admin",
6655+ ActiveOrg: OrgMini{
6656+ Id: childOrg.Id,
6657+ },
6658+ }
6659+
6660+ childOrgWorkflows, err := GetAllWorkflowsByQuery(ctx, user, 250, "")
66526661 if err != nil {
66536662 log.Printf("[WARNING] Failed getting org workflows: %s", err)
66546663 continue
@@ -6679,19 +6688,19 @@ func diffWorkflows(oldWorkflow Workflow, parentWorkflow Workflow, update bool) {
66796688
66806689 parentSubflowPointed.SuborgDistribution = append(parentSubflowPointed.SuborgDistribution, childWorkflow.OrgId)
66816690
6682- parentSubflowPointed, err = SetWorkflow(ctx, parentSubflowPointed, parentSubflowPointedId)
6691+ err = SetWorkflow(ctx, * parentSubflowPointed, parentSubflowPointedId)
66836692 if err != nil {
66846693 log.Printf("[WARNING] Failed setting parent subflow: %s", err)
66856694 continue
66866695 }
66876696
6688- propagatedSubflow, err := GenerateWorkflowFromParent(ctx, parentSubflowPointed, parentSubflowPointed.OrgId, suborgId )
6697+ propagatedSubflow, err := GenerateWorkflowFromParent(ctx, * parentSubflowPointed, parentSubflowPointed.OrgId, childWorkflow.OrgId )
66896698 if err != nil {
66906699 log.Printf("[WARNING] Failed to generate child workflow %s (%s) for %s (%s): %s", childWorkflow.Name, childWorkflow.ID, parentWorkflow.Name, parentWorkflow.ID, err)
66916700 } else {
66926701 log.Printf("[INFO] Generated child workflow %s (%s) for %s (%s)", childWorkflow.Name, childWorkflow.ID, parentWorkflow.Name, parentWorkflow.ID)
66936702
6694- triggers[index] .Parameters[paramIndex].Value = propagatedSubflow.ID
6703+ trigger .Parameters[paramIndex].Value = propagatedSubflow.ID
66956704 }
66966705
66976706 startnode := ""
@@ -6712,22 +6721,22 @@ func diffWorkflows(oldWorkflow Workflow, parentWorkflow Workflow, update bool) {
67126721 // find the equivalent of the startnode in the new workflow
67136722 for _, action := range propagatedSubflow.Actions {
67146723 if action.ID == startnode {
6715- triggers[index] .Parameters[startNodeParamIndex].Value = action.ID
6724+ trigger .Parameters[startNodeParamIndex].Value = action.ID
67166725 break
67176726 }
67186727 }
67196728
67206729 // sometimes, it can happen that it's a replaced trigger
67216730 for _, trigger := range propagatedSubflow.Triggers {
67226731 if trigger.ReplacementForTrigger == startnode {
6723- triggers[index] .Parameters[startNodeParamIndex].Value = trigger.ID
6732+ trigger .Parameters[startNodeParamIndex].Value = trigger.ID
67246733 break
67256734 }
67266735 }
67276736
67286737 } else if param.Name != "startnode" && param.Name != "startnode" {
67296738 // just use it
6730- triggers[index] .Parameters[paramIndex].Value = param.Value
6739+ trigger .Parameters[paramIndex].Value = param.Value
67316740 }
67326741 }
67336742 }
@@ -18767,6 +18776,264 @@ func GetDocList(resp http.ResponseWriter, request *http.Request) {
1876718776 resp.Write(b)
1876818777}
1876918778
18779+ func GetArticles(resp http.ResponseWriter, request *http.Request) {
18780+ cors := HandleCors(resp, request)
18781+ if cors {
18782+ return
18783+ }
18784+
18785+ location := strings.Split(request.URL.String(), "/")
18786+ if len(location) < 5 {
18787+ resp.WriteHeader(404)
18788+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"`)))
18789+ return
18790+ }
18791+
18792+ if strings.Contains(location[4], "?") {
18793+ location[4] = strings.Split(location[4], "?")[0]
18794+ }
18795+
18796+ ctx := GetContext(request)
18797+ downloadLocation, downloadOk := request.URL.Query()["location"]
18798+ version, versionOk := request.URL.Query()["version"]
18799+ cacheKey := fmt.Sprintf("articles_%s", location[4])
18800+ if downloadOk {
18801+ cacheKey = fmt.Sprintf("%s_%s", cacheKey, downloadLocation[0])
18802+ }
18803+
18804+ if versionOk {
18805+ cacheKey = fmt.Sprintf("%s_%s", cacheKey, version[0])
18806+ }
18807+
18808+ cache, err := GetCache(ctx, cacheKey)
18809+ if err == nil {
18810+ cacheData := []byte(cache.([]uint8))
18811+ resp.WriteHeader(200)
18812+ resp.Write(cacheData)
18813+ return
18814+ }
18815+
18816+ owner := "shuffle"
18817+ repo := "shuffle-docs"
18818+ path := "articles"
18819+ docPath := fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/master/%s/%s.md", owner, repo, path, location[4])
18820+
18821+ // FIXME: User controlled and dangerous (possibly). Uses Markdown on the frontend to render it
18822+ realPath := ""
18823+
18824+ newname := location[4]
18825+ if downloadOk {
18826+ if downloadLocation[0] == "openapi" {
18827+ newname = strings.ReplaceAll(strings.ToLower(location[4]), `%20`, "_")
18828+ docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/openapi-apps/master/docs/%s.md", newname)
18829+ realPath = fmt.Sprintf("https://github.com/Shuffle/openapi-apps/blob/master/docs/%s.md", newname)
18830+
18831+ } else if downloadLocation[0] == "python" && versionOk {
18832+ // Apparently this uses dashes for no good reason?
18833+ // Should maybe move everything over to underscores later?
18834+ newname = strings.ReplaceAll(newname, `%20`, "-")
18835+ newname = strings.ReplaceAll(newname, ` `, "-")
18836+ newname = strings.ReplaceAll(newname, `_`, "-")
18837+ newname = strings.ToLower(newname)
18838+
18839+ if version[0] == "1.0.0" {
18840+ docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/python-apps/master/%s/1.0.0/README.md", newname)
18841+ realPath = fmt.Sprintf("https://github.com/Shuffle/python-apps/blob/master/%s/1.0.0/README.md", newname)
18842+
18843+ log.Printf("[INFO] Should download python app for version %s: %s", version[0], docPath)
18844+
18845+ } else {
18846+ realPath = fmt.Sprintf("https://github.com/Shuffle/python-apps/blob/master/%s/README.md", newname)
18847+ docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/python-apps/master/%s/README.md", newname)
18848+ }
18849+
18850+ }
18851+ }
18852+
18853+ //log.Printf("Docpath: %s", docPath)
18854+
18855+ httpClient := &http.Client{}
18856+ req, err := http.NewRequest(
18857+ "GET",
18858+ docPath,
18859+ nil,
18860+ )
18861+
18862+ if err != nil {
18863+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"}`)))
18864+ resp.WriteHeader(404)
18865+ return
18866+ }
18867+
18868+ newresp, err := httpClient.Do(req)
18869+ if err != nil {
18870+ resp.WriteHeader(404)
18871+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"}`)))
18872+ return
18873+ }
18874+
18875+ defer newresp.Body.Close()
18876+ body, err := ioutil.ReadAll(newresp.Body)
18877+ if err != nil {
18878+ resp.WriteHeader(500)
18879+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse data"}`)))
18880+ return
18881+ }
18882+
18883+ commitOptions := &github.CommitsListOptions{
18884+ Path: fmt.Sprintf("%s/%s.md", path, location[4]),
18885+ }
18886+
18887+ parsedLink := fmt.Sprintf("https://github.com/%s/%s/blob/master/%s/%s.md", owner, repo, path, location[4])
18888+ if len(realPath) > 0 {
18889+ parsedLink = realPath
18890+ }
18891+
18892+ client := github.NewClient(nil)
18893+ githubResp := GithubResp{
18894+ Name: location[4],
18895+ Contributors: []GithubAuthor{},
18896+ Edited: "",
18897+ ReadTime: len(body) / 10 / 250,
18898+ Link: parsedLink,
18899+ }
18900+
18901+ if githubResp.ReadTime == 0 {
18902+ githubResp.ReadTime = 1
18903+ }
18904+
18905+ info, _, err := client.Repositories.ListCommits(ctx, owner, repo, commitOptions)
18906+ if err != nil {
18907+ log.Printf("[WARNING] Failed getting commit info: %s", err)
18908+ } else {
18909+ //log.Printf("Info: %s", info)
18910+ for _, commit := range info {
18911+ //log.Printf("Commit: %s", commit.Author)
18912+ newAuthor := GithubAuthor{}
18913+ if commit.Author != nil && commit.Author.AvatarURL != nil {
18914+ newAuthor.ImageUrl = *commit.Author.AvatarURL
18915+ }
18916+
18917+ if commit.Author != nil && commit.Author.HTMLURL != nil {
18918+ newAuthor.Url = *commit.Author.HTMLURL
18919+ }
18920+
18921+ found := false
18922+ for _, contributor := range githubResp.Contributors {
18923+ if contributor.Url == newAuthor.Url {
18924+ found = true
18925+ break
18926+ }
18927+ }
18928+
18929+ if !found && len(newAuthor.Url) > 0 && len(newAuthor.ImageUrl) > 0 {
18930+ githubResp.Contributors = append(githubResp.Contributors, newAuthor)
18931+ }
18932+ }
18933+ }
18934+
18935+ type Result struct {
18936+ Success bool `json:"success"`
18937+ Reason string `json:"reason"`
18938+ Meta GithubResp `json:"meta"`
18939+ }
18940+
18941+ var result Result
18942+ result.Success = true
18943+ result.Meta = githubResp
18944+
18945+ result.Reason = string(body)
18946+ b, err := json.Marshal(result)
18947+ if err != nil {
18948+ http.Error(resp, err.Error(), 500)
18949+ return
18950+ }
18951+
18952+ err = SetCache(ctx, cacheKey, b, 180)
18953+ if err != nil {
18954+ log.Printf("[WARNING] Failed setting cache for articles %s: %s", location[4], err)
18955+ }
18956+
18957+ resp.WriteHeader(200)
18958+ resp.Write(b)
18959+ }
18960+
18961+ func GetArticlesList(resp http.ResponseWriter, request *http.Request) {
18962+ cors := HandleCors(resp, request)
18963+ if cors {
18964+ return
18965+ }
18966+
18967+ ctx := GetContext(request)
18968+ cacheKey := "articles_list"
18969+ cache, err := GetCache(ctx, cacheKey)
18970+ result := FileList{}
18971+ if err == nil {
18972+ cacheData := []byte(cache.([]uint8))
18973+ resp.WriteHeader(200)
18974+ resp.Write(cacheData)
18975+ return
18976+ }
18977+
18978+ client := github.NewClient(nil)
18979+ owner := "shuffle"
18980+ repo := "shuffle-docs"
18981+ path := "articles"
18982+ _, item1, _, err := client.Repositories.GetContents(ctx, owner, repo, path, nil)
18983+ if err != nil {
18984+ log.Printf("[WARNING] Failed getting articles list: %s", err)
18985+ resp.WriteHeader(500)
18986+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Error listing directory"}`)))
18987+ return
18988+ }
18989+
18990+ if len(item1) == 0 {
18991+ resp.WriteHeader(500)
18992+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No articles available."}`)))
18993+ return
18994+ }
18995+
18996+ names := []GithubResp{}
18997+ for _, item := range item1 {
18998+ if !strings.HasSuffix(*item.Name, "md") {
18999+ continue
19000+ }
19001+
19002+ // FIXME: Scuffed readtime calc
19003+ // Average word length = 5. Space = 1. 5+1 = 6 avg.
19004+ // Words = *item.Size/6/250
19005+ //250 = average read time / minute
19006+ // Doubling this for bloat removal in Markdown~
19007+ githubResp := GithubResp{
19008+ Name: (*item.Name)[0 : len(*item.Name)-3],
19009+ Contributors: []GithubAuthor{},
19010+ Edited: "",
19011+ ReadTime: *item.Size / 6 / 250,
19012+ Link: fmt.Sprintf("https://github.com/%s/%s/blob/master/%s/%s", owner, repo, path, *item.Name),
19013+ }
19014+
19015+ names = append(names, githubResp)
19016+ }
19017+
19018+ //log.Printf(names)
19019+ result.Success = true
19020+ result.Reason = "Success"
19021+ result.List = names
19022+ b, err := json.Marshal(result)
19023+ if err != nil {
19024+ http.Error(resp, err.Error(), 500)
19025+ return
19026+ }
19027+
19028+ err = SetCache(ctx, cacheKey, b, 300)
19029+ if err != nil {
19030+ log.Printf("[WARNING] Failed setting cache for cachekey %s: %s", cacheKey, err)
19031+ }
19032+
19033+ resp.WriteHeader(200)
19034+ resp.Write(b)
19035+ }
19036+
1877019037func md5sum(data []byte) string {
1877119038 hasher := md5.New()
1877219039 hasher.Write(data)
0 commit comments