refactor(engine, controller, checkers, tests) Add more null checks, getting rid of NullReferenceException, remove repeat code

This commit is contained in:
lainon 2022-08-30 13:23:29 +03:00
commit afbd033a99
19 changed files with 130 additions and 126 deletions

View file

@ -32,7 +32,6 @@ namespace Ombi.Core.Tests.Engine
MusicRequestEngine = new Mock<IMusicRequestEngine>(); MusicRequestEngine = new Mock<IMusicRequestEngine>();
TvRequestEngine = new Mock<ITvRequestEngine>(); TvRequestEngine = new Mock<ITvRequestEngine>();
MovieRequestEngine = new Mock<IMovieRequestEngine>(); MovieRequestEngine = new Mock<IMovieRequestEngine>();
MovieRequestEngine = new Mock<IMovieRequestEngine>();
User = new Mock<ICurrentUser>(); User = new Mock<ICurrentUser>();
User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" }); User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" });

View file

@ -40,16 +40,16 @@ namespace Ombi.Core.Engine.Demo
{ {
var searchResult = await TvMazeApi.Search(search); var searchResult = await TvMazeApi.Search(search);
for (var i = 0; i < searchResult.Count; i++)
{
if (!_demoLists.TvShows.Contains(searchResult[i].show?.externals?.thetvdb ?? 0))
{
searchResult.RemoveAt(i);
}
}
if (searchResult != null) if (searchResult != null)
{ {
for (var i = 0; i < searchResult.Count; i++)
{
if (!_demoLists.TvShows.Contains(searchResult[i].show?.externals?.thetvdb ?? 0))
{
searchResult.RemoveAt(i);
}
}
var retVal = new List<SearchTvShowViewModel>(); var retVal = new List<SearchTvShowViewModel>();
foreach (var tvMazeSearch in searchResult) foreach (var tvMazeSearch in searchResult)
{ {

View file

@ -46,16 +46,15 @@ namespace Ombi.Core.Engine
{ {
_movieRepository = movieRepository; _movieRepository = movieRepository;
_userManager = userManager; _userManager = userManager;
_tvRepository = tvRepository;
_musicRepository = musicRepository;
_issuesRepository = issueRepo; _issuesRepository = issueRepo;
_issueCommentsRepository = issueCommentsRepo; _issueCommentsRepository = issueCommentsRepo;
_notificationRepository = notificationidsRepo;
_requestLogRepository = requestLogRepo; _requestLogRepository = requestLogRepo;
_requestSubscriptionRepository = requestSubRepository;
_notificationRepository = notificationidsRepo; _notificationRepository = notificationidsRepo;
_requestSubscriptionRepository = requestSubRepository;
_userNotificationPreferences = notificationPreferencesRepo; _userNotificationPreferences = notificationPreferencesRepo;
_userQualityProfiles = qualityProfilesRepo; _userQualityProfiles = qualityProfilesRepo;
_tvRepository = tvRepository;
_musicRepository = musicRepository;
_voteRepository = voteRepository; _voteRepository = voteRepository;
_mobileDevicesRepository = mobileDevicesRepository; _mobileDevicesRepository = mobileDevicesRepository;
_watchlistUserError = watchlistUserError; _watchlistUserError = watchlistUserError;

View file

@ -46,8 +46,8 @@ namespace Ombi.Core.Engine
TotalTvRequests = childrenCount, TotalTvRequests = childrenCount,
CompletedRequestsTv = availableChildren, CompletedRequestsTv = availableChildren,
CompletedRequestsMovies = availableMovies, CompletedRequestsMovies = availableMovies,
MostRequestedUserMovie = userMovie.FirstOrDefault()?.RequestedUser ?? new OmbiUser(), MostRequestedUserMovie = userMovie?.FirstOrDefault()?.RequestedUser ?? new OmbiUser(),
MostRequestedUserTv = userTv.FirstOrDefault()?.RequestedUser ?? new OmbiUser(), MostRequestedUserTv = userTv?.FirstOrDefault()?.RequestedUser ?? new OmbiUser(),
}; };
} }
} }

View file

@ -482,7 +482,7 @@ namespace Ombi.Core.Engine.V2
() => MovieApi.Find(imdbId, ExternalSource.imdb_id), DateTimeOffset.Now.AddHours(12)); () => MovieApi.Find(imdbId, ExternalSource.imdb_id), DateTimeOffset.Now.AddHours(12));
var movie = findResult.movie_results.FirstOrDefault(); var movie = findResult.movie_results.FirstOrDefault();
var movieInfo = await Cache.GetOrAddAsync(nameof(GetMovieInfoByImdbId) + movie.id + langCode, var movieInfo = await Cache.GetOrAddAsync(nameof(GetMovieInfoByImdbId) + movie?.id + langCode,
() => MovieApi.GetFullMovieInfo(movie.id, cancellationToken, langCode), DateTimeOffset.Now.AddHours(12)); () => MovieApi.GetFullMovieInfo(movie.id, cancellationToken, langCode), DateTimeOffset.Now.AddHours(12));
return await ProcessSingleMovie(movieInfo); return await ProcessSingleMovie(movieInfo);

View file

@ -84,7 +84,7 @@ namespace Ombi.Core.Rule
var ctor = ctors.FirstOrDefault(); var ctor = ctors.FirstOrDefault();
var services = new List<object>(); var services = new List<object>();
foreach (var param in ctor.GetParameters()) foreach (var param in ctor?.GetParameters())
{ {
services.Add(provider.GetService(param.ParameterType)); services.Add(provider.GetService(param.ParameterType));
} }
@ -106,7 +106,7 @@ namespace Ombi.Core.Rule
var ctor = ctors.FirstOrDefault(); var ctor = ctors.FirstOrDefault();
var services = new List<object>(); var services = new List<object>();
foreach (var param in ctor.GetParameters()) foreach (var param in ctor?.GetParameters())
{ {
services.Add(provider.GetService(param.ParameterType)); services.Add(provider.GetService(param.ParameterType));
} }

View file

@ -365,7 +365,7 @@ namespace Ombi.Core.Senders
// So we need to monitor the series but unmonitor every episode // So we need to monitor the series but unmonitor every episode
existingSeason.monitored = true; existingSeason.monitored = true;
var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber); var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber);
sea.monitored = true; sea?.monitored = true;
result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri);
var epToUnmonitored = new List<Episode>(); var epToUnmonitored = new List<Episode>();

View file

@ -21,7 +21,7 @@ namespace Ombi.Mapping.Profiles
.ForMember(dest => dest.ImdbId, opts => opts.MapFrom(src => src.ExternalIds.ImdbId)) .ForMember(dest => dest.ImdbId, opts => opts.MapFrom(src => src.ExternalIds.ImdbId))
.ForMember(dest => dest.TheTvDbId, opts => opts.MapFrom(src => src.ExternalIds.TvDbId)) .ForMember(dest => dest.TheTvDbId, opts => opts.MapFrom(src => src.ExternalIds.TvDbId))
.ForMember(dest => dest.Network, opts => opts.MapFrom(src => src.networks.FirstOrDefault())) .ForMember(dest => dest.Network, opts => opts.MapFrom(src => src.networks.FirstOrDefault()))
.ForMember(dest => dest.NetworkId, opts => opts.MapFrom(src => src.networks.FirstOrDefault()?.id)) .ForMember(dest => dest.NetworkId, opts => opts.MapFrom(src => src.networks.FirstOrDefault().id))
.ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.overview)) .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.overview))
.ForMember(dest => dest.Rating, .ForMember(dest => dest.Rating,
opts => opts.MapFrom(src => src.vote_average.ToString(CultureInfo.CurrentUICulture))) opts => opts.MapFrom(src => src.vote_average.ToString(CultureInfo.CurrentUICulture)))

View file

@ -277,7 +277,7 @@ namespace Ombi.Notifications.Agents
if (model.UserId.HasValue() && (!notificationIds?.Any() ?? true)) if (model.UserId.HasValue() && (!notificationIds?.Any() ?? true))
{ {
var user = _userManager.Users.Include(x => x.NotificationUserIds).FirstOrDefault(x => x.Id == model.UserId); var user = _userManager.Users.Include(x => x.NotificationUserIds).FirstOrDefault(x => x.Id == model.UserId);
notificationIds = user.NotificationUserIds; notificationIds = user?.NotificationUserIds;
} }
if (!notificationIds?.Any() ?? true) if (!notificationIds?.Any() ?? true)

View file

@ -25,7 +25,7 @@ namespace Ombi.Notifications
{ {
ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s.ApplicationName; ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s.ApplicationName;
ApplicationUrl = s?.ApplicationUrl.HasValue() ?? false ? s.ApplicationUrl : string.Empty; ApplicationUrl = s?.ApplicationUrl.HasValue() ?? false ? s.ApplicationUrl : string.Empty;
RequestedUser = user.UserName; RequestedUser = user?.UserName;
Alias = user.UserAlias; Alias = user.UserAlias;
UserName = user.UserName; UserName = user.UserName;
} }

View file

@ -70,7 +70,7 @@ namespace Ombi.Notifications
var ctor = ctors.FirstOrDefault(); var ctor = ctors.FirstOrDefault();
var services = new List<object>(); var services = new List<object>();
foreach (var param in ctor.GetParameters()) foreach (var param in ctor?.GetParameters())
{ {
services.Add(_provider.GetService(param.ParameterType)); services.Add(_provider.GetService(param.ParameterType));
} }

View file

@ -62,55 +62,58 @@ namespace Ombi.Schedule.Jobs.Emby
foreach (var movie in movies) foreach (var movie in movies)
{ {
var has4kRequest = movie.Has4KRequest; if (movie != null)
EmbyContent embyContent = null;
if (movie?.TheMovieDbId > 0)
{ {
embyContent = await _repo.GetByTheMovieDbId(movie.TheMovieDbId.ToString()); var has4kRequest = movie.Has4KRequest;
} EmbyContent embyContent = null;
else if(movie.ImdbId.HasValue()) if (movie?.TheMovieDbId > 0)
{
embyContent = await _repo.GetByImdbId(movie.ImdbId);
}
if (embyContent == null)
{
// We don't have this yet
continue;
}
_log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty);
var notify = false;
if (has4kRequest && embyContent.Has4K && !movie.Available4K)
{
movie.Available4K = true;
movie.MarkedAsAvailable4K = DateTime.Now;
notify = true;
}
// If we have a non-4k version or we don't care about versions, then mark as available
if (!movie.Available && ( !feature4kEnabled || embyContent.Quality != null ))
{
movie.Available = true;
movie.MarkedAsAvailable = DateTime.Now;
notify = true;
}
if (notify)
{
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
_log.LogDebug("MovieId: {0}, RequestUser: {1}", movie.Id, recipient);
await _notificationService.Notify(new NotificationOptions
{ {
DateTime = DateTime.Now, embyContent = await _repo.GetByTheMovieDbId(movie.TheMovieDbId.ToString());
NotificationType = NotificationType.RequestAvailable, }
RequestId = movie.Id, else if (movie.ImdbId.HasValue())
RequestType = RequestType.Movie, {
Recipient = recipient, embyContent = await _repo.GetByImdbId(movie.ImdbId);
}); }
if (embyContent == null)
{
// We don't have this yet
continue;
}
_log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty);
var notify = false;
if (has4kRequest && embyContent.Has4K && !movie.Available4K)
{
movie.Available4K = true;
movie.MarkedAsAvailable4K = DateTime.Now;
notify = true;
}
// If we have a non-4k version or we don't care about versions, then mark as available
if (!movie.Available && (!feature4kEnabled || embyContent.Quality != null))
{
movie.Available = true;
movie.MarkedAsAvailable = DateTime.Now;
notify = true;
}
if (notify)
{
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
_log.LogDebug("MovieId: {0}, RequestUser: {1}", movie.Id, recipient);
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
RequestId = movie.Id,
RequestType = RequestType.Movie,
Recipient = recipient,
});
}
} }
} }
await _movieRepo.Save(); await _movieRepo.Save();

View file

@ -87,56 +87,59 @@ namespace Ombi.Schedule.Jobs.Jellyfin
foreach (var movie in movies) foreach (var movie in movies)
{ {
var has4kRequest = movie.Has4KRequest; if (movie != null)
JellyfinContent jellyfinContent = null;
if (movie?.TheMovieDbId > 0)
{ {
jellyfinContent = await _repo.GetByTheMovieDbId(movie.TheMovieDbId.ToString()); var has4kRequest = movie.Has4KRequest;
} JellyfinContent jellyfinContent = null;
else if(movie.ImdbId.HasValue()) if (movie?.TheMovieDbId > 0)
{
jellyfinContent = await _repo.GetByImdbId(movie.ImdbId);
}
if (jellyfinContent == null)
{
// We don't have this yet
continue;
}
_log.LogInformation("We have found the request {0} on Jellyfin, sending the notification", movie?.Title ?? string.Empty);
var notify = false;
if (has4kRequest && jellyfinContent.Has4K && !movie.Available4K)
{
movie.Available4K = true;
movie.MarkedAsAvailable4K = DateTime.Now;
notify = true;
}
// If we have a non-4k version or we don't care about versions, then mark as available
if (!movie.Available && ( !feature4kEnabled || jellyfinContent.Quality != null ))
{
movie.Available = true;
movie.MarkedAsAvailable = DateTime.Now;
notify = true;
}
if (notify)
{
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
_log.LogDebug("MovieId: {0}, RequestUser: {1}", movie.Id, recipient);
await _notificationService.Notify(new NotificationOptions
{ {
DateTime = DateTime.Now, jellyfinContent = await _repo.GetByTheMovieDbId(movie.TheMovieDbId.ToString());
NotificationType = NotificationType.RequestAvailable, }
RequestId = movie.Id, else if (movie.ImdbId.HasValue())
RequestType = RequestType.Movie, {
Recipient = recipient, jellyfinContent = await _repo.GetByImdbId(movie.ImdbId);
}); }
if (jellyfinContent == null)
{
// We don't have this yet
continue;
}
_log.LogInformation("We have found the request {0} on Jellyfin, sending the notification", movie?.Title ?? string.Empty);
var notify = false;
if (has4kRequest && jellyfinContent.Has4K && !movie.Available4K)
{
movie.Available4K = true;
movie.MarkedAsAvailable4K = DateTime.Now;
notify = true;
}
// If we have a non-4k version or we don't care about versions, then mark as available
if (!movie.Available && (!feature4kEnabled || jellyfinContent.Quality != null))
{
movie.Available = true;
movie.MarkedAsAvailable = DateTime.Now;
notify = true;
}
if (notify)
{
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
_log.LogDebug("MovieId: {0}, RequestUser: {1}", movie.Id, recipient);
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
RequestId = movie.Id,
RequestType = RequestType.Movie,
Recipient = recipient,
});
}
} }
} }
await _movieRepo.Save(); await _movieRepo.Save();

View file

@ -294,7 +294,7 @@ namespace Ombi.Schedule.Jobs.Ombi
var guids = new List<string>(); var guids = new List<string>();
var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); var meta = metaData.MediaContainer.Metadata.FirstOrDefault();
guids.Add(meta.guid); guids.Add(meta?.guid);
if (meta.Guid != null) if (meta.Guid != null)
{ {
foreach (var g in meta.Guid) foreach (var g in meta.Guid)

View file

@ -354,7 +354,7 @@ namespace Ombi.Schedule.Jobs.Plex
movie.ratingKey); movie.ratingKey);
var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); var meta = metaData.MediaContainer.Metadata.FirstOrDefault();
guids.Add(meta.guid); guids.Add(meta?.guid);
if (meta.Guid != null) if (meta.Guid != null)
{ {
foreach (var g in meta.Guid) foreach (var g in meta.Guid)
@ -651,7 +651,7 @@ namespace Ombi.Schedule.Jobs.Plex
var metadata = showMetadata.MediaContainer.Metadata.FirstOrDefault(); var metadata = showMetadata.MediaContainer.Metadata.FirstOrDefault();
var guids = new List<string> var guids = new List<string>
{ {
metadata.guid metadata?.guid
}; };
if (metadata.Guid != null) if (metadata.Guid != null)
{ {

View file

@ -205,7 +205,7 @@ namespace Ombi.Schedule.Jobs.Plex
var metaData = await _plexApi.GetWatchlistMetadata(movie.ratingKey, authToken, cancellationToken); var metaData = await _plexApi.GetWatchlistMetadata(movie.ratingKey, authToken, cancellationToken);
var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); var meta = metaData.MediaContainer.Metadata.FirstOrDefault();
guids.Add(meta.guid); guids.Add(meta?.guid);
if (meta.Guid != null) if (meta.Guid != null)
{ {
foreach (var g in meta.Guid) foreach (var g in meta.Guid)

View file

@ -46,7 +46,7 @@ namespace Ombi.Controllers.V1.External
request.Enable = true; request.Enable = true;
var firstServer = request.Servers.FirstOrDefault(); var firstServer = request.Servers.FirstOrDefault();
// Test that we can connect // Test that we can connect
var result = await client.GetUsers(firstServer.FullUri, firstServer.ApiKey); var result = await client.GetUsers(firstServer?.FullUri, firstServer?.ApiKey);
if (result != null && result.Any()) if (result != null && result.Any())
{ {

View file

@ -47,7 +47,7 @@ namespace Ombi.Controllers.V1.External
request.Enable = true; request.Enable = true;
var firstServer = request.Servers.FirstOrDefault(); var firstServer = request.Servers.FirstOrDefault();
// Test that we can connect // Test that we can connect
var result = await client.GetUsers(firstServer.FullUri, firstServer.ApiKey); var result = await client.GetUsers(firstServer?.FullUri, firstServer?.ApiKey);
if (result != null && result.Any()) if (result != null && result.Any())
{ {

View file

@ -140,7 +140,7 @@ namespace Ombi.Controllers.V1.External
{ {
var s = await PlexSettings.GetSettingsAsync(); var s = await PlexSettings.GetSettingsAsync();
var settings = s.Servers.FirstOrDefault(x => x.MachineIdentifier == machineId); var settings = s.Servers.FirstOrDefault(x => x.MachineIdentifier == machineId);
var libs = await PlexApi.GetLibrariesForMachineId(settings.PlexAuthToken, machineId); var libs = await PlexApi.GetLibrariesForMachineId(settings?.PlexAuthToken, machineId);
return new PlexLibrariesLiteResponse return new PlexLibrariesLiteResponse
{ {
@ -167,7 +167,7 @@ namespace Ombi.Controllers.V1.External
{ {
var s = await PlexSettings.GetSettingsAsync(); var s = await PlexSettings.GetSettingsAsync();
var server = s.Servers.FirstOrDefault(x => x.MachineIdentifier == user.MachineIdentifier); var server = s.Servers.FirstOrDefault(x => x.MachineIdentifier == user.MachineIdentifier);
var result = await PlexApi.AddUser(user.Username, user.MachineIdentifier, server.PlexAuthToken, var result = await PlexApi.AddUser(user.Username, user.MachineIdentifier, server?.PlexAuthToken,
user.LibsSelected); user.LibsSelected);
if (result.HasError) if (result.HasError)
{ {