Skip to content

Commit

Permalink
feat: add radarr -cutoff tag to search for cutoff unmet movies (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
jolbol1 authored Apr 13, 2022
1 parent 2c338cd commit 6746c0e
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 11 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ missarr sends search requests for missing episodes to Sonarr

missarr offers [pre-compiled binaries](https://github.com/l3uddz/missarr/releases/latest) for Linux, macOS and Windows for each official release.

Example install (installing to /opt/missarr on linux amd64):
````
cd /opt
mkdir missarr && cd missarr
curl -fLvo missarr https://github.com/jolbol1/missarr/releases/download/v1.2.0/missarr_v1.2.0_linux_amd64
chmod +x missarr
````

Alternatively, you can build the Missarr binary yourself.
To build missarr on your system, make sure:

Expand Down Expand Up @@ -59,6 +67,9 @@ Search for 10 movies: `missarr radarr --limit 10`

Search for 10 movies (without updating movies cache) `missarr radarr --limit 10 --skip-refresh`

Search for 10 movies with cutoff unmet: `missarr radarr --limit 10 --cutoff`


## Donate

If you find this project helpful, feel free to make a small donation:
Expand All @@ -69,4 +80,4 @@ If you find this project helpful, feel free to make a small donation:

- [GitHub Sponsor](https://github.com/sponsors/l3uddz): GitHub matches contributions for first 12 months.

- BTC: 3CiHME1HZQsNNcDL6BArG7PbZLa8zUUgjL
- BTC: 3CiHME1HZQsNNcDL6BArG7PbZLa8zUUgjL
3 changes: 2 additions & 1 deletion cmd/missarr/radarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type RadarrCmd struct {
LastReleaseDate time.Duration `default:"72h" help:"How long before an item can be considered missing based on release date"`
SkipRefresh bool `default:"false" help:"Retrieve current missing from radarr"`
Delay time.Duration `default:"0s" help:"Delay between search requests"`
Cutoff bool `default:"false" help:"Search Cutoff Unmet Items"`
}

func (r *RadarrCmd) Run(c *config, db *sql.DB, mg *migrate.Migrator) error {
Expand Down Expand Up @@ -44,7 +45,7 @@ func (r *RadarrCmd) Run(c *config, db *sql.DB, mg *migrate.Migrator) error {
Msg("Retrieved movies")

// refresh datastore
us, rs, fm, err = sc.RefreshStore(rm, time.Now().Add(-r.LastReleaseDate))
us, rs, fm, err = sc.RefreshStore(rm, time.Now().Add(-r.LastReleaseDate), r.Cutoff)
if err != nil {
return fmt.Errorf("missing to store: %w", err)
}
Expand Down
5 changes: 5 additions & 0 deletions radarr/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func (c *Client) getSystemStatus() (*systemStatus, error) {
return b, nil
}

type MovieFile struct {
QualityCutoffNotMet bool
}

type MovieResponse struct {
SizeOnDisk int `json:"sizeOnDisk"`
Status string `json:"status"`
Expand All @@ -45,6 +49,7 @@ type MovieResponse struct {
IsAvailable bool `json:"isAvailable"`
Added time.Time `json:"added"`
Id int `json:"id"`
MovieFile MovieFile `json:"movieFile"`
}

func (c *Client) Movies() ([]MovieResponse, error) {
Expand Down
15 changes: 8 additions & 7 deletions radarr/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func newDatastore(db *sql.DB, mg *migrate.Migrator) (*datastore, error) {
}

const sqlUpsert = `
INSERT INTO movies (movie, release_date, search_date)
VALUES (?, ?, ?)
INSERT INTO movies (movie, release_date, search_date, type)
VALUES (?, ?, ?, ?)
ON CONFLICT (movie) DO UPDATE SET
release_date = excluded.release_date
, search_date = CASE
Expand All @@ -40,15 +40,16 @@ ON CONFLICT (movie) DO UPDATE SET
END
`

func (store *datastore) upsert(tx *sql.Tx, movie int, releaseDate time.Time, searchDate *time.Time) error {
_, err := tx.Exec(sqlUpsert, movie, releaseDate, searchDate)
func (store *datastore) upsert(tx *sql.Tx, movie int, releaseDate time.Time, searchDate *time.Time, missingType string) error {
_, err := tx.Exec(sqlUpsert, movie, releaseDate, searchDate, missingType)
return err
}

type Movie struct {
Id int
ReleaseDate time.Time
SearchDate *time.Time
Type string
}

func (store *datastore) Upsert(movies []Movie) error {
Expand All @@ -58,7 +59,7 @@ func (store *datastore) Upsert(movies []Movie) error {
}

for _, m := range movies {
if err = store.upsert(tx, m.Id, m.ReleaseDate, m.SearchDate); err != nil {
if err = store.upsert(tx, m.Id, m.ReleaseDate, m.SearchDate, m.Type); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
panic(rollbackErr)
}
Expand All @@ -71,7 +72,7 @@ func (store *datastore) Upsert(movies []Movie) error {
}

const sqlGetAll = `
SELECT movie, release_date, search_date
SELECT movie, release_date, search_date, type
FROM movies
ORDER BY release_date DESC
`
Expand All @@ -85,7 +86,7 @@ func (store *datastore) GetAll() (movies []Movie, err error) {
defer rows.Close()
for rows.Next() {
movie := Movie{}
err = rows.Scan(&movie.Id, &movie.ReleaseDate, &movie.SearchDate)
err = rows.Scan(&movie.Id, &movie.ReleaseDate, &movie.SearchDate, &movie.Type)
if err != nil {
return movies, err
}
Expand Down
16 changes: 14 additions & 2 deletions radarr/ds.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ func (c *Client) GetAll() ([]Movie, error) {
return c.store.GetAll()
}

func (c *Client) RefreshStore(data []MovieResponse, maxReleaseDate time.Time) (int, int, []Movie, error) {
func (c *Client) RefreshStore(data []MovieResponse, maxReleaseDate time.Time, cutoff bool) (int, int, []Movie, error) {
// filter movies
movies := make([]Movie, 0)
sm := make(map[int]int)
missingType := "missing"
if cutoff {
missingType = "cutoff"
}

for _, m := range data {
// skip if movie matches conditions
Expand All @@ -25,7 +29,11 @@ func (c *Client) RefreshStore(data []MovieResponse, maxReleaseDate time.Time) (i
continue
case !m.IsAvailable:
continue
case m.HasFile, m.SizeOnDisk > 0:
case m.HasFile && !cutoff, m.SizeOnDisk > 0 && !cutoff:
continue
case cutoff && m.HasFile && !m.MovieFile.QualityCutoffNotMet:
continue
case cutoff && !m.HasFile:
continue
}

Expand All @@ -49,6 +57,7 @@ func (c *Client) RefreshStore(data []MovieResponse, maxReleaseDate time.Time) (i
Id: m.Id,
ReleaseDate: releaseDate,
SearchDate: nil,
Type: missingType,
})
}

Expand All @@ -69,6 +78,9 @@ func (c *Client) RefreshStore(data []MovieResponse, maxReleaseDate time.Time) (i
moviesToRemove := make([]Movie, 0)
finalMovies := make([]Movie, 0)
for _, m := range em {
if m.Type != missingType {
continue
}
if _, ok := sm[m.Id]; !ok {
moviesToRemove = append(moviesToRemove, m)
continue
Expand Down
1 change: 1 addition & 0 deletions radarr/migrations/1_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ CREATE TABLE IF NOT EXISTS movies (
"movie" INTEGER NOT NULL,
"release_date" DATETIME NOT NULL,
"search_date" DATETIME NULL,
"type" VARCHAR(10),
PRIMARY KEY(movie)
)
1 change: 1 addition & 0 deletions radarr/migrations/2_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE movies ADD [type] VARCHAR(10) NOT NULL DEFAULT 'missing'

0 comments on commit 6746c0e

Please sign in to comment.