From cf478a4235594f7a363527206583dae4516cad93 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sat, 20 May 2017 17:01:13 +0200 Subject: [PATCH 1/4] Add Torrent WebLink + fixes Simplifying messages util (no need to add everytime r) --- router/modpanel.go | 18 ++++---- router/template_variables.go | 3 ++ router/upload.go | 29 +++++++++---- router/upload_handler.go | 34 +++++++-------- router/view_torrent_handler.go | 8 +++- templates/upload.html | 10 ++++- templates/view.html | 6 +++ util/messages/messages.go | 76 +++++++++++++++++----------------- 8 files changed, 109 insertions(+), 75 deletions(-) diff --git a/router/modpanel.go b/router/modpanel.go index 293c7de4..dd90558a 100644 --- a/router/modpanel.go +++ b/router/modpanel.go @@ -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) } } } diff --git a/router/template_variables.go b/router/template_variables.go index 8f1f6bb5..7217af7c 100644 --- a/router/template_variables.go +++ b/router/template_variables.go @@ -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 diff --git a/router/upload.go b/router/upload.go index 5deb2b31..7f0ea789 100644 --- a/router/upload.go +++ b/router/upload.go @@ -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 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?:\/\/)?([\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 diff --git a/router/upload_handler.go b/router/upload_handler.go index 57d98b54..ce52edd8 100644 --- a/router/upload_handler.go +++ b/router/upload_handler.go @@ -1,7 +1,6 @@ package router import ( - "fmt" "net/http" "strconv" "time" @@ -13,6 +12,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" ) @@ -25,31 +25,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 @@ -60,7 +57,11 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) { var sameTorrents int db.ORM.Model(&model.Torrent{}).Table(config.TorrentsTableName).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, @@ -80,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) } @@ -92,16 +92,13 @@ 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 user := GetUser(r) @@ -113,6 +110,7 @@ func UploadGetHandler(w http.ResponseWriter, r *http.Request) { utv := UploadTemplateVariables{ Upload: uploadForm, + FormErrors: messages.GetAllErrors(), Search: NewSearchForm(), Navigation: NewNavigation(), User: GetUser(r), diff --git a/router/view_torrent_handler.go b/router/view_torrent_handler.go index 13026f77..97c726f3 100644 --- a/router/view_torrent_handler.go +++ b/router/view_torrent_handler.go @@ -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) diff --git a/templates/upload.html b/templates/upload.html index d5d35163..c58e607e 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -4,7 +4,9 @@ {{with .Upload}}
- + {{ range (index $.FormErrors "errors")}} +
× {{ . }}
+ {{end}}
@@ -69,7 +71,11 @@

{{T "description_markdown_notice"}}

- + +
+
+ +
{{block "captcha" .}}{{end}} diff --git a/templates/view.html b/templates/view.html index bbdbbc88..b8d158b6 100644 --- a/templates/view.html +++ b/templates/view.html @@ -4,6 +4,12 @@
{{with .Torrent}}
+ {{ range (index $.FormErrors "errors")}} +
× {{ . }}
+ {{end}} + {{ range (index $.Infos "infos")}} +
× {{ . }}
+ {{end}}
diff --git a/util/messages/messages.go b/util/messages/messages.go index a47884b5..4ad0bc58 100644 --- a/util/messages/messages.go +++ b/util/messages/messages.go @@ -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) } \ No newline at end of file From 27db98dfc2fdeaa089c340c757edc893c41605af Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sat, 20 May 2017 17:02:34 +0200 Subject: [PATCH 2/4] Forgot to add in model insert --- router/upload_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/router/upload_handler.go b/router/upload_handler.go index ce52edd8..3c8cff7d 100644 --- a/router/upload_handler.go +++ b/router/upload_handler.go @@ -72,6 +72,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.Table(config.TorrentsTableName).Create(&torrent) From 3ac73daa779a2515fd1be9e034bb7da188118534 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sat, 20 May 2017 17:10:28 +0200 Subject: [PATCH 3/4] add irc support --- router/upload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router/upload.go b/router/upload.go index 7f0ea789..f7d3bd28 100644 --- a/router/upload.go +++ b/router/upload.go @@ -124,7 +124,7 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error { } // WebsiteLink - urlRegexp, _ := regexp.Compile(`^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`) + urlRegexp, _ := regexp.Compile(`^(https?:\/\/|irc:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`) if !urlRegexp.MatchString(f.WebsiteLink) { return ErrInvalidWebsiteLink } From f09b8bcae753b769fedcf03eb4507f16760ad86c Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sat, 20 May 2017 17:13:43 +0200 Subject: [PATCH 4/4] Modified info string --- router/upload.go | 2 +- router/upload_handler.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/router/upload.go b/router/upload.go index f7d3bd28..b8027cee 100644 --- a/router/upload.go +++ b/router/upload.go @@ -78,7 +78,7 @@ var ErrInvalidTorrentName = errors.New("Torrent name is invalid") var ErrInvalidTorrentDescription = errors.New("Torrent description is invalid") // error indicating a torrent's description is invalid -var ErrInvalidWebsiteLink = errors.New("Website url 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") diff --git a/router/upload_handler.go b/router/upload_handler.go index 559e013b..5677ab9c 100644 --- a/router/upload_handler.go +++ b/router/upload_handler.go @@ -101,6 +101,7 @@ func UploadGetHandler(w http.ResponseWriter, r *http.Request) { 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()