Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Possibility to add tags from edit panel + upload

Cette révision appartient à :
akuma06 2017-08-01 23:38:13 +02:00
Parent bd959764f3
révision 0db143d685
21 fichiers modifiés avec 417 ajouts et 34 suppressions

Voir le fichier

@ -358,6 +358,7 @@ func APIUpdateHandler(c *gin.Context) {
if !messages.HasErrors() {
c.Bind(&update)
torrent, err := torrents.FindByID(update.ID)
torrent.LoadTags()
if err != nil {
messages.AddErrorTf("errors", "torrent_not_exist", strconv.Itoa(int(update.ID)))
}

Voir le fichier

@ -70,6 +70,7 @@ func TorrentsListPanel(c *gin.Context) {
func TorrentEditModPanel(c *gin.Context) {
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
torrent, _ := torrents.FindUnscopeByID(uint(id))
torrent.LoadTags()
torrentJSON := torrent.ToJSON()
uploadForm := upload.NewTorrentRequest()
@ -80,6 +81,7 @@ func TorrentEditModPanel(c *gin.Context) {
uploadForm.WebsiteLink = string(torrentJSON.WebsiteLink)
uploadForm.Description = string(torrentJSON.Description)
uploadForm.Languages = torrent.Languages
uploadForm.Tags = torrent.Tags.ToJSON(true)
templates.Form(c, "admin/paneltorrentedit.jet.html", uploadForm)
}
@ -90,6 +92,7 @@ func TorrentPostEditModPanel(c *gin.Context) {
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
messages := msg.GetMessages(c)
torrent, _ := torrents.FindUnscopeByID(uint(id))
torrent.LoadTags()
currentUser := router.GetUser(c)
if torrent.ID > 0 {
errUp := upload.ExtractEditInfo(c, &uploadForm.Update)

Voir le fichier

@ -1,9 +1,9 @@
package torrentController
import (
"fmt"
"net/http"
"strconv"
"fmt"
"github.com/NyaaPantsu/nyaa/controllers/router"
"github.com/NyaaPantsu/nyaa/models"
@ -19,8 +19,9 @@ import (
func TorrentEditUserPanel(c *gin.Context) {
id, _ := strconv.ParseInt(c.Query("id"), 10, 32)
torrent, _ := torrents.FindByID(uint(id))
torrent.LoadTags()
currentUser := router.GetUser(c)
if currentUser.CurrentOrAdmin(torrent.UploaderID) && torrent.ID > 0 {
if currentUser.CurrentOrAdmin(torrent.UploaderID) && torrent.ID > 0 {
uploadForm := torrentValidator.TorrentRequest{}
uploadForm.Name = torrent.Name
uploadForm.Category = strconv.Itoa(torrent.Category) + "_" + strconv.Itoa(torrent.SubCategory)
@ -29,6 +30,7 @@ func TorrentEditUserPanel(c *gin.Context) {
uploadForm.Description = string(torrent.Description)
uploadForm.Hidden = torrent.Hidden
uploadForm.Languages = torrent.Languages
uploadForm.Tags = torrent.Tags.ToJSON(true)
templates.Form(c, "site/torrents/edit.jet.html", uploadForm)
} else {
c.AbortWithStatus(http.StatusNotFound)
@ -42,6 +44,7 @@ func TorrentPostEditUserPanel(c *gin.Context) {
uploadForm.ID = uint(id)
messages := msg.GetMessages(c)
torrent, _ := torrents.FindByID(uint(id))
torrent.LoadTags()
currentUser := router.GetUser(c)
if torrent.ID > 0 && currentUser.CurrentOrAdmin(torrent.UploaderID) {
errUp := upload.ExtractEditInfo(c, &uploadForm.Update)

Voir le fichier

@ -40,7 +40,7 @@ func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) *models
}
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
tags.Filter(tagForm.Tag, tagForm.Type, torrent) // Check if we have a tag reaching the maximum weight, if yes, deletes every tag and add only the one accepted
return tag
}

Voir le fichier

@ -1,9 +1,11 @@
package models
import (
"encoding/json"
"errors"
"net/http"
"github.com/NyaaPantsu/nyaa/utils/log"
"github.com/fatih/structs"
)
@ -52,6 +54,28 @@ func (ts Tags) Contains(tag Tag) bool {
return false
}
// HasType check if the tag map has the same tag type in it and returns its index
func (ts Tags) HasType(tagtype string) int {
for i, ta := range ts {
if ta.Type == tagtype {
return i
}
}
return -1
}
// DeleteType remove all tags from the map that have the same tag type in it
func (ts *Tags) DeleteType(tagtype string) {
var newTs Tags
for _, ta := range *ts {
if ta.Type == tagtype {
continue
}
newTs = append(newTs, ta)
}
ts = &newTs
}
// HasAccepted check if a tag has been accepted in the tags map
func (ts Tags) HasAccepted() bool {
for _, tag := range ts {
@ -61,3 +85,32 @@ func (ts Tags) HasAccepted() bool {
}
return false
}
// Replace a tag in map of tags
func (ts Tags) Replace(index int, tag *Tag) {
if index >= 0 && index < len(ts) {
ts[index].Delete()
ts[index] = *tag
ts[index].Update()
}
}
// ToJSON convert tags map to a json map and can exclud non accepted tags
func (ts Tags) ToJSON(onlyAccepted bool) string {
var toParse Tags
if onlyAccepted {
for _, tag := range ts {
if tag.Accepted {
toParse = append(toParse, tag)
}
}
} else {
toParse = ts
}
b, err := json.Marshal(toParse)
if err != nil {
log.Infof("Couldn't parse to json the tags %v", toParse)
return ""
}
return string(b)
}

Voir le fichier

@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
)
// Create a new tag based on string inputs
func Create(tag string, tagType string, torrent *models.Torrent, user *models.User) (*models.Tag, error) {
newTag := &models.Tag{
Tag: tag,
@ -15,13 +16,17 @@ func Create(tag string, tagType string, torrent *models.Torrent, user *models.Us
Weight: user.Pantsu,
Accepted: false,
}
return New(newTag, torrent)
}
// New is the low level functions that actually create a tag in db
func New(tag *models.Tag, torrent *models.Torrent) (*models.Tag, error) {
if torrent.ID == 0 {
return newTag, errors.New("Can't add a tag to no torrents")
return tag, errors.New("Can't add a tag to no torrents")
}
if err := models.ORM.Create(newTag).Error; err != nil {
return newTag, err
if err := models.ORM.Create(tag).Error; err != nil {
return tag, err
}
cache.C.Delete(torrent.Identifier())
return newTag, nil
return tag, nil
}

Voir le fichier

@ -3,8 +3,6 @@ package tags
import (
"fmt"
"github.com/NyaaPantsu/nyaa/models/torrents"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/models/users"
@ -12,15 +10,15 @@ import (
)
// Filter check if a tag type has reached the maximal votes and removes the other tag of the same type
func Filter(tag string, tagType string, torrentID uint) bool {
if torrentID == 0 || tagType == "" || tag == "" {
func Filter(tag string, tagType string, torrent *models.Torrent) bool {
if torrent.ID == 0 || tagType == "" || tag == "" {
return false
}
tagSum := models.Tag{}
if err := models.ORM.Select("torrent_id, tag, type, accepted, SUM(weight) as total").Where("torrent_id = ? AND tag = ? AND type = ?", torrentID, tag, tagType).Group("type, tag").Find(&tagSum).Error; err == nil {
if err := models.ORM.Select("torrent_id, tag, type, accepted, SUM(weight) as total").Where("torrent_id = ? AND tag = ? AND type = ?", torrent.ID, tag, tagType).Group("type, tag").Find(&tagSum).Error; err == nil {
fmt.Println(tagSum)
if tagSum.Total > config.Get().Torrents.Tags.MaxWeight {
tags, err := FindAll(tagType, torrentID)
tags, err := FindAll(tagType, torrent.ID)
if err != nil {
return false
}
@ -39,28 +37,25 @@ func Filter(tag string, tagType string, torrentID uint) bool {
}
toDelete.Delete()
}
/* err := DeleteAllType(tagType, torrentID) // We can also delete them in batch
/* err := DeleteAllType(tagType, torrent.ID) // We can also delete them in batch
log.CheckError(err) */
tagSum.Accepted = true
tagSum.UserID = 0 // System ID
tagSum.Weight = config.Get().Torrents.Tags.MaxWeight // Overriden to the maximal value
models.ORM.Save(&tagSum) // We only add back the tag accepted
callbackOnType(&tagSum)
callbackOnType(&tagSum, torrent)
return true
}
}
return false
}
func callbackOnType(tag *models.Tag) {
func callbackOnType(tag *models.Tag, torrent *models.Torrent) {
switch tag.Type {
case "anidbid", "vndbid":
if tag.Accepted && tag.TorrentID > 0 {
torrent, err := torrents.FindByID(tag.TorrentID)
if err == nil {
torrent.DbID = tag.Tag
torrent.Update(false)
}
if tag.Accepted && tag.TorrentID > 0 && torrent.ID > 0 {
torrent.DbID = tag.Tag
torrent.Update(false)
}
}
}

Voir le fichier

@ -1,14 +1,18 @@
package torrents
import (
"encoding/json"
"time"
"github.com/NyaaPantsu/nyaa/models/tag"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/utils/log"
"github.com/NyaaPantsu/nyaa/utils/validator/torrent"
)
// Create a new torrent based on the uploadform request struct
func Create(user *models.User, uploadForm *torrentValidator.TorrentRequest) (*models.Torrent, error) {
torrent := models.Torrent{
Name: uploadForm.Name,
@ -51,5 +55,17 @@ func Create(user *models.User, uploadForm *torrentValidator.TorrentRequest) (*mo
models.ORM.Create(&file)
}
}
var tagsReq models.Tags
json.Unmarshal([]byte(uploadForm.Tags), &tagsReq)
for _, tag := range tagsReq {
tag.Accepted = true
tag.TorrentID = torrent.ID
tag.Weight = config.Get().Torrents.Tags.MaxWeight
tags.New(&tag, &torrent) // We create new tags
torrent.Tags = append(torrent.Tags) // Finally we append it to the torrent
}
user.IncreasePantsu()
return &torrent, nil
}

Voir le fichier

@ -31,9 +31,9 @@ var Modal = {
// Get the button that opens the modal
if (!btn) {
btn = document.getElementById("modal_btn_" + modal.id)
} else if (btn instanceof String && btn.match(/^#/)) {
} else if (typeof(btn) == "string" && btn.match(/^#/)) {
btn = document.getElementById(btn.substr(1));
} else if (btn instanceof String && btn.match(/^\./)) {
} else if (typeof(btn) == "string" && btn.match(/^\./)) {
btn = document.getElementsByClassName(btn.substr(1));
isBtnArray = true;
} else if (btn instanceof Array) {

Voir le fichier

@ -48,11 +48,77 @@
<p class="help-block">{{ T("description_markdown_notice")}}</p>
<textarea name="desc" id="desc" class="form-input up-input" rows="10">{{Form.Description}}</textarea>
</div>
<h3>{{ T("torrent_tags")}}</h3>
<span id="tags_list"></span>
<a id="tagPopup" href="#" class="add-tag">{{ T("add") }}</a>
<input type="hidden" name="tags" id="tags" value="{{ Form.Tags }}">
{{ yield errors(name="tags")}}
<button type="submit" class="form-input up-input btn-green">{{ T("save_changes")}}</button>
</form>
</div>
{{end}} {{ block footer_js()}}
{{ include "layouts/partials/modal_tags" }}
{{end}}
{{ block footer_js()}}
<script type="text/javascript" src="/js/translation.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/template.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/modal.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/simplemde.min.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript">
// {{ range _, type := Config.Torrents.Tags.Types }}
T.Add("tagtype_{{ type }}", '{{ T("tagtype_" + type) }}')
// {{ end }}
Templates.Add("tag", function(tag) {
return `<span data-name="` + tag.type + `_` + tag.tag + `" class="tag accepted" title="Tag: ` + tag.type + `({{ T("accepted") }} )">
<span class="tag-text votable">
` + T.r("tagtype_" + tag.type) + `: ` + tag.tag + `
</span>
</span>`
})
// Modal initialization
Modal.Init({
elements: document.getElementsByClassName("modal"),
// order of apparition of the modals
button: "#tagPopup"
});
var tags = []
document.querySelector("#modal_tag_form form").addEventListener("submit", function(e) {
var form = e.target
var newTag = {type: form.querySelector("select#type").value, tag: form.querySelector("input#tag").value}
var replaced = false
var len = tags.length
for(var i = 0; i < len; i++) {
if (tags[i].type == newTag.type) {
var oldTag = document.querySelector("span[data-name='"+ tags[i].type + "_" + tags[i].tag + "']")
oldTag.parentElement.removeChild(oldTag)
tags[i] = newTag
replaced = true
break
}
}
if (!replaced) tags.push(newTag)
var tagHTml = Templates.Render("tag", newTag)
document.getElementById("tags_list").innerHTML += tagHTml
document.getElementById("tags").value = JSON.stringify(tags)
Modal.CloseActive()
e.preventDefault()
})
function renderTagsJSON() {
tagsIn = document.getElementById("tags").value
if (tagsIn == "") return
var jsonFromTags = JSON.parse(tagsIn)
if (jsonFromTags instanceof Array) {
for (var i = 0; i < jsonFromTags.length; i++) {
tags.push(jsonFromTags[i])
var tagHTml = Templates.Render("tag", jsonFromTags[i])
document.getElementById("tags_list").innerHTML += tagHTml
}
}
}
renderTagsJSON()
</script>
<script type="text/javascript">
new SimpleMDE({
element: document.getElementById("desc"),

Voir le fichier

@ -0,0 +1,36 @@
<!-- Modal to add a tag -->
<div id="modal_tag_form" class="modal">
<!-- Modal content -->
<div class="modal-content">
<form method="post" action="#">
<div class="modal-header">
<span class="close">&times;</span>
<h2>{{ T("add_tag") }}</h2>
</div>
<div class="modal-body">
<h4>{{ T("add_tag") }}</h4>
<div class="form-group">
<label class="input-label" for="tag">{{ T("tag")}}</label>
<input type="text" id="tag" name="tag" class="form-input up-input" value="" required/>
{{ yield errors(name="Tag")}}
</div>
<div class="form-group">
<label class="input-label" for="type">{{ T("tagtype")}}</label>
<select name="type" id="type" class="form-input up-input">
{{ range _, type := Config.Torrents.Tags.Types }}
<option value="{{ type }}">{{T("tagtype_" + type) }}</option>
{{ end }}
</select>
{{ yield errors(name="Type")}}
</div>
</div>
<div class="modal-footer">
<span>
<button id="confirm_changes" type="submit">{{ T("add")}}</button>
<button class="close" onclick="Modal.CloseActive();">{{ T("close")}}</button>
</span>
<h3>{{ T("are_you_sure") }} </h3>
</div>
</form>
</div>
</div>

Voir le fichier

@ -29,8 +29,8 @@ Templates.Add("torrents.item", function(torrent) {
// {{end}}
var languages = ""
var colspan = (torrent.comments.length == 0 ? ` colspan="2"` : "" )
var commentTd = ((torrent.comments.length > 0) ? '<td class="tr-cs home-td"><span>' + torrent.comments.length + '</span></td>' : "")
var dlLink = (torrent.torrent != "" ? ' <a href="` + torrent.torrent + `" title="{{ T("torrent_file") }}"><div class="icon-floppy"></div></a>' : "")
var commentTd = ((torrent.comments.length > 0) ? `<td class="tr-cs home-td"><span>` + torrent.comments.length + `</span></td>` : "")
var dlLink = (torrent.torrent != "" ? ` <a href="` + torrent.torrent + `" title="{{ T("torrent_file") }}"><div class="icon-floppy"></div></a>` : "")
if (torrent.languages[0] != "") {
var flagClass = (torrent.languages.length == 1) ? Templates.FlagCode(torrent.languages[0]) : "multiple"
@ -56,7 +56,7 @@ Templates.Add("torrents.item", function(torrent) {
<a href="` + torrent.magnet + `" title="{{ T("magnet_link") }}">
<div class="icon-magnet"></div>
</a>`+ dlLink +`
</td>"+
</td>
<td class="tr-size home-td hide-xs">` + humanFileSize(torrent.filesize) + `</td>
<td class="tr-se home-td hide-smol">` + torrent.seeders + `</td>
<td class="tr-le home-td hide-smol">` + torrent.leechers + `</td>

Voir le fichier

@ -47,7 +47,7 @@ Templates.Add("torrents.item", function(torrent) {
<a title="{{ T("magnet_link") }}">
<div class="icon-magnet"></div>
</a>`+ dlLink +`
</td>"+
</td>
<td class="tr-size home-td hide-xs">` + humanFileSize(torrent.filesize) + `</td>
<td class="tr-se home-td hide-smol">` + torrent.seeders + `</td>
<td class="tr-le home-td hide-smol">` + torrent.leechers + `</td>

Voir le fichier

@ -52,13 +52,78 @@
<p class="help-block">{{ T("description_markdown_notice")}}</p>
<textarea style="height: 10rem;" id="desc" name="desc" class="form-input up-input" rows="10">{{Form.Description}}</textarea>
</div>
<h3>{{ T("torrent_tags")}}</h3>
<span id="tags_list"></span>
<a id="tagPopup" href="#" class="add-tag">{{ T("add") }}</a>
<input type="hidden" name="tags" id="tags" value="{{ Form.Tags }}">
{{ yield errors(name="tags")}}
<button type="submit" class="form-input up-input">{{ T("save_changes")}}</button>
<br/>
<br/>
</form>
</div>
{{ include "layouts/partials/modal_tags" }}
{{end}}
{{ block footer_js()}}
<script type="text/javascript" src="/js/translation.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/template.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/modal.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript">
// {{ range _, type := Config.Torrents.Tags.Types }}
T.Add("tagtype_{{ type }}", '{{ T("tagtype_" + type) }}')
// {{ end }}
Templates.Add("tag", function(tag) {
return `<span data-name="` + tag.type + `_` + tag.tag + `" class="tag accepted" title="Tag: ` + tag.type + `({{ T("accepted") }} )">
<span class="tag-text votable">
` + T.r("tagtype_" + tag.type) + `: ` + tag.tag + `
</span>
</span>`
})
// Modal initialization
Modal.Init({
elements: document.getElementsByClassName("modal"),
// order of apparition of the modals
button: "#tagPopup"
});
var tags = []
document.querySelector("#modal_tag_form form").addEventListener("submit", function(e) {
var form = e.target
var newTag = {type: form.querySelector("select#type").value, tag: form.querySelector("input#tag").value}
var replaced = false
var len = tags.length
for(var i = 0; i < len; i++) {
if (tags[i].type == newTag.type) {
var oldTag = document.querySelector("span[data-name='"+ tags[i].type + "_" + tags[i].tag + "']")
oldTag.parentElement.removeChild(oldTag)
tags[i] = newTag
replaced = true
break
}
}
if (!replaced) tags.push(newTag)
var tagHTml = Templates.Render("tag", newTag)
document.getElementById("tags_list").innerHTML += tagHTml
document.getElementById("tags").value = JSON.stringify(tags)
Modal.CloseActive()
e.preventDefault()
})
function renderTagsJSON() {
tagsIn = document.getElementById("tags").value
if (tagsIn == "") return
var jsonFromTags = JSON.parse(tagsIn)
if (jsonFromTags instanceof Array) {
for (var i = 0; i < jsonFromTags.length; i++) {
tags.push(jsonFromTags[i])
var tagHTml = Templates.Render("tag", jsonFromTags[i])
document.getElementById("tags_list").innerHTML += tagHTml
}
}
}
renderTagsJSON()
</script>
<script type="text/javascript" src="/js/simplemde.min.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript">new SimpleMDE({ element: document.getElementById("desc"), spellChecker: false, showIcons: [ "strikethrough", "code", "table", "horizontal-rule" ] });</script>
{{end}}

Voir le fichier

@ -152,6 +152,7 @@
</p>
{{ yield errors(name="hidden")}}
{{ end }}
<h3>{{ T("website_link")}}</h3>
<input name="website_link" id="website_link" class="form-input up-input" type="text" value="{{Form.WebsiteLink}}"/>
{{ yield errors(name="website_link")}}
@ -159,7 +160,12 @@
<h3>{{ T("torrent_description")}}</h3>
<p>{{ T("description_markdown_notice")}}</p>
<textarea name="desc" id="desc" class="form-input up-input" style="height: 10rem;">{{Form.Description}}</textarea>
{{ yield errors(name="desc")}}
<h3>{{ T("torrent_tags")}}</h3>
<span id="tags_list"></span>
<a id="tagPopup" href="#" class="add-tag">{{ T("add") }}</a>
<input type="hidden" name="tags" id="tags" value="{{ Form.Tags }}">
{{ yield errors(name="tags")}}
<div style="width: 240px">
{{yield captcha(captchaid=Form.CaptchaID)}}
</div>
@ -168,11 +174,13 @@
<button type="submit" class="form-input up-btn">{{ T("upload")}}</button>
</form>
</div>
{{ include "layouts/partials/modal_tags" }}
{{end}}
{{ block footer_js()}}
<script type="text/javascript" src="/js/query.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/translation.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/template.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/modal.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/kilo.js?v={{ Config.Version}}{{ Config.Build }}"></script>
<script type="text/javascript" src="/js/simplemde.min.js?v={{ Config.Version}}{{ Config.Build }}"></script>
{{ include "layouts/partials/torrent_item_upload" }}
@ -190,6 +198,62 @@
listContext: true
})
preview.render()
</script>
<script type="text/javascript">new SimpleMDE({ element: document.getElementById("desc"), spellChecker: false, showIcons: [ "strikethrough", "code", "table", "horizontal-rule" ] });</script>
{{end}}
</script>
<script type="text/javascript">
// {{ range _, type := Config.Torrents.Tags.Types }}
T.Add("tagtype_{{ type }}", '{{ T("tagtype_" + type) }}')
// {{ end }}
Templates.Add("tag", function(tag) {
return `<span data-name="` + tag.type + `_` + tag.tag + `" class="tag accepted" title="Tag: ` + tag.type + `({{ T("accepted") }} )">
<span class="tag-text votable">
` + T.r("tagtype_" + tag.type) + `: ` + tag.tag + `
</span>
</span>`
})
// Modal initialization
Modal.Init({
elements: document.getElementsByClassName("modal"),
// order of apparition of the modals
button: "#tagPopup"
});
var tags = []
document.querySelector("#modal_tag_form form").addEventListener("submit", function(e) {
var form = e.target
var newTag = {type: form.querySelector("select#type").value, tag: form.querySelector("input#tag").value}
var replaced = false
var len = tags.length
for(var i = 0; i < len; i++) {
if (tags[i].type == newTag.type) {
var oldTag = document.querySelector("span[data-name='"+ tags[i].type + "_" + tags[i].tag + "']")
oldTag.parentElement.removeChild(oldTag)
tags[i] = newTag
replaced = true
break
}
}
if (!replaced) tags.push(newTag)
var tagHTml = Templates.Render("tag", newTag)
document.getElementById("tags_list").innerHTML += tagHTml
document.getElementById("tags").value = JSON.stringify(tags)
Modal.CloseActive()
e.preventDefault()
})
function renderTagsJSON() {
tagsIn = document.getElementById("tags").value
if (tagsIn == "") return
var jsonFromTags = JSON.parse(tagsIn)
if (jsonFromTags instanceof Array) {
for (var i = 0; i < jsonFromTags.length; i++) {
tags.push(jsonFromTags[i])
var tagHTml = Templates.Render("tag", jsonFromTags[i])
document.getElementById("tags_list").innerHTML += tagHTml
}
}
}
renderTagsJSON()
</script>
<script type="text/javascript">new SimpleMDE({ element: document.getElementById("desc"), spellChecker: false, showIcons: [ "strikethrough", "code", "table", "horizontal-rule" ] });</script>
{{end}}

Voir le fichier

@ -58,7 +58,7 @@ func walkDirTest(dir string, t *testing.T) {
fakeActivity := &models.Activity{1, "t", "e", "s", 1, fakeUser}
fakeDB := &models.DatabaseDump{time.Now(), 3, "test", "test"}
fakeLanguage := &publicSettings.Language{"English", "en", "en-us"}
fakeTorrentRequest := &torrentValidator.TorrentRequest{Name: "test", Magnet: "", Category: "", Remake: false, Description: "", Status: 1, Hidden: false, CaptchaID: "", WebsiteLink: "", SubCategory: 0, Languages: nil, Infohash: "", SubCategoryID: 0, CategoryID: 0, Filesize: 0, Filepath: "", FileList: nil, Trackers: nil}
fakeTorrentRequest := &torrentValidator.TorrentRequest{Name: "test", Magnet: "", Category: "", Remake: false, Description: "", Status: 1, Hidden: false, CaptchaID: "", WebsiteLink: "", SubCategory: 0, Languages: nil, Infohash: "", SubCategoryID: 0, CategoryID: 0, Filesize: 0, Filepath: "", FileList: nil, Trackers: nil, Tags: ""}
fakeLogin := &userValidator.LoginForm{"test", "test", "/"}
fakeRegistration := &userValidator.RegistrationForm{"test", "", "test", "test", "xxxx", "1"}
fakeReport := &models.TorrentReport{1, "test", 1, 1, time.Now(), fakeTorrent, fakeUser}

Voir le fichier

@ -1,6 +1,7 @@
package upload
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
@ -9,6 +10,8 @@ import (
"reflect"
"strings"
"github.com/NyaaPantsu/nyaa/models/tag"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/utils/sanitize"
@ -86,6 +89,8 @@ func ExtractEditInfo(c *gin.Context, r *torrentValidator.TorrentRequest) error {
// ExtractBasicValue : takes an http request and computes all basic fields for this form
func ExtractBasicValue(c *gin.Context, r *torrentValidator.TorrentRequest) error {
c.Bind(r)
r.Tags = c.PostForm("tags")
// trim whitespace
r.Name = strings.TrimSpace(r.Name)
r.Description = sanitize.Sanitize(strings.TrimSpace(r.Description), "default")
@ -102,6 +107,8 @@ func ExtractBasicValue(c *gin.Context, r *torrentValidator.TorrentRequest) error
return err
}
r.ValidateTags() // Tags should only be filtered, don't stop the errors from uploading
err = r.ValidateWebsiteLink()
return err
}
@ -179,6 +186,20 @@ func UpdateTorrent(r *torrentValidator.UpdateRequest, t *models.Torrent, current
t.Hidden = r.Update.Hidden
// This part of the code check that we have only one tag of the same type
var tagsReq models.Tags
json.Unmarshal([]byte(r.Update.Tags), &tagsReq)
for _, tag := range tagsReq {
tag.Accepted = true
tag.TorrentID = t.ID
tag.UserID = 0 // 0 so we don't increase pantsu points for every tag for the actual user (would be too much increase)
tag.Weight = config.Get().Torrents.Tags.MaxWeight + 1
tags.New(&tag, t) // We create new tags with the user id
tags.Filter(tag.Tag, tag.Type, t) // We filter out every tags and increase/decrease pantsu for already sent tags
t.Tags.DeleteType(tag.Type) // We cleanup the map from the other tags
t.Tags = append(t.Tags) // Finally we append ours to the torrent
}
return t
}

Voir le fichier

@ -12,3 +12,4 @@ var errTorrentPrivate = errors.New("torrent_private")
var errTorrentNoTrackers = errors.New("torrent_no_working_trackers")
var errTorrentAndMagnet = errors.New("torrent_plus_magnet")
var errTorrentHashInvalid = errors.New("torrent_hash_invalid")
var errTorrentTagsInvalid = errors.New("torrent_tags_invalid")

Voir le fichier

@ -22,6 +22,7 @@ type TorrentRequest struct {
Filepath string `json:"-"`
FileList []uploadedFile `json:"filelist,omitempty"`
Trackers []string `json:"trackers,omitempty"`
Tags string `json:"tags,omitempty" form:"tags"`
}
// UpdateRequest struct

Voir le fichier

@ -3,6 +3,7 @@ package torrentValidator
import (
"encoding/base32"
"encoding/hex"
"encoding/json"
"io"
"mime/multipart"
"net/url"
@ -14,9 +15,11 @@ import (
"github.com/NyaaPantsu/nyaa/utils/categories"
"github.com/NyaaPantsu/nyaa/utils/cookies"
"github.com/NyaaPantsu/nyaa/utils/format"
"github.com/NyaaPantsu/nyaa/utils/log"
msg "github.com/NyaaPantsu/nyaa/utils/messages"
"github.com/NyaaPantsu/nyaa/utils/metainfo"
"github.com/NyaaPantsu/nyaa/utils/torrentLanguages"
"github.com/NyaaPantsu/nyaa/utils/validator/tag"
"github.com/gin-gonic/gin"
"github.com/zeebo/bencode"
)
@ -29,6 +32,34 @@ func (r *TorrentRequest) ValidateName() error {
return nil
}
func (r *TorrentRequest) ValidateTags() error {
// We need to parse it to json
var tags []tagsValidator.CreateForm
err := json.Unmarshal([]byte(r.Tags), &tags)
if err != nil {
r.Tags = ""
return errTorrentTagsInvalid
}
// and filter out multiple tags with the same type (only keep the first one)
var index config.ArrayString
var filteredTags []tagsValidator.CreateForm
for _, tag := range tags {
if index.Contains(tag.Type) {
continue
}
filteredTags = append(filteredTags, tag)
index = append(index, tag.Type)
}
b, err := json.Marshal(filteredTags)
if err != nil {
r.Tags = ""
log.Infof("Couldn't parse to json the tags %v", filteredTags)
return errTorrentTagsInvalid
}
r.Tags = string(b)
return nil
}
func (r *TorrentRequest) ValidateDescription() error {
if len(r.Description) > config.Get().DescriptionLength {
return errTorrentDescInvalid

Voir le fichier

@ -172,3 +172,25 @@ func TestExtractLanguage(t *testing.T) {
}
}
}
func TestValidateTags(t *testing.T) {
r := TorrentRequest{}
tests := []struct {
Test string
Expected error
}{
{"", errTorrentTagsInvalid},
{`{"":"","":""}`, errTorrentTagsInvalid},
{`{"tag":"xD","type":"lol"}`, errTorrentTagsInvalid},
{`[{"tag":"xD","type":"lol"}]`, nil},
{`[{"tag":"xD","type":"lol"},{"tag":"xD","type":"lol"}]`, nil},
}
for _, test := range tests {
r.Tags = test.Test
err := r.ValidateTags()
if err != test.Expected {
t.Errorf("Validation of torrent hash for '%s' doesn't give the expected result, have '%v', wants '%v'", test.Test, err, test.Expected)
}
}
}