Cleanups and fixes (#623)
* Keep naming consistent * Remove execute bit from files * Default to DefaultLanguage (without passing it to the func) * Remove commented code * Use Content-Type to get language json * Lines of 400 characters is dumb * Update new repo in README * Remove useless script since we fallback to a defaultlang * Fix fallback language panic * Fix uninitialized MaxPerPage when not in querystr The issue was that the req.MaxPerPage was not set (default to 0) when the query string didn't include "max". This makes the server query the whole db since the resulting limit is 0. * Fix creating empty torrents (only worked once) * Lines of 400 characters is still dumb
Cette révision appartient à :
Parent
a0d5570cdf
révision
babf0a37f0
29 fichiers modifiés avec 325 ajouts et 277 suppressions
|
@ -25,9 +25,9 @@ You may now start the container as such.
|
|||
|
||||
```
|
||||
$ export GOPATH=$HOME/.go
|
||||
$ mkdir -p $HOME/.go/src/github.com/ewhal
|
||||
$ cd $HOME/.go/src/github.com/ewhal
|
||||
$ git clone https://github.com/ewhal/nyaa
|
||||
$ mkdir -p $HOME/.go/src/github.com/NyaaPantsu
|
||||
$ cd $HOME/.go/src/github.com/NyaaPantsu
|
||||
$ git clone https://github.com/NyaaPantsu/nyaa
|
||||
$ cd nyaa/deploy
|
||||
$ docker-compose -f <docker_compose_file> up
|
||||
```
|
||||
|
|
|
@ -24,7 +24,8 @@ function loadLanguages() {
|
|||
}
|
||||
}
|
||||
}
|
||||
xhr.open("GET", "/language?format=json", true)
|
||||
xhr.open("GET", "/language", true)
|
||||
xhr.setRequestHeader("Content-Type", "application/json")
|
||||
xhr.send()
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if req.MaxPerPage == 0 {
|
||||
req.MaxPerPage = 50
|
||||
req.MaxPerPage = config.TorrentsPerPage
|
||||
}
|
||||
if req.Page == 0 {
|
||||
req.Page = 1
|
||||
|
@ -47,8 +47,10 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if maxString != "" {
|
||||
req.MaxPerPage, err = strconv.Atoi(maxString)
|
||||
if !log.CheckError(err) {
|
||||
req.MaxPerPage = 50 // default Value maxPerPage
|
||||
req.MaxPerPage = config.TorrentsPerPage
|
||||
}
|
||||
} else {
|
||||
req.MaxPerPage = config.TorrentsPerPage
|
||||
}
|
||||
|
||||
req.Page = 1
|
||||
|
@ -125,12 +127,12 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if contentType == "application/json" {
|
||||
|
||||
defer r.Body.Close()
|
||||
|
||||
d := json.NewDecoder(r.Body)
|
||||
if err := d.Decode(&upload); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
decodeError := fmt.Errorf("Unable to decode upload data: %s", err).Error()
|
||||
http.Error(w, decodeError, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
err, code := upload.ValidateUpload()
|
||||
|
@ -139,7 +141,6 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
} else if strings.HasPrefix(contentType, "multipart/form-data") {
|
||||
|
||||
upload.Name = r.FormValue("name")
|
||||
upload.Category, _ = strconv.Atoi(r.FormValue("category"))
|
||||
upload.SubCategory, _ = strconv.Atoi(r.FormValue("sub_category"))
|
||||
|
@ -153,12 +154,17 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, err.Error(), code)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// TODO What should we do here ? upload is empty so we shouldn't
|
||||
// create a torrent from it
|
||||
err := fmt.Errorf("Please provide either of Content-Type: application/json header or multipart/form-data").Error()
|
||||
http.Error(w, err, http.StatusInternalServerError)
|
||||
}
|
||||
var sameTorrents int
|
||||
|
||||
db.ORM.Model(&model.Torrent{}).Where("torrent_hash = ?", upload.Hash).Count(&sameTorrents)
|
||||
|
||||
if sameTorrents == 0 {
|
||||
|
||||
torrent := model.Torrent{
|
||||
Name: upload.Name,
|
||||
Category: upload.Category,
|
||||
|
@ -183,6 +189,7 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME Impossible to update a torrent uploaded by user 0
|
||||
func ApiUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
user := model.User{}
|
|
@ -9,7 +9,14 @@ import (
|
|||
|
||||
func FaqHandler(w http.ResponseWriter, r *http.Request) {
|
||||
languages.SetTranslationFromRequest(faqTemplate, r)
|
||||
err := faqTemplate.ExecuteTemplate(w, "index.html", FaqTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
ftv := FaqTemplateVariables{
|
||||
Navigation: NewNavigation(),
|
||||
Search: NewSearchForm(),
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
err := faqTemplate.ExecuteTemplate(w, "index.html", ftv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
|
@ -52,12 +52,24 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return torrents, nbTorrents, err
|
||||
})
|
||||
|
||||
b := model.TorrentsToJSON(torrents)
|
||||
|
||||
navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"}
|
||||
navigationTorrents := Navigation{
|
||||
TotalItem: nbTorrents,
|
||||
MaxItemPerPage: maxPerPage,
|
||||
CurrentPage: pagenum,
|
||||
Route: "search_page",
|
||||
}
|
||||
|
||||
languages.SetTranslationFromRequest(homeTemplate, r)
|
||||
htv := HomeTemplateVariables{b, NewSearchForm(), navigationTorrents, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
torrentsJson := model.TorrentsToJSON(torrents)
|
||||
htv := HomeTemplateVariables{
|
||||
ListTorrents: torrentsJson,
|
||||
Search: NewSearchForm(),
|
||||
Navigation: navigationTorrents,
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
|
||||
err = homeTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
|
@ -18,8 +18,8 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
_, Tlang := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
|
||||
format := r.URL.Query().Get("format")
|
||||
if format == "json" {
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if contentType == "application/json" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(LanguagesJSONResponse{Tlang.Tag, availableLanguages})
|
||||
if err != nil {
|
||||
|
@ -27,7 +27,15 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
} else {
|
||||
clv := ChangeLanguageVariables{NewSearchForm(), NewNavigation(), Tlang.Tag, availableLanguages, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
clv := ChangeLanguageVariables{
|
||||
Search: NewSearchForm(),
|
||||
Navigation: NewNavigation(),
|
||||
Language: Tlang.Tag,
|
||||
Languages: availableLanguages,
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
languages.SetTranslationFromRequest(changeLanguageTemplate, r)
|
||||
err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv)
|
||||
if err != nil {
|
||||
|
@ -52,9 +60,8 @@ func ChangeLanguageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
user.Language = lang
|
||||
// I don't know if I should use this...
|
||||
userService.UpdateUserCore(&user)
|
||||
} else {
|
||||
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang})
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang})
|
||||
|
||||
url, _ := Router.Get("home").URL()
|
||||
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
|
@ -8,10 +8,18 @@ import (
|
|||
)
|
||||
|
||||
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
nftv := NotFoundTemplateVariables{
|
||||
Navigation: NewNavigation(),
|
||||
Search: NewSearchForm(),
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", nftv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
34
router/router.go
Fichier exécutable → Fichier normal
34
router/router.go
Fichier exécutable → Fichier normal
|
@ -30,43 +30,9 @@ func init() {
|
|||
gzipUserProfileFormHandler := http.HandlerFunc(UserProfileFormHandler)
|
||||
gzipDumpsHandler := handlers.CompressHandler(dumpsHandler)
|
||||
gzipGpgKeyHandler := handlers.CompressHandler(gpgKeyHandler)
|
||||
|
||||
/*
|
||||
// Enable GZIP compression for all handlers except imgHandler and captcha
|
||||
gzipCSSHandler := cssHandler)
|
||||
gzipJSHandler:= jsHandler)
|
||||
gzipSearchHandler:= http.HandlerFunc(SearchHandler)
|
||||
gzipAPIUploadHandler := http.HandlerFunc(ApiUploadHandler)
|
||||
gzipAPIUpdateHandler := http.HandlerFunc(ApiUpdateHandler)
|
||||
gzipFaqHandler := http.HandlerFunc(FaqHandler)
|
||||
gzipRSSHandler := http.HandlerFunc(RSSHandler)
|
||||
gzipUploadHandler := http.HandlerFunc(UploadHandler)
|
||||
gzipUserRegisterFormHandler := http.HandlerFunc(UserRegisterFormHandler)
|
||||
gzipUserLoginFormHandler := http.HandlerFunc(UserLoginFormHandler)
|
||||
gzipUserVerifyEmailHandler := http.HandlerFunc(UserVerifyEmailHandler)
|
||||
gzipUserRegisterPostHandler := http.HandlerFunc(UserRegisterPostHandler)
|
||||
gzipUserLoginPostHandler := http.HandlerFunc(UserLoginPostHandler)
|
||||
gzipUserLogoutHandler := http.HandlerFunc(UserLogoutHandler)
|
||||
gzipUserFollowHandler := http.HandlerFunc(UserFollowHandler)
|
||||
|
||||
gzipIndexModPanel := http.HandlerFunc(IndexModPanel)
|
||||
gzipTorrentsListPanel := http.HandlerFunc(TorrentsListPanel)
|
||||
gzipTorrentReportListPanel := http.HandlerFunc(TorrentReportListPanel)
|
||||
gzipUsersListPanel := http.HandlerFunc(UsersListPanel)
|
||||
gzipCommentsListPanel := http.HandlerFunc(CommentsListPanel)
|
||||
gzipTorrentEditModPanel := http.HandlerFunc(TorrentEditModPanel)
|
||||
gzipTorrentPostEditModPanel := http.HandlerFunc(TorrentPostEditModPanel)
|
||||
gzipCommentDeleteModPanel := http.HandlerFunc(CommentDeleteModPanel)
|
||||
gzipTorrentDeleteModPanel := http.HandlerFunc(TorrentDeleteModPanel)
|
||||
gzipTorrentReportDeleteModPanel := http.HandlerFunc(TorrentReportDeleteModPanel)*/
|
||||
//gzipTorrentReportCreateHandler := http.HandlerFunc(CreateTorrentReportHandler)
|
||||
//gzipTorrentReportDeleteHandler := http.HandlerFunc(DeleteTorrentReportHandler)
|
||||
//gzipTorrentDeleteHandler := http.HandlerFunc(DeleteTorrentHandler)
|
||||
gzipDatabaseDumpHandler := handlers.CompressHandler(http.HandlerFunc(DatabaseDumpHandler))
|
||||
|
||||
Router = mux.NewRouter()
|
||||
|
||||
// Routes
|
||||
http.Handle("/css/", http.StripPrefix("/css/", cssHandler))
|
||||
http.Handle("/js/", http.StripPrefix("/js/", jsHandler))
|
||||
http.Handle("/img/", http.StripPrefix("/img/", imgHandler))
|
||||
|
|
|
@ -7,9 +7,29 @@ import (
|
|||
|
||||
var TemplateDir = "templates"
|
||||
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate, viewProfileEditTemplate, viewUserDeleteTemplate, notFoundTemplate, changeLanguageTemplate, databaseDumpTemplate *template.Template
|
||||
var homeTemplate,
|
||||
searchTemplate,
|
||||
faqTemplate,
|
||||
uploadTemplate,
|
||||
viewTemplate,
|
||||
viewRegisterTemplate,
|
||||
viewLoginTemplate,
|
||||
viewRegisterSuccessTemplate,
|
||||
viewVerifySuccessTemplate,
|
||||
viewProfileTemplate,
|
||||
viewProfileEditTemplate,
|
||||
viewUserDeleteTemplate,
|
||||
notFoundTemplate,
|
||||
changeLanguageTemplate,
|
||||
databaseDumpTemplate *template.Template
|
||||
|
||||
var panelIndex, panelTorrentList, panelUserList, panelCommentList, panelTorrentEd, panelTorrentReportList, panelTorrentReassign *template.Template
|
||||
var panelIndex,
|
||||
panelTorrentList,
|
||||
panelUserList,
|
||||
panelCommentList,
|
||||
panelTorrentEd,
|
||||
panelTorrentReportList,
|
||||
panelTorrentReassign *template.Template
|
||||
|
||||
type templateLoader struct {
|
||||
templ **template.Template
|
||||
|
@ -93,8 +113,8 @@ func ReloadTemplates() {
|
|||
},
|
||||
templateLoader{
|
||||
templ: &changeLanguageTemplate,
|
||||
name: "change_language",
|
||||
file: "change_language.html",
|
||||
name: "change_language",
|
||||
file: "change_language.html",
|
||||
},
|
||||
}
|
||||
for idx := range pubTempls {
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/service/captcha"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
user := GetUser(r)
|
||||
|
||||
if config.UploadsDisabled {
|
||||
|
||||
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var uploadForm UploadForm
|
||||
if r.Method == "POST" {
|
||||
defer r.Body.Close()
|
||||
if userPermission.NeedsCaptcha(user) {
|
||||
userCaptcha := captcha.Extract(r)
|
||||
if !captcha.Authenticate(userCaptcha) {
|
||||
http.Error(w, captcha.ErrInvalidCaptcha.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// validation is done in ExtractInfo()
|
||||
err := uploadForm.ExtractInfo(r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
status := 1 // normal
|
||||
if uploadForm.Remake { // overrides trusted
|
||||
status = 2
|
||||
} else if user.Status == 1 {
|
||||
status = 3 // mark as trusted if user is trusted
|
||||
}
|
||||
|
||||
var sameTorrents int
|
||||
db.ORM.Model(&model.Torrent{}).Table(config.TableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
|
||||
if sameTorrents == 0 {
|
||||
// add to db and redirect
|
||||
torrent := model.Torrent{
|
||||
Name: uploadForm.Name,
|
||||
Category: uploadForm.CategoryID,
|
||||
SubCategory: uploadForm.SubCategoryID,
|
||||
Status: status,
|
||||
Hash: uploadForm.Infohash,
|
||||
Date: time.Now(),
|
||||
Filesize: uploadForm.Filesize,
|
||||
Description: uploadForm.Description,
|
||||
UploaderID: user.ID}
|
||||
db.ORM.Table(config.TableName).Create(&torrent)
|
||||
|
||||
// add filelist to files db, if we have one
|
||||
if len(uploadForm.FileList) > 0 {
|
||||
for _, uploadedFile := range uploadForm.FileList {
|
||||
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
|
||||
}
|
||||
db.ORM.Create(&file)
|
||||
}
|
||||
}
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, url.String(), 302)
|
||||
} else {
|
||||
http.Error(w, fmt.Errorf("Torrent already in database!").Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else if r.Method == "GET" {
|
||||
user := GetUser(r)
|
||||
if userPermission.NeedsCaptcha(user) {
|
||||
uploadForm.CaptchaID = captcha.GetID()
|
||||
} else {
|
||||
uploadForm.CaptchaID = ""
|
||||
}
|
||||
|
||||
htv := UploadTemplateVariables{uploadForm, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
languages.SetTranslationFromRequest(uploadTemplate, r)
|
||||
err := uploadTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
}
|
134
router/upload_handler.go
Fichier normal
134
router/upload_handler.go
Fichier normal
|
@ -0,0 +1,134 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/service/captcha"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if config.UploadsDisabled {
|
||||
user := GetUser(r)
|
||||
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
|
||||
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if r.Method == "POST" {
|
||||
UploadPostHandler(w, r)
|
||||
} else if r.Method == "GET" {
|
||||
UploadGetHandler(w, r)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var uploadForm UploadForm
|
||||
defer r.Body.Close()
|
||||
user := GetUser(r)
|
||||
if userPermission.NeedsCaptcha(user) {
|
||||
userCaptcha := captcha.Extract(r)
|
||||
if !captcha.Authenticate(userCaptcha) {
|
||||
http.Error(w, captcha.ErrInvalidCaptcha.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// validation is done in ExtractInfo()
|
||||
err := uploadForm.ExtractInfo(r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
status := 1 // normal
|
||||
if uploadForm.Remake { // overrides trusted
|
||||
status = 2
|
||||
} else if user.Status == 1 {
|
||||
status = 3 // mark as trusted if user is trusted
|
||||
}
|
||||
|
||||
var sameTorrents int
|
||||
db.ORM.Model(&model.Torrent{}).Table(config.TableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
|
||||
if sameTorrents == 0 {
|
||||
// add to db and redirect
|
||||
torrent := model.Torrent{
|
||||
Name: uploadForm.Name,
|
||||
Category: uploadForm.CategoryID,
|
||||
SubCategory: uploadForm.SubCategoryID,
|
||||
Status: status,
|
||||
Hash: uploadForm.Infohash,
|
||||
Date: time.Now(),
|
||||
Filesize: uploadForm.Filesize,
|
||||
Description: uploadForm.Description,
|
||||
UploaderID: user.ID}
|
||||
db.ORM.Table(config.TableName).Create(&torrent)
|
||||
|
||||
// add filelist to files db, if we have one
|
||||
if len(uploadForm.FileList) > 0 {
|
||||
for _, uploadedFile := range uploadForm.FileList {
|
||||
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
|
||||
}
|
||||
db.ORM.Create(&file)
|
||||
}
|
||||
}
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
languages.SetTranslationFromRequest(uploadTemplate, r)
|
||||
|
||||
var uploadForm UploadForm
|
||||
user := GetUser(r)
|
||||
if userPermission.NeedsCaptcha(user) {
|
||||
uploadForm.CaptchaID = captcha.GetID()
|
||||
} else {
|
||||
uploadForm.CaptchaID = ""
|
||||
}
|
||||
|
||||
utv := UploadTemplateVariables{
|
||||
Upload: uploadForm,
|
||||
Search: NewSearchForm(),
|
||||
Navigation: NewNavigation(),
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
err := uploadTemplate.ExecuteTemplate(w, "index.html", utv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
151
router/userHandler.go → router/user_handler.go
Fichier exécutable → Fichier normal
151
router/userHandler.go → router/user_handler.go
Fichier exécutable → Fichier normal
|
@ -18,30 +18,47 @@ import (
|
|||
// Getting View User Registration
|
||||
func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||
_, errorUser := userService.CurrentUser(r)
|
||||
if errorUser != nil {
|
||||
b := form.RegistrationForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
b.CaptchaID = captcha.GetID()
|
||||
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
|
||||
htv := UserRegisterTemplateVariables{b, form.NewErrors(), NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else {
|
||||
// User is already connected, redirect to home
|
||||
if errorUser == nil {
|
||||
HomeHandler(w, r)
|
||||
return
|
||||
}
|
||||
registrationForm := form.RegistrationForm{}
|
||||
modelHelper.BindValueForm(®istrationForm, r)
|
||||
registrationForm.CaptchaID = captcha.GetID()
|
||||
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
|
||||
urtv := UserRegisterTemplateVariables{
|
||||
RegistrationForm: registrationForm,
|
||||
FormErrors: form.NewErrors(),
|
||||
Search: NewSearchForm(),
|
||||
Navigation: NewNavigation(),
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", urtv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// Getting View User Login
|
||||
func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||
b := form.LoginForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
loginForm := form.LoginForm{}
|
||||
modelHelper.BindValueForm(&loginForm, r)
|
||||
|
||||
languages.SetTranslationFromRequest(viewLoginTemplate, r)
|
||||
htv := UserLoginFormVariables{b, form.NewErrors(), NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
ulfv := UserLoginFormVariables{
|
||||
LoginForm: loginForm,
|
||||
FormErrors: form.NewErrors(),
|
||||
Search: NewSearchForm(),
|
||||
Navigation: NewNavigation(),
|
||||
User: GetUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
|
||||
err := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
err := viewLoginTemplate.ExecuteTemplate(w, "index.html", ulfv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
@ -128,64 +145,64 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
id := vars["id"]
|
||||
currentUser := GetUser(r)
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if errorUser == nil {
|
||||
if userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
|
||||
b := form.UserForm{}
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
T := languages.SetTranslationFromRequest(viewProfileEditTemplate, r)
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
}
|
||||
if len(r.PostFormValue("username")) > 0 {
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
}
|
||||
if errorUser != nil || !userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
|
||||
NotFoundHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if len(err) == 0 {
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
if !userPermission.HasAdmin(currentUser) {
|
||||
b.Username = userProfile.Username
|
||||
b.Status = userProfile.Status
|
||||
} else {
|
||||
if userProfile.Status != b.Status && b.Status == 2 {
|
||||
err["errors"] = append(err["errors"], "Elevating status to moderator is prohibited")
|
||||
}
|
||||
}
|
||||
err = modelHelper.ValidateForm(&b, err)
|
||||
if len(err) == 0 {
|
||||
if b.Email != userProfile.Email {
|
||||
userService.SendVerificationToUser(*currentUser, b.Email)
|
||||
infos["infos"] = append(infos["infos"], fmt.Sprintf(T("email_changed"), b.Email))
|
||||
b.Email = userProfile.Email // reset, it will be set when user clicks verification
|
||||
}
|
||||
userProfile, _, errorUser = userService.UpdateUser(w, &b, currentUser, id)
|
||||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
} else {
|
||||
infos["infos"] = append(infos["infos"], T("profile_updated"))
|
||||
}
|
||||
}
|
||||
}
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
htv := UserProfileEditVariables{&userProfile, b, err, infos, availableLanguages, NewSearchForm(), NewNavigation(), currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
userForm := form.UserForm{}
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
T := languages.SetTranslationFromRequest(viewProfileEditTemplate, r)
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
}
|
||||
if len(r.PostFormValue("username")) > 0 {
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
}
|
||||
|
||||
if len(err) == 0 {
|
||||
modelHelper.BindValueForm(&userForm, r)
|
||||
if !userPermission.HasAdmin(currentUser) {
|
||||
userForm.Username = userProfile.Username
|
||||
userForm.Status = userProfile.Status
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
if userProfile.Status != userForm.Status && userForm.Status == 2 {
|
||||
err["errors"] = append(err["errors"], "Elevating status to moderator is prohibited")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
err = modelHelper.ValidateForm(&userForm, err)
|
||||
if len(err) == 0 {
|
||||
if userForm.Email != userProfile.Email {
|
||||
userService.SendVerificationToUser(*currentUser, userForm.Email)
|
||||
infos["infos"] = append(infos["infos"], fmt.Sprintf(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)
|
||||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
} else {
|
||||
infos["infos"] = append(infos["infos"], T("profile_updated"))
|
||||
}
|
||||
}
|
||||
}
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
upev := UserProfileEditVariables{
|
||||
UserProfile: &userProfile,
|
||||
UserForm: userForm,
|
||||
FormErrors: err,
|
||||
FormInfos: infos,
|
||||
Languages: availableLanguages,
|
||||
Search: NewSearchForm(),
|
||||
Navigation: NewNavigation(),
|
||||
User: currentUser,
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
}
|
||||
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", upev)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// Post Registration controller, we do some check on the form here, the rest on user service
|
|
@ -74,6 +74,7 @@ func validateName(r *TorrentRequest) (error, int) {
|
|||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
// TODO Check category is within accepted range
|
||||
func validateCategory(r *TorrentRequest) (error, int) {
|
||||
if r.Category == 0 {
|
||||
return ErrCategory, http.StatusNotAcceptable
|
||||
|
@ -81,6 +82,7 @@ func validateCategory(r *TorrentRequest) (error, int) {
|
|||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
// TODO Check subCategory is within accepted range
|
||||
func validateSubCategory(r *TorrentRequest) (error, int) {
|
||||
if r.SubCategory == 0 {
|
||||
return ErrSubCategory, http.StatusNotAcceptable
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
id="$1"
|
||||
translation="$2"
|
||||
|
||||
for file in *.json; do
|
||||
head -n -2 "${file}" > "${file}.tmp"
|
||||
echo -e " },\n {\n \"id\": \"${id}\",\n \"translation\": \"${translation}\"\n }\n]" >> "${file}.tmp"
|
||||
mv "${file}.tmp" "${file}"
|
||||
done
|
|
@ -29,7 +29,7 @@ func InitI18n(conf config.I18nConfig, retriever UserRetriever) error {
|
|||
defaultLanguage = conf.DefaultLanguage
|
||||
userRetriever = retriever
|
||||
|
||||
defaultFilepath := path.Join(conf.TranslationsDirectory, conf.DefaultLanguage+".all.json")
|
||||
defaultFilepath := path.Join(conf.TranslationsDirectory, defaultLanguage+".all.json")
|
||||
err := i18n.LoadTranslationFile(defaultFilepath)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to load default translation file '%s': %v", defaultFilepath, err))
|
||||
|
@ -57,27 +57,26 @@ func GetDefaultLanguage() string {
|
|||
// When go-i18n finds a language with >0 translations, it uses it as the Tfunc
|
||||
// However, if said language has a missing translation, it won't fallback to the "main" language
|
||||
func TfuncAndLanguageWithFallback(language string, languages ...string) (i18n.TranslateFunc, *language.Language, error) {
|
||||
// Use the last language on the args as the fallback one.
|
||||
fallbackLanguage := language
|
||||
if languages != nil {
|
||||
fallbackLanguage = languages[len(languages)-1]
|
||||
}
|
||||
fallbackLanguage := GetDefaultLanguage()
|
||||
|
||||
T, Tlang, err1 := i18n.TfuncAndLanguage(language, languages...)
|
||||
fallbackT, fallbackTlang, err2 := i18n.TfuncAndLanguage(fallbackLanguage)
|
||||
tFunc, tLang, err1 := i18n.TfuncAndLanguage(language, languages...)
|
||||
// If fallbackLanguage fails, it will give the "id" field so we don't
|
||||
// care about the error
|
||||
fallbackT, fallbackTlang, _ := i18n.TfuncAndLanguage(fallbackLanguage)
|
||||
|
||||
if err1 != nil && err2 != nil {
|
||||
// fallbackT is still a valid function even with the error, it returns translationID.
|
||||
return fallbackT, fallbackTlang, err2
|
||||
}
|
||||
|
||||
return func(translationID string, args ...interface{}) string {
|
||||
if translated := T(translationID, args...); translated != translationID {
|
||||
translateFunction := func(translationID string, args ...interface{}) string {
|
||||
if translated := tFunc(translationID, args...); translated != translationID {
|
||||
return translated
|
||||
}
|
||||
|
||||
return fallbackT(translationID, args...)
|
||||
}, Tlang, nil
|
||||
}
|
||||
|
||||
if err1 != nil {
|
||||
tLang = fallbackTlang
|
||||
}
|
||||
|
||||
return translateFunction, tLang, err1
|
||||
}
|
||||
|
||||
func GetAvailableLanguages() (languages map[string]string) {
|
||||
|
@ -112,8 +111,6 @@ func GetDefaultTfunc() (i18n.TranslateFunc, error) {
|
|||
}
|
||||
|
||||
func GetTfuncAndLanguageFromRequest(r *http.Request) (T i18n.TranslateFunc, Tlang *language.Language) {
|
||||
defaultLanguage := GetDefaultLanguage()
|
||||
|
||||
userLanguage := ""
|
||||
user, err := getCurrentUser(r)
|
||||
if err == nil {
|
||||
|
@ -126,9 +123,9 @@ func GetTfuncAndLanguageFromRequest(r *http.Request) (T i18n.TranslateFunc, Tlan
|
|||
cookieLanguage = cookie.Value
|
||||
}
|
||||
|
||||
// go-i18n supports the format of the Accept-Language header, thankfully.
|
||||
// go-i18n supports the format of the Accept-Language header
|
||||
headerLanguage := r.Header.Get("Accept-Language")
|
||||
T, Tlang, _ = TfuncAndLanguageWithFallback(userLanguage, cookieLanguage, headerLanguage, defaultLanguage)
|
||||
T, Tlang, _ = TfuncAndLanguageWithFallback(userLanguage, cookieLanguage, headerLanguage)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Référencer dans un nouveau ticket