fix mixed platform directory mapping (#106)
* sync plex platform and platform version * fix mixed-platform path replacements
This commit is contained in:
@@ -64,6 +64,8 @@ namespace ErsatzTV.Application.Plex.Commands
|
|||||||
await maybeExisting.Match(
|
await maybeExisting.Match(
|
||||||
existing =>
|
existing =>
|
||||||
{
|
{
|
||||||
|
existing.Platform = server.Platform;
|
||||||
|
existing.PlatformVersion = server.PlatformVersion;
|
||||||
existing.ProductVersion = server.ProductVersion;
|
existing.ProductVersion = server.ProductVersion;
|
||||||
existing.ServerName = server.ServerName;
|
existing.ServerName = server.ServerName;
|
||||||
var toAdd = server.Connections
|
var toAdd = server.Connections
|
||||||
|
|||||||
+10
-33
@@ -1,17 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ErsatzTV.Core;
|
using ErsatzTV.Core;
|
||||||
using ErsatzTV.Core.Domain;
|
using ErsatzTV.Core.Domain;
|
||||||
using ErsatzTV.Core.Errors;
|
using ErsatzTV.Core.Errors;
|
||||||
using ErsatzTV.Core.FFmpeg;
|
using ErsatzTV.Core.FFmpeg;
|
||||||
using ErsatzTV.Core.Interfaces.Metadata;
|
using ErsatzTV.Core.Interfaces.Metadata;
|
||||||
|
using ErsatzTV.Core.Interfaces.Plex;
|
||||||
using ErsatzTV.Core.Interfaces.Repositories;
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
using LanguageExt;
|
using LanguageExt;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using static LanguageExt.Prelude;
|
using static LanguageExt.Prelude;
|
||||||
|
|
||||||
namespace ErsatzTV.Application.Streaming.Queries
|
namespace ErsatzTV.Application.Streaming.Queries
|
||||||
@@ -22,26 +19,23 @@ namespace ErsatzTV.Application.Streaming.Queries
|
|||||||
private readonly IConfigElementRepository _configElementRepository;
|
private readonly IConfigElementRepository _configElementRepository;
|
||||||
private readonly FFmpegProcessService _ffmpegProcessService;
|
private readonly FFmpegProcessService _ffmpegProcessService;
|
||||||
private readonly ILocalFileSystem _localFileSystem;
|
private readonly ILocalFileSystem _localFileSystem;
|
||||||
private readonly ILogger<GetPlayoutItemProcessByChannelNumberHandler> _logger;
|
|
||||||
private readonly IMediaSourceRepository _mediaSourceRepository;
|
|
||||||
private readonly IPlayoutRepository _playoutRepository;
|
private readonly IPlayoutRepository _playoutRepository;
|
||||||
|
private readonly IPlexPathReplacementService _plexPathReplacementService;
|
||||||
|
|
||||||
public GetPlayoutItemProcessByChannelNumberHandler(
|
public GetPlayoutItemProcessByChannelNumberHandler(
|
||||||
IChannelRepository channelRepository,
|
IChannelRepository channelRepository,
|
||||||
IConfigElementRepository configElementRepository,
|
IConfigElementRepository configElementRepository,
|
||||||
IPlayoutRepository playoutRepository,
|
IPlayoutRepository playoutRepository,
|
||||||
IMediaSourceRepository mediaSourceRepository,
|
|
||||||
FFmpegProcessService ffmpegProcessService,
|
FFmpegProcessService ffmpegProcessService,
|
||||||
ILocalFileSystem localFileSystem,
|
ILocalFileSystem localFileSystem,
|
||||||
ILogger<GetPlayoutItemProcessByChannelNumberHandler> logger)
|
IPlexPathReplacementService plexPathReplacementService)
|
||||||
: base(channelRepository, configElementRepository)
|
: base(channelRepository, configElementRepository)
|
||||||
{
|
{
|
||||||
_configElementRepository = configElementRepository;
|
_configElementRepository = configElementRepository;
|
||||||
_playoutRepository = playoutRepository;
|
_playoutRepository = playoutRepository;
|
||||||
_mediaSourceRepository = mediaSourceRepository;
|
|
||||||
_ffmpegProcessService = ffmpegProcessService;
|
_ffmpegProcessService = ffmpegProcessService;
|
||||||
_localFileSystem = localFileSystem;
|
_localFileSystem = localFileSystem;
|
||||||
_logger = logger;
|
_plexPathReplacementService = plexPathReplacementService;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task<Either<BaseError, Process>> GetProcess(
|
protected override async Task<Either<BaseError, Process>> GetProcess(
|
||||||
@@ -166,33 +160,16 @@ namespace ErsatzTV.Application.Streaming.Queries
|
|||||||
string path = file.Path;
|
string path = file.Path;
|
||||||
return playoutItem.MediaItem switch
|
return playoutItem.MediaItem switch
|
||||||
{
|
{
|
||||||
PlexMovie plexMovie => await GetReplacementPlexPath(plexMovie.LibraryPathId, path),
|
PlexMovie plexMovie => await _plexPathReplacementService.GetReplacementPlexPath(
|
||||||
PlexEpisode plexEpisode => await GetReplacementPlexPath(plexEpisode.LibraryPathId, path),
|
plexMovie.LibraryPathId,
|
||||||
|
path),
|
||||||
|
PlexEpisode plexEpisode => await _plexPathReplacementService.GetReplacementPlexPath(
|
||||||
|
plexEpisode.LibraryPathId,
|
||||||
|
path),
|
||||||
_ => path
|
_ => path
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> GetReplacementPlexPath(int libraryPathId, string path)
|
|
||||||
{
|
|
||||||
List<PlexPathReplacement> replacements =
|
|
||||||
await _mediaSourceRepository.GetPlexPathReplacementsByLibraryId(libraryPathId);
|
|
||||||
// TODO: this might barf mixing platforms (i.e. plex on linux, etv on windows)
|
|
||||||
Option<PlexPathReplacement> maybeReplacement = replacements
|
|
||||||
.SingleOrDefault(r => path.StartsWith(r.PlexPath + Path.DirectorySeparatorChar));
|
|
||||||
return maybeReplacement.Match(
|
|
||||||
replacement =>
|
|
||||||
{
|
|
||||||
string finalPath = path.Replace(replacement.PlexPath, replacement.LocalPath);
|
|
||||||
_logger.LogInformation(
|
|
||||||
"Replacing plex path {PlexPath} with {LocalPath} resulting in {FinalPath}",
|
|
||||||
replacement.PlexPath,
|
|
||||||
replacement.LocalPath,
|
|
||||||
finalPath);
|
|
||||||
return finalPath;
|
|
||||||
},
|
|
||||||
() => path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private record PlayoutItemWithPath(PlayoutItem PlayoutItem, string Path);
|
private record PlayoutItemWithPath(PlayoutItem PlayoutItem, string Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ErsatzTV.Core.Domain;
|
||||||
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
|
using ErsatzTV.Core.Interfaces.Runtime;
|
||||||
|
using ErsatzTV.Core.Plex;
|
||||||
|
using FluentAssertions;
|
||||||
|
using LanguageExt;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Tests.Plex
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class PlexPathReplacementServiceTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public async Task PlexWindows_To_EtvWindows()
|
||||||
|
{
|
||||||
|
var replacements = new List<PlexPathReplacement>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
PlexPath = @"C:\Something\Some Shared Folder",
|
||||||
|
LocalPath = @"C:\Something Else\Some Shared Folder",
|
||||||
|
PlexMediaSource = new PlexMediaSource { Platform = "Windows" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var repo = new Mock<IMediaSourceRepository>();
|
||||||
|
repo.Setup(x => x.GetPlexPathReplacementsByLibraryId(It.IsAny<int>())).Returns(replacements.AsTask());
|
||||||
|
|
||||||
|
var runtime = new Mock<IRuntimeInfo>();
|
||||||
|
runtime.Setup(x => x.IsOSPlatform(OSPlatform.Windows)).Returns(true);
|
||||||
|
|
||||||
|
var service = new PlexPathReplacementService(
|
||||||
|
repo.Object,
|
||||||
|
runtime.Object,
|
||||||
|
new Mock<ILogger<PlexPathReplacementService>>().Object);
|
||||||
|
|
||||||
|
string result = await service.GetReplacementPlexPath(
|
||||||
|
0,
|
||||||
|
@"C:\Something\Some Shared Folder\Some Movie\Some Movie.mkv");
|
||||||
|
|
||||||
|
result.Should().Be(@"C:\Something Else\Some Shared Folder\Some Movie\Some Movie.mkv");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task PlexWindows_To_EtvLinux()
|
||||||
|
{
|
||||||
|
var replacements = new List<PlexPathReplacement>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
PlexPath = @"C:\Something\Some Shared Folder",
|
||||||
|
LocalPath = @"/mnt/something else/Some Shared Folder",
|
||||||
|
PlexMediaSource = new PlexMediaSource { Platform = "Windows" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var repo = new Mock<IMediaSourceRepository>();
|
||||||
|
repo.Setup(x => x.GetPlexPathReplacementsByLibraryId(It.IsAny<int>())).Returns(replacements.AsTask());
|
||||||
|
|
||||||
|
var runtime = new Mock<IRuntimeInfo>();
|
||||||
|
runtime.Setup(x => x.IsOSPlatform(OSPlatform.Windows)).Returns(false);
|
||||||
|
|
||||||
|
var service = new PlexPathReplacementService(
|
||||||
|
repo.Object,
|
||||||
|
runtime.Object,
|
||||||
|
new Mock<ILogger<PlexPathReplacementService>>().Object);
|
||||||
|
|
||||||
|
string result = await service.GetReplacementPlexPath(
|
||||||
|
0,
|
||||||
|
@"C:\Something\Some Shared Folder\Some Movie\Some Movie.mkv");
|
||||||
|
|
||||||
|
result.Should().Be(@"/mnt/something else/Some Shared Folder/Some Movie/Some Movie.mkv");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task PlexLinux_To_EtvWindows()
|
||||||
|
{
|
||||||
|
var replacements = new List<PlexPathReplacement>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
PlexPath = @"/mnt/something/Some Shared Folder",
|
||||||
|
LocalPath = @"C:\Something Else\Some Shared Folder",
|
||||||
|
PlexMediaSource = new PlexMediaSource { Platform = "Linux" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var repo = new Mock<IMediaSourceRepository>();
|
||||||
|
repo.Setup(x => x.GetPlexPathReplacementsByLibraryId(It.IsAny<int>())).Returns(replacements.AsTask());
|
||||||
|
|
||||||
|
var runtime = new Mock<IRuntimeInfo>();
|
||||||
|
runtime.Setup(x => x.IsOSPlatform(OSPlatform.Windows)).Returns(true);
|
||||||
|
|
||||||
|
var service = new PlexPathReplacementService(
|
||||||
|
repo.Object,
|
||||||
|
runtime.Object,
|
||||||
|
new Mock<ILogger<PlexPathReplacementService>>().Object);
|
||||||
|
|
||||||
|
string result = await service.GetReplacementPlexPath(
|
||||||
|
0,
|
||||||
|
@"/mnt/something/Some Shared Folder/Some Movie/Some Movie.mkv");
|
||||||
|
|
||||||
|
result.Should().Be(@"C:\Something Else\Some Shared Folder\Some Movie\Some Movie.mkv");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task PlexLinux_To_EtvLinux()
|
||||||
|
{
|
||||||
|
var replacements = new List<PlexPathReplacement>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
PlexPath = @"/mnt/something/Some Shared Folder",
|
||||||
|
LocalPath = @"/mnt/something else/Some Shared Folder",
|
||||||
|
PlexMediaSource = new PlexMediaSource { Platform = "Linux" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var repo = new Mock<IMediaSourceRepository>();
|
||||||
|
repo.Setup(x => x.GetPlexPathReplacementsByLibraryId(It.IsAny<int>())).Returns(replacements.AsTask());
|
||||||
|
|
||||||
|
var runtime = new Mock<IRuntimeInfo>();
|
||||||
|
runtime.Setup(x => x.IsOSPlatform(OSPlatform.Windows)).Returns(false);
|
||||||
|
|
||||||
|
var service = new PlexPathReplacementService(
|
||||||
|
repo.Object,
|
||||||
|
runtime.Object,
|
||||||
|
new Mock<ILogger<PlexPathReplacementService>>().Object);
|
||||||
|
|
||||||
|
string result = await service.GetReplacementPlexPath(
|
||||||
|
0,
|
||||||
|
@"/mnt/something/Some Shared Folder/Some Movie/Some Movie.mkv");
|
||||||
|
|
||||||
|
result.Should().Be(@"/mnt/something else/Some Shared Folder/Some Movie/Some Movie.mkv");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ namespace ErsatzTV.Core.Domain
|
|||||||
{
|
{
|
||||||
public string ServerName { get; set; }
|
public string ServerName { get; set; }
|
||||||
public string ProductVersion { get; set; }
|
public string ProductVersion { get; set; }
|
||||||
|
public string Platform { get; set; }
|
||||||
|
public string PlatformVersion { get; set; }
|
||||||
public string ClientIdentifier { get; set; }
|
public string ClientIdentifier { get; set; }
|
||||||
|
|
||||||
// public bool IsOwned { get; set; }
|
// public bool IsOwned { get; set; }
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Interfaces.Plex
|
||||||
|
{
|
||||||
|
public interface IPlexPathReplacementService
|
||||||
|
{
|
||||||
|
Task<string> GetReplacementPlexPath(int libraryPathId, string path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Interfaces.Runtime
|
||||||
|
{
|
||||||
|
public interface IRuntimeInfo
|
||||||
|
{
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
bool IsOSPlatform(OSPlatform osPlatform);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ErsatzTV.Core.Domain;
|
||||||
|
using ErsatzTV.Core.Interfaces.Plex;
|
||||||
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
|
using ErsatzTV.Core.Interfaces.Runtime;
|
||||||
|
using LanguageExt;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Plex
|
||||||
|
{
|
||||||
|
public class PlexPathReplacementService : IPlexPathReplacementService
|
||||||
|
{
|
||||||
|
private readonly ILogger<PlexPathReplacementService> _logger;
|
||||||
|
private readonly IMediaSourceRepository _mediaSourceRepository;
|
||||||
|
private readonly IRuntimeInfo _runtimeInfo;
|
||||||
|
|
||||||
|
public PlexPathReplacementService(
|
||||||
|
IMediaSourceRepository mediaSourceRepository,
|
||||||
|
IRuntimeInfo runtimeInfo,
|
||||||
|
ILogger<PlexPathReplacementService> logger)
|
||||||
|
{
|
||||||
|
_mediaSourceRepository = mediaSourceRepository;
|
||||||
|
_runtimeInfo = runtimeInfo;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetReplacementPlexPath(int libraryPathId, string path)
|
||||||
|
{
|
||||||
|
List<PlexPathReplacement> replacements =
|
||||||
|
await _mediaSourceRepository.GetPlexPathReplacementsByLibraryId(libraryPathId);
|
||||||
|
Option<PlexPathReplacement> maybeReplacement = replacements
|
||||||
|
.SingleOrDefault(
|
||||||
|
r =>
|
||||||
|
{
|
||||||
|
string separatorChar = IsWindows(r.PlexMediaSource) ? @"\" : @"/";
|
||||||
|
return path.StartsWith(r.PlexPath + separatorChar);
|
||||||
|
});
|
||||||
|
return maybeReplacement.Match(
|
||||||
|
replacement =>
|
||||||
|
{
|
||||||
|
string finalPath = path.Replace(replacement.PlexPath, replacement.LocalPath);
|
||||||
|
if (IsWindows(replacement.PlexMediaSource) && !_runtimeInfo.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
finalPath = finalPath.Replace(@"\", @"/");
|
||||||
|
}
|
||||||
|
else if (!IsWindows(replacement.PlexMediaSource) && _runtimeInfo.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
finalPath = finalPath.Replace(@"/", @"\");
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Replacing plex path {PlexPath} with {LocalPath} resulting in {FinalPath}",
|
||||||
|
replacement.PlexPath,
|
||||||
|
replacement.LocalPath,
|
||||||
|
finalPath);
|
||||||
|
return finalPath;
|
||||||
|
},
|
||||||
|
() => path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsWindows(PlexMediaSource plexMediaSource) =>
|
||||||
|
plexMediaSource.Platform.ToLowerInvariant() == "windows";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -135,6 +135,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
|||||||
inner join PlexPathReplacement ppr on ppr.PlexMediaSourceId = l.MediaSourceId
|
inner join PlexPathReplacement ppr on ppr.PlexMediaSourceId = l.MediaSourceId
|
||||||
where lp.Id = {0}",
|
where lp.Id = {0}",
|
||||||
plexLibraryPathId)
|
plexLibraryPathId)
|
||||||
|
.Include(ppr => ppr.PlexMediaSource)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +159,20 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
|||||||
List<PlexConnection> toDelete)
|
List<PlexConnection> toDelete)
|
||||||
{
|
{
|
||||||
await _dbConnection.ExecuteAsync(
|
await _dbConnection.ExecuteAsync(
|
||||||
@"UPDATE PlexMediaSource SET ProductVersion = @ProductVersion, ServerName = @ServerName WHERE Id = @Id",
|
@"UPDATE PlexMediaSource SET
|
||||||
new { plexMediaSource.ProductVersion, plexMediaSource.ServerName, plexMediaSource.Id });
|
ProductVersion = @ProductVersion,
|
||||||
|
Platform = @Platform,
|
||||||
|
PlatformVersion = @PlatformVersion,
|
||||||
|
ServerName = @ServerName
|
||||||
|
WHERE Id = @Id",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
plexMediaSource.ProductVersion,
|
||||||
|
plexMediaSource.Platform,
|
||||||
|
plexMediaSource.PlatformVersion,
|
||||||
|
plexMediaSource.ServerName,
|
||||||
|
plexMediaSource.Id
|
||||||
|
});
|
||||||
|
|
||||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
||||||
|
|
||||||
|
|||||||
+1755
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
public partial class Add_PlexMediaSourcePlatform : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
"Platform",
|
||||||
|
"PlexMediaSource",
|
||||||
|
"TEXT",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
"PlatformVersion",
|
||||||
|
"PlexMediaSource",
|
||||||
|
"TEXT",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
"Platform",
|
||||||
|
"PlexMediaSource");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
"PlatformVersion",
|
||||||
|
"PlexMediaSource");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1026,6 +1026,12 @@ namespace ErsatzTV.Infrastructure.Migrations
|
|||||||
b.Property<string>("ClientIdentifier")
|
b.Property<string>("ClientIdentifier")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Platform")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PlatformVersion")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("ProductVersion")
|
b.Property<string>("ProductVersion")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace ErsatzTV.Infrastructure.Plex.Models
|
|||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string ProductVersion { get; set; }
|
public string ProductVersion { get; set; }
|
||||||
|
public string Platform { get; set; }
|
||||||
|
public string PlatformVersion { get; set; }
|
||||||
public string ClientIdentifier { get; set; }
|
public string ClientIdentifier { get; set; }
|
||||||
|
|
||||||
public string AccessToken { get; set; }
|
public string AccessToken { get; set; }
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ namespace ErsatzTV.Infrastructure.Plex
|
|||||||
{
|
{
|
||||||
ServerName = resource.Name,
|
ServerName = resource.Name,
|
||||||
ProductVersion = resource.ProductVersion,
|
ProductVersion = resource.ProductVersion,
|
||||||
|
Platform = resource.Platform,
|
||||||
|
PlatformVersion = resource.PlatformVersion,
|
||||||
ClientIdentifier = resource.ClientIdentifier,
|
ClientIdentifier = resource.ClientIdentifier,
|
||||||
Connections = sortedConnections
|
Connections = sortedConnections
|
||||||
.Map(c => new PlexConnection { Uri = c.Uri }).ToList()
|
.Map(c => new PlexConnection { Uri = c.Uri }).ToList()
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using ErsatzTV.Core.Interfaces.Runtime;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Runtime
|
||||||
|
{
|
||||||
|
public class RuntimeInfo : IRuntimeInfo
|
||||||
|
{
|
||||||
|
public bool IsOSPlatform(OSPlatform osPlatform) => RuntimeInformation.IsOSPlatform(osPlatform);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using ErsatzTV.Core.Interfaces.Locking;
|
|||||||
using ErsatzTV.Core.Interfaces.Metadata;
|
using ErsatzTV.Core.Interfaces.Metadata;
|
||||||
using ErsatzTV.Core.Interfaces.Plex;
|
using ErsatzTV.Core.Interfaces.Plex;
|
||||||
using ErsatzTV.Core.Interfaces.Repositories;
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
|
using ErsatzTV.Core.Interfaces.Runtime;
|
||||||
using ErsatzTV.Core.Interfaces.Scheduling;
|
using ErsatzTV.Core.Interfaces.Scheduling;
|
||||||
using ErsatzTV.Core.Interfaces.Search;
|
using ErsatzTV.Core.Interfaces.Search;
|
||||||
using ErsatzTV.Core.Metadata;
|
using ErsatzTV.Core.Metadata;
|
||||||
@@ -25,6 +26,7 @@ using ErsatzTV.Infrastructure.Data.Repositories;
|
|||||||
using ErsatzTV.Infrastructure.Images;
|
using ErsatzTV.Infrastructure.Images;
|
||||||
using ErsatzTV.Infrastructure.Locking;
|
using ErsatzTV.Infrastructure.Locking;
|
||||||
using ErsatzTV.Infrastructure.Plex;
|
using ErsatzTV.Infrastructure.Plex;
|
||||||
|
using ErsatzTV.Infrastructure.Runtime;
|
||||||
using ErsatzTV.Infrastructure.Search;
|
using ErsatzTV.Infrastructure.Search;
|
||||||
using ErsatzTV.Serialization;
|
using ErsatzTV.Serialization;
|
||||||
using ErsatzTV.Services;
|
using ErsatzTV.Services;
|
||||||
@@ -212,6 +214,8 @@ namespace ErsatzTV
|
|||||||
services.AddScoped<IPlexTelevisionLibraryScanner, PlexTelevisionLibraryScanner>();
|
services.AddScoped<IPlexTelevisionLibraryScanner, PlexTelevisionLibraryScanner>();
|
||||||
services.AddScoped<IPlexServerApiClient, PlexServerApiClient>();
|
services.AddScoped<IPlexServerApiClient, PlexServerApiClient>();
|
||||||
services.AddScoped<ISearchIndex, SearchIndex>();
|
services.AddScoped<ISearchIndex, SearchIndex>();
|
||||||
|
services.AddScoped<IRuntimeInfo, RuntimeInfo>();
|
||||||
|
services.AddScoped<IPlexPathReplacementService, PlexPathReplacementService>();
|
||||||
|
|
||||||
services.AddHostedService<PlexService>();
|
services.AddHostedService<PlexService>();
|
||||||
services.AddHostedService<FFmpegLocatorService>();
|
services.AddHostedService<FFmpegLocatorService>();
|
||||||
|
|||||||
Reference in New Issue
Block a user