diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index 43a2badb6..7cb702fbc 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -46,6 +46,17 @@ namespace Ombi.Api.Emby return obj; } + public async Task GetPublicInformation(string baseUrl) + { + var request = new Request("emby/System/Info/public", baseUrl, HttpMethod.Get); + + AddHeaders(request, string.Empty); + + var obj = await Api.Request(request); + + return obj; + } + public async Task LogIn(string username, string password, string apiKey, string baseUri) { var request = new Request("emby/users/authenticatebyname", baseUri, HttpMethod.Post); @@ -124,6 +135,7 @@ namespace Ombi.Api.Emby { return await GetInformation(mediaId, apiKey, userId, baseUrl); } + public async Task GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl) { return await GetInformation(mediaId, apiKey, userId, baseUrl); diff --git a/src/Ombi.Api.Emby/IEmbyApi.cs b/src/Ombi.Api.Emby/IEmbyApi.cs index b4641ea5f..3c29878b7 100644 --- a/src/Ombi.Api.Emby/IEmbyApi.cs +++ b/src/Ombi.Api.Emby/IEmbyApi.cs @@ -29,5 +29,6 @@ namespace Ombi.Api.Emby Task GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl); Task GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl); Task GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl); + Task GetPublicInformation(string baseUrl); } } \ No newline at end of file diff --git a/src/Ombi.Api.Emby/Models/PublicInfo.cs b/src/Ombi.Api.Emby/Models/PublicInfo.cs new file mode 100644 index 000000000..01432d3c5 --- /dev/null +++ b/src/Ombi.Api.Emby/Models/PublicInfo.cs @@ -0,0 +1,19 @@ +namespace Ombi.Api.Emby.Models +{ + public class PublicInfo + { + public string LocalAddress { get; set; } + public string ServerName { get; set; } + public string Version { get; set; } + /// + /// Only populated for Jellyfin + /// + public string ProductName { get; set; } + + public bool IsJellyfin => !string.IsNullOrEmpty(ProductName) && ProductName.Contains("Jellyfin"); + + public string OperatingSystem { get; set; } + public string Id { get; set; } + } + +} \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs index 50fff3eb6..f235c635e 100644 --- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs @@ -68,11 +68,11 @@ namespace Ombi.Core.Rule.Rules.Search var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null); if ((server?.ServerHostname ?? string.Empty).HasValue()) { - obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerHostname); + obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerHostname, s.IsJellyfin); } else { - obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId); + obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, null, s.IsJellyfin); } if (obj.Type == RequestType.TvShow) diff --git a/src/Ombi.Helpers/EmbyHelper.cs b/src/Ombi.Helpers/EmbyHelper.cs index 7ab792ef7..e22bb1d99 100644 --- a/src/Ombi.Helpers/EmbyHelper.cs +++ b/src/Ombi.Helpers/EmbyHelper.cs @@ -1,21 +1,21 @@ -using System; -using System.Globalization; -using System.Collections.Generic; -using System.Text; - -namespace Ombi.Helpers +namespace Ombi.Helpers { public class EmbyHelper { - public static string GetEmbyMediaUrl(string mediaId, string customerServerUrl = null) + public static string GetEmbyMediaUrl(string mediaId, string customerServerUrl = null, bool isJellyfin = false) { + string path = "item/item"; + if (isJellyfin) + { + path = "itemdetails"; + } if (customerServerUrl.HasValue()) { - return $"{customerServerUrl}#!/item/item.html?id={mediaId}"; + return $"{customerServerUrl}#!/{path}.html?id={mediaId}"; } else { - return $"https://app.emby.media/#!/item/item.html?id={mediaId}"; + return $"https://app.emby.media/#!/{path}.html?id={mediaId}"; } } } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index a64b7bb30..bffce3ccc 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -45,11 +45,11 @@ namespace Ombi.Schedule.Jobs.Emby { try { - await StartServerCache(server); + await StartServerCache(server, embySettings); } catch (Exception e) { - _logger.LogError(e, "Exception when caching Emby for server {0}", server.Name); + _logger.LogError(e, "Exception when caching {1} for server {0}", server.Name, embySettings.IsJellyfin ? "Jellyfin" : "Emby"); } } @@ -60,7 +60,7 @@ namespace Ombi.Schedule.Jobs.Emby } - private async Task StartServerCache(EmbyServers server) + private async Task StartServerCache(EmbyServers server, EmbySettings settings) { if (!ValidateSettings(server)) return; @@ -135,7 +135,7 @@ namespace Ombi.Schedule.Jobs.Emby Title = tvShow.Name, Type = EmbyMediaType.Series, EmbyId = tvShow.Id, - Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server.ServerHostname), + Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server.ServerHostname, settings.IsJellyfin), AddedAt = DateTime.UtcNow }); } diff --git a/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs b/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs index 595733dc1..3ade5746b 100644 --- a/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs @@ -6,6 +6,7 @@ namespace Ombi.Core.Settings.Models.External public sealed class EmbySettings : Ombi.Settings.Settings.Models.Settings { public bool Enable { get; set; } + public bool IsJellyfin { get; set; } public List Servers { get; set; } = new List(); } diff --git a/src/Ombi/ClientApp/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/app/interfaces/ISettings.ts index 2145ba9e6..75aaf7605 100644 --- a/src/Ombi/ClientApp/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/ISettings.ts @@ -33,6 +33,7 @@ export interface IUpdateSettings extends ISettings { export interface IEmbySettings extends ISettings { enable: boolean; + isJellyfin: boolean; servers: IEmbyServer[]; } @@ -44,6 +45,11 @@ export interface IEmbyServer extends IExternalSettings { serverHostname: string; } +export interface IPublicInfo { + serverName: string; + isJellyfin: boolean; +} + export interface IPlexSettings extends ISettings { enable: boolean; servers: IPlexServer[]; diff --git a/src/Ombi/ClientApp/app/services/applications/emby.service.ts b/src/Ombi/ClientApp/app/services/applications/emby.service.ts index d4e52a630..9b433f5b7 100644 --- a/src/Ombi/ClientApp/app/services/applications/emby.service.ts +++ b/src/Ombi/ClientApp/app/services/applications/emby.service.ts @@ -5,7 +5,7 @@ import { Observable } from "rxjs"; import { ServiceHelpers } from "../service.helpers"; -import { IEmbySettings, IUsersModel } from "../../interfaces"; +import { IEmbyServer, IEmbySettings, IPublicInfo, IUsersModel } from "../../interfaces"; @Injectable() export class EmbyService extends ServiceHelpers { @@ -16,8 +16,13 @@ export class EmbyService extends ServiceHelpers { public logIn(settings: IEmbySettings): Observable { return this.http.post(`${this.url}`, JSON.stringify(settings), {headers: this.headers}); } + public getUsers(): Observable { return this.http.get(`${this.url}users`, {headers: this.headers}); } + + public getPublicInfo(server: IEmbyServer): Observable { + return this.http.post(`${this.url}info`, JSON.stringify(server), {headers: this.headers}); + } } diff --git a/src/Ombi/ClientApp/app/settings/emby/emby.component.html b/src/Ombi/ClientApp/app/settings/emby/emby.component.html index 32759fc16..18d42bb47 100644 --- a/src/Ombi/ClientApp/app/settings/emby/emby.component.html +++ b/src/Ombi/ClientApp/app/settings/emby/emby.component.html @@ -3,7 +3,7 @@
- Emby Configuration + Emby/Jellyfin Configuration
@@ -71,8 +71,8 @@
- Current URL: "{{server.serverHostname}}/#!/item/item.html?id=1" - Current URL: "https://app.emby.media/#!/item/item.html?id=1 + Current URL: "{{server.serverHostname}}/#!/{{settings.isJellyfin ? ("itemdetails"): ("item/item")}}.html?id=1" + Current URL: "https://app.emby.media/#!/{{settings.isJellyfin ? ("itemdetails"): ("item/item")}}.html?id=1
@@ -80,6 +80,11 @@
+
+
+ +
+
@@ -88,7 +93,7 @@
- +
diff --git a/src/Ombi/ClientApp/app/settings/emby/emby.component.ts b/src/Ombi/ClientApp/app/settings/emby/emby.component.ts index c2752a973..bc1d2bbb2 100644 --- a/src/Ombi/ClientApp/app/settings/emby/emby.component.ts +++ b/src/Ombi/ClientApp/app/settings/emby/emby.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from "@angular/core"; import { IEmbyServer, IEmbySettings } from "../../interfaces"; -import { JobService, NotificationService, SettingsService, TesterService } from "../../services"; +import { EmbyService, JobService, NotificationService, SettingsService, TesterService } from "../../services"; @Component({ templateUrl: "./emby.component.html", @@ -9,16 +9,25 @@ import { JobService, NotificationService, SettingsService, TesterService } from export class EmbyComponent implements OnInit { public settings: IEmbySettings; + public hasDiscovered: boolean; constructor(private settingsService: SettingsService, private notificationService: NotificationService, private testerService: TesterService, - private jobService: JobService) { } + private jobService: JobService, + private embyService: EmbyService) { } public ngOnInit() { this.settingsService.getEmby().subscribe(x => this.settings = x); } + public async discoverServerInfo(server: IEmbyServer) { + const result = await this.embyService.getPublicInfo(server).toPromise(); + this.settings.isJellyfin = result.isJellyfin; + server.name = result.serverName; + this.hasDiscovered = true; + } + public addTab() { if (this.settings.servers == null) { this.settings.servers = []; diff --git a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html index 81f901ecc..d58c96e2e 100644 --- a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html @@ -22,7 +22,7 @@ diff --git a/src/Ombi/ClientApp/app/wizard/emby/emby.component.html b/src/Ombi/ClientApp/app/wizard/emby/emby.component.html index c43aa7c6f..18e820e2c 100644 --- a/src/Ombi/ClientApp/app/wizard/emby/emby.component.html +++ b/src/Ombi/ClientApp/app/wizard/emby/emby.component.html @@ -3,7 +3,7 @@
-

Emby Authentication

+

Emby/Jellyfin Authentication

@@ -26,6 +26,11 @@
+
+
+ +
+
diff --git a/src/Ombi/ClientApp/app/wizard/emby/emby.component.ts b/src/Ombi/ClientApp/app/wizard/emby/emby.component.ts index f22fa915b..5a8c46b7b 100644 --- a/src/Ombi/ClientApp/app/wizard/emby/emby.component.ts +++ b/src/Ombi/ClientApp/app/wizard/emby/emby.component.ts @@ -28,6 +28,7 @@ export class EmbyComponent implements OnInit { } this.embySettings = { servers: [], + isJellyfin: false, id: 0, enable: true, }; diff --git a/src/Ombi/Controllers/External/EmbyController.cs b/src/Ombi/Controllers/External/EmbyController.cs index df865be61..98c15fc56 100644 --- a/src/Ombi/Controllers/External/EmbyController.cs +++ b/src/Ombi/Controllers/External/EmbyController.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Ombi.Api.Emby; +using Ombi.Api.Emby.Models; using Ombi.Api.Plex; using Ombi.Attributes; using Ombi.Core.Settings; @@ -60,6 +61,13 @@ namespace Ombi.Controllers.External return null; } + [HttpPost("info")] + public async Task GetServerInfo([FromBody] EmbyServers server) + { + var result = await EmbyApi.GetPublicInformation(server.FullUri); + return result; + } + /// /// Gets the emby users. ///