Merge branch 'dev' of https://github.com/NyaaPantsu/nyaa into dev
Cette révision appartient à :
révision
cdd382cd34
|
@ -103,7 +103,7 @@ func (p *TorrentParam) ToFilterQuery() string {
|
|||
}
|
||||
|
||||
if p.UserID != 0 {
|
||||
query += "uploader_id:" + strconv.FormatInt(int64(p.UserID), 10)
|
||||
query += " uploader_id:" + strconv.FormatInt(int64(p.UserID), 10)
|
||||
}
|
||||
|
||||
if p.Status != ShowAll {
|
||||
|
|
|
@ -6,7 +6,7 @@ package config
|
|||
var Trackers = []string{
|
||||
"udp://tracker.doko.moe:6969",
|
||||
"udp://tracker.coppersurfer.tk:6969",
|
||||
"udp://zer0day.to:1337/announce",
|
||||
"udp://tracker.zer0day.to:1337/announce",
|
||||
"udp://tracker.leechers-paradise.org:6969",
|
||||
"udp://explodie.org:6969",
|
||||
"udp://tracker.opentrackr.org:1337",
|
||||
|
|
4
main.go
4
main.go
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/scraper"
|
||||
"github.com/NyaaPantsu/nyaa/service/torrent/metainfoFetcher"
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
"github.com/NyaaPantsu/nyaa/util/search"
|
||||
"github.com/NyaaPantsu/nyaa/util/signals"
|
||||
|
@ -129,7 +129,7 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
err = languages.InitI18n(conf.I18n, userService.NewCurrentUserRetriever())
|
||||
err = publicSettings.InitI18n(conf.I18n, userService.NewCurrentUserRetriever())
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ type Torrent struct {
|
|||
Category int `gorm:"column:category"`
|
||||
SubCategory int `gorm:"column:sub_category"`
|
||||
Status int `gorm:"column:status"`
|
||||
Hidden bool `gorm:"column:hidden"`
|
||||
Date time.Time `gorm:"column:date"`
|
||||
UploaderID uint `gorm:"column:uploader"`
|
||||
Downloads int `gorm:"column:downloads"`
|
||||
|
@ -267,8 +268,13 @@ func (t *Torrent) ToJSON() TorrentJSON {
|
|||
})
|
||||
|
||||
uploader := ""
|
||||
if t.Uploader != nil {
|
||||
var uploaderID uint
|
||||
if t.Hidden {
|
||||
uploader = "れんちょん"
|
||||
uploaderID = 0
|
||||
} else if t.Uploader != nil {
|
||||
uploader = t.Uploader.Username
|
||||
uploaderID = t.UploaderID
|
||||
}
|
||||
torrentlink := ""
|
||||
if t.ID <= config.LastOldTorrentID && len(config.TorrentCacheLink) > 0 {
|
||||
|
@ -292,7 +298,7 @@ func (t *Torrent) ToJSON() TorrentJSON {
|
|||
SubCategory: strconv.Itoa(t.SubCategory),
|
||||
Category: strconv.Itoa(t.Category),
|
||||
Downloads: t.Downloads,
|
||||
UploaderID: t.UploaderID,
|
||||
UploaderID: uploaderID,
|
||||
UploaderName: util.SafeText(uploader),
|
||||
OldUploader: util.SafeText(t.OldUploader),
|
||||
WebsiteLink: util.Safe(t.WebsiteLink),
|
||||
|
|
|
@ -31,6 +31,7 @@ type User struct {
|
|||
APIToken string `gorm:"column:api_token"`
|
||||
APITokenExpiry time.Time `gorm:"column:api_token_expiry"`
|
||||
Language string `gorm:"column:language"`
|
||||
Theme string `gorm:"column:theme"`
|
||||
UserSettings string `gorm:"column:settings"`
|
||||
|
||||
// TODO: move this to PublicUser
|
||||
|
@ -62,7 +63,7 @@ func (u User) Size() (s int) {
|
|||
4*3 + //time.Time
|
||||
3*2 + // arrays
|
||||
// string arrays
|
||||
len(u.Username) + len(u.Password) + len(u.Email) + len(u.APIToken) + len(u.MD5) + len(u.Language)
|
||||
len(u.Username) + len(u.Password) + len(u.Email) + len(u.APIToken) + len(u.MD5) + len(u.Language) + len(u.Theme)
|
||||
s *= 8
|
||||
|
||||
// Ignoring foreign key users. Fuck them.
|
||||
|
|
|
@ -115,7 +115,7 @@ select.form-input {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.form-input.search-box { margin-right: -20px; }
|
||||
.form-input.search-box { margin-right: -20px; padding-right: 20px; }
|
||||
.form-input.search-box + .search-icon {
|
||||
left: -5px;
|
||||
position: relative;
|
||||
|
@ -221,8 +221,8 @@ select.form-input {
|
|||
.results { padding: 0 }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse:collapse;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ th { border-bottom-width: 2px; }
|
|||
.tr-size { width: 90px; }
|
||||
.tr-se, .tr-le { font-weight: bold; }
|
||||
.tr-se, .tr-le, .tr-dl { width: 50px; }
|
||||
.tr-date { width: 90px; }
|
||||
.tr-date { width: 100px; }
|
||||
|
||||
.sort-arrows { margin-left: 0.2rem; }
|
||||
.sort-arrows span {
|
||||
|
@ -278,8 +278,8 @@ th { border-bottom-width: 2px; }
|
|||
min-width: 35px;
|
||||
}
|
||||
|
||||
.pagination li:first-child { border-radius: 3px 0 0 3px; }
|
||||
.pagination li:nth-last-child(2) { border-radius: 0 3px 3px 0; border-right-width: 1px !important}
|
||||
.pagination a:first-child li { border-radius: 3px 0 0 3px; }
|
||||
.pagination a:nth-last-child(2) li { border-radius: 0 3px 3px 0; border-right-width: 1px !important}
|
||||
|
||||
|
||||
#footer { width: 100%; bottom: 0; left: 0; margin-top: 40px;}
|
||||
|
@ -287,6 +287,8 @@ th { border-bottom-width: 2px; }
|
|||
.footer {
|
||||
text-align: center;
|
||||
padding: 1rem 0 1.2rem 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.footer-opt {
|
||||
|
@ -376,7 +378,7 @@ a:hover { color: #238BC7; }
|
|||
|
||||
.form-input { border-color: #BBC9CF !important; background: #fafafa; color: #666; }
|
||||
|
||||
.form-input.btn:hover { background: rgba(192,192,192,0.2); }
|
||||
.btn:hover, .up-btn:hover { background: rgba(192,192,192,0.2); }
|
||||
|
||||
.form-input:focus { box-shadow: 0 0 5px #fff; }
|
||||
|
||||
|
@ -468,7 +470,7 @@ td.tr-le { color: #E84C4C; }
|
|||
font-weight: bold;
|
||||
}
|
||||
.torrent-info-data {
|
||||
width: 60%;
|
||||
width: 50%;
|
||||
}
|
||||
.torrent-info-row {
|
||||
text-align: left;
|
||||
|
@ -518,6 +520,10 @@ td.tr-le { color: #E84C4C; }
|
|||
}
|
||||
.profile-content {
|
||||
width: 70%;
|
||||
text-align: left;
|
||||
}
|
||||
div.profile-content.box > nav > ul > li {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
.magnet-icon {
|
||||
display: inline-block;
|
||||
|
@ -589,6 +595,9 @@ input#show-filelist:checked ~ #filelist {
|
|||
#filelist tr {
|
||||
background: none; /* Striped lines will look really ugly due to how it's drawn */
|
||||
}
|
||||
.table-filelist {
|
||||
width: 100%;
|
||||
}
|
||||
.tr-filelist {
|
||||
--nest-level: 0;
|
||||
}
|
||||
|
@ -610,7 +619,7 @@ input#show-filelist:checked ~ #filelist {
|
|||
}
|
||||
/* Filesize column */
|
||||
.tr-filelist td:nth-child(2) {
|
||||
width: 30%;
|
||||
width: 20%;
|
||||
text-align: center;
|
||||
}
|
||||
/* Input that show/hides each folder */
|
||||
|
|
|
@ -11,6 +11,40 @@ function toggleNightMode() {
|
|||
localStorage.setItem("night", (night == "true") ? "false" : "true");
|
||||
}
|
||||
|
||||
// Switches between themes when a new one is selected
|
||||
function switchThemes(){
|
||||
themeName = document.getElementById("theme-selector").value
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
// Remove the theme in place, it fails if one isn't set
|
||||
try{
|
||||
head.removeChild(document.getElementById("theme"));
|
||||
} catch(err){}
|
||||
// Don't add a node if we don't want extra styling
|
||||
if(themeName === ""){
|
||||
return;
|
||||
}
|
||||
// Create the new one and put it back
|
||||
var newTheme = document.createElement("link");
|
||||
newTheme.setAttribute("rel", "stylesheet");
|
||||
newTheme.setAttribute("href", "/css/"+ themeName + ".css");
|
||||
newTheme.setAttribute("id", "theme");
|
||||
head.appendChild(newTheme);
|
||||
}
|
||||
|
||||
|
||||
function toggleMascot(btn) {
|
||||
var state= btn.value;
|
||||
if (state == "hide") {
|
||||
btn.innerHTML = "Mascot";
|
||||
document.getElementById("mascot").className = "hide";
|
||||
btn.value = "show";
|
||||
} else {
|
||||
btn.innerHTML = "Mascot";
|
||||
document.getElementById("mascot").className = "";
|
||||
btn.value = "hide";
|
||||
}
|
||||
}
|
||||
|
||||
// Used by spoiler tags
|
||||
function toggleLayer(elem) {
|
||||
if (elem.classList.contains("hide"))
|
||||
|
@ -21,7 +55,7 @@ function toggleLayer(elem) {
|
|||
|
||||
// Date formatting
|
||||
var lang = document.getElementsByTagName("html")[0].getAttribute("lang");
|
||||
var ymdOpt = { year: "numeric", month: "2-digit", day: "2-digit" };
|
||||
var ymdOpt = { year: "numeric", month: "short", day: "numeric" };
|
||||
var hmOpt = { hour: "numeric", minute: "numeric" };
|
||||
|
||||
var list = document.getElementsByClassName("date-short");
|
||||
|
@ -42,16 +76,24 @@ window.onload = function() {
|
|||
var shiftWindow = function() { scrollBy(0, -70) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
document.getElementsByClassName("search-box")[0].addEventListener("focus", function (e) {
|
||||
var w = document.getElementsByClassName("h-user")[0].offsetWidth;
|
||||
document.getElementsByClassName("h-user")[0].style.display = "none";
|
||||
document.getElementsByClassName("search-box")[0].style.width = document.getElementsByClassName("search-box")[0].offsetWidth + w + "px";
|
||||
});
|
||||
document.getElementsByClassName("search-box")[0].addEventListener("blur", function (e) {
|
||||
document.getElementsByClassName("search-box")[0].style.width = "";
|
||||
document.getElementsByClassName("h-user")[0].style.display = "inline-block";
|
||||
});
|
||||
};
|
||||
|
||||
function playVoice() {
|
||||
switch (theme) {
|
||||
case "tomorrow.css":
|
||||
if (explosion) {
|
||||
explosion.play();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else {
|
||||
nyanpassu.volume = 0.5;
|
||||
nyanpassu.play();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,13 +3,14 @@ package router
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
"html"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
|
@ -172,6 +173,8 @@ func APIUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
upload.Category, _ = strconv.Atoi(r.FormValue("category"))
|
||||
upload.SubCategory, _ = strconv.Atoi(r.FormValue("sub_category"))
|
||||
upload.Description = r.FormValue("description")
|
||||
upload.Remake, _ = strconv.ParseBool(r.FormValue("remake"))
|
||||
upload.WebsiteLink = r.FormValue("website_link")
|
||||
|
||||
var err error
|
||||
var code int
|
||||
|
@ -197,14 +200,22 @@ func APIUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Name: upload.Name,
|
||||
Category: upload.Category,
|
||||
SubCategory: upload.SubCategory,
|
||||
Status: 1,
|
||||
Status: model.TorrentStatusNormal,
|
||||
Hash: upload.Hash,
|
||||
Date: time.Now(),
|
||||
Filesize: filesize,
|
||||
Description: upload.Description,
|
||||
UploaderID: user.ID,
|
||||
Uploader: &user,
|
||||
WebsiteLink: upload.WebsiteLink,
|
||||
}
|
||||
|
||||
if upload.Remake {
|
||||
torrent.Status = model.TorrentStatusRemake
|
||||
} else if user.IsTrusted() {
|
||||
torrent.Status = model.TorrentStatusTrusted
|
||||
}
|
||||
|
||||
db.ORM.Create(&torrent)
|
||||
|
||||
client, err := elastic.NewClient()
|
||||
|
|
|
@ -275,6 +275,7 @@ func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
uploadForm.Name = torrentJSON.Name
|
||||
uploadForm.Category = torrentJSON.Category + "_" + torrentJSON.SubCategory
|
||||
uploadForm.Status = torrentJSON.Status
|
||||
uploadForm.Hidden = torrent.Hidden
|
||||
uploadForm.WebsiteLink = string(torrentJSON.WebsiteLink)
|
||||
uploadForm.Description = string(torrentJSON.Description)
|
||||
htv := formTemplateVariables{newPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
|
@ -300,6 +301,7 @@ func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
torrent.Category = uploadForm.CategoryID
|
||||
torrent.SubCategory = uploadForm.SubCategoryID
|
||||
torrent.Status = uploadForm.Status
|
||||
torrent.Hidden = uploadForm.Hidden
|
||||
torrent.WebsiteLink = uploadForm.WebsiteLink
|
||||
torrent.Description = uploadForm.Description
|
||||
// torrent.Uploader = nil // GORM will create a new user otherwise (wtf?!)
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/NyaaPantsu/nyaa/util/timeHelper"
|
||||
)
|
||||
|
||||
|
@ -15,11 +15,10 @@ type LanguagesJSONResponse struct {
|
|||
Languages map[string]string `json:"languages"`
|
||||
}
|
||||
|
||||
// SeeLanguagesHandler : Controller to view the languages
|
||||
func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
_, Tlang := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
|
||||
// SeePublicSettingsHandler : Controller to view the languages and themes
|
||||
func SeePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
_, Tlang := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
availableLanguages := publicSettings.GetAvailableLanguages()
|
||||
defer r.Body.Close()
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if contentType == "application/json" {
|
||||
|
@ -35,7 +34,7 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Language: Tlang.Tag,
|
||||
Languages: availableLanguages,
|
||||
}
|
||||
err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv)
|
||||
err := changePublicSettingsTemplate.ExecuteTemplate(w, "index.html", clv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -43,25 +42,29 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// ChangeLanguageHandler : Controller for changing the current language
|
||||
func ChangeLanguageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// ChangePublicSettingsHandler : Controller for changing the current language and theme
|
||||
func ChangePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
theme := r.FormValue("theme")
|
||||
lang := r.FormValue("language")
|
||||
|
||||
availableLanguages := publicSettings.GetAvailableLanguages()
|
||||
defer r.Body.Close()
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
if _, exists := availableLanguages[lang]; !exists {
|
||||
http.Error(w, "Language not available", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// If logged in, update user language; if not, set cookie.
|
||||
// If logged in, update user language.
|
||||
user, _ := userService.CurrentUser(r)
|
||||
if user.ID > 0 {
|
||||
user.Language = lang
|
||||
user.Theme = theme
|
||||
// I don't know if I should use this...
|
||||
userService.UpdateUserCore(&user)
|
||||
}
|
||||
// Set cookie
|
||||
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang, Expires: timeHelper.FewDaysLater(365)})
|
||||
http.SetCookie(w, &http.Cookie{Name: "theme", Value: theme, Expires: timeHelper.FewDaysLater(365)})
|
||||
|
||||
url, _ := Router.Get("home").URL()
|
||||
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
|
@ -29,6 +29,7 @@ func init() {
|
|||
gzipUserProfileHandler := http.HandlerFunc(UserProfileHandler)
|
||||
gzipUserAPIKeyResetHandler := http.HandlerFunc(UserAPIKeyResetHandler)
|
||||
gzipUserDetailsHandler := http.HandlerFunc(UserDetailsHandler)
|
||||
downloadTorrentHandler := http.HandlerFunc(DownloadTorrent)
|
||||
gzipUserProfileFormHandler := http.HandlerFunc(UserProfileFormHandler)
|
||||
gzipUserNotificationsHandler := http.HandlerFunc(UserNotificationsHandler)
|
||||
gzipDumpsHandler := handlers.CompressHandler(dumpsHandler)
|
||||
|
@ -78,6 +79,9 @@ func init() {
|
|||
Router.HandleFunc("/user/{id}/{username}/feed", RSSHandler).Name("feed_user")
|
||||
Router.HandleFunc("/user/{id}/{username}/feed/{page}", RSSHandler).Name("feed_user_page")
|
||||
|
||||
// !!! This line need to have the same download location as the one define in config.TorrentStorageLink !!!
|
||||
Router.Handle("/download/{hash}", wrapHandler(downloadTorrentHandler)).Name("torrent_download")
|
||||
|
||||
// INFO Everything under /mod should be wrapped by wrapModHandler. This make
|
||||
// sure the page is only accessible by moderators
|
||||
// TODO Find a native mux way to add a 'prehook' for route /mod
|
||||
|
@ -114,8 +118,8 @@ func init() {
|
|||
|
||||
Router.Handle("/dumps", gzipDatabaseDumpHandler).Name("dump").Methods("GET")
|
||||
|
||||
Router.HandleFunc("/language", SeeLanguagesHandler).Methods("GET").Name("see_languages")
|
||||
Router.HandleFunc("/language", ChangeLanguageHandler).Methods("POST").Name("change_language")
|
||||
Router.HandleFunc("/settings", SeePublicSettingsHandler).Methods("GET").Name("see_languages")
|
||||
Router.HandleFunc("/settings", ChangePublicSettingsHandler).Methods("POST").Name("see_languages")
|
||||
|
||||
Router.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var homeTemplate,
|
|||
viewUserDeleteTemplate,
|
||||
userTorrentEd,
|
||||
notFoundTemplate,
|
||||
changeLanguageTemplate,
|
||||
changePublicSettingsTemplate,
|
||||
databaseDumpTemplate *template.Template
|
||||
|
||||
var panelIndex,
|
||||
|
@ -128,10 +128,11 @@ func ReloadTemplates() {
|
|||
file: "404.html",
|
||||
},
|
||||
{
|
||||
templ: &changeLanguageTemplate,
|
||||
name: "change_language",
|
||||
file: "change_language.html",
|
||||
templ: &changePublicSettingsTemplate,
|
||||
name: "change_settings",
|
||||
file: "public_settings.html",
|
||||
},
|
||||
|
||||
}
|
||||
for idx := range pubTempls {
|
||||
pubTempls[idx].indexFile = filepath.Join(TemplateDir, "index.html")
|
||||
|
|
|
@ -12,12 +12,12 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/util"
|
||||
"github.com/NyaaPantsu/nyaa/util/categories"
|
||||
"github.com/NyaaPantsu/nyaa/util/filelist"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
)
|
||||
|
||||
type captchaData struct {
|
||||
CaptchaID string
|
||||
T languages.TemplateTfunc
|
||||
T publicSettings.TemplateTfunc
|
||||
}
|
||||
|
||||
// FuncMap : Functions accessible in templates by {{ $.Function }}
|
||||
|
@ -146,7 +146,7 @@ var FuncMap = template.FuncMap{
|
|||
return template.HTML(ret)
|
||||
},
|
||||
"Sukebei": config.IsSukebei,
|
||||
"getDefaultLanguage": languages.GetDefaultLanguage,
|
||||
"getDefaultLanguage": publicSettings.GetDefaultLanguage,
|
||||
"getAvatar": func(hash string, size int) string {
|
||||
return "https://www.gravatar.com/avatar/" + hash + "?s=" + strconv.Itoa(size)
|
||||
},
|
||||
|
@ -180,23 +180,23 @@ var FuncMap = template.FuncMap{
|
|||
}
|
||||
return ""
|
||||
},
|
||||
"fileSize": func(filesize int64, T languages.TemplateTfunc) template.HTML {
|
||||
"fileSize": func(filesize int64, T publicSettings.TemplateTfunc) template.HTML {
|
||||
if filesize == 0 {
|
||||
return T("unknown")
|
||||
}
|
||||
return template.HTML(util.FormatFilesize(filesize))
|
||||
},
|
||||
"makeCaptchaData": func(captchaID string, T languages.TemplateTfunc) captchaData {
|
||||
"makeCaptchaData": func(captchaID string, T publicSettings.TemplateTfunc) captchaData {
|
||||
return captchaData{captchaID, T}
|
||||
},
|
||||
"DefaultUserSettings": func(s string) bool {
|
||||
return config.DefaultUserSettings[s]
|
||||
},
|
||||
"makeTreeViewData": func(f *filelist.FileListFolder, nestLevel int, T languages.TemplateTfunc, identifierChain string) interface{} {
|
||||
"makeTreeViewData": func(f *filelist.FileListFolder, nestLevel int, T publicSettings.TemplateTfunc, identifierChain string) interface{} {
|
||||
return struct{
|
||||
Folder *filelist.FileListFolder
|
||||
NestLevel int
|
||||
T languages.TemplateTfunc
|
||||
T publicSettings.TemplateTfunc
|
||||
IdentifierChain string
|
||||
}{ f, nestLevel, T, identifierChain }
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
userForms "github.com/NyaaPantsu/nyaa/service/user/form"
|
||||
"github.com/NyaaPantsu/nyaa/util/filelist"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
|
@ -74,6 +74,12 @@ type changeLanguageVariables struct {
|
|||
Languages map[string]string
|
||||
}
|
||||
|
||||
type publicSettingsVariables struct {
|
||||
commonTemplateVariables
|
||||
Language string
|
||||
Languages map[string]string
|
||||
}
|
||||
|
||||
/* MODERATION Variables */
|
||||
|
||||
type panelIndexVbs struct {
|
||||
|
@ -91,7 +97,8 @@ type panelIndexVbs struct {
|
|||
type commonTemplateVariables struct {
|
||||
Navigation navigation
|
||||
Search searchForm
|
||||
T languages.TemplateTfunc
|
||||
T publicSettings.TemplateTfunc
|
||||
Theme string
|
||||
User *model.User
|
||||
URL *url.URL // for parsing URL in templates
|
||||
Route *mux.Route // for getting current route in templates
|
||||
|
@ -140,7 +147,8 @@ func newCommonVariables(r *http.Request) commonTemplateVariables {
|
|||
return commonTemplateVariables{
|
||||
Navigation: newNavigation(),
|
||||
Search: newSearchForm(),
|
||||
T: languages.GetTfuncFromRequest(r),
|
||||
T: publicSettings.GetTfuncFromRequest(r),
|
||||
Theme: publicSettings.GetThemeFromRequest(r),
|
||||
User: getUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
|
|
|
@ -38,6 +38,7 @@ type uploadForm struct {
|
|||
Remake bool
|
||||
Description string
|
||||
Status int
|
||||
Hidden bool
|
||||
CaptchaID string
|
||||
WebsiteLink string
|
||||
|
||||
|
@ -61,6 +62,7 @@ const uploadFormRemake = "remake"
|
|||
const uploadFormDescription = "desc"
|
||||
const uploadFormWebsiteLink = "website_link"
|
||||
const uploadFormStatus = "status"
|
||||
const uploadFormHidden = "hidden"
|
||||
|
||||
// error indicating that you can't send both a magnet link and torrent
|
||||
var errTorrentPlusMagnet = errors.New("Upload either a torrent file or magnet link, not both")
|
||||
|
@ -77,7 +79,7 @@ var errInvalidTorrentName = errors.New("Torrent name is invalid")
|
|||
// error indicating a torrent's description is invalid
|
||||
var errInvalidTorrentDescription = errors.New("Torrent description is invalid")
|
||||
|
||||
// error indicating a torrent's description is invalid
|
||||
// error indicating a torrent's website link is invalid
|
||||
var errInvalidWebsiteLink = errors.New("Website url or IRC link is invalid")
|
||||
|
||||
// error indicating a torrent's category is invalid
|
||||
|
@ -97,6 +99,7 @@ func (f *uploadForm) ExtractInfo(r *http.Request) error {
|
|||
f.Status, _ = strconv.Atoi(r.FormValue(uploadFormStatus))
|
||||
f.Magnet = r.FormValue(uploadFormMagnet)
|
||||
f.Remake = r.FormValue(uploadFormRemake) == "on"
|
||||
f.Hidden = r.FormValue(uploadFormHidden) == "on"
|
||||
|
||||
// trim whitespace
|
||||
f.Name = util.TrimWhitespaces(f.Name)
|
||||
|
@ -242,6 +245,7 @@ func (f *uploadForm) ExtractEditInfo(r *http.Request) error {
|
|||
f.Category = r.FormValue(uploadFormCategory)
|
||||
f.WebsiteLink = r.FormValue(uploadFormWebsiteLink)
|
||||
f.Description = r.FormValue(uploadFormDescription)
|
||||
f.Hidden = r.FormValue(uploadFormHidden) == "on"
|
||||
f.Status, _ = strconv.Atoi(r.FormValue(uploadFormStatus))
|
||||
|
||||
// trim whitespace
|
||||
|
|
|
@ -2,11 +2,12 @@ package router
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
|
@ -16,9 +17,9 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/upload"
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
)
|
||||
|
||||
// UploadHandler : Main Controller for uploading a torrent
|
||||
|
@ -80,6 +81,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Category: uploadForm.CategoryID,
|
||||
SubCategory: uploadForm.SubCategoryID,
|
||||
Status: status,
|
||||
Hidden: uploadForm.Hidden,
|
||||
Hash: uploadForm.Infohash,
|
||||
Date: time.Now(),
|
||||
Filesize: uploadForm.Filesize,
|
||||
|
@ -109,7 +111,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
for _, follower := range user.Followers {
|
||||
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
|
||||
T, _, _ := publicSettings.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"))
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/user/form"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util/crypto"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"github.com/NyaaPantsu/nyaa/util/modelHelper"
|
||||
"github.com/gorilla/mux"
|
||||
|
@ -72,7 +72,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
defer r.Body.Close()
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
messages := msg.GetMessages(r)
|
||||
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
|
@ -125,7 +125,7 @@ func UserDetailsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
|
||||
b := form.UserForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
availableLanguages := publicSettings.GetAvailableLanguages()
|
||||
userProfile.ParseSettings()
|
||||
htv := userProfileEditVariables{newCommonVariables(r), &userProfile, b, messages.GetAllErrors(), messages.GetAllInfos(), availableLanguages}
|
||||
err := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
|
@ -154,7 +154,7 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
userForm := form.UserForm{}
|
||||
userSettingsForm := form.UserSettingsForm{}
|
||||
|
||||
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
form.EmailValidation(r.PostFormValue("email"), messages)
|
||||
|
@ -189,7 +189,7 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
}
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
availableLanguages := publicSettings.GetAvailableLanguages()
|
||||
upev := userProfileEditVariables{
|
||||
commonTemplateVariables: newCommonVariables(r),
|
||||
UserProfile: &userProfile,
|
||||
|
@ -325,7 +325,7 @@ func UserNotificationsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
currentUser := getUser(r)
|
||||
if currentUser.ID > 0 {
|
||||
messages := msg.GetMessages(r)
|
||||
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
if r.URL.Query()["clear"] != nil {
|
||||
notifierService.DeleteAllNotifications(currentUser.ID)
|
||||
messages.AddInfo("infos", Ts("notifications_cleared"))
|
||||
|
@ -348,7 +348,7 @@ func UserAPIKeyResetHandler(w http.ResponseWriter, r *http.Request) {
|
|||
id := vars["id"]
|
||||
currentUser := getUser(r)
|
||||
|
||||
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
messages := msg.GetMessages(r)
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if errorUser != nil || !userPermission.CurrentOrAdmin(currentUser, userProfile.ID) || userProfile.ID == 0 {
|
||||
|
|
|
@ -2,11 +2,15 @@ package router
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/service"
|
||||
|
@ -17,9 +21,9 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util"
|
||||
"github.com/NyaaPantsu/nyaa/util/filelist"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/log"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
|
@ -113,7 +117,7 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
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
|
||||
T, _, _ := publicSettings.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"))
|
||||
}
|
||||
|
||||
|
@ -170,6 +174,7 @@ func TorrentEditUserPanel(w http.ResponseWriter, r *http.Request) {
|
|||
uploadForm.Remake = torrent.Status == model.TorrentStatusRemake
|
||||
uploadForm.WebsiteLink = string(torrent.WebsiteLink)
|
||||
uploadForm.Description = string(torrent.Description)
|
||||
uploadForm.Hidden = torrent.Hidden
|
||||
htv := formTemplateVariables{newCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
|
||||
err := userTorrentEd.ExecuteTemplate(w, "index.html", htv)
|
||||
log.CheckError(err)
|
||||
|
@ -204,6 +209,7 @@ func TorrentPostEditUserPanel(w http.ResponseWriter, r *http.Request) {
|
|||
torrent.Category = uploadForm.CategoryID
|
||||
torrent.SubCategory = uploadForm.SubCategoryID
|
||||
torrent.Status = status
|
||||
torrent.Hidden = uploadForm.Hidden
|
||||
torrent.WebsiteLink = uploadForm.WebsiteLink
|
||||
torrent.Description = uploadForm.Description
|
||||
// torrent.Uploader = nil // GORM will create a new user otherwise (wtf?!)
|
||||
|
@ -240,3 +246,46 @@ func TorrentDeleteUserPanel(w http.ResponseWriter, r *http.Request) {
|
|||
NotFoundHandler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// DownloadTorrent : Controller for downloading a torrent
|
||||
func DownloadTorrent(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
vars := mux.Vars(r)
|
||||
hash := vars["hash"]
|
||||
|
||||
if hash == "" && len(config.TorrentFileStorage) == 0 {
|
||||
//File not found, send 404
|
||||
http.Error(w, "File not found.", 404)
|
||||
return
|
||||
}
|
||||
|
||||
//Check if file exists and open
|
||||
Openfile, err := os.Open(fmt.Sprintf("%s%c%s.torrent", config.TorrentFileStorage, os.PathSeparator, hash))
|
||||
defer Openfile.Close() //Close after function return
|
||||
if err != nil {
|
||||
//File not found, send 404
|
||||
http.Error(w, "File not found.", 404)
|
||||
return
|
||||
}
|
||||
|
||||
//Get the file size
|
||||
FileStat, _ := Openfile.Stat() //Get info from file
|
||||
FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string
|
||||
|
||||
torrent, err := torrentService.GetRawTorrentByHash(hash)
|
||||
|
||||
if err != nil {
|
||||
//File not found, send 404
|
||||
http.Error(w, "File not found.", 404)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.torrent\"", torrent.Name))
|
||||
w.Header().Set("Content-Type", "application/x-bittorrent")
|
||||
w.Header().Set("Content-Length", FileSize)
|
||||
//Send the file
|
||||
// We reset the offset to 0
|
||||
Openfile.Seek(0, 0)
|
||||
io.Copy(w, Openfile) //'Copy' the file to the client
|
||||
return
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ type TorrentRequest struct {
|
|||
Magnet string `json:"magnet"`
|
||||
Hash string `json:"hash"`
|
||||
Description string `json:"description"`
|
||||
Remake bool `json:"remake"`
|
||||
WebsiteLink string `json:"website_link"`
|
||||
}
|
||||
|
||||
// UpdateRequest struct
|
||||
|
@ -94,6 +96,17 @@ func validateSubCategory(r *TorrentRequest) (error, int) {
|
|||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
func validateWebsiteLink(r *TorrentRequest) (error, int) {
|
||||
if r.WebsiteLink != "" {
|
||||
// WebsiteLink
|
||||
urlRegexp, _ := regexp.Compile(`^(https?:\/\/|ircs?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`)
|
||||
if !urlRegexp.MatchString(r.WebsiteLink) {
|
||||
return ErrWebsiteLink, http.StatusNotAcceptable
|
||||
}
|
||||
}
|
||||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
func validateMagnet(r *TorrentRequest) (error, int) {
|
||||
magnetURL, err := url.Parse(string(r.Magnet)) //?
|
||||
if err != nil {
|
||||
|
@ -144,6 +157,7 @@ func (r *TorrentRequest) ValidateUpload() (err error, code int) {
|
|||
validateSubCategory,
|
||||
validateMagnet,
|
||||
validateHash,
|
||||
validateWebsiteLink,
|
||||
}
|
||||
|
||||
for i, validator := range validators {
|
||||
|
@ -206,6 +220,7 @@ func (r *TorrentRequest) ValidateUpdate() (err error, code int) {
|
|||
validateSubCategory,
|
||||
validateMagnet,
|
||||
validateHash,
|
||||
validateWebsiteLink,
|
||||
}
|
||||
|
||||
//don't update not requested values
|
||||
|
@ -243,4 +258,7 @@ func (r *UpdateRequest) UpdateTorrent(t *model.Torrent) {
|
|||
if r.Update.Description != "" {
|
||||
t.Description = r.Update.Description
|
||||
}
|
||||
if r.Update.WebsiteLink != "" {
|
||||
t.WebsiteLink = r.Update.WebsiteLink
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ var ErrCategory = errors.New("this category doesn't exist")
|
|||
// ErrSubCategory : Error for not found sub category used by api
|
||||
var ErrSubCategory = errors.New("this sub category doesn't exist")
|
||||
|
||||
// ErrWebsiteLink : error indicating a torrent's website link is invalid
|
||||
var ErrWebsiteLink = errors.New("website url or IRC link is invalid")
|
||||
|
||||
// ErrMagnet : Error for incorrect magnet used by api
|
||||
var ErrMagnet = errors.New("incorrect magnet")
|
||||
|
||||
|
|
|
@ -2,11 +2,12 @@ package torrentService
|
|||
|
||||
import (
|
||||
"errors"
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
elastic "gopkg.in/olivere/elastic.v5"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
|
@ -99,7 +100,17 @@ func GetTorrentByID(id string) (torrent model.Torrent, err error) {
|
|||
func GetRawTorrentByID(id uint) (torrent model.Torrent, err error) {
|
||||
err = nil
|
||||
if db.ORM.Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
|
||||
err = errors.New("Article is not found")
|
||||
err = errors.New("Torrent is not found")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetRawTorrentByHash : Get torrent with id without user or comments
|
||||
// won't fetch user or comments
|
||||
func GetRawTorrentByHash(hash string) (torrent model.Torrent, err error) {
|
||||
err = nil
|
||||
if db.ORM.Where("torrent_hash = ?", hash).Find(&torrent).RecordNotFound() {
|
||||
err = errors.New("Torrent is not found")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/util/email"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/NyaaPantsu/nyaa/util/timeHelper"
|
||||
"github.com/gorilla/securecookie"
|
||||
)
|
||||
|
@ -20,7 +20,7 @@ var verificationHandler = securecookie.New(config.EmailTokenHashKey, nil)
|
|||
|
||||
// SendEmailVerification sends an email verification token via email.
|
||||
func SendEmailVerification(to string, token string) error {
|
||||
T, err := languages.GetDefaultTfunc()
|
||||
T, err := publicSettings.GetDefaultTfunc()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
<div>
|
||||
<h1>{{call $.T "404_not_found"}}</h1>
|
||||
<br />
|
||||
<img class="center-block center-image" src="/img/404.svg"></img>
|
||||
<img class="center-block center-image" src="/img/404.svg" />
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<h2 id="trackers">{{call $.T "which_trackers_do_you_recommend"}}</h2>
|
||||
<p>{{call $.T "answer_which_trackers_do_you_recommend"}}</p>
|
||||
<pre>udp://tracker.doko.moe:6969
|
||||
udp://zer0day.to:1337/announce
|
||||
udp://tracker.zer0day.to:1337/announce
|
||||
udp://tracker.leechers-paradise.org:6969
|
||||
udp://explodie.org:6969
|
||||
udp://tracker.opentrackr.org:1337
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
<form role="form" method="POST">
|
||||
<label class="input-label">{{call $.T "api_token" }}:</label>
|
||||
<p style="font-family: monospace;">{{.APIToken}}</p>
|
||||
<a class="form-input" href="{{ genRoute "user_profile_apireset" "id" (print .ID) "username" .Username }}">Reset Api key</a> <br> <br>
|
||||
<a class="form-input up-input" href="{{ genRoute "user_profile_apireset" "id" (print .ID) "username" .Username }}">Reset Api key</a> <br> <br>
|
||||
<label class="input-label">{{ call $.T "email_address" }}:</label> <br>
|
||||
<input class="form-input" type="text" name="email" id="email" value="{{.Email}}"> <br>
|
||||
<input class="form-input up-input" type="text" name="email" id="email" value="{{.Email}}"> <br>
|
||||
{{ range (index $.FormErrors "email")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
<label class="input-label">{{ call $.T "language"}}:</label> <br>
|
||||
<select id="language" name="language" class="form-input">
|
||||
<select id="language" name="language" class="form-input up-input">
|
||||
{{ $userLanguage := .Language }}
|
||||
{{ range $tag, $translatedName := $.Languages }}
|
||||
<option value="{{ $tag }}" {{ if or (eq $userLanguage $tag) (and (eq $userLanguage "") (eq $tag getDefaultLanguage)) }}selected{{end}}>{{ $translatedName }} {{if eq $tag getDefaultLanguage}}({{ call $.T "default" }}){{end}}</option>
|
||||
|
@ -29,18 +29,18 @@
|
|||
{{end}}
|
||||
{{ if not (HasAdmin $.User)}}
|
||||
<label class="input-label">{{ call $.T "current_password"}}:</label> <br>
|
||||
<input class="form-input" name="current_password" id="current_password" type="password"> <br>
|
||||
<input class="form-input up-input up-input" name="current_password" id="current_password" type="password"> <br>
|
||||
{{ range (index $.FormErrors "current_password")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<label class="input-label">{{ call $.T "password"}}:</label> <br>
|
||||
<input class="form-input" name="password" id="password" type="password"> <br>
|
||||
<input class="form-input up-input up-input" name="password" id="password" type="password"> <br>
|
||||
{{ range (index $.FormErrors "password")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
<label class="input-label">{{ call $.T "confirm_password"}}:</label> <br>
|
||||
<input class="form-input" name="password_confirmation" id="password_confirmation" type="password"> <br>
|
||||
<input class="form-input up-input up-input" name="password_confirmation" id="password_confirmation" type="password"> <br>
|
||||
{{ range (index $.FormErrors "password_confirmation")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
|
@ -48,7 +48,7 @@
|
|||
{{ with .Settings }}
|
||||
{{ if DefaultUserSettings "new_torrent"}}
|
||||
<label class="input-label">{{ call $.T "new_torrent_settings" }}:</label> <br>
|
||||
<select id="new_torrent" name="new_torrent" class="form-control">
|
||||
<select id="new_torrent" name="new_torrent" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -58,7 +58,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_torrent_email"}}
|
||||
<label class="input-label">{{ call $.T "new_torrent_email_settings" }}:</label> <br>
|
||||
<select id="new_torrent_email" name="new_torrent_email" class="form-control">
|
||||
<select id="new_torrent_email" name="new_torrent_email" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -68,7 +68,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_comment"}}
|
||||
<label class="input-label">{{ call $.T "new_comment_settings" }}:</label> <br>
|
||||
<select id="new_comment" name="new_comment" class="form-control">
|
||||
<select id="new_comment" name="new_comment" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -78,7 +78,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_comment_email"}}
|
||||
<label class="input-label">{{ call $.T "new_comment_email_settings" }}:</label> <br>
|
||||
<select id="new_comment_email" name="new_comment_email" class="form-control">
|
||||
<select id="new_comment_email" name="new_comment_email" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -88,7 +88,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_responses"}}
|
||||
<label class="input-label">{{ call $.T "new_responses_settings" }}:</label> <br>
|
||||
<select id="new_responses" name="new_responses" class="form-control">
|
||||
<select id="new_responses" name="new_responses" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -98,7 +98,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_responses_email"}}
|
||||
<label class="input-label">{{ call $.T "new_responses_email_settings" }}:</label> <br>
|
||||
<select id="new_responses_email" name="new_responses_email" class="form-control">
|
||||
<select id="new_responses_email" name="new_responses_email" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -108,7 +108,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_follower"}}
|
||||
<label class="input-label">{{ call $.T "new_follower_settings" }}:</label> <br>
|
||||
<select id="new_follower" name="new_follower" class="form-control">
|
||||
<select id="new_follower" name="new_follower" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -118,7 +118,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "new_follower_email"}}
|
||||
<label class="input-label">{{ call $.T "new_follower_email_settings" }}:</label> <br>
|
||||
<select id="new_follower_email" name="new_follower_email" class="form-control">
|
||||
<select id="new_follower_email" name="new_follower_email" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -128,7 +128,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "followed"}}
|
||||
<label class="input-label">{{ call $.T "followed_settings" }}:</label> <br>
|
||||
<select id="followed" name="followed" class="form-control">
|
||||
<select id="followed" name="followed" class="form-input up-input">
|
||||
<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><br>
|
||||
|
@ -138,7 +138,7 @@
|
|||
{{end}}
|
||||
{{ if DefaultUserSettings "followed_email"}}
|
||||
<label class="input-label">{{ call $.T "followed_email_settings" }}:</label> <br>
|
||||
<select id="followed_email" name="followed_email" class="form-control">
|
||||
<select id="followed_email" name="followed_email" class="form-input up-input">
|
||||
<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> <br>
|
||||
|
@ -150,12 +150,12 @@
|
|||
{{ if HasAdmin $.User}}
|
||||
<h3>{{ call $.T "moderation"}}</h3>
|
||||
<label class="input-label">{{ call $.T "username"}}:</label> <br>
|
||||
<input class="form-control" name="username" id="username" type="text" value="{{.Username}}">
|
||||
<input class="form-input up-input" name="username" id="username" type="text" value="{{.Username}}">
|
||||
{{ range (index $.FormErrors "username")}}
|
||||
<p class="text-error">{{ . }}</p>
|
||||
{{end}}
|
||||
<label class="input-label">{{ call $.T "role" }}:</label>
|
||||
<select id="status" name="status" class="form-control">
|
||||
<select id="status" name="status" class="form-input up-input">
|
||||
<option value="-1" {{ if eq .Status -1 }}selected{{end}}>{{ call $.T "banned"}}</option>
|
||||
<option value="0" {{ if eq .Status 0 }}selected{{end}}>{{ call $.T "member"}} ({{ call $.T "default" }})</option>
|
||||
<option value="1" {{ if eq .Status 1 }}selected{{end}}>{{ call $.T "trusted_member"}}</option>
|
||||
|
@ -168,9 +168,9 @@
|
|||
{{end}}
|
||||
{{end}}
|
||||
<label class="input-label"></label>
|
||||
<input type="submit" class="btn btn-primary" name="save" value="{{ call $.T "save_changes"}}">
|
||||
<input type="submit" class="form-input" name="save" value="{{ call $.T "save_changes"}}">
|
||||
<span></span>
|
||||
<input type="reset" class="btn btn-default" value="{{ call $.T "cancel"}}">
|
||||
<input type="reset" class="form-input" value="{{ call $.T "cancel"}}">
|
||||
</form>
|
||||
</div>
|
||||
{{ if CurrentOrAdmin $.User .ID }}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<td class="tr-size hide-xs">
|
||||
{{ fileSize .Filesize $.T }}
|
||||
</td>
|
||||
<td class="tr-date home-td date-short hide-xs">{{.Date}}</td>
|
||||
<td class="tr-date date-short hide-xs">{{.Date}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -32,7 +32,12 @@
|
|||
<option value="4" {{if eq .Status 4}}selected{{end}}>A+</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{ if $.User }}
|
||||
<p>
|
||||
<input type="checkbox" name="hidden" id="hidden" {{ if .Hidden }}checked{{end}}>
|
||||
<label for="hidden">{{call $.T "mark_as_hidden"}}</label>
|
||||
</p>
|
||||
{{ end }}
|
||||
<div class="form-group">
|
||||
<label for="website_link">{{call $.T "website_link"}}</label>
|
||||
<input name="website_link" id="website_link" class="form-control" type="text" value="{{.WebsiteLink}}">
|
||||
|
|
|
@ -12,24 +12,18 @@
|
|||
|
||||
<!-- RSS Feed with Context -->
|
||||
<link href="{{ block "rss_link" . }}{{ genRouteWithQuery "feed" .URL }}{{end}}" rel="alternate" type="application/rss+xml" title="Nyaa Pantsu - {{block "rsstitle" .}}Last torrents{{end}} RSS Feed" />
|
||||
|
||||
|
||||
<!-- do NOT move -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
|
||||
|
||||
<link rel="stylesheet" id="style" href="{{.URL.Parse "/css/main.css"}}?v=3">
|
||||
<link rel="stylesheet" id="theme" href="">
|
||||
<!-- Base theme -->
|
||||
<link rel="stylesheet" id="style" href="{{.URL.Parse "/css/main.css"}}?v=2">
|
||||
<!-- User selected theme, if any -->
|
||||
{{if $.Theme}}<link rel="stylesheet" id="theme" href="/css/{{$.Theme}}.css">{{end}}
|
||||
|
||||
<!-- Search Box for Google -->
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","url":"https://nyaa.pantsu.cat/","potentialAction":{"@type":"SearchAction","target":"https://nyaa.pantsu.cat/search?q={search_term_string}","query-input":"required name=search_term_string"}}</script>
|
||||
<script>
|
||||
// We need this inline javascript for preventing theme flickering
|
||||
function changeTheme(opt) {
|
||||
theme = opt.value;
|
||||
localStorage.setItem("theme", theme);
|
||||
document.getElementById("theme").href = "/css/" + theme;
|
||||
console.log(theme);
|
||||
}
|
||||
|
||||
function toggleMascot(btn) {
|
||||
var state= btn.value;
|
||||
if (state == "hide") {
|
||||
|
@ -42,24 +36,10 @@
|
|||
btn.value = "hide";
|
||||
}
|
||||
}
|
||||
function setTheme() {
|
||||
var themeFromStorage = localStorage.getItem('theme');
|
||||
document.getElementById('theme').href = "/css/" + themeFromStorage;
|
||||
window.addEventListener("load", () => {
|
||||
var selectOptions = document.getElementById("theme_select").children
|
||||
for (var option of selectOptions) {
|
||||
option.selected = option.value == themeFromStorage;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<!-- Fix theme switching for google chrome where onload doesn't work -->
|
||||
<script type="text/javascript">
|
||||
setTheme();
|
||||
</script>
|
||||
{{ block "additional_header" .}}{{end}}
|
||||
</head>
|
||||
<body onload="setTheme();">
|
||||
<body>
|
||||
<nav id="header" class="header">
|
||||
<div class="container">
|
||||
<div class="h-left">
|
||||
|
@ -93,14 +73,16 @@
|
|||
{{block "content" .}}{{call $.T "nothing_here"}}{{end}}
|
||||
</div>
|
||||
<div id="mascot" class="hide-xs" onclick="playVoice();"></div>
|
||||
{{ if eq .Theme "tomorrow" }}
|
||||
<audio id="explosion" hidden preload="none">
|
||||
<source src="https://megumin.love/sounds/explosion.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
{{ else }}
|
||||
<audio id="nyanpassu" hidden preload="none">
|
||||
<source src="https://a.doko.moe/sewang.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
<audio id="explosion" hidden preload="none">
|
||||
<source src="https://megumin.love/sounds/explosion.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
|
||||
<div class="pagination">
|
||||
{{end}}
|
||||
<div class="pagination">
|
||||
{{ genNav .Navigation .URL 15 }}
|
||||
</div>
|
||||
|
||||
|
@ -108,15 +90,8 @@
|
|||
<div class="container footer center">
|
||||
|
||||
<div class="footer-opt">
|
||||
<select onchange="changeTheme(this.options[this.selectedIndex])" name="Theme" id="theme_select" class="form-input">
|
||||
<option value="">Default</option>
|
||||
<option value="g.css">/g/ Anon</option>
|
||||
<option value="tomorrow.css">Tomorrow</option>
|
||||
</select>
|
||||
|
||||
<button class="form-input btn" onclick="toggleMascot(this)" value="hide"><span class="oi" data-glyph="eye"></span> Mascot</button>
|
||||
|
||||
<p><a href="/language">Change Language</a></p>
|
||||
<p><a href="/settings">Change Settings</a></p>
|
||||
</div>
|
||||
|
||||
<span><i>Powered by <a href="#">NyaaPantsu</a></i></span>
|
||||
|
|
|
@ -11,8 +11,18 @@
|
|||
<option value="{{ $tag }}" {{ if eq $currentLanguage $tag }}selected{{end}}>{{ $translatedName }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
<h3>{{call $.T "theme"}}</h3>
|
||||
<select id="theme-selector" name="theme" class="form-input" onchange="switchThemes()">
|
||||
<option value="{{$.Theme}}" selected>{{call $.T "select"}}</option>
|
||||
<option value="g">/g/</option>
|
||||
<option value="tomorrow">Tomorrow</option>
|
||||
<option value="">None</option>
|
||||
</select>
|
||||
</br>
|
||||
</br>
|
||||
<button type="submit" class="form-input btn">{{call $.T "save_changes"}}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div style="padding-bottom: 1em"></div>
|
||||
</div>
|
|
@ -8,7 +8,7 @@
|
|||
{{end}}
|
||||
|
||||
<h3>{{call $.T "name"}}</h3>
|
||||
<input type="text" name="name" id="name" class="form-input up-input" placeholder="{{call $.T "file_name"}}" value="{{.Name}}" autofocus required>
|
||||
<input type="text" name="name" id="name" class="form-input up-input" placeholder="{{call $.T "file_name"}}" value="{{.Name}}" autofocus>
|
||||
|
||||
<h3>{{call $.T "torrent_file"}}</h3>
|
||||
<input type="file" name="torrent" id="torrent" class="up-input" accept=".torrent">
|
||||
|
@ -29,7 +29,12 @@
|
|||
<input type="checkbox" name="remake" id="remake" >
|
||||
<label for="remake">{{call $.T "mark_as_remake"}}</label>
|
||||
</p>
|
||||
|
||||
{{ if $.User }}
|
||||
<p>
|
||||
<input type="checkbox" name="hidden" id="hidden" >
|
||||
<label for="hidden">{{call $.T "mark_as_hidden"}}</label>
|
||||
</p>
|
||||
{{ end }}
|
||||
<h3>{{call $.T "website_link"}}</h3>
|
||||
<input name="website_link" id="website_link" class="form-input up-input" type="text" value="{{.WebsiteLink}}">
|
||||
|
||||
|
|
|
@ -26,7 +26,12 @@
|
|||
<input type="checkbox" name="remake" id="remake" {{ if .Remake }}checked{{end}}>
|
||||
<label for="remake">{{call $.T "mark_as_remake"}}</label>
|
||||
</div>
|
||||
|
||||
{{ if $.User }}
|
||||
<p>
|
||||
<input type="checkbox" name="hidden" id="hidden" {{ if .Hidden }}checked{{end}}>
|
||||
<label for="hidden">{{call $.T "mark_as_hidden"}}</label>
|
||||
</p>
|
||||
{{ end }}
|
||||
<div class="form-group">
|
||||
<label for="website_link">{{call $.T "website_link"}}</label>
|
||||
<input name="website_link" id="website_link" class="form-control" type="text" value="{{.WebsiteLink}}">
|
||||
|
|
|
@ -43,15 +43,15 @@
|
|||
<table>
|
||||
<tr class="torrent-info-row">
|
||||
<td class="torrent-info-td torrent-info-label">{{ call $.T "category" }}:</td><td class="torrent-info-td torrent-info-data" style="padding:0"><a href="{{$.URL.Parse (printf "/search?c=%s_%s" .Category .SubCategory) }}">{{ if Sukebei}}{{ call $.T (CategoryName .Category .SubCategory) }}{{else}}{{ call $.T (CategoryName .Category .SubCategory) }}{{end}}</a> <br></td>
|
||||
<td class="torrent-info-td torrent-info-label">{{ call $.T "date" }}:</td><td class="torrent-info-td date-short">{{.Date}}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{ call $.T "date" }}:</td><td class="torrent-info-td date-full">{{.Date}}</td>
|
||||
</tr>
|
||||
<tr class="torrent-info-row">
|
||||
<td class="torrent-info-td torrent-info-label">{{ call $.T "uploaded_by" }}:</td><td class="torrent-view-td torrent-info-data"><a href="{{ genRoute "user_profile" "id" ( print .UploaderID ) "username" (print .UploaderName) }}">{{.UploaderName}}</a></td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "seeders"}}:</td><td class="torrent-info-td">{{if .LastScrape.IsZero}}{{call $.T "unknown"}}{{else}}{{.Seeders}}{{end}}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "seeders"}}:</td><td class="tr-se torrent-info-td">{{if .LastScrape.IsZero}}{{call $.T "unknown"}}{{else}}{{.Seeders}}{{end}}</td>
|
||||
</tr>
|
||||
<tr class="torrent-info-row">
|
||||
<td class="torrent-info-td torrent-info-label">{{ call $.T "website_link" }}:</td><td class="torrent-view-td torrent-info-data">{{if ne .WebsiteLink ""}}<a href="{{.WebsiteLink}}">{{.WebsiteLink}}</a>{{else}}<a href="//nyaa.pantsu.cat">nyaa.pantsu.cat{{end}}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "leechers"}}:</td><td class="torrent-info-td">{{if .LastScrape.IsZero}}{{call $.T "unknown"}}{{else}}{{.Leechers}}{{end}}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "leechers"}}:</td><td class="tr-le torrent-info-td">{{if .LastScrape.IsZero}}{{call $.T "unknown"}}{{else}}{{.Leechers}}{{end}}</td>
|
||||
</tr>
|
||||
<tr class="torrent-info-row">
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "hash"}}:</td><td style="font-family: monospace;" class="torrent-view-td torrent-info-data">{{.Hash}}</td>
|
||||
|
@ -59,12 +59,14 @@
|
|||
</tr>
|
||||
<tr class="torrent-info-row">
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "size"}}:</td><td class="torrent-view-td torrent-info-data">{{ fileSize .Filesize $.T }}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "last_scraped"}}</td><td class="torrent-info-td">{{if not .LastScrape.IsZero}}{{formatDateRFC .LastScrape}}{{else}}{{call $.T "unknown"}}{{end}}</td>
|
||||
<td class="torrent-info-td torrent-info-label">{{call $.T "last_scraped"}}</td><td class="torrent-info-td{{if not .LastScrape.IsZero}} date-full">{{formatDateRFC .LastScrape}}{{else}}">{{call $.T "unknown"}}{{end}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="torrent-buttons">
|
||||
<a href="{{.Magnet}}" class="form-input">{{call $.T "magnet_link"}}</a>
|
||||
{{ if ne .TorrentLink ""}}
|
||||
<a href="{{.TorrentLink}}" class="form-input">{{call $.T "torrent_file"}}</a>
|
||||
{{end}}
|
||||
{{ if gt $.User.ID 0}}
|
||||
<script>
|
||||
function reportPopup() {
|
||||
|
@ -97,9 +99,9 @@
|
|||
<div class="torrent-info-box" id="filelist">
|
||||
{{ if gt (len .FileList) 0 }}
|
||||
{{/* how do i concat lol */}}
|
||||
<table>
|
||||
<table class="table-filelist">
|
||||
<thead>
|
||||
<th style="width: 70%">{{call $.T "filename"}}</th>
|
||||
<th style="width: 80%">{{call $.T "filename"}}</th>
|
||||
<th>{{call $.T "size"}}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
|
@ -37,15 +37,15 @@
|
|||
},
|
||||
{
|
||||
"id": "email_address",
|
||||
"translation": "Adresse email"
|
||||
"translation": "Adresse email "
|
||||
},
|
||||
{
|
||||
"id": "password",
|
||||
"translation": "Mot de passe"
|
||||
"translation": "Mot de passe "
|
||||
},
|
||||
{
|
||||
"id": "confirm_password",
|
||||
"translation": "Confirmer le mot de passe"
|
||||
"translation": "Confirmer le mot de passe "
|
||||
},
|
||||
{
|
||||
"id": "i_agree",
|
||||
|
@ -141,7 +141,7 @@
|
|||
},
|
||||
{
|
||||
"id": "category",
|
||||
"translation": "Catégorie"
|
||||
"translation": "Catégorie "
|
||||
},
|
||||
{
|
||||
"id": "name",
|
||||
|
@ -149,7 +149,7 @@
|
|||
},
|
||||
{
|
||||
"id": "date",
|
||||
"translation": "Date"
|
||||
"translation": "Date "
|
||||
},
|
||||
{
|
||||
"id": "size",
|
||||
|
@ -537,11 +537,15 @@
|
|||
},
|
||||
{
|
||||
"id": "hash",
|
||||
"translation": "Info Hash"
|
||||
"translation": "Info Hash "
|
||||
},
|
||||
{
|
||||
"id": "description",
|
||||
"translation": "Description"
|
||||
},
|
||||
{
|
||||
"id": "no_description",
|
||||
"translation": "Aucune description disponible."
|
||||
},
|
||||
{
|
||||
"id": "comments",
|
||||
|
@ -565,11 +569,11 @@
|
|||
},
|
||||
{
|
||||
"id": "language",
|
||||
"translation": "Langue"
|
||||
"translation": "Langue "
|
||||
},
|
||||
{
|
||||
"id": "current_password",
|
||||
"translation": "Mot de passe actuel"
|
||||
"translation": "Mot de passe actuel "
|
||||
},
|
||||
{
|
||||
"id": "role",
|
||||
|
@ -593,7 +597,7 @@
|
|||
},
|
||||
{
|
||||
"id": "api_token",
|
||||
"translation": "Authentifieur d'API"
|
||||
"translation": "Authentifieur d'API "
|
||||
},
|
||||
{
|
||||
"id": "save_changes",
|
||||
|
@ -657,15 +661,15 @@
|
|||
},
|
||||
{
|
||||
"id": "seeders",
|
||||
"translation": "Seeders"
|
||||
"translation": "Seeders "
|
||||
},
|
||||
{
|
||||
"id": "leechers",
|
||||
"translation": "Leechers"
|
||||
"translation": "Leechers "
|
||||
},
|
||||
{
|
||||
"id": "completed",
|
||||
"translation": "Téléchargements"
|
||||
"translation": "Téléchargements "
|
||||
},
|
||||
{
|
||||
"id": "change_language",
|
||||
|
@ -685,19 +689,23 @@
|
|||
},
|
||||
{
|
||||
"id": "website_link",
|
||||
"translation": "Site web"
|
||||
"translation": "Site web "
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"translation": "Liste des fichiers"
|
||||
},
|
||||
{
|
||||
"id": "no_files",
|
||||
"translation": "Aucun fichier trouvé."
|
||||
},
|
||||
{
|
||||
"id": "filename",
|
||||
"translation": "Nom du fichier"
|
||||
},
|
||||
{
|
||||
"id": "uploaded_by",
|
||||
"translation": "Uploadé par"
|
||||
"translation": "Uploadé par "
|
||||
},
|
||||
{
|
||||
"id": "download_btn",
|
||||
|
@ -757,7 +765,7 @@
|
|||
},
|
||||
{
|
||||
"id": "last_scraped",
|
||||
"translation": "Dernier scrape : "
|
||||
"translation": "Dernier scrape :"
|
||||
},
|
||||
{
|
||||
"id": "server_status_link",
|
||||
|
|
|
@ -20,115 +20,115 @@
|
|||
"translation": "Kattints az alábbi linkre jelszavad visszaállításához."
|
||||
},
|
||||
{
|
||||
"id":"register_title",
|
||||
"id": "register_title",
|
||||
"translation": "Új felhasználói fiók létrehozása"
|
||||
},
|
||||
{
|
||||
"id":"signup_box_title",
|
||||
"id": "signup_box_title",
|
||||
"translation": "Kérlek Regisztrálj <small>Ingyenes, és mindig is az lesz.</small>"
|
||||
},
|
||||
{
|
||||
"id":"username",
|
||||
"id": "username",
|
||||
"translation": "Felhasználónév"
|
||||
},
|
||||
{
|
||||
"id":"email_address_or_username",
|
||||
"id": "email_address_or_username",
|
||||
"translation": "E-mail Cím vagy Felhasználónév"
|
||||
},
|
||||
{
|
||||
"id":"email_address",
|
||||
"id": "email_address",
|
||||
"translation": "E-mail Cím"
|
||||
},
|
||||
{
|
||||
"id":"password",
|
||||
"id": "password",
|
||||
"translation": "Jelszó"
|
||||
},
|
||||
{
|
||||
"id":"confirm_password",
|
||||
"id": "confirm_password",
|
||||
"translation": "Jelszó mégegyszer"
|
||||
},
|
||||
{
|
||||
"id":"i_agree",
|
||||
"id": "i_agree",
|
||||
"translation": "Beleegyezek"
|
||||
},
|
||||
{
|
||||
"id":"terms_conditions_confirm",
|
||||
"id": "terms_conditions_confirm",
|
||||
"translation": "A <strong class=\"label label-primary\">Regisztráció</strong>-ra kattintva beleegyezel az oldal <a href=\"#\" data-toggle=\"modal\" data-target=\"#t_and_c_m\">Felhasználási Feltételei</a>-be, és a Cookie-k használatába."
|
||||
},
|
||||
{
|
||||
"id":"signin",
|
||||
"id": "signin",
|
||||
"translation": "Bejelentkezés"
|
||||
},
|
||||
{
|
||||
"id":"register",
|
||||
"id": "register",
|
||||
"translation": "Regisztráció"
|
||||
},
|
||||
{
|
||||
"id":"terms_conditions",
|
||||
"id": "terms_conditions",
|
||||
"translation": "Felhasználási Feltételek"
|
||||
},
|
||||
{
|
||||
"id":"terms_conditions_full",
|
||||
"id": "terms_conditions_full",
|
||||
"translation": "Valami Szar."
|
||||
},
|
||||
{
|
||||
"id":"remember_me",
|
||||
"id": "remember_me",
|
||||
"translation": "Emlékezz Rám"
|
||||
},
|
||||
{
|
||||
"id":"forgot_password",
|
||||
"id": "forgot_password",
|
||||
"translation": "Elfelejtett Jelszó?"
|
||||
},
|
||||
{
|
||||
"id":"sign_in_box_title",
|
||||
"id": "sign_in_box_title",
|
||||
"translation": "Kérlek Jelentkezz Be"
|
||||
},
|
||||
{
|
||||
"id":"sign_in_title",
|
||||
"id": "sign_in_title",
|
||||
"translation": "Bejelentkezés"
|
||||
},
|
||||
{
|
||||
"id":"register_success_title",
|
||||
"id": "register_success_title",
|
||||
"translation": "Sikeres Regisztráció"
|
||||
},
|
||||
{
|
||||
"id":"sign_up_success",
|
||||
"id": "sign_up_success",
|
||||
"translation": "Köszönjük, hogy regisztráltál!"
|
||||
},
|
||||
{
|
||||
"id":"verify_success",
|
||||
"id": "verify_success",
|
||||
"translation": "<i style=\"color:limegreen\" class=\"glyphicon glyphicon-ok-circle\"></i>A felhasználói fiókod aktiválásra került."
|
||||
},
|
||||
{
|
||||
"id":"signup_verification_email",
|
||||
"id": "signup_verification_email",
|
||||
"translation": "Végezetül kérlek nézd meg a bejövő e-mailjeidet (a Spam mappát is!) az Ellenörző E-mail miatt."
|
||||
},
|
||||
{
|
||||
"id":"signup_verification_noemail",
|
||||
"id": "signup_verification_noemail",
|
||||
"translation": "Sikeres Regisztráció, mostmár használhatod a felhasználói fiókodat."
|
||||
},
|
||||
{
|
||||
"id":"settings",
|
||||
"id": "settings",
|
||||
"translation": "Fiók Beállításai"
|
||||
},
|
||||
{
|
||||
"id":"torrents",
|
||||
"id": "torrents",
|
||||
"translation": "Torrentek"
|
||||
},
|
||||
{
|
||||
"id":"follow",
|
||||
"id": "follow",
|
||||
"translation": "Követés"
|
||||
},
|
||||
{
|
||||
"id":"profile_page",
|
||||
"id": "profile_page",
|
||||
"translation": "%s Profilja"
|
||||
},
|
||||
{
|
||||
"id":"see_more_torrents_from",
|
||||
"id": "see_more_torrents_from",
|
||||
"translation": "További torrentek megtekintése %s-től "
|
||||
},
|
||||
{
|
||||
"id":"category",
|
||||
"id": "category",
|
||||
"translation": "Kategória"
|
||||
},
|
||||
{
|
||||
|
@ -610,5 +610,293 @@
|
|||
{
|
||||
"id": "language_code",
|
||||
"translation": "hu-hu"
|
||||
},
|
||||
{
|
||||
"id": "delete",
|
||||
"translation": "Törlés"
|
||||
},
|
||||
{
|
||||
"id": "website_link",
|
||||
"translation": "Oldal linkje"
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"translation": "Fájlok"
|
||||
},
|
||||
{
|
||||
"id": "no_files",
|
||||
"translation": "Nincsenek meg a fájlok? Na, az meg hogy lehet?"
|
||||
},
|
||||
{
|
||||
"id": "filename",
|
||||
"translation": "Fájlnév"
|
||||
},
|
||||
{
|
||||
"id": "uploaded_by",
|
||||
"translation": "Feltöltötte: "
|
||||
},
|
||||
{
|
||||
"id": "download_btn",
|
||||
"translation": "Letöltés!"
|
||||
},
|
||||
{
|
||||
"id": "report_btn",
|
||||
"translation": "Bejelentés"
|
||||
},
|
||||
{
|
||||
"id": "are_you_sure",
|
||||
"translation": "Biztos vagy benne?"
|
||||
},
|
||||
{
|
||||
"id": "report_torrent_number",
|
||||
"translation": "#%s számú torránt bejelentése"
|
||||
},
|
||||
{
|
||||
"id": "report_type",
|
||||
"translation": "Bejelentés jellege"
|
||||
},
|
||||
{
|
||||
"id": "illegal_content",
|
||||
"translation": "Illegális tartalom"
|
||||
},
|
||||
{
|
||||
"id": "spam_garbage",
|
||||
"translation": "Spam / Szemét"
|
||||
},
|
||||
{
|
||||
"id": "wrong_category",
|
||||
"translation": "Hibás kategória"
|
||||
},
|
||||
{
|
||||
"id": "duplicate_deprecated",
|
||||
"translation": "Másolat / elavult"
|
||||
},
|
||||
{
|
||||
"id": "captcha",
|
||||
"translation": "Captcha"
|
||||
},
|
||||
{
|
||||
"id": "file_name",
|
||||
"translation": "Fájlnév"
|
||||
},
|
||||
{
|
||||
"id": "cancel",
|
||||
"translation": "Mégse"
|
||||
},
|
||||
{
|
||||
"id": "please_include_our_tracker",
|
||||
"translation": "Kérlek a trackerek között add meg a udp://tracker.doko.moe:6969-et is."
|
||||
},
|
||||
{
|
||||
"id": "unknown",
|
||||
"translation": "Ismeretlen"
|
||||
},
|
||||
{
|
||||
"id": "last_scraped",
|
||||
"translation": "legutóbb kiselejtezett: "
|
||||
},
|
||||
{
|
||||
"id": "server_status_link",
|
||||
"translation": "Itt találhatod meg a szerver állapotát"
|
||||
},
|
||||
{
|
||||
"id": "no_database_dumps_available",
|
||||
"translation": "Jelenleg nincsenek adatbázis dumpok. "
|
||||
},
|
||||
{
|
||||
"id": "clear_notifications",
|
||||
"translation": "Értesítések törlése"
|
||||
},
|
||||
{
|
||||
"id": "notifications_cleared",
|
||||
"translation": "Értesítések törölve!"
|
||||
},
|
||||
{
|
||||
"id": "my_notifications",
|
||||
"translation": "Értesítéseim"
|
||||
},
|
||||
{
|
||||
"id": "new_torrent_uploaded",
|
||||
"translation": "Új torrent: \"%s\". Feltöltötte: %s"
|
||||
},
|
||||
{
|
||||
"id": "preferences",
|
||||
"translation": "Beállítások"
|
||||
},
|
||||
{
|
||||
"id": "new_torrent_settings",
|
||||
"translation": "Értesíts, ha egy követett felhasználó új torrentet tölt fel."
|
||||
},
|
||||
{
|
||||
"id": "new_torrent_email_settings",
|
||||
"translation": "Értesíts e-mailben, ha egy követett felhasználó új torrentet tölt fel."
|
||||
},
|
||||
{
|
||||
"id": "new_comment_settings",
|
||||
"translation": "Értesíts, ha a torrentemre új megjegyzés érkezik"
|
||||
},
|
||||
{
|
||||
"id": "new_comment_email_settings",
|
||||
"translation": "Értesíts e-mailben, ha a torrentemre új megjegyzés érkezik"
|
||||
},
|
||||
{
|
||||
"id": "new_responses_settings",
|
||||
"translation": "Értesíts, ha válasz érkezik az egyik megjegyzésemre"
|
||||
},
|
||||
{
|
||||
"id": "new_responses_email_settings",
|
||||
"translation": "Értesíts e-mailben, ha válasz érkezik az egyik megjegyzésemre"
|
||||
},
|
||||
{
|
||||
"id": "new_follower_settings",
|
||||
"translation": "Értesíts, ha valaki elkezd követni."
|
||||
},
|
||||
{
|
||||
"id": "new_follower_email_settings",
|
||||
"translation": "Értesíts e-mailban, ha valaki elkezd követni."
|
||||
},
|
||||
{
|
||||
"id": "followed_settings",
|
||||
"translation": "Értesíts, ha elkezdek valakit követni"
|
||||
},
|
||||
{
|
||||
"id": "followed_email_settings",
|
||||
"translation": "Értesíts e-mailben, ha elkezdek valakit követni"
|
||||
},
|
||||
{
|
||||
"id": "yes",
|
||||
"translation": "Igen"
|
||||
},
|
||||
{
|
||||
"id": "no",
|
||||
"translation": "Nem"
|
||||
},
|
||||
{
|
||||
"id": "new_comment_on_torrent",
|
||||
"translation": "Új komment a torrenten: \"%s\""
|
||||
},
|
||||
{
|
||||
"id": "no_action_selected",
|
||||
"translation": "Meg kell adnod, hogy mit akarsz csinálni a kijelöléssel."
|
||||
},
|
||||
{
|
||||
"id": "no_move_location_selected",
|
||||
"translation": "Té ném mégmondání hová vinni kijelulés"
|
||||
},
|
||||
{
|
||||
"id": "select_one_element",
|
||||
"translation": "Legalább egy elemet ki kell választanod"
|
||||
},
|
||||
{
|
||||
"id": "torrent_moved",
|
||||
"translation": "Torrent %s elmozdítva!"
|
||||
},
|
||||
{
|
||||
"id": "no_status_exist",
|
||||
"translation": "Nincs olyan állapot, hogy %d."
|
||||
},
|
||||
{
|
||||
"id": "torrent_deleted",
|
||||
"translation": "Torrent %s kitörölve!"
|
||||
},
|
||||
{
|
||||
"id": "no_action_exist",
|
||||
"translation": "Nincs olyan művelet, hogy %s."
|
||||
},
|
||||
{
|
||||
"id": "torrent_not_exist",
|
||||
"translation": "Nem létezik torrent %s azonosítóval."
|
||||
},
|
||||
{
|
||||
"id": "something_went_wrong",
|
||||
"translation": "Valami elromlott..."
|
||||
},
|
||||
{
|
||||
"id": "nb_torrents_updated",
|
||||
"translation": "%d torrent feltöltve."
|
||||
},
|
||||
{
|
||||
"id": "torrent_updated",
|
||||
"translation": "Torrent részletek frissítve."
|
||||
},
|
||||
{
|
||||
"id": "fail_torrent_update",
|
||||
"translation": "Nem sikerült frissíteni a torrentet."
|
||||
},
|
||||
{
|
||||
"id": "bad_captcha",
|
||||
"translation": "Hibás captcha."
|
||||
},
|
||||
{
|
||||
"id": "comment_empty",
|
||||
"translation": "Üres megjegyzés."
|
||||
},
|
||||
{
|
||||
"id": "no_owner_selected",
|
||||
"translation": "Szükség van egy új torrent tulajra."
|
||||
},
|
||||
{
|
||||
"id": "no_category_selected",
|
||||
"translation": "Nincs kijelölve kategória"
|
||||
},
|
||||
{
|
||||
"id": "no_user_found_id",
|
||||
"translation": "Az adatbázisban nincs felhasználó %d azonosítóval."
|
||||
},
|
||||
{
|
||||
"id": "invalid_torrent_category",
|
||||
"translation": "Ez a kategória nem létezik."
|
||||
},
|
||||
{
|
||||
"id": "torrent_owner_changed",
|
||||
"translation": "\"%s\" torrent tulaját sikeresen lecserélted."
|
||||
},
|
||||
{
|
||||
"id": "torrent_category_changed",
|
||||
"translation": "\"%s\" torrent kategóriájáját sikeresen megváltoztattad."
|
||||
},
|
||||
{
|
||||
"id": "torrent_reports_deleted",
|
||||
"translation": "\"%s\" torrent bejelentéseit sikeresen kitörölted."
|
||||
},
|
||||
{
|
||||
"id": "edit",
|
||||
"translation": "Szerkesztés"
|
||||
},
|
||||
{
|
||||
"id": "delete_definitely_torrent_warning",
|
||||
"translation": "A fájlokat nem leszel képes visszaszerezni, viszont másokat sem tudsz megállítani attól, hogy újra feltöltsék."
|
||||
},
|
||||
{
|
||||
"id": "delete_definitely",
|
||||
"translation": "Biztosan töröld."
|
||||
},
|
||||
{
|
||||
"id": "torrent_unblock",
|
||||
"translation": "Felnyitás"
|
||||
},
|
||||
{
|
||||
"id": "torrent_block",
|
||||
"translation": "Lezárás"
|
||||
},
|
||||
{
|
||||
"id": "torrent_deleted_definitely",
|
||||
"translation": "A torrent ki lett törölve az adatbázisról."
|
||||
},
|
||||
{
|
||||
"id": "torrent_unblocked",
|
||||
"translation": "A torrent fel van nyitva."
|
||||
},
|
||||
{
|
||||
"id": "torrent_blocked",
|
||||
"translation": "A torrent le van zárva."
|
||||
},
|
||||
{
|
||||
"id": "torrent_nav_notdeleted",
|
||||
"translation": "A Torrentek nincsenek törölve"
|
||||
},
|
||||
{
|
||||
"id": "torrent_nav_deleted",
|
||||
"translation": "A Torrentek törölve lettek"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
"github.com/gorilla/context"
|
||||
"github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
@ -24,13 +24,13 @@ type Messages struct {
|
|||
func GetMessages(r *http.Request) *Messages {
|
||||
if rv := context.Get(r, MessagesKey); rv != nil {
|
||||
mes := rv.(*Messages)
|
||||
T, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
T, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
mes.T = T
|
||||
mes.r = r
|
||||
return mes
|
||||
}
|
||||
context.Set(r, MessagesKey, &Messages{})
|
||||
T, _ := languages.GetTfuncAndLanguageFromRequest(r)
|
||||
T, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
|
||||
return &Messages{make(map[string][]string), make(map[string][]string), r, T}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package languages
|
||||
package publicSettings
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -133,6 +133,19 @@ func GetTfuncFromRequest(r *http.Request) TemplateTfunc {
|
|||
}
|
||||
}
|
||||
|
||||
// GetThemeFromRequest: Gets the user selected theme from the request
|
||||
func GetThemeFromRequest(r *http.Request) string {
|
||||
user, _ := getCurrentUser(r)
|
||||
if user.ID > 0 {
|
||||
return user.Theme
|
||||
}
|
||||
cookie, err := r.Cookie("theme")
|
||||
if err == nil {
|
||||
return cookie.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getCurrentUser(r *http.Request) (model.User, error) {
|
||||
if userRetriever == nil {
|
||||
return model.User{}, errors.New("failed to get current user: no user retriever set")
|
|
@ -1,4 +1,4 @@
|
|||
package languages
|
||||
package publicSettings
|
||||
|
||||
import (
|
||||
"path"
|
Référencer dans un nouveau ticket