Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0
Ce dépôt a été archivé le 2022-05-07. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
nyaa-pantsu/util/search/search.go

262 lignes
9 Kio
Go
Brut Vue normale Historique

package search
2017-05-06 12:41:48 +02:00
import (
"net/http"
"strconv"
"strings"
"time"
2017-05-08 15:50:18 +02:00
"unicode"
"unicode/utf8"
2017-05-17 07:58:40 +02:00
"github.com/NyaaPantsu/nyaa/cache"
"github.com/NyaaPantsu/nyaa/common"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service"
"github.com/NyaaPantsu/nyaa/service/torrent"
"github.com/NyaaPantsu/nyaa/util/log"
)
var searchOperator string
var useTSQuery bool
// Configure : initialize search
func Configure(conf *config.SearchConfig) (err error) {
2017-05-12 19:38:08 +02:00
useTSQuery = false
// Postgres needs ILIKE for case-insensitivity
if db.ORM.Dialect().GetName() == "postgres" {
searchOperator = "ILIKE ?"
2017-05-12 19:38:08 +02:00
//useTSQuery = true
// !!DISABLED!! because this makes search a lot stricter
// (only matches at word borders)
} else {
searchOperator = "LIKE ?"
}
return
}
func stringIsASCII(input string) bool {
for _, char := range input {
if char > 127 {
return false
}
}
return true
}
// SearchByQuery : search torrents according to request without user
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) {
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
search, tor, count, err = searchByQuery(r, pagenum, true, false, false)
2017-05-20 13:45:15 +02:00
return
}
// SearchByQueryWithUser : search torrents according to request with user
2017-05-20 13:45:15 +02:00
func SearchByQueryWithUser(r *http.Request, pagenum int) (search common.SearchParam, tor []model.Torrent, count int, err error) {
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
search, tor, count, err = searchByQuery(r, pagenum, true, true, false)
2017-05-09 17:07:42 +02:00
return
}
// SearchByQueryNoCount : search torrents according to request without user and count
2017-05-10 11:03:49 +02:00
func SearchByQueryNoCount(r *http.Request, pagenum int) (search common.SearchParam, tor []model.Torrent, err error) {
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
search, tor, _, err = searchByQuery(r, pagenum, false, false, false)
2017-05-09 17:07:42 +02:00
return
}
// SearchByQueryDeleted : search deleted torrents according to request with user and count
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
func SearchByQueryDeleted(r *http.Request, pagenum int) (search common.SearchParam, tor []model.Torrent, count int, err error) {
search, tor, count, err = searchByQuery(r, pagenum, true, true, true)
return
}
// TODO Clean this up
// FIXME Some fields are not used by elasticsearch (pagenum, countAll, deleted, withUser)
// pagenum is extracted from request in .FromRequest()
// elasticsearch always provide a count to how many hits
// deleted is unused because es doesn't index deleted torrents
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
func searchByQuery(r *http.Request, pagenum int, countAll bool, withUser bool, deleted bool) (
2017-05-10 11:03:49 +02:00
search common.SearchParam, tor []model.Torrent, count int, err error,
) {
if db.ElasticSearchClient != nil {
var torrentParam common.TorrentParam
torrentParam.FromRequest(r)
2017-06-18 01:39:11 +02:00
torrentParam.Offset = uint32(pagenum)
totalHits, torrents, err := torrentParam.Find(db.ElasticSearchClient)
searchParam := common.SearchParam{
TorrentID: uint(torrentParam.TorrentID),
FromID: uint(torrentParam.FromID),
FromDate: torrentParam.FromDate,
ToDate: torrentParam.ToDate,
Order: torrentParam.Order,
Status: torrentParam.Status,
Sort: torrentParam.Sort,
Category: torrentParam.Category,
Page: int(torrentParam.Offset),
UserID: uint(torrentParam.UserID),
Max: uint(torrentParam.Max),
NotNull: torrentParam.NotNull,
Language: torrentParam.Language,
MinSize: torrentParam.MinSize,
MaxSize: torrentParam.MaxSize,
Query: torrentParam.NameLike,
}
// Convert back to non-json torrents
return searchParam, torrents, int(totalHits), err
}
log.Errorf("Unable to create elasticsearch client: %s", err)
log.Errorf("Falling back to postgresql query")
return searchByQueryPostgres(r, pagenum, countAll, withUser, deleted)
}
func searchByQueryPostgres(r *http.Request, pagenum int, countAll bool, withUser bool, deleted bool) (
search common.SearchParam, tor []model.Torrent, count int, err error,
2017-05-10 11:03:49 +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
}
search.Max = uint(max)
search.Page = pagenum
search.Query = r.URL.Query().Get("q")
search.Language = r.URL.Query().Get("lang")
userID, _ := strconv.Atoi(r.URL.Query().Get("userID"))
search.UserID = uint(userID)
fromID, _ := strconv.Atoi(r.URL.Query().Get("fromID"))
search.FromID = uint(fromID)
maxage, err := strconv.Atoi(r.URL.Query().Get("maxage"))
if err != nil {
if r.URL.Query().Get("toDate") != "" {
search.FromDate.Parse(r.URL.Query().Get("toDate"), r.URL.Query().Get("dateType"))
search.ToDate.Parse(r.URL.Query().Get("fromDate"), r.URL.Query().Get("dateType"))
} else {
search.FromDate.Parse(r.URL.Query().Get("fromDate"), r.URL.Query().Get("dateType"))
}
} else {
search.FromDate = common.DateFilter(time.Now().AddDate(0, 0, -maxage).Format("2006-01-02"))
}
search.Category = common.ParseCategories(r.URL.Query().Get("c"))
search.Status.Parse(r.URL.Query().Get("s"))
search.Sort.Parse(r.URL.Query().Get("sort"))
search.MinSize.Parse(r.URL.Query().Get("minSize"), r.URL.Query().Get("sizeType"))
search.MaxSize.Parse(r.URL.Query().Get("maxSize"), r.URL.Query().Get("sizeType"))
orderBy := search.Sort.ToDBField()
if search.Sort == common.Date {
search.NotNull = search.Sort.ToDBField() + " IS NOT NULL"
}
2017-05-08 16:39:41 +02:00
orderBy += " "
switch s := r.URL.Query().Get("order"); s {
case "true":
search.Order = true
orderBy += "asc"
2017-05-17 23:41:18 +02:00
if db.ORM.Dialect().GetName() == "postgres" {
orderBy += " NULLS FIRST"
2017-05-24 09:11:13 +02:00
}
2017-05-08 16:39:41 +02:00
default:
orderBy += "desc"
2017-05-17 23:41:18 +02:00
if db.ORM.Dialect().GetName() == "postgres" {
orderBy += " NULLS LAST"
2017-05-24 09:11:13 +02:00
}
}
2017-05-17 23:41:18 +02:00
2017-05-11 14:22:49 +02:00
parameters := serviceBase.WhereParams{
Params: make([]interface{}, 0, 64),
}
conditions := make([]string, 0, 64)
if len(search.Category) > 0 {
conditionsOr := make([]string, len(search.Category))
for key, val := range search.Category {
conditionsOr[key] = "(category = ? AND sub_category = ?)"
parameters.Params = append(parameters.Params, val.Main)
parameters.Params = append(parameters.Params, val.Sub)
}
conditions = append(conditions, strings.Join(conditionsOr, " OR "))
2017-05-11 14:22:49 +02:00
}
2017-05-11 14:22:49 +02:00
if search.UserID != 0 {
conditions = append(conditions, "uploader = ?")
parameters.Params = append(parameters.Params, search.UserID)
}
if search.FromID != 0 {
conditions = append(conditions, "torrent_id > ?")
parameters.Params = append(parameters.Params, search.FromID)
}
if search.FromDate != "" {
conditions = append(conditions, "date >= ?")
parameters.Params = append(parameters.Params, search.FromDate)
}
if search.ToDate != "" {
conditions = append(conditions, "date <= ?")
parameters.Params = append(parameters.Params, search.ToDate)
}
2017-05-11 14:22:49 +02:00
if search.Status != 0 {
if search.Status == common.FilterRemakes {
conditions = append(conditions, "status <> ?")
2017-05-11 14:22:49 +02:00
} else {
conditions = append(conditions, "status >= ?")
}
2017-05-11 14:22:49 +02:00
parameters.Params = append(parameters.Params, strconv.Itoa(int(search.Status)+1))
}
if len(search.NotNull) > 0 {
conditions = append(conditions, search.NotNull)
}
if search.Language != "" {
conditions = append(conditions, "language "+searchOperator)
parameters.Params = append(parameters.Params, "%"+search.Language+"%")
}
if search.MinSize > 0 {
conditions = append(conditions, "filesize >= ?")
parameters.Params = append(parameters.Params, uint64(search.MinSize))
}
if search.MaxSize > 0 {
conditions = append(conditions, "filesize <= ?")
parameters.Params = append(parameters.Params, uint64(search.MaxSize))
}
2017-05-11 14:22:49 +02:00
searchQuerySplit := strings.Fields(search.Query)
for _, word := range searchQuerySplit {
2017-05-11 14:22:49 +02:00
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-08 15:50:18 +02:00
}
if useTSQuery && stringIsASCII(word) {
conditions = append(conditions, "torrent_name @@ plainto_tsquery(?)")
parameters.Params = append(parameters.Params, word)
} else {
// TODO: possible to make this faster?
conditions = append(conditions, "torrent_name "+searchOperator)
parameters.Params = append(parameters.Params, "%"+word+"%")
}
2017-05-11 14:22:49 +02:00
}
parameters.Conditions = strings.Join(conditions[:], " AND ")
2017-05-11 14:22:49 +02:00
log.Infof("SQL query is :: %s\n", parameters.Conditions)
tor, count, err = cache.Impl.Get(search, func() (tor []model.Torrent, count int, err error) {
Deleted torrents mod done (#732) * Torrent Mass Edit Api (WIP) * Torrents can be deleted in mass from frontend with api post request * Torrents status can be edited from frontend with api post request -- Look to function doc for more info on how to use it It is a WIP so it might not work =D * Finished Mass mod Api As per suggestion of @yiiTT in #720, I added: * Changing torrents category * Deletion of reports with deletion of a torrent * Changing owner of multiple torrents Commit also add some new translation strings. * Make some changes * Reports can now be cleared for the torrents selected without having to delete them * Users with no admin rights can't delete reports * Fix moveto to status moveto deprecated in api * Tested and works! Changes: * Updates only the colomns of torrent table * Moved categories config in config/torrents.go * Forgot this file in last commit * Less useless queries The use of Save makes it that users are created and updates also all the associatiated models. Better to just update the colomns needed (less useless queries) * Some Updates * Added a new status of 5 for locking torrents * Modifying the list torrents view for using it in deleted torrents view * Added function to get deleted torrents * Torrents (and reports) can be definitely deleted * Some new translation string * Fixing * fix 2 * Added upload check for locked torrents If a user owns a torrent, has deleted it and try to repload it. As long as it has not been locked, he can. * Fixing wrong condition in isdeleted * Finished * Info messages on success when deletes or lock * Fixed double deleted_at is Null * Added Link to view of deleted torrents * Added new translation string
2017-05-25 02:19:05 +02:00
if deleted {
tor, count, err = torrentService.GetDeletedTorrents(&parameters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
} else if countAll && !withUser {
tor, count, err = torrentService.GetTorrentsOrderBy(&parameters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
2017-05-20 13:45:15 +02:00
} else if withUser {
tor, count, err = torrentService.GetTorrentsWithUserOrderBy(&parameters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
} else {
tor, err = torrentService.GetTorrentsOrderByNoCount(&parameters, orderBy, int(search.Max), int(search.Max)*(search.Page-1))
}
2017-05-10 11:03:49 +02:00
return
})
return
}