diff --git a/README.md b/README.md index 2fa3f55..4b239f3 100644 --- a/README.md +++ b/README.md @@ -1,164 +1,166 @@ - -[![Contributors][contributors-shield]][contributors-url] -[![Forks][forks-shield]][forks-url] -[![Stargazers][stars-shield]][stars-url] -[![Issues][issues-shield]][issues-url] -[![project_license][license-shield]][license-url] -[![LinkedIn][linkedin-shield]][linkedin-url] - -[![Docker](https://github.com/Fazzani/Proxarr/actions/workflows/docker-image.yml/badge.svg)](https://github.com/Fazzani/Proxarr/actions/workflows/docker-image.yml) -[![.NET](https://github.com/Fazzani/Proxarr/actions/workflows/pr.yml/badge.svg)](https://github.com/Fazzani/Proxarr/actions/workflows/pr.yml) - - -
-
- - Logo - - -

- Automatically categorize your requested movies and tv shows from your watching providers. -
- :boom: Report Bug :boom: - · - :sparkles: Request Feature :sparkles: -

-
- - -
- Table of Contents -
    -
  1. - About The Project -
  2. -
  3. - Getting Started - -
  4. -
  5. Roadmap
  6. -
  7. Contributing
  8. -
-
- - -## About The Project - -Proxarr is a lightweight proxy server for automatically qualify requested media items based in countries served by watching providers. -It uses TMDB to find out which streaming services are available in the selected region. - - - -

back to top

- - -## Getting Started - -### Prerequisites - -* 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
- - -### 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 indexers - - specify Application URL: is essential because it is used by Proxarr to determine which instance should return the response
- Application Url config - - establish a Webhook connection between Sonarr/Radarr and Proxarr
- Application Url config
- _Note_ : Webhook URL is `http:///api/qualifier/tv` for Sonarr and `http:///api/qualifier/movie` for Radarr -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 - container_name: proxarr - restart: unless-stopped - depends_on: - sonarr: - condition: service_healthy - radarr: - condition: service_healthy - healthcheck: - test: curl --fail http://localhost:8880/health || exit 1 - interval: 10s - retries: 3 - start_period: 5s - timeout: 3s - ports: - - "8880:8880" - environment: - - LOG_LEVEL=Information - volumes: - - ./:/app/config - - ./logs:/logs" - ``` -4. Run ```shell - docker compose -f docker-compose.yml up -d - ``` -> Standalone docker container example - -```shell -docker run -itd --rm -e LOG_LEVEL=Debug -p 8880:8880 -v ${PWD}/config:/app/config --name proxarr synker/proxarr:latest -``` - -

back to top

- -### Watching providers configuration - -- [TMDB API to get available regions](https://developer.themoviedb.org/reference/watch-providers-available-regions) -- [TMDB API to get available movie providers by region](https://developer.themoviedb.org/reference/watch-providers-movie-list) -- [TMDB API to get available tv providers by region](https://developer.themoviedb.org/reference/watch-providers-tv-list) - - -## Roadmap - -- [ ] Add Full scan library feature -- [ ] Add more providers (JustWatch, Reelgood, etc) -- [ ] Add more tests -- [ ] Improve logging and error handling -- [ ] Add Api versioning - -See the [open issues](https://github.com/Fazzani/Proxarr/issues) for a full list of proposed features (and known issues). - -

back to top

- - -## Contributing - -Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. -Don't forget to give the project a :star: star :star: ! Thanks again! - -For further information, [click here](CONTRIBUTING.md) - -### Top contributors: - - - contrib.rocks image - - -

back to top

- - -[contributors-shield]: https://img.shields.io/github/contributors/Fazzani/Proxarr.svg?style=for-the-badge -[contributors-url]: https://github.com/Fazzani/Proxarr/graphs/contributors -[forks-shield]: https://img.shields.io/github/forks/Fazzani/Proxarr.svg?style=for-the-badge -[forks-url]: https://github.com/Fazzani/Proxarr/network/members -[stars-shield]: https://img.shields.io/github/stars/Fazzani/Proxarr.svg?style=for-the-badge -[stars-url]: https://github.com/Fazzani/Proxarr/stargazers -[issues-shield]: https://img.shields.io/github/issues/Fazzani/Proxarr.svg?style=for-the-badge -[issues-url]: https://github.com/Fazzani/Proxarr/issues -[license-shield]: https://img.shields.io/github/license/Fazzani/Proxarr.svg?style=for-the-badge -[license-url]: https://github.com/Fazzani/Proxarr/blob/master/LICENSE.txt -[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 -[linkedin-url]: https://www.linkedin.com/in/heni-fazzani -[arr-api-key]: images/arr_api_key.png + +[![Contributors][contributors-shield]][contributors-url] +[![Forks][forks-shield]][forks-url] +[![Stargazers][stars-shield]][stars-url] +[![Issues][issues-shield]][issues-url] +[![project_license][license-shield]][license-url] +[![LinkedIn][linkedin-shield]][linkedin-url] + +[![Docker](https://github.com/Fazzani/Proxarr/actions/workflows/docker-image.yml/badge.svg)](https://github.com/Fazzani/Proxarr/actions/workflows/docker-image.yml) +[![.NET](https://github.com/Fazzani/Proxarr/actions/workflows/pr.yml/badge.svg)](https://github.com/Fazzani/Proxarr/actions/workflows/pr.yml) + + +
+
+ + Logo + + +

+ Automatically categorize your requested movies and tv shows from your watching providers. +
+ :boom: Report Bug :boom: + · + :sparkles: Request Feature :sparkles: +

+
+ + +
+ Table of Contents +
    +
  1. + About The Project +
  2. +
  3. + Getting Started + +
  4. +
  5. Roadmap
  6. +
  7. Contributing
  8. +
+
+ + +## About The Project + +Proxarr is a lightweight proxy server for automatically qualify requested media items based in countries served by watching providers. +It uses TMDB to find out which streaming services are available in the selected region. + + + +

back to top

+ + +## Getting Started + +### Prerequisites + +* 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
+ + +### 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 indexers + - specify Application URL: is essential because it is used by Proxarr to determine which instance should return the response
+ Application Url config + - establish a Webhook connection between Sonarr/Radarr and Proxarr
+ Application Url config
+ _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 + container_name: proxarr + restart: unless-stopped + depends_on: + sonarr: + condition: service_healthy + radarr: + condition: service_healthy + healthcheck: + test: curl --fail http://localhost:8880/health || exit 1 + interval: 10s + retries: 3 + start_period: 5s + timeout: 3s + ports: + - "8880:8880" + environment: + - LOG_LEVEL=Information + volumes: + - ./:/app/config + - ./logs:/logs" + ``` + +4. Run + ```shell + docker compose -f docker-compose.yml up -d + ``` +> Standalone docker container example + +```shell +docker run -itd --rm -e LOG_LEVEL=Debug -p 8880:8880 -v ${PWD}/config:/app/config --name proxarr synker/proxarr:latest +``` + +

back to top

+ +### Watching providers configuration + +- [TMDB API to get available regions](https://developer.themoviedb.org/reference/watch-providers-available-regions) +- [TMDB API to get available movie providers by region](https://developer.themoviedb.org/reference/watch-providers-movie-list) +- [TMDB API to get available tv providers by region](https://developer.themoviedb.org/reference/watch-providers-tv-list) + + +## Roadmap + +- [ ] Add Full scan library feature +- [ ] Add more providers (JustWatch, Reelgood, etc) +- [ ] Add more tests +- [ ] Improve logging and error handling +- [ ] Add Api versioning + +See the [open issues](https://github.com/Fazzani/Proxarr/issues) for a full list of proposed features (and known issues). + +

back to top

+ + +## Contributing + +Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. +Don't forget to give the project a :star: star :star: ! Thanks again! + +For further information, [click here](CONTRIBUTING.md) + +### Top contributors: + + + contrib.rocks image + + +

back to top

+ + +[contributors-shield]: https://img.shields.io/github/contributors/Fazzani/Proxarr.svg?style=for-the-badge +[contributors-url]: https://github.com/Fazzani/Proxarr/graphs/contributors +[forks-shield]: https://img.shields.io/github/forks/Fazzani/Proxarr.svg?style=for-the-badge +[forks-url]: https://github.com/Fazzani/Proxarr/network/members +[stars-shield]: https://img.shields.io/github/stars/Fazzani/Proxarr.svg?style=for-the-badge +[stars-url]: https://github.com/Fazzani/Proxarr/stargazers +[issues-shield]: https://img.shields.io/github/issues/Fazzani/Proxarr.svg?style=for-the-badge +[issues-url]: https://github.com/Fazzani/Proxarr/issues +[license-shield]: https://img.shields.io/github/license/Fazzani/Proxarr.svg?style=for-the-badge +[license-url]: https://github.com/Fazzani/Proxarr/blob/master/LICENSE.txt +[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 +[linkedin-url]: https://www.linkedin.com/in/heni-fazzani +[arr-api-key]: images/arr_api_key.png [config-yml]: ./src/Proxarr.Api/config.yml \ No newline at end of file diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 0000000..05a0338 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,94 @@ +[*.{cs,vb}] +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +[*.cs] +csharp_indent_labels = one_less_than_current +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_throw_expression = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_diagnostic.CA1304.severity = error +dotnet_diagnostic.CA1305.severity = error +[*] +[[*.gitignore](gitignore)] +# VSSPELL: gitignore +[[*.http](http file)] diff --git a/src/Proxarr.Api/Controllers/QualifierController.cs b/src/Proxarr.Api/Controllers/QualifierController.cs index f50751b..384b6b2 100644 --- a/src/Proxarr.Api/Controllers/QualifierController.cs +++ b/src/Proxarr.Api/Controllers/QualifierController.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Proxarr.Api.Models; using Proxarr.Api.Services; -using TMDbLib.Objects.Movies; namespace Proxarr.Api.Controllers { @@ -22,43 +21,41 @@ public QualifierController(ILogger logger, _sonarrService = sonarrService; } - [HttpPost("movie")] + [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task QualifiedMovie(MovieAdded movie, CancellationToken cancellationToken) + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task Qualified(MediaAdded media, CancellationToken cancellationToken) { - if (movie.EventType.Equals("test", StringComparison.OrdinalIgnoreCase)) + if (media.EventType.Equals("test", StringComparison.OrdinalIgnoreCase)) { return Ok(); } - var result = await _radarrService.Qualify(movie, cancellationToken).ConfigureAwait(false); - - if (result == nameof(NotFound)) + if(media is MovieAdded movie) { - _logger.LogError("Movie not found in Radarr {Title}", movie.Movie.Title); - return NotFound(); - } - return Ok(); - } + var result = await _radarrService.Qualify(movie, cancellationToken).ConfigureAwait(false); - [HttpPost("tv")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task QualifiedTv(TvAdded tvAdded, CancellationToken cancellationToken) - { - if (tvAdded.EventType.Equals("test", StringComparison.OrdinalIgnoreCase)) + if (result == nameof(NotFound)) + { + _logger.LogError("Movie not found in Radarr {Title}", movie.Movie.Title); + return NotFound(); + } + } + else if (media is TvAdded tvAdded) { - return Ok(); + var result = await _sonarrService.Qualify(tvAdded, cancellationToken).ConfigureAwait(false); + if (result == nameof(NotFound)) + { + _logger.LogError("Tv not found in Sonarr {Title}", tvAdded.Series.Title); + return NotFound(); + } } - - var result = await _sonarrService.Qualify(tvAdded, cancellationToken).ConfigureAwait(false); - - if (result == nameof(NotFound)) + else { - _logger.LogError("Tv not found in Sonarr {Title}", tvAdded.Series.Title); - return NotFound(); + return BadRequest(); } + return Ok(); } } diff --git a/src/Proxarr.Api/Core/MediaAddedJsonConverter.cs b/src/Proxarr.Api/Core/MediaAddedJsonConverter.cs new file mode 100644 index 0000000..cfe5b63 --- /dev/null +++ b/src/Proxarr.Api/Core/MediaAddedJsonConverter.cs @@ -0,0 +1,39 @@ +using Proxarr.Api.Models; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Proxarr.Api.Core +{ + public class MediaAddedJsonConverter : JsonConverter + { + public override MediaAdded Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + using JsonDocument doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var eventType = root.GetProperty("eventType").GetString(); + + if (eventType?.Equals("MovieAdded", StringComparison.OrdinalIgnoreCase) == true) + { + return JsonSerializer.Deserialize(root.GetRawText()) ?? throw new FormatException($"Malformed json content to deserialize {nameof(MovieAdded)} object"); + } + else if (eventType?.Equals("SeriesAdd", StringComparison.OrdinalIgnoreCase) == true) + { + return JsonSerializer.Deserialize(root.GetRawText()) ?? throw new FormatException($"Malformed json content to deserialize {nameof(TvAdded)} object"); + } + else if (eventType?.Equals("test", StringComparison.OrdinalIgnoreCase) == true) + { + return JsonSerializer.Deserialize(root.GetRawText()) ?? throw new FormatException($"Malformed json content to deserialize {nameof(TvAdded)} object"); + } + else + { + throw new JsonException(); + } + } + + public override void Write(Utf8JsonWriter writer, MediaAdded value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Proxarr.Api/Models/Image.cs b/src/Proxarr.Api/Models/Image.cs new file mode 100644 index 0000000..81fa128 --- /dev/null +++ b/src/Proxarr.Api/Models/Image.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Proxarr.Api.Models +{ + public class Image + { + [JsonPropertyName("coverType")] + public string? CoverType { get; set; } + + [JsonPropertyName("url")] + public string? Url { get; set; } + + [JsonPropertyName("remoteUrl")] + public string? RemoteUrl { get; set; } + } +} diff --git a/src/Proxarr.Api/Models/MediaAdded.cs b/src/Proxarr.Api/Models/MediaAdded.cs new file mode 100644 index 0000000..e76ed93 --- /dev/null +++ b/src/Proxarr.Api/Models/MediaAdded.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Proxarr.Api.Models +{ + public class MediaAdded + { + [JsonPropertyName("eventType")] + public required string EventType { get; set; } + + [JsonPropertyName("instanceName")] + public required string InstanceName { get; set; } + + [JsonPropertyName("applicationUrl")] + public required string ApplicationUrl { get; set; } + } +} diff --git a/src/Proxarr.Api/Models/MovieAdded.cs b/src/Proxarr.Api/Models/MovieAdded.cs index da4abf0..2e792b6 100644 --- a/src/Proxarr.Api/Models/MovieAdded.cs +++ b/src/Proxarr.Api/Models/MovieAdded.cs @@ -2,22 +2,13 @@ namespace Proxarr.Api.Models { - public class MovieAdded + public class MovieAdded : MediaAdded { [JsonPropertyName("movie")] public required Movie Movie { get; set; } [JsonPropertyName("addMethod")] public string? AddMethod { get; set; } - - [JsonPropertyName("eventType")] - public required string EventType { get; set; } - - [JsonPropertyName("instanceName")] - public required string InstanceName { get; set; } - - [JsonPropertyName("applicationUrl")] - public required string ApplicationUrl { get; set; } } public class Movie @@ -58,25 +49,4 @@ public class Movie [JsonPropertyName("originalLanguage")] public Originallanguage? OriginalLanguage { get; set; } } - - public class Originallanguage - { - [JsonPropertyName("id")] - public int? Id { get; set; } - - [JsonPropertyName("name")] - public string? Name { get; set; } - } - - public class Image - { - [JsonPropertyName("coverType")] - public string? CoverType { get; set; } - - [JsonPropertyName("url")] - public string? Url { get; set; } - - [JsonPropertyName("remoteUrl")] - public string? RemoteUrl { get; set; } - } } diff --git a/src/Proxarr.Api/Models/Originallanguage.cs b/src/Proxarr.Api/Models/Originallanguage.cs new file mode 100644 index 0000000..80c4b13 --- /dev/null +++ b/src/Proxarr.Api/Models/Originallanguage.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace Proxarr.Api.Models +{ + public class Originallanguage + { + [JsonPropertyName("id")] + public int? Id { get; set; } + + [JsonPropertyName("name")] + public string? Name { get; set; } + } +} diff --git a/src/Proxarr.Api/Models/TvAdded.cs b/src/Proxarr.Api/Models/TvAdded.cs index a44d4dc..c9e9627 100644 --- a/src/Proxarr.Api/Models/TvAdded.cs +++ b/src/Proxarr.Api/Models/TvAdded.cs @@ -2,19 +2,10 @@ namespace Proxarr.Api.Models { - public class TvAdded + public class TvAdded : MediaAdded { [JsonPropertyName("series")] public required Series Series { get; set; } - - [JsonPropertyName("eventType")] - public required string EventType { get; set; } - - [JsonPropertyName("instanceName")] - public required string InstanceName { get; set; } - - [JsonPropertyName("applicationUrl")] - public required string ApplicationUrl { get; set; } } public class Series diff --git a/src/Proxarr.Api/Program.cs b/src/Proxarr.Api/Program.cs index e70f406..667906e 100644 --- a/src/Proxarr.Api/Program.cs +++ b/src/Proxarr.Api/Program.cs @@ -5,6 +5,8 @@ using Scalar.AspNetCore; using Serilog; using Sonarr.Http.Client; +using System.Text.Json.Serialization; +using System.Text.Json; using TMDbLib.Client; @@ -35,7 +37,11 @@ // Add services to the container. -builder.Services.AddControllers(); +builder.Services.AddControllers().AddJsonOptions(options => +{ + options.JsonSerializerOptions.Converters.Add( + new MediaAddedJsonConverter()); +}); builder.Services.AddHealthChecks(); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi diff --git a/src/Proxarr.Api/Proxarr.Api.http b/src/Proxarr.Api/Proxarr.Api.http index 3fc4da3..9c68a69 100644 --- a/src/Proxarr.Api/Proxarr.Api.http +++ b/src/Proxarr.Api/Proxarr.Api.http @@ -4,7 +4,7 @@ ### Movie qualify endpoint -POST {{Proxarr.Api_HostAddress}}/api/qualifier/movie +POST {{Proxarr.Api_HostAddress}}/api/qualifier Content-Type: application/json Accept: application/json { @@ -49,7 +49,7 @@ Accept: application/json ### Movie qualify endpoint TEST -POST {{Proxarr.Api_HostAddress}}/api/qualifier/movie +POST {{Proxarr.Api_HostAddress}}/api/qualifier Content-Type: application/json Accept: application/json { @@ -86,7 +86,7 @@ Accept: application/json ### TV qualify endpoint -POST {{Proxarr.Api_HostAddress}}/api/qualifier/tv +POST {{Proxarr.Api_HostAddress}}/api/qualifier Content-Type: application/json Accept: application/json { @@ -143,7 +143,7 @@ Accept: application/json ### TV qualify endpoint TEST -POST {{Proxarr.Api_HostAddress}}/api/qualifier/tv +POST {{Proxarr.Api_HostAddress}}/api/qualifier Content-Type: application/json Accept: application/json { diff --git a/src/Proxarr.Api/Services/RadarrService.cs b/src/Proxarr.Api/Services/RadarrService.cs index e36964a..ff42223 100644 --- a/src/Proxarr.Api/Services/RadarrService.cs +++ b/src/Proxarr.Api/Services/RadarrService.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Options; using Proxarr.Api.Models; using Radarr.Http.Client; +using System.Globalization; using TMDbLib.Client; namespace Proxarr.Api.Services @@ -47,7 +48,7 @@ public async Task Qualify(MovieAdded movieAdded, CancellationToken cance await UpdateTags(tmdbItem, movieRadarr, cancellationToken).ConfigureAwait(false); await _radarrClient - .MoviePUTAsync(false, movieRadarr.Id.ToString(), movieRadarr, cancellationToken) + .MoviePUTAsync(false, movieRadarr.Id.ToString(CultureInfo.InvariantCulture), movieRadarr, cancellationToken) .ConfigureAwait(false); } diff --git a/src/Proxarr.Api/Services/SonarrService.cs b/src/Proxarr.Api/Services/SonarrService.cs index a6fca4a..be86e86 100644 --- a/src/Proxarr.Api/Services/SonarrService.cs +++ b/src/Proxarr.Api/Services/SonarrService.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Options; using Proxarr.Api.Models; using Sonarr.Http.Client; +using System.Globalization; using TMDbLib.Client; namespace Proxarr.Api.Services @@ -48,7 +49,7 @@ public async Task Qualify(TvAdded tvAdded, CancellationToken cancellatio await UpdateTags(tmdbItem, seriesSonarr, cancellationToken).ConfigureAwait(false); await _sonarrClient - .SeriesPUTAsync(false, seriesSonarr.Id.ToString(), seriesSonarr, cancellationToken) + .SeriesPUTAsync(false, seriesSonarr.Id.ToString(CultureInfo.InvariantCulture), seriesSonarr, cancellationToken) .ConfigureAwait(false); } diff --git a/src/Proxarr.Api/config.yml b/src/Proxarr.Api/config.yml index 018041b..50649be 100644 --- a/src/Proxarr.Api/config.yml +++ b/src/Proxarr.Api/config.yml @@ -17,7 +17,7 @@ Serilog: - Name: Console - Name: File Args: - path: "%LOG_FOLDER%/Serilog.log" + path: "%LOG_FOLDER%/log.log" rollingInterval: Day outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}" AllowedHosts: "*" diff --git a/src/Proxarr.sln b/src/Proxarr.sln index 0461925..5f3c14c 100644 --- a/src/Proxarr.sln +++ b/src/Proxarr.sln @@ -12,6 +12,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{07C8FD5B-2CFB-44CA-A0C8-FC456188447B}" ProjectSection(SolutionItems) = preProject ..\.dockerignore = ..\.dockerignore + .editorconfig = .editorconfig ..\.gitignore = ..\.gitignore ..\CONTRIBUTING.md = ..\CONTRIBUTING.md ..\docker-compose.yml = ..\docker-compose.yml