Skip to content

Commit 4a31b30

Browse files
authored
Merge pull request #130 from Monilprajapati/main
Fetching articles from shuffle-docs
2 parents dce480b + d564e57 commit 4a31b30

File tree

1 file changed

+258
-0
lines changed

1 file changed

+258
-0
lines changed

shared.go

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18525,6 +18525,264 @@ func GetDocList(resp http.ResponseWriter, request *http.Request) {
1852518525
resp.Write(b)
1852618526
}
1852718527

18528+
func GetArticles(resp http.ResponseWriter, request *http.Request) {
18529+
cors := HandleCors(resp, request)
18530+
if cors {
18531+
return
18532+
}
18533+
18534+
location := strings.Split(request.URL.String(), "/")
18535+
if len(location) < 5 {
18536+
resp.WriteHeader(404)
18537+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"`)))
18538+
return
18539+
}
18540+
18541+
if strings.Contains(location[4], "?") {
18542+
location[4] = strings.Split(location[4], "?")[0]
18543+
}
18544+
18545+
ctx := GetContext(request)
18546+
downloadLocation, downloadOk := request.URL.Query()["location"]
18547+
version, versionOk := request.URL.Query()["version"]
18548+
cacheKey := fmt.Sprintf("articles_%s", location[4])
18549+
if downloadOk {
18550+
cacheKey = fmt.Sprintf("%s_%s", cacheKey, downloadLocation[0])
18551+
}
18552+
18553+
if versionOk {
18554+
cacheKey = fmt.Sprintf("%s_%s", cacheKey, version[0])
18555+
}
18556+
18557+
cache, err := GetCache(ctx, cacheKey)
18558+
if err == nil {
18559+
cacheData := []byte(cache.([]uint8))
18560+
resp.WriteHeader(200)
18561+
resp.Write(cacheData)
18562+
return
18563+
}
18564+
18565+
owner := "shuffle"
18566+
repo := "shuffle-docs"
18567+
path := "articles"
18568+
docPath := fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/master/%s/%s.md", owner, repo, path, location[4])
18569+
18570+
// FIXME: User controlled and dangerous (possibly). Uses Markdown on the frontend to render it
18571+
realPath := ""
18572+
18573+
newname := location[4]
18574+
if downloadOk {
18575+
if downloadLocation[0] == "openapi" {
18576+
newname = strings.ReplaceAll(strings.ToLower(location[4]), `%20`, "_")
18577+
docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/openapi-apps/master/docs/%s.md", newname)
18578+
realPath = fmt.Sprintf("https://github.com/Shuffle/openapi-apps/blob/master/docs/%s.md", newname)
18579+
18580+
} else if downloadLocation[0] == "python" && versionOk {
18581+
// Apparently this uses dashes for no good reason?
18582+
// Should maybe move everything over to underscores later?
18583+
newname = strings.ReplaceAll(newname, `%20`, "-")
18584+
newname = strings.ReplaceAll(newname, ` `, "-")
18585+
newname = strings.ReplaceAll(newname, `_`, "-")
18586+
newname = strings.ToLower(newname)
18587+
18588+
if version[0] == "1.0.0" {
18589+
docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/python-apps/master/%s/1.0.0/README.md", newname)
18590+
realPath = fmt.Sprintf("https://github.com/Shuffle/python-apps/blob/master/%s/1.0.0/README.md", newname)
18591+
18592+
log.Printf("[INFO] Should download python app for version %s: %s", version[0], docPath)
18593+
18594+
} else {
18595+
realPath = fmt.Sprintf("https://github.com/Shuffle/python-apps/blob/master/%s/README.md", newname)
18596+
docPath = fmt.Sprintf("https://raw.githubusercontent.com/Shuffle/python-apps/master/%s/README.md", newname)
18597+
}
18598+
18599+
}
18600+
}
18601+
18602+
//log.Printf("Docpath: %s", docPath)
18603+
18604+
httpClient := &http.Client{}
18605+
req, err := http.NewRequest(
18606+
"GET",
18607+
docPath,
18608+
nil,
18609+
)
18610+
18611+
if err != nil {
18612+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"}`)))
18613+
resp.WriteHeader(404)
18614+
return
18615+
}
18616+
18617+
newresp, err := httpClient.Do(req)
18618+
if err != nil {
18619+
resp.WriteHeader(404)
18620+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/articles/workflows.md"}`)))
18621+
return
18622+
}
18623+
18624+
defer newresp.Body.Close()
18625+
body, err := ioutil.ReadAll(newresp.Body)
18626+
if err != nil {
18627+
resp.WriteHeader(500)
18628+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse data"}`)))
18629+
return
18630+
}
18631+
18632+
commitOptions := &github.CommitsListOptions{
18633+
Path: fmt.Sprintf("%s/%s.md", path, location[4]),
18634+
}
18635+
18636+
parsedLink := fmt.Sprintf("https://github.com/%s/%s/blob/master/%s/%s.md", owner, repo, path, location[4])
18637+
if len(realPath) > 0 {
18638+
parsedLink = realPath
18639+
}
18640+
18641+
client := github.NewClient(nil)
18642+
githubResp := GithubResp{
18643+
Name: location[4],
18644+
Contributors: []GithubAuthor{},
18645+
Edited: "",
18646+
ReadTime: len(body) / 10 / 250,
18647+
Link: parsedLink,
18648+
}
18649+
18650+
if githubResp.ReadTime == 0 {
18651+
githubResp.ReadTime = 1
18652+
}
18653+
18654+
info, _, err := client.Repositories.ListCommits(ctx, owner, repo, commitOptions)
18655+
if err != nil {
18656+
log.Printf("[WARNING] Failed getting commit info: %s", err)
18657+
} else {
18658+
//log.Printf("Info: %s", info)
18659+
for _, commit := range info {
18660+
//log.Printf("Commit: %s", commit.Author)
18661+
newAuthor := GithubAuthor{}
18662+
if commit.Author != nil && commit.Author.AvatarURL != nil {
18663+
newAuthor.ImageUrl = *commit.Author.AvatarURL
18664+
}
18665+
18666+
if commit.Author != nil && commit.Author.HTMLURL != nil {
18667+
newAuthor.Url = *commit.Author.HTMLURL
18668+
}
18669+
18670+
found := false
18671+
for _, contributor := range githubResp.Contributors {
18672+
if contributor.Url == newAuthor.Url {
18673+
found = true
18674+
break
18675+
}
18676+
}
18677+
18678+
if !found && len(newAuthor.Url) > 0 && len(newAuthor.ImageUrl) > 0 {
18679+
githubResp.Contributors = append(githubResp.Contributors, newAuthor)
18680+
}
18681+
}
18682+
}
18683+
18684+
type Result struct {
18685+
Success bool `json:"success"`
18686+
Reason string `json:"reason"`
18687+
Meta GithubResp `json:"meta"`
18688+
}
18689+
18690+
var result Result
18691+
result.Success = true
18692+
result.Meta = githubResp
18693+
18694+
result.Reason = string(body)
18695+
b, err := json.Marshal(result)
18696+
if err != nil {
18697+
http.Error(resp, err.Error(), 500)
18698+
return
18699+
}
18700+
18701+
err = SetCache(ctx, cacheKey, b, 180)
18702+
if err != nil {
18703+
log.Printf("[WARNING] Failed setting cache for articles %s: %s", location[4], err)
18704+
}
18705+
18706+
resp.WriteHeader(200)
18707+
resp.Write(b)
18708+
}
18709+
18710+
func GetArticlesList(resp http.ResponseWriter, request *http.Request) {
18711+
cors := HandleCors(resp, request)
18712+
if cors {
18713+
return
18714+
}
18715+
18716+
ctx := GetContext(request)
18717+
cacheKey := "articles_list"
18718+
cache, err := GetCache(ctx, cacheKey)
18719+
result := FileList{}
18720+
if err == nil {
18721+
cacheData := []byte(cache.([]uint8))
18722+
resp.WriteHeader(200)
18723+
resp.Write(cacheData)
18724+
return
18725+
}
18726+
18727+
client := github.NewClient(nil)
18728+
owner := "shuffle"
18729+
repo := "shuffle-docs"
18730+
path := "articles"
18731+
_, item1, _, err := client.Repositories.GetContents(ctx, owner, repo, path, nil)
18732+
if err != nil {
18733+
log.Printf("[WARNING] Failed getting articles list: %s", err)
18734+
resp.WriteHeader(500)
18735+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Error listing directory"}`)))
18736+
return
18737+
}
18738+
18739+
if len(item1) == 0 {
18740+
resp.WriteHeader(500)
18741+
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No articles available."}`)))
18742+
return
18743+
}
18744+
18745+
names := []GithubResp{}
18746+
for _, item := range item1 {
18747+
if !strings.HasSuffix(*item.Name, "md") {
18748+
continue
18749+
}
18750+
18751+
// FIXME: Scuffed readtime calc
18752+
// Average word length = 5. Space = 1. 5+1 = 6 avg.
18753+
// Words = *item.Size/6/250
18754+
//250 = average read time / minute
18755+
// Doubling this for bloat removal in Markdown~
18756+
githubResp := GithubResp{
18757+
Name: (*item.Name)[0 : len(*item.Name)-3],
18758+
Contributors: []GithubAuthor{},
18759+
Edited: "",
18760+
ReadTime: *item.Size / 6 / 250,
18761+
Link: fmt.Sprintf("https://github.com/%s/%s/blob/master/%s/%s", owner, repo, path, *item.Name),
18762+
}
18763+
18764+
names = append(names, githubResp)
18765+
}
18766+
18767+
//log.Printf(names)
18768+
result.Success = true
18769+
result.Reason = "Success"
18770+
result.List = names
18771+
b, err := json.Marshal(result)
18772+
if err != nil {
18773+
http.Error(resp, err.Error(), 500)
18774+
return
18775+
}
18776+
18777+
err = SetCache(ctx, cacheKey, b, 300)
18778+
if err != nil {
18779+
log.Printf("[WARNING] Failed setting cache for cachekey %s: %s", cacheKey, err)
18780+
}
18781+
18782+
resp.WriteHeader(200)
18783+
resp.Write(b)
18784+
}
18785+
1852818786
func md5sum(data []byte) string {
1852918787
hasher := md5.New()
1853018788
hasher.Write(data)

0 commit comments

Comments
 (0)