299 lignes
5,7 Kio
Go
299 lignes
5,7 Kio
Go
package structs
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
|
|
humanize "github.com/dustin/go-humanize"
|
|
|
|
"strconv"
|
|
"strings"
|
|
|
|
"fmt"
|
|
|
|
"github.com/NyaaPantsu/nyaa/config"
|
|
catUtil "github.com/NyaaPantsu/nyaa/utils/categories"
|
|
"github.com/NyaaPantsu/nyaa/utils/publicSettings"
|
|
)
|
|
|
|
const (
|
|
// ShowAll by default show all torrents
|
|
ShowAll Status = 0
|
|
// FilterRemakes filter torrent remakes
|
|
FilterRemakes = 2
|
|
// Trusted trusted torrents
|
|
Trusted = 3
|
|
// APlus torrents not used anymore
|
|
APlus = 4
|
|
)
|
|
|
|
// Status torrent status
|
|
type Status uint8
|
|
|
|
// SortMode selected sort mode
|
|
type SortMode uint8
|
|
|
|
// Category torrent categories
|
|
type Category struct {
|
|
Main, Sub uint8
|
|
}
|
|
|
|
// SizeBytes size in bytes
|
|
type SizeBytes uint64
|
|
|
|
// DateFilter date to filter for
|
|
type DateFilter string
|
|
|
|
// Categories multiple torrent categories
|
|
type Categories []*Category
|
|
|
|
// TorrentParam defines all parameters that can be provided when searching for a torrent
|
|
type TorrentParam struct {
|
|
Full bool // True means load all members
|
|
Order bool // True means ascending
|
|
Hidden bool // True means filter hidden torrents
|
|
Deleted bool // False means filter deleted torrents
|
|
Status Status
|
|
Sort SortMode
|
|
Category Categories
|
|
Max uint32
|
|
Offset uint32
|
|
UserID uint32
|
|
TorrentID uint32
|
|
FromID uint32
|
|
FromDate DateFilter
|
|
ToDate DateFilter
|
|
NotNull string // csv
|
|
NameLike string // csv
|
|
Languages publicSettings.Languages
|
|
MinSize SizeBytes
|
|
MaxSize SizeBytes
|
|
}
|
|
|
|
func (p *TorrentParam) Identifier() string {
|
|
cats := ""
|
|
for _, v := range p.Category {
|
|
cats += fmt.Sprintf("%d%d", v.Main, v.Sub)
|
|
}
|
|
languages := ""
|
|
for _, v := range p.Languages {
|
|
languages += fmt.Sprintf("%s%s", v.Code, v.Name)
|
|
}
|
|
return fmt.Sprintf("%s%s%s%d%d%d%d%d%d%d%s%s%d%d%s%t%t%t%t", p.NameLike, p.NotNull, languages, p.Max, p.Offset, p.FromID, p.MinSize, p.MaxSize, p.Status, p.Sort, p.FromDate, p.ToDate, p.UserID, p.TorrentID, cats, p.Full, p.Order, p.Hidden, p.Deleted)
|
|
}
|
|
|
|
func (st *Status) ToString() string {
|
|
switch *st {
|
|
case FilterRemakes:
|
|
return "2"
|
|
case Trusted:
|
|
return "3"
|
|
case APlus:
|
|
return "4"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (st *Status) Parse(s string) {
|
|
switch s {
|
|
case "2":
|
|
*st = FilterRemakes
|
|
case "3":
|
|
*st = Trusted
|
|
case "4":
|
|
*st = APlus
|
|
default:
|
|
*st = ShowAll
|
|
}
|
|
}
|
|
|
|
const (
|
|
ID SortMode = iota
|
|
Name
|
|
Date
|
|
Downloads
|
|
Size
|
|
Seeders
|
|
Leechers
|
|
Completed
|
|
)
|
|
|
|
func (s *SortMode) Parse(str string) {
|
|
switch str {
|
|
case "1":
|
|
*s = Name
|
|
case "2":
|
|
*s = Date
|
|
case "3":
|
|
*s = Downloads
|
|
case "4":
|
|
*s = Size
|
|
case "5":
|
|
*s = Seeders
|
|
case "6":
|
|
*s = Leechers
|
|
case "7":
|
|
*s = Completed
|
|
default:
|
|
*s = Date
|
|
}
|
|
}
|
|
|
|
/* INFO Always need to keep in sync with the field that are used in the
|
|
* elasticsearch index.
|
|
* TODO Verify the field in postgres database
|
|
*/
|
|
func (s *SortMode) ToESField() string {
|
|
switch *s {
|
|
case ID:
|
|
return "id"
|
|
case Name:
|
|
return "name.raw"
|
|
case Date:
|
|
return "date"
|
|
case Downloads:
|
|
return "downloads"
|
|
case Size:
|
|
return "filesize"
|
|
case Seeders:
|
|
return "seeders"
|
|
case Leechers:
|
|
return "leechers"
|
|
case Completed:
|
|
return "completed"
|
|
}
|
|
return "id"
|
|
}
|
|
|
|
func (s *SortMode) ToDBField() string {
|
|
switch *s {
|
|
case ID:
|
|
return "torrent_id"
|
|
case Name:
|
|
return "torrent_name"
|
|
case Date:
|
|
return "date"
|
|
case Downloads:
|
|
return "downloads"
|
|
case Size:
|
|
return "filesize"
|
|
case Seeders:
|
|
return "seeders"
|
|
case Leechers:
|
|
return "leechers"
|
|
case Completed:
|
|
return "completed"
|
|
}
|
|
return config.Get().Torrents.Order
|
|
}
|
|
|
|
func (c Category) String() (s string) {
|
|
if c.Main != 0 {
|
|
s += strconv.Itoa(int(c.Main))
|
|
}
|
|
s += "_"
|
|
if c.Sub != 0 {
|
|
s += strconv.Itoa(int(c.Sub))
|
|
}
|
|
return
|
|
}
|
|
|
|
func (c Category) IsSet() bool {
|
|
return c.IsMainSet() && c.IsSubSet()
|
|
}
|
|
|
|
func (c Category) IsMainSet() bool {
|
|
return c.Main != 0
|
|
}
|
|
|
|
func (c Category) IsSubSet() bool {
|
|
return c.Sub != 0
|
|
}
|
|
|
|
// ParseCategories sets category by string
|
|
func ParseCategories(s string) []*Category {
|
|
if s != "" {
|
|
parts := strings.Split(s, ",")
|
|
var categories []*Category
|
|
for _, val := range parts {
|
|
partsCat := strings.Split(val, "_")
|
|
if len(partsCat) == 2 {
|
|
tmp, err := strconv.ParseUint(partsCat[0], 10, 8)
|
|
if err == nil {
|
|
c := uint8(tmp)
|
|
tmp, err = strconv.ParseUint(partsCat[1], 10, 8)
|
|
var sub uint8
|
|
if err == nil {
|
|
sub = uint8(tmp)
|
|
}
|
|
if catUtil.Exists(partsCat[0] + "_" + partsCat[1]) {
|
|
categories = append(categories, &Category{
|
|
Main: c,
|
|
Sub: sub,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return categories
|
|
}
|
|
return Categories{}
|
|
}
|
|
|
|
// ParseLanguages sets languages by string
|
|
func ParseLanguages(s string) publicSettings.Languages {
|
|
var languages publicSettings.Languages
|
|
if s != "" {
|
|
parts := strings.Split(s, ",")
|
|
for _, lang := range parts {
|
|
languages = append(languages, publicSettings.Language{Name: "", Code: lang}) // We just need the code
|
|
}
|
|
}
|
|
return languages
|
|
}
|
|
|
|
func (sz *SizeBytes) Parse(s string, sizeType string) bool {
|
|
if s == "" {
|
|
*sz = 0
|
|
return false
|
|
}
|
|
var multiplier uint64
|
|
switch sizeType {
|
|
case "b":
|
|
multiplier = 1
|
|
case "k":
|
|
multiplier = uint64(math.Exp2(10))
|
|
case "m":
|
|
multiplier = uint64(math.Exp2(20))
|
|
case "g":
|
|
multiplier = uint64(math.Exp2(30))
|
|
}
|
|
size64, err := humanize.ParseBytes(s)
|
|
if err != nil {
|
|
*sz = 0
|
|
return false
|
|
}
|
|
*sz = SizeBytes(size64 * multiplier)
|
|
return true
|
|
}
|
|
|
|
func (d *DateFilter) Parse(s string, dateType string) bool {
|
|
if s == "" {
|
|
*d = ""
|
|
return false
|
|
}
|
|
dateInt, err := strconv.Atoi(s)
|
|
if err != nil {
|
|
*d = ""
|
|
return false
|
|
}
|
|
switch dateType {
|
|
case "m":
|
|
*d = DateFilter(time.Now().AddDate(0, -dateInt, 0).Format("2006-01-02"))
|
|
case "y":
|
|
*d = DateFilter(time.Now().AddDate(-dateInt, 0, 0).Format("2006-01-02"))
|
|
default:
|
|
*d = DateFilter(time.Now().AddDate(0, 0, -dateInt).Format("2006-01-02"))
|
|
}
|
|
return true
|
|
}
|