diff --git a/index.html b/index.html
index da7754bc..ab547d03 100644
--- a/index.html
+++ b/index.html
@@ -94,7 +94,7 @@
Hash |
Links |
- {{ range .Records}}
+ {{ range .ListTorrents}}
diff --git a/main.go b/main.go
index dbd3091d..f297697f 100644
--- a/main.go
+++ b/main.go
@@ -1,44 +1,33 @@
package main
import (
- "database/sql"
"encoding/json"
"github.com/gorilla/mux"
- _ "github.com/mattn/go-sqlite3"
+ "github.com/jinzhu/gorm"
+ _ "github.com/jinzhu/gorm/dialects/sqlite"
"html"
"html/template"
"log"
"net/http"
- "net/url"
"strconv"
"strings"
"time"
)
-var dbHandle *sql.DB
+var db *gorm.DB
var templates = template.Must(template.ParseFiles("index.html", "FAQ.html"))
var debugLogger *log.Logger
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"
-type Record struct {
- Category string `json: "category"`
- Records []Records `json: "records"`
- QueryRecordCount int `json: "queryRecordCount"`
- TotalRecordCount int `json: "totalRecordCount"`
-}
+func getDBHandle() *gorm.DB {
+ dbInit, err := gorm.Open("sqlite3", "./nyaa.db")
-type Records struct {
- Id string `json: "id"`
- Name string `json: "name"`
- Status int `json: "status"`
- Hash string `json: "hash"`
- Magnet template.URL `json: "magnet"`
-}
+ // Migrate the schema of Torrents
+ // dbInit.AutoMigrate(&Torrents{})
+ // dbInit.AutoMigrate(&SubCategories{})
-func getDBHandle() *sql.DB {
- db, err := sql.Open("sqlite3", "./nyaa.db")
checkErr(err)
- return db
+ return dbInit
}
func checkErr(err error) {
@@ -52,29 +41,22 @@ 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{}}
- 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))
- checkErr(err)
- for rows.Next() {
- var id, name, hash, magnet string
- var status int
- rows.Scan(&id, &name, &status, &hash)
- magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
- res := Records{
- Id: id,
- Name: name,
- Status: status,
- Hash: hash,
- Magnet: safe(magnet)}
- b.Records = append(b.Records, res)
+ b := CategoryJson{Torrents: []TorrentsJson{}}
+ maxPerPage := 50
+ nbTorrents := 0
+ torrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
+ for i, _ := range torrents {
+ nbTorrents++
+ res := torrents[i].toJson()
+
+ b.Torrents = append(b.Torrents, res)
}
- b.QueryRecordCount = 50
- b.TotalRecordCount = 1473098
- rows.Close()
+ b.QueryRecordCount = maxPerPage
+ b.TotalRecordCount = nbTorrents
w.Header().Set("Content-Type", "application/json")
- err = json.NewEncoder(w).Encode(b)
+ err := json.NewEncoder(w).Encode(b)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -85,27 +67,14 @@ func singleapiHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
- b := Record{Records: []Records{}}
- 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))
- checkErr(err)
- for rows.Next() {
- var id, name, hash, magnet string
- var status int
- rows.Scan(&id, &name, &status, &hash)
- magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
- res := Records{
- Id: id,
- Name: name,
- Status: status,
- Hash: hash,
- Magnet: safe(magnet)}
+ b := CategoryJson{Torrents: []TorrentsJson{}}
- b.Records = append(b.Records, res)
+ torrent, err := getTorrentById(id)
+ res := torrent.toJson()
+ b.Torrents = append(b.Torrents, res)
- }
b.QueryRecordCount = 1
- b.TotalRecordCount = 1473098
- rows.Close()
+ b.TotalRecordCount = 1
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(b)
@@ -125,46 +94,28 @@ func searchHandler(w http.ResponseWriter, r *http.Request) {
maxPerPage = 50 // default Value maxPerPage
}
pagenum, _ := strconv.Atoi(html.EscapeString(page))
- param1 := r.URL.Query().Get("q")
+ searchQuery := r.URL.Query().Get("q")
cat := r.URL.Query().Get("c")
-
- var param2, param3 string
- params := strings.Split(cat, "_")
- if len(params) == 2 {
- param2 = params[0]
- param3 = params[1]
- }
+ searchCatId := html.EscapeString(strings.Split(cat, "_")[0])
+ searchSubCatId := html.EscapeString(strings.Split(cat, "_")[1])
nbTorrents := 0
- b := Record{Category: cat, Records: []Records{}}
- rows, err := dbHandle.Query("select torrent_id, torrent_name, status_id, torrent_hash from torrents "+
- "where torrent_name LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ? "+
- "ORDER BY torrent_id DESC LIMIT ? offset ?",
- "%"+html.EscapeString(param1)+"%", html.EscapeString(param2)+"%", html.EscapeString(param3)+"%", maxPerPage, maxPerPage*(pagenum-1))
+ b := []TorrentsJson{}
- checkErr(err)
- defer rows.Close()
- for rows.Next() {
+ torrents := getTorrents(createWhereParams("torrent_name LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ?", "%"+searchQuery+"%", searchCatId+"%", searchSubCatId+"%"), maxPerPage, maxPerPage*(pagenum-1))
+
+ for i, _ := range torrents {
nbTorrents++
- var id, name, hash, magnet string
- var status int
- rows.Scan(&id, &name, &status, &hash)
- magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
- res := Records{
- Id: id,
- Name: name,
- Status: status,
- Hash: hash,
- Magnet: safe(magnet)}
+ res := torrents[i].toJson()
- b.Records = append(b.Records, res)
+ b = append(b, res)
}
- b.QueryRecordCount = maxPerPage
- b.TotalRecordCount = nbTorrents
- err = templates.ExecuteTemplate(w, "index.html", &b)
+ htv := HomeTemplateVariables{b, getAllCategories(false), searchQuery, cat, maxPerPage, nbTorrents}
+
+ err := templates.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
@@ -192,29 +143,19 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
nbTorrents := 0
pagenum, _ := strconv.Atoi(html.EscapeString(page))
- b := Record{Category: "_", Records: []Records{}}
- rows, err := dbHandle.Query("select torrent_id, torrent_name, status_id, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT ? offset ?", maxPerPage, maxPerPage*(pagenum-1))
- checkErr(err)
- for rows.Next() {
+ b := []TorrentsJson{}
+ torrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
+ for i, _ := range torrents {
nbTorrents++
- var id, name, hash, magnet string
- var status int
- rows.Scan(&id, &name, &status, &hash)
- magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
- res := Records{
- Id: id,
- Name: name,
- Status: status,
- Hash: hash,
- Magnet: safe(magnet)}
+ res := torrents[i].toJson()
- b.Records = append(b.Records, res)
+ b = append(b, res)
}
- b.QueryRecordCount = maxPerPage
- b.TotalRecordCount = nbTorrents
- rows.Close()
- err = templates.ExecuteTemplate(w, "index.html", &b)
+
+ htv := HomeTemplateVariables{b, getAllCategories(false), "", "_", maxPerPage, nbTorrents}
+
+ err := templates.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
@@ -223,8 +164,8 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
func main() {
- dbHandle = getDBHandle()
- router := mux.NewRouter().StrictSlash(true)
+ db = getDBHandle()
+ router := mux.NewRouter()
cssHandler := http.FileServer(http.Dir("./css/"))
jsHandler := http.FileServer(http.Dir("./js/"))
diff --git a/models.go b/models.go
new file mode 100644
index 00000000..0a3c9981
--- /dev/null
+++ b/models.go
@@ -0,0 +1,157 @@
+package main
+
+import (
+ "github.com/jinzhu/gorm"
+ "html"
+ "html/template"
+ "strconv"
+ "net/url"
+ "errors"
+)
+
+type Categories struct {
+ Category_id int
+ Category_name string
+ Torrents []Torrents `gorm:"ForeignKey:category_id;AssociationForeignKey:category_id"`
+ Sub_category []Sub_Categories `gorm:"ForeignKey:category_id;AssociationForeignKey:parent_id"`
+}
+
+type Sub_Categories struct {
+ Sub_category_id int
+ Sub_category_name string
+ Parent_id int
+ Torrents []Torrents `gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id"`
+}
+
+type Torrents struct {
+ gorm.Model
+ Id int `gorm:"column:torrent_id"`
+ Name string `gorm:"column:torrent_name"`
+ Category_id int `gorm:"column:category_id"`
+ Sub_category_id int
+ Status int `gorm:"column:status_id"`
+ Hash string `gorm:"column:torrent_hash"`
+ Categories Categories `gorm:"ForeignKey:category_id;AssociationForeignKey:category_id"`
+ Sub_Categories Sub_Categories `gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id"`
+}
+
+
+
+/* We need JSON Object instead because of Magnet URL that is not in the database but generated dynamically
+--------------------------------------------------------------------------------------------------------------
+JSON Models Oject
+--------------------------------------------------------------------------------------------------------------
+*/
+
+type CategoryJson struct {
+ Category string `json: "category"`
+ Torrents []TorrentsJson `json: "torrents"`
+ QueryRecordCount int `json: "queryRecordCount"`
+ TotalRecordCount int `json: "totalRecordCount"`
+}
+
+type TorrentsJson struct {
+ Id string `json: "id"` // Is there a need to put the ID?
+ Name string `json: "name"`
+ Status int `json: "status"`
+ Hash string `json: "hash"`
+ Magnet template.URL `json: "magnet"`
+}
+
+type WhereParams struct {
+ conditions string // Ex : name LIKE ? AND category_id LIKE ?
+ params []interface{}
+}
+
+
+/* Each Page should have an object to pass to their own template */
+
+type HomeTemplateVariables struct {
+ ListTorrents []TorrentsJson
+ ListCategories []Categories
+ Query string
+ Category string
+ QueryRecordCount int
+ TotalRecordCount int
+}
+
+
+/* Function to interact with Models
+ *
+ * Get the torrents with where clause
+ *
+*/
+
+func getTorrentById(id string) (Torrents, error) {
+ var torrent Torrents
+
+ if db.Order("torrent_id DESC").First(&torrent, "id = ?", html.EscapeString(id)).RecordNotFound() {
+ return torrent, errors.New("Article is not found.")
+ }
+
+ return torrent, nil
+}
+
+func getTorrents(parameters WhereParams, limit int, offset int) ([]Torrents) {
+ var torrents []Torrents
+ db.Limit(limit).Offset(offset).Order("torrent_id DESC").Where(parameters.conditions, parameters.params...).Preload("Categories").Preload("Sub_Categories").Find(&torrents)
+ return torrents
+}
+
+func getTorrentsDB(parameters WhereParams) ([]Torrents) {
+ var torrents []Torrents
+ db.Where(parameters.conditions, parameters.params...).Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents)
+ return torrents
+}
+
+/* Function to get all torrents
+*/
+
+func getAllTorrents(limit int, offset int) ([]Torrents) {
+ var torrents []Torrents
+ db.Model(&torrents).Limit(limit).Offset(offset).Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents)
+
+ return torrents
+}
+
+func getAllTorrentsDB() ([]Torrents) {
+ var torrents []Torrents
+ db.Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents)
+ return torrents
+}
+
+/* Function to get all categories with/without torrents (bool)
+*/
+func getAllCategories(populatedWithTorrents bool) ([]Categories) {
+ var categories []Categories
+ if populatedWithTorrents {
+ db.Preload("Torrents").Preload("Sub_Categories").Find(&categories)
+ } else {
+ db.Preload("Sub_Categories").Find(&categories)
+ }
+ return categories
+}
+
+
+
+func (t *Torrents) toJson() (TorrentsJson) {
+ magnet := "magnet:?xt=urn:btih:" + t.Hash + "&dn=" + url.QueryEscape(t.Name) + trackers
+ res := TorrentsJson{
+ Id: strconv.Itoa(t.Id),
+ Name: t.Name,
+ Status: t.Status,
+ Hash: t.Hash,
+ Magnet: safe(magnet)}
+ return res;
+}
+
+func createWhereParams(conditions string, params ...string) (WhereParams) {
+ whereParams := WhereParams{}
+ whereParams.conditions = conditions
+ for i, _ := range params {
+ whereParams.params = append(whereParams.params, params[i])
+ }
+
+ return whereParams
+}
+/* Complete the functions when necessary... */
\ No newline at end of file