mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
feat(sonarr): ✨ Add the username to a Sonarr tag when sent to Sonarr (#4802)
This commit is contained in:
parent
40843fd6ac
commit
1d5fabd317
10 changed files with 103 additions and 12 deletions
|
@ -1,7 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Sonarr.Models;
|
||||
using System.Net.Http;
|
||||
using Ombi.Api.Sonarr.Models.V3;
|
||||
|
||||
namespace Ombi.Api.Sonarr
|
||||
|
@ -9,5 +8,7 @@ namespace Ombi.Api.Sonarr
|
|||
public interface ISonarrV3Api : ISonarrApi
|
||||
{
|
||||
Task<IEnumerable<LanguageProfiles>> LanguageProfiles(string apiKey, string baseUrl);
|
||||
Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName);
|
||||
Task<Tag> GetTag(int tagId, string apiKey, string baseUrl);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public string seriesType { get; set; }
|
||||
public int id { get; set; }
|
||||
public List<SonarrImage> images { get; set; }
|
||||
public List<int> tags { get; set; }
|
||||
|
||||
// V3 Property
|
||||
public int languageProfileId { get; set; }
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Ombi.Api.Sonarr.Models
|
|||
public string titleSlug { get; set; }
|
||||
public string certification { get; set; }
|
||||
public string[] genres { get; set; }
|
||||
public object[] tags { get; set; }
|
||||
public List<int> tags { get; set; }
|
||||
public DateTime added { get; set; }
|
||||
public Ratings ratings { get; set; }
|
||||
public int qualityProfileId { get; set; }
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace Ombi.Api.Sonarr
|
|||
{
|
||||
public SonarrV3Api(IApi api) : base(api)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override string ApiBaseUrl => "/api/v3/";
|
||||
|
@ -30,5 +29,22 @@ namespace Ombi.Api.Sonarr
|
|||
request.AddHeader("X-Api-Key", apiKey);
|
||||
return await Api.Request<List<SonarrProfile>>(request);
|
||||
}
|
||||
|
||||
public Task<Tag> CreateTag(string apiKey, string baseUrl, string tagName)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}tag", baseUrl, HttpMethod.Post);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
request.AddJsonBody(new { Label = tagName });
|
||||
|
||||
return Api.Request<Tag>(request);
|
||||
}
|
||||
|
||||
public Task<Tag> GetTag(int tagId, string apiKey, string baseUrl)
|
||||
{
|
||||
var request = new Request($"{ApiBaseUrl}tag/{tagId}", baseUrl, HttpMethod.Get);
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
|
||||
return Api.Request<Tag>(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/Ombi.Core/Senders/SonarrSendOptions.cs
Normal file
10
src/Ombi.Core/Senders/SonarrSendOptions.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Ombi.Api.Sonarr.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Core.Senders
|
||||
{
|
||||
internal class SonarrSendOptions
|
||||
{
|
||||
public List<int> Tags { get; set; } = new List<int>();
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.VisualBasic;
|
||||
using Ombi.Api.DogNzb;
|
||||
using Ombi.Api.DogNzb.Models;
|
||||
using Ombi.Api.SickRage;
|
||||
|
@ -155,11 +157,13 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
return null;
|
||||
}
|
||||
var options = new SonarrSendOptions();
|
||||
|
||||
int qualityToUse;
|
||||
var languageProfileId = s.LanguageProfile;
|
||||
string rootFolderPath;
|
||||
string seriesType;
|
||||
int? tagToUse = null;
|
||||
|
||||
var profiles = await UserQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId);
|
||||
|
||||
|
@ -190,6 +194,7 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
seriesType = "anime";
|
||||
tagToUse = s.AnimeTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -209,6 +214,7 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
seriesType = "standard";
|
||||
tagToUse = s.Tag;
|
||||
}
|
||||
|
||||
// Overrides on the request take priority
|
||||
|
@ -240,6 +246,16 @@ namespace Ombi.Core.Senders
|
|||
|
||||
try
|
||||
{
|
||||
if (tagToUse.HasValue)
|
||||
{
|
||||
options.Tags.Add(tagToUse.Value);
|
||||
}
|
||||
if (s.SendUserTags)
|
||||
{
|
||||
var userTag = await GetOrCreateTag(model, s);
|
||||
options.Tags.Add(userTag.id);
|
||||
}
|
||||
|
||||
// Does the series actually exist?
|
||||
var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri);
|
||||
var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId);
|
||||
|
@ -265,10 +281,10 @@ namespace Ombi.Core.Senders
|
|||
ignoreEpisodesWithoutFiles = false, // We want all missing
|
||||
searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly.
|
||||
},
|
||||
languageProfileId = languageProfileId
|
||||
};
|
||||
languageProfileId = languageProfileId,
|
||||
tags = options.Tags
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Montitor the correct seasons,
|
||||
// If we have that season in the model then it's monitored!
|
||||
|
@ -280,11 +296,11 @@ namespace Ombi.Core.Senders
|
|||
throw new Exception(string.Join(',', result.ErrorMessages));
|
||||
}
|
||||
existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri);
|
||||
await SendToSonarr(model, existingSeries, s);
|
||||
await SendToSonarr(model, existingSeries, s, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
await SendToSonarr(model, existingSeries, s);
|
||||
await SendToSonarr(model, existingSeries, s, options);
|
||||
}
|
||||
|
||||
return new NewSeries
|
||||
|
@ -303,7 +319,30 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
|
||||
private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s)
|
||||
private async Task<Tag> GetOrCreateTag(ChildRequests model, SonarrSettings s)
|
||||
{
|
||||
var tagName = model.RequestedUser.UserName;
|
||||
// Does tag exist?
|
||||
|
||||
var allTags = await SonarrV3Api.GetTags(s.ApiKey, s.FullUri);
|
||||
var existingTag = allTags.FirstOrDefault(x => x.label.Equals(tagName, StringComparison.InvariantCultureIgnoreCase));
|
||||
existingTag ??= await SonarrV3Api.CreateTag(s.ApiKey, s.FullUri, tagName);
|
||||
|
||||
return existingTag;
|
||||
}
|
||||
|
||||
private async Task<Tag> GetTag(int tagId, SonarrSettings s)
|
||||
{
|
||||
var tag = await SonarrV3Api.GetTag(tagId, s.ApiKey, s.FullUri);
|
||||
if (tag == null)
|
||||
{
|
||||
Logger.LogError($"Tag ID {tagId} does not exist in sonarr. Please update the settings");
|
||||
return null;
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s, SonarrSendOptions options)
|
||||
{
|
||||
// Check to ensure we have the all the seasons, ensure the Sonarr metadata has grabbed all the data
|
||||
Season existingSeason = null;
|
||||
|
@ -321,15 +360,27 @@ namespace Ombi.Core.Senders
|
|||
}
|
||||
}
|
||||
|
||||
var episodesToUpdate = new List<Episode>();
|
||||
// Ok, now let's sort out the episodes.
|
||||
// Does the show have the correct tags we are expecting
|
||||
if (options.Tags.Any())
|
||||
{
|
||||
result.tags ??= options.Tags;
|
||||
var tagsToAdd = options.Tags.Except(result.tags);
|
||||
|
||||
if (tagsToAdd.Any())
|
||||
{
|
||||
result.tags.AddRange(tagsToAdd);
|
||||
}
|
||||
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
}
|
||||
|
||||
if (model.SeriesType == SeriesType.Anime)
|
||||
{
|
||||
result.seriesType = "anime";
|
||||
await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
|
||||
}
|
||||
|
||||
var episodesToUpdate = new List<Episode>();
|
||||
// Ok, now let's sort out the episodes.
|
||||
var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri);
|
||||
var sonarrEpList = sonarrEpisodes.ToList() ?? new List<Episode>();
|
||||
while (!sonarrEpList.Any())
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
|
||||
public string QualityProfileAnime { get; set; }
|
||||
public string RootPathAnime { get; set; }
|
||||
public int? AnimeTag { get; set; }
|
||||
public int? Tag { get; set; }
|
||||
public bool AddOnly { get; set; }
|
||||
public int LanguageProfile { get; set; }
|
||||
public int LanguageProfileAnime { get; set; }
|
||||
public bool ScanForAvailability { get; set; }
|
||||
|
||||
public bool SendUserTags { get; set; }
|
||||
}
|
||||
}
|
|
@ -146,6 +146,9 @@ export interface ISonarrSettings extends IExternalSettings {
|
|||
languageProfile: number;
|
||||
languageProfileAnime: number;
|
||||
scanForAvailability: boolean;
|
||||
sendUserTags: boolean;
|
||||
tag: number | null;
|
||||
animeTag: number | null;
|
||||
}
|
||||
|
||||
export interface IRadarrSettings extends IExternalSettings {
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
<div class="md-form-field">
|
||||
<mat-slide-toggle formControlName="scanForAvailability">Scan for Availability</mat-slide-toggle>
|
||||
</div>
|
||||
<div class="md-form-field">
|
||||
<mat-slide-toggle formControlName="sendUserTags" id="sendUserTags">Add the user as a tag</mat-slide-toggle>
|
||||
<small><br>This will add the username of the requesting user as a tag in Sonarr. If the tag doesn't exist, Ombi will create it.</small>
|
||||
</div>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -75,6 +75,7 @@ export class SonarrComponent implements OnInit {
|
|||
languageProfile: [x.languageProfile, [Validators.required, validateProfile]],
|
||||
languageProfileAnime: [x.languageProfileAnime],
|
||||
scanForAvailability: [x.scanForAvailability],
|
||||
sendUserTags: [x.sendUserTags]
|
||||
});
|
||||
|
||||
if (x.qualityProfile) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue