2017-05-02 20:39:53 +10:00
package main
import (
2017-05-05 11:57:08 +10:00
"bytes"
"compress/zlib"
2017-05-02 20:39:53 +10:00
"encoding/json"
2017-05-04 21:48:40 +02:00
"github.com/gorilla/feeds"
2017-05-02 20:39:53 +10:00
"github.com/gorilla/mux"
2017-05-04 05:28:42 +02:00
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
2017-05-02 20:39:53 +10:00
"html"
"html/template"
2017-05-05 11:57:08 +10:00
"io/ioutil"
2017-05-02 20:39:53 +10:00
"log"
"net/http"
"strconv"
2017-05-03 07:59:27 +03:00
"strings"
2017-05-02 20:39:53 +10:00
"time"
)
2017-05-04 05:28:42 +02:00
var db * gorm . DB
2017-05-05 03:53:38 +02:00
var router * mux . Router
2017-05-02 20:39:53 +10:00
var debugLogger * log . Logger
2017-05-03 10:33:39 +03:00
var trackers = "&tr=udp://zer0day.to:1337/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://explodie.org:6969&tr=udp://tracker.opentrackr.org:1337&tr=udp://tracker.coppersurfer.tk:6969"
2017-05-02 20:39:53 +10:00
2017-05-04 05:28:42 +02:00
func getDBHandle ( ) * gorm . DB {
dbInit , err := gorm . Open ( "sqlite3" , "./nyaa.db" )
2017-05-02 20:39:53 +10:00
2017-05-04 05:28:42 +02:00
// Migrate the schema of Torrents
2017-05-05 07:24:58 +03:00
dbInit . AutoMigrate ( & Torrents { } , & Categories { } , & Sub_Categories { } , & Statuses { } )
2017-05-02 20:39:53 +10:00
checkErr ( err )
2017-05-04 05:28:42 +02:00
return dbInit
2017-05-02 20:39:53 +10:00
}
func checkErr ( err error ) {
if err != nil {
debugLogger . Println ( " " + err . Error ( ) )
}
}
2017-05-05 11:57:08 +10:00
func unZlib ( description [ ] byte ) string {
2017-05-05 14:07:45 +10:00
if len ( description ) > 0 {
2017-05-05 05:04:04 +02:00
b := bytes . NewReader ( description )
log . Println ( b )
z , err := zlib . NewReader ( b )
checkErr ( err )
defer z . Close ( )
p , err := ioutil . ReadAll ( z )
checkErr ( err )
return string ( p )
2017-05-05 14:07:45 +10:00
}
2017-05-05 05:04:04 +02:00
return ""
2017-05-05 11:57:08 +10:00
}
2017-05-02 20:39:53 +10:00
func apiHandler ( w http . ResponseWriter , r * http . Request ) {
vars := mux . Vars ( r )
page := vars [ "page" ]
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
2017-05-04 05:28:42 +02:00
b := CategoryJson { Torrents : [ ] TorrentsJson { } }
maxPerPage := 50
nbTorrents := 0
2017-05-05 03:53:38 +02:00
torrents , nbTorrents := getAllTorrents ( maxPerPage , maxPerPage * ( pagenum - 1 ) )
2017-05-04 05:28:42 +02:00
for i , _ := range torrents {
res := torrents [ i ] . toJson ( )
b . Torrents = append ( b . Torrents , res )
2017-05-02 20:39:53 +10:00
}
2017-05-05 03:53:38 +02:00
2017-05-04 05:28:42 +02:00
b . QueryRecordCount = maxPerPage
b . TotalRecordCount = nbTorrents
2017-05-02 20:39:53 +10:00
w . Header ( ) . Set ( "Content-Type" , "application/json" )
2017-05-04 05:28:42 +02:00
err := json . NewEncoder ( w ) . Encode ( b )
2017-05-02 20:39:53 +10:00
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
return
}
}
2017-05-04 17:16:20 +02:00
2017-05-05 10:54:37 +10:00
func apiViewHandler ( w http . ResponseWriter , r * http . Request ) {
2017-05-02 20:39:53 +10:00
vars := mux . Vars ( r )
id := vars [ "id" ]
2017-05-04 05:28:42 +02:00
b := CategoryJson { Torrents : [ ] TorrentsJson { } }
torrent , err := getTorrentById ( id )
res := torrent . toJson ( )
b . Torrents = append ( b . Torrents , res )
2017-05-02 20:39:53 +10:00
b . QueryRecordCount = 1
2017-05-04 05:28:42 +02:00
b . TotalRecordCount = 1
2017-05-02 20:39:53 +10:00
w . Header ( ) . Set ( "Content-Type" , "application/json" )
err = json . NewEncoder ( w ) . Encode ( b )
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
return
}
}
func searchHandler ( w http . ResponseWriter , r * http . Request ) {
2017-05-05 03:53:38 +02:00
var templates = template . Must ( template . New ( "home" ) . Funcs ( funcMap ) . ParseFiles ( "templates/index.html" , "templates/home.html" ) )
2017-05-02 20:39:53 +10:00
vars := mux . Vars ( r )
page := vars [ "page" ]
2017-05-03 19:45:18 +02:00
// db params url
2017-05-04 08:20:50 +10:00
maxPerPage , errConv := strconv . Atoi ( r . URL . Query ( ) . Get ( "max" ) )
if errConv != nil {
2017-05-03 19:45:18 +02:00
maxPerPage = 50 // default Value maxPerPage
2017-05-04 08:20:50 +10:00
}
2017-05-02 20:39:53 +10:00
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
2017-05-05 14:07:45 +10:00
if pagenum == 0 {
pagenum = 1
}
2017-05-04 05:28:42 +02:00
searchQuery := r . URL . Query ( ) . Get ( "q" )
2017-05-03 07:59:27 +03:00
cat := r . URL . Query ( ) . Get ( "c" )
2017-05-04 15:01:07 +03:00
stat := r . URL . Query ( ) . Get ( "s" )
2017-05-05 07:24:58 +03:00
sort := r . URL . Query ( ) . Get ( "sort" )
order := r . URL . Query ( ) . Get ( "order" )
2017-05-04 16:53:21 +10:00
catsSplit := strings . Split ( cat , "_" )
2017-05-04 15:01:29 +10:00
// need this to prevent out of index panics
var searchCatId , searchSubCatId string
if len ( catsSplit ) == 2 {
2017-05-04 16:53:21 +10:00
2017-05-04 15:01:29 +10:00
searchCatId = html . EscapeString ( catsSplit [ 0 ] )
searchSubCatId = html . EscapeString ( catsSplit [ 1 ] )
}
2017-05-05 07:24:58 +03:00
if sort == "" {
sort = "torrent_id"
}
if order == "" {
order = "desc"
}
order_by := sort + " " + order
2017-05-03 19:45:18 +02:00
nbTorrents := 0
2017-05-04 05:28:42 +02:00
b := [ ] TorrentsJson { }
2017-05-04 08:54:07 +10:00
2017-05-05 07:24:58 +03:00
parameters := createWhereParams ( "torrent_name LIKE ? AND status_id LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ?" ,
"%" + searchQuery + "%" , stat + "%" , searchCatId + "%" , searchSubCatId + "%" )
2017-05-05 05:04:04 +02:00
torrents , nbTorrents := getTorrentsOrderBy ( & parameters , order_by , maxPerPage , maxPerPage * ( pagenum - 1 ) )
2017-05-04 13:38:11 +10:00
2017-05-04 05:28:42 +02:00
for i , _ := range torrents {
res := torrents [ i ] . toJson ( )
b = append ( b , res )
2017-05-02 20:39:53 +10:00
}
2017-05-05 03:53:38 +02:00
navigationTorrents := Navigation { nbTorrents , maxPerPage , pagenum , "search_page" }
2017-05-05 05:04:04 +02:00
htv := HomeTemplateVariables { b , getAllCategories ( false ) , searchQuery , stat , cat , sort , order , navigationTorrents , r . URL , mux . CurrentRoute ( r ) }
2017-05-04 05:28:42 +02:00
err := templates . ExecuteTemplate ( w , "index.html" , htv )
2017-05-02 20:39:53 +10:00
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
2017-05-03 10:33:39 +03:00
func safe ( s string ) template . URL {
return template . URL ( s )
}
2017-05-02 20:39:53 +10:00
2017-05-04 09:15:20 +10:00
func faqHandler ( w http . ResponseWriter , r * http . Request ) {
2017-05-05 03:53:38 +02:00
var templates = template . Must ( template . New ( "FAQ" ) . Funcs ( funcMap ) . ParseFiles ( "templates/index.html" , "templates/FAQ.html" ) )
2017-05-05 05:04:04 +02:00
err := templates . ExecuteTemplate ( w , "index.html" , FaqTemplateVariables { r . URL , mux . CurrentRoute ( r ) , "" , "" , "_" , "torrent_id" , "desc" , Navigation { } } )
2017-05-04 09:15:20 +10:00
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
2017-05-04 21:48:40 +02:00
func rssHandler ( w http . ResponseWriter , r * http . Request ) {
//vars := mux.Vars(r)
//category := vars["c"]
// db params url
//maxPerPage := 50 // default Value maxPerPage
torrents := getFeeds ( )
created := time . Now ( ) . String ( )
2017-05-05 07:24:58 +03:00
if len ( torrents ) > 0 {
2017-05-04 21:48:40 +02:00
created = torrents [ 0 ] . Timestamp
}
created_as_time , err := time . Parse ( "2006-01-02 15:04:05" , created )
if err == nil {
2017-05-05 07:24:58 +03:00
2017-05-04 21:48:40 +02:00
}
feed := & feeds . Feed {
2017-05-05 07:24:58 +03:00
Title : "Nyaa Pantsu" ,
Link : & feeds . Link { Href : "https://nyaa.pantsu.cat/" } ,
Created : created_as_time ,
2017-05-04 21:48:40 +02:00
}
feed . Items = [ ] * feeds . Item { }
2017-05-05 07:24:58 +03:00
feed . Items = make ( [ ] * feeds . Item , len ( torrents ) )
2017-05-04 21:48:40 +02:00
for i , _ := range torrents {
timestamp_as_time , err := time . Parse ( "2006-01-02 15:04:05" , torrents [ i ] . Timestamp )
if err == nil {
2017-05-05 07:24:58 +03:00
feed . Items [ i ] = & feeds . Item {
2017-05-04 21:48:40 +02:00
// need a torrent view first
//Id: URL + torrents[i].Hash,
2017-05-05 07:24:58 +03:00
Title : torrents [ i ] . Name ,
Link : & feeds . Link { Href : string ( torrents [ i ] . Magnet ) } ,
2017-05-04 21:48:40 +02:00
Description : "" ,
2017-05-05 07:24:58 +03:00
Created : timestamp_as_time ,
Updated : timestamp_as_time ,
2017-05-04 21:48:40 +02:00
}
}
}
rss , err := feed . ToRss ( )
if err == nil {
2017-05-05 07:24:58 +03:00
w . Write ( [ ] byte ( rss ) )
2017-05-04 21:48:40 +02:00
} else {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
2017-05-05 10:54:37 +10:00
func viewHandler ( w http . ResponseWriter , r * http . Request ) {
2017-05-05 05:04:04 +02:00
var templates = template . Must ( template . ParseFiles ( "templates/index.html" , "templates/view.html" ) )
2017-05-05 10:54:37 +10:00
vars := mux . Vars ( r )
id := vars [ "id" ]
b := [ ] TorrentsJson { }
torrent , err := getTorrentById ( id )
res := torrent . toJson ( )
b = append ( b , res )
2017-05-05 05:04:04 +02:00
htv := HomeTemplateVariables { b , getAllCategories ( false ) , "" , "" , "_" , "" , "" , Navigation { } , r . URL , mux . CurrentRoute ( r ) }
2017-05-05 10:54:37 +10:00
2017-05-05 05:04:04 +02:00
err = templates . ExecuteTemplate ( w , "index.html" , htv )
2017-05-04 09:15:20 +10:00
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
2017-05-02 20:39:53 +10:00
func rootHandler ( w http . ResponseWriter , r * http . Request ) {
2017-05-05 03:53:38 +02:00
var templates = template . Must ( template . New ( "home" ) . Funcs ( funcMap ) . ParseFiles ( "templates/index.html" , "templates/home.html" ) )
2017-05-02 20:39:53 +10:00
vars := mux . Vars ( r )
page := vars [ "page" ]
2017-05-03 19:45:18 +02:00
2017-05-04 08:20:50 +10:00
// db params url
maxPerPage , errConv := strconv . Atoi ( r . URL . Query ( ) . Get ( "max" ) )
if errConv != nil {
2017-05-03 19:45:18 +02:00
maxPerPage = 50 // default Value maxPerPage
2017-05-04 08:20:50 +10:00
}
2017-05-03 19:45:18 +02:00
nbTorrents := 0
2017-05-02 20:39:53 +10:00
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
2017-05-05 14:07:45 +10:00
if pagenum == 0 {
pagenum = 1
}
2017-05-05 03:53:38 +02:00
2017-05-04 05:28:42 +02:00
b := [ ] TorrentsJson { }
2017-05-05 03:53:38 +02:00
torrents , nbTorrents := getAllTorrents ( maxPerPage , maxPerPage * ( pagenum - 1 ) )
2017-05-04 05:28:42 +02:00
for i , _ := range torrents {
res := torrents [ i ] . toJson ( )
b = append ( b , res )
2017-05-02 20:39:53 +10:00
}
2017-05-04 05:28:42 +02:00
2017-05-05 03:53:38 +02:00
navigationTorrents := Navigation { nbTorrents , maxPerPage , pagenum , "search_page" }
2017-05-05 05:04:04 +02:00
htv := HomeTemplateVariables { b , getAllCategories ( false ) , "" , "" , "_" , "torrent_id" , "desc" , navigationTorrents , r . URL , mux . CurrentRoute ( r ) }
2017-05-04 05:28:42 +02:00
err := templates . ExecuteTemplate ( w , "index.html" , htv )
2017-05-02 20:39:53 +10:00
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
func main ( ) {
2017-05-04 05:28:42 +02:00
db = getDBHandle ( )
2017-05-05 03:53:38 +02:00
router = mux . NewRouter ( )
2017-05-02 20:39:53 +10:00
2017-05-03 19:45:18 +02:00
cssHandler := http . FileServer ( http . Dir ( "./css/" ) )
jsHandler := http . FileServer ( http . Dir ( "./js/" ) )
2017-05-05 03:53:38 +02:00
imgHandler := http . FileServer ( http . Dir ( "./img/" ) )
2017-05-04 08:20:50 +10:00
http . Handle ( "/css/" , http . StripPrefix ( "/css/" , cssHandler ) )
http . Handle ( "/js/" , http . StripPrefix ( "/js/" , jsHandler ) )
2017-05-05 03:53:38 +02:00
http . Handle ( "/img/" , http . StripPrefix ( "/img/" , imgHandler ) )
2017-05-03 19:45:18 +02:00
2017-05-02 20:39:53 +10:00
// Routes,
2017-05-05 03:53:38 +02:00
router . HandleFunc ( "/" , rootHandler ) . Name ( "home" )
router . HandleFunc ( "/page/{page:[0-9]+}" , rootHandler ) . Name ( "home_page" )
router . HandleFunc ( "/search" , searchHandler ) . Name ( "search" )
router . HandleFunc ( "/search/{page}" , searchHandler ) . Name ( "search_page" )
2017-05-02 20:39:53 +10:00
router . HandleFunc ( "/api/{page}" , apiHandler ) . Methods ( "GET" )
2017-05-05 10:54:37 +10:00
router . HandleFunc ( "/api/view/{id}" , apiViewHandler ) . Methods ( "GET" )
2017-05-05 03:53:38 +02:00
router . HandleFunc ( "/faq" , faqHandler ) . Name ( "faq" )
2017-05-04 21:48:40 +02:00
router . HandleFunc ( "/feed.xml" , rssHandler )
2017-05-05 05:04:04 +02:00
router . HandleFunc ( "/view/{id}" , viewHandler ) . Name ( "view_torrent" )
2017-05-03 19:45:18 +02:00
http . Handle ( "/" , router )
2017-05-02 20:39:53 +10:00
// Set up server,
srv := & http . Server {
Addr : "localhost:9999" ,
WriteTimeout : 15 * time . Second ,
ReadTimeout : 15 * time . Second ,
}
err := srv . ListenAndServe ( )
checkErr ( err )
}