2017-05-05 16:39:15 +02:00
package search
2017-05-06 12:41:48 +02:00
import (
"net/http"
2017-05-05 16:39:15 +02:00
"strconv"
"strings"
2017-05-08 15:50:18 +02:00
"unicode"
"unicode/utf8"
2017-05-05 16:39:15 +02:00
2017-05-10 11:03:49 +02:00
"github.com/ewhal/nyaa/cache"
"github.com/ewhal/nyaa/common"
"github.com/ewhal/nyaa/db"
"github.com/ewhal/nyaa/model"
2017-05-10 20:42:20 +02:00
"github.com/ewhal/nyaa/service"
2017-05-10 11:03:49 +02:00
"github.com/ewhal/nyaa/service/torrent"
"github.com/ewhal/nyaa/util/log"
2017-05-09 13:31:58 +02:00
)
2017-05-10 11:03:49 +02:00
func SearchByQuery ( r * http . Request , pagenum int ) ( search common . SearchParam , tor [ ] model . Torrent , count int , err error ) {
2017-05-09 17:07:42 +02:00
search , tor , count , err = searchByQuery ( r , pagenum , true )
return
}
2017-05-10 11:03:49 +02:00
func SearchByQueryNoCount ( r * http . Request , pagenum int ) ( search common . SearchParam , tor [ ] model . Torrent , err error ) {
2017-05-09 17:07:42 +02:00
search , tor , _ , err = searchByQuery ( r , pagenum , false )
return
}
2017-05-10 11:03:49 +02:00
func searchByQuery ( r * http . Request , pagenum int , countAll bool ) (
search common . SearchParam , tor [ ] model . Torrent , count int , err error ,
) {
2017-05-09 13:31:58 +02:00
max , err := strconv . ParseUint ( r . URL . Query ( ) . Get ( "max" ) , 10 , 32 )
if err != nil {
max = 50 // default Value maxPerPage
} else if max > 300 {
max = 300
2017-05-05 16:39:15 +02:00
}
2017-05-09 13:31:58 +02:00
search . Max = uint ( max )
2017-05-10 11:32:49 +02:00
search . Page = pagenum
2017-05-09 13:31:58 +02:00
search . Query = r . URL . Query ( ) . Get ( "q" )
2017-05-06 12:41:48 +02:00
2017-05-09 13:31:58 +02:00
switch s := r . URL . Query ( ) . Get ( "s" ) ; s {
case "1" :
2017-05-10 11:03:49 +02:00
search . Status = common . FilterRemakes
2017-05-09 13:31:58 +02:00
case "2" :
2017-05-10 11:03:49 +02:00
search . Status = common . Trusted
2017-05-09 13:31:58 +02:00
case "3" :
2017-05-10 11:03:49 +02:00
search . Status = common . APlus
2017-05-06 12:41:48 +02:00
}
2017-05-05 16:39:15 +02:00
2017-05-09 13:31:58 +02:00
catString := r . URL . Query ( ) . Get ( "c" )
if s := catString ; len ( s ) > 1 && s != "_" {
var tmp uint64
tmp , err = strconv . ParseUint ( string ( s [ 0 ] ) , 10 , 8 )
if err != nil {
return
}
search . Category . Main = uint8 ( tmp )
2017-05-05 16:39:15 +02:00
2017-05-09 13:31:58 +02:00
if len ( s ) == 3 {
tmp , err = strconv . ParseUint ( string ( s [ 2 ] ) , 10 , 8 )
if err != nil {
return
}
search . Category . Sub = uint8 ( tmp )
}
2017-05-05 16:39:15 +02:00
}
2017-05-08 16:39:41 +02:00
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy := ""
2017-05-09 13:31:58 +02:00
switch s := r . URL . Query ( ) . Get ( "sort" ) ; s {
case "1" :
2017-05-10 11:03:49 +02:00
search . Sort = common . Name
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "torrent_name"
2017-05-09 13:31:58 +02:00
case "2" :
2017-05-10 11:03:49 +02:00
search . Sort = common . Date
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "date"
2017-05-09 13:31:58 +02:00
case "3" :
2017-05-10 11:03:49 +02:00
search . Sort = common . Downloads
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "downloads"
2017-05-09 13:31:58 +02:00
case "4" :
2017-05-10 11:03:49 +02:00
search . Sort = common . Size
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "filesize"
2017-05-08 16:39:41 +02:00
default :
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "torrent_id"
2017-05-05 16:39:15 +02:00
}
2017-05-08 16:39:41 +02:00
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += " "
2017-05-09 13:31:58 +02:00
switch s := r . URL . Query ( ) . Get ( "order" ) ; s {
case "true" :
search . Order = true
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "asc"
2017-05-08 16:39:41 +02:00
default :
Consistency, formatting, error checking, cleanup, and a couple bug fixes (#245)
* Checkpoint: it builds
The config, db, model, network, os, and public packages have had some
fixes to glaringly obvious flaws, dead code removed, and stylistic
changes.
* Style changes and old code removal in router
Router needs a lot of work done to its (lack of) error handling.
* Dead code removal and style changes
Now up to util/email/email.go. After I'm finished with the initial sweep
I'll go back and fix error handling and security issues. Then I'll fix
the broken API. Then I'll go through to add documentation and fix code
visibility.
* Finish dead code removal and style changes
Vendored libraries not touched. Everything still needs security fixes
and documentation. There's also one case of broken functionality.
* Fix accidental find-and-replace
* Style, error checking, saftey, bug fix changes
* Redo error checking erased during merge
* Re-add merge-erased fix. Make Safe safe.
2017-05-10 04:34:40 +02:00
orderBy += "desc"
2017-05-05 16:39:15 +02:00
}
2017-05-08 16:39:41 +02:00
2017-05-10 11:32:49 +02:00
tor , count , err = cache . Get ( search , func ( ) ( tor [ ] model . Torrent , count int , err error ) {
2017-05-10 20:42:20 +02:00
parameters := serviceBase . WhereParams {
2017-05-10 11:03:49 +02:00
Params : make ( [ ] interface { } , 0 , 64 ) ,
2017-05-05 22:30:56 +02:00
}
2017-05-10 11:03:49 +02:00
conditions := make ( [ ] string , 0 , 64 )
if search . Category . Main != 0 {
conditions = append ( conditions , "category = ?" )
parameters . Params = append ( parameters . Params , string ( catString [ 0 ] ) )
}
if search . Category . Sub != 0 {
conditions = append ( conditions , "sub_category = ?" )
parameters . Params = append ( parameters . Params , string ( catString [ 2 ] ) )
}
if search . Status != 0 {
2017-05-10 23:09:38 +02:00
if search . Status == common . FilterRemakes {
2017-05-11 01:13:54 +02:00
conditions = append ( conditions , "status > ?" )
2017-05-10 11:03:49 +02:00
} else {
2017-05-11 01:13:54 +02:00
conditions = append ( conditions , "status >= ?" )
2017-05-10 11:03:49 +02:00
}
parameters . Params = append ( parameters . Params , strconv . Itoa ( int ( search . Status ) + 1 ) )
}
searchQuerySplit := strings . Fields ( search . Query )
for i , word := range searchQuerySplit {
firstRune , _ := utf8 . DecodeRuneInString ( word )
if len ( word ) == 1 && unicode . IsPunct ( firstRune ) {
// some queries have a single punctuation character
// which causes a full scan instead of using the index
// and yields no meaningful results.
// due to len() == 1 we're just looking at 1-byte/ascii
// punctuation characters.
continue
}
2017-05-09 13:31:58 +02:00
2017-05-10 11:03:49 +02:00
// SQLite has case-insensitive LIKE, but no ILIKE
var operator string
if db . ORM . Dialect ( ) . GetName ( ) == "sqlite3" {
operator = "LIKE ?"
} else {
operator = "ILIKE ?"
}
// TODO: make this faster ?
conditions = append ( conditions , "torrent_name " + operator )
parameters . Params = append ( parameters . Params , "%" + searchQuerySplit [ i ] + "%" )
2017-05-08 15:50:18 +02:00
}
2017-05-09 14:31:47 +02:00
2017-05-10 11:03:49 +02:00
parameters . Conditions = strings . Join ( conditions [ : ] , " AND " )
log . Infof ( "SQL query is :: %s\n" , parameters . Conditions )
if countAll {
2017-05-10 11:32:49 +02:00
tor , count , err = torrentService . GetTorrentsOrderBy ( & parameters , orderBy , int ( search . Max ) , int ( search . Max ) * ( search . Page - 1 ) )
2017-05-09 14:31:47 +02:00
} else {
2017-05-10 11:32:49 +02:00
tor , err = torrentService . GetTorrentsOrderByNoCount ( & parameters , orderBy , int ( search . Max ) , int ( search . Max ) * ( search . Page - 1 ) )
2017-05-09 14:31:47 +02:00
}
2017-05-10 11:03:49 +02:00
return
} )
2017-05-05 16:39:15 +02:00
2017-05-09 13:31:58 +02:00
return
2017-05-05 16:39:15 +02:00
}