unpackerr

package
v0.10.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2022 License: MIT Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Sonarr       = "Sonarr"
	Radarr       = "Radarr"
	Lidarr       = "Lidarr"
	Readarr      = "Readarr"
	FolderString = "Folder"
)

These are the names used to identify each app.

View Source
const (
	WAITING = ExtractStatus(iota)
	QUEUED
	EXTRACTING
	EXTRACTFAILED
	EXTRACTED
	IMPORTED
	DELETING
	DELETEFAILED // unused
	DELETED
)

Extract Statuses.

View Source
const DefaultQueuePageSize = 2000

DefaultQueuePageSize is how many items we request from Lidarr and Readarr. Once we have better support for Sonarr/Radarr v3 this will apply to those as well. If you have more than this many items queued.. oof. As the queue goes away, more things should get picked up.

View Source
const WebhookTemplateDiscord = `` /* 1736-byte string literal not displayed */

WebhookTemplateDiscord is used when sending a webhook to discord.com.

View Source
const WebhookTemplateGotify = `` /* 858-byte string literal not displayed */

The extra spaces before the newlines here are required to make this look good on web and on android.

View Source
const WebhookTemplateNotifiarr = `` /* 871-byte string literal not displayed */

WebhookTemplateNotifiarr is the default template when not using discord.com (below), or a custom template file.

View Source
const WebhookTemplatePushover = `token={{token}}&user={{channel}}&html=1&title={{formencode .Event.Desc}}&` +
	`{{if nickname}}device={{nickname}}&{{end}}message=<pre><b>App</b>: {{.App}}
<b>Name</b>: {{formencode (index .IDs "title")}}
<b>Path</b>: {{formencode .Path}}
{{ if .Data -}}
{{ if .Data.Elapsed.Duration}}<b>Time</b>: {{.Data.Elapsed}}
{{end}}{{ if .Data.Archives}}<b>RARs</b>: {{len .Data.Archives}}
{{end}}{{ if .Data.Files}}<b>Files</b>: {{len .Data.Files}}
{{end}}{{ if .Data.Bytes}}<b>Bytes</b>: {{humanbytes .Data.Bytes}}
{{end}}{{ if and (gt .Event 1) (lt .Event 5)}}<b>Queue</b>: {{.Data.Queue}}
{{end}}{{ if .Data.Error}}
<font color="#FF0000"><b>ERROR</b>: {{formencode .Data.Error}}</font>
{{end}}{{end -}}</pre>`
View Source
const WebhookTemplateSlack = `` /* 1871-byte string literal not displayed */

WebhookTemplateSlack is a built-in template for sending a message to Slack.

View Source
const WebhookTemplateTelegram = `` /* 821-byte string literal not displayed */

Variables

View Source
var (
	ErrInvalidURL = fmt.Errorf("provided application URL is invalid")
	ErrInvalidKey = fmt.Errorf("provided application API Key is invalid, must be 32 characters")
)

Application validation errors.

View Source
var (
	ErrInvalidStatus = fmt.Errorf("invalid HTTP status reply")
	ErrWebhookNoURL  = fmt.Errorf("webhook without a URL configured; fix it")
)

Errors produced by this file.

View Source
var (
	ErrCmdhookNoCmd = fmt.Errorf("cmdhook without a command configured; fix it")
)

Errors produced by this file.

Functions

func Start

func Start() (err error)

Start runs the app.

Types

type Config

type Config struct {
	Debug       bool             `json:"debug" toml:"debug" xml:"debug" yaml:"debug"`
	Quiet       bool             `json:"quiet" toml:"quiet" xml:"quiet" yaml:"quiet"`
	Activity    bool             `json:"activity" toml:"activity" xml:"activity" yaml:"activity"`
	Parallel    uint             `json:"parallel" toml:"parallel" xml:"parallel" yaml:"parallel"`
	LogFile     string           `json:"logFile" toml:"log_file" xml:"log_file" yaml:"logFile"`
	LogFiles    int              `json:"logFiles" toml:"log_files" xml:"log_files" yaml:"logFiles"`
	LogFileMb   int              `json:"logFileMb" toml:"log_file_mb" xml:"log_file_mb" yaml:"logFileMb"`
	MaxRetries  uint             `json:"maxRetries" toml:"max_retries" xml:"max_retries" yaml:"maxRetries"`
	FileMode    string           `json:"fileMode" toml:"file_mode" xml:"file_mode" yaml:"fileMode"`
	DirMode     string           `json:"dirMode" toml:"dir_mode" xml:"dir_mode" yaml:"dirMode"`
	LogQueues   cnfg.Duration    `json:"logQueues" toml:"log_queues" xml:"log_queues" yaml:"logQueues"`
	Interval    cnfg.Duration    `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
	Timeout     cnfg.Duration    `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
	DeleteDelay cnfg.Duration    `json:"deleteDelay" toml:"delete_delay" xml:"delete_delay" yaml:"deleteDelay"`
	StartDelay  cnfg.Duration    `json:"startDelay" toml:"start_delay" xml:"start_delay" yaml:"startDelay"`
	RetryDelay  cnfg.Duration    `json:"retryDelay" toml:"retry_delay" xml:"retry_delay" yaml:"retryDelay"`
	Buffer      uint             `json:"buffer" toml:"buffer" xml:"buffer" yaml:"buffer"`                       //nolint:lll // undocumented.
	KeepHistory uint             `json:"keepHistory" toml:"keep_history" xml:"keep_history" yaml:"keepHistory"` //nolint:lll // undocumented.
	Passwords   []string         `json:"passwords" toml:"passwords" xml:"password" yaml:"passwords"`
	Lidarr      []*LidarrConfig  `json:"lidarr,omitempty" toml:"lidarr" xml:"lidarr" yaml:"lidarr,omitempty"`
	Radarr      []*RadarrConfig  `json:"radarr,omitempty" toml:"radarr" xml:"radarr" yaml:"radarr,omitempty"`
	Readarr     []*ReadarrConfig `json:"readarr,omitempty" toml:"readarr" xml:"readarr" yaml:"readarr,omitempty"`
	Sonarr      []*SonarrConfig  `json:"sonarr,omitempty" toml:"sonarr" xml:"sonarr" yaml:"sonarr,omitempty"`
	Folders     []*FolderConfig  `json:"folder,omitempty" toml:"folder" xml:"folder" yaml:"folder,omitempty"`
	Webhook     []*WebhookConfig `json:"webhook,omitempty" toml:"webhook" xml:"webhook" yaml:"webhook,omitempty"`
	Cmdhook     []*WebhookConfig `json:"cmdhook,omitempty" toml:"cmdhook" xml:"cmdhook" yaml:"cmdhook,omitempty"`
	Folder      struct {
		Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` // undocumented.
	} `json:"folders,omitempty" toml:"folders" xml:"folders" yaml:"folders,omitempty"` // undocumented.
}

Config defines the configuration data used to start the application.

type Extract

type Extract struct {
	Retries     uint
	Path        string
	App         string
	Updated     time.Time
	DeleteDelay time.Duration
	DeleteOrig  bool
	Status      ExtractStatus
	IDs         map[string]interface{}
	Resp        *xtractr.Response
}

Extract holds data for files being extracted.

type ExtractStatus

type ExtractStatus uint8

ExtractStatus is our enum for an extract's status.

func (ExtractStatus) Desc

func (status ExtractStatus) Desc() string

Desc makes ExtractStatus human readable.

func (ExtractStatus) MarshalText

func (status ExtractStatus) MarshalText() ([]byte, error)

MarshalText turns a status into a word, for a json identifier.

func (ExtractStatus) String

func (status ExtractStatus) String() string

String turns a status into a short string.

func (*ExtractStatus) UnmarshalENV added in v0.10.1

func (status *ExtractStatus) UnmarshalENV(tag, envval string) error

UnmarshalENV turns environment variables into extraction statuses.

type Flags

type Flags struct {
	ConfigFile string
	EnvPrefix  string
	// contains filtered or unexported fields
}

Flags are our CLI input flags.

type Folder

type Folder struct {
	// contains filtered or unexported fields
}

Folder is a "new" watched folder.

type FolderConfig

type FolderConfig struct {
	DeleteOrig  bool          `json:"delete_original" toml:"delete_original" xml:"delete_original" yaml:"delete_original"`
	DeleteFiles bool          `json:"delete_files" toml:"delete_files" xml:"delete_files" yaml:"delete_files"`
	DisableLog  bool          `json:"disable_log" toml:"disable_log" xml:"disable_log" yaml:"disable_log"`
	MoveBack    bool          `json:"move_back" toml:"move_back" xml:"move_back" yaml:"move_back"`
	DeleteAfter cnfg.Duration `json:"delete_after" toml:"delete_after" xml:"delete_after" yaml:"delete_after"`
	ExtractPath string        `json:"extract_path" toml:"extract_path" xml:"extract_path" yaml:"extract_path"`
	Path        string        `json:"path" toml:"path" xml:"path" yaml:"path"`
}

FolderConfig defines the input data for a watched folder.

type Folders

type Folders struct {
	Interval time.Duration
	Config   []*FolderConfig
	Folders  map[string]*Folder
	Events   chan *eventData
	Updates  chan *xtractr.Response
	Printf   func(msg string, v ...interface{})
	Debugf   func(msg string, v ...interface{})
	FSNotify *fsnotify.Watcher
	Watcher  *watcher.Watcher
}

Folders holds all known (created) folders in all watch paths.

func (*Folders) Add added in v0.9.0

func (f *Folders) Add(folder string) error

Add uses either fsnotify or watcher.

func (*Folders) Remove added in v0.9.0

func (f *Folders) Remove(folder string)

Remove uses either fsnotify or watcher.

type History

type History struct {
	Items    []string
	Finished uint
	Retries  uint
	Map      map[string]*Extract
}

History holds the history of extracted items.

type LidarrConfig

type LidarrConfig struct {
	starr.Config
	Path           string        `json:"path" toml:"path" xml:"path" yaml:"path"`
	Paths          []string      `json:"paths" toml:"paths" xml:"paths" yaml:"paths"`
	Protocols      string        `json:"protocols" toml:"protocols" xml:"protocols" yaml:"protocols"`
	DeleteOrig     bool          `json:"delete_orig" toml:"delete_orig" xml:"delete_orig" yaml:"delete_orig"`
	DeleteDelay    cnfg.Duration `json:"delete_delay" toml:"delete_delay" xml:"delete_delay" yaml:"delete_delay"`
	Queue          *lidarr.Queue `json:"-" toml:"-" xml:"-" yaml:"-"`
	*lidarr.Lidarr `json:"-" toml:"-" xml:"-" yaml:"-"`
	sync.RWMutex   `json:"-" toml:"-" xml:"-" yaml:"-"`
}

LidarrConfig represents the input data for a Lidarr server.

type Logger

type Logger struct {
	Logger *log.Logger
	// contains filtered or unexported fields
}

Logger provides a struct we can pass into other packages.

func (*Logger) Debugf

func (l *Logger) Debugf(msg string, v ...interface{})

Debugf writes Debug log lines... to stdout and/or a file.

func (*Logger) Print

func (l *Logger) Print(v ...interface{})

Print writes log lines... to stdout and/or a file.

func (*Logger) Printf

func (l *Logger) Printf(msg string, v ...interface{})

Printf writes log lines... to stdout and/or a file.

type RadarrConfig

type RadarrConfig struct {
	starr.Config
	Path           string        `json:"path" toml:"path" xml:"path" yaml:"path"`
	Paths          []string      `json:"paths" toml:"paths" xml:"paths" yaml:"paths"`
	Protocols      string        `json:"protocols" toml:"protocols" xml:"protocols" yaml:"protocols"`
	DeleteOrig     bool          `json:"delete_orig" toml:"delete_orig" xml:"delete_orig" yaml:"delete_orig"`
	DeleteDelay    cnfg.Duration `json:"delete_delay" toml:"delete_delay" xml:"delete_delay" yaml:"delete_delay"`
	Queue          *radarr.Queue `json:"-" toml:"-" xml:"-" yaml:"-"`
	sync.RWMutex   `json:"-" toml:"-" xml:"-" yaml:"-"`
	*radarr.Radarr `json:"-" toml:"-" xml:"-" yaml:"-"`
}

RadarrConfig represents the input data for a Radarr server.

type ReadarrConfig

type ReadarrConfig struct {
	starr.Config
	Path             string         `json:"path" toml:"path" xml:"path" yaml:"path"`
	Paths            []string       `json:"paths" toml:"paths" xml:"paths" yaml:"paths"`
	Protocols        string         `json:"protocols" toml:"protocols" xml:"protocols" yaml:"protocols"`
	DeleteOrig       bool           `json:"delete_orig" toml:"delete_orig" xml:"delete_orig" yaml:"delete_orig"`
	DeleteDelay      cnfg.Duration  `json:"delete_delay" toml:"delete_delay" xml:"delete_delay" yaml:"delete_delay"`
	Queue            *readarr.Queue `json:"-" toml:"-" xml:"-" yaml:"-"`
	sync.RWMutex     `json:"-" toml:"-" xml:"-" yaml:"-"`
	*readarr.Readarr `json:"-" toml:"-" xml:"-" yaml:"-"`
}

ReadarrConfig represents the input data for a Readarr server.

type SonarrConfig

type SonarrConfig struct {
	starr.Config
	Path           string        `json:"path" toml:"path" xml:"path" yaml:"path"`
	Paths          []string      `json:"paths" toml:"paths" xml:"paths" yaml:"paths"`
	Protocols      string        `json:"protocols" toml:"protocols" xml:"protocols" yaml:"protocols"`
	DeleteOrig     bool          `json:"delete_orig" toml:"delete_orig" xml:"delete_orig" yaml:"delete_orig"`
	DeleteDelay    cnfg.Duration `json:"delete_delay" toml:"delete_delay" xml:"delete_delay" yaml:"delete_delay"`
	Queue          *sonarr.Queue `json:"-" toml:"-" xml:"-" yaml:"-"`
	sync.RWMutex   `json:"-" toml:"-" xml:"-" yaml:"-"`
	*sonarr.Sonarr `json:"-" toml:"-" xml:"-" yaml:"-"`
}

SonarrConfig represents the input data for a Sonarr server.

type Unpackerr

type Unpackerr struct {
	*Flags
	*Config
	*History
	*xtractr.Xtractr

	*Logger
	// contains filtered or unexported fields
}

Unpackerr stores all the running data.

func New

func New() *Unpackerr

New returns an UnpackerPoller struct full of defaults. An empty struct will surely cause you pain, so use this!

func (*Unpackerr) CmdhookCounts added in v0.9.9

func (u *Unpackerr) CmdhookCounts() (total uint, fails uint)

CmdhookCounts returns the total count of requests and errors for all webhooks.

func (*Unpackerr) ParseFlags

func (u *Unpackerr) ParseFlags() *Unpackerr

ParseFlags turns CLI args into usable data.

func (*Unpackerr) PollFolders

func (u *Unpackerr) PollFolders()

PollFolders begins the routines to watch folders for changes. if those changes include the addition of compressed files, they are processed for exctraction.

func (*Unpackerr) Run

func (u *Unpackerr) Run()

Run starts the loop that does the work.

func (*Unpackerr) WebhookCounts

func (u *Unpackerr) WebhookCounts() (total uint, fails uint)

WebhookCounts returns the total count of requests and errors for all webhooks.

type WebhookConfig

type WebhookConfig struct {
	Name      string          `json:"name" toml:"name" xml:"name" yaml:"name"`
	URL       string          `json:"url" toml:"url" xml:"url,omitempty" yaml:"url"`
	Command   string          `json:"command" toml:"command" xml:"command,omitempty" yaml:"command"`
	CType     string          `json:"contentType" toml:"content_type" xml:"content_type,omitempty" yaml:"contentType"`
	TmplPath  string          `json:"templatePath" toml:"template_path" xml:"template_path,omitempty" yaml:"templatePath"`
	TempName  string          `json:"template" toml:"template" xml:"template,omitempty" yaml:"template"`
	Timeout   cnfg.Duration   `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
	Shell     bool            `json:"shell" toml:"shell" xml:"shell" yaml:"shell"`
	IgnoreSSL bool            `json:"ignoreSsl" toml:"ignore_ssl" xml:"ignore_ssl,omitempty" yaml:"ignoreSsl"`
	Silent    bool            `json:"silent" toml:"silent" xml:"silent" yaml:"silent"`
	Events    []ExtractStatus `json:"events" toml:"events" xml:"events" yaml:"events"`
	Exclude   []string        `json:"exclude" toml:"exclude" xml:"exclude" yaml:"exclude"`
	Nickname  string          `json:"nickname" toml:"nickname" xml:"nickname,omitempty" yaml:"nickname"`
	Token     string          `json:"token" toml:"token" xml:"token,omitempty" yaml:"token"`
	Channel   string          `json:"channel" toml:"channel" xml:"channel,omitempty" yaml:"channel"`

	sync.Mutex `json:"-" toml:"-" xml:"-" yaml:"-"`
	// contains filtered or unexported fields
}

WebhookConfig defines the data to send webhooks to a server.

func (*WebhookConfig) Counts

func (w *WebhookConfig) Counts() (uint, uint)

Counts returns the total count of requests and failures for a webhook.

func (*WebhookConfig) Excluded

func (w *WebhookConfig) Excluded(app string) bool

Excluded returns true if an app is in the Exclude slice.

func (*WebhookConfig) HasEvent

func (w *WebhookConfig) HasEvent(e ExtractStatus) bool

HasEvent returns true if a status event is in the Events slice. Also returns true if the Events slice has only one value of WAITING.

func (*WebhookConfig) Send

func (w *WebhookConfig) Send(body io.Reader) ([]byte, error)

Send marshals an interface{} into json and POSTs it to a URL.

func (*WebhookConfig) Template added in v0.9.0

func (w *WebhookConfig) Template() (*template.Template, error)

Template returns a template specific to this webhook.

type WebhookPayload

type WebhookPayload struct {
	Path   string                 `json:"path"`                // Path for the extracted item.
	App    string                 `json:"app"`                 // Application Triggering Event
	IDs    map[string]interface{} `json:"ids,omitempty"`       // Arbitrary IDs from each app.
	Event  ExtractStatus          `json:"unpackerr_eventtype"` // The type of the event.
	Time   time.Time              `json:"time"`                // Time of this event.
	Data   *XtractPayload         `json:"data,omitempty"`      // Payload from extraction process.
	Config *WebhookConfig         `json:"-"`                   // Payload from extraction process.
	// Application Metadata.
	Go       string    `json:"go"`       // Version of go compiled with
	OS       string    `json:"os"`       // Operating system: linux, windows, darwin
	Arch     string    `json:"arch"`     // Architecture: amd64, armhf
	Version  string    `json:"version"`  // Application Version
	Revision string    `json:"revision"` // Application Revision
	Branch   string    `json:"branch"`   // Branch built from.
	Started  time.Time `json:"started"`  // App start time.
}

WebhookPayload defines the data sent to notifarr.com (and other) webhooks.

type XtractPayload

type XtractPayload struct {
	Error    string        `json:"error,omitempty"`    // error only during extractfailed
	Archives []string      `json:"archives,omitempty"` // list of all archive files extracted
	Files    []string      `json:"files,omitempty"`    // list of all files extracted
	Start    time.Time     `json:"start,omitempty"`    // start time of extraction
	Output   string        `json:"output,omitempty"`   // temporary items folder
	Bytes    int64         `json:"bytes,omitempty"`    // Bytes written
	Elapsed  cnfg.Duration `json:"elapsed,omitempty"`  // Duration as a string: 5m32s
	Queue    int           `json:"queue,omitempty"`    // Extraction Queue Size
}

XtractPayload is a rewrite of xtractr.Response.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL