Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0

Rearranged Files

Configurations are separated in files in the folder config
Connection to database by a package to import when needed
Models will be in a model package for better maintenance
Services access to the models
Utils are tools or functions that can be used anywhere
main.go cleaned a bit and other files modifications are there for the above modifications
Cette révision appartient à :
akuma06 2017-05-05 14:20:51 +02:00
Parent a50d218504
révision 9586f1e731
14 fichiers modifiés avec 426 ajouts et 329 suppressions

5
config/database.go Fichier normal
Voir le fichier

@ -0,0 +1,5 @@
package config
const (
DbName = "./nyaa.db"
)

8
config/env.go Fichier normal
Voir le fichier

@ -0,0 +1,8 @@
package config
// Constants for environment.
const (
// DEVELOPMENT | TEST | PRODUCTION
Environment = "DEVELOPMENT"
// Environment = "PRODUCTION"
)

6
config/navigation.go Fichier normal
Voir le fichier

@ -0,0 +1,6 @@
package config
// Constants for pagination.
const (
TorrentsPerPage = 50
)

7
config/sorting.go Fichier normal
Voir le fichier

@ -0,0 +1,7 @@
package config
// Constants for ordering models.
const (
TorrentOrder = "torrent_id"
TorrentSort = "DESC"
)

5
config/trackers.go Fichier normal
Voir le fichier

@ -0,0 +1,5 @@
package config
const (
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&tr=http://tracker.baka-sub.cf/announce"
)

57
db/gorm.go Fichier normal
Voir le fichier

@ -0,0 +1,57 @@
package db
import (
"github.com/ewhal/nyaa/config"
"github.com/ewhal/nyaa/util/log"
"github.com/ewhal/nyaa/model"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
// _ "github.com/go-sql-driver/mysql"
)
var ORM, Errs = GormInit()
// GormInit init gorm ORM.
func GormInit() (*gorm.DB, error) {
db, err := gorm.Open("sqlite3", config.DbName)
// db, err := gorm.Open("mysql", config.MysqlDSL())
//db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
// Get database connection handle [*sql.DB](http://golang.org/pkg/database/sql/#DB)
db.DB()
// Then you could invoke `*sql.DB`'s functions with it
db.DB().Ping()
db.DB().SetMaxIdleConns(10)
db.DB().SetMaxOpenConns(100)
// Disable table name's pluralization
// db.SingularTable(true)
if config.Environment == "DEVELOPMENT" {
db.LogMode(true)
// db.DropTable(&model.User{}, "UserFollower")
db.AutoMigrate(&model.Torrents{}, &model.Categories{}, &model.Sub_Categories{}, &model.Statuses{})
// db.AutoMigrate(&model.User{}, &model.Role{}, &model.Connection{}, &model.Language{}, &model.Article{}, &model.Location{}, &model.Comment{}, &model.File{})
// db.Model(&model.User{}).AddIndex("idx_user_token", "token")
}
log.CheckError(err)
// relation := gorm.Relationship{}
// relation.Kind = "many2many"
// relation.ForeignFieldNames = []string{"id"} //(M1 pkey)
// relation.ForeignDBNames = []string{"user_id"} //(M1 fkey in m1m2join)
// relation.AssociationForeignFieldNames = []string{"id"} //(M2 pkey)
// // relation.AssociationForeignStructFieldNames = []string{"id", "ID"} //(m2 pkey name in m2 struct?)
// relation.AssociationForeignDBNames = []string{"follower_id"} //(m2 fkey in m1m2join)
// m1Type := reflect.TypeOf(model.User{})
// m2Type := reflect.TypeOf(model.User{})
// handler := gorm.JoinTableHandler{}
// // ORDER BELOW MATTERS
// // Install handler
// db.SetJoinTableHandler(&model.User{}, "Likings", &handler)
// // Configure handler to use the relation that we've defined
// handler.Setup(&relation, "users_followers", m1Type, m2Type)
return db, err
}

115
main.go
Voir le fichier

@ -1,57 +1,23 @@
package main
import (
"bytes"
"compress/zlib"
"encoding/json"
"github.com/gorilla/feeds"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/ewhal/nyaa/model"
"github.com/ewhal/nyaa/service/torrent"
"github.com/ewhal/nyaa/util/log"
"html"
"html/template"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
"time"
)
var db *gorm.DB
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&tr=http://tracker.baka-sub.cf/announce"
func getDBHandle() *gorm.DB {
dbInit, err := gorm.Open("sqlite3", "./nyaa.db")
// Migrate the schema of Torrents
dbInit.AutoMigrate(&Torrents{}, &Categories{}, &Sub_Categories{}, &Statuses{})
checkErr(err)
return dbInit
}
func checkErr(err error) {
if err != nil {
debugLogger.Println(" " + err.Error())
}
}
func unZlib(description []byte) string {
if len(description) > 0 {
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)
}
return ""
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
@ -59,13 +25,13 @@ func apiHandler(w http.ResponseWriter, r *http.Request) {
page := vars["page"]
pagenum, _ := strconv.Atoi(html.EscapeString(page))
b := CategoryJson{Torrents: []TorrentsJson{}}
b := model.CategoryJson{Torrents: []model.TorrentsJson{}}
maxPerPage := 50
nbTorrents := 0
torrents, nbTorrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
for i, _ := range torrents {
res := torrents[i].toJson()
res := torrents[i].ToJson()
b.Torrents = append(b.Torrents, res)
}
@ -84,10 +50,10 @@ func apiViewHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
b := CategoryJson{Torrents: []TorrentsJson{}}
b := model.CategoryJson{Torrents: []model.TorrentsJson{}}
torrent, err := getTorrentById(id)
res := torrent.toJson()
torrent, err := torrentService.GetTorrentById(id)
res := torrent.ToJson()
b.Torrents = append(b.Torrents, res)
b.QueryRecordCount = 1
@ -103,7 +69,6 @@ func apiViewHandler(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"))
templates.ParseGlob("templates/_*.html") // common
vars := mux.Vars(r)
page := vars["page"]
@ -126,6 +91,7 @@ func searchHandler(w http.ResponseWriter, r *http.Request) {
// need this to prevent out of index panics
var searchCatId, searchSubCatId string
if len(catsSplit) == 2 {
searchCatId = html.EscapeString(catsSplit[0])
searchSubCatId = html.EscapeString(catsSplit[1])
}
@ -139,53 +105,29 @@ func searchHandler(w http.ResponseWriter, r *http.Request) {
nbTorrents := 0
b := []TorrentsJson{}
b := []model.TorrentsJson{}
parameters := WhereParams{}
conditions := []string{}
if searchCatId != "" {
conditions = append(conditions, "category_id = ?")
parameters.params = append(parameters.params, searchCatId)
}
if searchSubCatId != "" {
conditions = append(conditions, "sub_category_id = ?")
parameters.params = append(parameters.params, searchSubCatId)
}
if stat != "" {
conditions = append(conditions, "status_id = ?")
parameters.params = append(parameters.params, stat)
}
searchQuerySplit := strings.Split(searchQuery, " ")
for i, _ := range searchQuerySplit {
conditions = append(conditions, "torrent_name LIKE ?")
parameters.params = append(parameters.params, "%"+searchQuerySplit[i]+"%")
}
parameters.conditions = strings.Join(conditions[:], " AND ")
log.Printf("SQL query is :: %s\n", parameters.conditions)
torrents, nbTorrents := getTorrentsOrderBy(&parameters, order_by, maxPerPage, maxPerPage*(pagenum-1))
parameters := torrentService.CreateWhereParams("torrent_name LIKE ? AND status_id LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ?",
"%"+searchQuery+"%", stat+"%", searchCatId+"%", searchSubCatId+"%")
torrents, nbTorrents := torrentService.GetTorrentsOrderBy(&parameters, order_by, maxPerPage, maxPerPage*(pagenum-1))
for i, _ := range torrents {
res := torrents[i].toJson()
res := torrents[i].ToJson()
b = append(b, res)
}
navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"}
searchForm := SearchForm{searchQuery, stat, cat, sort, order}
htv := HomeTemplateVariables{b, getAllCategories(false), searchForm, navigationTorrents, r.URL, mux.CurrentRoute(r)}
htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), searchForm, navigationTorrents, r.URL, mux.CurrentRoute(r)}
err := templates.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func safe(s string) template.URL {
return template.URL(s)
}
func faqHandler(w http.ResponseWriter, r *http.Request) {
var templates = template.Must(template.New("FAQ").Funcs(funcMap).ParseFiles("templates/index.html", "templates/FAQ.html"))
templates.ParseGlob("templates/_*.html") // common
err := templates.ExecuteTemplate(w, "index.html", FaqTemplateVariables{Navigation{}, NewSearchForm(), r.URL, mux.CurrentRoute(r)})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -199,7 +141,7 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
// db params url
//maxPerPage := 50 // default Value maxPerPage
torrents := getFeeds()
torrents := torrentService.GetFeeds()
created := time.Now().String()
if len(torrents) > 0 {
created = torrents[0].Timestamp
@ -240,12 +182,11 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
var templates = template.Must(template.ParseFiles("templates/index.html", "templates/view.html"))
templates.ParseGlob("templates/_*.html") // common
vars := mux.Vars(r)
id := vars["id"]
torrent, err := getTorrentById(id)
b := torrent.toJson()
torrent, err := torrentService.GetTorrentById(id)
b := torrent.ToJson()
htv := ViewTemplateVariables{b, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}
@ -257,7 +198,6 @@ func viewHandler(w http.ResponseWriter, r *http.Request) {
func rootHandler(w http.ResponseWriter, r *http.Request) {
var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html"))
templates.ParseGlob("templates/_*.html") // common
vars := mux.Vars(r)
page := vars["page"]
@ -273,16 +213,16 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
pagenum = 1
}
b := []TorrentsJson{}
torrents, nbTorrents := getAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
b := []model.TorrentsJson{}
torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
for i, _ := range torrents {
res := torrents[i].toJson()
res := torrents[i].ToJson()
b = append(b, res)
}
navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"}
htv := HomeTemplateVariables{b, getAllCategories(false), NewSearchForm(), navigationTorrents, r.URL, mux.CurrentRoute(r)}
htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), NewSearchForm(), navigationTorrents, r.URL, mux.CurrentRoute(r)}
err := templates.ExecuteTemplate(w, "index.html", htv)
if err != nil {
@ -293,7 +233,6 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
func main() {
db = getDBHandle()
router = mux.NewRouter()
cssHandler := http.FileServer(http.Dir("./css/"))
@ -324,5 +263,5 @@ func main() {
}
err := srv.ListenAndServe()
checkErr(err)
}
log.CheckError(err)
}

122
model/torrent.go Fichier normal
Voir le fichier

@ -0,0 +1,122 @@
package model
import (
"github.com/ewhal/nyaa/util"
"github.com/ewhal/nyaa/config"
"html"
"html/template"
"strconv"
"strings"
"time"
)
type Feed struct {
Id int
Name string
Hash string
Magnet string
Timestamp string
}
type Categories struct {
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:parent_id;AssociationForeignKey:category_id"`
}
type Sub_Categories struct {
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"`
}
type Statuses struct {
Status_id int
Status_name string
Torrents []Torrents `gorm:"ForeignKey:status_id;AssociationForeignKey:status_id"`
}
type Torrents struct {
Id int `gorm:"column:torrent_id"`
Name string `gorm:"column:torrent_name"`
Category_id int `gorm:"column:category_id"`
Sub_category_id int `gorm:"column:sub_category_id"`
Status int `gorm:"column:status_id"`
Hash string `gorm:"column:torrent_hash"`
Date int64 `gorm:"column:date"`
Downloads int `gorm:"column:downloads"`
Filesize string `gorm:"column:filesize"`
Description []byte `gorm:"column:description"`
Statuses Statuses `gorm:"ForeignKey:status_id;AssociationForeignKey:status_id"`
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 {
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"`
Date string `json: "date"`
Filesize string `json: "filesize"`
Description template.HTML `json: "description"`
Sub_Category SubCategoryJson `json: "sub_category"`
Category CategoryJson `json: "category"`
Magnet template.URL `json: "magnet"`
}
/* Model Conversion to Json */
func (t *Torrents) ToJson() TorrentsJson {
magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(t.Hash) + "&dn=" + t.Name + config.Trackers
res := TorrentsJson{
Id: strconv.Itoa(t.Id),
Name: html.UnescapeString(t.Name),
Status: t.Status,
Hash: t.Hash,
Date: time.Unix(t.Date, 0).Format(time.RFC3339),
Filesize: t.Filesize,
Description: template.HTML(util.UnZlib(t.Description)),
Sub_Category: t.Sub_Categories.ToJson(),
Category: t.Categories.ToJson(),
Magnet: util.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... */

238
models.go
Voir le fichier

@ -1,238 +0,0 @@
package main
import (
"errors"
"github.com/jinzhu/gorm"
"html"
"html/template"
"strconv"
"strings"
"time"
)
type Feed struct {
Id int
Name string
Hash string
Magnet string
Timestamp string
}
type Categories struct {
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:parent_id;AssociationForeignKey:category_id"`
}
type Sub_Categories struct {
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"`
}
type Statuses struct {
Status_id int
Status_name string
Torrents []Torrents `gorm:"ForeignKey:status_id;AssociationForeignKey:status_id"`
}
type Torrents struct {
Id int `gorm:"column:torrent_id"`
Name string `gorm:"column:torrent_name"`
Category_id int `gorm:"column:category_id"`
Sub_category_id int `gorm:"column:sub_category_id"`
Status int `gorm:"column:status_id"`
Hash string `gorm:"column:torrent_hash"`
Date int64 `gorm:"column:date"`
Downloads int `gorm:"column:downloads"`
Filesize string `gorm:"column:filesize"`
Description []byte `gorm:"column:description"`
Statuses Statuses `gorm:"ForeignKey:status_id;AssociationForeignKey:status_id"`
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 {
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"`
Date string `json: "date"`
Filesize string `json: "filesize"`
Description template.HTML `json: "description"`
Sub_Category SubCategoryJson `json: "sub_category"`
Category CategoryJson `json: "category"`
Magnet template.URL `json: "magnet"`
}
type WhereParams struct {
conditions string // Ex : name LIKE ? AND category_id LIKE ?
params []interface{}
}
/* Function to interact with Models
*
* Get the torrents with where clause
*
*/
// don't need raw SQL once we get MySQL
func getFeeds() []Feed {
var result []Feed
rows, err := db.DB().
Query(
"SELECT `torrent_id` AS `id`, `torrent_name` AS `name`, `torrent_hash` AS `hash`, `timestamp` FROM `torrents` " +
"ORDER BY `timestamp` desc LIMIT 50")
if err == nil {
for rows.Next() {
item := Feed{}
rows.Scan(&item.Id, &item.Name, &item.Hash, &item.Timestamp)
magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(item.Hash) + "&dn=" + item.Name + trackers
item.Magnet = magnet
// memory hog
result = append(result, item)
}
rows.Close()
}
return result
}
func getTorrentById(id string) (Torrents, error) {
var torrent Torrents
if db.Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
return torrent, errors.New("Article is not found.")
}
return torrent, nil
}
func getTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]Torrents, int) {
var torrents []Torrents
var dbQuery *gorm.DB
var count int
conditions := "torrent_hash is not null" //filter out broken entries
var params []interface{}
if parameters != nil { // if there is where parameters
conditions += " AND " + parameters.conditions
params = parameters.params
}
db.Model(&torrents).Where(conditions, params...).Count(&count)
dbQuery = db.Model(&torrents).Where(conditions, params...)
if orderBy == "" {
orderBy = "torrent_id DESC"
} // Default OrderBy
if limit != 0 || offset != 0 { // if limits provided
dbQuery = dbQuery.Limit(limit).Offset(offset)
}
dbQuery.Order(orderBy).Preload("Categories").Preload("Sub_Categories").Find(&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, int) {
return getTorrentsOrderBy(&parameters, "", 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, int) {
return getTorrentsOrderBy(&parameters, "", 0, 0)
}
/* Function to get all torrents
*/
func getAllTorrentsOrderBy(orderBy string, limit int, offset int) ([]Torrents, int) {
return getTorrentsOrderBy(nil, orderBy, limit, offset)
}
func getAllTorrents(limit int, offset int) ([]Torrents, int) {
return getTorrentsOrderBy(nil, "", limit, offset)
}
func getAllTorrentsDB() ([]Torrents, int) {
return getTorrentsOrderBy(nil, "", 0, 0)
}
/* 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 createWhereParams(conditions string, params ...string) WhereParams {
whereParams := WhereParams{}
whereParams.conditions = conditions
for i, _ := range params {
whereParams.params = append(whereParams.params, params[i])
}
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,
Date: time.Unix(t.Date, 0).Format(time.RFC3339),
Filesize: t.Filesize,
Description: template.HTML(unZlib(t.Description)),
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... */

127
service/torrent/torrent.go Fichier normal
Voir le fichier

@ -0,0 +1,127 @@
package torrentService
import (
"github.com/ewhal/nyaa/db"
"github.com/ewhal/nyaa/model"
"github.com/ewhal/nyaa/config"
"github.com/jinzhu/gorm"
"errors"
"strings"
)
type WhereParams struct {
conditions string // Ex : name LIKE ? AND category_id LIKE ?
params []interface{}
}
/* Function to interact with Models
*
* Get the torrents with where clause
*
*/
// don't need raw SQL once we get MySQL
func GetFeeds() []model.Feed {
var result []model.Feed
rows, err := db.ORM.DB().
Query(
"SELECT `torrent_id` AS `id`, `torrent_name` AS `name`, `torrent_hash` AS `hash`, `timestamp` FROM `torrents` " +
"ORDER BY `timestamp` desc LIMIT 50")
if err == nil {
for rows.Next() {
item := model.Feed{}
rows.Scan(&item.Id, &item.Name, &item.Hash, &item.Timestamp)
magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(item.Hash) + "&dn=" + item.Name + config.Trackers
item.Magnet = magnet
// memory hog
result = append(result, item)
}
rows.Close()
}
return result
}
func GetTorrentById(id string) (model.Torrents, error) {
var torrent model.Torrents
if db.ORM.Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
return torrent, errors.New("Article is not found.")
}
return torrent, nil
}
func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]model.Torrents, int) {
var torrents []model.Torrents
var dbQuery *gorm.DB
var count int
conditions := "torrent_hash is not null" //filter out broken entries
var params []interface{}
if parameters != nil { // if there is where parameters
conditions += " AND " + parameters.conditions
params = parameters.params
}
db.ORM.Model(&torrents).Where(conditions, params...).Count(&count)
dbQuery = db.ORM.Model(&torrents).Where(conditions, params...)
if orderBy == "" {
orderBy = "torrent_id DESC"
} // Default OrderBy
if limit != 0 || offset != 0 { // if limits provided
dbQuery = dbQuery.Limit(limit).Offset(offset)
}
dbQuery.Order(orderBy).Preload("Categories").Preload("Sub_Categories").Find(&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) ([]model.Torrents, int) {
return GetTorrentsOrderBy(&parameters, "", 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) ([]model.Torrents, int) {
return GetTorrentsOrderBy(&parameters, "", 0, 0)
}
/* Function to get all torrents
*/
func GetAllTorrentsOrderBy(orderBy string, limit int, offset int) ([]model.Torrents, int) {
return GetTorrentsOrderBy(nil, orderBy, limit, offset)
}
func GetAllTorrents(limit int, offset int) ([]model.Torrents, int) {
return GetTorrentsOrderBy(nil, "", limit, offset)
}
func GetAllTorrentsDB() ([]model.Torrents, int) {
return GetTorrentsOrderBy(nil, "", 0, 0)
}
/* Function to get all categories with/without torrents (bool)
*/
func GetAllCategories(populatedWithTorrents bool) []model.Categories {
var categories []model.Categories
if populatedWithTorrents {
db.ORM.Preload("Torrents").Preload("Sub_Categories").Find(&categories)
} else {
db.ORM.Preload("Sub_Categories").Find(&categories)
}
return categories
}
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
}

Voir le fichier

@ -2,6 +2,7 @@ package main
import (
"github.com/gorilla/mux"
"github.com/ewhal/nyaa/model"
"net/url"
)
@ -19,7 +20,7 @@ type FaqTemplateVariables struct {
}
type ViewTemplateVariables struct {
Torrent TorrentsJson
Torrent model.TorrentsJson
Search SearchForm
Navigation Navigation
URL *url.URL // For parsing Url in templates
@ -27,8 +28,8 @@ type ViewTemplateVariables struct {
}
type HomeTemplateVariables struct {
ListTorrents []TorrentsJson
ListCategories []Categories
ListTorrents []model.TorrentsJson
ListCategories []model.Categories
Search SearchForm
Navigation Navigation
URL *url.URL // For parsing Url in templates

29
util/log/error.go Fichier normal
Voir le fichier

@ -0,0 +1,29 @@
package log
import (
"fmt"
"github.com/Sirupsen/logrus"
"runtime"
)
// CheckError check error and return true if error is nil and return false if error is not nil.
func CheckError(err error) bool {
return CheckErrorWithMessage(err, "")
}
// CheckErrorWithMessage check error with message and log messages with stack. And then return true if error is nil and return false if error is not nil.
func CheckErrorWithMessage(err error, msg string, args ...interface{}) bool {
if err != nil {
var stack [4096]byte
runtime.Stack(stack[:], false)
// logrus.Errorf(msg, args)
if len(args) == 0 {
logrus.Error(msg + fmt.Sprintf("%q\n%s\n", err, stack[:]))
} else {
logrus.Error(fmt.Sprintf(msg, args...) + fmt.Sprintf("%q\n%s\n", err, stack[:]))
}
// logrus.Printf(msg+"\n%q\n%s\n",args, err, stack[:])
return false
}
return true
}

7
util/safe.go Fichier normal
Voir le fichier

@ -0,0 +1,7 @@
package util
import "html/template"
func Safe(s string) template.URL {
return template.URL(s)
}

22
util/unzlib.go Fichier normal
Voir le fichier

@ -0,0 +1,22 @@
package util
import (
"github.com/ewhal/nyaa/util/log"
"bytes"
"compress/zlib"
"io/ioutil"
)
func UnZlib(description []byte) string {
if len(description) > 0 {
b := bytes.NewReader(description)
z, err := zlib.NewReader(b)
log.CheckError(err)
defer z.Close()
p, err := ioutil.ReadAll(z)
log.CheckError(err)
return string(p)
}
return ""
}