Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0
Ce dépôt a été archivé le 2022-05-07. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
nyaa-pantsu/controllers/torrent/tag.go
akuma06 5633a37030 Fix for Tags (#1494)
* Fix #1479 and allows the removal of accepted tags for torrent's owner/moderator
* Fix #1478 moved /add to old api behavior
2017-09-04 08:40:08 +10:00

170 lignes
5 Kio
Go

package torrentController
import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/NyaaPantsu/nyaa/controllers/router"
"github.com/NyaaPantsu/nyaa/models"
"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"
"github.com/NyaaPantsu/nyaa/utils/validator/tag"
"github.com/gin-gonic/gin"
)
// postTags is a function used by controllers to post tags
func postTags(c *gin.Context, torrent *models.Torrent, user *models.User) []models.Tag {
var newTags []models.Tag
messages := msg.GetMessages(c)
// Bind already check if a tag is valid or not
tagsForm := tagsValidator.Bind(c, false)
if len(tagsForm) == 0 {
messages.ErrorT(errors.New("wrong_tag_type"))
return nil
}
for _, tagForm := range tagsForm {
// We validate the tag CreateForm
validator.ValidateForm(tagForm, messages)
if messages.HasErrors() { // if there are errors while validating the form, we skip it
continue
}
if len(user.Tags) == 0 { // In case we didn't call userLoadTags before calling this function
user.LoadTags(torrent)
}
newTag := models.Tag{Tag: tagForm.Tag, Type: tagForm.Type, UserID: user.ID, TorrentID: torrent.ID, Weight: user.Pantsu}
if user.Tags.Contains(newTag) {
// We check if the user has already submitted this tag, if he has, we prevent him to vote twice for it
log.Info("User has already tagged the type for the torrent")
return nil
}
// Add a tag to the db and filter them if needed
// Filtering means that we sum up all the tag with the same type/value
// and compare the sum with the maximum value (of votes) a tag can have
// if the value is greater than the maximum, we don't add the tag as a simple vote
// we add it directly in torrent model as an accepted tag and remove other tags with the same type
if tags.FilterOrCreate(&newTag, torrent, user) {
newTags = append(newTags, newTag)
}
}
torrent.Update(false)
return newTags
}
// ViewFormTag is a controller displaying a form to add a tag to a torrent
func ViewFormTag(c *gin.Context) {
user := router.GetUser(c)
// We add a tag only if user logged
if user.ID > 0 {
messages := msg.GetMessages(c)
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
// Retrieve the torrent
torrent, err := torrents.FindByID(uint(id))
var tagsForm models.Tags
// If torrent not found, display 404
if err != nil {
c.Status(http.StatusNotFound)
return
}
// We load tags for user so we can check if they have them
user.LoadTags(torrent)
if c.Request.Method == "POST" {
tagsForm = postTags(c, torrent, user)
if _, ok := c.GetQuery("json"); ok {
apiUtils.ResponseHandler(c, tagsForm)
return
}
if !messages.HasErrors() {
c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id))
}
}
templates.Form(c, "/site/torrents/tag.jet.html", tagsForm)
}
}
// AddTag is a controller to add a tag
func AddTag(c *gin.Context) {
messages := msg.GetMessages(c)
user := router.GetUser(c)
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
// Retrieve the torrent
torrent, err := torrents.FindByID(uint(id))
// If torrent not found, display 404
if err != nil {
c.Status(http.StatusNotFound)
return
}
tagForm := &tagsValidator.CreateForm{c.Query("tag"), c.Query("type")}
if c.Query("tag") != "" && user.ID > 0 {
validator.ValidateForm(tagForm, messages)
if !messages.HasErrors() {
// We load tags for user and torrents
user.LoadTags(torrent)
newTag := models.Tag{Tag: tagForm.Tag, Type: tagForm.Type, UserID: user.ID, TorrentID: torrent.ID, Weight: user.Pantsu}
if !user.Tags.Contains(newTag) {
// We check if the user has already submitted this tag, if he has, we prevent him to vote twice for it
tags.FilterOrCreate(&newTag, torrent, user)
torrent.Update(false)
}
}
}
if _, ok := c.GetQuery("json"); ok {
apiUtils.ResponseHandler(c, tagForm)
return
}
c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id))
}
// DeleteTag is a controller to delete a user tag
func DeleteTag(c *gin.Context) {
messages := msg.GetMessages(c)
user := router.GetUser(c)
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
// Retrieve the torrent
torrent, err := torrents.FindByID(uint(id))
// If torrent not found, display 404
if err != nil {
c.Status(http.StatusNotFound)
return
}
// We load tags for user and torrents
user.LoadTags(torrent)
tagForm := &tagsValidator.CreateForm{c.Query("tag"), c.Query("type")}
if c.Query("tag") != "" && user.ID > 0 {
validator.ValidateForm(tagForm, messages)
if !messages.HasErrors() {
for _, tag := range user.Tags {
if tag.Tag == tagForm.Tag && tag.Type == tagForm.Type {
_, err := tag.Delete()
log.CheckError(err)
break
}
}
}
}
if _, ok := c.GetQuery("json"); ok {
apiUtils.ResponseHandler(c, tagForm)
return
}
c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id))
}