More work

This commit is contained in:
Jamie Rees 2019-04-23 13:34:25 +01:00
parent bc026e7e72
commit 396740b2c4
7 changed files with 87 additions and 13 deletions

View file

@ -1,28 +1,56 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Xml; using Microsoft.EntityFrameworkCore;
using Ombi.Core.Authentication;
using Ombi.Helpers;
namespace Ombi.Hubs namespace Ombi.Hubs
{ {
public class NotificationHub : Hub public class NotificationHub : Hub
{ {
public static ConcurrentDictionary<string, string> UsersOnline = new ConcurrentDictionary<string, string>(); public NotificationHub(OmbiUserManager um)
{
_userManager = um;
}
public override Task OnConnectedAsync() public static ConcurrentDictionary<string, HubUsers> UsersOnline = new ConcurrentDictionary<string, HubUsers>();
public static List<string> AdminConnectionIds
{
get
{
return UsersOnline.Where(x => x.Value.Roles.Contains(OmbiRoles.Admin)).Select(x => x.Key).ToList();
}
}
public const string NotificationEvent = "Notification";
private readonly OmbiUserManager _userManager;
public override async Task OnConnectedAsync()
{ {
var identity = (ClaimsIdentity) Context.User.Identity; var identity = (ClaimsIdentity) Context.User.Identity;
var userIdClaim = identity.Claims.FirstOrDefault(x => x.Type.Equals("Id", StringComparison.InvariantCultureIgnoreCase)); var userIdClaim = identity.Claims.FirstOrDefault(x => x.Type.Equals("Id", StringComparison.InvariantCultureIgnoreCase));
if (userIdClaim == null) if (userIdClaim == null)
{ {
return base.OnConnectedAsync(); await base.OnConnectedAsync();
return;
} }
UsersOnline.TryAdd(Context.ConnectionId, userIdClaim.Value); var user = await _userManager.Users.
return base.OnConnectedAsync(); FirstOrDefaultAsync(x => x.Id.Equals(userIdClaim.Value, StringComparison.InvariantCultureIgnoreCase));
var claims = await _userManager.GetRolesAsync(user);
UsersOnline.TryAdd(Context.ConnectionId, new HubUsers
{
UserId = userIdClaim.Value,
Roles = claims
});
await base.OnConnectedAsync();
} }
public override Task OnDisconnectedAsync(Exception exception) public override Task OnDisconnectedAsync(Exception exception)
@ -33,7 +61,13 @@ namespace Ombi.Hubs
public Task Notification(string data) public Task Notification(string data)
{ {
return Clients.All.SendAsync("Notification", data); return Clients.All.SendAsync(NotificationEvent, data);
} }
} }
public class HubUsers
{
public string UserId { get; set; }
public IList<string> Roles { get; set; }
}
} }

View file

@ -1,13 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.0" /> <PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.AspNetCore.SignalR.Core"> <Reference Include="Microsoft.AspNetCore.SignalR.Core">
<HintPath>..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.signalr.core\1.1.0\lib\netstandard2.0\Microsoft.AspNetCore.SignalR.Core.dll</HintPath> <HintPath>..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.signalr.core\1.1.0\lib\netstandard2.0\Microsoft.AspNetCore.SignalR.Core.dll</HintPath>

View file

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire; using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Ombi.Api.Plex; using Ombi.Api.Plex;
@ -37,6 +38,7 @@ using Ombi.Api.Plex.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External; using Ombi.Core.Settings.Models.External;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Hubs;
using Ombi.Schedule.Jobs.Ombi; using Ombi.Schedule.Jobs.Ombi;
using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Schedule.Jobs.Plex.Interfaces;
using Ombi.Schedule.Jobs.Plex.Models; using Ombi.Schedule.Jobs.Plex.Models;
@ -48,7 +50,7 @@ namespace Ombi.Schedule.Jobs.Plex
public class PlexContentSync : IPlexContentSync public class PlexContentSync : IPlexContentSync
{ {
public PlexContentSync(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentSync> logger, IPlexContentRepository repo, public PlexContentSync(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentSync> logger, IPlexContentRepository repo,
IPlexEpisodeSync epsiodeSync, IRefreshMetadata metadataRefresh, IPlexAvailabilityChecker checker) IPlexEpisodeSync epsiodeSync, IRefreshMetadata metadataRefresh, IPlexAvailabilityChecker checker, IHubContext<NotificationHub> hub)
{ {
Plex = plex; Plex = plex;
PlexApi = plexApi; PlexApi = plexApi;
@ -57,6 +59,7 @@ namespace Ombi.Schedule.Jobs.Plex
EpisodeSync = epsiodeSync; EpisodeSync = epsiodeSync;
Metadata = metadataRefresh; Metadata = metadataRefresh;
Checker = checker; Checker = checker;
Notification = hub;
} }
private ISettingsService<PlexSettings> Plex { get; } private ISettingsService<PlexSettings> Plex { get; }
@ -66,17 +69,23 @@ namespace Ombi.Schedule.Jobs.Plex
private IPlexEpisodeSync EpisodeSync { get; } private IPlexEpisodeSync EpisodeSync { get; }
private IRefreshMetadata Metadata { get; } private IRefreshMetadata Metadata { get; }
private IPlexAvailabilityChecker Checker { get; } private IPlexAvailabilityChecker Checker { get; }
private IHubContext<NotificationHub> Notification { get; set; }
public async Task CacheContent(bool recentlyAddedSearch = false) public async Task CacheContent(bool recentlyAddedSearch = false)
{ {
var plexSettings = await Plex.GetSettingsAsync(); var plexSettings = await Plex.GetSettingsAsync();
if (!plexSettings.Enable) if (!plexSettings.Enable)
{ {
return; return;
} }
await Notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, recentlyAddedSearch ? "Plex Recently Added Sync Started" : "Plex Content Sync Started");
if (!ValidateSettings(plexSettings)) if (!ValidateSettings(plexSettings))
{ {
Logger.LogError("Plex Settings are not valid"); Logger.LogError("Plex Settings are not valid");
await Notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, recentlyAddedSearch ? "Plex Recently Added Sync, Settings Not Valid" : "Plex Content, Settings Not Valid");
return; return;
} }
var processedContent = new ProcessedContent(); var processedContent = new ProcessedContent();
@ -94,6 +103,8 @@ namespace Ombi.Schedule.Jobs.Plex
} }
catch (Exception e) catch (Exception e)
{ {
await Notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, recentlyAddedSearch ? "Plex Recently Added Sync Errored" : "Plex Content Sync Errored");
Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content"); Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content");
} }
@ -113,6 +124,9 @@ namespace Ombi.Schedule.Jobs.Plex
{ {
BackgroundJob.Enqueue(() => Checker.Start()); BackgroundJob.Enqueue(() => Checker.Start());
} }
await Notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, recentlyAddedSearch ? "Plex Recently Added Sync Finished" : "Plex Content Sync Finished");
} }
private async Task<ProcessedContent> StartTheCache(PlexSettings plexSettings, bool recentlyAddedSearch) private async Task<ProcessedContent> StartTheCache(PlexSettings plexSettings, bool recentlyAddedSearch)

View file

@ -35,9 +35,16 @@
<ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" /> <ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" />
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" /> <ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" /> <ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
<ProjectReference Include="..\Ombi.Hubs\Ombi.Hubs.csproj" />
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" /> <ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" /> <ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" /> <ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.SignalR.Core">
<HintPath>..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.signalr.core\1.1.0\lib\netstandard2.0\Microsoft.AspNetCore.SignalR.Core.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View file

@ -26,6 +26,7 @@ export class SignalRNotificationService {
this.hubConnection.on("Notification", (data: any) => { this.hubConnection.on("Notification", (data: any) => {
debugger;
this.Notification.emit(data); this.Notification.emit(data);
}); });

View file

@ -4,12 +4,14 @@ using Microsoft.AspNetCore.Mvc;
using Ombi.Api.TheMovieDb.Models; using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.Engine.V2; using Ombi.Core.Engine.V2;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Ombi.Core; using Ombi.Core;
using Ombi.Core.Engine.Interfaces; using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Core.Models.Search.V2; using Ombi.Core.Models.Search.V2;
using Ombi.Helpers;
using Ombi.Hubs; using Ombi.Hubs;
using Ombi.Models; using Ombi.Models;
@ -36,5 +38,16 @@ namespace Ombi.Controllers.V2
{ {
await _hub.Clients.All.SendAsync("Notification", searchTerm); await _hub.Clients.All.SendAsync("Notification", searchTerm);
} }
/// <summary>
/// Returns search results for both TV and Movies
/// </summary>
/// <returns></returns>
[HttpGet("admin/{searchTerm}")]
public async Task Admin(string searchTerm)
{
var admins = NotificationHub.UsersOnline.Where(x => x.Value.Roles.Contains(OmbiRoles.Admin)).Select(x => x.Key).ToList();
await _hub.Clients.Clients(admins).SendAsync("Notification", searchTerm);
}
} }
} }

View file

@ -110,9 +110,10 @@ namespace Ombi
services.AddCors(o => o.AddPolicy("MyPolicy", builder => services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{ {
builder.AllowAnyOrigin() builder.AllowAnyHeader()
.AllowAnyMethod() .AllowAnyMethod()
.AllowAnyHeader().AllowCredentials(); .SetIsOriginAllowed(isOriginAllowed: _ => true)
.AllowCredentials();
})); }));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);