2017-06-28 13:42:38 +02:00
package controllers
2017-05-05 16:39:15 +02:00
2017-05-09 13:31:58 +02:00
import (
2017-06-15 15:43:18 +02:00
"errors"
2017-05-25 21:54:58 +02:00
"html"
"net/http"
"strconv"
2017-06-19 01:55:09 +02:00
"strings"
2017-05-25 21:54:58 +02:00
"time"
2017-05-17 07:58:40 +02:00
"github.com/NyaaPantsu/nyaa/config"
2017-06-29 13:15:23 +02:00
"github.com/NyaaPantsu/nyaa/models"
2017-07-02 23:53:23 +02:00
"github.com/NyaaPantsu/nyaa/models/users"
2017-07-02 16:54:55 +02:00
"github.com/NyaaPantsu/nyaa/utils/categories"
"github.com/NyaaPantsu/nyaa/utils/feeds"
"github.com/NyaaPantsu/nyaa/utils/publicSettings"
"github.com/NyaaPantsu/nyaa/utils/search"
2017-06-28 13:42:38 +02:00
"github.com/gin-gonic/gin"
2017-06-14 08:36:38 +02:00
"github.com/gorilla/feeds"
2017-05-05 16:39:15 +02:00
)
2017-05-25 21:54:58 +02:00
// RSSHandler : Controller for displaying rss feed, accepting common search arguments
2017-06-28 13:42:38 +02:00
func RSSHandler ( c * gin . Context ) {
2017-06-15 15:43:18 +02:00
// We only get the basic variable for rss based on search param
2017-06-28 13:42:38 +02:00
torrents , createdAsTime , title , err := getTorrentList ( c )
2017-06-15 15:43:18 +02:00
if err != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusBadRequest , err )
2017-06-15 15:43:18 +02:00
return
}
feed := & nyaafeeds . RssFeed {
Title : title ,
Link : config . WebAddress ( ) + "/" ,
PubDate : createdAsTime . String ( ) ,
}
feed . Items = make ( [ ] * nyaafeeds . RssItem , len ( torrents ) )
for i , torrent := range torrents {
torrentJSON := torrent . ToJSON ( )
feed . Items [ i ] = & nyaafeeds . RssItem {
Title : torrentJSON . Name ,
2017-06-19 01:55:09 +02:00
Link : config . WebAddress ( ) + "/download/" + torrentJSON . Hash ,
2017-06-15 15:43:18 +02:00
Description : string ( torrentJSON . Description ) ,
2017-06-19 01:55:09 +02:00
PubDate : torrent . Date . Format ( time . RFC822 ) ,
2017-06-21 15:38:08 +02:00
GUID : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
2017-06-15 15:43:18 +02:00
Enclosure : & nyaafeeds . RssEnclosure {
2017-06-19 01:55:09 +02:00
URL : config . WebAddress ( ) + "/download/" + strings . TrimSpace ( torrentJSON . Hash ) ,
2017-06-15 15:43:18 +02:00
Length : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
Type : "application/x-bittorrent" ,
2017-06-25 02:45:56 +02:00
} ,
}
}
// allow cross domain AJAX requests
2017-06-28 13:42:38 +02:00
c . Header ( "Access-Control-Allow-Origin" , "*" )
2017-06-25 02:45:56 +02:00
rss , rssErr := feeds . ToXML ( feed )
if rssErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , rssErr )
2017-06-25 02:45:56 +02:00
}
2017-06-28 13:42:38 +02:00
_ , writeErr := c . Writer . Write ( [ ] byte ( rss ) )
2017-06-25 02:45:56 +02:00
if writeErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , writeErr )
2017-06-25 02:45:56 +02:00
}
}
// RSSMagnetHandler : Controller for displaying rss feeds with magnet URL, accepting common search arguments
2017-06-28 13:42:38 +02:00
func RSSMagnetHandler ( c * gin . Context ) {
2017-06-25 02:45:56 +02:00
// We only get the basic variable for rss based on search param
2017-06-28 13:42:38 +02:00
torrents , createdAsTime , title , err := getTorrentList ( c )
2017-06-25 02:45:56 +02:00
if err != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , err )
2017-06-25 02:45:56 +02:00
return
}
feed := & nyaafeeds . RssFeed {
Title : title ,
Link : config . WebAddress ( ) + "/" ,
PubDate : createdAsTime . String ( ) ,
}
feed . Items = make ( [ ] * nyaafeeds . RssItem , len ( torrents ) )
for i , torrent := range torrents {
torrentJSON := torrent . ToJSON ( )
feed . Items [ i ] = & nyaafeeds . RssItem {
Title : torrentJSON . Name ,
2017-07-03 02:37:36 +02:00
Link : & nyaafeeds . RssMagnetLink { Text : string ( torrentJSON . Magnet ) } ,
2017-06-25 02:45:56 +02:00
Description : string ( torrentJSON . Description ) ,
PubDate : torrent . Date . Format ( time . RFC822 ) ,
GUID : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
Enclosure : & nyaafeeds . RssEnclosure {
2017-06-28 13:42:38 +02:00
URL : config . WebAddress ( ) + "/download/" + strings . TrimSpace ( torrentJSON . Hash ) ,
2017-06-25 02:45:56 +02:00
Length : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
Type : "application/x-bittorrent" ,
2017-06-15 15:43:18 +02:00
} ,
}
}
// allow cross domain AJAX requests
2017-06-28 13:42:38 +02:00
c . Header ( "Access-Control-Allow-Origin" , "*" )
2017-06-15 15:43:18 +02:00
rss , rssErr := feeds . ToXML ( feed )
if rssErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , rssErr )
2017-06-15 15:43:18 +02:00
}
2017-06-28 13:42:38 +02:00
_ , writeErr := c . Writer . Write ( [ ] byte ( rss ) )
2017-06-15 15:43:18 +02:00
if writeErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , writeErr )
2017-06-15 15:43:18 +02:00
}
}
// RSSEztvHandler : Controller for displaying rss feed, accepting common search arguments
2017-06-28 13:42:38 +02:00
func RSSEztvHandler ( c * gin . Context ) {
2017-06-15 15:43:18 +02:00
// We only get the basic variable for rss based on search param
2017-06-28 13:42:38 +02:00
torrents , createdAsTime , title , err := getTorrentList ( c )
2017-06-15 15:43:18 +02:00
if err != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , err )
2017-06-15 15:43:18 +02:00
return
}
feed := & nyaafeeds . RssFeed {
Title : title ,
Link : config . WebAddress ( ) + "/" ,
PubDate : createdAsTime . String ( ) ,
}
feed . Items = make ( [ ] * nyaafeeds . RssItem , len ( torrents ) )
for i , torrent := range torrents {
torrentJSON := torrent . ToJSON ( )
feed . Items [ i ] = & nyaafeeds . RssItem {
Title : torrentJSON . Name ,
Link : config . WebAddress ( ) + "/download/" + torrentJSON . Hash ,
Category : & nyaafeeds . RssCategory {
Domain : config . WebAddress ( ) + "/search?c=" + torrentJSON . Category + "_" + torrentJSON . SubCategory ,
} ,
Description : string ( torrentJSON . Description ) ,
Comments : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
2017-06-19 01:55:09 +02:00
PubDate : torrent . Date . Format ( time . RFC822 ) ,
2017-06-15 15:43:18 +02:00
GUID : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
Enclosure : & nyaafeeds . RssEnclosure {
2017-06-19 01:55:09 +02:00
URL : config . WebAddress ( ) + "/download/" + strings . TrimSpace ( torrentJSON . Hash ) ,
2017-06-15 15:43:18 +02:00
Length : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
Type : "application/x-bittorrent" ,
} ,
Torrent : & nyaafeeds . RssTorrent {
Xmlns : "http://xmlns.ezrss.it/0.1/" ,
FileName : torrentJSON . Name + ".torrent" ,
ContentLength : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
InfoHash : torrentJSON . Hash ,
MagnetURI : string ( torrentJSON . Magnet ) ,
} ,
}
}
// allow cross domain AJAX requests
2017-06-28 13:42:38 +02:00
c . Header ( "Access-Control-Allow-Origin" , "*" )
2017-06-15 15:43:18 +02:00
rss , rssErr := feeds . ToXML ( feed )
if rssErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , rssErr )
2017-06-15 15:43:18 +02:00
}
2017-06-28 13:42:38 +02:00
_ , writeErr := c . Writer . Write ( [ ] byte ( rss ) )
2017-06-15 15:43:18 +02:00
if writeErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , writeErr )
2017-06-15 15:43:18 +02:00
}
}
2017-06-15 21:54:06 +02:00
// RSSTorznabHandler : Controller for displaying rss feed, accepting common search arguments
2017-06-28 13:42:38 +02:00
func RSSTorznabHandler ( c * gin . Context ) {
t := c . Query ( "t" )
2017-06-15 21:54:06 +02:00
rss := ""
title := "Nyaa Pantsu"
if config . IsSukebei ( ) {
title = "Sukebei Pantsu"
2017-06-15 15:43:18 +02:00
}
2017-06-15 21:54:06 +02:00
if t == "caps" {
2017-06-28 13:42:38 +02:00
T := publicSettings . GetTfuncFromRequest ( c )
2017-07-06 22:19:44 +02:00
cats := categories . GetSelect ( true , true )
2017-06-15 21:54:06 +02:00
var categories [ ] * nyaafeeds . RssCategoryTorznab
2017-06-18 00:30:12 +02:00
categories = append ( categories , & nyaafeeds . RssCategoryTorznab {
ID : "5070" ,
Name : "Anime" ,
Description : "Anime" ,
} )
2017-07-06 22:19:44 +02:00
2017-06-18 00:30:12 +02:00
last := 0
2017-07-06 22:19:44 +02:00
for _ , v := range cats {
if len ( v . ID ) <= 2 {
2017-06-15 21:54:06 +02:00
categories = append ( categories , & nyaafeeds . RssCategoryTorznab {
2017-07-06 22:19:44 +02:00
ID : nyaafeeds . ConvertFromCat ( v . ID ) ,
Name : string ( T ( v . Name ) ) ,
2017-06-15 21:54:06 +02:00
} )
last ++
} else {
categories [ last ] . Subcat = append ( categories [ last ] . Subcat , & nyaafeeds . RssSubCat {
2017-07-06 22:19:44 +02:00
ID : nyaafeeds . ConvertFromCat ( v . ID ) ,
Name : string ( T ( v . Name ) ) ,
2017-06-15 21:54:06 +02:00
} )
}
}
feed := & nyaafeeds . RssCaps {
Server : & nyaafeeds . RssServer {
Version : "1.0" ,
Title : title ,
Strapline : "..." ,
Email : config . Conf . Email . From ,
URL : config . WebAddress ( ) ,
Image : config . WebAddress ( ) + "/img/logo.png" ,
2017-06-15 15:43:18 +02:00
} ,
2017-06-15 21:54:06 +02:00
Limits : & nyaafeeds . RssLimits {
Max : "300" ,
Default : "50" ,
} ,
Registration : & nyaafeeds . RssRegistration {
Available : "yes" ,
Open : "yes" ,
2017-06-15 15:43:18 +02:00
} ,
2017-06-15 21:54:06 +02:00
Searching : & nyaafeeds . RssSearching {
Search : & nyaafeeds . RssSearch {
Available : "yes" ,
SupportedParams : "q" ,
} ,
TvSearch : & nyaafeeds . RssSearch {
Available : "no" ,
} ,
MovieSearch : & nyaafeeds . RssSearch {
Available : "no" ,
} ,
2017-06-15 15:43:18 +02:00
} ,
2017-06-15 21:54:06 +02:00
Categories : & nyaafeeds . RssCategories {
Category : categories ,
} ,
}
var rssErr error
rss , rssErr = feeds . ToXML ( feed )
if rssErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , rssErr )
2017-06-15 21:54:06 +02:00
}
} else {
// We only get the basic variable for rss based on search param
2017-06-28 13:42:38 +02:00
torrents , createdAsTime , title , err := getTorrentList ( c )
2017-06-15 21:54:06 +02:00
if err != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusBadRequest , err )
2017-06-15 21:54:06 +02:00
return
}
feed := & nyaafeeds . RssFeed {
Title : title ,
2017-06-18 00:30:12 +02:00
Xmlns : "http://torznab.com/schemas/2015/feed" ,
2017-06-15 21:54:06 +02:00
Link : config . WebAddress ( ) + "/" ,
PubDate : createdAsTime . String ( ) ,
}
feed . Items = make ( [ ] * nyaafeeds . RssItem , len ( torrents ) )
for i , torrent := range torrents {
2017-06-18 00:30:12 +02:00
2017-06-15 21:54:06 +02:00
torrentJSON := torrent . ToJSON ( )
2017-06-18 00:30:12 +02:00
filesNumber := ""
if len ( torrentJSON . FileList ) > 0 {
filesNumber = strconv . Itoa ( len ( torrentJSON . FileList ) )
}
seeders := ""
if torrentJSON . Seeders > 0 {
seeders = strconv . Itoa ( int ( torrentJSON . Seeders ) )
}
leechers := ""
if torrentJSON . Leechers > 0 {
leechers = strconv . Itoa ( int ( torrentJSON . Leechers ) )
}
2017-06-15 21:54:06 +02:00
feed . Items [ i ] = & nyaafeeds . RssItem {
Title : torrentJSON . Name ,
Link : config . WebAddress ( ) + "/download/" + torrentJSON . Hash ,
Category : & nyaafeeds . RssCategory {
Domain : config . WebAddress ( ) + "/search?c=" + torrentJSON . Category + "_" + torrentJSON . SubCategory ,
} ,
Description : string ( torrentJSON . Description ) ,
Comments : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
2017-06-19 01:55:09 +02:00
PubDate : torrent . Date . Format ( time . RFC822 ) ,
2017-06-15 21:54:06 +02:00
GUID : config . WebAddress ( ) + "/view/" + strconv . FormatUint ( uint64 ( torrentJSON . ID ) , 10 ) ,
Enclosure : & nyaafeeds . RssEnclosure {
2017-06-19 01:55:09 +02:00
URL : config . WebAddress ( ) + "/download/" + strings . TrimSpace ( torrentJSON . Hash ) ,
2017-06-15 21:54:06 +02:00
Length : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
Type : "application/x-bittorrent" ,
} ,
2017-06-20 14:27:36 +02:00
}
torznab := [ ] * nyaafeeds . RssTorznab { }
if torrentJSON . Filesize > 0 {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "size" ,
Value : strconv . FormatUint ( uint64 ( torrentJSON . Filesize ) , 10 ) ,
} )
}
if filesNumber != "" {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "files" ,
Value : filesNumber ,
} )
}
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "grabs" ,
2017-07-09 14:53:52 +02:00
Value : strconv . Itoa ( int ( torrentJSON . Completed ) ) ,
2017-06-20 14:27:36 +02:00
} )
if seeders != "" {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "seeders" ,
Value : seeders ,
} )
}
if leechers != "" {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "leechers" ,
Value : leechers ,
} )
}
if torrentJSON . Hash != "" {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "infohash" ,
Value : torrentJSON . Hash ,
} )
}
if torrentJSON . Magnet != "" {
torznab = append ( torznab , & nyaafeeds . RssTorznab {
Name : "magneturl" ,
Value : string ( torrentJSON . Magnet ) ,
} )
}
if len ( torznab ) > 0 {
feed . Items [ i ] . Torznab = torznab
2017-06-15 21:54:06 +02:00
}
}
var rssErr error
rss , rssErr = feeds . ToXML ( feed )
if rssErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , rssErr )
2017-06-15 15:43:18 +02:00
}
}
// allow cross domain AJAX requests
2017-06-28 13:42:38 +02:00
c . Header ( "Access-Control-Allow-Origin" , "*" )
2017-06-15 15:43:18 +02:00
2017-06-28 13:42:38 +02:00
_ , writeErr := c . Writer . Write ( [ ] byte ( rss ) )
2017-06-15 15:43:18 +02:00
if writeErr != nil {
2017-06-28 13:42:38 +02:00
c . AbortWithError ( http . StatusInternalServerError , writeErr )
2017-06-15 15:43:18 +02:00
}
}
2017-07-01 23:09:35 +02:00
func getTorrentList ( c * gin . Context ) ( torrents [ ] models . Torrent , createdAsTime time . Time , title string , err error ) {
2017-06-28 13:42:38 +02:00
page := c . Param ( "page" )
userID := c . Param ( "id" )
cat := c . Query ( "cat" )
2017-06-18 00:30:12 +02:00
offset := 0
2017-06-28 13:42:38 +02:00
if c . Query ( "offset" ) != "" {
offset , err = strconv . Atoi ( html . EscapeString ( c . Query ( "offset" ) ) )
2017-06-18 00:30:12 +02:00
if err != nil {
return
}
}
2017-05-17 07:58:40 +02:00
2017-06-18 00:30:12 +02:00
createdAsTime = time . Now ( )
if len ( torrents ) > 0 {
createdAsTime = torrents [ 0 ] . Date
2017-06-15 12:48:38 +02:00
}
2017-06-18 00:30:12 +02:00
title = "Nyaa Pantsu"
if config . IsSukebei ( ) {
title = "Sukebei Pantsu"
}
pagenum := 1
if page == "" && offset > 0 { // first page for offset is 0
pagenum = offset + 1
} else if page != "" {
2017-05-16 23:32:41 +02:00
pagenum , err = strconv . Atoi ( html . EscapeString ( page ) )
if err != nil {
return
}
2017-06-18 00:30:12 +02:00
}
if pagenum <= 0 {
err = errors . New ( "Page number is invalid" )
return
2017-05-16 23:32:41 +02:00
}
2017-05-20 01:09:09 +02:00
if userID != "" {
2017-06-15 15:43:18 +02:00
userIDnum := 0
userIDnum , err = strconv . Atoi ( html . EscapeString ( userID ) )
2017-05-20 01:09:09 +02:00
// Should we have a feed for anonymous uploads?
if err != nil || userIDnum == 0 {
return
}
2017-07-02 23:53:23 +02:00
_ , _ , err = users . FindForAdmin ( uint ( userIDnum ) )
2017-05-20 01:09:09 +02:00
if err != nil {
return
}
// Set the user ID on the request, so that SearchByQuery finds it.
2017-06-28 13:42:38 +02:00
query := c . Request . URL . Query ( )
2017-05-20 01:09:09 +02:00
query . Set ( "userID" , userID )
2017-06-28 13:42:38 +02:00
c . Request . URL . RawQuery = query . Encode ( )
2017-05-20 01:09:09 +02:00
}
2017-06-15 21:54:06 +02:00
if cat != "" {
2017-06-28 13:42:38 +02:00
query := c . Request . URL . Query ( )
catConv := nyaafeeds . ConvertToCat ( cat )
if catConv == "" {
2017-06-18 01:19:46 +02:00
return
2017-06-18 00:30:12 +02:00
}
2017-06-28 13:42:38 +02:00
query . Set ( "c" , catConv )
c . Request . URL . RawQuery = query . Encode ( )
2017-06-15 21:54:06 +02:00
}
2017-07-05 13:33:12 +02:00
_ , torrents , err = search . ByQueryNoCount ( c , pagenum )
2017-06-15 15:43:18 +02:00
return
2017-05-07 15:19:36 +02:00
}