package common import ( "math" "time" humanize "github.com/dustin/go-humanize" "strconv" "strings" "github.com/NyaaPantsu/nyaa/config" catUtil "github.com/NyaaPantsu/nyaa/util/categories" ) type Status uint8 const ( ShowAll Status = 0 FilterRemakes = 2 Trusted = 3 APlus = 4 ) 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 } } type SortMode uint8 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.Conf.Torrents.Order } type Category struct { Main, Sub uint8 } 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 } // Parse sets category by string // returns true if string is valid otherwise returns false 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.CategoryExists(partsCat[0] + "_" + partsCat[1]) { categories = append(categories, &Category{ Main: c, Sub: sub, }) } } } } return categories } return Categories{} } type SizeBytes uint64 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 } type DateFilter string 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 } type Categories []*Category // deprecated for TorrentParam type SearchParam struct { TorrentID uint FromID uint // Search for torrentID > FromID Order bool // True means acsending Hidden bool // True means filter hidden torrents Status Status Sort SortMode Category Categories FromDate DateFilter ToDate DateFilter Page int UserID uint Max uint NotNull string Language string MinSize SizeBytes MaxSize SizeBytes Query string }