Skip to content

Commit

Permalink
feat(arrs): add support for including unmonitored titles (#96)
Browse files Browse the repository at this point in the history
* feat(arrs): add support for including unmonitored titles

* fix: revert go import ordering

* fix: remove includeUnmonitored from unsupported in configTemplate
  • Loading branch information
s0up4200 authored Nov 6, 2024
1 parent 3113f8d commit 1f0dbcb
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 47 deletions.
50 changes: 29 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Omegabrr transforms items monitored by arrs or lists into autobrr filters. Useful for automating your filters for monitored media or racing criteria.

## Table of Contents

- [Config](#config)
- [Tags](#tags)
- [Lists](#lists)
Expand Down Expand Up @@ -36,6 +37,7 @@ clients:
filters:
- 15 # Change me
#matchRelease: false / true
#includeUnmonitored: false # Set to true to include unmonitored items

- name: sonarr
type: sonarr
Expand All @@ -50,6 +52,7 @@ clients:
- 14 # Change me
#matchRelease: false / true
#excludeAlternateTitles: false/ true # only works for Sonarr and defaults to false
#includeUnmonitored: false # Set to true to include unmonitored items

- name: lidarr
type: lidarr
Expand Down Expand Up @@ -104,7 +107,7 @@ lists:
url: https://api.autobrr.com/lists/trakt/popular-tv
filters:
- 25 # Change me

- name: StevenLu
type: trakt
url: https://api.autobrr.com/lists/stevenlu
Expand Down Expand Up @@ -133,27 +136,27 @@ lists:
If you're trying to reach radarr or sonarr hosted on swizzin from some other location, you need to do it like this with basic auth:
```yaml
arr:
- name: radarr
type: radarr
host: https://domain.com/radarr
apikey: YOUR_API_KEY
basicAuth:
user: username
pass: password
filters:
- 15 # Change me
arr:
- name: radarr
type: radarr
host: https://domain.com/radarr
apikey: YOUR_API_KEY
basicAuth:
user: username
pass: password
filters:
- 15 # Change me
```
Same goes for autobrr if it's behind basic auth.
```yaml
autobrr:
host: http://localhost:7474
apikey: YOUR_API_KEY
basicAuth:
user: username
pass: password
autobrr:
host: http://localhost:7474
apikey: YOUR_API_KEY
basicAuth:
user: username
pass: password
```
### Tags
Expand Down Expand Up @@ -188,7 +191,7 @@ If you want to exclude certain tags, you can use the `tagsExclude`.

### Lists

Formerly known as regbrr and maintained by community members is now integrated into omegabrr! We now maintain the lists of media.
Formerly known as regbrr and maintained by community members is now integrated into omegabrr! We now maintain the lists of media.

**Trakt**

Expand All @@ -215,6 +218,10 @@ Readarr will only use the `Match releases` field for now, so setting `matchRelea

You can drop alternate show titles from being added by setting `excludeAlternateTitles: true` for Sonarr in your config.

### Include Unmonitored Items

By default, omegabrr only processes monitored items. You can include unmonitored items by setting `includeUnmonitored: true` in your arr configuration. This is particularly useful in cross-seed scenarios where you want to match against all items.

## Plaintext lists specific options

Plaintext lists can be anything, therefore you can optionally set `matchRelease: true` or `album: true` to use these fields in your autobrr filter. If not set, it will use the `Movies / Shows` field.
Expand Down Expand Up @@ -242,6 +249,7 @@ server:
port: 7441
apiToken: MY_NEW_LONG_SECURE_TOKEN
```

Call with `omegabrr generate-token`
If you are using docker `docker exec omegabrr omegabrr generate-token`
Optionally call with `--length <number>`for a custom length.
Expand Down Expand Up @@ -276,7 +284,7 @@ The API Token can be set as either an HTTP header like `X-API-Token`, or be pass

### Docker compose

Check the `docker-compose.yml` example.
Check the `docker-compose.yml` example.

1. Set `user: 1000:1000` with your user id you can get with the `id` command, or remove to run as **root**.
2. Set the `volume` so it matches your system. To run from the same path as the `docker-compose` first create a config dir like `mkdir config`, and place this `./config:/config` in the compose file. This will create a default config on the first run.
Expand All @@ -287,13 +295,13 @@ If you have custom networks then make sure to add those, so it can communicate w

For users who prioritize container security, we offer alternative Docker images built on [Distroless](https://github.com/GoogleContainerTools/distroless). Specifically the `distroless/static-debian12:nonroot` base image.

Distroless images do not contain a package manager or shell, thereby reducing the potential attack surface and making them a more secure option. These stripped-back images contain only the application and its runtime dependencies.
Distroless images do not contain a package manager or shell, thereby reducing the potential attack surface and making them a more secure option. These stripped-back images contain only the application and its runtime dependencies.

### Systemd

On Linux-based systems it is recommended to run omegabrr as a systemd service.

Download the [latest binary](https://github.com/autobrr/omegabrr/releases/latest) for your system and place it in `/usr/local/bin`.
Download the [latest binary](https://github.com/autobrr/omegabrr/releases/latest) for your system and place it in `/usr/local/bin`.

Example: Download binary

Expand Down
4 changes: 4 additions & 0 deletions internal/domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type ArrConfig struct {
TagsExclude []string `koanf:"tagsExclude"`
MatchRelease bool `koanf:"matchRelease"`
ExcludeAlternateTitles bool `koanf:"excludeAlternateTitles"`
IncludeUnmonitored bool `koanf:"includeUnmonitored"`
}

type ArrType string
Expand Down Expand Up @@ -234,20 +235,23 @@ clients:
# apikey: API_KEY
# filters:
# - 15 # Change me
# includeUnmonitored: false # Set to true to include unmonitored items
#- name: radarr4k
# type: radarr
# host: http://localhost:7878
# apikey: API_KEY
# filters:
# - 16 # Change me
# includeUnmonitored: false # Set to true to include unmonitored items
#- name: sonarr
# type: sonarr
# host: http://localhost:8989
# apikey: API_KEY
# filters:
# - 14 # Change me
# includeUnmonitored: false # Set to true to include unmonitored items
# #excludeAlternateTitles: true # defaults to false
#- name: readarr
Expand Down
12 changes: 5 additions & 7 deletions internal/processor/radarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/autobrr/omegabrr/internal/domain"
"github.com/autobrr/omegabrr/pkg/autobrr"
"github.com/pkg/errors"

"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golift.io/starr"
Expand Down Expand Up @@ -91,13 +91,12 @@ func (s Service) processRadarr(ctx context.Context, cfg *domain.ArrConfig, logge
logger.Debug().Msgf("found %d movies to process", len(movies))

titleSet := make(map[string]struct{})
var monitoredTitles int
var processedTitles int

for _, movie := range movies {
m := movie

// only want monitored
if !m.Monitored {
if !s.shouldProcessItem(m.Monitored, cfg) {
continue
}

Expand All @@ -116,8 +115,7 @@ func (s Service) processRadarr(ctx context.Context, cfg *domain.ArrConfig, logge
}
}

// increment monitored titles
monitoredTitles++
processedTitles++

// Taking the international title and the original title and appending them to the titles array.
for _, title := range []string{m.Title, m.OriginalTitle} {
Expand All @@ -135,7 +133,7 @@ func (s Service) processRadarr(ctx context.Context, cfg *domain.ArrConfig, logge
}

sort.Strings(uniqueTitles)
logger.Debug().Msgf("from a total of %d movies we found %d monitored and created %d release titles", len(movies), monitoredTitles, len(uniqueTitles))
logger.Debug().Msgf("from a total of %d movies we found %d titles and created %d release titles", len(movies), processedTitles, len(uniqueTitles))

return uniqueTitles, nil
}
11 changes: 8 additions & 3 deletions internal/processor/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ func (s Service) newAutobrrClient() *autobrr.Client {
return a
}

// shouldProcessItem determines if an item should be processed based on its monitored status and configuration
func (s Service) shouldProcessItem(monitored bool, arrConfig *domain.ArrConfig) bool {
if arrConfig.IncludeUnmonitored {
return true
}
return monitored
}

func (s Service) ProcessArrs(ctx context.Context, dryRun bool) []string {
var processingErrors []string

Expand Down Expand Up @@ -91,7 +99,6 @@ func (s Service) ProcessArrs(ctx context.Context, dryRun bool) []string {
}

return processingErrors

}

func (s Service) ProcessLists(ctx context.Context, dryRun bool) []string {
Expand Down Expand Up @@ -133,13 +140,11 @@ func (s Service) ProcessLists(ctx context.Context, dryRun bool) []string {
log.Error().Err(err).Str("type", "steam").Str("client", listsClient.Name).Msg("error while processing Steam wishlist, continuing with other lists")
processingErrors = append(processingErrors, fmt.Sprintf("Steam - %s: %v", listsClient.Name, err))
}

}
}
}

return processingErrors

}

func (s Service) GetFilters(ctx context.Context) ([]autobrr.Filter, error) {
Expand Down
17 changes: 17 additions & 0 deletions internal/processor/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package processor

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/autobrr/omegabrr/internal/domain"
)

func TestService_shouldProcessItem(t *testing.T) {
s := &Service{}
cfg := &domain.ArrConfig{
IncludeUnmonitored: true,
}
assert.True(t, s.shouldProcessItem(false, cfg), "unmonitored items should be processed when includeUnmonitored is true")
}
27 changes: 11 additions & 16 deletions internal/processor/sonarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/autobrr/omegabrr/internal/domain"
"github.com/autobrr/omegabrr/pkg/autobrr"
"github.com/pkg/errors"

"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golift.io/starr"
Expand Down Expand Up @@ -98,44 +98,39 @@ func (s Service) processSonarr(ctx context.Context, cfg *domain.ArrConfig, logge
logger.Debug().Msgf("found %d shows to process", len(shows))

titleSet := make(map[string]struct{})
var monitoredTitles int
var processedTitles int

for _, show := range shows {
s := show
series := show

// only want monitored
if !s.Monitored {
if !s.shouldProcessItem(series.Monitored, cfg) {
continue
}

if len(cfg.TagsInclude) > 0 {
if len(s.Tags) == 0 {
if len(series.Tags) == 0 {
continue
}
if !containsTag(tags, s.Tags, cfg.TagsInclude) {
if !containsTag(tags, series.Tags, cfg.TagsInclude) {
continue
}
}

if len(cfg.TagsExclude) > 0 {
if containsTag(tags, s.Tags, cfg.TagsExclude) {
if containsTag(tags, series.Tags, cfg.TagsExclude) {
continue
}
}

// increment monitored titles
monitoredTitles++

//titles = append(titles, rls.MustNormalize(s.Title))
//titles = append(titles, rls.MustClean(s.Title))
processedTitles++

titles := processTitle(s.Title, cfg.MatchRelease)
titles := processTitle(series.Title, cfg.MatchRelease)
for _, title := range titles {
titleSet[title] = struct{}{}
}

if !cfg.ExcludeAlternateTitles {
for _, title := range s.AlternateTitles {
for _, title := range series.AlternateTitles {
altTitles := processTitle(title.Title, cfg.MatchRelease)
for _, altTitle := range altTitles {
titleSet[altTitle] = struct{}{}
Expand All @@ -150,7 +145,7 @@ func (s Service) processSonarr(ctx context.Context, cfg *domain.ArrConfig, logge
}

sort.Strings(uniqueTitles)
logger.Debug().Msgf("from a total of %d shows we found %d monitored and created %d release titles", len(shows), monitoredTitles, len(uniqueTitles))
logger.Debug().Msgf("from a total of %d shows we found %d titles and created %d release titles", len(shows), processedTitles, len(uniqueTitles))

return uniqueTitles, nil
}

0 comments on commit 1f0dbcb

Please sign in to comment.