diff --git a/README.md b/README.md index 8810e07..655e089 100644 --- a/README.md +++ b/README.md @@ -9,38 +9,24 @@ The easiest way to try this code is using docker: ```bash docker run \ -e SONARR_API_KEY=YOUR_API_KEY \ - -e SONARR_QUALITY_PROFILE_ID=6 \ -e RADARR_API_KEY=YOUR_API_KEY \ - -e RADARR_QUALITY_PROFILE_ID=6 \ -e PLEX_WATCHLIST_URL_1=YOUR_PLEX_WATCHLIST_URL \ nylonee/watchlistarr ``` -| Key | Example Value | Optional | Description | -|---------------------------|----------------------------------|----------|-----------------------------------------------------------------| -| REFRESH_INTERVAL_SECONDS | 60 | Yes | Number of seconds to wait in between checking the watchlist | -| SONARR_API_KEY | 7a392fb4817a46e59f2e84e7d5f021bc | No | API key for Sonarr, found in your Sonarr UI -> General settings | -| SONARR_BASE_URL | http://localhost:8989 | Yes | Base URL for Sonarr, including the 'http' and port | -| SONARR_QUALITY_PROFILE_ID | 6 | No | Quality profile ID for Sonarr | -| SONARR_ROOT_FOLDER | /data/ | Yes | Root folder for Sonarr | -| RADARR_API_KEY | 7a392fb4817a46e59f2e84e7d5f021bc | No | API key for Radarr, found in your Radarr UI -> General settings | -| RADARR_BASE_URL | http://127.0.0.1:7878 | Yes | Base URL for Radarr, including the 'http' and port | -| RADARR_QUALITY_PROFILE_ID | 6 | No | Quality profile ID for Radarr | -| RADARR_ROOT_FOLDER | /data/ | Yes | Root folder for Radarr | -| PLEX_WATCHLIST_URL_1 | https://rss.plex.tv/UUID | No | First Plex Watchlist URL | -| PLEX_WATCHLIST_URL_2 | https://rss.plex.tv/UUID | Yes | Second Plex Watchlist URL (if applicable) | - -### Getting your Quality Profile IDs - -Eventually I will make this easier to get, but for now: - -1. Go to your Sonarr/Radarr UI -2. Go to Settings -> Profiles -3. Open the profile you want to find the ID for -4. Right-click your browser and click "Inspect" -5. On the screen that shows up, navigate to the "Network" tab -6. On the Sonarr/Radarr UI, click "Save" on the profile card -7. A new entry will show up on the network tab, with a number. This number is your Quality Profile ID +| Key | Example Value | Optional | Description | +|--------------------------|----------------------------------|----------|--------------------------------------------------------------------------| +| REFRESH_INTERVAL_SECONDS | 60 | Yes | Number of seconds to wait in between checking the watchlist | +| SONARR_API_KEY | 7a392fb4817a46e59f2e84e7d5f021bc | No | API key for Sonarr, found in your Sonarr UI -> General settings | +| SONARR_BASE_URL | http://localhost:8989 | Yes | Base URL for Sonarr, including the 'http' and port | +| SONARR_QUALITY_PROFILE | 1080p | Yes | Quality profile for Sonarr, found in your Sonarr UI -> Profiles settings | +| SONARR_ROOT_FOLDER | /data/ | Yes | Root folder for Sonarr | +| RADARR_API_KEY | 7a392fb4817a46e59f2e84e7d5f021bc | No | API key for Radarr, found in your Radarr UI -> General settings | +| RADARR_BASE_URL | http://127.0.0.1:7878 | Yes | Base URL for Radarr, including the 'http' and port | +| RADARR_QUALITY_PROFILE | 1080p | Yes | Quality profile for Radarr, found in your Radarr UI -> Profiles settings | +| RADARR_ROOT_FOLDER | /data/ | Yes | Root folder for Radarr | +| PLEX_WATCHLIST_URL_1 | https://rss.plex.tv/UUID | No | First Plex Watchlist URL | +| PLEX_WATCHLIST_URL_2 | https://rss.plex.tv/UUID | Yes | Second Plex Watchlist URL (if applicable) | ### Getting your Plex Watchlist URLs diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index dace1e2..849bd49 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -10,8 +10,8 @@ if [ -n "$SONARR_BASE_URL" ]; then CMD="$CMD -Dsonarr.baseUrl=$SONARR_BASE_URL" fi -if [ -n "$SONARR_QUALITY_PROFILE_ID" ]; then - CMD="$CMD -Dsonarr.qualityProfile=$SONARR_QUALITY_PROFILE_ID" +if [ -n "$SONARR_QUALITY_PROFILE" ]; then + CMD="$CMD -Dsonarr.qualityProfile=$SONARR_QUALITY_PROFILE" fi if [ -n "$SONARR_ROOT_FOLDER" ]; then @@ -26,8 +26,8 @@ if [ -n "$RADARR_BASE_URL" ]; then CMD="$CMD -Dradarr.baseUrl=$RADARR_BASE_URL" fi -if [ -n "$RADARR_QUALITY_PROFILE_ID" ]; then - CMD="$CMD -Dradarr.qualityProfile=$RADARR_QUALITY_PROFILE_ID" +if [ -n "$RADARR_QUALITY_PROFILE" ]; then + CMD="$CMD -Dradarr.qualityProfile=$RADARR_QUALITY_PROFILE" fi if [ -n "$RADARR_ROOT_FOLDER" ]; then diff --git a/src/main/scala/Configuration.scala b/src/main/scala/Configuration.scala index 6917765..26ed398 100644 --- a/src/main/scala/Configuration.scala +++ b/src/main/scala/Configuration.scala @@ -1,5 +1,7 @@ import cats.effect.IO import cats.effect.unsafe.implicits.global +import model.QualityProfile +import io.circe.generic.auto._ import scala.concurrent.duration._ @@ -7,43 +9,61 @@ class Configuration { val refreshInterval: FiniteDuration = getConfigOption("interval.seconds").flatMap(_.toIntOption).getOrElse(60).seconds - val (sonarrBaseUrl, sonarrApiKey) = getAndTestSonarrUrlAndApiKey.unsafeRunSync() - // TODO: Grab the quality profile ID automatically if it's not set - val sonarrQualityProfileId: Option[Int] = getConfigOption("sonarr.qualityProfile").flatMap(_.toIntOption) + val (sonarrBaseUrl, sonarrApiKey, sonarrQualityProfileId) = getAndTestSonarrUrlAndApiKey.unsafeRunSync() val sonarrRootFolder: String = getConfigOption("sonarr.rootFolder").getOrElse("/data/") - val (radarrBaseUrl, radarrApiKey) = getAndTestRadarrUrlAndApiKey.unsafeRunSync() - val radarrQualityProfileId: Option[Int] = getConfigOption("radarr.qualityProfile").flatMap(_.toIntOption) + val (radarrBaseUrl, radarrApiKey, radarrQualityProfileId) = getAndTestRadarrUrlAndApiKey.unsafeRunSync() val radarrRootFolder: String = getConfigOption("radarr.rootFolder").getOrElse("/data/") val plexWatchlistUrls: List[String] = getPlexWatchlistUrls - private def getAndTestSonarrUrlAndApiKey: IO[(String, String)] = { + private def getAndTestSonarrUrlAndApiKey: IO[(String, String, Int)] = { val url = getConfigOption("sonarr.baseUrl").getOrElse("http://localhost:8989") val apiKey = getConfig("sonarr.apikey") - ArrUtils.getToArr(url, apiKey, "health").map { - case Right(_) => - println("Successfully tested the connection to Sonarr!") - (url, apiKey) + ArrUtils.getToArr(url, apiKey, "qualityprofile").map { + case Right(res) => + println("Successfully connected to Sonarr") + val allQualityProfiles = res.as[List[QualityProfile]].getOrElse(List.empty) + val chosenQualityProfile = getConfigOption("sonarr.qualityProfile") + (url, apiKey, getQualityProfileId(allQualityProfiles, chosenQualityProfile)) case Left(err) => throw new IllegalArgumentException(s"Unable to connect to Sonarr at $url, with error $err") } } - private def getAndTestRadarrUrlAndApiKey: IO[(String, String)] = { + private def getAndTestRadarrUrlAndApiKey: IO[(String, String, Int)] = { val url = getConfigOption("radarr.baseUrl").getOrElse("http://localhost:7878") val apiKey = getConfig("radarr.apikey") - ArrUtils.getToArr(url, apiKey, "health").map { - case Right(_) => - println("Successfully tested the connection to Radarr!") - (url, apiKey) + ArrUtils.getToArr(url, apiKey, "qualityprofile").map { + case Right(res) => + println("Successfully connected to Radarr") + val allQualityProfiles = res.as[List[QualityProfile]].getOrElse(List.empty) + val chosenQualityProfile = getConfigOption("radarr.qualityProfile") + (url, apiKey, getQualityProfileId(allQualityProfiles, chosenQualityProfile)) case Left(err) => throw new IllegalArgumentException(s"Unable to connect to Radarr at $url, with error $err") } } + private def getQualityProfileId(allProfiles: List[QualityProfile], maybeEnvVariable: Option[String]): Int = + (allProfiles, maybeEnvVariable) match { + case (Nil, _) => + println("Could not find any quality profiles defined, check your Sonarr/Radarr settings") + throw new IllegalArgumentException("Unable to fetch quality profiles from Sonarr or Radarr") + case (List(one), _) => + println(s"Only one quality profile defined: ${one.name}") + one.id + case (_, None) => + println("Multiple quality profiles found, selecting the first one in the list.") + allProfiles.head.id + case (_, Some(profileName)) => + allProfiles.find(_.name.toLowerCase == profileName.toLowerCase).map(_.id).getOrElse( + throw new IllegalArgumentException(s"Unable to find quality profile $profileName. Possible values are $allProfiles") + ) + } + private def getPlexWatchlistUrls: List[String] = Set( getConfigOption("plex.watchlist1"), diff --git a/src/main/scala/WatchlistSync.scala b/src/main/scala/WatchlistSync.scala index 4799322..0d1930d 100644 --- a/src/main/scala/WatchlistSync.scala +++ b/src/main/scala/WatchlistSync.scala @@ -97,7 +97,7 @@ object WatchlistSync { private def addToRadarr(config: Configuration)(item: Item): IO[Unit] = { - val movie = RadarrPost(item.title, findTmdbId(item.guids).getOrElse(0L), config.radarrQualityProfileId.getOrElse(0), config.radarrRootFolder) + val movie = RadarrPost(item.title, findTmdbId(item.guids).getOrElse(0L), config.radarrQualityProfileId, config.radarrRootFolder) ArrUtils.postToArr(config.radarrBaseUrl, config.radarrApiKey, "movie")(movie.asJson).map { case Right(_) => @@ -116,7 +116,7 @@ object WatchlistSync { private def addToSonarr(config: Configuration)(item: Item): IO[Unit] = { - val show = SonarrPost(item.title, findTvdbId(item.guids).getOrElse(0L), config.sonarrQualityProfileId.getOrElse(0), config.sonarrRootFolder) + val show = SonarrPost(item.title, findTvdbId(item.guids).getOrElse(0L), config.sonarrQualityProfileId, config.sonarrRootFolder) ArrUtils.postToArr(config.sonarrBaseUrl, config.sonarrApiKey, "series")(show.asJson).map { case Right(_) => diff --git a/src/main/scala/model/QualityProfile.scala b/src/main/scala/model/QualityProfile.scala new file mode 100644 index 0000000..b22b7d7 --- /dev/null +++ b/src/main/scala/model/QualityProfile.scala @@ -0,0 +1,3 @@ +package model + +case class QualityProfile(name: String, id: Int)