Skip to content

Commit

Permalink
Sonarr v3 compatibility (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
nylonee committed Dec 19, 2023
1 parent 76e4261 commit dcbbc34
Show file tree
Hide file tree
Showing 11 changed files with 519 additions and 19 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ upon startup of the app, where the logs will list the movies/tv shows that are o
### Requirements

* Plex Pass Subscription
* Sonarr v4 or higher
* Sonarr v3 or higher
* Radarr v3 or higher
* Friends must change their privacy settings so that the main user can see their watchlists
* Docker or Java
Expand Down Expand Up @@ -65,9 +65,9 @@ Docker tag options:
Running this using native java requires the fat jar, download the latest from the Releases tab, and run:

```bash
java -Dsonarr.apikey=YOUR_API_KEY\
-Dradarr.apikey=YOUR_API_KEY\
-Dplex.token=YOUR_PLEX_TOKEN\
java "-Dsonarr.apikey=YOUR_API_KEY"\
"-Dradarr.apikey=YOUR_API_KEY"\
"-Dplex.token=YOUR_PLEX_TOKEN"\
-Xmx100m\
-jar watchlistarr.java
```
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/configuration/Configuration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ case class Configuration(
sonarrRootFolder: String,
sonarrBypassIgnored: Boolean,
sonarrSeasonMonitoring: String,
sonarrLanguageProfileId: Int,
radarrBaseUrl: Uri,
radarrApiKey: String,
radarrQualityProfileId: Int,
Expand Down
38 changes: 25 additions & 13 deletions src/main/scala/configuration/ConfigurationUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object ConfigurationUtils {
for {
sonarrConfig <- getSonarrConfig(configReader, client)
refreshInterval = configReader.getConfigOption(Keys.intervalSeconds).flatMap(_.toIntOption).getOrElse(60).seconds
(sonarrBaseUrl, sonarrApiKey, sonarrQualityProfileId, sonarrRootFolder) = sonarrConfig
(sonarrBaseUrl, sonarrApiKey, sonarrQualityProfileId, sonarrRootFolder, sonarrLanguageProfileId) = sonarrConfig
sonarrBypassIgnored = configReader.getConfigOption(Keys.sonarrBypassIgnored).exists(_.toBoolean)
sonarrSeasonMonitoring = configReader.getConfigOption(Keys.sonarrSeasonMonitoring).getOrElse("all")
radarrConfig <- getRadarrConfig(configReader, client)
Expand All @@ -36,6 +36,7 @@ object ConfigurationUtils {
sonarrRootFolder,
sonarrBypassIgnored,
sonarrSeasonMonitoring,
sonarrLanguageProfileId,
radarrBaseUrl,
radarrApiKey,
radarrQualityProfileId,
Expand All @@ -46,31 +47,42 @@ object ConfigurationUtils {
skipFriendSync
)

private def getSonarrConfig(configReader: ConfigurationReader, client: HttpClient): IO[(Uri, String, Int, String)] = {
private def getSonarrConfig(configReader: ConfigurationReader, client: HttpClient): IO[(Uri, String, Int, String, Int)] = {
val url = configReader.getConfigOption(Keys.sonarrBaseUrl).flatMap(Uri.fromString(_).toOption).getOrElse {
val default = "http://localhost:8989"
logger.warn(s"Unable to fetch sonarr baseUrl, using default $default")
Uri.unsafeFromString(default)
}
val apiKey = configReader.getConfigOption(Keys.sonarrApiKey).getOrElse(throwError("Unable to find sonarr API key"))

getToArr(client)(url, apiKey, "rootFolder").map {
case Right(res) =>
logger.info("Successfully connected to Sonarr")
val allRootFolders = res.as[List[RootFolder]].getOrElse(List.empty)
selectRootFolder(allRootFolders, configReader.getConfigOption(Keys.sonarrRootFolder))
case Left(err) =>
throwError(s"Unable to connect to Sonarr at $url, with error $err")
}.flatMap(rootFolder =>
getToArr(client)(url, apiKey, "qualityprofile").map {
for {
rootFolder <- getToArr(client)(url, apiKey, "rootFolder").map {
case Right(res) =>
logger.info("Successfully connected to Sonarr")
val allRootFolders = res.as[List[RootFolder]].getOrElse(List.empty)
selectRootFolder(allRootFolders, configReader.getConfigOption(Keys.sonarrRootFolder))
case Left(err) =>
throwError(s"Unable to connect to Sonarr at $url, with error $err")
}
qualityProfileId <- getToArr(client)(url, apiKey, "qualityprofile").map {
case Right(res) =>
val allQualityProfiles = res.as[List[QualityProfile]].getOrElse(List.empty)
val chosenQualityProfile = configReader.getConfigOption(Keys.sonarrQualityProfile)
(url, apiKey, getQualityProfileId(allQualityProfiles, chosenQualityProfile), rootFolder)
getQualityProfileId(allQualityProfiles, chosenQualityProfile)
case Left(err) =>
throwError(s"Unable to connect to Sonarr at $url, with error $err")
}
)
languageProfileId <- getToArr(client)(url, apiKey, "languageprofile").map {
case Right(res) =>
val allLanguageProfiles = res.as[List[LanguageProfile]].getOrElse(List.empty)
allLanguageProfiles.headOption.map(_.id).getOrElse {
logger.warn("Unable to find a language profile, using 1 as default")
1
}
case Left(err) =>
throwError(s"Unable to connect to Sonarr at $url, with error $err")
}
} yield (url, apiKey, qualityProfileId, rootFolder, languageProfileId)
}

private def getRadarrConfig(configReader: ConfigurationReader, client: HttpClient): IO[(Uri, String, Int, String)] = {
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/configuration/LanguageProfile.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package configuration

private[configuration] case class LanguageProfile(name: String, id: Int)
10 changes: 9 additions & 1 deletion src/main/scala/sonarr/SonarrPost.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
package sonarr

private[sonarr] case class SonarrPost(title: String, tvdbId: Long, qualityProfileId: Int, rootFolderPath: String, addOptions: SonarrAddOptions, monitored: Boolean = true)
private[sonarr] case class SonarrPost(
title: String,
tvdbId: Long,
qualityProfileId: Int,
rootFolderPath: String,
addOptions: SonarrAddOptions,
languageProfileId: Int,
monitored: Boolean = true
)
9 changes: 8 additions & 1 deletion src/main/scala/sonarr/SonarrUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ trait SonarrUtils extends SonarrConversions {
protected def addToSonarr(client: HttpClient)(config: Configuration)(item: Item): IO[Unit] = {

val addOptions = SonarrAddOptions(config.sonarrSeasonMonitoring)
val show = SonarrPost(item.title, item.getTvdbId.getOrElse(0L), config.sonarrQualityProfileId, config.sonarrRootFolder, addOptions)
val show = SonarrPost(
item.title,
item.getTvdbId.getOrElse(0L),
config.sonarrQualityProfileId,
config.sonarrRootFolder,
addOptions,
config.sonarrLanguageProfileId,
)

val result = postToArr[Unit](client)(config.sonarrBaseUrl, config.sonarrApiKey, "series")(show.asJson)
.fold(
Expand Down

0 comments on commit dcbbc34

Please sign in to comment.