fixed build and added logging

This commit is contained in:
TidusJar 2018-02-07 20:27:36 +00:00
parent 1ab8112c68
commit b223306ee8
12 changed files with 576 additions and 574 deletions

View file

@ -1,388 +1,388 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Ombi.Api.DogNzb; using Ombi.Api.DogNzb;
using Ombi.Api.DogNzb.Models; using Ombi.Api.DogNzb.Models;
using Ombi.Api.SickRage; using Ombi.Api.SickRage;
using Ombi.Api.SickRage.Models; using Ombi.Api.SickRage.Models;
using Ombi.Api.Sonarr; using Ombi.Api.Sonarr;
using Ombi.Api.Sonarr.Models; using Ombi.Api.Sonarr.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Settings.Settings.Models.External; using Ombi.Settings.Settings.Models.External;
using Ombi.Store.Entities.Requests; using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Senders namespace Ombi.Core.Senders
{ {
public class TvSender : ITvSender public class TvSender : ITvSender
{ {
public TvSender(ISonarrApi sonarrApi, ILogger<TvSender> log, ISettingsService<SonarrSettings> sonarrSettings, public TvSender(ISonarrApi sonarrApi, ILogger<TvSender> log, ISettingsService<SonarrSettings> sonarrSettings,
ISettingsService<DogNzbSettings> dog, IDogNzbApi dogApi, ISettingsService<SickRageSettings> srSettings, ISettingsService<DogNzbSettings> dog, IDogNzbApi dogApi, ISettingsService<SickRageSettings> srSettings,
ISickRageApi srApi) ISickRageApi srApi)
{ {
SonarrApi = sonarrApi; SonarrApi = sonarrApi;
Logger = log; Logger = log;
SonarrSettings = sonarrSettings; SonarrSettings = sonarrSettings;
DogNzbSettings = dog; DogNzbSettings = dog;
DogNzbApi = dogApi; DogNzbApi = dogApi;
SickRageSettings = srSettings; SickRageSettings = srSettings;
SickRageApi = srApi; SickRageApi = srApi;
} }
private ISonarrApi SonarrApi { get; } private ISonarrApi SonarrApi { get; }
private IDogNzbApi DogNzbApi { get; } private IDogNzbApi DogNzbApi { get; }
private ISickRageApi SickRageApi { get; } private ISickRageApi SickRageApi { get; }
private ILogger<TvSender> Logger { get; } private ILogger<TvSender> Logger { get; }
private ISettingsService<SonarrSettings> SonarrSettings { get; } private ISettingsService<SonarrSettings> SonarrSettings { get; }
private ISettingsService<DogNzbSettings> DogNzbSettings { get; } private ISettingsService<DogNzbSettings> DogNzbSettings { get; }
private ISettingsService<SickRageSettings> SickRageSettings { get; } private ISettingsService<SickRageSettings> SickRageSettings { get; }
public async Task<SenderResult> Send(ChildRequests model) public async Task<SenderResult> Send(ChildRequests model)
{ {
var sonarr = await SonarrSettings.GetSettingsAsync(); var sonarr = await SonarrSettings.GetSettingsAsync();
if (sonarr.Enabled) if (sonarr.Enabled)
{ {
var result = await SendToSonarr(model); var result = await SendToSonarr(model);
if (result != null) if (result != null)
{ {
return new SenderResult return new SenderResult
{ {
Sent = true, Sent = true,
Success = true Success = true
}; };
} }
} }
var dog = await DogNzbSettings.GetSettingsAsync(); var dog = await DogNzbSettings.GetSettingsAsync();
if (dog.Enabled) if (dog.Enabled)
{ {
var result = await SendToDogNzb(model, dog); var result = await SendToDogNzb(model, dog);
if (!result.Failure) if (!result.Failure)
{ {
return new SenderResult return new SenderResult
{ {
Sent = true, Sent = true,
Success = true Success = true
}; };
} }
return new SenderResult return new SenderResult
{ {
Message = result.ErrorMessage Message = result.ErrorMessage
}; };
} }
var sr = await SickRageSettings.GetSettingsAsync(); var sr = await SickRageSettings.GetSettingsAsync();
if (sr.Enabled) if (sr.Enabled)
{ {
var result = await SendToSickRage(model, sr); var result = await SendToSickRage(model, sr);
if (result) if (result)
{ {
return new SenderResult return new SenderResult
{ {
Sent = true, Sent = true,
Success = true Success = true
}; };
} }
return new SenderResult return new SenderResult
{ {
Message = "Could not send to SickRage!" Message = "Could not send to SickRage!"
}; };
} }
return new SenderResult return new SenderResult
{ {
Success = true Success = true
}; };
} }
private async Task<DogNzbAddResult> SendToDogNzb(ChildRequests model, DogNzbSettings settings) private async Task<DogNzbAddResult> SendToDogNzb(ChildRequests model, DogNzbSettings settings)
{ {
var id = model.ParentRequest.TvDbId; var id = model.ParentRequest.TvDbId;
return await DogNzbApi.AddTvShow(settings.ApiKey, id.ToString()); return await DogNzbApi.AddTvShow(settings.ApiKey, id.ToString());
} }
/// <summary> /// <summary>
/// Send the request to Sonarr to process /// Send the request to Sonarr to process
/// </summary> /// </summary>
/// <param name="s"></param> /// <param name="s"></param>
/// <param name="model"></param> /// <param name="model"></param>
/// <param name="qualityId">This is for any qualities overriden from the UI</param> /// <param name="qualityId">This is for any qualities overriden from the UI</param>
/// <returns></returns> /// <returns></returns>
public async Task<NewSeries> SendToSonarr(ChildRequests model, string qualityId = null) public async Task<NewSeries> SendToSonarr(ChildRequests model, string qualityId = null)
{ {
var s = await SonarrSettings.GetSettingsAsync(); var s = await SonarrSettings.GetSettingsAsync();
if (!s.Enabled) if (!s.Enabled)
{ {
return null; return null;
} }
if (string.IsNullOrEmpty(s.ApiKey)) if (string.IsNullOrEmpty(s.ApiKey))
{ {
return null; return null;
} }
var qualityProfile = 0; var qualityProfile = 0;
if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality
{ {
int.TryParse(qualityId, out qualityProfile); int.TryParse(qualityId, out qualityProfile);
} }
if (qualityProfile <= 0) if (qualityProfile <= 0)
{ {
int.TryParse(s.QualityProfile, out qualityProfile); int.TryParse(s.QualityProfile, out qualityProfile);
} }
// Get the root path from the rootfolder selected. // Get the root path from the rootfolder selected.
// For some reason, if we haven't got one use the first root folder in Sonarr // For some reason, if we haven't got one use the first root folder in Sonarr
// TODO make this overrideable via the UI // TODO make this overrideable via the UI
var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s); var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s);
try try
{ {
// Does the series actually exist? // Does the series actually exist?
var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri); var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri);
var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId); var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId);
if (existingSeries == null) if (existingSeries == null)
{ {
// Time to add a new one // Time to add a new one
var newSeries = new NewSeries var newSeries = new NewSeries
{ {
title = model.ParentRequest.Title, title = model.ParentRequest.Title,
imdbId = model.ParentRequest.ImdbId, imdbId = model.ParentRequest.ImdbId,
tvdbId = model.ParentRequest.TvDbId, tvdbId = model.ParentRequest.TvDbId,
cleanTitle = model.ParentRequest.Title, cleanTitle = model.ParentRequest.Title,
monitored = true, monitored = true,
seasonFolder = s.SeasonFolders, seasonFolder = s.SeasonFolders,
rootFolderPath = rootFolderPath, rootFolderPath = rootFolderPath,
qualityProfileId = qualityProfile, qualityProfileId = qualityProfile,
titleSlug = model.ParentRequest.Title, titleSlug = model.ParentRequest.Title,
addOptions = new AddOptions addOptions = new AddOptions
{ {
ignoreEpisodesWithFiles = true, // There shouldn't be any episodes with files, this is a new season ignoreEpisodesWithFiles = true, // There shouldn't be any episodes with files, this is a new season
ignoreEpisodesWithoutFiles = true, // We want all missing ignoreEpisodesWithoutFiles = true, // We want all missing
searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly. searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly.
} }
}; };
// Montitor the correct seasons, // Montitor the correct seasons,
// If we have that season in the model then it's monitored! // If we have that season in the model then it's monitored!
var seasonsToAdd = new List<Season>(); var seasonsToAdd = new List<Season>();
for (var i = 1; i < model.ParentRequest.TotalSeasons + 1; i++) for (var i = 1; i < model.ParentRequest.TotalSeasons + 1; i++)
{ {
var index = i; var index = i;
var season = new Season var season = new Season
{ {
seasonNumber = i, seasonNumber = i,
monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index) monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index)
}; };
seasonsToAdd.Add(season); seasonsToAdd.Add(season);
} }
newSeries.seasons = seasonsToAdd; newSeries.seasons = seasonsToAdd;
var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri); var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri);
existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri); existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri);
await SendToSonarr(model, existingSeries, s); await SendToSonarr(model, existingSeries, s);
} }
else else
{ {
await SendToSonarr(model, existingSeries, s); await SendToSonarr(model, existingSeries, s);
} }
return new NewSeries return new NewSeries
{ {
id = existingSeries.id, id = existingSeries.id,
seasons = existingSeries.seasons.ToList(), seasons = existingSeries.seasons.ToList(),
cleanTitle = existingSeries.cleanTitle, cleanTitle = existingSeries.cleanTitle,
title = existingSeries.title, title = existingSeries.title,
tvdbId = existingSeries.tvdbId tvdbId = existingSeries.tvdbId
}; };
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogError(LoggingEvents.SonarrSender, e, "Exception thrown when attempting to send series over to Sonarr"); Logger.LogError(LoggingEvents.SonarrSender, e, "Exception thrown when attempting to send series over to Sonarr");
throw; throw;
} }
} }
private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s) private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s)
{ {
var episodesToUpdate = new List<Episode>(); var episodesToUpdate = new List<Episode>();
// Ok, now let's sort out the episodes. // Ok, now let's sort out the episodes.
if (model.SeriesType == SeriesType.Anime) if (model.SeriesType == SeriesType.Anime)
{ {
result.seriesType = "anime"; result.seriesType = "anime";
await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
} }
var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri); var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri);
var sonarrEpList = sonarrEpisodes.ToList() ?? new List<Episode>(); var sonarrEpList = sonarrEpisodes.ToList() ?? new List<Episode>();
while (!sonarrEpList.Any()) while (!sonarrEpList.Any())
{ {
// It could be that the series metadata is not ready yet. So wait // It could be that the series metadata is not ready yet. So wait
sonarrEpList = (await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri)).ToList(); sonarrEpList = (await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri)).ToList();
await Task.Delay(500); await Task.Delay(500);
} }
foreach (var req in model.SeasonRequests) foreach (var req in model.SeasonRequests)
{ {
foreach (var ep in req.Episodes) foreach (var ep in req.Episodes)
{ {
var sonarrEp = sonarrEpList.FirstOrDefault(x => var sonarrEp = sonarrEpList.FirstOrDefault(x =>
x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == req.SeasonNumber); x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == req.SeasonNumber);
if (sonarrEp != null) if (sonarrEp != null)
{ {
sonarrEp.monitored = true; sonarrEp.monitored = true;
episodesToUpdate.Add(sonarrEp); episodesToUpdate.Add(sonarrEp);
} }
} }
} }
var seriesChanges = false; var seriesChanges = false;
foreach (var season in model.SeasonRequests) foreach (var season in model.SeasonRequests)
{ {
var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber); var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber);
var sonarrEpCount = sonarrSeason.Count(); var sonarrEpCount = sonarrSeason.Count();
var ourRequestCount = season.Episodes.Count; var ourRequestCount = season.Episodes.Count;
if (sonarrEpCount == ourRequestCount) if (sonarrEpCount == ourRequestCount)
{ {
// We have the same amount of requests as all of the episodes in the season. // We have the same amount of requests as all of the episodes in the season.
var existingSeason = var existingSeason =
result.seasons.First(x => x.seasonNumber == season.SeasonNumber); result.seasons.First(x => x.seasonNumber == season.SeasonNumber);
existingSeason.monitored = true; existingSeason.monitored = true;
seriesChanges = true; seriesChanges = true;
} }
else else
{ {
// Now update the episodes that need updating // Now update the episodes that need updating
foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber))
{ {
await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri);
} }
} }
} }
if (seriesChanges) if (seriesChanges)
{ {
await SonarrApi.SeasonPass(s.ApiKey, s.FullUri, result); await SonarrApi.SeasonPass(s.ApiKey, s.FullUri, result);
} }
if (!s.AddOnly) if (!s.AddOnly)
{ {
await SearchForRequest(model, sonarrEpList, result, s, episodesToUpdate); await SearchForRequest(model, sonarrEpList, result, s, episodesToUpdate);
} }
} }
private async Task<bool> SendToSickRage(ChildRequests model, SickRageSettings settings, string qualityId = null) private async Task<bool> SendToSickRage(ChildRequests model, SickRageSettings settings, string qualityId = null)
{ {
var tvdbid = model.ParentRequest.TvDbId; var tvdbid = model.ParentRequest.TvDbId;
if (qualityId.HasValue()) if (qualityId.HasValue())
{ {
var id = qualityId; var id = qualityId;
if (settings.Qualities.All(x => x.Value != id)) if (settings.Qualities.All(x => x.Value != id))
{ {
qualityId = settings.QualityProfile; qualityId = settings.QualityProfile;
} }
} }
else else
{ {
qualityId = settings.QualityProfile; qualityId = settings.QualityProfile;
} }
// Check if the show exists // Check if the show exists
var existingShow = await SickRageApi.GetShow(tvdbid, settings.ApiKey, settings.FullUri); var existingShow = await SickRageApi.GetShow(tvdbid, settings.ApiKey, settings.FullUri);
if (existingShow.message.Equals("Show not found", StringComparison.CurrentCultureIgnoreCase)) if (existingShow.message.Equals("Show not found", StringComparison.CurrentCultureIgnoreCase))
{ {
var addResult = await SickRageApi.AddSeries(model.ParentRequest.TvDbId, qualityId, SickRageStatus.Ignored, var addResult = await SickRageApi.AddSeries(model.ParentRequest.TvDbId, qualityId, SickRageStatus.Ignored,
settings.ApiKey, settings.FullUri); settings.ApiKey, settings.FullUri);
Logger.LogDebug("Added the show (tvdbid) {0}. The result is '{2}' : '{3}'", tvdbid, addResult.result, addResult.message); Logger.LogDebug("Added the show (tvdbid) {0}. The result is '{2}' : '{3}'", tvdbid, addResult.result, addResult.message);
if (addResult.result.Equals("failure") || addResult.result.Equals("fatal")) if (addResult.result.Equals("failure") || addResult.result.Equals("fatal"))
{ {
// Do something // Do something
return false; return false;
} }
} }
foreach (var seasonRequests in model.SeasonRequests) foreach (var seasonRequests in model.SeasonRequests)
{ {
var srEpisodes = await SickRageApi.GetEpisodesForSeason(tvdbid, seasonRequests.SeasonNumber, settings.ApiKey, settings.FullUri); var srEpisodes = await SickRageApi.GetEpisodesForSeason(tvdbid, seasonRequests.SeasonNumber, settings.ApiKey, settings.FullUri);
while (srEpisodes.message.Equals("Show not found", StringComparison.CurrentCultureIgnoreCase) && srEpisodes.data.Count <= 0) while (srEpisodes.message.Equals("Show not found", StringComparison.CurrentCultureIgnoreCase) && srEpisodes.data.Count <= 0)
{ {
await Task.Delay(TimeSpan.FromSeconds(1)); await Task.Delay(TimeSpan.FromSeconds(1));
srEpisodes = await SickRageApi.GetEpisodesForSeason(tvdbid, seasonRequests.SeasonNumber, settings.ApiKey, settings.FullUri); srEpisodes = await SickRageApi.GetEpisodesForSeason(tvdbid, seasonRequests.SeasonNumber, settings.ApiKey, settings.FullUri);
} }
var totalSrEpisodes = srEpisodes.data.Count; var totalSrEpisodes = srEpisodes.data.Count;
if (totalSrEpisodes == seasonRequests.Episodes.Count) if (totalSrEpisodes == seasonRequests.Episodes.Count)
{ {
// This is a request for the whole season // This is a request for the whole season
var wholeSeasonResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid, SickRageStatus.Wanted, var wholeSeasonResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid, SickRageStatus.Wanted,
seasonRequests.SeasonNumber); seasonRequests.SeasonNumber);
Logger.LogDebug("Set the status to Wanted for season {0}. The result is '{1}' : '{2}'", seasonRequests.SeasonNumber, wholeSeasonResult.result, wholeSeasonResult.message); Logger.LogDebug("Set the status to Wanted for season {0}. The result is '{1}' : '{2}'", seasonRequests.SeasonNumber, wholeSeasonResult.result, wholeSeasonResult.message);
continue; continue;
} }
foreach (var srEp in srEpisodes.data) foreach (var srEp in srEpisodes.data)
{ {
var epNumber = srEp.Key; var epNumber = srEp.Key;
var epData = srEp.Value; var epData = srEp.Value;
var epRequest = seasonRequests.Episodes.FirstOrDefault(x => x.EpisodeNumber == epNumber); var epRequest = seasonRequests.Episodes.FirstOrDefault(x => x.EpisodeNumber == epNumber);
if (epRequest != null) if (epRequest != null)
{ {
// We want to monior this episode since we have a request for it // We want to monior this episode since we have a request for it
// Let's check to see if it's wanted first, save an api call // Let's check to see if it's wanted first, save an api call
if (epData.status.Equals(SickRageStatus.Wanted, StringComparison.CurrentCultureIgnoreCase)) if (epData.status.Equals(SickRageStatus.Wanted, StringComparison.CurrentCultureIgnoreCase))
{ {
continue; continue;
} }
var epResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid, var epResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid,
SickRageStatus.Wanted, seasonRequests.SeasonNumber, epNumber); SickRageStatus.Wanted, seasonRequests.SeasonNumber, epNumber);
Logger.LogDebug("Set the status to Wanted for Episode {0} in season {1}. The result is '{2}' : '{3}'", seasonRequests.SeasonNumber, epNumber, epResult.result, epResult.message); Logger.LogDebug("Set the status to Wanted for Episode {0} in season {1}. The result is '{2}' : '{3}'", seasonRequests.SeasonNumber, epNumber, epResult.result, epResult.message);
} }
} }
} }
return true; return true;
} }
private async Task SearchForRequest(ChildRequests model, IEnumerable<Episode> sonarrEpList, SonarrSeries existingSeries, SonarrSettings s, private async Task SearchForRequest(ChildRequests model, IEnumerable<Episode> sonarrEpList, SonarrSeries existingSeries, SonarrSettings s,
IReadOnlyCollection<Episode> episodesToUpdate) IReadOnlyCollection<Episode> episodesToUpdate)
{ {
foreach (var season in model.SeasonRequests) foreach (var season in model.SeasonRequests)
{ {
var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber); var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber);
var sonarrEpCount = sonarrSeason.Count(); var sonarrEpCount = sonarrSeason.Count();
var ourRequestCount = season.Episodes.Count; var ourRequestCount = season.Episodes.Count;
if (sonarrEpCount == ourRequestCount) if (sonarrEpCount == ourRequestCount)
{ {
// We have the same amount of requests as all of the episodes in the season. // We have the same amount of requests as all of the episodes in the season.
// Do a season search // Do a season search
await SonarrApi.SeasonSearch(existingSeries.id, season.SeasonNumber, s.ApiKey, s.FullUri); await SonarrApi.SeasonSearch(existingSeries.id, season.SeasonNumber, s.ApiKey, s.FullUri);
} }
else else
{ {
// There is a miss-match, let's search the episodes indiviaully // There is a miss-match, let's search the episodes indiviaully
await SonarrApi.EpisodeSearch(episodesToUpdate.Select(x => x.id).ToArray(), s.ApiKey, s.FullUri); await SonarrApi.EpisodeSearch(episodesToUpdate.Select(x => x.id).ToArray(), s.ApiKey, s.FullUri);
} }
} }
} }
private async Task<string> GetSonarrRootPath(int pathId, SonarrSettings sonarrSettings) private async Task<string> GetSonarrRootPath(int pathId, SonarrSettings sonarrSettings)
{ {
var rootFoldersResult = await SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri); var rootFoldersResult = await SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri);
if (pathId == 0) if (pathId == 0)
{ {
return rootFoldersResult.FirstOrDefault().path; return rootFoldersResult.FirstOrDefault().path;
} }
foreach (var r in rootFoldersResult.Where(r => r.id == pathId)) foreach (var r in rootFoldersResult.Where(r => r.id == pathId))
{ {
return r.path; return r.path;
} }
return string.Empty; return string.Empty;
} }
} }
} }

View file

@ -18,7 +18,10 @@ namespace Ombi.Notifications.Agents
{ {
public class DiscordNotification : BaseNotification<DiscordNotificationSettings>, IDiscordNotification public class DiscordNotification : BaseNotification<DiscordNotificationSettings>, IDiscordNotification
{ {
public DiscordNotification(IDiscordApi api, ISettingsService<DiscordNotificationSettings> sn, ILogger<DiscordNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s) public DiscordNotification(IDiscordApi api, ISettingsService<DiscordNotificationSettings> sn,
ILogger<DiscordNotification> log, INotificationTemplatesRepository r,
IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s)
: base(sn, r, m, t,s,log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;

View file

@ -19,7 +19,7 @@ namespace Ombi.Notifications.Agents
public class EmailNotification : BaseNotification<EmailNotificationSettings>, IEmailNotification public class EmailNotification : BaseNotification<EmailNotificationSettings>, IEmailNotification
{ {
public EmailNotification(ISettingsService<EmailNotificationSettings> settings, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, IEmailProvider prov, ISettingsService<CustomizationSettings> c, public EmailNotification(ISettingsService<EmailNotificationSettings> settings, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, IEmailProvider prov, ISettingsService<CustomizationSettings> c,
ILogger<EmailNotification> log) : base(settings, r, m, t, c) ILogger<EmailNotification> log) : base(settings, r, m, t, c,log)
{ {
EmailProvider = prov; EmailProvider = prov;
Logger = log; Logger = log;

View file

@ -21,7 +21,7 @@ namespace Ombi.Notifications.Agents
public class MattermostNotification : BaseNotification<MattermostNotificationSettings>, IMattermostNotification public class MattermostNotification : BaseNotification<MattermostNotificationSettings>, IMattermostNotification
{ {
public MattermostNotification(IMattermostApi api, ISettingsService<MattermostNotificationSettings> sn, ILogger<MattermostNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, public MattermostNotification(IMattermostApi api, ISettingsService<MattermostNotificationSettings> sn, ILogger<MattermostNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s) ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s,log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;

View file

@ -22,7 +22,7 @@ namespace Ombi.Notifications.Agents
{ {
public MobileNotification(IOneSignalApi api, ISettingsService<MobileNotificationSettings> sn, ILogger<MobileNotification> log, INotificationTemplatesRepository r, public MobileNotification(IOneSignalApi api, ISettingsService<MobileNotificationSettings> sn, ILogger<MobileNotification> log, INotificationTemplatesRepository r,
IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s, IRepository<NotificationUserId> notification, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s, IRepository<NotificationUserId> notification,
UserManager<OmbiUser> um) : base(sn, r, m, t, s) UserManager<OmbiUser> um) : base(sn, r, m, t, s,log)
{ {
_api = api; _api = api;
_logger = log; _logger = log;

View file

@ -17,7 +17,7 @@ namespace Ombi.Notifications.Agents
public class PushbulletNotification : BaseNotification<PushbulletSettings>, IPushbulletNotification public class PushbulletNotification : BaseNotification<PushbulletSettings>, IPushbulletNotification
{ {
public PushbulletNotification(IPushbulletApi api, ISettingsService<PushbulletSettings> sn, ILogger<PushbulletNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, public PushbulletNotification(IPushbulletApi api, ISettingsService<PushbulletSettings> sn, ILogger<PushbulletNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s) ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s,log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;

View file

@ -17,8 +17,8 @@ namespace Ombi.Notifications.Agents
{ {
public class PushoverNotification : BaseNotification<PushoverSettings>, IPushoverNotification public class PushoverNotification : BaseNotification<PushoverSettings>, IPushoverNotification
{ {
public PushoverNotification(IPushoverApi api, ISettingsService<PushoverSettings> sn, ILogger<PushbulletNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, public PushoverNotification(IPushoverApi api, ISettingsService<PushoverSettings> sn, ILogger<PushoverNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
ISettingsService<CustomizationSettings> s) : base(sn, r, m, t, s) ISettingsService<CustomizationSettings> s) : base(sn, r, m, t, s, log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;
@ -27,7 +27,7 @@ namespace Ombi.Notifications.Agents
public override string NotificationName => "PushoverNotification"; public override string NotificationName => "PushoverNotification";
private IPushoverApi Api { get; } private IPushoverApi Api { get; }
private ILogger<PushbulletNotification> Logger { get; } private ILogger<PushoverNotification> Logger { get; }
protected override bool ValidateConfiguration(PushoverSettings settings) protected override bool ValidateConfiguration(PushoverSettings settings)
{ {

View file

@ -18,7 +18,7 @@ namespace Ombi.Notifications.Agents
public class SlackNotification : BaseNotification<SlackNotificationSettings>, ISlackNotification public class SlackNotification : BaseNotification<SlackNotificationSettings>, ISlackNotification
{ {
public SlackNotification(ISlackApi api, ISettingsService<SlackNotificationSettings> sn, ILogger<SlackNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, public SlackNotification(ISlackApi api, ISettingsService<SlackNotificationSettings> sn, ILogger<SlackNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
ISettingsService<CustomizationSettings> s) : base(sn, r, m, t, s) ISettingsService<CustomizationSettings> s) : base(sn, r, m, t, s, log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;

View file

@ -16,7 +16,9 @@ namespace Ombi.Notifications.Agents
{ {
public class TelegramNotification : BaseNotification<TelegramSettings>, ITelegramNotification public class TelegramNotification : BaseNotification<TelegramSettings>, ITelegramNotification
{ {
public TelegramNotification(ITelegramApi api, ISettingsService<TelegramSettings> sn, ILogger<TelegramNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s) public TelegramNotification(ITelegramApi api, ISettingsService<TelegramSettings> sn, ILogger<TelegramNotification> log,
INotificationTemplatesRepository r, IMovieRequestRepository m,
ITvRequestRepository t, ISettingsService<CustomizationSettings> s) : base(sn, r, m, t,s,log)
{ {
Api = api; Api = api;
Logger = log; Logger = log;

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Notifications.Exceptions; using Ombi.Notifications.Exceptions;
@ -16,7 +17,7 @@ namespace Ombi.Notifications.Interfaces
public abstract class BaseNotification<T> : INotification where T : Settings.Settings.Models.Settings, new() public abstract class BaseNotification<T> : INotification where T : Settings.Settings.Models.Settings, new()
{ {
protected BaseNotification(ISettingsService<T> settings, INotificationTemplatesRepository templateRepo, IMovieRequestRepository movie, ITvRequestRepository tv, protected BaseNotification(ISettingsService<T> settings, INotificationTemplatesRepository templateRepo, IMovieRequestRepository movie, ITvRequestRepository tv,
ISettingsService<CustomizationSettings> customization) ISettingsService<CustomizationSettings> customization, ILogger<BaseNotification<T>> log)
{ {
Settings = settings; Settings = settings;
TemplateRepository = templateRepo; TemplateRepository = templateRepo;
@ -25,6 +26,7 @@ namespace Ombi.Notifications.Interfaces
CustomizationSettings = customization; CustomizationSettings = customization;
Settings.ClearCache(); Settings.ClearCache();
CustomizationSettings.ClearCache(); CustomizationSettings.ClearCache();
_log = log;
} }
protected ISettingsService<T> Settings { get; } protected ISettingsService<T> Settings { get; }
@ -33,6 +35,7 @@ namespace Ombi.Notifications.Interfaces
protected ITvRequestRepository TvRepository { get; } protected ITvRequestRepository TvRepository { get; }
protected CustomizationSettings Customization { get; set; } protected CustomizationSettings Customization { get; set; }
private ISettingsService<CustomizationSettings> CustomizationSettings { get; } private ISettingsService<CustomizationSettings> CustomizationSettings { get; }
private readonly ILogger<BaseNotification<T>> _log;
protected ChildRequests TvRequest { get; set; } protected ChildRequests TvRequest { get; set; }
@ -159,10 +162,13 @@ namespace Ombi.Notifications.Interfaces
var curlys = new NotificationMessageCurlys(); var curlys = new NotificationMessageCurlys();
if (model.RequestType == RequestType.Movie) if (model.RequestType == RequestType.Movie)
{ {
_log.LogDebug("Notification options: {@model}, Req: {@MovieRequest}, Settings: {@Customization}", model, MovieRequest, Customization);
curlys.Setup(model, MovieRequest, Customization); curlys.Setup(model, MovieRequest, Customization);
} }
else else
{ {
_log.LogDebug("Notification options: {@model}, Req: {@TvRequest}, Settings: {@Customization}", model, TvRequest, Customization);
curlys.Setup(model, TvRequest, Customization); curlys.Setup(model, TvRequest, Customization);
} }
var parsed = resolver.ParseMessage(template, curlys); var parsed = resolver.ParseMessage(template, curlys);

View file

@ -11,16 +11,8 @@ namespace Ombi.Notifications
{ {
public class NotificationMessageCurlys public class NotificationMessageCurlys
{ {
public NotificationMessageCurlys(ILogger<NotificationMessageCurlys> log)
{
_log = log;
}
private readonly ILogger<NotificationMessageCurlys> _log;
public void Setup(NotificationOptions opts, FullBaseRequest req, CustomizationSettings s) public void Setup(NotificationOptions opts, FullBaseRequest req, CustomizationSettings s)
{ {
_log.LogDebug("Notification options: {@Opts}, Req: {@Req}, Settings: {@S}", opts, req, s);
ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty; ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty;
ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName; ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName;
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias) RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
@ -39,8 +31,7 @@ namespace Ombi.Notifications
public void Setup(NotificationOptions opts, ChildRequests req, CustomizationSettings s) public void Setup(NotificationOptions opts, ChildRequests req, CustomizationSettings s)
{ {
_log.LogDebug("Notification options: {@Opts}, Req: {@Req}, Settings: {@S}", opts, req, s); ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty;
ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty;
ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName; ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName;
RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias) RequestedUser = string.IsNullOrEmpty(req.RequestedUser.Alias)
? req.RequestedUser.UserName ? req.RequestedUser.UserName

View file

@ -1,167 +1,167 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire; using Hangfire;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Ombi.Core.Notifications; using Ombi.Core.Notifications;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using Ombi.Store.Repository; using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests; using Ombi.Store.Repository.Requests;
namespace Ombi.Schedule.Jobs.Plex namespace Ombi.Schedule.Jobs.Plex
{ {
public class PlexAvailabilityChecker : IPlexAvailabilityChecker public class PlexAvailabilityChecker : IPlexAvailabilityChecker
{ {
public PlexAvailabilityChecker(IPlexContentRepository repo, ITvRequestRepository tvRequest, IMovieRequestRepository movies, public PlexAvailabilityChecker(IPlexContentRepository repo, ITvRequestRepository tvRequest, IMovieRequestRepository movies,
INotificationService notification, IBackgroundJobClient background) INotificationService notification, IBackgroundJobClient background)
{ {
_tvRepo = tvRequest; _tvRepo = tvRequest;
_repo = repo; _repo = repo;
_movieRepo = movies; _movieRepo = movies;
_notificationService = notification; _notificationService = notification;
_backgroundJobClient = background; _backgroundJobClient = background;
} }
private readonly ITvRequestRepository _tvRepo; private readonly ITvRequestRepository _tvRepo;
private readonly IMovieRequestRepository _movieRepo; private readonly IMovieRequestRepository _movieRepo;
private readonly IPlexContentRepository _repo; private readonly IPlexContentRepository _repo;
private readonly INotificationService _notificationService; private readonly INotificationService _notificationService;
private readonly IBackgroundJobClient _backgroundJobClient; private readonly IBackgroundJobClient _backgroundJobClient;
public async Task Start() public async Task Start()
{ {
await ProcessMovies(); await ProcessMovies();
await ProcessTv(); await ProcessTv();
} }
private async Task ProcessTv() private async Task ProcessTv()
{ {
var tv = _tvRepo.GetChild().Where(x => !x.Available); var tv = _tvRepo.GetChild().Where(x => !x.Available);
var plexEpisodes = _repo.GetAllEpisodes().Include(x => x.Series); var plexEpisodes = _repo.GetAllEpisodes().Include(x => x.Series);
foreach (var child in tv) foreach (var child in tv)
{ {
var useImdb = false; var useImdb = false;
var useTvDb = false; var useTvDb = false;
if (child.ParentRequest.ImdbId.HasValue()) if (child.ParentRequest.ImdbId.HasValue())
{ {
useImdb = true; useImdb = true;
} }
if (child.ParentRequest.TvDbId.ToString().HasValue()) if (child.ParentRequest.TvDbId.ToString().HasValue())
{ {
useTvDb = true; useTvDb = true;
} }
var tvDbId = child.ParentRequest.TvDbId; var tvDbId = child.ParentRequest.TvDbId;
var imdbId = child.ParentRequest.ImdbId; var imdbId = child.ParentRequest.ImdbId;
IQueryable<PlexEpisode> seriesEpisodes = null; IQueryable<PlexEpisode> seriesEpisodes = null;
if (useImdb) if (useImdb)
{ {
seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
} }
if (useTvDb) if (useTvDb)
{ {
seriesEpisodes = plexEpisodes.Where(x => x.Series.TvDbId == tvDbId.ToString()); seriesEpisodes = plexEpisodes.Where(x => x.Series.TvDbId == tvDbId.ToString());
} }
foreach (var season in child.SeasonRequests) foreach (var season in child.SeasonRequests)
{ {
foreach (var episode in season.Episodes) foreach (var episode in season.Episodes)
{ {
var foundEp = await seriesEpisodes.FirstOrDefaultAsync( var foundEp = await seriesEpisodes.FirstOrDefaultAsync(
x => x.EpisodeNumber == episode.EpisodeNumber && x => x.EpisodeNumber == episode.EpisodeNumber &&
x.SeasonNumber == episode.Season.SeasonNumber); x.SeasonNumber == episode.Season.SeasonNumber);
if (foundEp != null) if (foundEp != null)
{ {
episode.Available = true; episode.Available = true;
} }
} }
} }
// Check to see if all of the episodes in all seasons are available for this request // Check to see if all of the episodes in all seasons are available for this request
var allAvailable = child.SeasonRequests.All(x => x.Episodes.All(c => c.Available)); var allAvailable = child.SeasonRequests.All(x => x.Episodes.All(c => c.Available));
if (allAvailable) if (allAvailable)
{ {
// We have fulfulled this request! // We have fulfulled this request!
child.Available = true; child.Available = true;
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions _backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
{ {
DateTime = DateTime.Now, DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable, NotificationType = NotificationType.RequestAvailable,
RequestId = child.ParentRequestId, RequestId = child.ParentRequestId,
RequestType = RequestType.TvShow, RequestType = RequestType.TvShow,
Recipient = child.RequestedUser.Email Recipient = child.RequestedUser.Email
})); }));
} }
} }
await _tvRepo.Save(); await _tvRepo.Save();
} }
private async Task ProcessMovies() private async Task ProcessMovies()
{ {
// Get all non available // Get all non available
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
foreach (var movie in movies) foreach (var movie in movies)
{ {
PlexServerContent item = null; PlexServerContent item = null;
if (movie.ImdbId.HasValue()) if (movie.ImdbId.HasValue())
{ {
item = await _repo.Get(movie.ImdbId); item = await _repo.Get(movie.ImdbId);
} }
if (item == null) if (item == null)
{ {
if (movie.TheMovieDbId.ToString().HasValue()) if (movie.TheMovieDbId.ToString().HasValue())
{ {
item = await _repo.Get(movie.TheMovieDbId.ToString()); item = await _repo.Get(movie.TheMovieDbId.ToString());
} }
} }
if (item == null) if (item == null)
{ {
// We don't yet have this // We don't yet have this
continue; continue;
} }
movie.Available = true; movie.Available = true;
if (movie.Available) if (movie.Available)
{ {
_backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions _backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions
{ {
DateTime = DateTime.Now, DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable, NotificationType = NotificationType.RequestAvailable,
RequestId = movie.Id, RequestId = movie.Id,
RequestType = RequestType.Movie, RequestType = RequestType.Movie,
Recipient = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty Recipient = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty
})); }));
} }
} }
await _movieRepo.Save(); await _movieRepo.Save();
} }
private bool _disposed; private bool _disposed;
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (_disposed) if (_disposed)
return; return;
if (disposing) if (disposing)
{ {
_movieRepo?.Dispose(); _movieRepo?.Dispose();
_repo?.Dispose(); _repo?.Dispose();
} }
_disposed = true; _disposed = true;
} }
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
} }
} }