Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Merge pull request #653 from NyaaPantsu/torrent-weblink

Torrent weblink
Cette révision appartient à :
akuma06 2017-05-20 17:14:11 +02:00 révisé par GitHub
révision 41b57edfe3
8 fichiers modifiés avec 111 ajouts et 75 suppressions

Voir le fichier

@ -365,13 +365,13 @@ func torrentManyAction(r *http.Request) {
messages := msg.GetMessages(r) // new util for errors and infos
if action == "" {
messages.AddError(r, "errors", "You have to tell what you want to do with your selection!")
messages.AddError("errors", "You have to tell what you want to do with your selection!")
}
if action == "move" && r.FormValue("moveto") == "" { // We need to check the form value, not the int one because hidden is 0
messages.AddError(r, "errors", "Thou has't to telleth whither thee wanteth to moveth thy selection!")
messages.AddError("errors", "Thou has't to telleth whither thee wanteth to moveth thy selection!")
}
if len(torrentsSelected) == 0 {
messages.AddError(r, "errors", "You need to select at least 1 element!")
messages.AddError("errors", "You need to select at least 1 element!")
}
if !messages.HasErrors() {
for _, torrent_id := range torrentsSelected {
@ -382,22 +382,22 @@ func torrentManyAction(r *http.Request) {
if config.TorrentStatus[moveTo] {
torrent.Status = moveTo
db.ORM.Save(&torrent)
messages.AddInfof(r, "infos", "Torrent %s moved!", torrent.Name)
messages.AddInfof("infos", "Torrent %s moved!", torrent.Name)
} else {
messages.AddErrorf(r, "errors", "No such status %d exist!", moveTo)
messages.AddErrorf("errors", "No such status %d exist!", moveTo)
}
case "delete":
_, err := torrentService.DeleteTorrent(torrent_id)
if err != nil {
messages.ImportFromError(r, "errors", err)
messages.ImportFromError("errors", err)
} else {
messages.AddInfof(r, "infos", "Torrent %s deleted!", torrent.Name)
messages.AddInfof("infos", "Torrent %s deleted!", torrent.Name)
}
default:
messages.AddErrorf(r, "errors", "No such action %s exist!", action)
messages.AddErrorf("errors", "No such action %s exist!", action)
}
} else {
messages.AddErrorf(r, "errors", "Torrent with ID %s doesn't exist!", torrent_id)
messages.AddErrorf("errors", "Torrent with ID %s doesn't exist!", torrent_id)
}
}
}

Voir le fichier

@ -36,6 +36,8 @@ type NotFoundTemplateVariables struct {
type ViewTemplateVariables struct {
Torrent model.TorrentJSON
CaptchaID string
FormErrors map[string][]string
Infos map[string][]string
Search SearchForm
Navigation Navigation
User *model.User
@ -116,6 +118,7 @@ type DatabaseDumpTemplateVariables struct {
type UploadTemplateVariables struct {
Upload UploadForm
FormErrors map[string][]string
Search SearchForm
Navigation Navigation
User *model.User

Voir le fichier

@ -40,6 +40,7 @@ type UploadForm struct {
Description string
Status int
CaptchaID string
WebsiteLink string
Infohash string
CategoryID int
@ -58,25 +59,29 @@ const UploadFormMagnet = "magnet"
const UploadFormCategory = "c"
const UploadFormRemake = "remake"
const UploadFormDescription = "desc"
const UploadFormWebsiteLink = "website_link"
const UploadFormStatus = "status"
// error indicating that you can't send both a magnet link and torrent
var ErrTorrentPlusMagnet = errors.New("upload either a torrent file or magnet link, not both")
var ErrTorrentPlusMagnet = errors.New("Upload either a torrent file or magnet link, not both")
// error indicating a torrent is private
var ErrPrivateTorrent = errors.New("torrent is private")
var ErrPrivateTorrent = errors.New("Torrent is private")
// error indicating a problem with its trackers
var ErrTrackerProblem = errors.New("torrent does not have any (working) trackers: https://" + config.WebAddress + "/faq#trackers")
var ErrTrackerProblem = errors.New("Torrent does not have any (working) trackers: https://" + config.WebAddress + "/faq#trackers")
// error indicating a torrent's name is invalid
var ErrInvalidTorrentName = errors.New("torrent name is invalid")
var ErrInvalidTorrentName = errors.New("Torrent name is invalid")
// error indicating a torrent's description is invalid
var ErrInvalidTorrentDescription = errors.New("torrent description is invalid")
var ErrInvalidTorrentDescription = errors.New("Torrent description is invalid")
// error indicating a torrent's description is invalid
var ErrInvalidWebsiteLink = errors.New("Website url or IRC link is invalid")
// error indicating a torrent's category is invalid
var ErrInvalidTorrentCategory = errors.New("torrent category is invalid")
var ErrInvalidTorrentCategory = errors.New("Torrent category is invalid")
var p = bluemonday.UGCPolicy()
@ -88,6 +93,7 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
f.Name = r.FormValue(UploadFormName)
f.Category = r.FormValue(UploadFormCategory)
f.Description = r.FormValue(UploadFormDescription)
f.WebsiteLink = r.FormValue(UploadFormWebsiteLink)
f.Status, _ = strconv.Atoi(r.FormValue(UploadFormStatus))
f.Magnet = r.FormValue(UploadFormMagnet)
f.Remake = r.FormValue(UploadFormRemake) == "on"
@ -95,6 +101,7 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
// trim whitespace
f.Name = util.TrimWhitespaces(f.Name)
f.Description = p.Sanitize(util.TrimWhitespaces(f.Description))
f.WebsiteLink = util.TrimWhitespaces(f.WebsiteLink)
f.Magnet = util.TrimWhitespaces(f.Magnet)
cache.Impl.ClearAll()
@ -116,6 +123,12 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
return ErrInvalidTorrentCategory
}
// WebsiteLink
urlRegexp, _ := regexp.Compile(`^(https?:\/\/|irc:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`)
if !urlRegexp.MatchString(f.WebsiteLink) {
return ErrInvalidWebsiteLink
}
// first: parse torrent file (if any) to fill missing information
tfile, _, err := r.FormFile(UploadFormTorrent)
if err == nil {
@ -175,7 +188,7 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
}
xt := magnetUrl.Query().Get("xt")
if !strings.HasPrefix(xt, "urn:btih:") {
return errors.New("incorrect magnet")
return errors.New("Incorrect magnet")
}
xt = strings.SplitAfter(xt, ":")[2]
f.Infohash = strings.ToUpper(strings.Split(xt, "&")[0])
@ -189,7 +202,7 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
return err
}
if !isBase16 {
return errors.New("incorrect hash")
return errors.New("Incorrect hash")
}
} else {
//convert to base16

Voir le fichier

@ -1,7 +1,6 @@
package router
import (
"fmt"
"net/http"
"strconv"
"time"
@ -12,6 +11,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/upload"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
msg "github.com/NyaaPantsu/nyaa/util/messages"
"github.com/gorilla/mux"
)
@ -24,31 +24,28 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
UploadPostHandler(w, r)
} else if r.Method == "GET" {
UploadGetHandler(w, r)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
UploadGetHandler(w, r)
}
func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
var uploadForm UploadForm
defer r.Body.Close()
user := GetUser(r)
messages := msg.GetMessages(r) // new util for errors and infos
if userPermission.NeedsCaptcha(user) {
userCaptcha := captcha.Extract(r)
if !captcha.Authenticate(userCaptcha) {
http.Error(w, captcha.ErrInvalidCaptcha.Error(), http.StatusInternalServerError)
return
messages.AddError("errors", captcha.ErrInvalidCaptcha.Error())
}
}
// validation is done in ExtractInfo()
err := uploadForm.ExtractInfo(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
messages.AddError("errors", err.Error())
}
status := model.TorrentStatusNormal
if uploadForm.Remake { // overrides trusted
@ -59,7 +56,11 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
var sameTorrents int
db.ORM.Model(&model.Torrent{}).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
if sameTorrents == 0 {
if sameTorrents > 0 {
messages.AddError("errors", "Torrent already in database !")
}
if !messages.HasErrors() {
// add to db and redirect
torrent := model.Torrent{
Name: uploadForm.Name,
@ -70,6 +71,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
Date: time.Now(),
Filesize: uploadForm.Filesize,
Description: uploadForm.Description,
WebsiteLink: uploadForm.WebsiteLink,
UploaderID: user.ID}
db.ORM.Create(&torrent)
@ -79,8 +81,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
file := model.File{TorrentID: torrent.ID, Filesize: uploadedFile.Filesize}
err := file.SetPath(uploadedFile.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
messages.AddError("errors", err.Error())
}
db.ORM.Create(&file)
}
@ -91,18 +92,16 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, url.String(), 302)
} else {
err = fmt.Errorf("Torrent already in database!")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
http.Redirect(w, r, url.String()+"?success", 302)
}
}
func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
languages.SetTranslationFromRequest(uploadTemplate, r)
messages := msg.GetMessages(r) // new util for errors and infos
var uploadForm UploadForm
_ = uploadForm.ExtractInfo(r)
user := GetUser(r)
if userPermission.NeedsCaptcha(user) {
uploadForm.CaptchaID = captcha.GetID()
@ -112,6 +111,7 @@ func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
utv := UploadTemplateVariables{
Upload: uploadForm,
FormErrors: messages.GetAllErrors(),
Search: NewSearchForm(),
Navigation: NewNavigation(),
User: GetUser(r),

Voir le fichier

@ -14,12 +14,18 @@ import (
"github.com/NyaaPantsu/nyaa/util"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/log"
msg "github.com/NyaaPantsu/nyaa/util/messages"
"github.com/gorilla/mux"
)
func ViewHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
messages := msg.GetMessages(r)
if (r.URL.Query()["success"] != nil) {
messages.AddInfo("infos", "Torrent uploaded successfully!")
}
torrent, err := torrentService.GetTorrentById(id)
if err != nil {
@ -32,7 +38,7 @@ func ViewHandler(w http.ResponseWriter, r *http.Request) {
if userPermission.NeedsCaptcha(user) {
captchaID = captcha.GetID()
}
htv := ViewTemplateVariables{b, captchaID, NewSearchForm(), NewNavigation(), user, r.URL, mux.CurrentRoute(r)}
htv := ViewTemplateVariables{b, captchaID, messages.GetAllErrors(), messages.GetAllInfos(), NewSearchForm(), NewNavigation(), user, r.URL, mux.CurrentRoute(r)}
languages.SetTranslationFromRequest(viewTemplate, r)
err = viewTemplate.ExecuteTemplate(w, "index.html", htv)

Voir le fichier

@ -4,7 +4,9 @@
{{with .Upload}}
<hr>
<form enctype="multipart/form-data" role="upload" method="POST">
{{ range (index $.FormErrors "errors")}}
<div class="alert alert-danger"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-exclamation-sign"></i> {{ . }}</div>
{{end}}
<div class="form-group">
<label for="name">{{T "name"}}</label>
<input type="text" name="name" id="name" class="form-control" placeholder="{{T "file_name"}}" value="{{.Name}}" autofocus required>
@ -69,7 +71,11 @@
<div class="form-group">
<label for="desc">{{T "torrent_description"}}</label>
<p class="help-block">{{T "description_markdown_notice"}}</p>
<textarea name="desc" id="desc" class="form-contro torrent-desc" rows="15">{{.Description}}</textarea>
<textarea name="desc" id="desc" class="form-control torrent-desc" rows="15">{{.Description}}</textarea>
</div>
<div class="form-group">
<label for="website_link">{{T "website_link"}}</label>
<input name="website_link" id="website_link" class="form-control" type="text" value="{{.WebsiteLink}}">
</div>
{{block "captcha" .}}{{end}}

Voir le fichier

@ -4,6 +4,12 @@
<div class="blockBody">
{{with .Torrent}}
<hr>
{{ range (index $.FormErrors "errors")}}
<div class="alert alert-danger"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-exclamation-sign"></i> {{ . }}</div>
{{end}}
{{ range (index $.Infos "infos")}}
<div class="alert alert-danger"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-exclamation-sign"></i> {{ . }}</div>
{{end}}
<div class="content" style="margin-bottom: 2em;">
<div class="row">
<div class="col-md-12">

Voir le fichier

@ -10,6 +10,7 @@ const MessagesKey = "messages"
type Messages struct {
Errors map[string][]string
Infos map[string][]string
r *http.Request
}
func GetMessages(r *http.Request) Messages {
@ -17,64 +18,65 @@ func GetMessages(r *http.Request) Messages {
return rv.(Messages)
} else {
context.Set(r, MessagesKey, Messages{})
return Messages{make(map[string][]string),make(map[string][]string)}
return Messages{make(map[string][]string),make(map[string][]string), r}
}
}
func (mes Messages) AddError(r *http.Request, name string, msg string) {
func (mes Messages) AddError(name string, msg string) {
mes.Errors[name] = append(mes.Errors[name], msg)
mes.setMessagesInContext(r)
mes.setMessagesInContext()
}
func (mes Messages) AddErrorf( name string, msg string, args ...interface{}) {
mes.AddError(name, fmt.Sprintf(msg, args...))
}
func (mes Messages) ImportFromError(name string, err error) {
mes.AddError(name, err.Error())
}
func (mes Messages) ImportFromError(r *http.Request, name string, err error) {
mes.AddError(r, name, err.Error())
}
func (mes Messages) AddInfo(r *http.Request, name string, msg string) {
func (mes Messages) AddInfo(name string, msg string) {
mes.Infos[name] = append(mes.Infos[name], msg)
mes.setMessagesInContext(r)
mes.setMessagesInContext()
}
func (mes Messages) AddInfof(name string, msg string, args ...interface{}) {
mes.AddInfo(name, fmt.Sprintf(msg, args...))
}
func (mes Messages) AddErrorf(r *http.Request, name string, msg string, args ...interface{}) {
mes.Errors[name] = append(mes.Errors[name], fmt.Sprintf(msg, args...))
mes.setMessagesInContext(r)
}
func (mes Messages) AddInfof(r *http.Request, name string, msg string, args ...interface{}) {
mes.Infos[name] = append(mes.Infos[name], fmt.Sprintf(msg, args...))
mes.setMessagesInContext(r)
}
func (mes Messages) ClearInfos(r *http.Request) {
mes.Errors = nil
mes.setMessagesInContext(r)
}
func (mes Messages) ClearErrors(r *http.Request) {
func (mes Messages) ClearErrors() {
mes.Infos = nil
mes.setMessagesInContext(r)
mes.setMessagesInContext()
}
func (mes Messages) ClearInfos() {
mes.Errors = nil
mes.setMessagesInContext()
}
func (mes Messages) GetInfos(name string) []string {
return mes.Infos[name]
}
func (mes Messages) GetErrors(name string) []string {
return mes.Errors[name]
}
func (mes Messages) GetAllInfos() map[string][]string {
return mes.Infos
}
func (mes Messages) GetAllErrors() map[string][]string {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return mes.Errors
}
func (mes Messages) GetErrors(name string) []string {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return mes.Errors[name]
}
func (mes Messages) setMessagesInContext(r *http.Request) {
context.Set(r, MessagesKey, mes)
func (mes Messages) GetAllInfos() map[string][]string {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return mes.Infos
}
func (mes Messages) GetInfos(name string) []string {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return mes.Infos[name]
}
func (mes Messages) HasErrors() bool {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return len(mes.Errors) > 0
}
func (mes Messages) HasInfos() bool {
mes = GetMessages(mes.r) // We need to look if any new errors from other functions has updated context
return len(mes.Infos) > 0
}
func (mes Messages) setMessagesInContext() {
context.Set(mes.r, MessagesKey, mes)
}