feat: add torznab feed support (#246)

* feat(torznab): initial impl

* feat: torznab processing

* feat: torznab more scheduling

* feat: feeds web

* feat(feeds): create on indexer create

* feat(feeds): update migration

* feat(feeds): restart on update

* feat(feeds): set cron schedule

* feat(feeds): use basic empty state

* chore: remove duplicate migrations

* feat: parse release size from torznab

* chore: cleanup unused code
This commit is contained in:
Ludvig Lundgren 2022-04-25 12:58:54 +02:00 committed by GitHub
parent d4d864cd2c
commit bb62e724a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 2408 additions and 361 deletions

52
internal/domain/feed.go Normal file
View file

@ -0,0 +1,52 @@
package domain
import (
"context"
"time"
)
type FeedCacheRepo interface {
Get(bucket string, key string) ([]byte, error)
Exists(bucket string, key string) (bool, error)
Put(bucket string, key string, val []byte, ttl time.Duration) error
Delete(bucket string, key string) error
}
type FeedRepo interface {
FindByID(ctx context.Context, id int) (*Feed, error)
FindByIndexerIdentifier(ctx context.Context, indexer string) (*Feed, error)
Find(ctx context.Context) ([]Feed, error)
Store(ctx context.Context, feed *Feed) error
Update(ctx context.Context, feed *Feed) error
ToggleEnabled(ctx context.Context, id int, enabled bool) error
Delete(ctx context.Context, id int) error
}
type Feed struct {
ID int `json:"id"`
Name string `json:"name"`
Indexer string `json:"indexer"`
Type string `json:"type"`
Enabled bool `json:"enabled"`
URL string `json:"url"`
Interval int `json:"interval"`
Capabilities []string `json:"capabilities"`
ApiKey string `json:"api_key"`
Settings map[string]string `json:"settings"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
IndexerID int `json:"-"`
Indexerr FeedIndexer `json:"-"`
}
type FeedIndexer struct {
ID int `json:"id"`
Name string `json:"name"`
Identifier string `json:"identifier"`
}
type FeedType string
const (
FeedTypeTorznab FeedType = "TORZNAB"
)

View file

@ -15,29 +15,31 @@ type IndexerRepo interface {
}
type Indexer struct {
ID int64 `json:"id"`
Name string `json:"name"`
Identifier string `json:"identifier"`
Enabled bool `json:"enabled"`
Type string `json:"type,omitempty"`
Settings map[string]string `json:"settings,omitempty"`
ID int64 `json:"id"`
Name string `json:"name"`
Identifier string `json:"identifier"`
Enabled bool `json:"enabled"`
Implementation string `json:"implementation"`
Settings map[string]string `json:"settings,omitempty"`
}
type IndexerDefinition struct {
ID int `json:"id,omitempty"`
Name string `json:"name"`
Identifier string `json:"identifier"`
Enabled bool `json:"enabled,omitempty"`
Description string `json:"description"`
Language string `json:"language"`
Privacy string `json:"privacy"`
Protocol string `json:"protocol"`
URLS []string `json:"urls"`
Supports []string `json:"supports"`
Settings []IndexerSetting `json:"settings"`
SettingsMap map[string]string `json:"-"`
IRC *IndexerIRC `json:"irc"`
Parse IndexerParse `json:"parse"`
ID int `json:"id,omitempty"`
Name string `json:"name"`
Identifier string `json:"identifier"`
Implementation string `json:"implementation"`
Enabled bool `json:"enabled,omitempty"`
Description string `json:"description"`
Language string `json:"language"`
Privacy string `json:"privacy"`
Protocol string `json:"protocol"`
URLS []string `json:"urls"`
Supports []string `json:"supports"`
Settings []IndexerSetting `json:"settings,omitempty"`
SettingsMap map[string]string `json:"-"`
IRC *IndexerIRC `json:"irc,omitempty"`
Torznab *Torznab `json:"torznab,omitempty"`
Parse *IndexerParse `json:"parse,omitempty"`
}
func (i IndexerDefinition) HasApi() bool {
@ -61,6 +63,11 @@ type IndexerSetting struct {
Regex string `json:"regex,omitempty"`
}
type Torznab struct {
MinInterval int `json:"minInterval"`
Settings []IndexerSetting `json:"settings"`
}
type IndexerIRC struct {
Network string `json:"network"`
Server string `json:"server"`

View file

@ -157,6 +157,15 @@ func (r *Release) Parse() error {
return nil
}
func (r *Release) ParseSizeBytesString(size string) {
s, err := humanize.ParseBytes(size)
if err != nil {
// log could not parse into bytes
r.Size = 0
}
r.Size = s
}
func (r *Release) extractYear() error {
if r.Year > 0 {
return nil
@ -1514,7 +1523,8 @@ const (
type ReleaseImplementation string
const (
ReleaseImplementationIRC ReleaseImplementation = "IRC"
ReleaseImplementationIRC ReleaseImplementation = "IRC"
ReleaseImplementationTorznab ReleaseImplementation = "TORZNAB"
)
type ReleaseQueryParams struct {