2017-05-04 05:28:42 +02:00
package main
import (
2017-05-04 12:01:27 +02:00
"errors"
2017-05-04 05:28:42 +02:00
"github.com/jinzhu/gorm"
"html"
"html/template"
"strconv"
2017-05-04 12:31:40 +02:00
"strings"
2017-05-05 08:20:57 +02:00
"time"
2017-05-04 05:28:42 +02:00
)
2017-05-04 21:48:40 +02:00
type Feed struct {
2017-05-05 06:24:58 +02:00
Id int
Name string
Hash string
Magnet string
Timestamp string
2017-05-04 21:48:40 +02:00
}
2017-05-04 05:28:42 +02:00
type Categories struct {
2017-05-05 06:07:45 +02:00
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" `
2017-05-04 05:28:42 +02:00
}
type Sub_Categories struct {
2017-05-05 06:07:45 +02:00
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" `
2017-05-04 05:28:42 +02:00
}
2017-05-05 06:24:58 +02:00
type Statuses struct {
Status_id int
Status_name string
Torrents [ ] Torrents ` gorm:"ForeignKey:status_id;AssociationForeignKey:status_id" `
}
2017-05-04 05:28:42 +02:00
type Torrents struct {
2017-05-04 14:01:07 +02:00
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" `
2017-05-05 06:07:45 +02:00
Status int ` gorm:"column:status_id" `
2017-05-04 12:01:27 +02:00
Hash string ` gorm:"column:torrent_hash" `
2017-05-05 08:20:57 +02:00
Date int64 ` gorm:"column:date" `
2017-05-05 06:24:58 +02:00
Downloads int ` gorm:"column:downloads" `
Filesize string ` gorm:"column:filesize" `
Description [ ] byte ` gorm:"column:description" `
Statuses Statuses ` gorm:"ForeignKey:status_id;AssociationForeignKey:status_id" `
2017-05-04 12:01:27 +02:00
Categories Categories ` gorm:"ForeignKey:category_id;AssociationForeignKey:category_id" `
Sub_Categories Sub_Categories ` gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id" `
2017-05-04 05:28:42 +02:00
}
/ * We need JSON Object instead because of Magnet URL that is not in the database but generated dynamically
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
JSON Models Oject
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
type CategoryJson struct {
2017-05-05 06:07:45 +02:00
Id string ` json: "id" `
Name string ` json: "category" `
2017-05-04 12:01:27 +02:00
Torrents [ ] TorrentsJson ` json: "torrents" `
QueryRecordCount int ` json: "queryRecordCount" `
TotalRecordCount int ` json: "totalRecordCount" `
2017-05-04 05:28:42 +02:00
}
2017-05-05 03:53:38 +02:00
type SubCategoryJson struct {
2017-05-05 06:07:45 +02:00
Id string ` json: "id" `
Name string ` json: "category" `
2017-05-05 03:53:38 +02:00
}
2017-05-04 05:28:42 +02:00
type TorrentsJson struct {
2017-05-05 06:07:45 +02:00
Id string ` json: "id" ` // Is there a need to put the ID?
Name string ` json: "name" `
Status int ` json: "status" `
Hash string ` json: "hash" `
2017-05-05 08:20:57 +02:00
Date string ` json: "date" `
2017-05-05 06:07:45 +02:00
Filesize string ` json: "filesize" `
2017-05-05 08:14:13 +02:00
Description template . HTML ` json: "description" `
2017-05-05 03:53:38 +02:00
Sub_Category SubCategoryJson ` json: "sub_category" `
2017-05-05 06:07:45 +02:00
Category CategoryJson ` json: "category" `
Magnet template . URL ` json: "magnet" `
2017-05-04 05:28:42 +02:00
}
type WhereParams struct {
conditions string // Ex : name LIKE ? AND category_id LIKE ?
2017-05-04 12:01:27 +02:00
params [ ] interface { }
2017-05-04 05:28:42 +02:00
}
/ * Function to interact with Models
*
* Get the torrents with where clause
*
2017-05-04 12:01:27 +02:00
* /
2017-05-04 05:28:42 +02:00
2017-05-04 21:48:40 +02:00
// 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` " +
2017-05-05 06:24:58 +02:00
"ORDER BY `timestamp` desc LIMIT 50" )
if err == nil {
2017-05-04 21:48:40 +02:00
for rows . Next ( ) {
item := Feed { }
2017-05-05 06:24:58 +02:00
rows . Scan ( & item . Id , & item . Name , & item . Hash , & item . Timestamp )
2017-05-04 21:48:40 +02:00
magnet := "magnet:?xt=urn:btih:" + strings . TrimSpace ( item . Hash ) + "&dn=" + item . Name + trackers
item . Magnet = magnet
// memory hog
2017-05-05 06:24:58 +02:00
result = append ( result , item )
2017-05-04 21:48:40 +02:00
}
rows . Close ( )
}
return result
}
2017-05-04 05:28:42 +02:00
func getTorrentById ( id string ) ( Torrents , error ) {
var torrent Torrents
2017-05-04 14:51:16 +02:00
if db . Where ( "torrent_id = ?" , id ) . Find ( & torrent ) . RecordNotFound ( ) {
2017-05-04 05:28:42 +02:00
return torrent , errors . New ( "Article is not found." )
}
return torrent , nil
}
2017-05-05 03:53:38 +02:00
func getTorrentsOrderBy ( parameters * WhereParams , orderBy string , limit int , offset int ) ( [ ] Torrents , int ) {
2017-05-04 05:28:42 +02:00
var torrents [ ] Torrents
2017-05-04 17:16:20 +02:00
var dbQuery * gorm . DB
2017-05-05 03:53:38 +02:00
var count int
2017-05-05 09:18:24 +02:00
conditions := "torrent_hash is not null" //filter out broken entries
var params [ ] interface { }
2017-05-05 06:07:45 +02:00
if parameters != nil { // if there is where parameters
2017-05-05 09:18:24 +02:00
conditions += " AND " + parameters . conditions
params = parameters . params
2017-05-05 06:24:58 +02:00
}
2017-05-05 09:18:24 +02:00
db . Model ( & torrents ) . Where ( conditions , params ... ) . Count ( & count )
dbQuery = db . Model ( & torrents ) . Where ( conditions , params ... )
2017-05-05 06:24:58 +02:00
if orderBy == "" {
orderBy = "torrent_id DESC"
} // Default OrderBy
2017-05-04 17:16:20 +02:00
if limit != 0 || offset != 0 { // if limits provided
dbQuery = dbQuery . Limit ( limit ) . Offset ( offset )
}
2017-05-05 06:07:45 +02:00
dbQuery . Order ( orderBy ) . Preload ( "Categories" ) . Preload ( "Sub_Categories" ) . Find ( & torrents )
2017-05-05 03:53:38 +02:00
return torrents , count
2017-05-05 05:04:04 +02:00
2017-05-04 05:28:42 +02:00
}
2017-05-05 06:24:58 +02:00
/ * Functions to simplify the get parameters of the main function
*
2017-05-04 17:16:20 +02:00
* Get Torrents with where parameters and limits , order by default
* /
2017-05-05 03:53:38 +02:00
func getTorrents ( parameters WhereParams , limit int , offset int ) ( [ ] Torrents , int ) {
2017-05-04 17:16:20 +02:00
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 )
* /
2017-05-05 03:53:38 +02:00
func getTorrentsDB ( parameters WhereParams ) ( [ ] Torrents , int ) {
2017-05-04 17:16:20 +02:00
return getTorrentsOrderBy ( & parameters , "" , 0 , 0 )
2017-05-04 05:28:42 +02:00
}
2017-05-04 12:01:27 +02:00
/ * Function to get all torrents
* /
2017-05-04 05:28:42 +02:00
2017-05-05 03:53:38 +02:00
func getAllTorrentsOrderBy ( orderBy string , limit int , offset int ) ( [ ] Torrents , int ) {
2017-05-05 05:04:04 +02:00
2017-05-04 17:16:20 +02:00
return getTorrentsOrderBy ( nil , orderBy , limit , offset )
}
2017-05-04 05:28:42 +02:00
2017-05-05 03:53:38 +02:00
func getAllTorrents ( limit int , offset int ) ( [ ] Torrents , int ) {
2017-05-04 17:16:20 +02:00
return getTorrentsOrderBy ( nil , "" , limit , offset )
2017-05-04 05:28:42 +02:00
}
2017-05-05 03:53:38 +02:00
func getAllTorrentsDB ( ) ( [ ] Torrents , int ) {
2017-05-04 17:16:20 +02:00
return getTorrentsOrderBy ( nil , "" , 0 , 0 )
2017-05-04 05:28:42 +02:00
}
/ * Function to get all categories with / without torrents ( bool )
2017-05-04 12:01:27 +02:00
* /
func getAllCategories ( populatedWithTorrents bool ) [ ] Categories {
2017-05-04 05:28:42 +02:00
var categories [ ] Categories
if populatedWithTorrents {
db . Preload ( "Torrents" ) . Preload ( "Sub_Categories" ) . Find ( & categories )
} else {
db . Preload ( "Sub_Categories" ) . Find ( & categories )
}
return categories
}
2017-05-05 03:53:38 +02:00
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 */
2017-05-04 12:01:27 +02:00
func ( t * Torrents ) toJson ( ) TorrentsJson {
2017-05-04 12:30:12 +02:00
magnet := "magnet:?xt=urn:btih:" + strings . TrimSpace ( t . Hash ) + "&dn=" + t . Name + trackers
2017-05-04 05:28:42 +02:00
res := TorrentsJson {
2017-05-05 06:07:45 +02:00
Id : strconv . Itoa ( t . Id ) ,
Name : html . UnescapeString ( t . Name ) ,
Status : t . Status ,
Hash : t . Hash ,
2017-05-05 08:20:57 +02:00
Date : time . Unix ( t . Date , 0 ) . Format ( time . RFC3339 ) ,
2017-05-05 06:07:45 +02:00
Filesize : t . Filesize ,
2017-05-05 08:14:13 +02:00
Description : template . HTML ( unZlib ( t . Description ) ) ,
2017-05-05 03:53:38 +02:00
Sub_Category : t . Sub_Categories . toJson ( ) ,
2017-05-05 06:07:45 +02:00
Category : t . Categories . toJson ( ) ,
Magnet : safe ( magnet ) }
2017-05-05 05:04:04 +02:00
2017-05-04 12:01:27 +02:00
return res
2017-05-04 05:28:42 +02:00
}
2017-05-05 03:53:38 +02:00
func ( c * Sub_Categories ) toJson ( ) SubCategoryJson {
return SubCategoryJson {
2017-05-05 06:07:45 +02:00
Id : strconv . Itoa ( c . Id ) ,
Name : html . UnescapeString ( c . Name ) }
2017-05-05 03:53:38 +02:00
}
2017-05-04 05:28:42 +02:00
2017-05-05 03:53:38 +02:00
func ( c * Categories ) toJson ( ) CategoryJson {
return CategoryJson {
2017-05-05 06:07:45 +02:00
Id : strconv . Itoa ( c . Id ) ,
Name : html . UnescapeString ( c . Name ) }
2017-05-04 05:28:42 +02:00
}
2017-05-04 12:01:27 +02:00
2017-05-05 06:24:58 +02:00
/* Complete the functions when necessary... */