mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
Finished the emby wizard #865
This commit is contained in:
parent
7294f942d9
commit
1480e980e8
32 changed files with 606 additions and 1398 deletions
|
@ -164,11 +164,24 @@ namespace Ombi.Core.Tv
|
|||
|
||||
for (var i = 1; i <= model.SeasonCount; i++)
|
||||
{
|
||||
var season = new Season
|
||||
Season season;
|
||||
if (model.Episodes.Any(x => x.SeasonNumber == i))
|
||||
{
|
||||
seasonNumber = i,
|
||||
monitored = false // Do not monitor any seasons
|
||||
};
|
||||
season = new Season
|
||||
{
|
||||
seasonNumber = i,
|
||||
monitored = true // Do not monitor any seasons
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
season = new Season
|
||||
{
|
||||
seasonNumber = i,
|
||||
monitored = false // Do not monitor any seasons
|
||||
};
|
||||
|
||||
}
|
||||
seriesToAdd.seasons.Add(season);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
78
Ombi/Ombi.Api.Emby/EmbyApi.cs
Normal file
78
Ombi/Ombi.Api.Emby/EmbyApi.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Emby.Models;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Api.Emby
|
||||
{
|
||||
public class EmbyApi : IEmbyApi
|
||||
{
|
||||
public EmbyApi()
|
||||
{
|
||||
Api = new Api();
|
||||
}
|
||||
|
||||
private Api Api { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all users from the Emby Instance
|
||||
/// </summary>
|
||||
/// <param name="baseUri"></param>
|
||||
/// <param name="apiKey"></param>
|
||||
public async Task<List<EmbyUser>> GetUsers(Uri baseUri, string apiKey)
|
||||
{
|
||||
var request = new Request("emby/users", baseUri.ToString(), HttpMethod.Get);
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
var obj = await Api.Request<List<EmbyUser>>(request);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public async Task<EmbySystemInfo> GetSystemInformation(string apiKey, Uri baseUrl)
|
||||
{
|
||||
var request = new Request("emby/System/Info", baseUrl.ToString(), HttpMethod.Get);
|
||||
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
var obj = await Api.Request<EmbySystemInfo>(request);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public async Task<EmbyUser> LogIn(string username, string password, string apiKey, Uri baseUri)
|
||||
{
|
||||
var request = new Request("emby/users/authenticatebyname", baseUri.ToString(), HttpMethod.Post);
|
||||
|
||||
|
||||
var body = new
|
||||
{
|
||||
username,
|
||||
password = password.GetSha1Hash().ToLower(),
|
||||
passwordMd5 = password.CalcuateMd5Hash()
|
||||
};
|
||||
|
||||
request.AddJsonBody(body);
|
||||
|
||||
request.AddHeader("X-Emby-Authorization",
|
||||
$"MediaBrowser Client=\"Ombi\", Device=\"Ombi\", DeviceId=\"v3\", Version=\"v3\"");
|
||||
AddHeaders(request, apiKey);
|
||||
|
||||
var obj = await Api.Request<EmbyUser>(request);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private static void AddHeaders(Request req, string apiKey)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
req.AddHeader("X-MediaBrowser-Token", apiKey);
|
||||
}
|
||||
req.AddHeader("Accept", "application/json");
|
||||
req.AddContentHeader("Content-Type", "application/json");
|
||||
req.AddHeader("Device", "Ombi");
|
||||
}
|
||||
}
|
||||
}
|
14
Ombi/Ombi.Api.Emby/IEmbyApi.cs
Normal file
14
Ombi/Ombi.Api.Emby/IEmbyApi.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Api.Emby.Models;
|
||||
|
||||
namespace Ombi.Api.Emby
|
||||
{
|
||||
public interface IEmbyApi
|
||||
{
|
||||
Task<EmbySystemInfo> GetSystemInformation(string apiKey, Uri baseUrl);
|
||||
Task<List<EmbyUser>> GetUsers(Uri baseUri, string apiKey);
|
||||
Task<EmbyUser> LogIn(string username, string password, string apiKey, Uri baseUri);
|
||||
}
|
||||
}
|
45
Ombi/Ombi.Api.Emby/Models/EmbyConfiguration.cs
Normal file
45
Ombi/Ombi.Api.Emby/Models/EmbyConfiguration.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2017 Jamie Rees
|
||||
// File: EmbyConfiguration.cs
|
||||
// Created By: Jamie Rees
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public class EmbyConfiguration
|
||||
{
|
||||
public bool PlayDefaultAudioTrack { get; set; }
|
||||
public bool DisplayMissingEpisodes { get; set; }
|
||||
public bool DisplayUnairedEpisodes { get; set; }
|
||||
public object[] GroupedFolders { get; set; }
|
||||
public string SubtitleMode { get; set; }
|
||||
public bool DisplayCollectionsView { get; set; }
|
||||
public bool EnableLocalPassword { get; set; }
|
||||
public object[] OrderedViews { get; set; }
|
||||
public object[] LatestItemsExcludes { get; set; }
|
||||
public bool HidePlayedInLatest { get; set; }
|
||||
public bool RememberAudioSelections { get; set; }
|
||||
public bool RememberSubtitleSelections { get; set; }
|
||||
public bool EnableNextEpisodeAutoPlay { get; set; }
|
||||
}
|
||||
}
|
59
Ombi/Ombi.Api.Emby/Models/EmbyPolicy.cs
Normal file
59
Ombi/Ombi.Api.Emby/Models/EmbyPolicy.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2017 Jamie Rees
|
||||
// File: EmbyPolicy.cs
|
||||
// Created By: Jamie Rees
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public class EmbyPolicy
|
||||
{
|
||||
public bool IsAdministrator { get; set; }
|
||||
public bool IsHidden { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
public object[] BlockedTags { get; set; }
|
||||
public bool EnableUserPreferenceAccess { get; set; }
|
||||
public object[] AccessSchedules { get; set; }
|
||||
public object[] BlockUnratedItems { get; set; }
|
||||
public bool EnableRemoteControlOfOtherUsers { get; set; }
|
||||
public bool EnableSharedDeviceControl { get; set; }
|
||||
public bool EnableLiveTvManagement { get; set; }
|
||||
public bool EnableLiveTvAccess { get; set; }
|
||||
public bool EnableMediaPlayback { get; set; }
|
||||
public bool EnableAudioPlaybackTranscoding { get; set; }
|
||||
public bool EnableVideoPlaybackTranscoding { get; set; }
|
||||
public bool EnablePlaybackRemuxing { get; set; }
|
||||
public bool EnableContentDeletion { get; set; }
|
||||
public bool EnableContentDownloading { get; set; }
|
||||
public bool EnableSync { get; set; }
|
||||
public bool EnableSyncTranscoding { get; set; }
|
||||
public object[] EnabledDevices { get; set; }
|
||||
public bool EnableAllDevices { get; set; }
|
||||
public object[] EnabledChannels { get; set; }
|
||||
public bool EnableAllChannels { get; set; }
|
||||
public object[] EnabledFolders { get; set; }
|
||||
public bool EnableAllFolders { get; set; }
|
||||
public int InvalidLoginAttemptCount { get; set; }
|
||||
public bool EnablePublicSharing { get; set; }
|
||||
}
|
||||
}
|
63
Ombi/Ombi.Api.Emby/Models/EmbySystemInfo.cs
Normal file
63
Ombi/Ombi.Api.Emby/Models/EmbySystemInfo.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2017 Jamie Rees
|
||||
// File: EmbySystemInfo.cs
|
||||
// Created By: Jamie Rees
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public class EmbySystemInfo
|
||||
{
|
||||
public string SystemUpdateLevel { get; set; }
|
||||
public string OperatingSystemDisplayName { get; set; }
|
||||
public bool SupportsRunningAsService { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public bool HasPendingRestart { get; set; }
|
||||
public bool SupportsLibraryMonitor { get; set; }
|
||||
public object[] InProgressInstallations { get; set; }
|
||||
public int WebSocketPortNumber { get; set; }
|
||||
public object[] CompletedInstallations { get; set; }
|
||||
public bool CanSelfRestart { get; set; }
|
||||
public bool CanSelfUpdate { get; set; }
|
||||
public object[] FailedPluginAssemblies { get; set; }
|
||||
public string ProgramDataPath { get; set; }
|
||||
public string ItemsByNamePath { get; set; }
|
||||
public string CachePath { get; set; }
|
||||
public string LogPath { get; set; }
|
||||
public string InternalMetadataPath { get; set; }
|
||||
public string TranscodingTempPath { get; set; }
|
||||
public int HttpServerPortNumber { get; set; }
|
||||
public bool SupportsHttps { get; set; }
|
||||
public int HttpsPortNumber { get; set; }
|
||||
public bool HasUpdateAvailable { get; set; }
|
||||
public bool SupportsAutoRunAtStartup { get; set; }
|
||||
public string EncoderLocationType { get; set; }
|
||||
public string SystemArchitecture { get; set; }
|
||||
public string LocalAddress { get; set; }
|
||||
public string WanAddress { get; set; }
|
||||
public string ServerName { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string OperatingSystem { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
48
Ombi/Ombi.Api.Emby/Models/EmbyUser.cs
Normal file
48
Ombi/Ombi.Api.Emby/Models/EmbyUser.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2017 Jamie Rees
|
||||
// File: EmbyUser.cs
|
||||
// Created By: Jamie Rees
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public class EmbyUser
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string ServerId { get; set; }
|
||||
public string ConnectUserName { get; set; }
|
||||
public string ConnectUserId { get; set; }
|
||||
public string ConnectLinkType { get; set; }
|
||||
public string Id { get; set; }
|
||||
public bool HasPassword { get; set; }
|
||||
public bool HasConfiguredPassword { get; set; }
|
||||
public bool HasConfiguredEasyPassword { get; set; }
|
||||
public DateTime LastLoginDate { get; set; }
|
||||
public DateTime LastActivityDate { get; set; }
|
||||
public EmbyConfiguration Configuration { get; set; }
|
||||
public EmbyPolicy Policy { get; set; }
|
||||
}
|
||||
}
|
7
Ombi/Ombi.Api.Emby/Models/EmbyUserLogin.cs
Normal file
7
Ombi/Ombi.Api.Emby/Models/EmbyUserLogin.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public class EmbyUserLogin
|
||||
{
|
||||
public EmbyUser User { get; set; }
|
||||
}
|
||||
}
|
12
Ombi/Ombi.Api.Emby/Ombi.Api.Emby.csproj
Normal file
12
Ombi/Ombi.Api.Emby/Ombi.Api.Emby.csproj
Normal file
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.6</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ombi.Api.Emby;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Core;
|
||||
using Ombi.Core.Engine;
|
||||
|
@ -42,6 +43,7 @@ namespace Ombi.DependencyInjection
|
|||
{
|
||||
services.AddTransient<IMovieDbApi, TheMovieDbApi.TheMovieDbApi>();
|
||||
services.AddTransient<IPlexApi, PlexApi>();
|
||||
services.AddTransient<IEmbyApi, EmbyApi>();
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api.Emby\Ombi.Api.Emby.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Ombi.Helpers
|
||||
{
|
||||
|
@ -8,5 +11,34 @@ namespace Ombi.Helpers
|
|||
{
|
||||
return CultureInfo.CurrentUICulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
public static string CalcuateMd5Hash(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
var inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
var hash = md5.ComputeHash(inputBytes);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var t in hash)
|
||||
{
|
||||
sb.Append(t.ToString("x2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetSha1Hash(this string input)
|
||||
{
|
||||
var sha1 = SHA1.Create();
|
||||
return string.Join("", (sha1.ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("x2")).ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.9
|
||||
VisualStudioVersion = 15.0.26403.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
|
||||
EndProject
|
||||
|
@ -36,6 +36,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Plex", "Ombi.Api.P
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Schedule", "Ombi.Schedule\Ombi.Schedule.csproj", "{5B42ADD4-757A-47C1-9CC5-320829C5E665}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Emby", "Ombi.Api.Emby\Ombi.Api.Emby.csproj", "{08FF107D-31E1-470D-AF86-E09B015CEE06}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -82,6 +84,10 @@ Global
|
|||
{5B42ADD4-757A-47C1-9CC5-320829C5E665}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5B42ADD4-757A-47C1-9CC5-320829C5E665}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5B42ADD4-757A-47C1-9CC5-320829C5E665}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{08FF107D-31E1-470D-AF86-E09B015CEE06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{08FF107D-31E1-470D-AF86-E09B015CEE06}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{08FF107D-31E1-470D-AF86-E09B015CEE06}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{08FF107D-31E1-470D-AF86-E09B015CEE06}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -92,5 +98,6 @@ Global
|
|||
{B39E4558-C557-48E7-AA74-19C5CD809617} = {410F36CF-9C60-428A-B191-6FD90610991A}
|
||||
{63E63511-1C7F-4162-8F92-8F7391B3C8A3} = {025FB189-2FFB-4F43-A64B-6F1B5A0D2065}
|
||||
{2E1A7B91-F29B-42BC-8F1E-1CF2DCC389BA} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{08FF107D-31E1-470D-AF86-E09B015CEE06} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
45
Ombi/Ombi/Controllers/EmbyController.cs
Normal file
45
Ombi/Ombi/Controllers/EmbyController.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.Emby;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class EmbyController : BaseV1ApiController
|
||||
{
|
||||
public EmbyController(IEmbyApi emby, ISettingsService<EmbySettings> embySettings)
|
||||
{
|
||||
EmbyApi = emby;
|
||||
EmbySettings = embySettings;
|
||||
}
|
||||
|
||||
private IEmbyApi EmbyApi { get; }
|
||||
private ISettingsService<EmbySettings> EmbySettings { get; }
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<EmbySettings> SignIn([FromBody] EmbySettings request)
|
||||
{
|
||||
// Check if settings exist
|
||||
var settings = await EmbySettings.GetSettingsAsync();
|
||||
if (settings != null && !string.IsNullOrEmpty(settings.ApiKey)) return null;
|
||||
|
||||
request.Enable = true;
|
||||
// Test that we can connect
|
||||
var result = await EmbyApi.GetUsers(request.FullUri, request.ApiKey);
|
||||
|
||||
if (result != null && result.Any())
|
||||
{
|
||||
request.AdministratorId = result.FirstOrDefault(x => x.Policy.IsAdministrator)?.Id ?? string.Empty;
|
||||
await EmbySettings.SaveSettingsAsync(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Api.Plex.Models;
|
||||
|
@ -12,6 +13,7 @@ using Ombi.Core.Settings.Models.External;
|
|||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class PlexController : BaseV1ApiController
|
||||
{
|
||||
public PlexController(IPlexApi plexApi, ISettingsService<PlexSettings> plexSettings)
|
||||
|
@ -24,8 +26,13 @@ namespace Ombi.Controllers
|
|||
private ISettingsService<PlexSettings> PlexSettings { get; }
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<PlexAuthentication> SignIn([FromBody] UserRequest request)
|
||||
{
|
||||
// Do we already have settings?
|
||||
var settings = await PlexSettings.GetSettingsAsync();
|
||||
if (settings != null && !string.IsNullOrEmpty(settings.PlexAuthToken)) return null;
|
||||
|
||||
var result = await PlexApi.SignIn(request);
|
||||
if (!string.IsNullOrEmpty(result.user?.authentication_token))
|
||||
{
|
||||
|
|
|
@ -18,19 +18,26 @@
|
|||
<Content Include="wwwroot\app\auth\auth.module.ts" />
|
||||
<Content Include="wwwroot\app\auth\auth.service.ts" />
|
||||
<Content Include="wwwroot\app\auth\IUserLogin.ts" />
|
||||
<Content Include="wwwroot\app\interfaces\IEmby.ts" />
|
||||
<Content Include="wwwroot\app\interfaces\ISettings.js">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\interfaces\ISettings.js.map">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\interfaces\ISettings.ts">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\login\login.component.html" />
|
||||
<Content Include="wwwroot\app\login\login.component.ts" />
|
||||
<Content Include="wwwroot\app\services\identity - Copy.service.js">
|
||||
<DependentUpon>identity - Copy.service.ts</DependentUpon>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\services\identity - Copy.service.js.map">
|
||||
<DependentUpon>identity - Copy.service.js</DependentUpon>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\services\identity - Copy.service.ts">
|
||||
<Content Include="wwwroot\app\services\applications\emby.service.js" />
|
||||
<Content Include="wwwroot\app\services\applications\emby.service.js.map" />
|
||||
<Content Include="wwwroot\app\services\applications\emby.service.ts">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\services\applications\plex.service.js" />
|
||||
<Content Include="wwwroot\app\services\applications\plex.service.js.map" />
|
||||
<Content Include="wwwroot\app\services\applications\plex.service.ts" />
|
||||
<Content Include="wwwroot\app\services\identity.service.js" />
|
||||
<Content Include="wwwroot\app\services\identity.service.js.map" />
|
||||
<Content Include="wwwroot\app\services\identity.service.ts" />
|
||||
|
@ -45,27 +52,14 @@
|
|||
<Content Include="wwwroot\app\services\status.service.js" />
|
||||
<Content Include="wwwroot\app\services\status.service.js.map" />
|
||||
<Content Include="wwwroot\app\services\status.service.ts" />
|
||||
<Content Include="wwwroot\app\services\useridentity.service.ts" />
|
||||
<Content Include="wwwroot\app\settings\emby\emby.component.html" />
|
||||
<Content Include="wwwroot\app\settings\emby\emby.component.js" />
|
||||
<Content Include="wwwroot\app\settings\emby\emby.component.js.map" />
|
||||
<Content Include="wwwroot\app\settings\emby\emby.component.ts" />
|
||||
<Content Include="wwwroot\app\settings\emby\plex.component.html">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\settings\emby\plex.component.js">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\settings\emby\plex.component.ts">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\settings\interfaces\ISettings.ts" />
|
||||
<Content Include="wwwroot\app\settings\plex\plex.component.html">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\settings\plex\ombi.component.js.map">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="wwwroot\app\settings\plex\plex.component.js" />
|
||||
<Content Include="wwwroot\app\settings\plex\plex.component.js.map" />
|
||||
<Content Include="wwwroot\app\settings\plex\plex.component.ts" />
|
||||
|
@ -77,6 +71,10 @@
|
|||
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.js" />
|
||||
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.js.map" />
|
||||
<Content Include="wwwroot\app\wizard\createadmin\createadmin.component.ts" />
|
||||
<Content Include="wwwroot\app\wizard\emby\emby.component.html" />
|
||||
<Content Include="wwwroot\app\wizard\emby\emby.component.js" />
|
||||
<Content Include="wwwroot\app\wizard\emby\emby.component.js.map" />
|
||||
<Content Include="wwwroot\app\wizard\emby\emby.component.ts" />
|
||||
<Content Include="wwwroot\app\wizard\mediaserver\mediaserver.component.html">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
|
@ -121,6 +119,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ombi.Api.Emby\Ombi.Api.Emby.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\Ombi.Mapping\Ombi.Mapping.csproj" />
|
||||
|
|
|
@ -19,10 +19,19 @@
|
|||
<ul class="nav navbar-nav">
|
||||
<li><a [routerLinkActive]="['active']" [routerLink]="['/requests']"><i class="fa fa-plus"></i> Requests</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a [routerLinkActive]="['active']" [routerLink]="['/Settings/Ombi']"><i class="fa fa-cog"></i> Settings</a></li>
|
||||
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a [routerLinkActive]="['active']" [routerLink]="['/Settings/Ombi']"><i class="fa fa-cog"></i> Settings</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-user"></i> Welcome {{username}} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a [routerLink]="['/user/changepassword']"><i class="fa fa-key"></i> Change Password</a></li>
|
||||
<li><a (click)="logOut()"><i class="fa fa-sign-out"></i> Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { NotificationService } from './services/notification.service';
|
||||
import { AuthService } from './auth/auth.service';
|
||||
|
||||
|
@ -7,15 +8,26 @@ import { AuthService } from './auth/auth.service';
|
|||
moduleId: module.id,
|
||||
templateUrl: './app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor(public notificationService: NotificationService, public authService: AuthService) {
|
||||
this.showNav = true;
|
||||
//console.log(this.route);
|
||||
//if (this.route.("/Wizard/*") !== -1) {
|
||||
// this.showNav = false;
|
||||
//}
|
||||
constructor(public notificationService: NotificationService, public authService: AuthService, private router: Router) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.router.events.subscribe(() => {
|
||||
this.username = localStorage.getItem('currentUser');
|
||||
this.showNav = this.authService.loggedIn();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
logOut() {
|
||||
this.authService.logout();
|
||||
this.router.navigate(["login"]);
|
||||
}
|
||||
|
||||
username:string;
|
||||
showNav :boolean;
|
||||
}
|
|
@ -28,6 +28,7 @@ export class AuthService extends ServiceHelpers {
|
|||
|
||||
logout() {
|
||||
localStorage.removeItem('id_token');
|
||||
localStorage.removeItem('currentUser');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
export interface IExternalSettings extends ISettings {
|
||||
ssl: boolean,
|
||||
subDir: boolean,
|
||||
subDir: string,
|
||||
ip: string,
|
||||
port:number
|
||||
}
|
||||
|
||||
export interface IOmbiSettings extends ISettings {
|
||||
port: number,
|
||||
//baseUrl:string,
|
||||
//baseUrl:string,
|
||||
collectAnalyticData: boolean,
|
||||
wizard: boolean,
|
||||
apiKey:string
|
|
@ -28,6 +28,8 @@ export class LoginComponent {
|
|||
this.authService.login({ password: this.password, username: this.username })
|
||||
.subscribe(x => {
|
||||
localStorage.setItem("id_token", x.access_token);
|
||||
localStorage.setItem('currentUser', this.username);
|
||||
|
||||
if (this.authService.loggedIn()) {
|
||||
this.router.navigate(['search']);
|
||||
} else {
|
||||
|
|
20
Ombi/Ombi/wwwroot/app/services/applications/emby.service.ts
Normal file
20
Ombi/Ombi/wwwroot/app/services/applications/emby.service.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ServiceHelpers } from '../service.helpers';
|
||||
|
||||
import { IEmbySettings } from '../../interfaces/ISettings'
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class EmbyService extends ServiceHelpers {
|
||||
constructor(http: Http) {
|
||||
super(http, '/api/v1/Emby/');
|
||||
}
|
||||
|
||||
logIn(settings: IEmbySettings): Observable<IEmbySettings> {
|
||||
return this.http.post(`${this.url}/`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
import { Http } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ServiceHelpers } from './service.helpers';
|
||||
import { ServiceHelpers } from '../service.helpers';
|
||||
|
||||
import { IPlexAuthentication } from '../interfaces/IPlex'
|
||||
import { IPlexAuthentication } from '../../interfaces/IPlex'
|
||||
|
||||
|
||||
@Injectable()
|
|
@ -3,8 +3,7 @@ import { AuthHttp } from 'angular2-jwt';
|
|||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ServiceAuthHelpers } from './service.helpers';
|
||||
import { IOmbiSettings, IEmbySettings, IPlexSettings } from '../settings/interfaces/ISettings';
|
||||
|
||||
import { IOmbiSettings, IEmbySettings, IPlexSettings } from '../interfaces/ISettings';
|
||||
|
||||
@Injectable()
|
||||
export class SettingsService extends ServiceAuthHelpers {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { IEmbySettings } from '../interfaces/ISettings'
|
||||
import { IEmbySettings } from '../../interfaces/ISettings'
|
||||
import { SettingsService } from '../../services/settings.service';
|
||||
import { NotificationService } from "../../services/notification.service";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { IOmbiSettings } from '../interfaces/ISettings'
|
||||
import { IOmbiSettings } from '../../interfaces/ISettings'
|
||||
import { SettingsService } from '../../services/settings.service';
|
||||
import { NotificationService } from "../../services/notification.service";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { IPlexSettings } from '../interfaces/ISettings'
|
||||
import { IPlexSettings } from '../../interfaces/ISettings'
|
||||
import { SettingsService } from '../../services/settings.service';
|
||||
import { NotificationService } from "../../services/notification.service";
|
||||
|
||||
|
|
30
Ombi/Ombi/wwwroot/app/wizard/emby/emby.component.html
Normal file
30
Ombi/Ombi/wwwroot/app/wizard/emby/emby.component.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
<h4 class="media-heading landing-title">Emby Authentication</h4>
|
||||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Emby Hostname or IP Address</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="embySettings.ip" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="192.168.1.1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="portNumber" class="control-label">Port</label>
|
||||
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="embySettings.port" class="form-control form-control-custom " id="portNumber" name="Port" value="{{embySettings.port}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" [(ngModel)]="embySettings.ssl" id="Ssl" name="Ssl"><label for="Ssl">SSL</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label">Api Key</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="embySettings.apiKey" class="form-control form-control-custom" id="apiKey" name="ApiKey" placeholder="ApiKey">
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<a (click)="save()" id="embyApiKeySave" class="btn btn-primary-outline">Next <div id="spinner"></div></a>
|
||||
</div>
|
45
Ombi/Ombi/wwwroot/app/wizard/emby/emby.component.ts
Normal file
45
Ombi/Ombi/wwwroot/app/wizard/emby/emby.component.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { EmbyService } from '../../services/applications/emby.service';
|
||||
import { NotificationService } from '../../services/notification.service';
|
||||
|
||||
import { IEmbySettings } from '../../interfaces/ISettings';
|
||||
|
||||
@Component({
|
||||
selector: 'ombi',
|
||||
moduleId: module.id,
|
||||
templateUrl: './emby.component.html',
|
||||
})
|
||||
export class EmbyComponent {
|
||||
|
||||
constructor(private embyService: EmbyService,
|
||||
private router: Router,
|
||||
private notificationService: NotificationService) {
|
||||
|
||||
this.embySettings = {
|
||||
administratorId: "",
|
||||
apiKey: "",
|
||||
enable: true,
|
||||
enableEpisodeSearching: true,
|
||||
id: 0,
|
||||
ip: "",
|
||||
port: 8096,
|
||||
ssl: false,
|
||||
subDir: "",
|
||||
}
|
||||
}
|
||||
|
||||
private embySettings: IEmbySettings;
|
||||
|
||||
|
||||
save() {
|
||||
this.embyService.logIn(this.embySettings).subscribe(x => {
|
||||
if (x == null || !x.apiKey) {
|
||||
this.notificationService.error("Could Not Authenticate", "Username or password was incorrect. Could not authenticate with Emby.");
|
||||
return;
|
||||
}
|
||||
this.router.navigate(['Wizard/CreateAdmin']);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { PlexService } from '../../services/plex.service';
|
||||
import { PlexService } from '../../services/applications/plex.service';
|
||||
import { NotificationService } from '../../services/notification.service';
|
||||
|
||||
import { IPlexAuthentication } from '../../interfaces/IPlex';
|
||||
|
|
|
@ -7,14 +7,17 @@ import { WelcomeComponent } from './welcome/welcome.component';
|
|||
import { MediaServerComponent } from './mediaserver/mediaserver.component';
|
||||
import { PlexComponent } from './plex/plex.component';
|
||||
import { CreateAdminComponent } from './createadmin/createadmin.component';
|
||||
import { EmbyComponent } from './emby/emby.component';
|
||||
|
||||
import { PlexService } from '../services/plex.service';
|
||||
import { PlexService } from '../services/applications/plex.service';
|
||||
import { EmbyService } from '../services/applications/emby.service';
|
||||
import { IdentityService } from '../services/identity.service';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'Wizard', component: WelcomeComponent},
|
||||
{ path: 'Wizard/MediaServer', component: MediaServerComponent},
|
||||
{ path: 'Wizard/Plex', component: PlexComponent},
|
||||
{ path: 'Wizard/Emby', component: EmbyComponent},
|
||||
{ path: 'Wizard/CreateAdmin', component: CreateAdminComponent},
|
||||
];
|
||||
|
||||
|
@ -28,14 +31,16 @@ const routes: Routes = [
|
|||
WelcomeComponent,
|
||||
MediaServerComponent,
|
||||
PlexComponent,
|
||||
CreateAdminComponent
|
||||
CreateAdminComponent,
|
||||
EmbyComponent
|
||||
],
|
||||
exports: [
|
||||
RouterModule
|
||||
],
|
||||
providers: [
|
||||
PlexService,
|
||||
IdentityService
|
||||
IdentityService,
|
||||
EmbyService
|
||||
],
|
||||
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue