5dcd30676f
* Fix "torrent is being generated" message showing up even when the torrent couldn't be generated * Add janitor user status * Remove usage of deprecated HasAdmin() function * Give Janitors access to mod panel * Stop using deprecated HasAdmin() function * Stop using deprecated HasAdmin() function * Update edit.go * Update profile.go * Rollback bad changes, remove redundant email check and stop using deprecated function * Show every userstatus (member, janitor, banned, mod) in comments * Return empty status if anonymous * Show no userstatus for anonymous profile * Show moderation link to janitors too * Stop using deprecated HasAdmin() function * Stop using deprecated HasAdmin() function * Stop using deprecated HasAdmin() function * Add Janitor to userstatus select in user edit * "Janitor" translation string * didnt mean to commit this change * rollback wrongfully comitted changes * rollback commit * Update CHANGELOG.md * Fix wrong id for translation * remove deprecated HasAdmin() function again * change name of variable used in comment loop for clarity purposes * visual cue for locked torrents in torrent listing for admins * add visual cues for hidden torrents in admin torrent listing * Dont show delete buttons for janitors * janitor cannot delete torrents * show block/unblock button in torrent list for janitors instead of delete button * fix function that didnt get executed * add ban buttons on userlist & visual cue for banned users * Fix "user successfully deleted" message showing even if user wasnt deleted * Add "ban" button, no "delete" button for jantiors * add "unban" and "ban" translation strings * add "unban" and "ban" translation strings * different <form> for ban button * Update index.jet.html * add userprofile ban route * add toggleBan() function, janitors dont need captcha either * fix panic error when deleting an anonymous comment * add user_banned_by and user_unbanned_by * add user_banned_by and user_unbanned_by * Make ToggleBan() return whether or not the user is now banned * Add handler for /ban route * change log filter * hide locked torrents from regular users * hide locked torrents from regular users * hide locked torrent from api search for regular users * change function to CurrentOrJanitor * change function to currentorjanitor * change function to currentorjanitor * add CurrentOrJanitor function * fix extra ( * fix extra ) and wrong variable name * Fix wrong value for janitor user status * Fix user edit that did not work because of "unique constraint user.emails" error * only immediately visually update user if user has been updated successfully * use FindAllForAdminsOrderBy in order to preload users * create FindAllForAdminsOrderBy that preloads users * Show username instead of ID in Uploader column in admin panel * Fix userprofile buttons overflowing at some specific resolutions * Mods can set users as janitors * Show ban/unban buttons on userprofile for janitors * Identical styling for usermenu links and buttons * dont show ban buttons on other staff * add ban message through get parameter * make toggleBan() trigger user update * Add "user_banned" and "user_unbanned" * add "user_banned" and "user_unbanned" * Visual cue for banned user * banned users can still log in * visual cue for banned user in badgemenu * locked status if banned user on upload * banned users cannot comment * Put "banned" text between () * add GetCategoryName() to template_test * add GetCategoryName() that returns full category name from full category string * Show search content in page title if it exists, or search category if it exists, otherwise shows "Home" * error message when user uploads an torrent & is banned * add torrent_uploaded_locked * add torrent_uploaded_locked * fix delete definitely button that never appeared * Show delete definitely button on admin panel index * admins can undelete a torrent by editing it's status * Trigger ViewHandler() directly instead of redirecting * Render the template directly instead of triggering torrent view handler * bigger usermenu buttons once responsive design kicks in * make btn-* class non-bold * Responsive notification page * visual cue for locked torrents in torrent listing * Update search.go * Update search.go * Update api.go * Update helpers.go * Update template.go * Update torrentParam.go * remove "hidden" class * Update search.go * fix an html error * Add files via upload * Update admin.jet.html * Update index.go * Update index.go * Update router.go * Update torrentParam_test.go * Update torrentParam_test.go * fix extra " * fix bad copypaste * Update CHANGELOG.md * Update guidelines.jet.html * Update CHANGELOG.md * add Guidelines and Moderation Guidelines * fix missing commas * Update torrentlist.jet.html * Update find.go * Update stats.go * Update view.jet.html * Update index.jet.html
106 lignes
3,7 Kio
Go
106 lignes
3,7 Kio
Go
package torrentController
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/NyaaPantsu/nyaa/models/torrents"
|
|
"github.com/NyaaPantsu/nyaa/models"
|
|
"github.com/NyaaPantsu/nyaa/config"
|
|
"github.com/Stephen304/goscrape"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ViewHeadHandler : Controller for getting torrent stats
|
|
func GetStatsHandler(c *gin.Context) {
|
|
id, err := strconv.ParseInt(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
torrent, err := torrents.FindRawByID(uint(id))
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var CurrentData models.Scrape
|
|
statsExists := !(models.ORM.Where("torrent_id = ?", id).Find(&CurrentData).RecordNotFound())
|
|
|
|
if statsExists {
|
|
//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 {
|
|
//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 {
|
|
//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
|
|
}
|
|
}
|
|
|
|
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 {
|
|
stats.Seeders = -1
|
|
}
|
|
|
|
c.JSON(200, gin.H{
|
|
"seeders": stats.Seeders,
|
|
"leechers": stats.Leechers,
|
|
"downloads": stats.Completed,
|
|
})
|
|
|
|
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
|
|
} 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()}
|
|
} else {
|
|
torrent.Scrape = &models.Scrape{uint(id), uint32(CurrentData.Seeders), uint32(CurrentData.Leechers), uint32(CurrentData.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
|
|
torrent.Scrape.Update(false)
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func contains(s []string, e string) bool {
|
|
for _, a := range s {
|
|
if a == e {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|