Added better support for Jellyfin, we will now auto detect if it's a jellyfin server after pressing the discover button

pull/3200/head
tidusjar 5 years ago
parent 2cfad10a82
commit e5ef111087

@ -46,6 +46,17 @@ namespace Ombi.Api.Emby
return obj;
}
public async Task<PublicInfo> GetPublicInformation(string baseUrl)
{
var request = new Request("emby/System/Info/public", baseUrl, HttpMethod.Get);
AddHeaders(request, string.Empty);
var obj = await Api.Request<PublicInfo>(request);
return obj;
}
public async Task<EmbyUser> 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<MovieInformation>(mediaId, apiKey, userId, baseUrl);
}
public async Task<EpisodeInformation> GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl)
{
return await GetInformation<EpisodeInformation>(mediaId, apiKey, userId, baseUrl);

@ -29,5 +29,6 @@ namespace Ombi.Api.Emby
Task<SeriesInformation> GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl);
Task<MovieInformation> GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl);
Task<EpisodeInformation> GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl);
Task<PublicInfo> GetPublicInformation(string baseUrl);
}
}

@ -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; }
/// <summary>
/// Only populated for Jellyfin
/// </summary>
public string ProductName { get; set; }
public bool IsJellyfin => !string.IsNullOrEmpty(ProductName) && ProductName.Contains("Jellyfin");
public string OperatingSystem { get; set; }
public string Id { get; set; }
}
}

@ -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)

@ -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}";
}
}
}

@ -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
});
}

@ -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<EmbyServers> Servers { get; set; } = new List<EmbyServers>();
}

@ -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[];

@ -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<IEmbySettings> {
return this.http.post<IEmbySettings>(`${this.url}`, JSON.stringify(settings), {headers: this.headers});
}
public getUsers(): Observable<IUsersModel[]> {
return this.http.get<IUsersModel[]>(`${this.url}users`, {headers: this.headers});
}
public getPublicInfo(server: IEmbyServer): Observable<IPublicInfo> {
return this.http.post<IPublicInfo>(`${this.url}info`, JSON.stringify(server), {headers: this.headers});
}
}

@ -3,7 +3,7 @@
<div *ngIf="settings">
<fieldset>
<legend>
Emby Configuration
Emby/Jellyfin Configuration
</legend>
<div class="row">
@ -71,8 +71,8 @@
</label>
<div>
<input type="text" class="form-control-custom form-control" id="authToken" [(ngModel)]="server.serverHostname" placeholder="e.g. https://jellyfin.server.com/" value="{{server.serverHostname}}">
<small><span *ngIf="server.serverHostname">Current URL: "{{server.serverHostname}}/#!/item/item.html?id=1"</span>
<span *ngIf="!server.serverHostname">Current URL: "https://app.emby.media/#!/item/item.html?id=1</span></small>
<small><span *ngIf="server.serverHostname">Current URL: "{{server.serverHostname}}/#!/{{settings.isJellyfin ? ("itemdetails"): ("item/item")}}.html?id=1"</span>
<span *ngIf="!server.serverHostname">Current URL: "https://app.emby.media/#!/{{settings.isJellyfin ? ("itemdetails"): ("item/item")}}.html?id=1</span></small>
</div>
</div>
<div class="form-group">
@ -80,6 +80,11 @@
<button id="testEmby" type="button" (click)="test(server)" class="btn btn-primary-outline">Test Connectivity <div id="spinner"></div></button>
</div>
</div>
<div class="form-group">
<div>
<button id="discover" type="button" (click)="discoverServerInfo(server)" class="btn btn-primary-outline">Discover Server Information <div id="spinner"></div></button>
</div>
</div>
</div>
</ng-template>
</ngb-tab>
@ -88,7 +93,7 @@
<div class="col-md-1">
<div class="form-group">
<div>
<button (click)="save()" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
<button [disabled]="!hasDiscovered" (click)="save()" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
</div>
</div>
</div>

@ -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 = [];

@ -22,7 +22,7 @@
</a>
<ul class="dropdown-menu">
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Plex']">Plex</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Emby']">Emby</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Emby']">Emby/Jellyfin</a></li>
</ul>
</li>

@ -3,7 +3,7 @@
<div class="landing-block shadow">
<div class="media">
<div id="contentBody" class="media-body">
<h4 class="media-heading landing-title">Emby Authentication</h4>
<h4 class="media-heading landing-title">Emby/Jellyfin Authentication</h4>
<div *ngIf="embySettings">
<div *ngIf="embySettings.servers">
<div *ngFor="let server of embySettings.servers">
@ -26,6 +26,11 @@
<input type="checkbox" [(ngModel)]="server.ssl" id="Ssl" name="Ssl"><label for="Ssl">SSL</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" [(ngModel)]="embySettings.isJellyfin" id="isJellyfin" name="isJellyfin"><label for="isJellyfin">Jellyfin Install</label>
</div>
</div>
<div class="form-group">
<label for="username" class="control-label">Api Key</label>
<div>

@ -28,6 +28,7 @@ export class EmbyComponent implements OnInit {
}
this.embySettings = {
servers: [],
isJellyfin: false,
id: 0,
enable: true,
};

@ -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<PublicInfo> GetServerInfo([FromBody] EmbyServers server)
{
var result = await EmbyApi.GetPublicInformation(server.FullUri);
return result;
}
/// <summary>
/// Gets the emby users.
/// </summary>

Loading…
Cancel
Save