diff --git a/css/style.css b/css/style.css index 291b8784..ecf5dd83 100644 --- a/css/style.css +++ b/css/style.css @@ -7,3 +7,51 @@ .aplus { background-color: #60b0f0; } + + +/* Copy of NyaaTorrent theme */ +nav#mainmenu { + background: url(/img/topbar.png) repeat-x black; + position: fixed; + color:white; + width: 100%; + z-index:2; +} +nav#mainmenu a { + color: white; +} +div#container { + padding-top: 7rem; +} + +body { + background-color: #FBFBFB; + color: #111111; + font-family: Arial, sans-serif; + margin: 0; + padding: 0; +} + +.blockBody { + border-radius: 5px; + border: 2px solid black; + padding: 1rem; +} + +.torrentNav { + text-align: center; +} + +/* Links, Text */ +a { + color: #106655; + text-decoration : none; +} + +.torrentName { + font-weight: bold; + overflow: hidden; + padding-bottom: 3px; + padding-top: 3px; + word-wrap: break-word; +} diff --git a/img/topbar.png b/img/topbar.png new file mode 100644 index 00000000..5b585bd4 Binary files /dev/null and b/img/topbar.png differ diff --git a/img/torrents/1.png b/img/torrents/1.png new file mode 100644 index 00000000..68c89219 Binary files /dev/null and b/img/torrents/1.png differ diff --git a/img/torrents/10.png b/img/torrents/10.png new file mode 100644 index 00000000..7ba4b2c0 Binary files /dev/null and b/img/torrents/10.png differ diff --git a/img/torrents/11.png b/img/torrents/11.png new file mode 100644 index 00000000..0327d7c1 Binary files /dev/null and b/img/torrents/11.png differ diff --git a/img/torrents/12.png b/img/torrents/12.png new file mode 100644 index 00000000..81bfb409 Binary files /dev/null and b/img/torrents/12.png differ diff --git a/img/torrents/13.png b/img/torrents/13.png new file mode 100644 index 00000000..d5f41bd4 Binary files /dev/null and b/img/torrents/13.png differ diff --git a/img/torrents/14.png b/img/torrents/14.png new file mode 100644 index 00000000..d64bd511 Binary files /dev/null and b/img/torrents/14.png differ diff --git a/img/torrents/15.png b/img/torrents/15.png new file mode 100644 index 00000000..21c7de03 Binary files /dev/null and b/img/torrents/15.png differ diff --git a/img/torrents/16.png b/img/torrents/16.png new file mode 100644 index 00000000..b1e1ad28 Binary files /dev/null and b/img/torrents/16.png differ diff --git a/img/torrents/17.png b/img/torrents/17.png new file mode 100644 index 00000000..0923ae4f Binary files /dev/null and b/img/torrents/17.png differ diff --git a/img/torrents/2.png b/img/torrents/2.png new file mode 100644 index 00000000..3b993414 Binary files /dev/null and b/img/torrents/2.png differ diff --git a/img/torrents/3.png b/img/torrents/3.png new file mode 100644 index 00000000..54ca2378 Binary files /dev/null and b/img/torrents/3.png differ diff --git a/img/torrents/4.png b/img/torrents/4.png new file mode 100644 index 00000000..a72c68c6 Binary files /dev/null and b/img/torrents/4.png differ diff --git a/img/torrents/5.png b/img/torrents/5.png new file mode 100644 index 00000000..1f1dfcb1 Binary files /dev/null and b/img/torrents/5.png differ diff --git a/img/torrents/6.png b/img/torrents/6.png new file mode 100644 index 00000000..fa42f044 Binary files /dev/null and b/img/torrents/6.png differ diff --git a/img/torrents/7.png b/img/torrents/7.png new file mode 100644 index 00000000..fbcee211 Binary files /dev/null and b/img/torrents/7.png differ diff --git a/img/torrents/8.png b/img/torrents/8.png new file mode 100644 index 00000000..a4d98d44 Binary files /dev/null and b/img/torrents/8.png differ diff --git a/img/torrents/9.png b/img/torrents/9.png new file mode 100644 index 00000000..7f92164a Binary files /dev/null and b/img/torrents/9.png differ diff --git a/main.go b/main.go index 2b211e7f..0420657f 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,8 @@ import ( ) var db *gorm.DB -var templates = template.Must(template.ParseFiles("index.html", "FAQ.html")) +var router *mux.Router + 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" @@ -46,13 +47,12 @@ func apiHandler(w http.ResponseWriter, r *http.Request) { maxPerPage := 50 nbTorrents := 0 - torrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1)) + torrents, nbTorrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1)) for i, _ := range torrents { - nbTorrents++ res := torrents[i].toJson() - b.Torrents = append(b.Torrents, res) } + b.QueryRecordCount = maxPerPage b.TotalRecordCount = nbTorrents w.Header().Set("Content-Type", "application/json") @@ -86,6 +86,7 @@ func singleapiHandler(w http.ResponseWriter, r *http.Request) { } func searchHandler(w http.ResponseWriter, r *http.Request) { + var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html")) vars := mux.Vars(r) page := vars["page"] @@ -95,6 +96,7 @@ func searchHandler(w http.ResponseWriter, r *http.Request) { maxPerPage = 50 // default Value maxPerPage } pagenum, _ := strconv.Atoi(html.EscapeString(page)) + if (pagenum == 0) { pagenum = 1 } searchQuery := r.URL.Query().Get("q") cat := r.URL.Query().Get("c") stat := r.URL.Query().Get("s") @@ -111,18 +113,16 @@ func searchHandler(w http.ResponseWriter, r *http.Request) { b := []TorrentsJson{} - torrents := getTorrents(createWhereParams("torrent_name LIKE ? AND status_id LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ?", + torrents, nbTorrents := getTorrents(createWhereParams("torrent_name LIKE ? AND status_id LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ?", "%"+searchQuery+"%", stat+"%", searchCatId+"%", searchSubCatId+"%"), maxPerPage, maxPerPage*(pagenum-1)) for i, _ := range torrents { - nbTorrents++ res := torrents[i].toJson() - b = append(b, res) - } - htv := HomeTemplateVariables{b, getAllCategories(false), searchQuery, stat, cat, maxPerPage, nbTorrents} + navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"} + htv := HomeTemplateVariables{b, getAllCategories(false), searchQuery, stat, cat, navigationTorrents, r.URL, mux.CurrentRoute(r)} err := templates.ExecuteTemplate(w, "index.html", htv) if err != nil { @@ -134,13 +134,15 @@ func safe(s string) template.URL { } func faqHandler(w http.ResponseWriter, r *http.Request) { - err := templates.ExecuteTemplate(w, "FAQ.html", "") + var templates = template.Must(template.New("FAQ").Funcs(funcMap).ParseFiles("templates/index.html", "templates/FAQ.html")) + err := templates.ExecuteTemplate(w, "index.html", FaqTemplateVariables{r.URL, mux.CurrentRoute(r), "", "", "", Navigation{}}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func rootHandler(w http.ResponseWriter, r *http.Request) { + var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html")) vars := mux.Vars(r) page := vars["page"] @@ -152,17 +154,18 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { nbTorrents := 0 pagenum, _ := strconv.Atoi(html.EscapeString(page)) + if (pagenum == 0) { pagenum = 1 } + b := []TorrentsJson{} - torrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1)) + torrents, nbTorrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1)) + for i, _ := range torrents { - nbTorrents++ res := torrents[i].toJson() - b = append(b, res) - } - htv := HomeTemplateVariables{b, getAllCategories(false), "", "", "_", maxPerPage, nbTorrents} + navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"} + htv := HomeTemplateVariables{b, getAllCategories(false), "", "", "_", navigationTorrents, r.URL, mux.CurrentRoute(r)} err := templates.ExecuteTemplate(w, "index.html", htv) if err != nil { @@ -174,21 +177,23 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { func main() { db = getDBHandle() - router := mux.NewRouter() + router = mux.NewRouter() cssHandler := http.FileServer(http.Dir("./css/")) jsHandler := http.FileServer(http.Dir("./js/")) + imgHandler := http.FileServer(http.Dir("./img/")) http.Handle("/css/", http.StripPrefix("/css/", cssHandler)) http.Handle("/js/", http.StripPrefix("/js/", jsHandler)) + http.Handle("/img/", http.StripPrefix("/img/", imgHandler)) // Routes, - router.HandleFunc("/", rootHandler) - router.HandleFunc("/page/{page}", rootHandler) - router.HandleFunc("/search", searchHandler) - router.HandleFunc("/search/{page}", searchHandler) - router.HandleFunc("/api/{page}", apiHandler).Methods("GET") - router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET") - router.HandleFunc("/faq", faqHandler) + 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") + router.HandleFunc("/api/{page:[0-9]+}", apiHandler).Methods("GET") + router.HandleFunc("/api/torrent/{id:[0-9]+}", singleapiHandler).Methods("GET") + router.HandleFunc("/faq", faqHandler).Name("faq") http.Handle("/", router) diff --git a/models.go b/models.go index 66a36ef0..783ae1b2 100644 --- a/models.go +++ b/models.go @@ -10,15 +10,15 @@ import ( ) type Categories struct { - Category_id int - Category_name string + Id int `gorm:"column:category_id"` + Name string `gorm:"column:category_name"` Torrents []Torrents `gorm:"ForeignKey:category_id;AssociationForeignKey:category_id"` - Sub_Categories []Sub_Categories `gorm:"ForeignKey:category_id;AssociationForeignKey:parent_id"` + Sub_Categories []Sub_Categories `gorm:"ForeignKey:parent_id;AssociationForeignKey:category_id"` } type Sub_Categories struct { - Sub_category_id int `gorm:"column:sub_category_id"` - Sub_category_name string `gorm:"column:Sub_category_name"` + Id int `gorm:"column:sub_category_id"` + Name string `gorm:"column:Sub_category_name"` Parent_id int `gorm:"column:parent_id"` Torrents []Torrents `gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id"` } @@ -42,17 +42,25 @@ JSON Models Oject */ type CategoryJson struct { - Category string `json: "category"` + Id string `json: "id"` + Name string `json: "category"` Torrents []TorrentsJson `json: "torrents"` QueryRecordCount int `json: "queryRecordCount"` TotalRecordCount int `json: "totalRecordCount"` } +type SubCategoryJson struct { + Id string `json: "id"` + Name string `json: "category"` +} + 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"` + Sub_Category SubCategoryJson `json: "sub_category"` + Category CategoryJson `json: "category"` Magnet template.URL `json: "magnet"` } @@ -61,17 +69,6 @@ type WhereParams struct { params []interface{} } -/* Each Page should have an object to pass to their own template */ - -type HomeTemplateVariables struct { - ListTorrents []TorrentsJson - ListCategories []Categories - Query string - Status string - Category string - QueryRecordCount int - TotalRecordCount int -} /* Function to interact with Models * @@ -89,13 +86,15 @@ func getTorrentById(id string) (Torrents, error) { return torrent, nil } -func getTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) []Torrents { +func getTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]Torrents, int) { var torrents []Torrents var dbQuery *gorm.DB - + var count int if (parameters != nil) { // if there is where parameters + db.Model(&torrents).Where(parameters.conditions, parameters.params...).Count(&count) dbQuery = db.Model(&torrents).Where(parameters.conditions, parameters.params...) } else { + db.Model(&torrents).Count(&count) dbQuery = db.Model(&torrents) } @@ -104,35 +103,35 @@ func getTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offs dbQuery = dbQuery.Limit(limit).Offset(offset) } dbQuery.Order(orderBy).Preload("Categories").Preload("Sub_Categories").Find(&torrents) - return torrents + return torrents, count } /* Functions to simplify the get parameters of the main function * * Get Torrents with where parameters and limits, order by default */ -func getTorrents(parameters WhereParams, limit int, offset int) []Torrents { +func getTorrents(parameters WhereParams, limit int, offset int) ([]Torrents, int) { return getTorrentsOrderBy(¶meters, "", limit, offset) } /* Get Torrents with where parameters but no limit and order by default (get all the torrents corresponding in the db) */ -func getTorrentsDB(parameters WhereParams) []Torrents { +func getTorrentsDB(parameters WhereParams) ([]Torrents, int) { return getTorrentsOrderBy(¶meters, "", 0, 0) } /* Function to get all torrents */ -func getAllTorrentsOrderBy(orderBy string, limit int, offset int) [] Torrents { +func getAllTorrentsOrderBy(orderBy string, limit int, offset int) ([]Torrents, int) { return getTorrentsOrderBy(nil, orderBy, limit, offset) } -func getAllTorrents(limit int, offset int) []Torrents { +func getAllTorrents(limit int, offset int) ([]Torrents, int) { return getTorrentsOrderBy(nil, "", limit, offset) } -func getAllTorrentsDB() []Torrents { +func getAllTorrentsDB() ([]Torrents, int) { return getTorrentsOrderBy(nil, "", 0, 0) } @@ -148,17 +147,6 @@ func getAllCategories(populatedWithTorrents bool) []Categories { return categories } -func (t *Torrents) toJson() TorrentsJson { - magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(t.Hash) + "&dn=" + t.Name + trackers - res := TorrentsJson{ - Id: strconv.Itoa(t.Id), - Name: html.UnescapeString(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 @@ -169,4 +157,31 @@ func createWhereParams(conditions string, params ...string) WhereParams { return whereParams } +/* Model Conversion to Json */ + +func (t *Torrents) toJson() TorrentsJson { + magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(t.Hash) + "&dn=" + t.Name + trackers + res := TorrentsJson{ + Id: strconv.Itoa(t.Id), + Name: html.UnescapeString(t.Name), + Status: t.Status, + Hash: t.Hash, + Sub_Category: t.Sub_Categories.toJson(), + Category: t.Categories.toJson(), + Magnet: safe(magnet)} + return res +} + +func (c *Sub_Categories) toJson() SubCategoryJson { + return SubCategoryJson{ + Id: strconv.Itoa(c.Id), + Name: html.UnescapeString(c.Name)} +} + +func (c *Categories) toJson() CategoryJson { + return CategoryJson{ + Id: strconv.Itoa(c.Id), + Name: html.UnescapeString(c.Name)} +} + /* Complete the functions when necessary... */ \ No newline at end of file diff --git a/templateFunctions.go b/templateFunctions.go new file mode 100644 index 00000000..284de4d7 --- /dev/null +++ b/templateFunctions.go @@ -0,0 +1,50 @@ +package main + +import( + "math" + "html/template" + "net/url" + "strconv" + "log" +) + +var funcMap = template.FuncMap{ + "min": math.Min, + "genRoute": func (name string, params ...string) string { + url, err := router.Get(name).URL(params...) + if (err == nil) { + return url.String() + } + return "error" + }, + "genNav" : func (nav Navigation, currentUrl *url.URL, pagesSelectable int) template.HTML { + maxPages := math.Ceil(float64(nav.TotalItem)/float64(nav.MaxItemPerPage)) + route := router.Get(nav.Route) + + var ret = "" + if nav.CurrentPage-1 > 0 { + url, _ := route.URL("page", "1") + ret = ret + "
If you have website development expertise, you can join the #nyaapantsu IRC channel on irc.rizon.net. If you have any current databases, UPLOAD THEM.
Id | +Name | +Hash | +Links | +
---|---|---|---|
+ | {{.Name}} | +{{.Hash}} | + ++ | + + +