2017-05-05 14:20:51 +02:00
package torrentService
2017-05-07 03:10:35 +02:00
2017-05-05 14:20:51 +02:00
import (
2017-05-07 03:10:35 +02:00
"errors"
2017-05-09 01:56:57 +02:00
"strconv"
"strings"
2017-05-07 03:10:35 +02:00
"github.com/ewhal/nyaa/config"
2017-05-05 14:20:51 +02:00
"github.com/ewhal/nyaa/db"
"github.com/ewhal/nyaa/model"
2017-05-07 03:10:35 +02:00
"github.com/ewhal/nyaa/util"
2017-05-05 14:20:51 +02:00
)
type WhereParams struct {
2017-05-05 14:51:19 +02:00
Conditions string // Ex : name LIKE ? AND category_id LIKE ?
Params [ ] interface { }
2017-05-05 14:20:51 +02:00
}
/ * Function to interact with Models
*
* Get the torrents with where clause
*
* /
// don't need raw SQL once we get MySQL
2017-05-09 19:23:21 +02:00
func GetFeeds ( ) ( result [ ] model . Feed , err error ) {
result = make ( [ ] model . Feed , 0 , 50 )
2017-05-05 14:20:51 +02:00
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" )
2017-05-09 19:23:21 +02:00
if err != nil {
return nil , err
}
defer rows . Close ( )
for rows . Next ( ) {
item := model . Feed { }
err = rows . Scan ( & item . Id , & item . Name , & item . Hash , & item . Timestamp )
if err != nil {
return
2017-05-05 14:20:51 +02:00
}
2017-05-09 19:23:21 +02:00
magnet := util . InfoHashToMagnet ( strings . TrimSpace ( item . Hash ) , item . Name , config . Trackers ... )
item . Magnet = magnet
// memory hog
result = append ( result , item )
2017-05-05 14:20:51 +02:00
}
2017-05-09 19:23:21 +02:00
err = rows . Err ( )
return
2017-05-05 14:20:51 +02:00
}
2017-05-09 19:23:21 +02:00
func GetTorrentById ( id string ) ( torrent model . Torrents , err error ) {
2017-05-08 23:40:54 +02:00
id_int , err := strconv . Atoi ( id )
if err != nil {
2017-05-09 19:23:21 +02:00
return
2017-05-08 23:40:54 +02:00
}
2017-05-05 14:20:51 +02:00
2017-05-08 23:40:54 +02:00
tmp := db . ORM . Where ( "torrent_id = ?" , id ) . Preload ( "Comments" )
2017-05-09 19:23:21 +02:00
err = tmp . Error
if err != nil {
return
}
2017-05-08 23:40:54 +02:00
if id_int <= config . LastOldTorrentId {
// only preload old comments if they could actually exist
tmp = tmp . Preload ( "OldComments" )
}
if tmp . Find ( & torrent ) . RecordNotFound ( ) {
2017-05-09 19:23:21 +02:00
err = errors . New ( "Article is not found." )
return
2017-05-05 14:20:51 +02:00
}
2017-05-09 12:35:46 +02:00
// GORM relly likes not doing its job correctly
// (or maybe I'm just retarded)
torrent . Uploader = new ( model . User )
db . ORM . Where ( "user_id = ?" , torrent . UploaderId ) . Find ( torrent . Uploader )
2017-05-08 21:18:48 +02:00
for i := range torrent . Comments {
torrent . Comments [ i ] . User = new ( model . User )
2017-05-09 19:23:21 +02:00
err = db . ORM . Where ( "user_id = ?" , torrent . Comments [ i ] . UserId ) . Find ( torrent . Comments [ i ] . User ) . Error
if err != nil {
return
}
2017-05-08 21:18:48 +02:00
}
2017-05-05 14:20:51 +02:00
2017-05-09 19:23:21 +02:00
return
2017-05-05 14:20:51 +02:00
}
2017-05-09 17:07:42 +02:00
func GetTorrentsOrderByNoCount ( parameters * WhereParams , orderBy string , limit int , offset int ) ( torrents [ ] model . Torrents , err error ) {
torrents , _ , err = getTorrentsOrderBy ( parameters , orderBy , limit , offset , false )
return
}
2017-05-09 13:31:58 +02:00
func GetTorrentsOrderBy ( parameters * WhereParams , orderBy string , limit int , offset int ) ( torrents [ ] model . Torrents , count int , err error ) {
2017-05-09 17:07:42 +02:00
torrents , count , err = getTorrentsOrderBy ( parameters , orderBy , limit , offset , true )
return
}
2017-05-09 19:23:21 +02:00
func getTorrentsOrderBy ( parameters * WhereParams , orderBy string , limit int , offset int , countAll bool ) (
torrents [ ] model . Torrents , count int , err error ,
) {
2017-05-08 22:46:49 +02:00
var conditionArray [ ] string
2017-05-07 21:04:21 +02:00
if strings . HasPrefix ( orderBy , "filesize" ) {
// torrents w/ NULL filesize fuck up the sorting on postgres
2017-05-08 22:46:49 +02:00
conditionArray = append ( conditionArray , "filesize IS NOT NULL" )
2017-05-07 21:04:21 +02:00
}
2017-05-05 14:20:51 +02:00
var params [ ] interface { }
if parameters != nil { // if there is where parameters
2017-05-08 16:53:15 +02:00
if len ( parameters . Conditions ) > 0 {
2017-05-08 22:46:49 +02:00
conditionArray = append ( conditionArray , parameters . Conditions )
2017-05-08 16:53:15 +02:00
}
2017-05-05 14:51:19 +02:00
params = parameters . Params
2017-05-05 14:20:51 +02:00
}
2017-05-08 22:46:49 +02:00
conditions := strings . Join ( conditionArray , " AND " )
2017-05-09 17:07:42 +02:00
if countAll {
err = db . ORM . Model ( & torrents ) . Where ( conditions , params ... ) . Count ( & count ) . Error
if err != nil {
return
}
2017-05-09 13:31:58 +02:00
}
// TODO: Vulnerable to injections. Use query builder.
2017-05-08 22:46:49 +02:00
// build custom db query for performance reasons
2017-05-08 15:50:18 +02:00
dbQuery := "SELECT * FROM torrents"
if conditions != "" {
dbQuery = dbQuery + " WHERE " + conditions
}
if strings . Contains ( conditions , "torrent_name" ) {
dbQuery = "WITH t AS (SELECT * FROM torrents WHERE " + conditions + ") SELECT * FROM t"
}
2017-05-05 14:20:51 +02:00
2017-05-07 21:04:21 +02:00
if orderBy == "" { // default OrderBy
2017-05-05 14:20:51 +02:00
orderBy = "torrent_id DESC"
2017-05-07 21:04:21 +02:00
}
2017-05-08 15:50:18 +02:00
dbQuery = dbQuery + " ORDER BY " + orderBy
2017-05-05 14:20:51 +02:00
if limit != 0 || offset != 0 { // if limits provided
2017-05-08 15:50:18 +02:00
dbQuery = dbQuery + " LIMIT " + strconv . Itoa ( limit ) + " OFFSET " + strconv . Itoa ( offset )
2017-05-05 14:20:51 +02:00
}
2017-05-09 13:31:58 +02:00
err = db . ORM . Raw ( dbQuery , params ... ) . Find ( & torrents ) . Error
return
2017-05-05 14:20:51 +02:00
}
/ * Functions to simplify the get parameters of the main function
*
* Get Torrents with where parameters and limits , order by default
* /
2017-05-09 13:31:58 +02:00
func GetTorrents ( parameters WhereParams , limit int , offset int ) ( [ ] model . Torrents , int , error ) {
2017-05-05 14:20:51 +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-09 13:31:58 +02:00
func GetTorrentsDB ( parameters WhereParams ) ( [ ] model . Torrents , int , error ) {
2017-05-05 14:20:51 +02:00
return GetTorrentsOrderBy ( & parameters , "" , 0 , 0 )
}
/ * Function to get all torrents
* /
2017-05-09 13:31:58 +02:00
func GetAllTorrentsOrderBy ( orderBy string , limit int , offset int ) ( [ ] model . Torrents , int , error ) {
2017-05-05 14:20:51 +02:00
return GetTorrentsOrderBy ( nil , orderBy , limit , offset )
}
2017-05-09 13:31:58 +02:00
func GetAllTorrents ( limit int , offset int ) ( [ ] model . Torrents , int , error ) {
2017-05-05 14:20:51 +02:00
return GetTorrentsOrderBy ( nil , "" , limit , offset )
}
2017-05-09 13:31:58 +02:00
func GetAllTorrentsDB ( ) ( [ ] model . Torrents , int , error ) {
2017-05-05 14:20:51 +02:00
return GetTorrentsOrderBy ( nil , "" , 0 , 0 )
}
func CreateWhereParams ( conditions string , params ... string ) WhereParams {
2017-05-09 01:56:57 +02:00
whereParams := WhereParams {
Conditions : conditions ,
Params : make ( [ ] interface { } , len ( params ) ) ,
}
for i := range params {
whereParams . Params [ i ] = params [ i ]
2017-05-05 14:20:51 +02:00
}
return whereParams
2017-05-06 22:32:50 +02:00
}
2017-05-10 04:03:25 +02:00
func DeleteTorrent ( id string ) {
var torrent model . Torrents
if db . ORM . First ( & torrent , id ) . RecordNotFound ( ) {
return http . StatusNotFound , errors . New ( "Torrent is not found." )
}
if db . ORM . Delete ( & torrent ) . Error != nil {
return http . StatusInternalServerError , errors . New ( "Torrent is not deleted." )
}
return http . StatusOK , nil
}