- Retyr RD 502 errors
- Fix issues with re-inserted torrents bugging out - Fix version.txt - Massive improvements in importing times - Fix issues with config.json resetting - Fix other minor issues
This commit is contained in:
@@ -119,19 +119,21 @@ func (c *Config) loadConfig() error {
|
||||
file, err := os.ReadFile(c.JsonFile())
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Printf("Config file not found, creating a new one at %s\n", c.JsonFile())
|
||||
// Create a default config file if it doesn't exist
|
||||
if err := c.createConfig(c.Path); err != nil {
|
||||
return fmt.Errorf("failed to create config file: %w", err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("error reading config file: %w", err)
|
||||
}
|
||||
} else {
|
||||
if err := json.Unmarshal(file, &c); err != nil {
|
||||
return fmt.Errorf("error unmarshaling config: %w", err)
|
||||
return c.Save()
|
||||
}
|
||||
return fmt.Errorf("error reading config file: %w", err)
|
||||
}
|
||||
return c.Save()
|
||||
|
||||
if err := json.Unmarshal(file, &c); err != nil {
|
||||
return fmt.Errorf("error unmarshaling config: %w", err)
|
||||
}
|
||||
c.setDefaults()
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDebrids(debrids []Debrid) error {
|
||||
@@ -312,7 +314,7 @@ func (c *Config) updateDebrid(d Debrid) Debrid {
|
||||
return d
|
||||
}
|
||||
|
||||
func (c *Config) Save() error {
|
||||
func (c *Config) setDefaults() {
|
||||
for i, debrid := range c.Debrids {
|
||||
c.Debrids[i] = c.updateDebrid(debrid)
|
||||
}
|
||||
@@ -333,6 +335,12 @@ func (c *Config) Save() error {
|
||||
|
||||
// Load the auth file
|
||||
c.Auth = c.GetAuth()
|
||||
}
|
||||
|
||||
func (c *Config) Save() error {
|
||||
|
||||
c.setDefaults()
|
||||
|
||||
data, err := json.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -382,22 +382,45 @@ func JSONResponse(w http.ResponseWriter, data interface{}, code int) {
|
||||
}
|
||||
}
|
||||
|
||||
func Gzip(body []byte) []byte {
|
||||
|
||||
var b bytes.Buffer
|
||||
func Gzip(body []byte, pool *sync.Pool) []byte {
|
||||
if len(body) == 0 {
|
||||
return nil
|
||||
}
|
||||
gz := gzip.NewWriter(&b)
|
||||
_, err := gz.Write(body)
|
||||
|
||||
var (
|
||||
buf *bytes.Buffer
|
||||
ok bool
|
||||
)
|
||||
|
||||
// Check if the pool is nil
|
||||
if pool == nil {
|
||||
buf = bytes.NewBuffer(make([]byte, 0, len(body)))
|
||||
} else {
|
||||
buf, ok = pool.Get().(*bytes.Buffer)
|
||||
|
||||
if !ok || buf == nil {
|
||||
buf = bytes.NewBuffer(make([]byte, 0, len(body)))
|
||||
} else {
|
||||
buf.Reset()
|
||||
}
|
||||
defer pool.Put(buf)
|
||||
}
|
||||
|
||||
gz, err := gzip.NewWriterLevel(buf, gzip.BestSpeed)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err = gz.Close()
|
||||
if err != nil {
|
||||
|
||||
if _, err := gz.Write(body); err != nil {
|
||||
return nil
|
||||
}
|
||||
return b.Bytes()
|
||||
if err := gz.Close(); err != nil {
|
||||
return nil
|
||||
}
|
||||
result := make([]byte, buf.Len())
|
||||
copy(result, buf.Bytes())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Default() *Client {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Debouncer[T any] struct {
|
||||
mu sync.Mutex
|
||||
timer *time.Timer
|
||||
interval time.Duration
|
||||
caller func(arg T)
|
||||
arg T
|
||||
}
|
||||
|
||||
func NewDebouncer[T any](interval time.Duration, caller func(arg T)) *Debouncer[T] {
|
||||
return &Debouncer[T]{
|
||||
interval: interval,
|
||||
caller: caller,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Debouncer[T]) Call(arg T) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
if d.timer != nil {
|
||||
d.timer.Stop()
|
||||
}
|
||||
|
||||
d.timer = time.AfterFunc(d.interval, func() {
|
||||
d.caller(arg)
|
||||
})
|
||||
}
|
||||
@@ -11,7 +11,7 @@ var (
|
||||
MUSICMATCH = "(?i)(\\.)(mp2|mp3|m4a|m4b|m4p|ogg|oga|opus|wma|wav|wv|flac|ape|aif|aiff|aifc)$"
|
||||
)
|
||||
|
||||
var SAMPLEMATCH = `(?i)(^|[\\/])(sample|trailer|thumb|special|extras?)s?([\s._-]|$|/)|(\(sample\))|(-\s*sample)`
|
||||
var SAMPLEMATCH = `(?i)(^|[\s/\\])(sample|trailer|thumb|special|extras?)s?[-/]|(\((sample|trailer|thumb|special|extras?)s?\))|(-\s*(sample|trailer|thumb|special|extras?)s?)`
|
||||
|
||||
func RegexMatch(regex string, value string) bool {
|
||||
re := regexp.MustCompile(regex)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-co-op/gocron/v2"
|
||||
"github.com/robfig/cron/v3"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -40,14 +41,17 @@ func convertToJD(interval string) (gocron.JobDefinition, error) {
|
||||
return gocron.DailyJob(1, gocron.NewAtTimes(
|
||||
gocron.NewAtTime(uint(t.Hour()), uint(t.Minute()), uint(t.Second())),
|
||||
)), nil
|
||||
} else {
|
||||
dur, err := time.ParseDuration(interval)
|
||||
if err != nil {
|
||||
return jd, fmt.Errorf("failed to parse duration: %w", err)
|
||||
}
|
||||
jd = gocron.DurationJob(dur)
|
||||
}
|
||||
return jd, nil
|
||||
|
||||
if _, err := cron.ParseStandard(interval); err == nil {
|
||||
return gocron.CronJob(interval, false), nil
|
||||
}
|
||||
|
||||
if dur, err := time.ParseDuration(interval); err == nil {
|
||||
return gocron.DurationJob(dur), nil
|
||||
}
|
||||
|
||||
return jd, fmt.Errorf("invalid interval format: %s", interval)
|
||||
}
|
||||
|
||||
func parseClockTime(s string) (time.Time, bool) {
|
||||
|
||||
Reference in New Issue
Block a user