Compare commits
2 Commits
20b8d45495
...
691506ccc5
Author | SHA1 | Date | |
---|---|---|---|
|
691506ccc5 | ||
|
2b0d13cadf |
9
errors.go
Normal file
9
errors.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "git.milar.in/milarin/adverr"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrFeatureAlreadyCreated = adverr.NewErrTmpl("ErrFeatureAlreadyCreated", "duplicate feature: '%s'")
|
||||||
|
ErrFeatureWithoutValue = adverr.NewErrTmpl("ErrFeatureWithoutValue", "feature needs a value: '%s'")
|
||||||
|
ErrInvalidFeatureValue = adverr.NewErrTmpl("ErrInvalidFeatureValue", "feature needs a value of type %s")
|
||||||
|
)
|
204
feature.go
Normal file
204
feature.go
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Feature[T any] struct {
|
||||||
|
name string
|
||||||
|
value T
|
||||||
|
priority int
|
||||||
|
essential bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Feature1080p = &Feature[bool]{
|
||||||
|
name: "1080p",
|
||||||
|
value: true,
|
||||||
|
}
|
||||||
|
Feature720p = &Feature[bool]{
|
||||||
|
name: "720p",
|
||||||
|
value: true,
|
||||||
|
}
|
||||||
|
FeatureTrusted = &Feature[bool]{
|
||||||
|
name: "trusted",
|
||||||
|
value: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// string features are user-defined. 'primary key' is name and value
|
||||||
|
stringFeatures = []*Feature[string]{}
|
||||||
|
|
||||||
|
// bool features are known at compile time. 'primary key' is value only
|
||||||
|
boolFeatures = []*Feature[bool]{Feature1080p, Feature720p, FeatureTrusted}
|
||||||
|
)
|
||||||
|
|
||||||
|
func PrintAllFeatures() {
|
||||||
|
fmt.Printf("string features: %#v\n", stringFeatures)
|
||||||
|
fmt.Printf("bool features: %#v\n", boolFeatures)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeStringFeature(name, value string, priority int, essential bool) *Feature[string] {
|
||||||
|
for _, feature := range stringFeatures {
|
||||||
|
if feature.name == name && feature.value == value {
|
||||||
|
panic(ErrFeatureAlreadyCreated.New(fmt.Sprintf("%s:%s", name, value)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
feature := &Feature[string]{
|
||||||
|
name: name,
|
||||||
|
value: value,
|
||||||
|
priority: priority,
|
||||||
|
essential: essential,
|
||||||
|
}
|
||||||
|
|
||||||
|
stringFeatures = append(stringFeatures, feature)
|
||||||
|
return feature
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStringFeature(name, value string) *Feature[string] {
|
||||||
|
for _, feature := range stringFeatures {
|
||||||
|
if feature.name == name && feature.value == value {
|
||||||
|
return feature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lang and sub features have their special '_' value
|
||||||
|
if name == "lang" {
|
||||||
|
return makeStringFeature(name, value, 0, false)
|
||||||
|
} else if name == "sub" {
|
||||||
|
return makeStringFeature(name, value, 0, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBoolFeature(name string, value bool) *Feature[bool] {
|
||||||
|
for _, feature := range boolFeatures {
|
||||||
|
if feature.name == name {
|
||||||
|
return feature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseEssentialFeatures(essentialFeatureString string) {
|
||||||
|
featureSpecs := strings.Split(essentialFeatureString, ",")
|
||||||
|
|
||||||
|
for _, featureSpec := range featureSpecs {
|
||||||
|
handleFeatureSpec(featureSpec, -1, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParsePrioritizedFeatures(prioritizedFeatureString string) {
|
||||||
|
featureSpecs := strings.Split(prioritizedFeatureString, ",")
|
||||||
|
|
||||||
|
for index, featureSpec := range featureSpecs {
|
||||||
|
handleFeatureSpec(featureSpec, len(featureSpec)-index, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleFeatureSpec(featureSpec string, priority int, essential bool) {
|
||||||
|
data := strings.Split(featureSpec, ":")
|
||||||
|
name := data[0]
|
||||||
|
|
||||||
|
if name == "lang" || name == "sub" {
|
||||||
|
if len(data) < 2 {
|
||||||
|
panic(ErrFeatureWithoutValue.New(featureSpec))
|
||||||
|
}
|
||||||
|
value := data[1]
|
||||||
|
|
||||||
|
makeStringFeature(name, value, priority, essential)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
value := ""
|
||||||
|
if len(data) >= 2 {
|
||||||
|
value = data[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch name {
|
||||||
|
|
||||||
|
case "1080p":
|
||||||
|
{
|
||||||
|
Feature1080p.value, err = strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
panic(ErrInvalidFeatureValue.New("bool"))
|
||||||
|
}
|
||||||
|
Feature1080p.priority = priority
|
||||||
|
Feature1080p.essential = essential
|
||||||
|
}
|
||||||
|
|
||||||
|
case "720p":
|
||||||
|
{
|
||||||
|
Feature720p.value, err = strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
panic(ErrInvalidFeatureValue.New("bool"))
|
||||||
|
}
|
||||||
|
Feature720p.priority = priority
|
||||||
|
Feature720p.essential = essential
|
||||||
|
}
|
||||||
|
|
||||||
|
case "trusted":
|
||||||
|
{
|
||||||
|
FeatureTrusted.value, err = strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
panic(ErrInvalidFeatureValue.New("bool"))
|
||||||
|
}
|
||||||
|
FeatureTrusted.priority = priority
|
||||||
|
FeatureTrusted.essential = essential
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
examples for feature priorization:
|
||||||
|
|
||||||
|
# if multiple torrents are available, the torrent with most features of this list will be prioritized.
|
||||||
|
# when a new torrent with more features is uploaded, it will replace the files of the old torrent.
|
||||||
|
# that ensures availability of latest episodes but highest preferred quality on the long run
|
||||||
|
#
|
||||||
|
# This list is ordered by the separator '|'. Features within the same '|' block (separated by comma) get same priority.
|
||||||
|
# the first '|' block is prioritized highest.
|
||||||
|
#
|
||||||
|
# '_' is a placeholder for all other features not directly mentioned in the list.
|
||||||
|
# It can be used for a default priority. If not default priority is given, it will be set to 0.
|
||||||
|
#
|
||||||
|
# This example basically means:
|
||||||
|
# torrents with japanese language have priority 3
|
||||||
|
# torrents with english or german languages or subtitles in english or german have priority 2
|
||||||
|
# torrents with any other languages or subtitles will have priority 1
|
||||||
|
TORRENT_PRIORITIZED_FEATURES="sub:ja|lang:en,sub:en,lang:de,sub:de|lang:_,sub:_"
|
||||||
|
|
||||||
|
# torrents without these features will never be downloaded ('_' features not supported)-
|
||||||
|
#
|
||||||
|
# essential features will be parsed before prioritized features.
|
||||||
|
# a feature cannot be both essential and prioritized.
|
||||||
|
#
|
||||||
|
# This example basically means: Only download torrents with japanese language and subtitles
|
||||||
|
TORRENT_ESSENTIAL_FEATURES="lang:ja,1080p"
|
||||||
|
|
||||||
|
# complete feature list:
|
||||||
|
# "lang:<lang_code>": language (audio)
|
||||||
|
# "sub:<lang_code>": subtitles
|
||||||
|
# "1080p[:<bool>]": full hd resolution with optional bool flag
|
||||||
|
# "720p[:<bool>]": hd resolution
|
||||||
|
# "trusted[:<bool>]": trusted torrent uploader (highlighted in green on nyaa.si)
|
||||||
|
|
||||||
|
TODO: add feature min-seeders:<int_amount>
|
||||||
|
TODO: add feature max-seeders:<int_amount>
|
||||||
|
TODO: add feature min-leechers:<int_amount>
|
||||||
|
TODO: add feature max-leechers:<int_amount>
|
||||||
|
TODO: add feature min-downloads:<int_amount>
|
||||||
|
TODO: add feature max-downloads:<int_amount>
|
||||||
|
TODO: add feature min-upload-time:<datetime>
|
||||||
|
TODO: add feature max-upload-time:<datetime>
|
||||||
|
|
||||||
|
*/
|
5
go.mod
5
go.mod
@ -2,4 +2,7 @@ module git.milar.in/animan/model
|
|||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require git.milar.in/milarin/anilist v1.4.1
|
require (
|
||||||
|
git.milar.in/milarin/adverr v0.2.1
|
||||||
|
git.milar.in/milarin/anilist v1.4.1
|
||||||
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -1,2 +1,4 @@
|
|||||||
|
git.milar.in/milarin/adverr v0.2.1 h1:eyXFGC+Ui/kcNt2+NqP3HiAplwxzqeNr9DfitsUb3c4=
|
||||||
|
git.milar.in/milarin/adverr v0.2.1/go.mod h1:wwfglcey4R3vqjNL/d8mbnvFJGzETRXzAEolIHZY32w=
|
||||||
git.milar.in/milarin/anilist v1.4.1 h1:XxpKZ3CZiwKf7tUW2z+OMktWt/fLKMd8xAGPr+eodQE=
|
git.milar.in/milarin/anilist v1.4.1 h1:XxpKZ3CZiwKf7tUW2z+OMktWt/fLKMd8xAGPr+eodQE=
|
||||||
git.milar.in/milarin/anilist v1.4.1/go.mod h1:8PTHXFMA45JpfRFIpcdrKwDHue8fbT/wwV1BuHFn6c0=
|
git.milar.in/milarin/anilist v1.4.1/go.mod h1:8PTHXFMA45JpfRFIpcdrKwDHue8fbT/wwV1BuHFn6c0=
|
||||||
|
Loading…
Reference in New Issue
Block a user