Merge branch 'develop' of https://github.com/tidusjar/Ombi into develop

pull/2142/head
Jamie Rees 7 years ago
commit 0e248ed397

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@ version: 3.0.{build}
configuration: Release
os: Visual Studio 2017
environment:
nodejs_version: "7.8.0"
nodejs_version: "Current"
install:
# Get the latest stable version of Node.js or io.js

@ -25,7 +25,7 @@ namespace Ombi.Core.Tests.Rule.Search
[Test]
public async Task Movie_ShouldBe_Available_WhenFoundInEmby()
{
ContextMock.Setup(x => x.Get(It.IsAny<string>())).ReturnsAsync(new EmbyContent
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
{
ProviderId = "123"
});
@ -39,7 +39,7 @@ namespace Ombi.Core.Tests.Rule.Search
[Test]
public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby()
{
ContextMock.Setup(x => x.Get(It.IsAny<string>())).Returns(Task.FromResult(default(EmbyContent)));
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).Returns(Task.FromResult(default(EmbyContent)));
var search = new SearchMovieViewModel();
var result = await Rule.Execute(search);

@ -152,7 +152,9 @@ namespace Ombi.Core.Engine
model.Add(new RecentlyAddedMovieModel
{
Id = emby.Id,
ImdbId = emby.ProviderId,
ImdbId = emby.ImdbId,
TheMovieDbId = emby.TheMovieDbId,
TvDbId = emby.TvDbId,
AddedAt = emby.AddedAt,
Title = emby.Title,
});
@ -211,7 +213,9 @@ namespace Ombi.Core.Engine
model.Add(new RecentlyAddedTvModel
{
Id = emby.Id,
ImdbId = emby.ProviderId,
ImdbId = emby.ImdbId,
TvDbId = emby.TvDbId,
TheMovieDbId = emby.TheMovieDbId,
AddedAt = emby.AddedAt,
Title = emby.Title,
EpisodeNumber = episode.EpisodeNumber,

@ -23,20 +23,20 @@ namespace Ombi.Core.Rule.Rules.Search
EmbyContent item = null;
if (obj.ImdbId.HasValue())
{
item = await EmbyContentRepository.Get(obj.ImdbId);
item = await EmbyContentRepository.GetByImdbId(obj.ImdbId);
}
if (item == null)
{
if (obj.TheMovieDbId.HasValue())
{
item = await EmbyContentRepository.Get(obj.TheMovieDbId);
item = await EmbyContentRepository.GetByTheMovieDbId(obj.TheMovieDbId);
}
if (item == null)
{
if (obj.TheTvDbId.HasValue())
{
item = await EmbyContentRepository.Get(obj.TheTvDbId);
item = await EmbyContentRepository.GetByTvDbId(obj.TheTvDbId);
}
}
}

@ -1,4 +1,5 @@
using Hangfire;
using System;
using Hangfire;
using Ombi.Core.Settings;
using Ombi.Schedule.Jobs;
using Ombi.Schedule.Jobs.Couchpotato;
@ -12,7 +13,7 @@ using Ombi.Settings.Settings.Models;
namespace Ombi.Schedule
{
public class JobSetup : IJobSetup
public class JobSetup : IJobSetup, IDisposable
{
public JobSetup(IPlexContentSync plexContentSync, IRadarrSync radarrSync,
IOmbiAutomaticUpdater updater, IEmbyContentSync embySync, IPlexUserImporter userImporter,
@ -65,5 +66,36 @@ namespace Ombi.Schedule
RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s));
RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s));
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_plexContentSync?.Dispose();
_radarrSync?.Dispose();
_updater?.Dispose();
_plexUserImporter?.Dispose();
_embyContentSync?.Dispose();
_embyUserImporter?.Dispose();
_sonarrSync?.Dispose();
_cpCache?.Dispose();
_srSync?.Dispose();
_jobSettings?.Dispose();
_refreshMetadata?.Dispose();
_newsletter?.Dispose();
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

@ -70,7 +70,16 @@ namespace Ombi.Schedule.Jobs.Emby
foreach (var movie in movies)
{
var embyContent = await _repo.Get(movie.ImdbId);
EmbyContent embyContent = null;
if (movie.TheMovieDbId > 0)
{
embyContent = await _repo.GetByTheMovieDbId(movie.TheMovieDbId.ToString());
}
else if(movie.ImdbId.HasValue())
{
embyContent = await _repo.GetByImdbId(movie.ImdbId);
}
if (embyContent == null)
{
// We don't have this yet
@ -112,8 +121,20 @@ namespace Ombi.Schedule.Jobs.Emby
foreach (var child in tv)
{
var tvDbId = child.ParentRequest.TvDbId;
var seriesEpisodes = embyEpisodes.Where(x => x.Series.ProviderId == tvDbId.ToString());
IQueryable<EmbyEpisode> seriesEpisodes;
if (child.ParentRequest.TvDbId > 0)
{
seriesEpisodes = embyEpisodes.Where(x => x.Series.TvDbId == child.ParentRequest.TvDbId.ToString());
}
else if(child.ParentRequest.ImdbId.HasValue())
{
seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == child.ParentRequest.ImdbId);
}
else
{
continue;
}
foreach (var season in child.SeasonRequests)
{
foreach (var episode in season.Episodes)

@ -38,12 +38,21 @@ namespace Ombi.Schedule.Jobs.Emby
public async Task Start()
{
var embySettings = await _settings.GetSettingsAsync();
var embySettings = await _settings.GetSettingsAsync();
if (!embySettings.Enable)
return;
foreach (var server in embySettings.Servers)
await StartServerCache(server);
{
try
{
await StartServerCache(server);
}
catch (Exception e)
{
_logger.LogError(e, "Exception when caching Emby for server {0}", server.Name);
}
}
// Episodes
BackgroundJob.Enqueue(() => _episodeSync.Start());
@ -55,8 +64,11 @@ namespace Ombi.Schedule.Jobs.Emby
if (!ValidateSettings(server))
return;
await _repo.ExecuteSql("DELETE FROM EmbyEpisode");
await _repo.ExecuteSql("DELETE FROM EmbyContent");
var movies = await _api.GetAllMovies(server.ApiKey, server.AdministratorId, server.FullUri);
var mediaToAdd = new List<EmbyContent>();
var mediaToAdd = new HashSet<EmbyContent>();
foreach (var movie in movies.Items)
{
if (movie.Type.Equals("boxset", StringComparison.CurrentCultureIgnoreCase))
@ -96,7 +108,9 @@ namespace Ombi.Schedule.Jobs.Emby
if (existingTv == null)
mediaToAdd.Add(new EmbyContent
{
ProviderId = tvInfo.ProviderIds.Tvdb,
TvDbId = tvInfo.ProviderIds?.Tvdb,
ImdbId = tvInfo.ProviderIds?.Imdb,
TheMovieDbId = tvInfo.ProviderIds?.Tmdb,
Title = tvInfo.Name,
Type = EmbyMediaType.Series,
EmbyId = tvShow.Id,
@ -110,18 +124,14 @@ namespace Ombi.Schedule.Jobs.Emby
private async Task ProcessMovies(MovieInformation movieInfo, ICollection<EmbyContent> content)
{
if (string.IsNullOrEmpty(movieInfo.ProviderIds.Imdb))
{
Log.Error("Provider Id on movie {0} is null", movieInfo.Name);
return;
}
// Check if it exists
var existingMovie = await _repo.GetByEmbyId(movieInfo.Id);
if (existingMovie == null)
content.Add(new EmbyContent
{
ProviderId = movieInfo.ProviderIds.Imdb,
ImdbId = movieInfo.ProviderIds.Imdb,
TheMovieDbId = movieInfo.ProviderIds?.Tmdb,
Title = movieInfo.Name,
Type = EmbyMediaType.Movie,
EmbyId = movieInfo.Id,

@ -85,10 +85,10 @@ namespace Ombi.Schedule.Jobs.Emby
}
var epInfo = await _api.GetEpisodeInformation(ep.Id, server.ApiKey, server.AdministratorId, server.FullUri);
if (epInfo?.ProviderIds?.Tvdb == null)
{
continue;
}
//if (epInfo?.ProviderIds?.Tvdb == null)
//{
// continue;
//}
// Let's make sure we have the parent request, stop those pesky forign key errors,
// Damn me having data integrity
@ -109,7 +109,9 @@ namespace Ombi.Schedule.Jobs.Emby
EpisodeNumber = ep.IndexNumber,
SeasonNumber = ep.ParentIndexNumber,
ParentId = ep.SeriesId,
ProviderId = epInfo.ProviderIds.Tvdb,
TvDbId = epInfo.ProviderIds.Tvdb,
TheMovieDbId = epInfo.ProviderIds.Tmdb,
ImdbId = epInfo.ProviderIds.Imdb,
Title = ep.Name,
AddedAt = DateTime.UtcNow
});

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MailKit;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Ombi.Api.TheMovieDb;
@ -100,11 +101,11 @@ namespace Ombi.Schedule.Jobs.Ombi
var embym = embyContent.Where(x => x.Type == EmbyMediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10);
var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10);
var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10);
body = await BuildHtml(plexm, embym, plext, embyt);
body = await BuildHtml(plexm, embym, plext, embyt, settings);
}
else
{
body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend);
body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, settings);
if (body.IsNullOrEmpty())
{
return;
@ -120,6 +121,15 @@ namespace Ombi.Schedule.Jobs.Ombi
{
return;
}
foreach (var emails in settings.ExternalEmails)
{
users.Add(new OmbiUser
{
UserName = emails,
Email = emails
});
}
var emailTasks = new List<Task>();
foreach (var user in users)
{
@ -229,20 +239,20 @@ namespace Ombi.Schedule.Jobs.Ombi
return resolver.ParseMessage(template, curlys);
}
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend, IQueryable<PlexEpisode> plexEpisodes, IQueryable<EmbyEpisode> embyEp)
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend, IQueryable<PlexEpisode> plexEpisodes, IQueryable<EmbyEpisode> embyEp, NewsletterSettings settings)
{
var sb = new StringBuilder();
var plexMovies = plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Movie);
var embyMovies = embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie);
if (plexMovies.Any() || embyMovies.Any())
if ((plexMovies.Any() || embyMovies.Any()) && !settings.DisableMovies)
{
sb.Append("<h1>New Movies:</h1><br /><br />");
await ProcessPlexMovies(plexMovies, sb);
await ProcessEmbyMovies(embyMovies, sb);
}
if (plexEpisodes.Any() || embyEp.Any())
if ((plexEpisodes.Any() || embyEp.Any()) && !settings.DisableTv)
{
sb.Append("<h1>New Episodes:</h1><br /><br />");
await ProcessPlexTv(plexEpisodes, sb);
@ -292,14 +302,21 @@ namespace Ombi.Schedule.Jobs.Ombi
var ordered = embyContent.OrderByDescending(x => x.AddedAt);
foreach (var content in ordered)
{
var imdbId = content.ProviderId;
var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id);
var result = findResult.movie_results?.FirstOrDefault();
if(result == null)
var theMovieDbId = content.TheMovieDbId;
if (!content.TheMovieDbId.HasValue())
{
continue;
var imdbId = content.ImdbId;
var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id);
var result = findResult.movie_results?.FirstOrDefault();
if (result == null)
{
continue;
}
theMovieDbId = result.id.ToString();
}
var info = await _movieApi.GetMovieInformationWithExtraInfo(result.id);
var info = await _movieApi.GetMovieInformationWithExtraInfo(int.Parse(theMovieDbId));
if (info == null)
{
continue;
@ -503,7 +520,11 @@ namespace Ombi.Schedule.Jobs.Ombi
{
try
{
int.TryParse(t.ProviderId, out var tvdbId);
if (!t.TvDbId.HasValue())
{
continue;
}
int.TryParse(t.TvDbId, out var tvdbId);
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
if (info == null)
{

@ -10,7 +10,6 @@ using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
namespace Ombi.Schedule.Jobs.Ombi
{
@ -44,6 +43,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (settings.Enable)
{
await StartPlex();
await StartEmby();
}
}
catch (Exception e)
@ -61,6 +61,12 @@ namespace Ombi.Schedule.Jobs.Ombi
await StartPlexTv();
}
private async Task StartEmby()
{
await StartEmbyMovies();
await StartEmbyTv();
}
private async Task StartPlexTv()
{
var allTv = _plexRepo.GetAll().Where(x =>
@ -101,6 +107,46 @@ namespace Ombi.Schedule.Jobs.Ombi
await _plexRepo.SaveChangesAsync();
}
private async Task StartEmbyTv()
{
var allTv = _embyRepo.GetAll().Where(x =>
x.Type == EmbyMediaType.Series && (!x.TheMovieDbId.HasValue() || !x.ImdbId.HasValue() || !x.TvDbId.HasValue()));
var tvCount = 0;
foreach (var show in allTv)
{
var hasImdb = show.ImdbId.HasValue();
var hasTheMovieDb = show.TheMovieDbId.HasValue();
var hasTvDbId = show.TvDbId.HasValue();
if (!hasTheMovieDb)
{
var id = await GetTheMovieDbId(hasTvDbId, hasImdb, show.TvDbId, show.ImdbId, show.Title);
show.TheMovieDbId = id;
}
if (!hasImdb)
{
var id = await GetImdbId(hasTheMovieDb, hasTvDbId, show.Title, show.TheMovieDbId, show.TvDbId);
show.ImdbId = id;
_embyRepo.UpdateWithoutSave(show);
}
if (!hasTvDbId)
{
var id = await GetTvDbId(hasTheMovieDb, hasImdb, show.TheMovieDbId, show.ImdbId, show.Title);
show.TvDbId = id;
_embyRepo.UpdateWithoutSave(show);
}
tvCount++;
if (tvCount >= 20)
{
await _embyRepo.SaveChangesAsync();
tvCount = 0;
}
}
await _embyRepo.SaveChangesAsync();
}
private async Task StartPlexMovies()
{
var allMovies = _plexRepo.GetAll().Where(x =>
@ -135,7 +181,41 @@ namespace Ombi.Schedule.Jobs.Ombi
await _plexRepo.SaveChangesAsync();
}
private async Task<string> GetTheMovieDbId(bool hasTvDbId, bool hasImdb, string tvdbID, string imdbId, string title)
private async Task StartEmbyMovies()
{
var allMovies = _embyRepo.GetAll().Where(x =>
x.Type == EmbyMediaType.Movie && (!x.TheMovieDbId.HasValue() || !x.ImdbId.HasValue()));
int movieCount = 0;
foreach (var movie in allMovies)
{
var hasImdb = movie.ImdbId.HasValue();
var hasTheMovieDb = movie.TheMovieDbId.HasValue();
// Movies don't really use TheTvDb
if (!hasImdb)
{
var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty);
movie.ImdbId = imdbId;
_embyRepo.UpdateWithoutSave(movie);
}
if (!hasTheMovieDb)
{
var id = await GetTheMovieDbId(false, hasImdb, string.Empty, movie.ImdbId, movie.Title);
movie.TheMovieDbId = id;
_embyRepo.UpdateWithoutSave(movie);
}
movieCount++;
if (movieCount >= 20)
{
await _embyRepo.SaveChangesAsync();
movieCount = 0;
}
}
await _embyRepo.SaveChangesAsync();
}
private async Task<string> GetTheMovieDbId(bool hasTvDbId, bool hasImdb, string tvdbID, string imdbId, string title)
{
_log.LogInformation("The Media item {0} does not have a TheMovieDbId, searching for TheMovieDbId", title);
FindResult result = null;

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -43,14 +45,15 @@ namespace Ombi.Schedule.Jobs.Sonarr
var series = await _api.GetSeries(settings.ApiKey, settings.FullUri);
if (series != null)
{
var sonarrSeries = series as IList<SonarrSeries> ?? series.ToList();
var sonarrSeries = series as ImmutableHashSet<SonarrSeries> ?? series.ToImmutableHashSet();
var ids = sonarrSeries.Select(x => x.tvdbId);
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SonarrCache");
var entites = ids.Select(id => new SonarrCache { TvDbId = id }).ToList();
var entites = ids.Select(id => new SonarrCache { TvDbId = id }).ToImmutableHashSet();
await _ctx.SonarrCache.AddRangeAsync(entites);
entites.Clear();
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SonarrEpisodeCache");
foreach (var s in sonarrSeries)
{
@ -67,10 +70,10 @@ namespace Ombi.Schedule.Jobs.Sonarr
TvDbId = s.tvdbId,
HasFile = episode.hasFile
}));
_log.LogDebug("Commiting the transaction");
await _ctx.SaveChangesAsync();
}
_log.LogDebug("Commiting the transaction");
await _ctx.SaveChangesAsync();
}
}
catch (Exception e)

@ -1,7 +1,12 @@
namespace Ombi.Settings.Settings.Models.Notifications
using System.Collections.Generic;
namespace Ombi.Settings.Settings.Models.Notifications
{
public class NewsletterSettings : Settings
{
public bool DisableTv { get; set; }
public bool DisableMovies { get; set; }
public bool Enabled { get; set; }
public List<string> ExternalEmails { get; set; }
}
}

@ -36,11 +36,18 @@ namespace Ombi.Store.Entities
{
public string Title { get; set; }
/// <summary>
/// OBSOLETE, Cannot delete due to DB migration issues with SQLite
/// </summary>
public string ProviderId { get; set; }
public string EmbyId { get; set; }
public EmbyMediaType Type { get; set; }
public DateTime AddedAt { get; set; }
public string ImdbId { get; set; }
public string TheMovieDbId { get; set; }
public string TvDbId { get; set; }
public ICollection<EmbyEpisode> Episodes { get; set; }
}

@ -39,8 +39,14 @@ namespace Ombi.Store.Entities
public int EpisodeNumber { get; set; }
public int SeasonNumber { get; set; }
public string ParentId { get; set; }
/// <summary>
/// NOT USED
/// </summary>
public string ProviderId { get; set; }
public DateTime AddedAt { get; set; }
public string TvDbId { get; set; }
public string ImdbId { get; set; }
public string TheMovieDbId { get; set; }
public EmbyContent Series { get; set; }
}

@ -0,0 +1,948 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Ombi.Helpers;
using Ombi.Store.Context;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using System;
namespace Ombi.Store.Migrations
{
[DbContext(typeof(OmbiContext))]
[Migration("20180406224743_EmbyMetadata")]
partial class EmbyMetadata
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Type");
b.Property<string>("Value");
b.HasKey("Id");
b.ToTable("ApplicationConfiguration");
});
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AuditArea");
b.Property<int>("AuditType");
b.Property<DateTime>("DateTime");
b.Property<string>("Description");
b.Property<string>("User");
b.HasKey("Id");
b.ToTable("Audit");
});
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TheMovieDbId");
b.HasKey("Id");
b.ToTable("CouchPotatoCache");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("EmbyId")
.IsRequired();
b.Property<string>("ImdbId");
b.Property<string>("ProviderId");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.Property<int>("Type");
b.HasKey("Id");
b.ToTable("EmbyContent");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("EmbyId");
b.Property<int>("EpisodeNumber");
b.Property<string>("ImdbId");
b.Property<string>("ParentId");
b.Property<string>("ProviderId");
b.Property<int>("SeasonNumber");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("EmbyEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Content");
b.Property<string>("SettingsName");
b.HasKey("Id");
b.ToTable("GlobalSettings");
});
modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Agent");
b.Property<bool>("Enabled");
b.Property<string>("Message");
b.Property<int>("NotificationType");
b.Property<string>("Subject");
b.HasKey("Id");
b.ToTable("NotificationTemplates");
});
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("PlayerId");
b.Property<string>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("NotificationUserId");
});
modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("Alias");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<string>("EmbyConnectUserId");
b.Property<int?>("EpisodeRequestLimit");
b.Property<DateTime?>("LastLoggedIn");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<int?>("MovieRequestLimit");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("ProviderUserId");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserAccessToken");
b.Property<string>("UserName")
.HasMaxLength(256);
b.Property<int>("UserType");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<int>("GrandparentKey");
b.Property<int>("Key");
b.Property<int>("ParentKey");
b.Property<int>("SeasonNumber");
b.Property<string>("Title");
b.HasKey("Id");
b.HasIndex("GrandparentKey");
b.ToTable("PlexEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("ParentKey");
b.Property<int>("PlexContentId");
b.Property<int?>("PlexServerContentId");
b.Property<int>("SeasonKey");
b.Property<int>("SeasonNumber");
b.HasKey("Id");
b.HasIndex("PlexServerContentId");
b.ToTable("PlexSeasonsContent");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("ImdbId");
b.Property<int>("Key");
b.Property<string>("Quality");
b.Property<string>("ReleaseYear");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.Property<int>("Type");
b.Property<string>("Url");
b.HasKey("Id");
b.ToTable("PlexServerContent");
});
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("HasFile");
b.Property<int>("TheMovieDbId");
b.HasKey("Id");
b.ToTable("RadarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<int>("ContentId");
b.Property<int>("ContentType");
b.Property<int>("Type");
b.HasKey("Id");
b.ToTable("RecentlyAddedLog");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Approved");
b.Property<bool>("Available");
b.Property<bool?>("Denied");
b.Property<string>("DeniedReason");
b.Property<int?>("IssueId");
b.Property<int>("ParentRequestId");
b.Property<int>("RequestType");
b.Property<DateTime>("RequestedDate");
b.Property<string>("RequestedUserId");
b.Property<int>("SeriesType");
b.Property<string>("Title");
b.HasKey("Id");
b.HasIndex("ParentRequestId");
b.HasIndex("RequestedUserId");
b.ToTable("ChildRequests");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Value");
b.HasKey("Id");
b.ToTable("IssueCategory");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Comment");
b.Property<DateTime>("Date");
b.Property<int?>("IssuesId");
b.Property<string>("UserId");
b.HasKey("Id");
b.HasIndex("IssuesId");
b.HasIndex("UserId");
b.ToTable("IssueComments");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Description");
b.Property<int>("IssueCategoryId");
b.Property<int?>("IssueId");
b.Property<string>("ProviderId");
b.Property<int?>("RequestId");
b.Property<int>("RequestType");
b.Property<DateTime?>("ResovledDate");
b.Property<int>("Status");
b.Property<string>("Subject");
b.Property<string>("Title");
b.Property<string>("UserReportedId");
b.HasKey("Id");
b.HasIndex("IssueCategoryId");
b.HasIndex("IssueId");
b.HasIndex("UserReportedId");
b.ToTable("Issues");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Approved");
b.Property<bool>("Available");
b.Property<string>("Background");
b.Property<bool?>("Denied");
b.Property<string>("DeniedReason");
b.Property<DateTime?>("DigitalReleaseDate");
b.Property<string>("ImdbId");
b.Property<int?>("IssueId");
b.Property<string>("Overview");
b.Property<string>("PosterPath");
b.Property<int>("QualityOverride");
b.Property<DateTime>("ReleaseDate");
b.Property<int>("RequestType");
b.Property<DateTime>("RequestedDate");
b.Property<string>("RequestedUserId");
b.Property<int>("RootPathOverride");
b.Property<string>("Status");
b.Property<int>("TheMovieDbId");
b.Property<string>("Title");
b.HasKey("Id");
b.HasIndex("RequestedUserId");
b.ToTable("MovieRequests");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeCount");
b.Property<DateTime>("RequestDate");
b.Property<int>("RequestId");
b.Property<int>("RequestType");
b.Property<string>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("RequestLog");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ImdbId");
b.Property<string>("Overview");
b.Property<string>("PosterPath");
b.Property<int?>("QualityOverride");
b.Property<DateTime>("ReleaseDate");
b.Property<int?>("RootFolder");
b.Property<string>("Status");
b.Property<string>("Title");
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("TvRequests");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SickRageCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<int>("SeasonNumber");
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SickRageEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SonarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<bool>("HasFile");
b.Property<int>("SeasonNumber");
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SonarrEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Token");
b.Property<string>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Tokens");
});
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AirDate");
b.Property<bool>("Approved");
b.Property<bool>("Available");
b.Property<int>("EpisodeNumber");
b.Property<bool>("Requested");
b.Property<int>("SeasonId");
b.Property<string>("Title");
b.Property<string>("Url");
b.HasKey("Id");
b.HasIndex("SeasonId");
b.ToTable("EpisodeRequests");
});
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("ChildRequestId");
b.Property<int>("SeasonNumber");
b.HasKey("Id");
b.HasIndex("ChildRequestId");
b.ToTable("SeasonRequests");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Ombi.Store.Entities.OmbiUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
.WithMany("Episodes")
.HasForeignKey("ParentId")
.HasPrincipalKey("EmbyId");
});
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
.WithMany("NotificationUserIds")
.HasForeignKey("UserId");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
.WithMany("Episodes")
.HasForeignKey("GrandparentKey")
.HasPrincipalKey("Key")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.HasOne("Ombi.Store.Entities.PlexServerContent")
.WithMany("Seasons")
.HasForeignKey("PlexServerContentId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
{
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
.WithMany("ChildRequests")
.HasForeignKey("ParentRequestId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
.WithMany()
.HasForeignKey("RequestedUserId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
{
b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues")
.WithMany("Comments")
.HasForeignKey("IssuesId");
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
.WithMany()
.HasForeignKey("UserId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
{
b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory")
.WithMany()
.HasForeignKey("IssueCategoryId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
.WithMany("Issues")
.HasForeignKey("IssueId");
b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
.WithMany("Issues")
.HasForeignKey("IssueId");
b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported")
.WithMany()
.HasForeignKey("UserReportedId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
.WithMany()
.HasForeignKey("RequestedUserId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
.WithMany()
.HasForeignKey("UserId");
});
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
.WithMany()
.HasForeignKey("UserId");
});
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
{
b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season")
.WithMany("Episodes")
.HasForeignKey("SeasonId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
{
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest")
.WithMany("SeasonRequests")
.HasForeignKey("ChildRequestId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
namespace Ombi.Store.Migrations
{
public partial class EmbyMetadata : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ImdbId",
table: "EmbyEpisode",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "TheMovieDbId",
table: "EmbyEpisode",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "TvDbId",
table: "EmbyEpisode",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "ImdbId",
table: "EmbyContent",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "TheMovieDbId",
table: "EmbyContent",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "TvDbId",
table: "EmbyContent",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ImdbId",
table: "EmbyEpisode");
migrationBuilder.DropColumn(
name: "TheMovieDbId",
table: "EmbyEpisode");
migrationBuilder.DropColumn(
name: "TvDbId",
table: "EmbyEpisode");
migrationBuilder.DropColumn(
name: "ImdbId",
table: "EmbyContent");
migrationBuilder.DropColumn(
name: "TheMovieDbId",
table: "EmbyContent");
migrationBuilder.DropColumn(
name: "TvDbId",
table: "EmbyContent");
}
}
}

@ -185,10 +185,16 @@ namespace Ombi.Store.Migrations
b.Property<string>("EmbyId")
.IsRequired();
b.Property<string>("ImdbId");
b.Property<string>("ProviderId");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.Property<int>("Type");
b.HasKey("Id");
@ -207,14 +213,20 @@ namespace Ombi.Store.Migrations
b.Property<int>("EpisodeNumber");
b.Property<string>("ImdbId");
b.Property<string>("ParentId");
b.Property<string>("ProviderId");
b.Property<int>("SeasonNumber");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.HasKey("Id");
b.HasIndex("ParentId");

@ -35,42 +35,28 @@ using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public class EmbyContentRepository : IEmbyContentRepository
public class EmbyContentRepository : Repository<EmbyContent>, IEmbyContentRepository
{
public EmbyContentRepository(IOmbiContext db)
public EmbyContentRepository(IOmbiContext db):base(db)
{
Db = db;
}
private IOmbiContext Db { get; }
public IQueryable<EmbyContent> GetAll()
public async Task<EmbyContent> GetByImdbId(string imdbid)
{
return Db.EmbyContent.AsQueryable();
return await Db.EmbyContent.FirstOrDefaultAsync(x => x.ImdbId == imdbid);
}
public async Task AddRange(IEnumerable<EmbyContent> content)
public async Task<EmbyContent> GetByTvDbId(string tv)
{
Db.EmbyContent.AddRange(content);
await Db.SaveChangesAsync();
return await Db.EmbyContent.FirstOrDefaultAsync(x => x.TvDbId == tv);
}
public async Task<bool> ContentExists(string providerId)
public async Task<EmbyContent> GetByTheMovieDbId(string mov)
{
return await Db.EmbyContent.AnyAsync(x => x.ProviderId == providerId);
}
public async Task<EmbyContent> Add(EmbyContent content)
{
await Db.EmbyContent.AddAsync(content);
await Db.SaveChangesAsync();
return content;
}
public async Task<EmbyContent> Get(string providerId)
{
return await Db.EmbyContent.FirstOrDefaultAsync(x => x.ProviderId == providerId);
return await Db.EmbyContent.FirstOrDefaultAsync(x => x.TheMovieDbId == mov);
}
public IQueryable<EmbyContent> Get()
@ -111,23 +97,9 @@ namespace Ombi.Store.Repository
await Db.SaveChangesAsync();
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
Db?.Dispose();
}
_disposed = true;
}
public void Dispose()
public void UpdateWithoutSave(EmbyContent existingContent)
{
Dispose(true);
GC.SuppressFinalize(this);
Db.EmbyContent.Update(existingContent);
}
}
}

@ -6,19 +6,19 @@ using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IEmbyContentRepository : IDisposable
public interface IEmbyContentRepository : IRepository<EmbyContent>
{
Task<EmbyContent> Add(EmbyContent content);
Task AddRange(IEnumerable<EmbyContent> content);
Task<bool> ContentExists(string providerId);
IQueryable<EmbyContent> Get();
Task<EmbyContent> Get(string providerId);
IQueryable<EmbyContent> GetAll();
Task<EmbyContent> GetByTheMovieDbId(string mov);
Task<EmbyContent> GetByTvDbId(string tv);
Task<EmbyContent> GetByImdbId(string imdbid);
Task<EmbyContent> GetByEmbyId(string embyId);
Task Update(EmbyContent existingContent);
IQueryable<EmbyEpisode> GetAllEpisodes();
Task<EmbyEpisode> Add(EmbyEpisode content);
Task<EmbyEpisode> GetEpisodeByEmbyId(string key);
Task AddRange(IEnumerable<EmbyEpisode> content);
void UpdateWithoutSave(EmbyContent existingContent);
}
}

@ -57,6 +57,9 @@ export interface IDiscordNotifcationSettings extends INotificationSettings {
export interface INewsletterNotificationSettings extends INotificationSettings {
notificationTemplate: INotificationTemplates;
disableMovies: boolean;
disableTv: boolean;
externalEmails: string[];
}
export interface ITelegramNotifcationSettings extends INotificationSettings {

@ -38,7 +38,7 @@
<span>Discord</span>
</td>
<td>
<a href="https://discord.gg/KxYZ64w" target="_blank">https://discord.gg/KxYZ64w</a>
<a href="https://discord.gg/Sa7wNWb" target="_blank">https://discord.gg/</a>
</td>
</tr>

@ -9,6 +9,16 @@
<div class="checkbox">
<input type="checkbox" id="enabled" [(ngModel)]="settings.enabled" ng-checked="settings.enabled"><label for="enabled">Enable</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="disableTv" [(ngModel)]="settings.disableTv" ng-checked="settings.disableTv"><label for="disableTv">Disable TV</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="disableMovies" [(ngModel)]="settings.disableMovies" ng-checked="settings.disableMovies"><label for="disableMovies">Disable Movies</label>
</div>
</div>
<div class="form-group">
<label class="control-label">Subject</label>
@ -43,6 +53,31 @@
<br/>
<small>When testing, the test newsletter will go to all users that have the Admin role, please ensure that there are valid email addresses for this. The test will also only grab the latest 10 movies and 10 shows just to give you an example.</small>
<br/>
<br/>
<div class="form-group row">
<div class="col-md-12">
<label for="emailToAdd" class="control-label">Add External Email (For users that are not in Ombi)</label>
</div>
<div class="col-md-9">
<input type="text" [(ngModel)]="emailToAdd" class="form-control form-control-custom " id="emailToAdd"
email name="emailToAdd" value="{{emailToAdd}}">
</div>
<div class="col-md-3">
<button class="btn btn-primary-outline" (click)="addEmail()" pTooltip="Don't forget to press the Submit button!">Add</button>
</div>
</div>
<div class="row">
<div *ngFor="let email of settings.externalEmails">
<div class="col-md-9">
{{email}}
</div>
<div class="col-md-3">
<button class="btn btn-sm btn-danger-outline" (click)="deleteEmail(email)">Delete</button>
</div>
</div>
</div>
</div>
</fieldset>
</div>

@ -11,6 +11,7 @@ export class NewsletterComponent implements OnInit {
public NotificationType = NotificationType;
public settings: INewsletterNotificationSettings;
public emailToAdd: string;
constructor(private settingsService: SettingsService,
private notificationService: NotificationService,
@ -48,4 +49,24 @@ export class NewsletterComponent implements OnInit {
});
}
public addEmail() {
if(this.emailToAdd) {
const emailRegex = "[a-zA-Z0-9.-_]{1,}@[a-zA-Z.-]{2,}[.]{1}[a-zA-Z]{2,}";
const match = this.emailToAdd.match(emailRegex)!;
if(match && match.length > 0) {
this.settings.externalEmails.push(this.emailToAdd);
this.emailToAdd = "";
} else {
this.notificationService.error("Please enter a valid email address");
}
}
}
public deleteEmail(email: string) {
const index = this.settings.externalEmails.indexOf(email); // <-- Not supported in <IE9
if (index !== -1) {
this.settings.externalEmails.splice(index, 1);
}
}
}

@ -11,6 +11,7 @@ using Hangfire;
using Hangfire.Console;
using Hangfire.Dashboard;
using Hangfire.SQLite;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -85,7 +86,7 @@ namespace Ombi
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
TelemetryConfiguration.Active.DisableTelemetry = true;
// Add framework services.
services.AddDbContext<OmbiContext>();
@ -183,12 +184,12 @@ namespace Ombi
Authorization = new[] { new HangfireAuthorizationFilter() }
});
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 3 });
// Setup the scheduler
var jobSetup = app.ApplicationServices.GetService<IJobSetup>();
jobSetup.Setup();
ctx.Seed();
var provider = new FileExtensionContentTypeProvider { Mappings = { [".map"] = "application/octet-stream" } };
app.UseStaticFiles(new StaticFileOptions()
@ -218,6 +219,8 @@ namespace Ombi
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
ombiService.Dispose();
}
}

@ -168,6 +168,7 @@ namespace Ombi
if (user == null)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Response.RegisterForDispose(um);
await context.Response.WriteAsync("Invalid User Access Token");
}
else
@ -177,6 +178,7 @@ namespace Ombi
var roles = await um.GetRolesAsync(user);
var principal = new GenericPrincipal(identity, roles.ToArray());
context.User = principal;
context.Response.RegisterForDispose(um);
await next();
}
}
@ -189,6 +191,7 @@ namespace Ombi
if (!valid)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Response.RegisterForDispose(settingsProvider);
await context.Response.WriteAsync("Invalid API Key");
}
else
@ -196,6 +199,7 @@ namespace Ombi
var identity = new GenericIdentity("API");
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
context.User = principal;
context.Response.RegisterForDispose(settingsProvider);
await next();
}
}

@ -12344,7 +12344,8 @@
"uglify-to-browserify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc="
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"optional": true
},
"uglifyjs-webpack-plugin": {
"version": "1.1.8",
@ -12945,7 +12946,7 @@
"os-locale": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
"integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
"integrity": "sha1-QrwpAKa1uL0XN2yOiCtlr8zyS/I=",
"requires": {
"execa": "0.7.0",
"lcid": "1.0.0",
@ -12987,7 +12988,7 @@
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=",
"requires": {
"is-fullwidth-code-point": "2.0.0",
"strip-ansi": "4.0.0"

Loading…
Cancel
Save