Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Code refactoring: group endpoints into a single one
Browse files Browse the repository at this point in the history
Fazzani committed Dec 28, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent b3215ce commit f4163f1
Showing 15 changed files with 384 additions and 237 deletions.
328 changes: 165 additions & 163 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,164 +1,166 @@
<a id="readme-top"></a>
[![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)

<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/Fazzani/Proxarr">
<img src="images/logo.png" alt="Logo" width="320" height="320">
</a>

<p align="center">
Automatically categorize your requested movies and tv shows from your watching providers.
<br />
<a href="https://github.com/Fazzani/Proxarr/issues/new?labels=bug&template=bug-report.yml">:boom: Report Bug :boom:</a>
·
<a href="https://github.com/Fazzani/Proxarr/issues/new?labels=enhancement&template=feature-request.yml">:sparkles: Request Feature :sparkles:</a>
</p>
</div>

<!-- TABLE OF CONTENTS -->
<details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation-with-docker-compose">Installation with Docker compose</a></li>
</ul>
</li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
</ol>
</details>

<!-- ABOUT THE PROJECT -->
## 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.

<img src="images/workflow.gif" with="500" />

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- GETTING STARTED -->
## 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<br/>
<img src="images/arr_api_key.png" width="230">

### 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)<br/>
<img src="images/tagging-indexers.png" width="250" alt="tag indexers" />
- specify Application URL: is essential because it is used by Proxarr to determine which instance should return the response<br/>
<img src="images/application_url.png" width="250" alt="Application Url config"/>
- establish a Webhook connection between Sonarr/Radarr and Proxarr<br/>
<img src="images/webhook_config.png" width="250" alt="Application Url config"/><br/>
_Note_ : Webhook URL is `http://<Proxarr_Instance>/api/qualifier/tv` for Sonarr and `http://<Proxarr_Instance>/api/qualifier/movie` for Radarr
3. Add the following to your docker-compose.yml (to be adapted according to your stack)<br/>
[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
```

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

### 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 -->
## 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).

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- CONTRIBUTING -->
## 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:

<a href="https://github.com/Fazzani/Proxarr/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Fazzani/Proxarr" alt="contrib.rocks image" />
</a>

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- MARKDOWN LINKS & IMAGES -->
[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
<a id="readme-top"></a>
[![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)

<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/Fazzani/Proxarr">
<img src="images/logo.png" alt="Logo" width="320" height="320">
</a>

<p align="center">
Automatically categorize your requested movies and tv shows from your watching providers.
<br />
<a href="https://github.com/Fazzani/Proxarr/issues/new?labels=bug&template=bug-report.yml">:boom: Report Bug :boom:</a>
·
<a href="https://github.com/Fazzani/Proxarr/issues/new?labels=enhancement&template=feature-request.yml">:sparkles: Request Feature :sparkles:</a>
</p>
</div>

<!-- TABLE OF CONTENTS -->
<details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation-with-docker-compose">Installation with Docker compose</a></li>
</ul>
</li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
</ol>
</details>

<!-- ABOUT THE PROJECT -->
## 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.

<img src="images/workflow.gif" with="500" />

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- GETTING STARTED -->
## 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<br/>
<img src="images/arr_api_key.png" width="230">

### 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)<br/>
<img src="images/tagging-indexers.png" width="250" alt="tag indexers" />
- specify Application URL: is essential because it is used by Proxarr to determine which instance should return the response<br/>
<img src="images/application_url.png" width="250" alt="Application Url config"/>
- establish a Webhook connection between Sonarr/Radarr and Proxarr<br/>
<img src="images/webhook_config.png" width="250" alt="Application Url config"/><br/>
_Note_ : Webhook URL is `http://<Proxarr_Instance>/api/qualifier
3. Add the following to your docker-compose.yml (to be adapted according to your stack)<br/>
[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
```

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

### 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 -->
## 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).

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- CONTRIBUTING -->
## 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:

<a href="https://github.com/Fazzani/Proxarr/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Fazzani/Proxarr" alt="contrib.rocks image" />
</a>

<p align="right"><a href="#readme-top"><img src="images/back-to-top.png" alt="back to top" width="35" /></a></p>

<!-- MARKDOWN LINKS & IMAGES -->
[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
94 changes: 94 additions & 0 deletions src/.editorconfig
Original file line number Diff line number Diff line change
@@ -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)]
47 changes: 22 additions & 25 deletions src/Proxarr.Api/Controllers/QualifierController.cs
Original file line number Diff line number Diff line change
@@ -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<QualifierController> logger,
_sonarrService = sonarrService;
}

[HttpPost("movie")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> QualifiedMovie(MovieAdded movie, CancellationToken cancellationToken)
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> 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<IActionResult> 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();
}
}
39 changes: 39 additions & 0 deletions src/Proxarr.Api/Core/MediaAddedJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -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<MediaAdded>
{
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<MovieAdded>(root.GetRawText()) ?? throw new FormatException($"Malformed json content to deserialize {nameof(MovieAdded)} object");
}
else if (eventType?.Equals("SeriesAdd", StringComparison.OrdinalIgnoreCase) == true)
{
return JsonSerializer.Deserialize<TvAdded>(root.GetRawText()) ?? throw new FormatException($"Malformed json content to deserialize {nameof(TvAdded)} object");
}
else if (eventType?.Equals("test", StringComparison.OrdinalIgnoreCase) == true)
{
return JsonSerializer.Deserialize<MediaAdded>(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();
}
}
}
16 changes: 16 additions & 0 deletions src/Proxarr.Api/Models/Image.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
16 changes: 16 additions & 0 deletions src/Proxarr.Api/Models/MediaAdded.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
32 changes: 1 addition & 31 deletions src/Proxarr.Api/Models/MovieAdded.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
13 changes: 13 additions & 0 deletions src/Proxarr.Api/Models/Originallanguage.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
11 changes: 1 addition & 10 deletions src/Proxarr.Api/Models/TvAdded.cs
Original file line number Diff line number Diff line change
@@ -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
8 changes: 7 additions & 1 deletion src/Proxarr.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -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
8 changes: 4 additions & 4 deletions src/Proxarr.Api/Proxarr.Api.http
Original file line number Diff line number Diff line change
@@ -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
{
3 changes: 2 additions & 1 deletion src/Proxarr.Api/Services/RadarrService.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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);
}

3 changes: 2 additions & 1 deletion src/Proxarr.Api/Services/SonarrService.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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);
}

2 changes: 1 addition & 1 deletion src/Proxarr.Api/config.yml
Original file line number Diff line number Diff line change
@@ -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: "*"
1 change: 1 addition & 0 deletions src/Proxarr.sln
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f4163f1

Please sign in to comment.