Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/resources/config-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
## Uncomment the lines you would like to configure, then save this file and restart Watchlistarr

#interval:
## How often do you want Watchlistarr to pull the latest from Plex? In general, 10-30 seconds is okay.
## How often do you want Watchlistarr to pull the latest from Plex? In general, 60-300 seconds is okay.
## If you're running this on a slower system (e.g. Raspberry Pi), you may want to increase this
## Note: If you do not have Plex Pass, this will be overridden to ~19 minute syncs, see README
# seconds: 10
# seconds: 120


#################################################################
Expand Down
11 changes: 7 additions & 4 deletions src/main/scala/Server.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import cats.effect._
import cats.effect.std.Random
import cats.implicits.catsSyntaxTuple4Parallel
import configuration.{Configuration, ConfigurationUtils, FileAndSystemPropertyReader}
import http.HttpClient
Expand Down Expand Up @@ -48,10 +49,12 @@ object Server extends IOApp {
httpClient: HttpClient
): IO[Unit] =
for {
config <- fetchLatestConfig(configRef)
_ <- PlexTokenSync.run(config, httpClient, runFullSync = false)
_ <- IO.sleep(config.refreshInterval)
_ <- plexRssSync(configRef, httpClient)
config <- fetchLatestConfig(configRef)
_ <- PlexTokenSync.run(config, httpClient, runFullSync = false)
// We should be considerate with the Plex servers
randomMillis <- Random.scalaUtilRandom[IO].flatMap(_.nextLongBounded(3 * config.refreshInterval.toMillis))
_ <- IO.sleep(config.refreshInterval + randomMillis.millis)
_ <- plexRssSync(configRef, httpClient)
} yield ()

private def plexFullSync(
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/configuration/ConfigurationUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ object ConfigurationUtils {
def create(configReader: ConfigurationReader, client: HttpClient): IO[Configuration] = {
val config = for {
sonarrConfig <- getSonarrConfig(configReader, client)
refreshInterval = configReader.getConfigOption(Keys.intervalSeconds).flatMap(_.toIntOption).getOrElse(60).seconds
refreshInterval = configReader.getConfigOption(Keys.intervalSeconds).flatMap(_.toIntOption).getOrElse(120).seconds
(sonarrBaseUrl, sonarrApiKey, sonarrQualityProfileId, sonarrRootFolder, sonarrLanguageProfileId, sonarrTagIds) =
sonarrConfig
sonarrBypassIgnored = configReader.getConfigOption(Keys.sonarrBypassIgnored).exists(_.toBoolean)
Expand Down
21 changes: 16 additions & 5 deletions src/main/scala/plex/PlexUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package plex

import cats.data.EitherT
import cats.effect.IO
import cats.effect.implicits.parSequenceN
import cats.implicits.toTraverseOps
import configuration.PlexConfiguration
import http.HttpClient
Expand All @@ -14,6 +15,8 @@ import io.circe.syntax.EncoderOps
import org.http4s.client.UnexpectedStatus

import java.util.UUID
import scala.concurrent.duration.DurationInt
import scala.util.Random

trait PlexUtils {

Expand All @@ -23,10 +26,8 @@ trait PlexUtils {
extras.Configuration.default.withDefaults

protected def fetchWatchlistFromRss(client: HttpClient)(url: Uri): IO[Set[Item]] = {
val randomUUID = UUID.randomUUID().toString.take(12)
val jsonFormatUrl = url
.withQueryParam("format", "json")
.withQueryParam("cache_buster", randomUUID)

client.httpRequest(Method.GET, jsonFormatUrl).map {
case Left(UnexpectedStatus(s, _, _)) if s.code == 500 =>
Expand Down Expand Up @@ -69,7 +70,7 @@ trait PlexUtils {
containerStart: Int = 0
): EitherT[IO, Throwable, Set[Item]] = config.plexTokens
.map { token =>
val containerSize = 300
val containerSize = 100
val url = Uri
.unsafeFromString("https://discover.provider.plex.tv/library/sections/watchlist/all")
.withQueryParam("X-Plex-Token", token)
Expand All @@ -82,7 +83,12 @@ trait PlexUtils {
result <- EitherT.liftF(toItems(config, client)(tokenWatchlist))
nextPage <-
if (tokenWatchlist.MediaContainer.totalSize > containerStart + containerSize)
getSelfWatchlist(config, client, containerStart + containerSize)
for {
// We should be considerate with the Plex servers
randomSeconds <- EitherT.liftF(IO(Random.nextInt(11)))
_ <- EitherT.liftF(IO.sleep(3.seconds + randomSeconds.seconds))
next <- getSelfWatchlist(config, client, containerStart + containerSize)
} yield next
else
EitherT.pure[IO, Throwable](Set.empty[Item])
} yield result ++ nextPage
Expand Down Expand Up @@ -178,7 +184,12 @@ trait PlexUtils {
if (
watchlist.data.user.watchlist.pageInfo.hasNextPage && watchlist.data.user.watchlist.pageInfo.endCursor.nonEmpty
)
getWatchlistIdsForUser(config, client, token)(user, watchlist.data.user.watchlist.pageInfo.endCursor)
for {
// We should be considerate with the Plex servers
randomSeconds <- EitherT.liftF(IO(Random.nextInt(11)))
_ <- EitherT.liftF(IO.sleep(3.seconds + randomSeconds.seconds))
next <- getWatchlistIdsForUser(config, client, token)(user, watchlist.data.user.watchlist.pageInfo.endCursor)
} yield next
else
EitherT.pure[IO, Throwable](Set.empty[TokenWatchlistItem])
} yield watchlist.data.user.watchlist.nodes.map(_.toTokenWatchlistItem).toSet ++ extraContent
Expand Down