Merge pull request #673 from NyaaPantsu/user-setttings-notification
User settings notification
Cette révision appartient à :
révision
6500aece22
22
config/user_settings.go
Fichier normal
22
config/user_settings.go
Fichier normal
|
@ -0,0 +1,22 @@
|
|||
package config
|
||||
|
||||
|
||||
/*
|
||||
* Here we config the notifications options
|
||||
* Uses in user model for default setting
|
||||
* Be aware, default values in user update form are
|
||||
* in service/user/form/form_validator.go
|
||||
*/
|
||||
|
||||
var DefaultUserSettings = map[string]bool {
|
||||
"new_torrent": true,
|
||||
"new_torrent_email": false,
|
||||
"new_comment": true,
|
||||
"new_comment_email": false,
|
||||
"new_responses": false,
|
||||
"new_responses_email": false,
|
||||
"new_follower": false,
|
||||
"new_follower_email": false,
|
||||
"followed": false,
|
||||
"followed_email": false,
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"time"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
)
|
||||
|
||||
type Comment struct {
|
||||
|
@ -27,6 +28,10 @@ func (c Comment) TableName() string {
|
|||
return config.CommentsTableName
|
||||
}
|
||||
|
||||
func (c *Comment) Identifier() string { // We Can personalize the identifier but we would have to handle toggle read in that case
|
||||
return c.Torrent.Identifier()
|
||||
}
|
||||
|
||||
type OldComment struct {
|
||||
TorrentID uint `gorm:"column:torrent_id"`
|
||||
Username string `gorm:"column:username"`
|
||||
|
|
|
@ -86,7 +86,7 @@ func (t Torrent) TableName() string {
|
|||
return config.TorrentsTableName
|
||||
}
|
||||
|
||||
func (t Torrent) Identifier() string {
|
||||
func (t *Torrent) Identifier() string {
|
||||
return "torrent_"+strconv.Itoa(int(t.ID))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
)
|
||||
|
@ -24,6 +26,7 @@ type User struct {
|
|||
ApiToken string `gorm:"column:api_token"`
|
||||
ApiTokenExpiry time.Time `gorm:"column:api_token_expiry"`
|
||||
Language string `gorm:"column:language"`
|
||||
UserSettings string `gorm:"column:settings"`
|
||||
|
||||
// TODO: move this to PublicUser
|
||||
Likings []User // Don't work `gorm:"foreignkey:user_id;associationforeignkey:follower_id;many2many:user_follows"`
|
||||
|
@ -31,9 +34,10 @@ type User struct {
|
|||
|
||||
MD5 string `json:"md5" gorm:"column:md5"` // Hash of email address, used for Gravatar
|
||||
Torrents []Torrent `gorm:"ForeignKey:UploaderID"`
|
||||
Notifications []Notification `gorm:"ForeignKey:UserID"`
|
||||
|
||||
UnreadNotifications int `gorm:"-"` // We don't want to loop every notifications when accessing user unread notif
|
||||
Notifications []Notification `gorm:"ForeignKey:UserID"`
|
||||
Settings UserSettings `gorm:"-"` // We don't want to load settings everytime, stock it as a string, parse it when needed
|
||||
}
|
||||
|
||||
type UserJSON struct {
|
||||
|
@ -99,6 +103,10 @@ type UserUploadsOld struct {
|
|||
TorrentId uint `gorm:"column:torrent_id"`
|
||||
}
|
||||
|
||||
type UserSettings struct {
|
||||
Settings map[string]bool`json:"settings"`
|
||||
}
|
||||
|
||||
func (c UserUploadsOld) TableName() string {
|
||||
// is this needed here?
|
||||
return config.UploadsOldTableName
|
||||
|
@ -115,3 +123,51 @@ func (u *User) ToJSON() UserJSON {
|
|||
}
|
||||
return json
|
||||
}
|
||||
|
||||
/* User Settings */
|
||||
|
||||
func(s *UserSettings) Get(key string) bool {
|
||||
if val, ok:= s.Settings[key]; ok {
|
||||
return val
|
||||
} else {
|
||||
return config.DefaultUserSettings[key]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *UserSettings) GetSettings() map[string]bool {
|
||||
return s.Settings
|
||||
}
|
||||
|
||||
func (s *UserSettings) Set(key string, val bool) {
|
||||
if s.Settings == nil {
|
||||
s.Settings = make(map[string]bool)
|
||||
}
|
||||
s.Settings[key] = val
|
||||
}
|
||||
|
||||
func (s *UserSettings) ToDefault() {
|
||||
s.Settings = config.DefaultUserSettings
|
||||
}
|
||||
|
||||
func (s *UserSettings) Initialize() {
|
||||
s.Settings = make(map[string]bool)
|
||||
}
|
||||
|
||||
func (u *User) SaveSettings() {
|
||||
byteArray, err := json.Marshal(u.Settings)
|
||||
|
||||
if (err != nil) {
|
||||
fmt.Print(err)
|
||||
}
|
||||
u.UserSettings = string(byteArray)
|
||||
}
|
||||
|
||||
func (u *User) ParseSettings() {
|
||||
if len(u.Settings.GetSettings()) == 0 && u.UserSettings != "" {
|
||||
u.Settings.Initialize()
|
||||
json.Unmarshal([]byte(u.UserSettings), &u.Settings)
|
||||
} else if len(u.Settings.GetSettings()) == 0 && u.UserSettings != "" {
|
||||
u.Settings.Initialize()
|
||||
u.Settings.ToDefault()
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/torrent"
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
form "github.com/NyaaPantsu/nyaa/service/user/form"
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"github.com/NyaaPantsu/nyaa/util/search"
|
||||
|
@ -235,6 +234,7 @@ func CommentsListPanel(w http.ResponseWriter, r *http.Request) {
|
|||
func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get("id")
|
||||
torrent, _ := torrentService.GetTorrentById(id)
|
||||
messages:= msg.GetMessages(r)
|
||||
|
||||
torrentJson := torrent.ToJSON()
|
||||
uploadForm := NewUploadForm()
|
||||
|
@ -243,7 +243,7 @@ func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
uploadForm.Status = torrentJson.Status
|
||||
uploadForm.WebsiteLink = string(torrentJson.WebsiteLink)
|
||||
uploadForm.Description = string(torrentJson.Description)
|
||||
htv := PanelTorrentEdVbs{NewPanelCommonVariables(r), uploadForm, form.NewErrors(), form.NewInfos()}
|
||||
htv := PanelTorrentEdVbs{NewPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
err := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err)
|
||||
}
|
||||
|
@ -251,15 +251,14 @@ func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
var uploadForm UploadForm
|
||||
id := r.URL.Query().Get("id")
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
messages := msg.GetMessages(r)
|
||||
torrent, _ := torrentService.GetTorrentById(id)
|
||||
if torrent.ID > 0 {
|
||||
errUp := uploadForm.ExtractEditInfo(r)
|
||||
if errUp != nil {
|
||||
err["errors"] = append(err["errors"], "Failed to update torrent!")
|
||||
messages.AddError("errors", "Failed to update torrent!")
|
||||
}
|
||||
if len(err) == 0 {
|
||||
if !messages.HasErrors() {
|
||||
// update some (but not all!) values
|
||||
torrent.Name = uploadForm.Name
|
||||
torrent.Category = uploadForm.CategoryID
|
||||
|
@ -269,10 +268,10 @@ 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)
|
||||
infos["infos"] = append(infos["infos"], "Torrent details updated.")
|
||||
messages.AddInfo("infos", "Torrent details updated.")
|
||||
}
|
||||
}
|
||||
htv := PanelTorrentEdVbs{NewPanelCommonVariables(r), uploadForm, err, infos}
|
||||
htv := PanelTorrentEdVbs{NewPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
err_ := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err_)
|
||||
}
|
||||
|
@ -280,7 +279,6 @@ func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
func CommentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get("id")
|
||||
|
||||
_ = form.NewErrors()
|
||||
_, _ = userService.DeleteComment(id)
|
||||
url, _ := Router.Get("mod_clist").URL()
|
||||
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
|
||||
|
@ -288,7 +286,6 @@ func CommentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func TorrentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get("id")
|
||||
_ = form.NewErrors()
|
||||
_, _ = torrentService.DeleteTorrent(id)
|
||||
|
||||
//delete reports of torrent
|
||||
|
@ -305,7 +302,6 @@ func TorrentReportDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
id := r.URL.Query().Get("id")
|
||||
fmt.Println(id)
|
||||
idNum, _ := strconv.ParseUint(id, 10, 64)
|
||||
_ = form.NewErrors()
|
||||
_, _ = reportService.DeleteTorrentReport(uint(idNum))
|
||||
|
||||
url, _ := Router.Get("mod_trlist").URL()
|
||||
|
@ -313,29 +309,29 @@ func TorrentReportDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func TorrentReassignModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
htv := PanelTorrentReassignVbs{NewPanelCommonVariables(r), ReassignForm{}, form.NewErrors(), form.NewInfos()}
|
||||
messages := msg.GetMessages(r)
|
||||
htv := PanelTorrentReassignVbs{NewPanelCommonVariables(r), ReassignForm{}, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
err := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err)
|
||||
}
|
||||
|
||||
func TorrentPostReassignModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
var rForm ReassignForm
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
err2 := rForm.ExtractInfo(r)
|
||||
if err2 != nil {
|
||||
err["errors"] = append(err["errors"], err2.Error())
|
||||
messages.ImportFromError("errors", err2)
|
||||
} else {
|
||||
count, err2 := rForm.ExecuteAction()
|
||||
if err2 != nil {
|
||||
err["errors"] = append(err["errors"], "Something went wrong")
|
||||
messages.AddError("errors", "Something went wrong")
|
||||
} else {
|
||||
infos["infos"] = append(infos["infos"], fmt.Sprintf("%d torrents updated.", count))
|
||||
messages.AddInfof("infos", "%d torrents updated.", count)
|
||||
}
|
||||
}
|
||||
|
||||
htv := PanelTorrentReassignVbs{NewPanelCommonVariables(r), rForm, err, infos}
|
||||
htv := PanelTorrentReassignVbs{NewPanelCommonVariables(r), rForm, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
err_ := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err_)
|
||||
}
|
||||
|
|
|
@ -216,4 +216,7 @@ var FuncMap = template.FuncMap{
|
|||
"makeCaptchaData": func(captchaID string, T languages.TemplateTfunc) captchaData {
|
||||
return captchaData{captchaID, T}
|
||||
},
|
||||
"DefaultUserSettings": func(s string) bool{
|
||||
return config.DefaultUserSettings[s]
|
||||
},
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/service/captcha"
|
||||
|
@ -79,14 +80,16 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
|
||||
|
||||
if (user.ID > 0) { // If we are a member
|
||||
if (user.ID > 0 && config.DefaultUserSettings["new_torrent"]) { // If we are a member and notifications for new torrents are enabled
|
||||
userService.GetLikings(user) // We populate the liked field for users
|
||||
if len(user.Likings) > 0 { // If we are followed by at least someone
|
||||
for _, follower := range user.Likings {
|
||||
T, _, _ := languages.TfuncAndLanguageWithFallback(user.Language, user.Language) // We need to send the notification to every user in their language
|
||||
|
||||
notifierService.NotifyUser(&follower, torrent.Identifier(), fmt.Sprintf(T("new_torrent_uploaded"), torrent.Name, user.Username), url.String())
|
||||
follower.ParseSettings() // We need to call it before checking settings
|
||||
if follower.Settings.Get("new_torrent") {
|
||||
T, _, _ := languages.TfuncAndLanguageWithFallback(follower.Language, follower.Language) // We need to send the notification to every user in their language
|
||||
|
||||
notifierService.NotifyUser(&follower, torrent.Identifier(), fmt.Sprintf(T("new_torrent_uploaded"), torrent.Name, user.Username), url.String(), follower.Settings.Get("new_torrent_email"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
|
@ -25,13 +24,14 @@ func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
HomeHandler(w, r)
|
||||
return
|
||||
}
|
||||
messages := msg.GetMessages(r)
|
||||
registrationForm := form.RegistrationForm{}
|
||||
modelHelper.BindValueForm(®istrationForm, r)
|
||||
registrationForm.CaptchaID = captcha.GetID()
|
||||
urtv := UserRegisterTemplateVariables{
|
||||
CommonTemplateVariables: NewCommonVariables(r),
|
||||
RegistrationForm: registrationForm,
|
||||
FormErrors: form.NewErrors(),
|
||||
FormErrors: messages.GetAllErrors(),
|
||||
}
|
||||
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", urtv)
|
||||
if err != nil {
|
||||
|
@ -41,13 +41,20 @@ func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Getting View User Login
|
||||
func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||
_, errorUser := userService.CurrentUser(r)
|
||||
// User is already connected, redirect to home
|
||||
if errorUser == nil {
|
||||
HomeHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
loginForm := form.LoginForm{}
|
||||
modelHelper.BindValueForm(&loginForm, r)
|
||||
|
||||
messages := msg.GetMessages(r)
|
||||
ulfv := UserLoginFormVariables{
|
||||
CommonTemplateVariables: NewCommonVariables(r),
|
||||
LoginForm: loginForm,
|
||||
FormErrors: form.NewErrors(),
|
||||
FormErrors: messages.GetAllErrors(),
|
||||
}
|
||||
|
||||
err := viewLoginTemplate.ExecuteTemplate(w, "index.html", ulfv)
|
||||
|
@ -61,33 +68,34 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
T := languages.GetTfuncFromRequest(r)
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if errorUser == nil {
|
||||
currentUser := GetUser(r)
|
||||
follow := r.URL.Query()["followed"]
|
||||
unfollow := r.URL.Query()["unfollowed"]
|
||||
infosForm := form.NewInfos()
|
||||
deleteVar := r.URL.Query()["delete"]
|
||||
|
||||
if (deleteVar != nil) && (userPermission.CurrentOrAdmin(currentUser, userProfile.ID)) {
|
||||
err := form.NewErrors()
|
||||
_, errUser := userService.DeleteUser(w, currentUser, id)
|
||||
if errUser != nil {
|
||||
err["errors"] = append(err["errors"], errUser.Error())
|
||||
messages.ImportFromError("errors", errUser)
|
||||
}
|
||||
htv := UserVerifyTemplateVariables{NewCommonVariables(r), err}
|
||||
htv := UserVerifyTemplateVariables{NewCommonVariables(r), messages.GetAllErrors()}
|
||||
errorTmpl := viewUserDeleteTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else {
|
||||
if follow != nil {
|
||||
infosForm["infos"] = append(infosForm["infos"], fmt.Sprintf(string(T("user_followed_msg")), userProfile.Username))
|
||||
messages.AddInfof("infos", string(T("user_followed_msg")), userProfile.Username)
|
||||
}
|
||||
if unfollow != nil {
|
||||
infosForm["infos"] = append(infosForm["infos"], fmt.Sprintf(string(T("user_unfollowed_msg")), userProfile.Username))
|
||||
messages.AddInfof("infos", string(T("user_unfollowed_msg")), userProfile.Username)
|
||||
}
|
||||
htv := UserProfileVariables{NewCommonVariables(r), &userProfile, infosForm}
|
||||
userProfile.ParseSettings()
|
||||
htv := UserProfileVariables{NewCommonVariables(r), &userProfile, messages.GetAllInfos()}
|
||||
|
||||
err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
|
@ -95,10 +103,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewCommonVariables(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
NotFoundHandler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,23 +112,23 @@ func UserDetailsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
currentUser := GetUser(r)
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if errorUser == nil && userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
|
||||
if userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
|
||||
b := form.UserForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
htv := UserProfileEditVariables{NewCommonVariables(r), &userProfile, b, form.NewErrors(), form.NewInfos(), availableLanguages}
|
||||
userProfile.ParseSettings()
|
||||
htv := UserProfileEditVariables{NewCommonVariables(r), &userProfile, b, messages.GetAllErrors(), messages.GetAllInfos(), availableLanguages}
|
||||
err := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewCommonVariables(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
NotFoundHandler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,40 +142,43 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
NotFoundHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
userProfile.ParseSettings()
|
||||
messages := msg.GetMessages(r)
|
||||
userForm := form.UserForm{}
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
userSettingsForm := form.UserSettingsForm{}
|
||||
|
||||
|
||||
T := languages.GetTfuncFromRequest(r)
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
form.EmailValidation(r.PostFormValue("email"), &messages)
|
||||
}
|
||||
if len(r.PostFormValue("username")) > 0 {
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
form.ValidateUsername(r.PostFormValue("username"), &messages)
|
||||
}
|
||||
|
||||
if len(err) == 0 {
|
||||
if !messages.HasErrors() {
|
||||
modelHelper.BindValueForm(&userForm, r)
|
||||
modelHelper.BindValueForm(&userSettingsForm, r)
|
||||
if !userPermission.HasAdmin(currentUser) {
|
||||
userForm.Username = userProfile.Username
|
||||
userForm.Status = userProfile.Status
|
||||
} else {
|
||||
if userProfile.Status != userForm.Status && userForm.Status == 2 {
|
||||
err["errors"] = append(err["errors"], "Elevating status to moderator is prohibited")
|
||||
messages.AddError("errors", "Elevating status to moderator is prohibited")
|
||||
}
|
||||
}
|
||||
err = modelHelper.ValidateForm(&userForm, err)
|
||||
if len(err) == 0 {
|
||||
modelHelper.ValidateForm(&userForm, &messages)
|
||||
if !messages.HasErrors() {
|
||||
if userForm.Email != userProfile.Email {
|
||||
userService.SendVerificationToUser(*currentUser, userForm.Email)
|
||||
infos["infos"] = append(infos["infos"], fmt.Sprintf(string(T("email_changed")), userForm.Email))
|
||||
messages.AddInfof("infos", string(T("email_changed")), userForm.Email)
|
||||
userForm.Email = userProfile.Email // reset, it will be set when user clicks verification
|
||||
}
|
||||
userProfile, _, errorUser = userService.UpdateUser(w, &userForm, currentUser, id)
|
||||
userProfile, _, errorUser = userService.UpdateUser(w, &userForm, &userSettingsForm, currentUser, id)
|
||||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
messages.ImportFromError("errors", errorUser)
|
||||
} else {
|
||||
infos["infos"] = append(infos["infos"], string(T("profile_updated")))
|
||||
messages.AddInfo("infos", string(T("profile_updated")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,8 +187,8 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
CommonTemplateVariables: NewCommonVariables(r),
|
||||
UserProfile: &userProfile,
|
||||
UserForm: userForm,
|
||||
FormErrors: err,
|
||||
FormInfos: infos,
|
||||
FormErrors: messages.GetAllErrors(),
|
||||
FormInfos: messages.GetAllInfos(),
|
||||
Languages: availableLanguages,
|
||||
}
|
||||
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", upev)
|
||||
|
@ -192,29 +200,30 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// Post Registration controller, we do some check on the form here, the rest on user service
|
||||
func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
b := form.RegistrationForm{}
|
||||
err := form.NewErrors()
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
if !captcha.Authenticate(captcha.Extract(r)) {
|
||||
err["errors"] = append(err["errors"], "Wrong captcha!")
|
||||
messages.AddError("errors", "Wrong captcha!")
|
||||
}
|
||||
if len(err) == 0 {
|
||||
if !messages.HasErrors() {
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
form.EmailValidation(r.PostFormValue("email"), &messages)
|
||||
}
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
if len(err) == 0 {
|
||||
form.ValidateUsername(r.PostFormValue("username"), &messages)
|
||||
if !messages.HasErrors() {
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
err = modelHelper.ValidateForm(&b, err)
|
||||
if len(err) == 0 {
|
||||
modelHelper.ValidateForm(&b, &messages)
|
||||
if !messages.HasErrors() {
|
||||
_, errorUser := userService.CreateUser(w, r)
|
||||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
messages.ImportFromError("errors", errorUser)
|
||||
}
|
||||
if len(err) == 0 {
|
||||
if !messages.HasErrors() {
|
||||
common := NewCommonVariables(r)
|
||||
common.User = &model.User{
|
||||
Email: r.PostFormValue("email"), // indicate whether user had email set
|
||||
}
|
||||
htv := UserRegisterTemplateVariables{common, b, err}
|
||||
htv := UserRegisterTemplateVariables{common, b, messages.GetAllErrors()}
|
||||
errorTmpl := viewRegisterSuccessTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -223,25 +232,21 @@ func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if len(err) > 0 {
|
||||
b.CaptchaID = captcha.GetID()
|
||||
htv := UserRegisterTemplateVariables{NewCommonVariables(r), b, err}
|
||||
errorTmpl := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
if messages.HasErrors() {
|
||||
UserRegisterFormHandler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func UserVerifyEmailHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
token := vars["token"]
|
||||
err := form.NewErrors()
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
_, errEmail := userService.EmailVerification(token, w)
|
||||
if errEmail != nil {
|
||||
err["errors"] = append(err["errors"], errEmail.Error())
|
||||
messages.ImportFromError("errors", errEmail)
|
||||
}
|
||||
htv := UserVerifyTemplateVariables{NewCommonVariables(r), err}
|
||||
htv := UserVerifyTemplateVariables{NewCommonVariables(r), messages.GetAllErrors()}
|
||||
errorTmpl := viewVerifySuccessTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -252,13 +257,14 @@ func UserVerifyEmailHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func UserLoginPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
b := form.LoginForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
err := form.NewErrors()
|
||||
err = modelHelper.ValidateForm(&b, err)
|
||||
if len(err) == 0 {
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
modelHelper.ValidateForm(&b, &messages)
|
||||
if !messages.HasErrors() {
|
||||
_, errorUser := userService.CreateUserAuthentication(w, r)
|
||||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
htv := UserLoginFormVariables{NewCommonVariables(r), b, err}
|
||||
messages.ImportFromError("errors", errorUser)
|
||||
htv := UserLoginFormVariables{NewCommonVariables(r), b, messages.GetAllErrors()}
|
||||
errorTmpl := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -269,12 +275,8 @@ func UserLoginPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
if len(err) > 0 {
|
||||
htv := UserLoginFormVariables{NewCommonVariables(r), b, err}
|
||||
errorTmpl := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
if messages.HasErrors() {
|
||||
UserLoginFormHandler(w,r)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/notifier"
|
||||
"github.com/NyaaPantsu/nyaa/service/torrent"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"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"
|
||||
|
@ -55,53 +56,58 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
|
||||
torrent, err := torrentService.GetTorrentById(id)
|
||||
if (err != nil) {
|
||||
NotFoundHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
currentUser := GetUser(r)
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
if userPermission.NeedsCaptcha(currentUser) {
|
||||
userCaptcha := captcha.Extract(r)
|
||||
if !captcha.Authenticate(userCaptcha) {
|
||||
http.Error(w, "bad captcha", 403)
|
||||
return
|
||||
messages.AddError("errors", "Bad captcham!")
|
||||
}
|
||||
}
|
||||
content := p.Sanitize(r.FormValue("comment"))
|
||||
|
||||
if strings.TrimSpace(content) == "" {
|
||||
http.Error(w, "comment empty", 406)
|
||||
return
|
||||
messages.AddError("errors", "Comment empty!")
|
||||
}
|
||||
|
||||
idNum, err := strconv.Atoi(id)
|
||||
|
||||
if !messages.HasErrors() {
|
||||
userID := currentUser.ID
|
||||
comment := model.Comment{TorrentID: uint(idNum), UserID: userID, Content: content, CreatedAt: time.Now()}
|
||||
comment := model.Comment{TorrentID: torrent.ID, UserID: userID, Content: content, CreatedAt: time.Now()}
|
||||
err := db.ORM.Create(&comment).Error
|
||||
comment.Torrent = &torrent
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
|
||||
torrent.Uploader.ParseSettings()
|
||||
if torrent.Uploader.Settings.Get("new_comment") {
|
||||
T, _, _ := languages.TfuncAndLanguageWithFallback(torrent.Uploader.Language, torrent.Uploader.Language) // We need to send the notification to every user in their language
|
||||
notifierService.NotifyUser(torrent.Uploader, comment.Identifier(), fmt.Sprintf(T("new_comment_on_torrent"), torrent.Name), url.String(), torrent.Uploader.Settings.Get("new_comment_email"))
|
||||
}
|
||||
|
||||
err = db.ORM.Create(&comment).Error
|
||||
if err != nil {
|
||||
util.SendError(w, err, 500)
|
||||
return
|
||||
messages.ImportFromError("errors", err)
|
||||
}
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", id)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, url.String(), 302)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
ViewHandler(w,r)
|
||||
}
|
||||
|
||||
func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
|
||||
messages := msg.GetMessages(r)
|
||||
currentUser := GetUser(r)
|
||||
if userPermission.NeedsCaptcha(currentUser) {
|
||||
userCaptcha := captcha.Extract(r)
|
||||
if !captcha.Authenticate(userCaptcha) {
|
||||
http.Error(w, "bad captcha", 403)
|
||||
return
|
||||
messages.AddError("errors", "Bad captchae!")
|
||||
}
|
||||
}
|
||||
|
||||
if !messages.HasErrors() {
|
||||
idNum, err := strconv.Atoi(id)
|
||||
userID := currentUser.ID
|
||||
|
||||
|
@ -114,14 +120,8 @@ func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err = db.ORM.Create(&report).Error
|
||||
if err != nil {
|
||||
util.SendError(w, err, 500)
|
||||
return
|
||||
}
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", id)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, url.String(), 302)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
messages.ImportFromError("errors", err)
|
||||
}
|
||||
}
|
||||
ViewHandler(w,r)
|
||||
}
|
||||
|
|
|
@ -6,12 +6,15 @@ import (
|
|||
)
|
||||
|
||||
|
||||
func NotifyUser(user *model.User, name string, msg string, url string) {
|
||||
func NotifyUser(user *model.User, name string, msg string, url string, email bool) {
|
||||
if (user.ID > 0) {
|
||||
notification := model.NewNotification(name, msg, url)
|
||||
notification.UserID = user.ID
|
||||
db.ORM.Create(¬ification)
|
||||
// TODO: Email notification
|
||||
/* if email {
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
formStruct "github.com/NyaaPantsu/nyaa/service/user/form"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"github.com/NyaaPantsu/nyaa/util/modelHelper"
|
||||
"github.com/NyaaPantsu/nyaa/util/timeHelper"
|
||||
"github.com/gorilla/context"
|
||||
|
@ -62,14 +63,15 @@ func ClearCookie(w http.ResponseWriter) (int, error) {
|
|||
}
|
||||
|
||||
// SetCookieHandler sets the authentication cookie
|
||||
func SetCookieHandler(w http.ResponseWriter, email string, pass string) (int, error) {
|
||||
func SetCookieHandler(w http.ResponseWriter, r *http.Request, email string, pass string) (int, error) {
|
||||
if email == "" || pass == "" {
|
||||
return http.StatusNotFound, errors.New("No username/password entered")
|
||||
}
|
||||
|
||||
var user model.User
|
||||
messages := msg.GetMessages(r)
|
||||
// search by email or username
|
||||
isValidEmail, _ := formStruct.EmailValidation(email, formStruct.NewErrors())
|
||||
isValidEmail := formStruct.EmailValidation(email, &messages)
|
||||
if isValidEmail {
|
||||
if db.ORM.Where("email = ?", email).First(&user).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("User not found")
|
||||
|
@ -104,17 +106,17 @@ func SetCookieHandler(w http.ResponseWriter, email string, pass string) (int, er
|
|||
}
|
||||
|
||||
// RegisterHanderFromForm sets cookie from a RegistrationForm.
|
||||
func RegisterHanderFromForm(w http.ResponseWriter, registrationForm formStruct.RegistrationForm) (int, error) {
|
||||
func RegisterHanderFromForm(w http.ResponseWriter, r *http.Request, registrationForm formStruct.RegistrationForm) (int, error) {
|
||||
username := registrationForm.Username // email isn't set at this point
|
||||
pass := registrationForm.Password
|
||||
return SetCookieHandler(w, username, pass)
|
||||
return SetCookieHandler(w, r, username, pass)
|
||||
}
|
||||
|
||||
// RegisterHandler sets a cookie when user registered.
|
||||
func RegisterHandler(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
var registrationForm formStruct.RegistrationForm
|
||||
modelHelper.BindValueForm(®istrationForm, r)
|
||||
return RegisterHanderFromForm(w, registrationForm)
|
||||
return RegisterHanderFromForm(w, r, registrationForm)
|
||||
}
|
||||
|
||||
// CurrentUser determines the current user from the request or context
|
||||
|
|
|
@ -4,33 +4,34 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
)
|
||||
|
||||
const EMAIL_REGEX = `(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})`
|
||||
const USERNAME_REGEX = `(\W)`
|
||||
|
||||
func EmailValidation(email string, err map[string][]string) (bool, map[string][]string) {
|
||||
func EmailValidation(email string, mes *msg.Messages) bool {
|
||||
exp, errorRegex := regexp.Compile(EMAIL_REGEX)
|
||||
if regexpCompiled := log.CheckError(errorRegex); regexpCompiled {
|
||||
if exp.MatchString(email) {
|
||||
return true, err
|
||||
return true
|
||||
}
|
||||
}
|
||||
err["email"] = append(err["email"], "Email Address is not valid")
|
||||
return false, err
|
||||
mes.AddError("email", "Email Address is not valid")
|
||||
return false
|
||||
}
|
||||
|
||||
func ValidateUsername(username string, err map[string][]string) (bool, map[string][]string) {
|
||||
func ValidateUsername(username string, mes *msg.Messages) bool {
|
||||
exp, errorRegex := regexp.Compile(USERNAME_REGEX)
|
||||
if regexpCompiled := log.CheckError(errorRegex); regexpCompiled {
|
||||
if exp.MatchString(username) {
|
||||
err["username"] = append(err["username"], "Username contains illegal characters")
|
||||
return false, err
|
||||
mes.AddError("username", "Username contains illegal characters")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false, err
|
||||
return false
|
||||
}
|
||||
return true, err
|
||||
return true
|
||||
}
|
||||
|
||||
func NewErrors() map[string][]string {
|
||||
|
@ -73,6 +74,20 @@ type UserForm struct {
|
|||
Status int `form:"status" default:"0"`
|
||||
}
|
||||
|
||||
// UserSettingsForm is used when updating a user.
|
||||
type UserSettingsForm struct {
|
||||
NewTorrent bool `form:"new_torrent" default:"true"`
|
||||
NewTorrentEmail bool `form:"new_torrent_email" default:"true"`
|
||||
NewComment bool `form:"new_comment" default:"true"`
|
||||
NewCommentEmail bool `form:"new_comment_email" default:"false"`
|
||||
NewResponses bool `form:"new_responses" default:"true"`
|
||||
NewResponsesEmail bool `form:"new_responses_email" default:"false"`
|
||||
NewFollower bool `form:"new_follower" default:"true"`
|
||||
NewFollowerEmail bool `form:"new_follower_email" default:"true"`
|
||||
Followed bool `form:"followed" default:"false"`
|
||||
FollowedEmail bool `form:"followed_email" default:"false"`
|
||||
}
|
||||
|
||||
// PasswordForm is used when updating a user password.
|
||||
type PasswordForm struct {
|
||||
CurrentPassword string `form:"currentPassword"`
|
||||
|
|
|
@ -80,6 +80,9 @@ func CreateUserFromForm(registrationForm formStruct.RegistrationForm) (model.Use
|
|||
}
|
||||
user.Email = "" // unset email because it will be verified later
|
||||
user.CreatedAt = time.Now()
|
||||
// User settings to default
|
||||
user.Settings.ToDefault()
|
||||
user.SaveSettings()
|
||||
// currently unused but needs to be set:
|
||||
user.ApiToken = ""
|
||||
user.ApiTokenExpiry = time.Unix(0, 0)
|
||||
|
@ -172,7 +175,7 @@ func UpdateUserCore(user *model.User) (int, error) {
|
|||
}
|
||||
|
||||
// UpdateUser updates a user.
|
||||
func UpdateUser(w http.ResponseWriter, form *formStruct.UserForm, currentUser *model.User, id string) (model.User, int, error) {
|
||||
func UpdateUser(w http.ResponseWriter, form *formStruct.UserForm, formSet *formStruct.UserSettingsForm, currentUser *model.User, id string) (model.User, int, error) {
|
||||
var user model.User
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return user, http.StatusNotFound, errors.New("user not found")
|
||||
|
@ -203,6 +206,21 @@ func UpdateUser(w http.ResponseWriter, form *formStruct.UserForm, currentUser *m
|
|||
}
|
||||
log.Debugf("form %+v\n", form)
|
||||
modelHelper.AssignValue(&user, form)
|
||||
|
||||
// We set settings here
|
||||
user.ParseSettings()
|
||||
user.Settings.Set("new_torrent", formSet.NewTorrent)
|
||||
user.Settings.Set("new_torrent_email", formSet.NewTorrentEmail)
|
||||
user.Settings.Set("new_comment", formSet.NewComment)
|
||||
user.Settings.Set("new_comment_email", formSet.NewCommentEmail)
|
||||
user.Settings.Set("new_responses", formSet.NewResponses)
|
||||
user.Settings.Set("new_responses_email", formSet.NewResponsesEmail)
|
||||
user.Settings.Set("new_follower", formSet.NewFollower)
|
||||
user.Settings.Set("new_follower_email", formSet.NewFollowerEmail)
|
||||
user.Settings.Set("followed", formSet.Followed)
|
||||
user.Settings.Set("followed_email", formSet.FollowedEmail)
|
||||
user.SaveSettings()
|
||||
|
||||
status, err := UpdateUserCore(&user)
|
||||
return user, status, err
|
||||
}
|
||||
|
@ -319,7 +337,7 @@ func CreateUserAuthentication(w http.ResponseWriter, r *http.Request) (int, erro
|
|||
modelHelper.BindValueForm(&form, r)
|
||||
username := form.Username
|
||||
pass := form.Password
|
||||
status, err := SetCookieHandler(w, username, pass)
|
||||
status, err := SetCookieHandler(w, r, username, pass)
|
||||
return status, err
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,169 @@
|
|||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<h3>{{ call $.T "preferences"}}</h3>
|
||||
{{ with .Settings }}
|
||||
{{ if DefaultUserSettings "new_torrent"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_torrent_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_torrent" name="new_torrent" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_torrent") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_torrent" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_torrent")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_torrent_email"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_torrent_email_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_torrent_email" name="new_torrent_email" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_torrent_email") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_torrent_email"}}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_torrent_email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_comment"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_comment_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_comment" name="new_comment" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_comment") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_comment" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_comment")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_comment_email"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_comment_email_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_comment_email" name="new_comment_email" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_comment_email") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_comment_email" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_comment_email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_responses"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_responses_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_responses" name="new_responses" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_responses") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_responses" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_responses")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_responses_email"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_responses_email_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_responses_email" name="new_responses_email" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_responses_email") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_responses_email" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_responses_email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_follower"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_follower_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_follower" name="new_follower" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_follower") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_follower" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_follower")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "new_follower_email"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "new_follower_email_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="new_follower_email" name="new_follower_email" class="form-control">
|
||||
<option value="0" {{ if not (.Get "new_follower_email") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "new_follower_email"}}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "new_follower_email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "followed"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "followed_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="followed" name="followed" class="form-control">
|
||||
<option value="0" {{ if not (.Get "followed") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "followed" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "followed")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ if DefaultUserSettings "followed_email"}}
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ call $.T "followed_email_settings" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="followed_email" name="followed_email" class="form-control">
|
||||
<option value="0" {{ if not (.Get "followed_email") }}selected{{end}}>{{ call $.T "no"}}</option>
|
||||
<option value="1" {{ if .Get "followed_email" }}selected{{end}}>{{ call $.T "yes"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "followed_email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{ if HasAdmin $.User}}
|
||||
<h3>{{ call $.T "moderation"}}</h3>
|
||||
<div class="form-group">
|
||||
|
|
|
@ -782,5 +782,61 @@
|
|||
{
|
||||
"id": "new_torrent_uploaded",
|
||||
"translation": "New torrent: \"%s\" from %s"
|
||||
},
|
||||
{
|
||||
"id": "preferences",
|
||||
"translation": "Preferences"
|
||||
},
|
||||
{
|
||||
"id": "new_torrent_settings",
|
||||
"translation": "Be notified when a new torrent is added from a user followed"
|
||||
},
|
||||
{
|
||||
"id": "new_torrent_email_settings",
|
||||
"translation": "Be notified by e-mail when a new torrent is added from a user followed"
|
||||
},
|
||||
{
|
||||
"id": "new_comment_settings",
|
||||
"translation": "Be notified when there is a new comment on your torrents"
|
||||
},
|
||||
{
|
||||
"id": "new_comment_email_settings",
|
||||
"translation": "Be notified by e-mail when there is a new comment on your torrents"
|
||||
},
|
||||
{
|
||||
"id": "new_responses_settings",
|
||||
"translation": "Be notified when there is a new response to your comment"
|
||||
},
|
||||
{
|
||||
"id": "new_responses_email_settings",
|
||||
"translation": "Be notified by e-mail when there is a new response to your comment"
|
||||
},
|
||||
{
|
||||
"id": "new_follower_settings",
|
||||
"translation": "Be notified when you have a new follower"
|
||||
},
|
||||
{
|
||||
"id": "new_follower_email_settings",
|
||||
"translation": "Be notified by e-mail when you have a new follower"
|
||||
},
|
||||
{
|
||||
"id": "followed_settings",
|
||||
"translation": "Be notified when you have followed someone"
|
||||
},
|
||||
{
|
||||
"id": "followed_email_settings",
|
||||
"translation": "Be notified by e-mail when you have followed someone"
|
||||
},
|
||||
{
|
||||
"id": "yes",
|
||||
"translation": "Yes"
|
||||
},
|
||||
{
|
||||
"id": "no",
|
||||
"translation": "No"
|
||||
},
|
||||
{
|
||||
"id": "new_comment_on_torrent",
|
||||
"translation": "New comment on torrent: \"%s\""
|
||||
}
|
||||
]
|
||||
|
|
|
@ -23,6 +23,9 @@ func GetMessages(r *http.Request) Messages {
|
|||
}
|
||||
|
||||
func (mes Messages) AddError(name string, msg string) {
|
||||
if (mes.Errors == nil) {
|
||||
mes.Errors = make(map[string][]string)
|
||||
}
|
||||
mes.Errors[name] = append(mes.Errors[name], msg)
|
||||
mes.setMessagesInContext()
|
||||
}
|
||||
|
@ -34,6 +37,9 @@ func (mes Messages) ImportFromError(name string, err error) {
|
|||
}
|
||||
|
||||
func (mes Messages) AddInfo(name string, msg string) {
|
||||
if (mes.Infos == nil) {
|
||||
mes.Infos = make(map[string][]string)
|
||||
}
|
||||
mes.Infos[name] = append(mes.Infos[name], msg)
|
||||
mes.setMessagesInContext()
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package modelHelper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
@ -57,7 +57,7 @@ func BindValueForm(form interface{}, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func ValidateForm(form interface{}, errorForm map[string][]string) map[string][]string {
|
||||
func ValidateForm(form interface{}, mes *msg.Messages) {
|
||||
formElem := reflect.ValueOf(form).Elem()
|
||||
for i := 0; i < formElem.NumField(); i++ {
|
||||
typeField := formElem.Type().Field(i)
|
||||
|
@ -69,28 +69,28 @@ func ValidateForm(form interface{}, errorForm map[string][]string) map[string][]
|
|||
if tag.Get("len_min") != "" && (tag.Get("needed") != "" || formElem.Field(i).Len() > 0) { // Check minimum length
|
||||
lenMin, _ := strconv.Atoi(tag.Get("len_min"))
|
||||
if formElem.Field(i).Len() < lenMin {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Minimal length of %s required for the input: %s", strconv.Itoa(lenMin), inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Minimal length of %s required for the input: %s", strconv.Itoa(lenMin), inputName)
|
||||
}
|
||||
}
|
||||
if tag.Get("len_max") != "" && (tag.Get("needed") != "" || formElem.Field(i).Len() > 0) { // Check maximum length
|
||||
lenMax, _ := strconv.Atoi(tag.Get("len_max"))
|
||||
if formElem.Field(i).Len() > lenMax {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Maximal length of %s required for the input: %s", strconv.Itoa(lenMax), inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Maximal length of %s required for the input: %s", strconv.Itoa(lenMax), inputName)
|
||||
}
|
||||
}
|
||||
if tag.Get("equalInput") != "" && (tag.Get("needed") != "" || formElem.Field(i).Len() > 0) {
|
||||
otherInput := formElem.FieldByName(tag.Get("equalInput"))
|
||||
if formElem.Field(i).Interface() != otherInput.Interface() {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Must be same %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Must be same %s", inputName)
|
||||
}
|
||||
}
|
||||
switch typeField.Type.Name() {
|
||||
case "string":
|
||||
if tag.Get("equal") != "" && formElem.Field(i).String() != tag.Get("equal") {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Wrong value for the input: %s", inputName)
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).String() == "" {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Field needed: %s", inputName)
|
||||
}
|
||||
if formElem.Field(i).String() == "" && tag.Get("default") != "" {
|
||||
formElem.Field(i).SetString(tag.Get("default"))
|
||||
|
@ -99,11 +99,11 @@ func ValidateForm(form interface{}, errorForm map[string][]string) map[string][]
|
|||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.Atoi(tag.Get("equal"))
|
||||
if formElem.Field(i).Int() > int64(equal) {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Wrong value for the input: %s", inputName)
|
||||
}
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).Int() == 0 {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Field needed: %s", inputName)
|
||||
}
|
||||
if formElem.Field(i).Interface == nil && tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.Atoi(tag.Get("default"))
|
||||
|
@ -113,11 +113,11 @@ func ValidateForm(form interface{}, errorForm map[string][]string) map[string][]
|
|||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.Atoi(tag.Get("equal"))
|
||||
if formElem.Field(i).Float() != float64(equal) {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Wrong value for the input: %s", inputName)
|
||||
}
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).Float() == 0 {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Field needed: %s", inputName)
|
||||
}
|
||||
if formElem.Field(i).Interface == nil && tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.Atoi(tag.Get("default"))
|
||||
|
@ -127,10 +127,13 @@ func ValidateForm(form interface{}, errorForm map[string][]string) map[string][]
|
|||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.ParseBool(tag.Get("equal"))
|
||||
if formElem.Field(i).Bool() != equal {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
mes.AddErrorf(tag.Get("form"), "Wrong value for the input: %s", inputName)
|
||||
}
|
||||
}
|
||||
if formElem.Field(i).Interface == nil && tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.ParseBool(tag.Get("default"))
|
||||
formElem.Field(i).SetBool(defaultValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return errorForm
|
||||
}
|
||||
|
|
Référencer dans un nouveau ticket