Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0
Cette révision appartient à :
kilo 2019-07-06 20:17:50 +00:00 révisé par GitHub
révision 80e4d2454c
Signature inconnue de Forgejo
ID de la clé GPG: 4AEE18F83AFDEB23
14 fichiers modifiés avec 349 ajouts et 62 suppressions

Voir le fichier

@ -124,6 +124,8 @@ torrents:
torrents:
# GenerationClientPort : Port used by the torrent client created during torrent generation
generation_client_port: 50006
# FilesFetchingClientPort: Port used by the client created by file fetching
files_fetching_client_port: 50005
# FileStorage : Location of folder that will contain generated torrent files
filestorage: ./downloads/
# TorrentStorageLink : Url of torrent file download location (eg https://your.site/somewhere/%s)

Voir le fichier

@ -133,20 +133,21 @@ type TrackersConfig struct {
// TorrentsConfig : Config struct for Torrents
type TorrentsConfig struct {
Status []bool `yaml:"status,omitempty,omitempty"`
SukebeiCategories map[string]string `yaml:"sukebei_categories,omitempty"`
CleanCategories map[string]string `yaml:"clean_categories,omitempty"`
EnglishOnlyCategories ArrayString `yaml:"english_only_categories,omitempty"`
NonEnglishOnlyCategories ArrayString `yaml:"non_english_only_categories,omitempty"`
AdditionalLanguages ArrayString `yaml:"additional_languages,omitempty"`
FileStorage string `yaml:"filestorage,omitempty"`
StorageLink string `yaml:"storage_link,omitempty"`
CacheLink string `yaml:"cache_link,omitempty"`
Trackers TrackersConfig `yaml:"trackers,flow,omitempty"`
Order string `yaml:"order,omitempty"`
Sort string `yaml:"sort,omitempty"`
Tags Tags `yaml:"tags,flow,omitempty"`
GenerationClientPort int `yaml:"generation_client_port,flow,omitempty"`
Status []bool `yaml:"status,omitempty,omitempty"`
SukebeiCategories map[string]string `yaml:"sukebei_categories,omitempty"`
CleanCategories map[string]string `yaml:"clean_categories,omitempty"`
EnglishOnlyCategories ArrayString `yaml:"english_only_categories,omitempty"`
NonEnglishOnlyCategories ArrayString `yaml:"non_english_only_categories,omitempty"`
AdditionalLanguages ArrayString `yaml:"additional_languages,omitempty"`
FileStorage string `yaml:"filestorage,omitempty"`
StorageLink string `yaml:"storage_link,omitempty"`
CacheLink string `yaml:"cache_link,omitempty"`
Trackers TrackersConfig `yaml:"trackers,flow,omitempty"`
Order string `yaml:"order,omitempty"`
Sort string `yaml:"sort,omitempty"`
Tags Tags `yaml:"tags,flow,omitempty"`
GenerationClientPort int `yaml:"generation_client_port,flow,omitempty"`
FilesFetchingClientPort int `yaml:"files_fetching_client_port,flow,omitempty"`
}
// UploadConfig : Config struct for uploading torrents

78
controllers/torrent/files.go Fichier normal
Voir le fichier

@ -0,0 +1,78 @@
package torrentController
import (
"html/template"
"encoding/hex"
"net/http"
"strings"
"strconv"
"github.com/NyaaPantsu/nyaa/models/torrents"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/templates"
"github.com/NyaaPantsu/nyaa/utils/format"
"github.com/NyaaPantsu/nyaa/utils/filelist"
"github.com/Stephen304/goscrape"
"github.com/gin-gonic/gin"
)
func GetFilesHandler(c *gin.Context) {
id, _ := strconv.ParseInt(c.Param("id"), 10, 32)
torrent, err := torrents.FindByID(uint(id))
if err != nil {
c.Status(http.StatusNotFound)
return
}
if len(torrent.FileList) == 0 {
var blankScrape models.Scrape
ScrapeFiles(format.InfoHashToMagnet(strings.TrimSpace(torrent.Hash), torrent.Name, GetTorrentTrackers(torrent)...), torrent, blankScrape, true)
}
folder := filelist.FileListToFolder(torrent.FileList, "root")
templates.TorrentFileList(c, torrent.ToJSON(), folder)
}
// ScrapeFiles : Scrape torrent files
func ScrapeFiles(magnet string, torrent *models.Torrent, currentStats models.Scrape, statsExists bool) (error, []FileJSON) {
if client == nil {
err := initClient()
if err != nil {
return err, []FileJSON{}
}
}
t, _ := client.AddMagnet(magnet)
<-t.GotInfo()
infoHash := t.InfoHash()
dst := make([]byte, hex.EncodedLen(len(t.InfoHash())))
hex.Encode(dst, infoHash[:])
var UDP []string
for _, tracker := range t.Metainfo().AnnounceList[0] {
if strings.HasPrefix(tracker, "udp") {
UDP = append(UDP, tracker)
}
}
var results goscrape.Result
if len(UDP) != 0 {
udpscrape := goscrape.NewBulk(UDP)
results = udpscrape.ScrapeBulk([]string{torrent.Hash})[0]
}
t.Drop()
return nil, UpdateTorrentStats(torrent, results, currentStats, t.Files(), statsExists)
}
// FileJSON for file model in json,
type FileJSON struct {
Path string `json:"path"`
Filesize template.HTML `json:"filesize"`
}
func fileSize(filesize int64) template.HTML {
return template.HTML(format.FileSize(filesize))
}

Voir le fichier

@ -8,6 +8,7 @@ import (
func init() {
router.Get().Any("/download/:hash", DownloadTorrent)
router.Get().Any("/stats/:id", GetStatsHandler)
router.Get().Any("/files/:id", GetFilesHandler)
torrentRoutes := router.Get().Group("/torrent", middlewares.LoggedInMiddleware())
{

Voir le fichier

@ -1,6 +1,7 @@
package torrentController
import (
"path/filepath"
"strconv"
"strings"
"net/url"
@ -9,10 +10,34 @@ import (
"github.com/NyaaPantsu/nyaa/models/torrents"
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/utils/log"
"github.com/NyaaPantsu/nyaa/utils/format"
"github.com/Stephen304/goscrape"
"github.com/gin-gonic/gin"
"github.com/anacrolix/dht"
"github.com/anacrolix/torrent"
"github.com/bradfitz/slice"
)
var client *torrent.Client
func initClient() error {
clientConfig := torrent.Config{
DHTConfig: dht.ServerConfig{
StartingNodes: dht.GlobalBootstrapAddrs,
},
ListenAddr: ":" + strconv.Itoa(config.Get().Torrents.FilesFetchingClientPort),
}
cl, err := torrent.NewClient(&clientConfig)
if err != nil {
log.Errorf("error creating client: %s", err)
return err
}
client = cl
return nil
}
// ViewHeadHandler : Controller for getting torrent stats
func GetStatsHandler(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 32)
@ -20,8 +45,8 @@ func GetStatsHandler(c *gin.Context) {
return
}
torrent, err := torrents.FindRawByID(uint(id))
updateTorrent, err := torrents.FindByID(uint(id))
if err != nil {
return
}
@ -29,42 +54,42 @@ func GetStatsHandler(c *gin.Context) {
var CurrentData models.Scrape
statsExists := !(models.ORM.Where("torrent_id = ?", id).Find(&CurrentData).RecordNotFound())
if statsExists {
if statsExists && c.Request.URL.Query()["files"] == nil {
//Stats already exist, we check if the torrent stats have been scraped already very recently and if so, we stop there to avoid abuse of the /stats/:id route
if (CurrentData.Seeders == 0 && CurrentData.Leechers == 0 && CurrentData.Completed == 0) && time.Since(CurrentData.LastScrape).Minutes() <= config.Get().Scrape.MaxStatScrapingFrequencyUnknown {
if isEmptyScrape(CurrentData) && time.Since(CurrentData.LastScrape).Minutes() <= config.Get().Scrape.MaxStatScrapingFrequencyUnknown {
//Unknown stats but has been scraped less than X minutes ago (X being the limit set in the config file)
return
}
if (CurrentData.Seeders != 0 || CurrentData.Leechers != 0 || CurrentData.Completed != 0) && time.Since(CurrentData.LastScrape).Minutes() <= config.Get().Scrape.MaxStatScrapingFrequency {
if !isEmptyScrape(CurrentData) && time.Since(CurrentData.LastScrape).Minutes() <= config.Get().Scrape.MaxStatScrapingFrequency {
//Known stats but has been scraped less than X minutes ago (X being the limit set in the config file)
return
}
}
var Trackers []string
if len(torrent.Trackers) > 3 {
for _, line := range strings.Split(torrent.Trackers[3:], "&tr=") {
tracker, error := url.QueryUnescape(line)
if error == nil && strings.HasPrefix(tracker, "udp") {
Trackers = append(Trackers, tracker)
}
//Cannot scrape from http trackers so don't put them in the array
Trackers := GetTorrentTrackers(updateTorrent)
var stats goscrape.Result
var torrentFiles []FileJSON
if c.Request.URL.Query()["files"] != nil {
if len(updateTorrent.FileList) > 0 {
return
}
err, torrentFiles = ScrapeFiles(format.InfoHashToMagnet(strings.TrimSpace(updateTorrent.Hash), updateTorrent.Name, Trackers...), updateTorrent, CurrentData, statsExists)
if err != nil {
return
}
} else {
//Single() returns an array which contain results for each torrent Hash it is fed, since we only feed him one we want to directly access the results
stats = goscrape.Single(Trackers, []string{
updateTorrent.Hash,
})[0]
UpdateTorrentStats(updateTorrent, stats, CurrentData, []torrent.File{}, statsExists)
}
for _, tracker := range config.Get().Torrents.Trackers.Default {
if !contains(Trackers, tracker) && strings.HasPrefix(tracker, "udp") {
Trackers = append(Trackers, tracker)
}
}
stats := goscrape.Single(Trackers, []string{
torrent.Hash,
})[0]
//Single() returns an array which contain results for each torrent Hash it is fed, since we only feed him one we want to directly access the results
//If we put seeders on -1, the script instantly knows the fetching did not give any result, avoiding having to check all three stats below and in view.jet.html's javascript
if stats.Seeders == 0 && stats.Leechers == 0 && stats.Completed == 0 {
if isEmptyResult(stats) {
stats.Seeders = -1
}
@ -72,30 +97,89 @@ func GetStatsHandler(c *gin.Context) {
"seeders": stats.Seeders,
"leechers": stats.Leechers,
"downloads": stats.Completed,
"filelist": torrentFiles,
"totalsize": fileSize(updateTorrent.Filesize),
})
return
}
// UpdateTorrentStats : Update stats & filelist if files are specified, otherwise just stats
func UpdateTorrentStats(torrent *models.Torrent, stats goscrape.Result, currentStats models.Scrape, Files []torrent.File, statsExists bool) (JSONFilelist []FileJSON) {
if stats.Seeders == -1 {
stats.Seeders = 0
}
if !statsExists {
torrent.Scrape = torrent.Scrape.Create(uint(id), uint32(stats.Seeders), uint32(stats.Leechers), uint32(stats.Completed), time.Now())
//Create entry in the DB because none exist
torrent.Scrape = torrent.Scrape.Create(torrent.ID, uint32(stats.Seeders), uint32(stats.Leechers), uint32(stats.Completed), time.Now())
//Create a stat entry in the DB because none exist
} else {
//Entry in the DB already exists, simply update it
if (CurrentData.Seeders == 0 && CurrentData.Leechers == 0 && CurrentData.Completed == 0) || (stats.Seeders != 0 && stats.Leechers != 0 && stats.Completed != 0 ) {
torrent.Scrape = &models.Scrape{uint(id), uint32(stats.Seeders), uint32(stats.Leechers), uint32(stats.Completed), time.Now()}
if isEmptyScrape(currentStats) || !isEmptyResult(stats) {
torrent.Scrape = &models.Scrape{torrent.ID, uint32(stats.Seeders), uint32(stats.Leechers), uint32(stats.Completed), time.Now()}
} else {
torrent.Scrape = &models.Scrape{uint(id), uint32(CurrentData.Seeders), uint32(CurrentData.Leechers), uint32(CurrentData.Completed), time.Now()}
torrent.Scrape = &models.Scrape{torrent.ID, uint32(currentStats.Seeders), uint32(currentStats.Leechers), uint32(currentStats.Completed), time.Now()}
}
//Only overwrite stats if the old one are Unknown OR if the current ones are not unknown, preventing good stats from being turned into unknown own but allowing good stats to be updated to more reliable ones
//Only overwrite stats if the old one are Unknown OR if the new ones are not unknown, preventing good stats from being turned into unknown but allowing good stats to be updated to more reliable ones
torrent.Scrape.Update(false)
}
if len(Files) > 1 {
files, err := torrent.CreateFileList(Files)
if err != nil {
return
}
JSONFilelist = make([]FileJSON, 0, len(files))
for _, f := range files {
JSONFilelist = append(JSONFilelist, FileJSON{
Path: filepath.Join(f.Path()...),
Filesize: fileSize(f.Filesize),
})
}
// Sort file list by lowercase filename
slice.Sort(JSONFilelist, func(i, j int) bool {
return strings.ToLower(JSONFilelist[i].Path) < strings.ToLower(JSONFilelist[j].Path)
})
} else if len(Files) == 1 {
torrent.Filesize = Files[0].Length()
torrent.Update(false)
}
return
}
// GetTorrentTrackers : Get the torrent trackers and add the default ones if they are missing
func GetTorrentTrackers(torrent *models.Torrent) []string {
var Trackers []string
if len(torrent.Trackers) > 3 {
for _, line := range strings.Split(torrent.Trackers[3:], "&tr=") {
tracker, error := url.QueryUnescape(line)
if error == nil && strings.HasPrefix(tracker, "udp") {
Trackers = append(Trackers, tracker)
}
//Cannot scrape from http trackers only keep UDP ones
}
}
for _, tracker := range config.Get().Torrents.Trackers.Default {
if !contains(Trackers, tracker) && strings.HasPrefix(tracker, "udp") {
Trackers = append(Trackers, tracker)
}
}
return Trackers
}
func isEmptyResult(stats goscrape.Result) bool {
return stats.Seeders == 0 && stats.Leechers == 0 && stats.Completed == 0
}
func isEmptyScrape(stats models.Scrape) bool {
return stats.Seeders == 0 && stats.Leechers == 0 && stats.Completed == 0
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {

Voir le fichier

@ -52,12 +52,18 @@ func (f *File) SetPath(path []string) error {
// Filename : Returns the filename of the file
func (f *File) Filename() string {
path := f.Path()
if len(path) == 0 {
return ""
}
return path[len(path)-1]
}
// FilenameWithoutExtension : Returns the filename of the file without the extension
func (f *File) FilenameWithoutExtension() string {
path := f.Path()
if len(path) == 0 {
return ""
}
fileName := path[len(path)-1]
index := strings.LastIndex(fileName, ".")
@ -71,10 +77,13 @@ func (f *File) FilenameWithoutExtension() string {
// FilenameExtension : Returns the extension of a filename, or an empty string
func (f *File) FilenameExtension() string {
path := f.Path()
if len(path) == 0 {
return ""
}
fileName := path[len(path)-1]
index := strings.LastIndex(fileName, ".")
if index == -1 {
if index == -1 || index+1 == len(fileName){
return ""
}

Voir le fichier

@ -22,6 +22,7 @@ import (
"github.com/NyaaPantsu/nyaa/utils/format"
"github.com/NyaaPantsu/nyaa/utils/log"
"github.com/NyaaPantsu/nyaa/utils/sanitize"
"github.com/anacrolix/torrent"
"github.com/bradfitz/slice"
"github.com/fatih/structs"
)
@ -460,6 +461,26 @@ func (t *Torrent) Update(unscope bool) (int, error) {
return http.StatusOK, nil
}
func (t *Torrent) CreateFileList(Files []torrent.File) ([]File, error) {
var createdFilelist []File
t.Filesize = 0
for _, uploadedFile := range Files {
file := File{TorrentID: t.ID, Filesize: uploadedFile.Length()}
err := file.SetPath(uploadedFile.FileInfo().Path)
if err != nil {
return []File{}, err
}
createdFilelist = append(createdFilelist, file)
t.Filesize += uploadedFile.Length()
ORM.Create(&file)
}
t.FileList = createdFilelist
t.Update(false)
return createdFilelist, nil
}
// UpdateUnscope : Update a torrent based on model
func (t *Torrent) UpdateUnscope() (int, error) {
return t.Update(true)

Voir le fichier

@ -39,10 +39,8 @@ func FindByID(id uint) (*models.Torrent, error) {
}
tmp := models.ORM.Where("torrent_id = ?", id).Preload("Scrape").Preload("Uploader").Preload("Comments")
if id > config.Get().Models.LastOldTorrentID {
tmp = tmp.Preload("FileList")
}
tmp := models.ORM.Where("torrent_id = ?", id).Preload("Scrape").Preload("Uploader").Preload("Comments").Preload("FileList")
if id <= config.Get().Models.LastOldTorrentID && !config.IsSukebei() {
// only preload old comments if they could actually exist
tmp = tmp.Preload("OldComments")

Voir le fichier

@ -0,0 +1,33 @@
{{ extends "layouts/index_site" }}
{{ import "layouts/partials/helpers/csrf" }}
{{ import "layouts/partials/helpers/captcha" }}
{{ import "layouts/partials/helpers/errors" }}
{{ import "layouts/partials/helpers/tags" }}
{{ import "layouts/partials/helpers/treeview" }}
{{ import "layouts/partials/helpers/tag_form" }}
{{block title()}}{{Torrent.Name}}{{end}}
{{block content_body()}}
<div style="text-align: left;" class="box">
<div id="torrent-name"><h1 style="text-align: center;" class="torrent-hr">{{T("torrent_filelist")}}</h1></div>
<a href="/view/{{Torrent.ID}}">«- {{T("back_to_torrent", Torrent.Name)}}</a><br/>
<input type="checkbox" id="show-filelist" checked/>
<label class="torrent-hr filelist-control{{if len(Torrent.FileList) == 0}} hidden{{end}}" for="show-filelist">{{ T("files")}}</label>
<div class="torrent-info-box{{if len(Torrent.FileList) == 0}} hidden{{end}}" id="filelist">
<table class="table-filelist">
<thead>
<tr>
<th style="width: 80%">{{ T("file_name")}}</th>
<th>{{ T("size")}}</th>
</tr>
</thead>
<tbody>
{{ if len(Torrent.FileList) > 0 }}
{{ yield make_treeview(treeviewData=makeTreeViewData(RootFolder, 0, "root")) }}
{{else}}
<tr class="tr-filelist"><td colspan="2">{{ T("no_files") }}</td></tr>
{{end}}
</tbody>
</table>
</div>
</div>
{{end}}

Voir le fichier

@ -52,7 +52,7 @@
</tr>
<tr class="torrent-info-row">
<td class="torrent-info-td torrent-info-label">{{ T("size")}}:</td>
<td class="torrent-view-td torrent-info-data">{{ fileSize(Torrent.Filesize, T, true) }}</td>
<td class="torrent-view-td torrent-info-data torrent-info-size">{{ fileSize(Torrent.Filesize, T, true) }}</td>
</tr>
{{ if len(Torrent.Languages) > 0 && Torrent.Languages[0] != "" }}
<tr class="torrent-info-row">
@ -205,10 +205,14 @@
<p>{{ T("no_description") }}</p>
{{end}}
<input type="checkbox" id="show-filelist" {{if len(Torrent.FileList) < 4 && len(Torrent.FileList) > 0}}checked{{end}}/>
<label class="torrent-hr filelist-control{{if len(Torrent.FileList) == 0}} hidden{{end}}" for="show-filelist">{{ T("files")}}</label>
<label class="torrent-hr filelist-control{{if len(Torrent.FileList) == 0}} hidden{{end}}" for="show-filelist">
{{ if len(Torrent.FileList) == 0 }}
<a href="/files/{{Torrent.ID}}">{{ T("files")}}</a>
{{else}}
{{ T("files")}}
{{end}}
</label>
<div class="torrent-info-box{{if len(Torrent.FileList) == 0}} hidden{{end}}" id="filelist">
{{ if len(Torrent.FileList) > 0 }}
{* how do i concat lol *}
<table class="table-filelist">
<thead>
<tr>
@ -217,12 +221,13 @@
</tr>
</thead>
<tbody>
{{ yield make_treeview(treeviewData=makeTreeViewData(RootFolder, 0, "root")) }}
{{ if len(Torrent.FileList) > 0 }}
{{ yield make_treeview(treeviewData=makeTreeViewData(RootFolder, 0, "root")) }}
{{else}}
<tr class="tr-filelist"><td colspan="2">{{ T("no_files") }}</td></tr>
{{end}}
</tbody>
</table>
{{ else }}
<p>{{ T("no_files") }}</p>
{{ end }}
</div>
<p class="torrent-hr" id="comments">{{ T("comments")}}</p>
@ -353,11 +358,40 @@ Modal.Init({
// order of apparition of the modals
button: ["#reportPopup", "#tagPopup"]
});
{{ if len(Torrent.FileList) == 0 }}
var FileListContainer = document.querySelector("#filelist tbody"),
FileListLabel = document.getElementsByClassName("filelist-control")[0],
FileListOldHtml = FileListContainer.innerHTML
FileListLabel.innerHTML = FileListLabel.innerText
FileListLabel.addEventListener("click", function (e) {
FileListContainer.innerHTML = "<tr class='tr-filelist'><td>{{T("loading_file_list")}}</td></tr>"
Query.Get('/stats/{{Torrent.ID}}?files', function (data) {
if(data.totalsize != null && data.totalsize != "0.0 B") document.getElementsByClassName("torrent-info-size")[0].innerHTML = data.totalsize
if(data.filelist != null) {
FileListContainer.innerHTML = ""
FileListLabel.style.opacity = 1
document.getElementById("filelist").style.opacity = 1
for(var i = 0; i < data.filelist.length; i++) {
var file = data.filelist[i]
if(file.filesize == "0.0 B") file.filesize = "{{T("unknown")}}"
FileListContainer.innerHTML = FileListContainer.innerHTML + '<tr class="tr-filelist '+ file.class +'"><td>'+ file.path +'</td><td>'+ file.filesize +'</td></tr>'
}
} else {
FileListContainer.innerHTML = FileListOldHtml
}
})
})
{{end}}
</script>
<script type="text/javascript" src="{{ URL.Parse("/js/simplemde.min.js") }}"></script>
<script type="text/javascript">new SimpleMDE({ element: document.getElementsByName("comment")[0], spellChecker: false, showIcons: [ "strikethrough", "code", "table", "horizontal-rule" ] });</script>
{{ if !torrentFileExists(Torrent.Hash, Torrent.TorrentLink)}}
<script type="text/javascript">
{{ if !torrentFileExists(Torrent.Hash, Torrent.TorrentLink)}}
var torrentLink = document.getElementById("torrent-download-link"),
oldDownloadHtml = torrentLink.innerHTML,
downloadIconHtml = torrentLink.innerHTML.substring(0, torrentLink.innerHTML.indexOf("</div>") + 6),
@ -397,10 +431,8 @@ Modal.Init({
}
});
}
</script>
{{end}}
{{if Torrent.StatsObsolete[1] }}
<script type="text/javascript">
var seeders = document.querySelector(".tr-se"),
leechers = document.querySelector(".tr-le"),
downloads = document.querySelector(".tr-dl"),
@ -427,9 +459,8 @@ Modal.Init({
}
})
</script>
{{end}}
</script>
{{ if User.ID > 0 }}
<script type="text/javascript" src="{{ URL.Parse("/js/template.js") }}"></script>
<script type="text/javascript" src="{{ URL.Parse("/js/modal.js") }}"></script>

Voir le fichier

@ -160,6 +160,14 @@ func Torrent(c *gin.Context, torrent models.TorrentJSON, rootFolder *filelist.Fi
Render(c, path.Join(SiteDir, "torrents", "view.jet.html"), variables)
}
// Torrent render a torrent view template
func TorrentFileList(c *gin.Context, torrent models.TorrentJSON, rootFolder *filelist.FileListFolder) {
variables := Commonvariables(c)
variables.Set("Torrent", torrent)
variables.Set("RootFolder", rootFolder)
Render(c, path.Join(SiteDir, "torrents", "filelist.jet.html"), variables)
}
// userProfilBase render the base for user profile
func userProfileBase(c *gin.Context, templateName string, userProfile *models.User, variables jet.VarMap) {
currentUser, _, _ := cookies.CurrentUser(c)

Voir le fichier

@ -110,6 +110,11 @@ func walkDirTest(dir string, t *testing.T) {
variables.Set("RootFolder", filelist.FileListToFolder(fakeTorrent.FileList, "root"))
return variables
},
"filelist.jet.html": func(variables jet.VarMap) jet.VarMap {
variables.Set("Torrent", fakeTorrent.ToJSON())
variables.Set("RootFolder", filelist.FileListToFolder(fakeTorrent.FileList, "root"))
return variables
},
"settings.jet.html": func(variables jet.VarMap) jet.VarMap {
variables.Set("Form", &LanguagesJSONResponse{"test", publicSettings.Languages{*fakeLanguage, *fakeLanguage}})
return variables

Voir le fichier

@ -101,6 +101,10 @@
## 2017/11/04
* + nsfw_content
* + generating_torrent_failed
## 2017/11/08
* + loading_file_list
* + torrent_filelist
* + back_to_torrent
## 2017/11/09
* + userstatus_janitor
* + ban

Voir le fichier

@ -767,6 +767,18 @@
"id": "no_files",
"translation": "No files found? That doesn't even make sense!"
},
{
"id": "loading_file_list",
"translation": "Loading the file list, long file lists can take time to fetch..."
},
{
"id": "torrent_filelist",
"translation": "Torrent filelist"
},
{
"id": "back_to_torrent",
"translation": "Back to \"%s\""
},
{
"id": "uploaded_by",
"translation": "Uploaded by"