From c8c3dc1980c3730eea6ce12bf1c2bd5e5bb62667 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Tue, 23 May 2017 01:26:09 +0200 Subject: [PATCH] New User Edit Panel User can edit torrents * delete torrents + New translation string for mod panel and user edit torrent panel + Improvement of messages util with implementation of T (no need to get Tfunc now, messages util do that for you) + Use of @ElegantMonkey GetCategories to generate select of categories in search and forms --- router/home_handler.go | 8 ++- router/modpanel.go | 24 ++++---- router/router.go | 3 + router/search_handler.go | 5 +- router/template.go | 6 ++ router/template_functions.go | 3 + router/template_variables.go | 8 +++ router/view_torrent_handler.go | 87 ++++++++++++++++++++++++++- templates/_search.html | 38 +----------- templates/admin/paneltorrentedit.html | 36 +---------- templates/home.html | 4 +- templates/upload.html | 38 +----------- templates/user/torrent_edit.html | 54 +++++++++++++++++ templates/view.html | 3 + translations/en-us.all.json | 56 +++++++++++++++++ util/categories/categories.go | 11 ++++ util/messages/messages.go | 18 +++++- 17 files changed, 279 insertions(+), 123 deletions(-) create mode 100644 templates/user/torrent_edit.html diff --git a/router/home_handler.go b/router/home_handler.go index f3906839..254b1168 100644 --- a/router/home_handler.go +++ b/router/home_handler.go @@ -11,12 +11,15 @@ import ( "github.com/NyaaPantsu/nyaa/service/torrent" "github.com/NyaaPantsu/nyaa/util" "github.com/NyaaPantsu/nyaa/util/log" + msg "github.com/NyaaPantsu/nyaa/util/messages" "github.com/gorilla/mux" ) func HomeHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) page := vars["page"] + messages := msg.GetMessages(r) + deleteVar := r.URL.Query()["deleted"] // db params url var err error @@ -28,7 +31,9 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) { maxPerPage = 50 // default Value maxPerPage } } - + if (deleteVar != nil) { + messages.AddInfoTf("infos", "torrent_deleted", "") + } pagenum := 1 if page != "" { pagenum, err = strconv.Atoi(html.EscapeString(page)) @@ -68,6 +73,7 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) { htv := HomeTemplateVariables{ CommonTemplateVariables: common, ListTorrents: torrentsJson, + Infos: messages.GetAllInfos(), } err = homeTemplate.ExecuteTemplate(w, "index.html", htv) diff --git a/router/modpanel.go b/router/modpanel.go index 8a4b1668..b9050ca5 100644 --- a/router/modpanel.go +++ b/router/modpanel.go @@ -256,7 +256,7 @@ func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) { if torrent.ID > 0 { errUp := uploadForm.ExtractEditInfo(r) if errUp != nil { - messages.AddError("errors", "Failed to update torrent!") + messages.AddErrorT("errors", "fail_torrent_update") } if !messages.HasErrors() { // update some (but not all!) values @@ -268,7 +268,7 @@ func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) { torrent.Description = uploadForm.Description torrent.Uploader = nil // GORM will create a new user otherwise (wtf?!) db.ORM.Save(&torrent) - messages.AddInfo("infos", "Torrent details updated.") + messages.AddInfoT("infos", "torrent_updated") } } htv := PanelTorrentEdVbs{NewPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()} @@ -325,9 +325,9 @@ func TorrentPostReassignModPanel(w http.ResponseWriter, r *http.Request) { } else { count, err2 := rForm.ExecuteAction() if err2 != nil { - messages.AddError("errors", "Something went wrong") + messages.AddErrorT("errors", "something_went_wrong") } else { - messages.AddInfof("infos", "%d torrents updated.", count) + messages.AddInfoTf("infos", "nb_torrents_updated", count) } } @@ -356,13 +356,13 @@ func torrentManyAction(r *http.Request) { messages := msg.GetMessages(r) // new util for errors and infos if action == "" { - messages.AddError("errors", "You have to tell what you want to do with your selection!") + messages.AddErrorT("errors", "no_action_selected") } if action == "move" && r.FormValue("moveto") == "" { // We need to check the form value, not the int one because hidden is 0 - messages.AddError("errors", "Thou has't to telleth whither thee wanteth to moveth thy selection!") + messages.AddErrorT("errors", "no_move_location_selected") } if len(torrentsSelected) == 0 { - messages.AddError("errors", "You need to select at least 1 element!") + messages.AddErrorT("errors", "select_one_element") } if !messages.HasErrors() { for _, torrent_id := range torrentsSelected { @@ -373,22 +373,22 @@ func torrentManyAction(r *http.Request) { if config.TorrentStatus[moveTo] { torrent.Status = moveTo db.ORM.Save(&torrent) - messages.AddInfof("infos", "Torrent %s moved!", torrent.Name) + messages.AddInfoTf("infos", "torrent_moved", torrent.Name) } else { - messages.AddErrorf("errors", "No such status %d exist!", moveTo) + messages.AddErrorTf("errors", "no_status_exist", moveTo) } case "delete": _, err := torrentService.DeleteTorrent(torrent_id) if err != nil { messages.ImportFromError("errors", err) } else { - messages.AddInfof("infos", "Torrent %s deleted!", torrent.Name) + messages.AddInfoTf("infos", "torrent_deleted", torrent.Name) } default: - messages.AddErrorf("errors", "No such action %s exist!", action) + messages.AddErrorTf("errors", "no_action_exist", action) } } else { - messages.AddErrorf("errors", "Torrent with ID %s doesn't exist!", torrent_id) + messages.AddErrorTf("errors", "torrent_not_exist", torrent_id) } } } diff --git a/router/router.go b/router/router.go index 0a2e676c..4dc13843 100755 --- a/router/router.go +++ b/router/router.go @@ -53,6 +53,9 @@ func init() { Router.HandleFunc("/feed/{page}", RSSHandler).Name("feed_page") Router.Handle("/view/{id}", wrapHandler(gzipViewHandler)).Methods("GET").Name("view_torrent") Router.HandleFunc("/view/{id}", PostCommentHandler).Methods("POST").Name("post_comment") + Router.HandleFunc("/torrent/", TorrentEditUserPanel).Methods("GET").Name("user_torrent_edit") + Router.HandleFunc("/torrent/", TorrentPostEditUserPanel).Methods("POST").Name("user_torrent_edit") + Router.HandleFunc("/torrent/delete", TorrentDeleteUserPanel).Methods("GET").Name("user_torrent_delete") Router.HandleFunc("/upload", UploadHandler).Name("upload") Router.HandleFunc("/user/register", UserRegisterFormHandler).Name("user_register").Methods("GET") Router.HandleFunc("/user/login", UserLoginFormHandler).Name("user_login").Methods("GET") diff --git a/router/search_handler.go b/router/search_handler.go index efd665c5..906e852a 100644 --- a/router/search_handler.go +++ b/router/search_handler.go @@ -4,6 +4,7 @@ import ( "github.com/NyaaPantsu/nyaa/model" "github.com/NyaaPantsu/nyaa/util" "github.com/NyaaPantsu/nyaa/util/log" + msg "github.com/NyaaPantsu/nyaa/util/messages" "github.com/NyaaPantsu/nyaa/util/search" "github.com/gorilla/mux" "html" @@ -14,6 +15,7 @@ import ( func SearchHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) page := vars["page"] + messages := msg.GetMessages(r) // db params url var err error @@ -30,6 +32,7 @@ func SearchHandler(w http.ResponseWriter, r *http.Request) { } } + searchParam, torrents, nbTorrents, err := search.SearchByQuery(r, pagenum) if err != nil { util.SendError(w, err, 400) @@ -46,7 +49,7 @@ func SearchHandler(w http.ResponseWriter, r *http.Request) { Category: searchParam.Category.String(), ShowItemsPerPage: true, } - htv := HomeTemplateVariables{common, b} + htv := HomeTemplateVariables{common, b, messages.GetAllInfos()} err = searchTemplate.ExecuteTemplate(w, "index.html", htv) if err != nil { diff --git a/router/template.go b/router/template.go index f64c10b1..b72703c5 100644 --- a/router/template.go +++ b/router/template.go @@ -23,6 +23,7 @@ var homeTemplate, viewProfileNotifTemplate, viewProfileEditTemplate, viewUserDeleteTemplate, + userTorrentEd, notFoundTemplate, changeLanguageTemplate, databaseDumpTemplate *template.Template @@ -115,6 +116,11 @@ func ReloadTemplates() { name: "user_delete", file: filepath.Join("user", "delete_success.html"), }, + templateLoader{ + templ: &userTorrentEd, + name: "user_torrent_edit", + file: filepath.Join("user", "torrent_edit.html"), + }, templateLoader{ templ: ¬FoundTemplate, name: "404", diff --git a/router/template_functions.go b/router/template_functions.go index c6ddcfcc..b5a2e3f6 100644 --- a/router/template_functions.go +++ b/router/template_functions.go @@ -162,6 +162,9 @@ var FuncMap = template.FuncMap{ // because time.* isn't available in templates... return t.Format(time.RFC3339) }, + "GetCategories": func(keepParent bool) map[string]string { + return categories.GetCategoriesSelect(keepParent) + }, "CategoryName": func(category string, sub_category string) string { s := category + "_" + sub_category diff --git a/router/template_variables.go b/router/template_variables.go index f1892c9b..55244833 100644 --- a/router/template_variables.go +++ b/router/template_variables.go @@ -71,9 +71,17 @@ type UserProfileNotifVariables struct { Infos map[string][]string } +type UserTorrentEdVbs struct { + CommonTemplateVariables + Upload UploadForm + FormErrors map[string][]string + FormInfos map[string][]string +} + type HomeTemplateVariables struct { CommonTemplateVariables ListTorrents []model.TorrentJSON + Infos map[string][]string } type DatabaseDumpTemplateVariables struct { diff --git a/router/view_torrent_handler.go b/router/view_torrent_handler.go index ec384272..803e6b4b 100644 --- a/router/view_torrent_handler.go +++ b/router/view_torrent_handler.go @@ -9,8 +9,10 @@ import ( "github.com/NyaaPantsu/nyaa/db" "github.com/NyaaPantsu/nyaa/model" + "github.com/NyaaPantsu/nyaa/service" "github.com/NyaaPantsu/nyaa/service/captcha" "github.com/NyaaPantsu/nyaa/service/notifier" + "github.com/NyaaPantsu/nyaa/service/report" "github.com/NyaaPantsu/nyaa/service/torrent" "github.com/NyaaPantsu/nyaa/service/user/permission" "github.com/NyaaPantsu/nyaa/util/languages" @@ -68,13 +70,13 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) { if userPermission.NeedsCaptcha(currentUser) { userCaptcha := captcha.Extract(r) if !captcha.Authenticate(userCaptcha) { - messages.AddError("errors", "Bad captcha!") + messages.AddErrorT("errors", "bad_captcha") } } content := p.Sanitize(r.FormValue("comment")) if strings.TrimSpace(content) == "" { - messages.AddError("errors", "Comment empty!") + messages.AddErrorT("errors", "comment_empty") } if !messages.HasErrors() { userID := currentUser.ID @@ -104,7 +106,7 @@ func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) { if userPermission.NeedsCaptcha(currentUser) { userCaptcha := captcha.Extract(r) if !captcha.Authenticate(userCaptcha) { - messages.AddError("errors", "Bad captcha!") + messages.AddErrorT("errors", "bad_captcha") } } if !messages.HasErrors() { @@ -125,3 +127,82 @@ func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) { } ViewHandler(w,r) } + +func TorrentEditUserPanel(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + torrent, _ := torrentService.GetTorrentById(id) + messages:= msg.GetMessages(r) + currentUser := GetUser(r) + if userPermission.CurrentOrAdmin(currentUser, torrent.UploaderID) { + torrentJson := torrent.ToJSON() + uploadForm := NewUploadForm() + uploadForm.Name = torrentJson.Name + uploadForm.Category = torrentJson.Category + "_" + torrentJson.SubCategory + uploadForm.Status = torrentJson.Status + uploadForm.WebsiteLink = string(torrentJson.WebsiteLink) + uploadForm.Description = string(torrentJson.Description) + htv := UserTorrentEdVbs{NewCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()} + err := userTorrentEd.ExecuteTemplate(w, "index.html", htv) + log.CheckError(err) + } else { + NotFoundHandler(w, r) + } +} + +func TorrentPostEditUserPanel(w http.ResponseWriter, r *http.Request) { + var uploadForm UploadForm + id := r.URL.Query().Get("id") + messages := msg.GetMessages(r) + torrent, _ := torrentService.GetTorrentById(id) + currentUser := GetUser(r) + if torrent.ID > 0 && userPermission.CurrentOrAdmin(currentUser, torrent.UploaderID) { + errUp := uploadForm.ExtractEditInfo(r) + if errUp != nil { + messages.AddErrorT("errors", "fail_torrent_update") + } + if !messages.HasErrors() { + status := model.TorrentStatusNormal + if uploadForm.Remake { // overrides trusted + status = model.TorrentStatusRemake + } else if currentUser.IsTrusted() { + status = model.TorrentStatusTrusted + } + // update some (but not all!) values + torrent.Name = uploadForm.Name + torrent.Category = uploadForm.CategoryID + torrent.SubCategory = uploadForm.SubCategoryID + torrent.Status = status + torrent.WebsiteLink = uploadForm.WebsiteLink + torrent.Description = uploadForm.Description + torrent.Uploader = nil // GORM will create a new user otherwise (wtf?!) + db.ORM.Save(&torrent) + messages.AddInfoT("infos", "torrent_updated") + } + htv := UserTorrentEdVbs{NewCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()} + err_ := userTorrentEd.ExecuteTemplate(w, "index.html", htv) + log.CheckError(err_) + } else { + NotFoundHandler(w, r) + } +} + +func TorrentDeleteUserPanel(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + currentUser := GetUser(r) + torrent, _ := torrentService.GetTorrentById(id) + if userPermission.CurrentOrAdmin(currentUser, torrent.UploaderID) { + _, err := torrentService.DeleteTorrent(id) + if (err == nil) { + //delete reports of torrent + whereParams := serviceBase.CreateWhereParams("torrent_id = ?", id) + reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0) + for _, report := range reports { + reportService.DeleteTorrentReport(report.ID) + } + } + url, _ := Router.Get("home").URL() + http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther) + } else { + NotFoundHandler(w, r) + } +} diff --git a/templates/_search.html b/templates/_search.html index 63ee5898..6f0852c7 100644 --- a/templates/_search.html +++ b/templates/_search.html @@ -1,41 +1,9 @@ {{define "search_common"}} - {{ if Sukebei }} - - - - - - - - - - {{ else }} - - - - - - - - - - - - - - - - - - - - - - - + {{ range $name_cat, $id_cat := (GetCategories false) }} + {{ end }} diff --git a/templates/home.html b/templates/home.html index d02a07cc..c80e729f 100644 --- a/templates/home.html +++ b/templates/home.html @@ -12,7 +12,9 @@ Your browser does not support the audio element. - + {{ range (index $.Infos "infos")}} +
× {{ . }}
+ {{end}}
- - {{ if Sukebei }} - - - - - - - - - - {{ else }} - - - - - - - - - - - - - - - - - - - - - - - + {{ range $name_cat, $id_cat := (GetCategories false) }} + {{ end }}

{{ call $.T "please_include_our_tracker" }}

diff --git a/templates/user/torrent_edit.html b/templates/user/torrent_edit.html new file mode 100644 index 00000000..eb50e11b --- /dev/null +++ b/templates/user/torrent_edit.html @@ -0,0 +1,54 @@ +{{define "title"}}Torrent Edit{{end}} +{{define "content"}} +
+ {{with .Upload}} +
+ {{ range (index $.FormInfos "infos")}} +
× {{ . }}
+ {{end}} + {{ range (index $.FormErrors "errors")}} +
× {{ . }}
+ {{end}} +
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+
+ +

{{call $.T "description_markdown_notice"}}

+ +
+ +
+
+
+{{end}} +
+{{end}} +{{define "js_footer"}} + + + + + +{{end}} \ No newline at end of file diff --git a/templates/view.html b/templates/view.html index 172dd8f5..73b8e229 100644 --- a/templates/view.html +++ b/templates/view.html @@ -53,6 +53,9 @@ {{ if HasAdmin $.User}} + {{ else if CurrentUserIdentical $.User .UploaderID }} + + {{end}}
diff --git a/translations/en-us.all.json b/translations/en-us.all.json index efbb4ff4..c164398b 100644 --- a/translations/en-us.all.json +++ b/translations/en-us.all.json @@ -838,5 +838,61 @@ { "id": "new_comment_on_torrent", "translation": "New comment on torrent: \"%s\"" + }, + { + "id": "no_action_selected", + "translation": "You have to tell what you want to do with your selection!" + }, + { + "id": "no_move_location_selected", + "translation": "Thou has't to telleth whither thee wanteth to moveth thy selection!" + }, + { + "id": "select_one_element", + "translation": "You need to select at least 1 element!" + }, + { + "id": "torrent_moved", + "translation": "Torrent %s moved!" + }, + { + "id": "no_status_exist", + "translation": "No such status %d exist!" + }, + { + "id": "torrent_deleted", + "translation": "Torrent %s deleted!" + }, + { + "id": "no_action_exist", + "translation": "No such action %s exist!" + }, + { + "id": "torrent_not_exist", + "translation": "Torrent with ID %s doesn't exist!" + }, + { + "id": "something_went_wrong", + "translation": "Something went wrong" + }, + { + "id": "nb_torrents_updated", + "translation": "%d torrents updated." + }, + { + "id": "torrent_updated", + "translation": "Torrent details updated." + }, + { + "id": "fail_torrent_update", + "translation": "Failed to update torrent!" + }, + { + "id": "bad_captcha", + "translation": "Bad captcha!" + }, + { + "id": "comment_empty", + "translation": "Comment empty!" } ] diff --git a/util/categories/categories.go b/util/categories/categories.go index 916dafb3..37d5ba0d 100644 --- a/util/categories/categories.go +++ b/util/categories/categories.go @@ -58,3 +58,14 @@ func CategoryExists(category string) bool { _, exists := GetCategories()[category] return exists } + +func GetCategoriesSelect(keepParent bool) map[string]string { + categories := GetCategories() + catSelect := make(map[string]string, len(categories)) + for k, v := range categories { + if len(k) > 2 || keepParent { + catSelect[v] = k + } + } + return catSelect +} \ No newline at end of file diff --git a/util/messages/messages.go b/util/messages/messages.go index 17f4d836..8344048f 100644 --- a/util/messages/messages.go +++ b/util/messages/messages.go @@ -3,6 +3,8 @@ import ( "github.com/gorilla/context" "fmt" "net/http" + "github.com/nicksnyder/go-i18n/i18n" + "github.com/NyaaPantsu/nyaa/util/languages" ) const MessagesKey = "messages" @@ -11,6 +13,7 @@ type Messages struct { Errors map[string][]string Infos map[string][]string r *http.Request + T i18n.TranslateFunc } func GetMessages(r *http.Request) *Messages { @@ -18,7 +21,8 @@ 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), r} + T, _ := languages.GetTfuncAndLanguageFromRequest(r) + return &Messages{make(map[string][]string),make(map[string][]string), r, T} } } @@ -32,6 +36,12 @@ func (mes *Messages) AddError(name string, msg string) { func (mes *Messages) AddErrorf( name string, msg string, args ...interface{}) { mes.AddError(name, fmt.Sprintf(msg, args...)) } +func (mes *Messages) AddErrorTf( name string, id string, args ...interface{}) { + mes.AddErrorf(name, mes.T(id), args...) +} +func (mes *Messages) AddErrorT( name string, id string) { + mes.AddError(name, mes.T(id)) +} func (mes *Messages) ImportFromError(name string, err error) { mes.AddError(name, err.Error()) } @@ -46,6 +56,12 @@ func (mes *Messages) AddInfo(name string, msg string) { func (mes *Messages) AddInfof(name string, msg string, args ...interface{}) { mes.AddInfo(name, fmt.Sprintf(msg, args...)) } +func (mes *Messages) AddInfoTf(name string, id string, args ...interface{}) { + mes.AddInfof(name, mes.T(id), args...) +} +func (mes *Messages) AddInfoT(name string, id string) { + mes.AddInfo(name, mes.T(id)) +} func (mes *Messages) ClearErrors() { mes.Infos = nil