feat(sonarr): Add the username to a Sonarr tag when sent to Sonarr (#4802)

pull/4803/head
Jamie 2 years ago committed by GitHub
parent 40843fd6ac
commit 1d5fabd317
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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);
}
}
}

@ -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…
Cancel
Save