diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..08fd618
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: [Fazzani]
\ No newline at end of file
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index fbef5c3..8e954d5 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -10,8 +10,8 @@ _Put an `x` in the boxes that apply_
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
-- [ ] Documentation Update (if none of the other choices apply)
-- [ ] CI/CD or unit tests improvements
+- [ ] Documentation Update
+- [ ] CI/CD or unit tests improvements (if none of the other choices apply)
## Further comments
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index 75c50cb..c97bbcc 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -55,4 +55,10 @@ jobs:
if: github.event_name == 'pull_request'
with:
recreate: true
- path: code-coverage-results.md
\ No newline at end of file
+ path: code-coverage-results.md
+
+ - name: Run codacy-coverage-reporter
+ uses: codacy/codacy-coverage-reporter-action@v1.3.0
+ with:
+ project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
+ coverage-reports: coverage/**/coverage.cobertura.xml
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 78e3e89..8931742 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -38,4 +38,9 @@ If you have a suggestion that would make this better, please fork the repo and c
```sh
dotnet run ./src/Proxarr.Api/Proxarr.Api.csproj
```
-
\ No newline at end of file
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 90d8578..12d04c7 100644
--- a/README.md
+++ b/README.md
@@ -65,22 +65,22 @@ It uses TMDB to find out which streaming services are available in the selected
* Acquire TMDB API KEY
[How](https://dev.to/codexive_zech/streamlining-your-contribution-how-to-get-your-tmdb-api-key-for-ldbflix-contribution-52gf#:~:text=How%20to%20Obtain%20a%20TMDB%20API%20Key)
-* Obtain SONARR/RADARR API KEY
-
+* Obtain SONARR/RADARR API KEY
+
### Installation with Docker compose
1. Prepare your [config.yml][config-yml] to fit your setup
2. On your Radarr/Sonarr instances we have to do some changes
- - tag all indexers by the TAG_NAME defined in your [config.yml][config-yml] (`q` by default)
-
+ - tag all indexers by the TAG_NAME defined in your [config.yml][config-yml] (`q` by default)
+
- specify Application URL: is essential because it is used by Proxarr to determine to which instance should return the response
- - establish a Webhook connection between Sonarr/Radarr and Proxarr
-
- _Note_ : Webhook URL is `http:///api/qualifier
-3. Add the following to your docker-compose.yml (to be adapted according to your stack)
- [docker-compose.yml](docker-compose.yml) is an another full example of how to integrate Proxarr with Sonarr and Radarr.
+ - establish a Webhook connection between Sonarr/Radarr and Proxarr
+
+
_Note_ : Webhook URL is `http:///api/qualifier
+3. Add the following to your docker-compose.yml (to be adapted according to your stack)
+
[docker-compose.yml](docker-compose.yml) is an another full example of how to integrate Proxarr with Sonarr and Radarr.
```yaml
proxarr:
image: synker/proxarr:latest
@@ -117,7 +117,11 @@ It uses TMDB to find out which streaming services are available in the selected
docker run -itd --rm -e LOG_LEVEL=Debug -p 8880:8880 -v ${PWD}/config:/app/config --name proxarr synker/proxarr:latest
```
-
+
+
+
+
+
### Watching providers configuration
diff --git a/src/Proxarr.Api.Tests/RadarrServiceTests.cs b/src/Proxarr.Api.Tests/RadarrServiceTests.cs
index 9a3c3cb..6af1f3c 100644
--- a/src/Proxarr.Api.Tests/RadarrServiceTests.cs
+++ b/src/Proxarr.Api.Tests/RadarrServiceTests.cs
@@ -61,7 +61,7 @@ public async Task Qualify_ShouldReturnNotFound_WhenMovieNotFoundIntoRadarr()
};
var cancellationToken = new CancellationToken();
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync(new TMDbLib.Objects.Movies.Movie { WatchProviders = new SingleResultContainer> { Results = [] } });
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
@@ -86,7 +86,7 @@ public async Task Qualify_ShouldReturnNotFound_WhenMovieNotFoundIntoTMDB()
};
var cancellationToken = new CancellationToken();
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync((TMDbLib.Objects.Movies.Movie)null);
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
@@ -121,7 +121,7 @@ public async Task Qualify_ShouldUpdateTags_WhenMovieFound()
var seriesResource = new MovieResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync(new TMDbLib.Objects.Movies.Movie { WatchProviders = watchProviders });
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
@@ -163,7 +163,7 @@ public async Task Qualify_Should_NotBeTagged_When_MatchedWatchProvider()
var movieResource = new MovieResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync(new TMDbLib.Objects.Movies.Movie { WatchProviders = watchProviders });
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
@@ -210,7 +210,7 @@ public async Task Qualify_Should_BeTagged_When_MatchedWatchProvider()
var movieResource = new MovieResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync(new TMDbLib.Objects.Movies.Movie { WatchProviders = watchProviders });
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
@@ -246,10 +246,9 @@ public async Task Qualify_Should_BeTagged_When_NoWatchProviders()
};
var cancellationToken = new CancellationToken();
-
var movieResource = new MovieResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetMovieAsync(123, MovieMethods.WatchProviders, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetMovieAsync(123, cancellationToken, MovieMethods.WatchProviders))
.ReturnsAsync(new TMDbLib.Objects.Movies.Movie());
_radarrClientMock.Setup(x => x.MovieGET2Async(1, cancellationToken))
diff --git a/src/Proxarr.Api.Tests/SonarrServiceTests.cs b/src/Proxarr.Api.Tests/SonarrServiceTests.cs
index d3db58e..6512ac9 100644
--- a/src/Proxarr.Api.Tests/SonarrServiceTests.cs
+++ b/src/Proxarr.Api.Tests/SonarrServiceTests.cs
@@ -60,7 +60,7 @@ public async Task Qualify_ShouldReturnNotFound_WhenSeriesNotFoundIntoSonarr()
};
var cancellationToken = new CancellationToken();
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
.ReturnsAsync(new TvShow { WatchProviders = new SingleResultContainer> { Results = [] } });
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
@@ -85,7 +85,7 @@ public async Task Qualify_ShouldReturnNotFound_WhenSeriesNotFoundIntoTMDB()
};
var cancellationToken = new CancellationToken();
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
.ReturnsAsync((TvShow)null);
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
@@ -120,7 +120,7 @@ public async Task Qualify_ShouldUpdateTags_WhenSeriesFound()
var seriesResource = new SeriesResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
.ReturnsAsync(new TvShow { WatchProviders = watchProviders });
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
@@ -162,7 +162,7 @@ public async Task Qualify_Should_NotBeTagged_When_MatchedWatchProvider()
var seriesResource = new SeriesResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
.ReturnsAsync(new TvShow { WatchProviders = watchProviders });
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
@@ -208,7 +208,7 @@ public async Task Qualify_Should_BeTagged_When_MatchedWatchProvider()
var seriesResource = new SeriesResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
.ReturnsAsync(new TvShow { WatchProviders = watchProviders });
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
@@ -244,8 +244,8 @@ public async Task Qualify_Should_BeTagged_When_NoWatchProvider()
var seriesResource = new SeriesResource { Id = 1, Title = "Test Series", Tags = [] };
- _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, TvShowMethods.WatchProviders, null, null, cancellationToken))
- .ReturnsAsync(new TvShow ());
+ _tmdbClientMock.Setup(x => x.GetTvShowAsync(123, cancellationToken, TvShowMethods.WatchProviders))
+ .ReturnsAsync(new TvShow());
_sonarrClientMock.Setup(x => x.SeriesGETAsync(1, false, cancellationToken))
.ReturnsAsync(seriesResource);
diff --git a/src/Proxarr.Api/Configuration/ClientConfiguration.cs b/src/Proxarr.Api/Configuration/ClientConfiguration.cs
index cb86064..d112abb 100644
--- a/src/Proxarr.Api/Configuration/ClientConfiguration.cs
+++ b/src/Proxarr.Api/Configuration/ClientConfiguration.cs
@@ -5,7 +5,7 @@ namespace Proxarr.Api.Configuration
[ExcludeFromCodeCoverage]
public sealed class ClientConfiguration
{
- public const string SECTION_NAME = $"{AppConfiguration.SECTION_NAME}:Clients";
+ public static string SECTION_NAME { get; } = $"{AppConfiguration.SECTION_NAME}:Clients";
///
/// Must be Sonarr or Radarr
diff --git a/src/Proxarr.Api/Core/CronJobService.cs b/src/Proxarr.Api/Core/CronJobService.cs
index b939351..ecd67c7 100644
--- a/src/Proxarr.Api/Core/CronJobService.cs
+++ b/src/Proxarr.Api/Core/CronJobService.cs
@@ -28,10 +28,15 @@ protected virtual async Task ScheduleJob(CancellationToken cancellationToken)
while (!cancellationToken.IsCancellationRequested)
{
var next = _expression.GetNextOccurrence(DateTimeOffset.Now, timeZoneInfo);
- if (!next.HasValue) continue;
+
+ if (!next.HasValue)
+ {
+ continue;
+ }
logger.LogInformation("{JobName}: scheduled next run at {NextRun}", GetType().Name, next.ToString());
var delay = next.Value - DateTimeOffset.Now;
+
if (delay.TotalMilliseconds <= 0) // prevent non-positive values from being passed into Timer
{
logger.LogInformation("{LoggerName}: scheduled next run is in the past. Moving to next.", GetType().Name);
diff --git a/src/Proxarr.Api/Core/Http/BasicAuthenticationHandler.cs b/src/Proxarr.Api/Core/Http/BasicAuthenticationHandler.cs
index e621f63..784e87f 100644
--- a/src/Proxarr.Api/Core/Http/BasicAuthenticationHandler.cs
+++ b/src/Proxarr.Api/Core/Http/BasicAuthenticationHandler.cs
@@ -13,7 +13,11 @@ namespace Proxarr.Api.Core.Http
[ExcludeFromCodeCoverage]
public class BasicAuthenticationDefaults
{
- public const string AuthenticationScheme = "Basic";
+ protected BasicAuthenticationDefaults()
+ {
+ }
+
+ public static string AuthenticationScheme { get; } = "Basic";
}
[ExcludeFromCodeCoverage]
diff --git a/src/Proxarr.Api/Core/TmdbProxy.cs b/src/Proxarr.Api/Core/TmdbProxy.cs
index 96459ba..5bd77f9 100644
--- a/src/Proxarr.Api/Core/TmdbProxy.cs
+++ b/src/Proxarr.Api/Core/TmdbProxy.cs
@@ -7,8 +7,10 @@ namespace Proxarr.Api.Core
{
public interface ITmdbProxy
{
- Task GetMovieAsync(int movieId, MovieMethods extraMethods = MovieMethods.Undefined, CancellationToken cancellationToken = default);
- Task GetTvShowAsync(int id, TvShowMethods extraMethods = TvShowMethods.Undefined, string language = null, string includeImageLanguage = null, CancellationToken cancellationToken = default);
+ Task GetMovieAsync(int movieId, MovieMethods extraMethods = MovieMethods.Undefined);
+ Task GetMovieAsync(int movieId, CancellationToken cancellationToken, MovieMethods extraMethods = MovieMethods.Undefined);
+ Task GetTvShowAsync(int id, TvShowMethods extraMethods = TvShowMethods.Undefined);
+ Task GetTvShowAsync(int id, CancellationToken cancellationToken, TvShowMethods extraMethods = TvShowMethods.Undefined);
}
[ExcludeFromCodeCoverage]
@@ -22,12 +24,22 @@ public TmdbProxy(TMDbClient tMDbClient)
_tMDbClient = tMDbClient;
}
- public Task GetTvShowAsync(int id, TvShowMethods extraMethods = TvShowMethods.Undefined, string language = null, string includeImageLanguage = null, CancellationToken cancellationToken = default)
+ public Task GetTvShowAsync(int id, TvShowMethods extraMethods = TvShowMethods.Undefined)
{
- return _tMDbClient.GetTvShowAsync(id, extraMethods, language, includeImageLanguage, cancellationToken);
+ return _tMDbClient.GetTvShowAsync(id, extraMethods, null, null, CancellationToken.None);
}
- public Task GetMovieAsync(int movieId, MovieMethods extraMethods = MovieMethods.Undefined, CancellationToken cancellationToken = default)
+ public Task GetTvShowAsync(int id, CancellationToken cancellationToken, TvShowMethods extraMethods = TvShowMethods.Undefined)
+ {
+ return _tMDbClient.GetTvShowAsync(id, extraMethods, null, null, cancellationToken);
+ }
+
+ public Task GetMovieAsync(int movieId, MovieMethods extraMethods = MovieMethods.Undefined)
+ {
+ return _tMDbClient.GetMovieAsync(movieId, extraMethods, CancellationToken.None);
+ }
+
+ public Task GetMovieAsync(int movieId, CancellationToken cancellationToken, MovieMethods extraMethods = MovieMethods.Undefined)
{
return _tMDbClient.GetMovieAsync(movieId, extraMethods, cancellationToken);
}
diff --git a/src/Proxarr.Api/Services/RadarrService.cs b/src/Proxarr.Api/Services/RadarrService.cs
index 7c18515..620ebf8 100644
--- a/src/Proxarr.Api/Services/RadarrService.cs
+++ b/src/Proxarr.Api/Services/RadarrService.cs
@@ -61,7 +61,7 @@ public async Task Qualify(MovieAdded movieAdded, CancellationToken cance
_logger.LogInformation("Qualifying movie {Title}", movieAdded.Movie.Title);
var tmdbItem = await _tMDbClient
- .GetMovieAsync(movieAdded.Movie.TmdbId, TMDbLib.Objects.Movies.MovieMethods.WatchProviders, cancellationToken)
+ .GetMovieAsync(movieAdded.Movie.TmdbId, cancellationToken, TMDbLib.Objects.Movies.MovieMethods.WatchProviders)
.ConfigureAwait(false);
if (tmdbItem != null)
@@ -135,7 +135,7 @@ private async Task AddTag(MovieResource movieRadarr,
{
_logger.LogInformation("Adding tag {Tag} for {Title}", tag.Label, movieRadarr.Title);
movieRadarr.Tags.Add(tag.Id);
- updated = true;
+ return true;
}
return updated;
diff --git a/src/Proxarr.Api/Services/SonarrService.cs b/src/Proxarr.Api/Services/SonarrService.cs
index df31cf8..6a27b00 100644
--- a/src/Proxarr.Api/Services/SonarrService.cs
+++ b/src/Proxarr.Api/Services/SonarrService.cs
@@ -61,7 +61,7 @@ public async Task Qualify(TvAdded tvAdded, CancellationToken cancellatio
_logger.LogInformation("Qualifying tv {Title}", tvAdded.Series.Title);
var tmdbItem = await _tMDbClient
- .GetTvShowAsync(tvAdded.Series.TmdbId, TMDbLib.Objects.TvShows.TvShowMethods.WatchProviders, cancellationToken: cancellationToken)
+ .GetTvShowAsync(tvAdded.Series.TmdbId, cancellationToken, TMDbLib.Objects.TvShows.TvShowMethods.WatchProviders)
.ConfigureAwait(false);
if (tmdbItem != null)
@@ -135,7 +135,7 @@ private async Task AddTag(SeriesResource seriesSonarr,
{
_logger.LogInformation("Adding tag {Tag} for {Title}", tag.Label, seriesSonarr.Title);
seriesSonarr.Tags.Add(tag.Id);
- updated = true;
+ return true;
}
return updated;