2017-05-02 12:39:53 +02:00
package main
import (
"database/sql"
"encoding/json"
"github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
"html"
"html/template"
"log"
"net/http"
2017-05-02 14:00:57 +02:00
"net/url"
2017-05-02 12:39:53 +02:00
"strconv"
2017-05-03 06:59:27 +02:00
"strings"
2017-05-02 12:39:53 +02:00
"time"
)
var dbHandle * sql . DB
var templates = template . Must ( template . ParseFiles ( "index.html" ) )
var debugLogger * log . Logger
2017-05-03 09:33:39 +02: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 12:39:53 +02:00
type Record struct {
2017-05-03 06:59:27 +02:00
Category string ` json: "category" `
2017-05-02 12:39:53 +02:00
Records [ ] Records ` json: "records" `
QueryRecordCount int ` json: "queryRecordCount" `
TotalRecordCount int ` json: "totalRecordCount" `
}
type Records struct {
2017-05-03 09:33:39 +02:00
Id string ` json: "id" `
Name string ` json: "name" `
Status int ` json: "status" `
Hash string ` json: "hash" `
Magnet template . URL ` json: "magnet" `
2017-05-02 12:39:53 +02:00
}
func getDBHandle ( ) * sql . DB {
db , err := sql . Open ( "sqlite3" , "./nyaa.db" )
checkErr ( err )
return db
}
func checkErr ( err error ) {
if err != nil {
debugLogger . Println ( " " + err . Error ( ) )
}
}
func apiHandler ( w http . ResponseWriter , r * http . Request ) {
vars := mux . Vars ( r )
page := vars [ "page" ]
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
b := Record { Records : [ ] Records { } }
2017-05-03 13:11:16 +02:00
rows , err := dbHandle . Query ( "select torrent_id, torrent_name, status_id, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?" , 50 * ( pagenum - 1 ) )
2017-05-02 12:39:53 +02:00
for rows . Next ( ) {
var id , name , hash , magnet string
2017-05-03 08:58:06 +02:00
var status int
2017-05-03 09:33:39 +02:00
rows . Scan ( & id , & name , & status , & hash )
magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url . QueryEscape ( name ) + trackers
2017-05-02 12:39:53 +02:00
res := Records {
Id : id ,
Name : name ,
2017-05-03 12:01:20 +02:00
Status : status ,
2017-05-02 12:39:53 +02:00
Hash : hash ,
2017-05-03 09:33:39 +02:00
Magnet : safe ( magnet ) }
2017-05-02 12:39:53 +02:00
b . Records = append ( b . Records , res )
}
b . QueryRecordCount = 50
b . TotalRecordCount = 1473098
rows . Close ( )
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 singleapiHandler ( w http . ResponseWriter , r * http . Request ) {
vars := mux . Vars ( r )
id := vars [ "id" ]
2017-05-03 07:01:13 +02:00
b := Record { Records : [ ] Records { } }
2017-05-03 08:58:06 +02:00
rows , err := dbHandle . Query ( "select torrent_id, torrent_name, status_id, torrent_hash from torrents where torrent_id = ? ORDER BY torrent_id DESC" , html . EscapeString ( id ) )
2017-05-02 12:39:53 +02:00
for rows . Next ( ) {
var id , name , hash , magnet string
2017-05-03 08:58:06 +02:00
var status int
2017-05-03 09:33:39 +02:00
rows . Scan ( & id , & name , & status , & hash )
magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url . QueryEscape ( name ) + trackers
2017-05-02 12:39:53 +02:00
res := Records {
Id : id ,
Name : name ,
2017-05-03 12:01:20 +02:00
Status : status ,
2017-05-02 12:39:53 +02:00
Hash : hash ,
2017-05-03 09:33:39 +02:00
Magnet : safe ( magnet ) }
2017-05-02 12:39:53 +02:00
b . Records = append ( b . Records , res )
}
b . QueryRecordCount = 1
b . TotalRecordCount = 1473098
rows . Close ( )
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 ) {
vars := mux . Vars ( r )
page := vars [ "page" ]
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
param1 := r . URL . Query ( ) . Get ( "q" )
2017-05-03 06:59:27 +02:00
cat := r . URL . Query ( ) . Get ( "c" )
param2 := strings . Split ( cat , "_" ) [ 0 ]
param3 := strings . Split ( cat , "_" ) [ 1 ]
b := Record { Category : cat , Records : [ ] Records { } }
2017-05-03 08:58:06 +02:00
rows , err := dbHandle . Query ( "select torrent_id, torrent_name, status_id, torrent_hash from torrents " +
2017-05-03 06:59:27 +02:00
"where torrent_name LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ? " +
"ORDER BY torrent_id DESC LIMIT 50 offset ?" ,
2017-05-03 12:01:20 +02:00
"%" + html . EscapeString ( param1 ) + "%" , html . EscapeString ( param2 ) + "%" , html . EscapeString ( param3 ) + "%" , 50 * ( pagenum - 1 ) )
2017-05-02 12:39:53 +02:00
for rows . Next ( ) {
var id , name , hash , magnet string
2017-05-03 12:01:20 +02:00
var status int
2017-05-03 09:33:39 +02:00
rows . Scan ( & id , & name , & status , & hash )
magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url . QueryEscape ( name ) + trackers
2017-05-02 12:39:53 +02:00
res := Records {
Id : id ,
Name : name ,
2017-05-03 12:01:20 +02:00
Status : status ,
2017-05-02 12:39:53 +02:00
Hash : hash ,
2017-05-03 09:33:39 +02:00
Magnet : safe ( magnet ) }
2017-05-02 12:39:53 +02:00
b . Records = append ( b . Records , res )
}
rows . Close ( )
err = templates . ExecuteTemplate ( w , "index.html" , & b )
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
2017-05-03 09:33:39 +02:00
func safe ( s string ) template . URL {
return template . URL ( s )
}
2017-05-02 12:39:53 +02:00
func rootHandler ( w http . ResponseWriter , r * http . Request ) {
vars := mux . Vars ( r )
page := vars [ "page" ]
pagenum , _ := strconv . Atoi ( html . EscapeString ( page ) )
2017-05-03 06:59:27 +02:00
b := Record { Category : "_" , Records : [ ] Records { } }
2017-05-03 13:11:16 +02:00
rows , err := dbHandle . Query ( "select torrent_id, torrent_name, status_id, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?" , 50 * ( pagenum - 1 ) )
2017-05-02 12:39:53 +02:00
for rows . Next ( ) {
var id , name , hash , magnet string
2017-05-03 12:01:20 +02:00
var status int
2017-05-03 09:33:39 +02:00
rows . Scan ( & id , & name , & status , & hash )
magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url . QueryEscape ( name ) + trackers
2017-05-02 12:39:53 +02:00
res := Records {
Id : id ,
Name : name ,
2017-05-03 12:01:20 +02:00
Status : status ,
2017-05-02 12:39:53 +02:00
Hash : hash ,
2017-05-03 09:33:39 +02:00
Magnet : safe ( magnet ) }
2017-05-02 12:39:53 +02:00
b . Records = append ( b . Records , res )
}
b . QueryRecordCount = 50
b . TotalRecordCount = 1473098
rows . Close ( )
err = templates . ExecuteTemplate ( w , "index.html" , & b )
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
}
}
func main ( ) {
dbHandle = getDBHandle ( )
router := mux . NewRouter ( )
// Routes,
router . HandleFunc ( "/" , rootHandler )
router . HandleFunc ( "/page/{page}" , rootHandler )
router . HandleFunc ( "/search" , searchHandler )
2017-05-02 13:07:04 +02:00
router . HandleFunc ( "/search/{page}" , searchHandler )
2017-05-02 12:39:53 +02:00
router . HandleFunc ( "/api/{page}" , apiHandler ) . Methods ( "GET" )
router . HandleFunc ( "/api/torrent/{id}" , singleapiHandler ) . Methods ( "GET" )
// Set up server,
srv := & http . Server {
Handler : router ,
Addr : "localhost:9999" ,
WriteTimeout : 15 * time . Second ,
ReadTimeout : 15 * time . Second ,
}
err := srv . ListenAndServe ( )
checkErr ( err )
}