From a65cf086f0192b984ec6f18142cd9281684feccd Mon Sep 17 00:00:00 2001 From: Howl Date: Mon, 13 Jun 2016 22:40:01 +0200 Subject: [PATCH] Add Documentation API --- app/start.go | 3 ++ app/v1/doc.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ app/v1/friend.go | 2 +- common/int.go | 2 ++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 app/v1/doc.go diff --git a/app/start.go b/app/start.go index 49e908e..13dd0c1 100644 --- a/app/start.go +++ b/app/start.go @@ -29,6 +29,9 @@ func Start(conf common.Conf, dbO *sql.DB) *gin.Engine { gv1.GET("/ping", Method(v1.PingGET)) gv1.GET("/surprise_me", Method(v1.SurpriseMeGET)) gv1.GET("/privileges", Method(v1.PrivilegesGET)) + gv1.GET("/doc", Method(v1.DocGET)) + gv1.GET("/doc/content", Method(v1.DocContentGET)) + gv1.GET("/doc/rules", Method(v1.DocRulesGET)) // Read privilege required gv1.GET("/users", Method(v1.UsersGET, common.PrivilegeRead)) diff --git a/app/v1/doc.go b/app/v1/doc.go new file mode 100644 index 0000000..53c38b0 --- /dev/null +++ b/app/v1/doc.go @@ -0,0 +1,92 @@ +package v1 + +import ( + "database/sql" + + "git.zxq.co/ripple/rippleapi/common" +) + +type docFile struct { + ID int `json:"id"` + DocName string `json:"doc_name"` + Public bool `json:"public"` + IsRule bool `json:"is_rule"` +} + +type docResponse struct { + common.ResponseBase + Files []docFile `json:"files"` +} + +// DocGET retrieves a list of documentation files. +func DocGET(md common.MethodData) common.CodeMessager { + var wc string + if !md.User.Privileges.HasPrivilegeBlog() || md.C.Query("public") == "1" { + wc = "WHERE public = '1'" + } + rows, err := md.DB.Query("SELECT id, doc_name, public, is_rule FROM docs " + wc) + if err != nil { + md.Err(err) + return Err500 + } + var r docResponse + for rows.Next() { + var f docFile + err := rows.Scan(&f.ID, &f.DocName, &f.Public, &f.IsRule) + if err != nil { + md.Err(err) + return Err500 + } + r.Files = append(r.Files, f) + } + r.Code = 200 + return r +} + +type docContentResponse struct { + common.ResponseBase + Content string `json:"content"` +} + +// DocContentGET retrieves the raw markdown file of a doc file +func DocContentGET(md common.MethodData) common.CodeMessager { + docID := common.Int(md.C.Query("id")) + if docID == 0 { + return common.SimpleResponse(404, "Documentation file not found!") + } + var wc string + if !md.User.Privileges.HasPrivilegeBlog() || md.C.Query("public") == "1" { + wc = "AND public = '1'" + } + var r docContentResponse + err := md.DB.QueryRow("SELECT doc_contents FROM docs WHERE id = ? "+wc+" LIMIT 1", docID).Scan(&r.Content) + switch { + case err == sql.ErrNoRows: + r.Code = 404 + r.Message = "Documentation file not found!" + case err != nil: + md.Err(err) + return Err500 + default: + r.Code = 200 + } + return r +} + +// DocRulesGET gets the rules. +func DocRulesGET(md common.MethodData) common.CodeMessager { + var r docContentResponse + err := md.DB.QueryRow("SELECT doc_contents FROM docs WHERE is_rule = '1' LIMIT 1").Scan(&r.Content) + const ruleFree = "# This Ripple instance is rule-free! Yay!" + switch { + case err == sql.ErrNoRows: + r.Content = ruleFree + case err != nil: + md.Err(err) + return Err500 + case len(r.Content) == 0: + r.Content = ruleFree + } + r.Code = 200 + return r +} diff --git a/app/v1/friend.go b/app/v1/friend.go index f950322..96be9a8 100644 --- a/app/v1/friend.go +++ b/app/v1/friend.go @@ -121,7 +121,7 @@ func FriendsWithGET(md common.MethodData) common.CodeMessager { if uid == 0 { return r } - err = md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users_relationships WHERE user1 = ? AND user2 = ? LIMIT 1), EXISTS(SELECT 1 FROM users_relationships WHERE user2 = ? AND user1 = ? LIMIT 1)", md.ID(), uid, md.ID(), uid).Scan(&r.Friends, &r.Mutual) + err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users_relationships WHERE user1 = ? AND user2 = ? LIMIT 1), EXISTS(SELECT 1 FROM users_relationships WHERE user2 = ? AND user1 = ? LIMIT 1)", md.ID(), uid, md.ID(), uid).Scan(&r.Friends, &r.Mutual) if err != sql.ErrNoRows && err != nil { md.Err(err) return Err500 diff --git a/common/int.go b/common/int.go index 7c0ae26..152fc96 100644 --- a/common/int.go +++ b/common/int.go @@ -1,5 +1,7 @@ package common +import "strconv" + // Int converts s to an int. If s in an invalid int, it defaults to 0. func Int(s string) int { r, _ := strconv.Atoi(s)