diff --git a/controllers/api/api.go b/controllers/api/api.go index 3613821d..e6369b22 100644 --- a/controllers/api/api.go +++ b/controllers/api/api.go @@ -13,6 +13,7 @@ import ( "github.com/NyaaPantsu/nyaa/models" "github.com/NyaaPantsu/nyaa/models/torrents" "github.com/NyaaPantsu/nyaa/models/users" + "github.com/NyaaPantsu/nyaa/utils/api" "github.com/NyaaPantsu/nyaa/utils/cookies" "github.com/NyaaPantsu/nyaa/utils/crypto" "github.com/NyaaPantsu/nyaa/utils/log" @@ -290,12 +291,12 @@ func APIUploadHandler(c *gin.Context) { } messages.AddInfoT("infos", "torrent_uploaded") - apiResponseHandler(c, torrent.ToJSON()) + apiUtils.ResponseHandler(c, torrent.ToJSON()) return } } } - apiResponseHandler(c) + apiUtils.ResponseHandler(c) } /** @@ -365,7 +366,7 @@ func APIUpdateHandler(c *gin.Context) { } upload.UpdateTorrent(&update, torrent, user).Update(false) } - apiResponseHandler(c) + apiUtils.ResponseHandler(c) } /** @@ -504,12 +505,12 @@ func APILoginHandler(c *gin.Context) { user, _, errorUser := cookies.CreateUserAuthentication(c, &b) if errorUser == nil { messages.AddInfo("infos", "Logged") - apiResponseHandler(c, user.ToJSON()) + apiUtils.ResponseHandler(c, user.ToJSON()) return } messages.Error(errorUser) } - apiResponseHandler(c) + apiUtils.ResponseHandler(c) } /** @@ -554,11 +555,11 @@ func APIProfileHandler(c *gin.Context) { user, _, errorUser := users.FindByID(uint(id)) if errorUser == nil { user.APIToken = "" // We erase apitoken from public profile - apiResponseHandler(c, user.ToJSON()) + apiUtils.ResponseHandler(c, user.ToJSON()) return } messages.Error(errorUser) - apiResponseHandler(c) + apiUtils.ResponseHandler(c) } /** @@ -604,11 +605,11 @@ func APIOwnProfile(c *gin.Context) { client := oauthCtx.GetSession() user, _, _, errorUser := users.FindByUsername(client.GetSubject()) if errorUser == nil { - apiResponseHandler(c, user.ToJSON()) + apiUtils.ResponseHandler(c, user.ToJSON()) return } messages.Error(errorUser) - apiResponseHandler(c) + apiUtils.ResponseHandler(c) return } c.AbortWithError(http.StatusBadRequest, errors.New("Can't get your tokens")) @@ -631,12 +632,12 @@ func APIRefreshTokenHandler(c *gin.Context) { _, errorUser := user.UpdateRaw() if errorUser == nil { messages.AddInfoT("infos", "profile_updated") - apiResponseHandler(c, user.ToJSON()) + apiUtils.ResponseHandler(c, user.ToJSON()) return } messages.Error(errorUser) } - apiResponseHandler(c) + apiUtils.ResponseHandler(c) } // APICheckTokenHandler : Check Token with API @@ -652,37 +653,5 @@ func APICheckTokenHandler(c *gin.Context) { } else { messages.AddInfo("infos", "Logged") } - apiResponseHandler(c, user.ToJSON()) -} - -// This function is the global response for every simple Post Request API -// Please use it. Responses are of the type: -// {ok: bool, [errors | infos]: ArrayOfString [, data: ArrayOfObjects, all_errors: ArrayOfObjects]} -// To send errors or infos, you just need to use the Messages Util -func apiResponseHandler(c *gin.Context, obj ...interface{}) { - messages := msg.GetMessages(c) - - var mapOk map[string]interface{} - if !messages.HasErrors() { - mapOk = map[string]interface{}{"ok": true, "infos": messages.GetInfos("infos")} - if len(obj) > 0 { - mapOk["data"] = obj - if len(obj) == 1 { - mapOk["data"] = obj[0] - } - } - } else { // We need to show error messages - mapOk = map[string]interface{}{"ok": false, "errors": messages.GetErrors("errors"), "all_errors": messages.GetAllErrors()} - if len(obj) > 0 { - mapOk["data"] = obj - if len(obj) == 1 { - mapOk["data"] = obj[0] - } - } - if len(messages.GetAllErrors()) > 0 && len(messages.GetErrors("errors")) == 0 { - mapOk["errors"] = "errors" - } - } - - c.JSON(http.StatusOK, mapOk) + apiUtils.ResponseHandler(c, user.ToJSON()) } diff --git a/controllers/torrent/tag.go b/controllers/torrent/tag.go index 0ae50c5d..0d65368a 100644 --- a/controllers/torrent/tag.go +++ b/controllers/torrent/tag.go @@ -12,6 +12,7 @@ import ( "github.com/NyaaPantsu/nyaa/models/tag" "github.com/NyaaPantsu/nyaa/models/torrents" "github.com/NyaaPantsu/nyaa/templates" + "github.com/NyaaPantsu/nyaa/utils/api" "github.com/NyaaPantsu/nyaa/utils/log" msg "github.com/NyaaPantsu/nyaa/utils/messages" "github.com/NyaaPantsu/nyaa/utils/validator" @@ -20,7 +21,7 @@ import ( ) // postTag is a function used by controllers to post a tag -func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) { +func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) *models.Tag { messages := msg.GetMessages(c) tagForm := &tagsValidator.CreateForm{} @@ -30,16 +31,17 @@ func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) { // We check that the tag type sent is one enabled in config.yml if !tagsValidator.CheckTagType(tagForm.Type) { messages.ErrorT(errors.New("wrong_tag_type")) - return + return nil } if user.Tags.Contains(models.Tag{Tag: tagForm.Tag, Type: tagForm.Type}) { log.Info("User has already tagged the type for the torrent") - return + return nil } - tags.Create(tagForm.Tag, tagForm.Type, torrent, user) // Add a tag to the db - tags.Filter(tagForm.Tag, tagForm.Type, torrent.ID) // Check if we have a tag reaching the maximum weight, if yes, deletes every tag and add only the one accepted + tag, _ := tags.Create(tagForm.Tag, tagForm.Type, torrent, user) // Add a tag to the db + tags.Filter(tagForm.Tag, tagForm.Type, torrent.ID) // Check if we have a tag reaching the maximum weight, if yes, deletes every tag and add only the one accepted + return tag } // ViewFormTag is a controller displaying a form to add a tag to a torrent @@ -62,20 +64,16 @@ func ViewFormTag(c *gin.Context) { // We add a tag if posted if c.PostForm("tag") != "" && user.ID > 0 { - postTag(c, torrent, user) + tag := postTag(c, torrent, user) if !messages.HasErrors() { if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{true}) + apiUtils.ResponseHandler(c, tag) return } c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id)) } if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{false}) + apiUtils.ResponseHandler(c) return } } @@ -109,21 +107,17 @@ func AddTag(c *gin.Context) { validator.ValidateForm(tagForm, messages) if !messages.HasErrors() { - postTag(c, torrent, user) + tag := postTag(c, torrent, user) if !messages.HasErrors() { if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{true}) + apiUtils.ResponseHandler(c, tag) return } } } } if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{false}) + apiUtils.ResponseHandler(c) return } c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id)) @@ -161,9 +155,7 @@ func DeleteTag(c *gin.Context) { break } if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{true}) + apiUtils.ResponseHandler(c, tag) return } break @@ -172,9 +164,7 @@ func DeleteTag(c *gin.Context) { } } if _, ok := c.GetQuery("json"); ok { - c.JSON(http.StatusOK, struct { - Ok bool - }{false}) + apiUtils.ResponseHandler(c) return } c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id)) diff --git a/models/tag.go b/models/tag.go index 912084ce..dac3a367 100644 --- a/models/tag.go +++ b/models/tag.go @@ -9,13 +9,13 @@ import ( // Tag model for a torrent vote system type Tag struct { - TorrentID uint `gorm:"column:torrent_id"` - UserID uint `gorm:"column:user_id"` - Tag string `gorm:"column:tag"` - Type string `gorm:"column:type"` - Weight float64 `gorm:"column:weight"` - Accepted bool `gorm:"column:accepted"` - Total float64 `gorm:"-"` + TorrentID uint `gorm:"column:torrent_id" json:"torrent_id"` + UserID uint `gorm:"column:user_id" json:"user_id"` + Tag string `gorm:"column:tag" json:"tag"` + Type string `gorm:"column:type" json:"type"` + Weight float64 `gorm:"column:weight" json:"weight"` + Accepted bool `gorm:"column:accepted" json:"accepted"` + Total float64 `gorm:"-" json:"total"` } // Update a tag diff --git a/templates/site/torrents/view.jet.html b/templates/site/torrents/view.jet.html index 23dc576a..0dfb8c78 100644 --- a/templates/site/torrents/view.jet.html +++ b/templates/site/torrents/view.jet.html @@ -66,9 +66,9 @@ {{end}} {{ if Torrent.Tags.HasAccepted() || User.ID > 0 }} - + {{ T("torrent_tags")}}: - + {{ range Torrent.Tags }} {{if .Accepted || User.ID > 0 }} @@ -248,11 +248,11 @@ Templates.Add("tag", function(tag) { var tagClass = (tag.accepted) ? "tag" : "tag pending" - var tagTitle = (tag.accepted) ? 'Tag: ' + tag.type + '({{ T("accepted") }} )' : tag.type + "(" + tag.total + ")" + var tagTitle = (tag.accepted) ? 'Tag: ' + tag.type + '({{ T("accepted") }} )' : tag.type + "(" + tag.weight + ")" return ` - `.T.r("tagtype_" + tag.type)+`: ` + tag.tag + ` + ` + T.r("tagtype_" + tag.type) + `: ` + tag.tag + ` ` @@ -269,11 +269,12 @@ document.querySelector("#modal_tag_form form").addEventListener("submit", functi var form = e.target var tag = form.querySelector("input#tag").value var tagtype = form.querySelector("select#type").value + var csrf = form.querySelector("input[name='csrf_token']").value - Query.Post(form.action+"&json", "tag="+tag+"&type="+tagtype, function(data) { + Query.Post(form.action+"&json", "tag="+tag+"&type="+encodeURIComponent(tagtype)+"&csrf_token="+encodeURIComponent(csrf), function(data) { if (data.ok) { Modal.CloseActive() - var tagHTml = Templates.render("tag", data.data) + var tagHTml = Templates.Render("tag", data.data) document.getElementById("tags-torrent").innerHTML = tagHTml + document.getElementById("tags-torrent").innerHTML } else { alert("Couldn't add a tag, please check your internet connexion and that all fields are filled.") diff --git a/utils/api/response.go b/utils/api/response.go new file mode 100644 index 00000000..cd0db877 --- /dev/null +++ b/utils/api/response.go @@ -0,0 +1,41 @@ +package apiUtils + +import ( + "net/http" + + msg "github.com/NyaaPantsu/nyaa/utils/messages" + + "github.com/gin-gonic/gin" +) + +// ResponseHandler : This function is the global response for every simple Post Request API +// Please use it. Responses are of the type: +// {ok: bool, [errors | infos]: ArrayOfString [, data: ArrayOfObjects, all_errors: ArrayOfObjects]} +// To send errors or infos, you just need to use the Messages Util +func ResponseHandler(c *gin.Context, obj ...interface{}) { + messages := msg.GetMessages(c) + + var mapOk map[string]interface{} + if !messages.HasErrors() { + mapOk = map[string]interface{}{"ok": true, "infos": messages.GetInfos("infos")} + if len(obj) > 0 { + mapOk["data"] = obj + if len(obj) == 1 { + mapOk["data"] = obj[0] + } + } + } else { // We need to show error messages + mapOk = map[string]interface{}{"ok": false, "errors": messages.GetErrors("errors"), "all_errors": messages.GetAllErrors()} + if len(obj) > 0 { + mapOk["data"] = obj + if len(obj) == 1 { + mapOk["data"] = obj[0] + } + } + if len(messages.GetAllErrors()) > 0 && len(messages.GetErrors("errors")) == 0 { + mapOk["errors"] = "errors" + } + } + + c.JSON(http.StatusOK, mapOk) +}