Merge branch 'dev'
Cette révision appartient à :
révision
4e61605a30
|
@ -12,10 +12,12 @@ import (
|
|||
const (
|
||||
// LastOldTorrentID is the highest torrent ID
|
||||
// that was copied from the original Nyaa
|
||||
LastOldTorrentID = 923000
|
||||
TableName = "torrents"
|
||||
LastOldTorrentID = 923000
|
||||
TableName = "torrents"
|
||||
CommentsTableName = "comments"
|
||||
// for sukebei
|
||||
//TableName = "sukebei_torrents"
|
||||
//TableName = "sukebei_torrents"
|
||||
//CommentsTableName = "sukebei_comments"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/ewhal/nyaa/config"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -22,6 +23,10 @@ func (c Comment) Size() int {
|
|||
return (3 + 3*3 + 2 + 2 + len(c.Content)) * 8
|
||||
}
|
||||
|
||||
func (c Comment) TableName() string {
|
||||
return config.CommentsTableName
|
||||
}
|
||||
|
||||
type OldComment struct {
|
||||
TorrentID uint `gorm:"column:torrent_id"`
|
||||
Username string `gorm:"column:username"`
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeebo/bencode"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
ID uint `gorm:"column:file_id;primary_key"`
|
||||
TorrentID uint `gorm:"column:torrent_id;unique_index:idx_tid_path"`
|
||||
Path string `gorm:"column:path;unique_index:idx_tid_path"`
|
||||
Filesize int64 `gorm:"column:filesize"`
|
||||
ID uint `gorm:"column:file_id;primary_key"`
|
||||
TorrentID uint `gorm:"column:torrent_id;unique_index:idx_tid_path"`
|
||||
// this path is bencode'd, call Path() to obtain
|
||||
BencodedPath string `gorm:"column:path;unique_index:idx_tid_path"`
|
||||
Filesize int64 `gorm:"column:filesize"`
|
||||
}
|
||||
|
||||
// Returns the total size of memory allocated for this struct
|
||||
func (f File) Size() int {
|
||||
return (2 + len(f.Path) + 2) * 8;
|
||||
return (2 + len(f.BencodedPath) + 1) * 8;
|
||||
}
|
||||
|
||||
func (f *File) Path() (out []string) {
|
||||
bencode.DecodeString(f.BencodedPath, &out)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) SetPath(path []string) error {
|
||||
encoded, err := bencode.EncodeString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.BencodedPath = encoded
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"fmt"
|
||||
"html/template"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -73,6 +74,10 @@ func (t Torrent) Size() (s int) {
|
|||
|
||||
}
|
||||
|
||||
func (t Torrent) TableName() string {
|
||||
return config.TableName
|
||||
}
|
||||
|
||||
/* We need a JSON object instead of a Gorm structure because magnet URLs are
|
||||
not in the database and have to be generated dynamically */
|
||||
|
||||
|
@ -131,7 +136,10 @@ func (t *Torrent) ToJSON() TorrentJSON {
|
|||
}
|
||||
fileListJSON := make([]FileJSON, 0, len(t.FileList))
|
||||
for _, f := range t.FileList {
|
||||
fileListJSON = append(fileListJSON, FileJSON{Path: f.Path, Filesize: util.FormatFilesize2(f.Filesize)})
|
||||
fileListJSON = append(fileListJSON, FileJSON{
|
||||
Path: filepath.Join(f.Path()...),
|
||||
Filesize: util.FormatFilesize2(f.Filesize),
|
||||
})
|
||||
}
|
||||
uploader := ""
|
||||
if t.Uploader != nil {
|
||||
|
|
|
@ -106,6 +106,11 @@ a:hover {
|
|||
background-color: #b294bb;
|
||||
}
|
||||
|
||||
.form-control, pre {
|
||||
color: #fff;
|
||||
background-color: #29363d
|
||||
}
|
||||
|
||||
/* style the dropdown member menu */
|
||||
.nav > .dropdown.open, .profile-image[aria-expanded="true"], .nav ul.dropdown-menu {
|
||||
background: #282A2E;
|
||||
|
|
|
@ -426,6 +426,17 @@ select#bottom_language_selector {
|
|||
hyphens: auto;
|
||||
}
|
||||
|
||||
.filelist-control {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filelist-control::before {
|
||||
content: "\25B6 ";
|
||||
}
|
||||
|
||||
.filelist-control[aria-expanded="true"]::before {
|
||||
content: "\25BC ";
|
||||
}
|
||||
|
||||
/*Comments*/
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
} else {
|
||||
clv := ChangeLanguageVariables{NewSearchForm(), Navigation{}, Tlang.Tag, availableLanguages, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
clv := ChangeLanguageVariables{NewSearchForm(), NewNavigation(), Tlang.Tag, availableLanguages, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
languages.SetTranslationFromRequest(changeLanguageTemplate, r)
|
||||
err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv)
|
||||
if err != nil {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
func FaqHandler(w http.ResponseWriter, r *http.Request) {
|
||||
languages.SetTranslationFromRequest(faqTemplate, r)
|
||||
err := faqTemplate.ExecuteTemplate(w, "index.html", FaqTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
err := faqTemplate.ExecuteTemplate(w, "index.html", FaqTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ type PanelTorrentReassignVbs struct {
|
|||
*/
|
||||
type Navigation struct {
|
||||
TotalItem int
|
||||
MaxItemPerPage int
|
||||
MaxItemPerPage int // FIXME: shouldn't this be in SearchForm?
|
||||
CurrentPage int
|
||||
Route string
|
||||
}
|
||||
|
@ -200,6 +200,12 @@ type SearchForm struct {
|
|||
}
|
||||
|
||||
// Some Default Values to ease things out
|
||||
func NewNavigation() Navigation {
|
||||
return Navigation{
|
||||
MaxItemPerPage: 50,
|
||||
}
|
||||
}
|
||||
|
||||
func NewSearchForm() SearchForm {
|
||||
return SearchForm{
|
||||
Category: "_",
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
// Use this, because we seem to avoid using models, and we would need
|
||||
// the torrent ID to create the File in the DB
|
||||
type UploadedFile struct {
|
||||
Path string
|
||||
Path []string
|
||||
Filesize int64
|
||||
}
|
||||
|
||||
|
@ -161,10 +161,10 @@ func (f *UploadForm) ExtractInfo(r *http.Request) error {
|
|||
|
||||
// extract filelist
|
||||
fileInfos := torrent.Info.GetFiles()
|
||||
for _, info := range fileInfos {
|
||||
for _, fileInfo := range fileInfos {
|
||||
f.FileList = append(f.FileList, UploadedFile{
|
||||
Path: info.Path.FilePath(),
|
||||
Filesize: int64(info.Length),
|
||||
Path: fileInfo.Path,
|
||||
Filesize: int64(fileInfo.Length),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -64,10 +64,12 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// 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,
|
||||
Path: uploadedFile.Path,
|
||||
Filesize: uploadedFile.Filesize}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +92,7 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
uploadForm.CaptchaID = ""
|
||||
}
|
||||
|
||||
htv := UploadTemplateVariables{uploadForm, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
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 {
|
||||
|
|
|
@ -23,7 +23,7 @@ func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
modelHelper.BindValueForm(&b, r)
|
||||
b.CaptchaID = captcha.GetID()
|
||||
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
|
||||
htv := UserRegisterTemplateVariables{b, form.NewErrors(), NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
|
@ -39,7 +39,7 @@ func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
modelHelper.BindValueForm(&b, r)
|
||||
|
||||
languages.SetTranslationFromRequest(viewLoginTemplate, r)
|
||||
htv := UserLoginFormVariables{b, form.NewErrors(), NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserLoginFormVariables{b, form.NewErrors(), NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
err := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
|
@ -66,7 +66,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
err["errors"] = append(err["errors"], errUser.Error())
|
||||
}
|
||||
languages.SetTranslationFromRequest(viewUserDeleteTemplate, r)
|
||||
htv := UserVerifyTemplateVariables{err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserVerifyTemplateVariables{err, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewUserDeleteTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -79,7 +79,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if unfollow != nil {
|
||||
infosForm["infos"] = append(infosForm["infos"], fmt.Sprintf(T("user_unfollowed_msg"), userProfile.Username))
|
||||
}
|
||||
htv := UserProfileVariables{&userProfile, infosForm, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserProfileVariables{&userProfile, infosForm, NewSearchForm(), NewNavigation(), currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
|
@ -88,7 +88,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func UserDetailsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
modelHelper.BindValueForm(&b, r)
|
||||
languages.SetTranslationFromRequest(viewProfileEditTemplate, r)
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
htv := UserProfileEditVariables{&userProfile, b, form.NewErrors(), form.NewInfos(), availableLanguages, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserProfileEditVariables{&userProfile, b, form.NewErrors(), form.NewInfos(), availableLanguages, NewSearchForm(), NewNavigation(), currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
err := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
@ -115,7 +115,7 @@ func UserDetailsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
}
|
||||
|
@ -167,21 +167,21 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
availableLanguages := languages.GetAvailableLanguages()
|
||||
htv := UserProfileEditVariables{&userProfile, b, err, infos, availableLanguages, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r)
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(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)
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
u := model.User{
|
||||
Email: r.PostFormValue("email"), // indicate whether user had email set
|
||||
}
|
||||
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), Navigation{}, &u, r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), NewNavigation(), &u, r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewRegisterSuccessTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -225,7 +225,7 @@ func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if len(err) > 0 {
|
||||
b.CaptchaID = captcha.GetID()
|
||||
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
|
||||
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -242,7 +242,7 @@ func UserVerifyEmailHandler(w http.ResponseWriter, r *http.Request) {
|
|||
err["errors"] = append(err["errors"], errEmail.Error())
|
||||
}
|
||||
languages.SetTranslationFromRequest(viewVerifySuccessTemplate, r)
|
||||
htv := UserVerifyTemplateVariables{err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserVerifyTemplateVariables{err, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewVerifySuccessTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
@ -260,7 +260,7 @@ func UserLoginPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if errorUser != nil {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
languages.SetTranslationFromRequest(viewLoginTemplate, r)
|
||||
htv := UserLoginFormVariables{b, err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserLoginFormVariables{b, err, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
|
|
|
@ -32,7 +32,7 @@ func ViewHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if userPermission.NeedsCaptcha(user) {
|
||||
captchaID = captcha.GetID()
|
||||
}
|
||||
htv := ViewTemplateVariables{b, captchaID, NewSearchForm(), Navigation{}, user, r.URL, mux.CurrentRoute(r)}
|
||||
htv := ViewTemplateVariables{b, captchaID, NewSearchForm(), NewNavigation(), user, r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
languages.SetTranslationFromRequest(viewTemplate, r)
|
||||
err = viewTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package commentService
|
||||
|
||||
import (
|
||||
"github.com/ewhal/nyaa/config"
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
|
||||
)
|
||||
|
||||
func GetAllComments(limit int, offset int, conditions string, values ...interface{}) ([]model.Comment, int){
|
||||
func GetAllComments(limit int, offset int, conditions string, values ...interface{}) ([]model.Comment, int) {
|
||||
var comments []model.Comment
|
||||
var nbComments int
|
||||
db.ORM.Model(&comments).Where(conditions, values...).Count(&nbComments)
|
||||
db.ORM.Table(config.CommentsTableName).Model(&comments).Where(conditions, values...).Count(&nbComments)
|
||||
db.ORM.Preload("User").Limit(limit).Offset(offset).Where(conditions, values...).Find(&comments)
|
||||
return comments, nbComments
|
||||
}
|
||||
|
|
|
@ -119,23 +119,32 @@ func (fetcher *MetainfoFetcher) removeFromFailed(tID uint) {
|
|||
|
||||
delete(fetcher.failedOperations, tID)
|
||||
}
|
||||
|
||||
func updateFileList(dbEntry model.Torrent, info *metainfo.Info) error {
|
||||
torrentFiles := info.UpvertedFiles()
|
||||
log.Infof("TID %d has %d files.", dbEntry.ID, len(torrentFiles))
|
||||
|
||||
for _, file := range torrentFiles {
|
||||
path := file.DisplayPath(info)
|
||||
var path []string
|
||||
if file.Path != nil {
|
||||
path = file.Path
|
||||
} else {
|
||||
// If it's nil, use the torrent name (info.Name) as the path (single-file torrent)
|
||||
path = append(path, info.Name)
|
||||
}
|
||||
|
||||
// Can't read FileList from the GetTorrents output, rely on the unique_index
|
||||
// to ensure no files are duplicated.
|
||||
log.Infof("Adding file %s to filelist of TID %d", path, dbEntry.ID)
|
||||
log.Infof("Adding file %s to filelist of TID %d", file.DisplayPath(info), dbEntry.ID)
|
||||
dbFile := model.File{
|
||||
TorrentID: dbEntry.ID,
|
||||
Path: path,
|
||||
Filesize: file.Length,
|
||||
}
|
||||
err := dbFile.SetPath(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := db.ORM.Create(&dbFile).Error
|
||||
err = db.ORM.Create(&dbFile).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ewhal/nyaa/config"
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
formStruct "github.com/ewhal/nyaa/service/user/form"
|
||||
|
@ -128,7 +129,7 @@ func RetrieveUser(r *http.Request, id string) (*model.PublicUser, bool, uint, in
|
|||
var currentUserID uint
|
||||
var isAuthor bool
|
||||
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
if db.ORM.Table(config.TableName).First(&user, id).RecordNotFound() {
|
||||
return nil, isAuthor, currentUserID, http.StatusNotFound, errors.New("user not found")
|
||||
}
|
||||
currentUser, err := CurrentUser(r)
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
<option value="1_2" {{if eq .Search.Category "1_2"}}selected{{end}}>{{T "art_doujinshi"}}</option>
|
||||
<option value="1_3" {{if eq .Search.Category "1_3"}}selected{{end}}>{{T "art_games"}}</option>
|
||||
<option value="1_4" {{if eq .Search.Category "1_4"}}selected{{end}}>{{T "art_manga"}}</option>
|
||||
<option value="1_5" {{if eq .Search.Category "1_5"}}selected{{end}}>{{T "art_pictures"}}</option>
|
||||
<option value="1_5" {{if eq .Search.Category "1_5"}}selected{{end}}>{{T "art_pictures"}}</option>
|
||||
<option value="2_" {{if eq .Search.Category "2_"}}selected{{end}}>{{T "real_life"}}</option>
|
||||
<option value="2_1" {{if eq .Search.Category "2_1"}}selected{{end}}>{{T "real_life_photobooks_and_Pictures"}}</option>
|
||||
<option value="2_1" {{if eq .Search.Category "2_1"}}selected{{end}}>{{T "real_life_photobooks_and_pictures"}}</option>
|
||||
<option value="2_2" {{if eq .Search.Category "2_2"}}selected{{end}}>{{T "real_life_videos"}}</option>
|
||||
{{ else }}
|
||||
<option value="3_" {{if eq .Search.Category "3_"}}selected{{end}}>{{T "anime"}}</option>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<li><a href="{{.URL.Parse "/faq"}}">{{T "faq"}}</a></li>
|
||||
<li><a href="{{ genRouteWithQuery "feed" .URL }}">RSS</a></li>
|
||||
{{ if Sukebei }}
|
||||
<li><a href="https:/nyaa.pantsu.cat">{{T "fun"}}</a></li>
|
||||
<li><a href="https://nyaa.pantsu.cat">{{T "fun"}}</a></li>
|
||||
{{ else }}
|
||||
<li><a href="https://sukebei.pantsu.cat">{{T "fap"}}</a></li>
|
||||
{{ end }}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
<div class="form-group">
|
||||
<label for="c">{{T "category"}}</label>
|
||||
<select name="c" id="c" class="form-control input-sm" required>
|
||||
|
||||
<option value="">{{T "select_a_torrent_category"}}</option>
|
||||
{{ if Sukebei }}
|
||||
<option value="1_" {{if eq .Category "1_"}}selected{{end}}>{{T "art"}}</option>
|
||||
|
|
|
@ -15,19 +15,18 @@
|
|||
<div class="row" id="description">
|
||||
<div class="col-md-12">
|
||||
<div style="float: left;">
|
||||
<div class="uploaded_by">
|
||||
|
||||
{{ if Sukebei }}
|
||||
|
||||
<img style="float:left; margin-right: 1em;" src="{{$.URL.Parse (printf "/img/torrents/sukebei/%s%s.png" .Category .SubCategory) }}">
|
||||
|
||||
{{ else }}
|
||||
<img style="float:left; margin-right: 1em;" src="{{$.URL.Parse (printf "/img/torrents/%s.png" .SubCategory) }}">
|
||||
{{ end}}
|
||||
|
||||
<h4>{{ T "uploaded_by" }} <a href="{{$.URL.Parse (printf "/user/%d/-" .UploaderID) }}">{{.UploaderName}}</a></h4>
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
<br />
|
||||
<h4 style="display:inline-block">
|
||||
{{ T "uploaded_by" }} <a href="{{$.URL.Parse (printf "/user/%d/-" .UploaderID) }}">{{.UploaderName}}</a>
|
||||
</h4>
|
||||
{{if ne .OldUploader ""}}
|
||||
<span>({{.OldUploader}})</span>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div style="float:right;">
|
||||
|
@ -67,7 +66,7 @@
|
|||
<p>{{.Filesize}}</p>
|
||||
<hr>
|
||||
{{if ne .WebsiteLink ""}}
|
||||
<h4>{{T "Link"}}</h4>
|
||||
<h4>{{T "link"}}</h4>
|
||||
<p><a href="{{.WebsiteLink}}">{{.WebsiteLink}}</a></p>
|
||||
<hr>
|
||||
{{end}}
|
||||
|
@ -91,10 +90,10 @@
|
|||
</div>
|
||||
</div>
|
||||
{{ if gt (len .FileList) 0 }}
|
||||
<div class="row" id="files">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4>{{T "files"}}</h4>
|
||||
<div class="table-responsive">
|
||||
<h4 data-toggle="collapse" data-target="#files" class="filelist-control" aria-expanded="false">{{T "files"}}</h4>
|
||||
<div class="table-responsive collapse" id="files">
|
||||
<table class="table custom-table-hover">
|
||||
<tr>
|
||||
<th class="col-xs-8">{{T "filename"}}</th>
|
||||
|
|
|
@ -183,6 +183,10 @@
|
|||
"id": "fap",
|
||||
"translation": "Fap"
|
||||
},
|
||||
{
|
||||
"id": "fun",
|
||||
"translation": "Fun"
|
||||
},
|
||||
{
|
||||
"id": "advanced_search",
|
||||
"translation": "Advanced Search"
|
||||
|
@ -455,6 +459,38 @@
|
|||
"id": "software_games",
|
||||
"translation": "Software - Games"
|
||||
},
|
||||
{
|
||||
"id": "art",
|
||||
"translation": "Art"
|
||||
},
|
||||
{
|
||||
"id": "art_anime",
|
||||
"translation": "Art - Anime"
|
||||
},
|
||||
{
|
||||
"id": "art_doujinshi",
|
||||
"translation": "Art - Doujinshi"
|
||||
},
|
||||
{
|
||||
"id": "art_games",
|
||||
"translation": "Art - Games"
|
||||
},
|
||||
{
|
||||
"id": "art_manga",
|
||||
"translation": "Art - Manga"
|
||||
},
|
||||
{
|
||||
"id": "real_life",
|
||||
"translation": "Real Life"
|
||||
},
|
||||
{
|
||||
"id": "real_life_photobooks_and_pictures",
|
||||
"translation": "Real Life - Photobooks and Pictures"
|
||||
},
|
||||
{
|
||||
"id": "real_life_videos",
|
||||
"translation": "Real Life - Videos"
|
||||
},
|
||||
{
|
||||
"id": "torrent_description",
|
||||
"translation": "Torrent Description"
|
||||
|
|
|
@ -573,7 +573,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん es el nombre de usuario asignado a las subidas y comentarios hechos anónimamente. También es usado en los torrents importados desde el nyaa original, aunque es posible que se muestre junto al nombre de usuario original."
|
||||
"translation": "れんちょん (Ren-chon) es el nombre de usuario asignado a las subidas y comentarios hechos anónimamente. También es usado en los torrents importados desde el nyaa original, aunque es posible que se muestre junto al nombre de usuario original."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
|
@ -183,6 +183,10 @@
|
|||
"id": "fap",
|
||||
"translation": "Fap"
|
||||
},
|
||||
{
|
||||
"id": "fun",
|
||||
"translation": "Fun"
|
||||
},
|
||||
{
|
||||
"id": "advanced_search",
|
||||
"translation": "Recherche avancée"
|
||||
|
@ -317,11 +321,7 @@
|
|||
},
|
||||
{
|
||||
"id": "answer_which_trackers_do_you_recommend",
|
||||
"translation": "Nous avons maintenant notre propre tracker, ajoutez-le en haut de la liste avant d'uploader :"
|
||||
},
|
||||
{
|
||||
"id": "other_trackers",
|
||||
"translation": "Mais vous devriez également ajouter ceux-ci, dans le cas où cela ne fonctionnerait pas :"
|
||||
"translation": "Nous avons maintenant notre propre tracker appelé doko.moe, placez-le en haut de la liste avant d'uploader. Vous devriez également ajouter plusieurs autres trackers pour assurer la persistance du torrent :"
|
||||
},
|
||||
{
|
||||
"id": "how_can_i_help",
|
||||
|
@ -459,6 +459,38 @@
|
|||
"id": "software_games",
|
||||
"translation": "Logiciels - Jeux"
|
||||
},
|
||||
{
|
||||
"id": "art",
|
||||
"translation": "Art"
|
||||
},
|
||||
{
|
||||
"id": "art_anime",
|
||||
"translation": "Art - Anime"
|
||||
},
|
||||
{
|
||||
"id": "art_doujinshi",
|
||||
"translation": "Art - Doujinshi"
|
||||
},
|
||||
{
|
||||
"id": "art_games",
|
||||
"translation": "Art - Jeux"
|
||||
},
|
||||
{
|
||||
"id": "art_manga",
|
||||
"translation": "Art - Manga"
|
||||
},
|
||||
{
|
||||
"id": "real_life",
|
||||
"translation": "Vie Réelle"
|
||||
},
|
||||
{
|
||||
"id": "real_life_photobooks_and_pictures",
|
||||
"translation": "Vie Réelle - Livres photo et Images"
|
||||
},
|
||||
{
|
||||
"id": "real_life_videos",
|
||||
"translation": "Vie Réelle - Vidéos"
|
||||
},
|
||||
{
|
||||
"id": "torrent_description",
|
||||
"translation": "Description du torrent"
|
||||
|
@ -589,7 +621,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん (Renchon) est le nom d'utilisateur par défaut assigné aux uploads et commentaires anonymes ainsi que la mascotte du site. Il est utilisé pour les torrents importés du Nyaa original, bien que l'auteur d'origine puisse parfois être affiché."
|
||||
"translation": "れんちょん (Ren-chon) est le nom d'utilisateur par défaut assigné aux uploads et commentaires anonymes ainsi que la mascotte du site. Il est utilisé pour les torrents importés du Nyaa original, bien que l'auteur d'origine puisse parfois être affiché."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
@ -647,6 +679,14 @@
|
|||
"id": "delete",
|
||||
"translation": "Supprimer"
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"translation": "Fichiers"
|
||||
},
|
||||
{
|
||||
"id": "filename",
|
||||
"translation": "Nom du fichier"
|
||||
},
|
||||
{
|
||||
"id": "uploaded_by",
|
||||
"translation": "Uploadé par"
|
||||
|
|
|
@ -557,7 +557,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん nevet az kapja, aki névtelenül ír kommentet vagy tölt fel valamit. Ezt a nevet kapják az eredeti nyaa-ról átimportált torrentek is, viszont az eredeti feltöltő neve megjelenhet mellette."
|
||||
"translation": "れんちょん (Ren-chon) nevet az kapja, aki névtelenül ír kommentet vagy tölt fel valamit. Ezt a nevet kapják az eredeti nyaa-ról átimportált torrentek is, viszont az eredeti feltöltő neve megjelenhet mellette."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
},
|
||||
{
|
||||
"id":"signup_verification_email",
|
||||
"translation": "認証メールを送信しました。メールボックスを確認してください。迷惑メールフォルダーの確認もお忘れなく。"
|
||||
"translation": "現在は一時的にメールアドレスの認証が無効になっているので、すぐにアカウントを使うことができます。後日、メールボックスを確認してください。迷惑メールフォルダーの確認もお忘れなく。"
|
||||
},
|
||||
{
|
||||
"id":"signup_verification_noemail",
|
||||
|
@ -149,7 +149,7 @@
|
|||
},
|
||||
{
|
||||
"id": "date",
|
||||
"translation": "日付"
|
||||
"translation": "日時"
|
||||
},
|
||||
{
|
||||
"id": "size",
|
||||
|
@ -317,11 +317,7 @@
|
|||
},
|
||||
{
|
||||
"id": "answer_which_trackers_do_you_recommend",
|
||||
"translation": "独自のトラッカーを用意していますので、アップロードする前にリストの一番上に追加してください:"
|
||||
},
|
||||
{
|
||||
"id": "other_trackers",
|
||||
"translation": "ただし、うまくいかない場合に備え、これらも追加しておく必要があります"
|
||||
"translation": "doko.moe という独自のトラッカーをご用意しました。アップロードする前にリストの一番上に追加してください。また、Torrent の安定性を維持するために、以下のトラッカーをすべて追加する必要があります。"
|
||||
},
|
||||
{
|
||||
"id": "how_can_i_help",
|
||||
|
@ -459,6 +455,38 @@
|
|||
"id": "software_games",
|
||||
"translation": "ソフトウェア ‐ ゲーム"
|
||||
},
|
||||
{
|
||||
"id": "art",
|
||||
"translation": "アート"
|
||||
},
|
||||
{
|
||||
"id": "art_anime",
|
||||
"translation": "アート - アニメ"
|
||||
},
|
||||
{
|
||||
"id": "art_doujinshi",
|
||||
"translation": "アート - 同人誌"
|
||||
},
|
||||
{
|
||||
"id": "art_games",
|
||||
"translation": "アート - ゲーム"
|
||||
},
|
||||
{
|
||||
"id": "art_manga",
|
||||
"translation": "アート - 漫画"
|
||||
},
|
||||
{
|
||||
"id": "real_life",
|
||||
"translation": "日常"
|
||||
},
|
||||
{
|
||||
"id": "real_life_photobooks_and_pictures",
|
||||
"translation": "日常 - フォトブック、写真"
|
||||
},
|
||||
{
|
||||
"id": "real_life_videos",
|
||||
"translation": "日常 - ビデオ"
|
||||
},
|
||||
{
|
||||
"id": "torrent_description",
|
||||
"translation": "Torrent の説明"
|
||||
|
@ -473,7 +501,7 @@
|
|||
},
|
||||
{
|
||||
"id": "filter_remakes",
|
||||
"translation": "再構成フィルター"
|
||||
"translation": "リメイクを非表示"
|
||||
},
|
||||
{
|
||||
"id": "trusted",
|
||||
|
@ -593,7 +621,7 @@
|
|||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
"translation": "再構成としてマーク"
|
||||
"translation": "リメイクとしてマーク"
|
||||
},
|
||||
{
|
||||
"id": "email_changed",
|
||||
|
@ -613,7 +641,7 @@
|
|||
},
|
||||
{
|
||||
"id": "torrent_status_remake",
|
||||
"translation": "再構成"
|
||||
"translation": "リメイク"
|
||||
},
|
||||
{
|
||||
"id": "profile_edit_page",
|
||||
|
@ -646,5 +674,65 @@
|
|||
{
|
||||
"id": "delete",
|
||||
"translation": "削除"
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"translation": "ファイル"
|
||||
},
|
||||
{
|
||||
"id": "filename",
|
||||
"translation": "ファイル名"
|
||||
},
|
||||
{
|
||||
"id": "uploaded_by",
|
||||
"translation": "アップロード者:"
|
||||
},
|
||||
{
|
||||
"id": "download_btn",
|
||||
"translation": "ダウンロード"
|
||||
},
|
||||
{
|
||||
"id": "report_btn",
|
||||
"translation": "通報"
|
||||
},
|
||||
{
|
||||
"id": "are_you_sure",
|
||||
"translation": "よろしいですか。"
|
||||
},
|
||||
{
|
||||
"id": "report_torrent_number",
|
||||
"translation": "Torrent #%s を通報"
|
||||
},
|
||||
{
|
||||
"id": "report_type",
|
||||
"translation": "通報理由"
|
||||
},
|
||||
{
|
||||
"id": "illegal_content",
|
||||
"translation": "違法なコンテンツ"
|
||||
},
|
||||
{
|
||||
"id": "spam_garbage",
|
||||
"translation": "スパム / ゴミ"
|
||||
},
|
||||
{
|
||||
"id": "wrong_category",
|
||||
"translation": "誤ったカテゴリー"
|
||||
},
|
||||
{
|
||||
"id": "duplicate_deprecated",
|
||||
"translation": "重複 / 非推奨"
|
||||
},
|
||||
{
|
||||
"id": "captcha",
|
||||
"translation": "画像認証"
|
||||
},
|
||||
{
|
||||
"id": "file_name",
|
||||
"translation": "ファイル名"
|
||||
},
|
||||
{
|
||||
"id": "cancel",
|
||||
"translation": "キャンセル"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -569,7 +569,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん er brukernavnet vi putter på anonyme torrenter og kommentarer. Navnet brukes også for materiale fra proto-nyaa, men vanligvis ser man det ordentlige brukernavnet ved siden av."
|
||||
"translation": "れんちょん (Ren-chon) er brukernavnet vi putter på anonyme torrenter og kommentarer. Navnet brukes også for materiale fra proto-nyaa, men vanligvis ser man det ordentlige brukernavnet ved siden av."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
},
|
||||
{
|
||||
"id": "faq",
|
||||
"translation": "Perguntas Frequentes"
|
||||
"translation": "Dúvidas"
|
||||
},
|
||||
{
|
||||
"id": "fap",
|
||||
|
|
|
@ -589,7 +589,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん Это имя пользователя, назначенное для загрузок и комментариев, сделанных анонимно. Он также используется для торрентов, импортированных из оригинального nyaa, хотя оригинальный загрузчик может отображаться рядом."
|
||||
"translation": "れんちょん (Ren-chon) Это имя пользователя, назначенное для загрузок и комментариев, сделанных анонимно. Он также используется для торрентов, импортированных из оригинального nyaa, хотя оригинальный загрузчик может отображаться рядом."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
|
@ -569,7 +569,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん är användarnamnet som ges till anonyma kommentarer och uppladdningar. Det används även för importerade torrents från gamla nyaa, men den ursprungliga uppladdaren kan även visas vid sidan av."
|
||||
"translation": "れんちょん (Ren-chon) är användarnamnet som ges till anonyma kommentarer och uppladdningar. Det används även för importerade torrents från gamla nyaa, men den ursprungliga uppladdaren kan även visas vid sidan av."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
|
@ -181,7 +181,11 @@
|
|||
},
|
||||
{
|
||||
"id": "fap",
|
||||
"translation": "Fap"
|
||||
"translation": "กาม"
|
||||
},
|
||||
{
|
||||
"id": "fun",
|
||||
"translation": "ไม่กาม"
|
||||
},
|
||||
{
|
||||
"id": "advanced_search",
|
||||
|
@ -413,23 +417,23 @@
|
|||
},
|
||||
{
|
||||
"id": "live_action",
|
||||
"translation": "Live Action"
|
||||
"translation": "คนแสดง"
|
||||
},
|
||||
{
|
||||
"id": "live_action_english_translated",
|
||||
"translation": "Live Action - ถูกแปลเป็นภาษาอังกฤษ"
|
||||
"translation": "คนแสดง - ถูกแปลเป็นภาษาอังกฤษ"
|
||||
},
|
||||
{
|
||||
"id": "live_action_idol_pv",
|
||||
"translation": "Live Action - ไอดอล/Promotional Video"
|
||||
"translation": "คนแสดง - ไอดอล/Promotional Video"
|
||||
},
|
||||
{
|
||||
"id": "live_action_non_english_translated",
|
||||
"translation": "Live Action - ถูกแปลเป็นภาษาอื่น"
|
||||
"translation": "คนแสดง - ถูกแปลเป็นภาษาอื่น"
|
||||
},
|
||||
{
|
||||
"id": "live_action_raw",
|
||||
"translation": "Live Action - Raw"
|
||||
"translation": "คนแสดง - Raw"
|
||||
},
|
||||
{
|
||||
"id": "pictures",
|
||||
|
@ -455,9 +459,41 @@
|
|||
"id": "software_games",
|
||||
"translation": "ซอฟท์แวร์ - เกม"
|
||||
},
|
||||
{
|
||||
"id": "art",
|
||||
"translation": "งานศิลป์"
|
||||
},
|
||||
{
|
||||
"id": "art_anime",
|
||||
"translation": "งานศิลป์ - อนิเมะ"
|
||||
},
|
||||
{
|
||||
"id": "art_doujinshi",
|
||||
"translation": "งานศิลป์ - โดจินชิ"
|
||||
},
|
||||
{
|
||||
"id": "art_games",
|
||||
"translation": "งานศิลป์ - เกม"
|
||||
},
|
||||
{
|
||||
"id": "art_manga",
|
||||
"translation": "งานศิลป์ - มังงะ"
|
||||
},
|
||||
{
|
||||
"id": "real_life",
|
||||
"translation": "คนจริง"
|
||||
},
|
||||
{
|
||||
"id": "real_life_photobooks_and_pictures",
|
||||
"translation": "คนจริง - โฟโต้บุ๊คและภาพถ่าย"
|
||||
},
|
||||
{
|
||||
"id": "real_life_videos",
|
||||
"translation": "คนจริง - วีดีโอ"
|
||||
},
|
||||
{
|
||||
"id": "torrent_description",
|
||||
"translation": "รายละเอียดของไฟล์ทอร์เรนท์"
|
||||
"translation": "รายละเอียดของทอร์เรนท์"
|
||||
},
|
||||
{
|
||||
"id": "description_markdown_notice",
|
||||
|
@ -585,7 +621,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん คือชื่อผู้ใช้ที่ตั้งไว้สำหรับอัพโหลดและคอมเมนท์แบบไม่ระบุตัวตน ซึ่งถูกใช้กับทอร์เรนท์ที่กู้มาจาก Nyaa ดั้งเดิม และในบางครั้งชื่อผู้อัพโหลดดั้งเดิมจะแสดงผลคู่กัน"
|
||||
"translation": "れんちょん (Ren-chon) คือชื่อผู้ใช้ที่ตั้งไว้สำหรับอัพโหลดและคอมเมนท์แบบไม่ระบุตัวตน ซึ่งถูกใช้กับทอร์เรนท์ที่กู้มาจาก Nyaa ดั้งเดิม และในบางครั้งชื่อผู้อัพโหลดดั้งเดิมจะแสดงผลคู่กัน"
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
@ -643,9 +679,17 @@
|
|||
"id": "delete",
|
||||
"translation": "ลบ"
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"translation": "ไฟล์"
|
||||
},
|
||||
{
|
||||
"id": "filename",
|
||||
"translation": "ชื่อไฟล์"
|
||||
},
|
||||
{
|
||||
"id": "uploaded_by",
|
||||
"translation": "อัพโหลด"
|
||||
"translation": "อัพโหลดโดย"
|
||||
},
|
||||
{
|
||||
"id": "download_btn",
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
},
|
||||
{
|
||||
"id": "no_torrents_uploaded",
|
||||
"translation": "没有被上传的种子喵!"
|
||||
"translation": "这个人很懒,什么资源都没上传过喵!"
|
||||
},
|
||||
{
|
||||
"id": "profile",
|
||||
|
@ -329,7 +329,7 @@
|
|||
},
|
||||
{
|
||||
"id": "answer_how_can_i_help",
|
||||
"translation": "如果您是个技术宅,請加入 #nyaapantsu 的 IRC,位於 irc.rizon.net 。如果您有最新的资料库,特別是 sukebei 的,<b>请上传它們!</b>"
|
||||
"translation": "如果您是个技术宅,请加入位于 irc.rizon.net 上的 IRC 频道 #nyaapantsu 。如果您有最新的资源,特别是 sukebei 的,<b>请上传它们</b>!"
|
||||
},
|
||||
{
|
||||
"id": "your_design_sucks_found_a_bug",
|
||||
|
@ -465,7 +465,7 @@
|
|||
},
|
||||
{
|
||||
"id": "description_markdown_notice",
|
||||
"translation": "描述可使用 Markdown"
|
||||
"translation": "描述中可以使用 Markdown 标记语言"
|
||||
},
|
||||
{
|
||||
"id": "show_all",
|
||||
|
@ -501,7 +501,7 @@
|
|||
},
|
||||
{
|
||||
"id": "hash",
|
||||
"translation": "哈希"
|
||||
"translation": "文件Hash"
|
||||
},
|
||||
{
|
||||
"id": "description",
|
||||
|
@ -513,7 +513,7 @@
|
|||
},
|
||||
{
|
||||
"id": "submit_a_comment_as_username",
|
||||
"translation": "作为 %s 发表评论"
|
||||
"translation": "欢迎 %s 发表评论"
|
||||
},
|
||||
{
|
||||
"id": "submit_a_comment_as_anonymous",
|
||||
|
@ -561,7 +561,7 @@
|
|||
},
|
||||
{
|
||||
"id": "profile_updated",
|
||||
"translation": "您的个人资料已保存喵!"
|
||||
"translation": "您的个人资料保存成功喵!"
|
||||
},
|
||||
{
|
||||
"id": "delete_account",
|
||||
|
@ -569,7 +569,7 @@
|
|||
},
|
||||
{
|
||||
"id": "delete_account_confirm",
|
||||
"translation": "您真的要删除您的账号喵?这无法挽回!"
|
||||
"translation": "您真的要删除您的账号喵?这是无法挽回的!"
|
||||
},
|
||||
{
|
||||
"id": "delete_success",
|
||||
|
@ -589,7 +589,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん(Ren-chon)是匿名评论与上传者的默认用户名,同时也显示为Nyaa站原始资源的上传者."
|
||||
"translation": "れんちょん(小莲)是匿名评论与上传者的默认用户名,同时也显示为Nyaa站原始资源的上传者."
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
@ -707,4 +707,4 @@
|
|||
"id": "cancel",
|
||||
"translation": "取消"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -581,7 +581,7 @@
|
|||
},
|
||||
{
|
||||
"id": "renchon_anon_explanation",
|
||||
"translation": "れんちょん是匿名評論與上傳者的默認用戶名,同時也顯示為Nyaa站原始資源的上傳者。"
|
||||
"translation": "れんちょん (Ren-chon) 是匿名評論與上傳者的默認用戶名,同時也顯示為Nyaa站原始資源的上傳者。"
|
||||
},
|
||||
{
|
||||
"id": "mark_as_remake",
|
||||
|
|
Référencer dans un nouveau ticket