mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* sync plex platform and platform version * fix mixed-platform path replacementspull/107/head
15 changed files with 2075 additions and 35 deletions
@ -0,0 +1,147 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,9 @@
@@ -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 @@
@@ -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 @@
@@ -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"; |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -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); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue