When in a user page and clicked on more torrents, show a list navigable of the user torrent On that list, we can make advance search (categories, order, ...) Moderation search reimplemented Clicking on user (id) in the torrent list redirect to the list of the user torrents Ability to search within the user torrents
170 lignes
4,4 Kio
Go
170 lignes
4,4 Kio
Go
package search
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
|
|
"github.com/ewhal/nyaa/cache"
|
|
"github.com/ewhal/nyaa/common"
|
|
"github.com/ewhal/nyaa/db"
|
|
"github.com/ewhal/nyaa/model"
|
|
"github.com/ewhal/nyaa/service"
|
|
"github.com/ewhal/nyaa/service/torrent"
|
|
"github.com/ewhal/nyaa/util/log"
|
|
)
|
|
|
|
func SearchByQuery(r *http.Request, pagenum int) (search common.SearchParam, tor []model.Torrent, count int, err error) {
|
|
search, tor, count, err = searchByQuery(r, pagenum, true)
|
|
return
|
|
}
|
|
|
|
func SearchByQueryNoCount(r *http.Request, pagenum int) (search common.SearchParam, tor []model.Torrent, err error) {
|
|
search, tor, _, err = searchByQuery(r, pagenum, false)
|
|
return
|
|
}
|
|
|
|
func searchByQuery(r *http.Request, pagenum int, countAll bool) (
|
|
search common.SearchParam, tor []model.Torrent, count int, err error,
|
|
) {
|
|
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
|
|
}
|
|
search.Max = uint(max)
|
|
|
|
search.Page = pagenum
|
|
search.Query = r.URL.Query().Get("q")
|
|
userID, _ := strconv.Atoi(r.URL.Query().Get("userID"))
|
|
search.UserID = uint(userID)
|
|
|
|
switch s := r.URL.Query().Get("s"); s {
|
|
case "1":
|
|
search.Status = common.FilterRemakes
|
|
case "2":
|
|
search.Status = common.Trusted
|
|
case "3":
|
|
search.Status = common.APlus
|
|
}
|
|
|
|
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)
|
|
|
|
if len(s) == 3 {
|
|
tmp, err = strconv.ParseUint(string(s[2]), 10, 8)
|
|
if err != nil {
|
|
return
|
|
}
|
|
search.Category.Sub = uint8(tmp)
|
|
}
|
|
}
|
|
|
|
orderBy := ""
|
|
|
|
switch s := r.URL.Query().Get("sort"); s {
|
|
case "1":
|
|
search.Sort = common.Name
|
|
orderBy += "torrent_name"
|
|
case "2":
|
|
search.Sort = common.Date
|
|
orderBy += "date"
|
|
case "3":
|
|
search.Sort = common.Downloads
|
|
orderBy += "downloads"
|
|
case "4":
|
|
search.Sort = common.Size
|
|
orderBy += "filesize"
|
|
case "5":
|
|
orderBy += "seeders"
|
|
case "6":
|
|
orderBy += "leechers"
|
|
case "7":
|
|
orderBy += "completed"
|
|
default:
|
|
orderBy += "torrent_id"
|
|
}
|
|
|
|
orderBy += " "
|
|
|
|
switch s := r.URL.Query().Get("order"); s {
|
|
case "true":
|
|
search.Order = true
|
|
orderBy += "asc"
|
|
default:
|
|
orderBy += "desc"
|
|
}
|
|
|
|
tor, count, err = cache.Get(search, func() (tor []model.Torrent, count int, err error) {
|
|
parameters := serviceBase.WhereParams{
|
|
Params: make([]interface{}, 0, 64),
|
|
}
|
|
conditions := make([]string, 0, 64)
|
|
if search.Category.Main != 0 {
|
|
conditions = append(conditions, "category = ?")
|
|
parameters.Params = append(parameters.Params, string(catString[0]))
|
|
}
|
|
if search.UserID != 0 {
|
|
conditions = append(conditions, "uploader = ?")
|
|
parameters.Params = append(parameters.Params, search.UserID)
|
|
}
|
|
if search.Category.Sub != 0 {
|
|
conditions = append(conditions, "sub_category = ?")
|
|
parameters.Params = append(parameters.Params, string(catString[2]))
|
|
}
|
|
if search.Status != 0 {
|
|
if search.Status == common.FilterRemakes {
|
|
conditions = append(conditions, "status > ?")
|
|
} else {
|
|
conditions = append(conditions, "status >= ?")
|
|
}
|
|
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
|
|
}
|
|
|
|
// 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]+"%")
|
|
}
|
|
|
|
parameters.Conditions = strings.Join(conditions[:], " AND ")
|
|
log.Infof("SQL query is :: %s\n", parameters.Conditions)
|
|
if countAll {
|
|
tor, count, err = torrentService.GetTorrentsOrderBy(¶meters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
|
|
} else {
|
|
tor, err = torrentService.GetTorrentsOrderByNoCount(¶meters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
|
|
}
|
|
|
|
return
|
|
})
|
|
|
|
return
|
|
}
|