Merge branch 'develop' into feature/v4

This commit is contained in:
Jamie Rees 2019-03-07 09:42:13 +00:00
commit cc5fb56e7b
13 changed files with 89 additions and 78 deletions

View file

@ -82,9 +82,9 @@ Task("SetVersionInfo")
versionInfo = GitVersion(settings); versionInfo = GitVersion(settings);
Information("GitResults -> {0}", versionInfo.Dump()); // Information("GitResults -> {0}", versionInfo.Dump());
Information(@"Build:{0}",AppVeyor.Environment.Build.Dump()); //Information(@"Build:{0}",AppVeyor.Environment.Build.Dump());
var buildVersion = string.Empty; var buildVersion = string.Empty;
if(string.IsNullOrEmpty(AppVeyor.Environment.Build.Version)) if(string.IsNullOrEmpty(AppVeyor.Environment.Build.Version))

View file

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
@ -14,7 +15,7 @@ namespace Ombi.Core.Tests.Rule.Search
public void Setup() public void Setup()
{ {
ContextMock = new Mock<IPlexContentRepository>(); ContextMock = new Mock<IPlexContentRepository>();
Rule = new PlexAvailabilityRule(ContextMock.Object); Rule = new PlexAvailabilityRule(ContextMock.Object, new Mock<ILogger<PlexAvailabilityRule>>().Object);
} }
private PlexAvailabilityRule Rule { get; set; } private PlexAvailabilityRule Rule { get; set; }

View file

@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using Ombi.Store.Repository.Requests; using Ombi.Store.Repository.Requests;
@ -31,7 +32,7 @@ namespace Ombi.Core.Rule.Rules.Search
if (!airedButNotAvailable) if (!airedButNotAvailable)
{ {
var unairedEpisodes = search.SeasonRequests.Any(x => var unairedEpisodes = search.SeasonRequests.Any(x =>
x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date && c.AirDate != DateTime.MinValue)); x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date || c.AirDate != DateTime.MinValue));
if (unairedEpisodes) if (unairedEpisodes)
{ {
search.FullyAvailable = true; search.FullyAvailable = true;
@ -41,28 +42,36 @@ namespace Ombi.Core.Rule.Rules.Search
} }
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<PlexEpisode> allEpisodes, EpisodeRequests episode, public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<PlexEpisode> allEpisodes, EpisodeRequests episode,
SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb) SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log)
{ {
PlexEpisode epExists = null; PlexEpisode epExists = null;
if (useImdb) try
{ {
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.ImdbId == item.ImdbId);
}
if (useTheMovieDb) if (useImdb)
{ {
epExists = await allEpisodes.FirstOrDefaultAsync(x => epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TheMovieDbId == item.TheMovieDbId); x.Series.ImdbId == item.ImdbId);
} }
if (useTvDb) if (useTheMovieDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TheMovieDbId == item.TheMovieDbId);
}
if (useTvDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TvDbId == item.TvDbId);
}
}
catch (Exception e)
{ {
epExists = await allEpisodes.FirstOrDefaultAsync(x => log.LogError(e, "Exception thrown when attempting to check if something is available");
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TvDbId == item.TvDbId);
} }
if (epExists != null) if (epExists != null)

View file

@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces; using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers; using Ombi.Helpers;
@ -10,12 +11,14 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
public class PlexAvailabilityRule : BaseSearchRule, IRules<SearchViewModel> public class PlexAvailabilityRule : BaseSearchRule, IRules<SearchViewModel>
{ {
public PlexAvailabilityRule(IPlexContentRepository repo) public PlexAvailabilityRule(IPlexContentRepository repo, ILogger<PlexAvailabilityRule> log)
{ {
PlexContentRepository = repo; PlexContentRepository = repo;
Log = log;
} }
private IPlexContentRepository PlexContentRepository { get; } private IPlexContentRepository PlexContentRepository { get; }
private ILogger Log { get; }
public async Task<RuleResult> Execute(SearchViewModel obj) public async Task<RuleResult> Execute(SearchViewModel obj)
{ {
@ -72,7 +75,7 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
foreach (var episode in season.Episodes) foreach (var episode in season.Episodes)
{ {
await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log);
} }
} }

View file

@ -52,7 +52,7 @@ namespace Ombi.Notifications.Agents
private void AddOtherInformation(NotificationOptions model, NotificationMessage notification, private void AddOtherInformation(NotificationOptions model, NotificationMessage notification,
NotificationMessageContent parsed) NotificationMessageContent parsed)
{ {
notification.Other.Add("image", parsed.Image); notification.Other.Add("image", parsed?.Image ?? string.Empty);
notification.Other.Add("title", model.RequestType == RequestType.Movie ? MovieRequest.Title : TvRequest.Title); notification.Other.Add("title", model.RequestType == RequestType.Movie ? MovieRequest.Title : TvRequest.Title);
} }

View file

@ -13,6 +13,7 @@ namespace Ombi.Store.Context
if (_created) return; if (_created) return;
_created = true; _created = true;
Database.SetCommandTimeout(60);
Database.Migrate(); Database.Migrate();
} }

View file

@ -18,6 +18,7 @@ namespace Ombi.Store.Context
if (_created) return; if (_created) return;
_created = true; _created = true;
Database.SetCommandTimeout(60);
Database.Migrate(); Database.Migrate();
} }
@ -107,6 +108,7 @@ namespace Ombi.Store.Context
var allAgents = Enum.GetValues(typeof(NotificationAgent)).Cast<NotificationAgent>().ToList(); var allAgents = Enum.GetValues(typeof(NotificationAgent)).Cast<NotificationAgent>().ToList();
var allTypes = Enum.GetValues(typeof(NotificationType)).Cast<NotificationType>().ToList(); var allTypes = Enum.GetValues(typeof(NotificationType)).Cast<NotificationType>().ToList();
var needToSave = false;
foreach (var agent in allAgents) foreach (var agent in allAgents)
{ {
foreach (var notificationType in allTypes) foreach (var notificationType in allTypes)
@ -116,6 +118,8 @@ namespace Ombi.Store.Context
// We already have this // We already have this
continue; continue;
} }
needToSave = true;
NotificationTemplates notificationToAdd; NotificationTemplates notificationToAdd;
switch (notificationType) switch (notificationType)
{ {
@ -230,7 +234,11 @@ namespace Ombi.Store.Context
NotificationTemplates.Add(notificationToAdd); NotificationTemplates.Add(notificationToAdd);
} }
} }
SaveChanges();
if (needToSave)
{
SaveChanges();
}
} }
} }
} }

View file

@ -14,6 +14,7 @@ namespace Ombi.Store.Context
if (_created) return; if (_created) return;
_created = true; _created = true;
Database.SetCommandTimeout(60);
Database.Migrate(); Database.Migrate();
} }
@ -63,13 +64,6 @@ namespace Ombi.Store.Context
}); });
SaveChanges(); SaveChanges();
} }
SaveChanges();
}
~SettingsContext()
{
} }
} }
} }

View file

@ -15,6 +15,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="Nito.AsyncEx" Version="5.0.0-pre-05" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="1.1.9" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="1.1.9" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -5,6 +5,7 @@ using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query;
using Nito.AsyncEx;
using Ombi.Store.Context; using Ombi.Store.Context;
using Ombi.Store.Entities; using Ombi.Store.Entities;
@ -19,6 +20,7 @@ namespace Ombi.Store.Repository
} }
public DbSet<T> _db { get; } public DbSet<T> _db { get; }
private readonly U _ctx; private readonly U _ctx;
private readonly AsyncLock _mutex = new AsyncLock();
public async Task<T> Find(object key) public async Task<T> Find(object key)
{ {
@ -40,32 +42,32 @@ namespace Ombi.Store.Repository
_db.AddRange(content); _db.AddRange(content);
if (save) if (save)
{ {
await _ctx.SaveChangesAsync(); await InternalSaveChanges();
} }
} }
public async Task<T> Add(T content) public async Task<T> Add(T content)
{ {
await _db.AddAsync(content); await _db.AddAsync(content);
await _ctx.SaveChangesAsync(); await InternalSaveChanges();
return content; return content;
} }
public async Task Delete(T request) public async Task Delete(T request)
{ {
_db.Remove(request); _db.Remove(request);
await _ctx.SaveChangesAsync(); await InternalSaveChanges();
} }
public async Task DeleteRange(IEnumerable<T> req) public async Task DeleteRange(IEnumerable<T> req)
{ {
_db.RemoveRange(req); _db.RemoveRange(req);
await _ctx.SaveChangesAsync(); await InternalSaveChanges();
} }
public async Task<int> SaveChangesAsync() public async Task<int> SaveChangesAsync()
{ {
return await _ctx.SaveChangesAsync(); return await InternalSaveChanges();
} }
public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>( public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
@ -80,6 +82,14 @@ namespace Ombi.Store.Repository
await _ctx.Database.ExecuteSqlCommandAsync(sql); await _ctx.Database.ExecuteSqlCommandAsync(sql);
} }
private async Task<int> InternalSaveChanges()
{
using (await _mutex.LockAsync())
{
return await _ctx.SaveChangesAsync();
}
}
private bool _disposed; private bool _disposed;
// Protected implementation of Dispose pattern. // Protected implementation of Dispose pattern.

View file

@ -91,9 +91,7 @@ namespace Ombi
dbBaseUrl.Value = baseUrl; dbBaseUrl.Value = baseUrl;
ctx.SaveChanges(); ctx.SaveChanges();
} }
DeleteSchedulesDb();
Console.WriteLine($"We are running on {urlValue}"); Console.WriteLine($"We are running on {urlValue}");
CreateWebHostBuilder(args).Build().Run(); CreateWebHostBuilder(args).Build().Run();
@ -226,20 +224,6 @@ namespace Ombi
} }
} }
private static void DeleteSchedulesDb()
{
try
{
if (File.Exists("Schedules.db"))
{
File.Delete("Schedules.db");
}
}
catch (Exception)
{
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() .UseStartup<Startup>()

View file

@ -13,7 +13,7 @@
"ContinueButton": "Weiter", "ContinueButton": "Weiter",
"Available": "Verfügbar", "Available": "Verfügbar",
"PartiallyAvailable": "Teilweise verfügbar", "PartiallyAvailable": "Teilweise verfügbar",
"Monitored": "Monitored", "Monitored": "Überwacht",
"NotAvailable": "Nicht verfügbar", "NotAvailable": "Nicht verfügbar",
"ProcessingRequest": "Anfrage wird bearbeitet", "ProcessingRequest": "Anfrage wird bearbeitet",
"PendingApproval": "Genehmigung ausstehend", "PendingApproval": "Genehmigung ausstehend",
@ -68,13 +68,13 @@
"MusicTab": "Musik", "MusicTab": "Musik",
"Suggestions": "Vorschläge", "Suggestions": "Vorschläge",
"NoResults": "Es tut uns leid, wir haben keine Ergebnisse gefunden!", "NoResults": "Es tut uns leid, wir haben keine Ergebnisse gefunden!",
"DigitalDate": "Digital Release: {{date}}", "DigitalDate": "Veröffentlichung der digitalen Version: {{date}}",
"TheatricalRelease": "Kinostart: {{date}}", "TheatricalRelease": "Kinostart: {{date}}",
"ViewOnPlex": "In Plex anschauen", "ViewOnPlex": "In Plex anschauen",
"ViewOnEmby": "In Emby anschauen", "ViewOnEmby": "In Emby anschauen",
"RequestAdded": "Anfrage für {{title}} wurde erfolgreich hinzugefügt", "RequestAdded": "Anfrage für {{title}} wurde erfolgreich hinzugefügt",
"Similar": "Ähnliche", "Similar": "Ähnliche",
"Refine": "Refine", "Refine": "Auswahl verfeinern",
"Movies": { "Movies": {
"PopularMovies": "Beliebte Filme", "PopularMovies": "Beliebte Filme",
"UpcomingMovies": "Kommende Filme", "UpcomingMovies": "Kommende Filme",
@ -112,7 +112,7 @@
"TheatricalRelease": "Kinostart: {{date}}", "TheatricalRelease": "Kinostart: {{date}}",
"ReleaseDate": "Veröffentlicht: {{date}}", "ReleaseDate": "Veröffentlicht: {{date}}",
"TheatricalReleaseSort": "Kinostart", "TheatricalReleaseSort": "Kinostart",
"DigitalRelease": "Digital Release: {{date}}", "DigitalRelease": "Veröffentlichung der digitalen Version: {{date}}",
"RequestDate": "Datum der Anfrage:", "RequestDate": "Datum der Anfrage:",
"QualityOverride": "Qualitäts Überschreiben:", "QualityOverride": "Qualitäts Überschreiben:",
"RootFolderOverride": "Stammverzeichnis Überschreiben:", "RootFolderOverride": "Stammverzeichnis Überschreiben:",
@ -132,16 +132,16 @@
"SeasonNumberHeading": "Staffel: {seasonNumber}", "SeasonNumberHeading": "Staffel: {seasonNumber}",
"SortTitleAsc": "Titel ▲", "SortTitleAsc": "Titel ▲",
"SortTitleDesc": "Titel ▼", "SortTitleDesc": "Titel ▼",
"SortRequestDateAsc": "Request Date ▲", "SortRequestDateAsc": "Datum der Anfrage ▲",
"SortRequestDateDesc": "Request Date ▼", "SortRequestDateDesc": "Datum der Anfrage ▼",
"SortStatusAsc": "Status ▲", "SortStatusAsc": "Status ▲",
"SortStatusDesc": "Status ▼", "SortStatusDesc": "Status ▼",
"Remaining": { "Remaining": {
"Quota": "{{remaining}}/{{total}} Anfragen verbleiben", "Quota": "{{remaining}}/{{total}} Anfragen verbleiben",
"NextDays": "Another request will be added in {{time}} days", "NextDays": "Eine weitere Anfrage wird in {{time}} Tagen hinzugefügt",
"NextHours": "Another request will be added in {{time}} hours", "NextHours": "Eine weitere Anfrage wird in {{time}} Stunden hinzugefügt",
"NextMinutes": "Another request will be added in {{time}} minutes", "NextMinutes": "Eine weitere Anfrage wird in {{time}} Minuten hinzugefügt",
"NextMinute": "Another request will be added in {{time}} minute" "NextMinute": "Eine weitere Anfrage wird in {{time}} Minute hinzugefügt"
} }
}, },
"Issues": { "Issues": {

View file

@ -13,7 +13,7 @@
"ContinueButton": "Gå videre", "ContinueButton": "Gå videre",
"Available": "Tilgjengelig", "Available": "Tilgjengelig",
"PartiallyAvailable": "Partially Available", "PartiallyAvailable": "Partially Available",
"Monitored": "Monitored", "Monitored": "Overvåket",
"NotAvailable": "Ikke tilgjengelig", "NotAvailable": "Ikke tilgjengelig",
"ProcessingRequest": "Behandler forespørsel", "ProcessingRequest": "Behandler forespørsel",
"PendingApproval": "Venter på godkjenning", "PendingApproval": "Venter på godkjenning",
@ -48,7 +48,7 @@
"Requests": "Forespørsler", "Requests": "Forespørsler",
"UserManagement": "Brukeradministrasjon", "UserManagement": "Brukeradministrasjon",
"Issues": "Mangler", "Issues": "Mangler",
"Vote": "Vote", "Vote": "Stem",
"Donate": "Doner!", "Donate": "Doner!",
"DonateLibraryMaintainer": "Doner til vedlikeholderen av biblioteket", "DonateLibraryMaintainer": "Doner til vedlikeholderen av biblioteket",
"DonateTooltip": "Dette er hvordan jeg overbevise min kone til å la meg bruke min fritid til å utvikle Ombi ;)", "DonateTooltip": "Dette er hvordan jeg overbevise min kone til å la meg bruke min fritid til å utvikle Ombi ;)",
@ -58,14 +58,14 @@
"UpdateDetails": "Oppdater detaljer", "UpdateDetails": "Oppdater detaljer",
"Logout": "Logg av", "Logout": "Logg av",
"OpenMobileApp": "Åpne mobilapp", "OpenMobileApp": "Åpne mobilapp",
"RecentlyAdded": "Recently Added" "RecentlyAdded": "Nylig lagt til"
}, },
"Search": { "Search": {
"Title": "Søk", "Title": "Søk",
"Paragraph": "Vil du se noe som foreløpig ikke er tilgjengelig? Ikke noe problem, bare søk etter det nedenfor og be om det!", "Paragraph": "Vil du se noe som foreløpig ikke er tilgjengelig? Ikke noe problem, bare søk etter det nedenfor og be om det!",
"MoviesTab": "Filmer", "MoviesTab": "Filmer",
"TvTab": "TV serier", "TvTab": "TV serier",
"MusicTab": "Music", "MusicTab": "Musikk",
"Suggestions": "Forslag", "Suggestions": "Forslag",
"NoResults": "Beklager, vi fant ingen resultater!", "NoResults": "Beklager, vi fant ingen resultater!",
"DigitalDate": "Digital utgivelse: {{date}}", "DigitalDate": "Digital utgivelse: {{date}}",
@ -104,7 +104,7 @@
"Paragraph": "Nedenfor kan du se dine og alle andres forespørsler, du ser også status for nedlasting og godkjenning.", "Paragraph": "Nedenfor kan du se dine og alle andres forespørsler, du ser også status for nedlasting og godkjenning.",
"MoviesTab": "Filmer", "MoviesTab": "Filmer",
"TvTab": "TV serier", "TvTab": "TV serier",
"MusicTab": "Music", "MusicTab": "Musikk",
"RequestedBy": "Etterspurt av:", "RequestedBy": "Etterspurt av:",
"Status": "Status:", "Status": "Status:",
"RequestStatus": "Status for forespørsel:", "RequestStatus": "Status for forespørsel:",
@ -128,10 +128,10 @@
"GridStatus": "Status", "GridStatus": "Status",
"ReportIssue": "Rapportér en feil", "ReportIssue": "Rapportér en feil",
"Filter": "Filter", "Filter": "Filter",
"Sort": "Sort", "Sort": "Sorter",
"SeasonNumberHeading": "Sesong: {seasonNumber}", "SeasonNumberHeading": "Sesong: {seasonNumber}",
"SortTitleAsc": "Title ▲", "SortTitleAsc": "Tittel ▲",
"SortTitleDesc": "Title ▼", "SortTitleDesc": "Tittel ▼",
"SortRequestDateAsc": "Request Date ▲", "SortRequestDateAsc": "Request Date ▲",
"SortRequestDateDesc": "Request Date ▼", "SortRequestDateDesc": "Request Date ▼",
"SortStatusAsc": "Status ▲", "SortStatusAsc": "Status ▲",
@ -168,18 +168,18 @@
"FilterHeaderAvailability": "Tilgjengelighet", "FilterHeaderAvailability": "Tilgjengelighet",
"FilterHeaderRequestStatus": "Status", "FilterHeaderRequestStatus": "Status",
"Approved": "Godkjent", "Approved": "Godkjent",
"PendingApproval": "Pending Approval" "PendingApproval": "Venter på godkjenning"
}, },
"UserManagment": { "UserManagment": {
"TvRemaining": "TV: {{remaining}}/{{total}} remaining", "TvRemaining": "TV: {{remaining}}/{{total}} gjenstående",
"MovieRemaining": "Movies: {{remaining}}/{{total}} remaining", "MovieRemaining": "Filmer: {{remaining}}/{{total}} gjenstående",
"MusicRemaining": "Music: {{remaining}}/{{total}} remaining", "MusicRemaining": "Musikk: {{remaining}}/{{total}} gjenstående",
"TvDue": "TV: {{date}}", "TvDue": "TV: {{date}}",
"MovieDue": "Movie: {{date}}", "MovieDue": "Film:{{date}}",
"MusicDue": "Music: {{date}}" "MusicDue": "Musikk:{{date}}"
}, },
"Votes": { "Votes": {
"CompletedVotesTab": "Voted", "CompletedVotesTab": "Stemt",
"VotesTab": "Votes Needed" "VotesTab": "Votes Needed"
} }
} }