Bläddra i källkod

Add some docs and tests

Bond_009 3 år sedan
förälder
incheckning
4dfb7b18ae

+ 30 - 7
Emby.Server.Implementations/IO/ManagedFileSystem.cs

@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
 using System;
 using System.Collections.Generic;
 using System.Globalization;
@@ -23,6 +21,11 @@ namespace Emby.Server.Implementations.IO
         private readonly string _tempPath;
         private static readonly bool _isEnvironmentCaseInsensitive = OperatingSystem.IsWindows();
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ManagedFileSystem"/> class.
+        /// </summary>
+        /// <param name="logger">The <see cref="ILogger"/> instance to use.</param>
+        /// <param name="applicationPaths">The <see cref="IApplicationPaths"/> instance to use.</param>
         public ManagedFileSystem(
             ILogger<ManagedFileSystem> logger,
             IApplicationPaths applicationPaths)
@@ -31,6 +34,7 @@ namespace Emby.Server.Implementations.IO
             _tempPath = applicationPaths.TempDirectory;
         }
 
+        /// <inheritdoc />
         public virtual void AddShortcutHandler(IShortcutHandler handler)
         {
             _shortcutHandlers.Add(handler);
@@ -72,6 +76,7 @@ namespace Emby.Server.Implementations.IO
             return handler?.Resolve(filename);
         }
 
+        /// <inheritdoc />
         public virtual string MakeAbsolutePath(string folderPath, string filePath)
         {
             // path is actually a stream
@@ -358,11 +363,13 @@ namespace Emby.Server.Implementations.IO
             return GetCreationTimeUtc(GetFileSystemInfo(path));
         }
 
+        /// <inheritdoc />
         public virtual DateTime GetCreationTimeUtc(FileSystemMetadata info)
         {
             return info.CreationTimeUtc;
         }
 
+        /// <inheritdoc />
         public virtual DateTime GetLastWriteTimeUtc(FileSystemMetadata info)
         {
             return info.LastWriteTimeUtc;
@@ -397,6 +404,7 @@ namespace Emby.Server.Implementations.IO
             return GetLastWriteTimeUtc(GetFileSystemInfo(path));
         }
 
+        /// <inheritdoc />
         public virtual void SetHidden(string path, bool isHidden)
         {
             if (!OperatingSystem.IsWindows())
@@ -421,6 +429,7 @@ namespace Emby.Server.Implementations.IO
             }
         }
 
+        /// <inheritdoc />
         public virtual void SetAttributes(string path, bool isHidden, bool readOnly)
         {
             if (!OperatingSystem.IsWindows())
@@ -444,7 +453,7 @@ namespace Emby.Server.Implementations.IO
 
             if (readOnly)
             {
-                attributes = attributes | FileAttributes.ReadOnly;
+                attributes |= FileAttributes.ReadOnly;
             }
             else
             {
@@ -453,7 +462,7 @@ namespace Emby.Server.Implementations.IO
 
             if (isHidden)
             {
-                attributes = attributes | FileAttributes.Hidden;
+                attributes |= FileAttributes.Hidden;
             }
             else
             {
@@ -498,6 +507,7 @@ namespace Emby.Server.Implementations.IO
             File.Copy(temp1, file2, true);
         }
 
+        /// <inheritdoc />
         public virtual bool ContainsSubPath(string parentPath, string path)
         {
             if (string.IsNullOrEmpty(parentPath))
@@ -515,6 +525,7 @@ namespace Emby.Server.Implementations.IO
                 _isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
         }
 
+        /// <inheritdoc />
         public virtual string NormalizePath(string path)
         {
             if (string.IsNullOrEmpty(path))
@@ -530,6 +541,7 @@ namespace Emby.Server.Implementations.IO
             return Path.TrimEndingDirectorySeparator(path);
         }
 
+        /// <inheritdoc />
         public virtual bool AreEqual(string path1, string path2)
         {
             if (path1 == null && path2 == null)
@@ -548,6 +560,7 @@ namespace Emby.Server.Implementations.IO
                 _isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
         }
 
+        /// <inheritdoc />
         public virtual string GetFileNameWithoutExtension(FileSystemMetadata info)
         {
             if (info.IsDirectory)
@@ -558,11 +571,11 @@ namespace Emby.Server.Implementations.IO
             return Path.GetFileNameWithoutExtension(info.FullName);
         }
 
+        /// <inheritdoc />
         public virtual bool IsPathFile(string path)
         {
-            // Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
-            if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
-                !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
+            if (path.Contains("://", StringComparison.OrdinalIgnoreCase)
+                && !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
             {
                 return false;
             }
@@ -570,12 +583,14 @@ namespace Emby.Server.Implementations.IO
             return true;
         }
 
+        /// <inheritdoc />
         public virtual void DeleteFile(string path)
         {
             SetAttributes(path, false, false);
             File.Delete(path);
         }
 
+        /// <inheritdoc />
         public virtual List<FileSystemMetadata> GetDrives()
         {
             // check for ready state to avoid waiting for drives to timeout
@@ -593,16 +608,19 @@ namespace Emby.Server.Implementations.IO
                 }).ToList();
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false)
         {
             return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", GetEnumerationOptions(recursive)));
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false)
         {
             return GetFiles(path, null, false, recursive);
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, IReadOnlyList<string>? extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
         {
             var enumerationOptions = GetEnumerationOptions(recursive);
@@ -633,6 +651,7 @@ namespace Emby.Server.Implementations.IO
             return ToMetadata(files);
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false)
         {
             var directoryInfo = new DirectoryInfo(path);
@@ -646,16 +665,19 @@ namespace Emby.Server.Implementations.IO
             return infos.Select(GetFileSystemMetadata);
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false)
         {
             return Directory.EnumerateDirectories(path, "*", GetEnumerationOptions(recursive));
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<string> GetFilePaths(string path, bool recursive = false)
         {
             return GetFilePaths(path, null, false, recursive);
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<string> GetFilePaths(string path, string[]? extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
         {
             var enumerationOptions = GetEnumerationOptions(recursive);
@@ -686,6 +708,7 @@ namespace Emby.Server.Implementations.IO
             return files;
         }
 
+        /// <inheritdoc />
         public virtual IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false)
         {
             return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive));

+ 13 - 24
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -45,6 +45,7 @@ namespace Emby.Server.Implementations.Library
         private readonly IMediaEncoder _mediaEncoder;
         private readonly ILocalizationManager _localizationManager;
         private readonly IApplicationPaths _appPaths;
+        private readonly IDirectoryService _directoryService;
 
         private readonly ConcurrentDictionary<string, ILiveStream> _openStreams = new ConcurrentDictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase);
         private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1);
@@ -61,7 +62,8 @@ namespace Emby.Server.Implementations.Library
             ILogger<MediaSourceManager> logger,
             IFileSystem fileSystem,
             IUserDataManager userDataManager,
-            IMediaEncoder mediaEncoder)
+            IMediaEncoder mediaEncoder,
+            IDirectoryService directoryService)
         {
             _itemRepo = itemRepo;
             _userManager = userManager;
@@ -72,6 +74,7 @@ namespace Emby.Server.Implementations.Library
             _mediaEncoder = mediaEncoder;
             _localizationManager = localizationManager;
             _appPaths = applicationPaths;
+            _directoryService = directoryService;
         }
 
         public void AddParts(IEnumerable<IMediaSourceProvider> providers)
@@ -106,16 +109,6 @@ namespace Emby.Server.Implementations.Library
             return false;
         }
 
-        public List<MediaStream> GetMediaStreams(string mediaSourceId)
-        {
-            var list = GetMediaStreams(new MediaStreamQuery
-            {
-                ItemId = new Guid(mediaSourceId)
-            });
-
-            return GetMediaStreamsForItem(list);
-        }
-
         public List<MediaStream> GetMediaStreams(Guid itemId)
         {
             var list = GetMediaStreams(new MediaStreamQuery
@@ -161,7 +154,7 @@ namespace Emby.Server.Implementations.Library
             if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio || i.Type == MediaStreamType.Video))
             {
                 await item.RefreshMetadata(
-                    new MetadataRefreshOptions(new DirectoryService(_fileSystem))
+                    new MetadataRefreshOptions(_directoryService)
                     {
                         EnableRemoteContentProbe = true,
                         MetadataRefreshMode = MetadataRefreshMode.FullRefresh
@@ -212,6 +205,7 @@ namespace Emby.Server.Implementations.Library
             return SortMediaSources(list);
         }
 
+        /// <inheritdoc />>
         public MediaProtocol GetPathProtocol(string path)
         {
             if (path.StartsWith("Rtsp", StringComparison.OrdinalIgnoreCase))
@@ -258,7 +252,7 @@ namespace Emby.Server.Implementations.Library
             {
                 if (path != null)
                 {
-                    if (path.IndexOf(".m3u", StringComparison.OrdinalIgnoreCase) != -1)
+                    if (path.Contains(".m3u", StringComparison.OrdinalIgnoreCase))
                     {
                         return false;
                     }
@@ -297,7 +291,7 @@ namespace Emby.Server.Implementations.Library
             catch (Exception ex)
             {
                 _logger.LogError(ex, "Error getting media sources");
-                return new List<MediaSourceInfo>();
+                return Enumerable.Empty<MediaSourceInfo>();
             }
         }
 
@@ -494,14 +488,11 @@ namespace Emby.Server.Implementations.Library
                 _liveStreamSemaphore.Release();
             }
 
-            // TODO: Don't hardcode this
-            const bool isAudio = false;
-
             try
             {
                 if (mediaSource.MediaStreams.Any(i => i.Index != -1) || !mediaSource.SupportsProbing)
                 {
-                    AddMediaInfo(mediaSource, isAudio);
+                    AddMediaInfo(mediaSource);
                 }
                 else
                 {
@@ -509,14 +500,14 @@ namespace Emby.Server.Implementations.Library
                     string cacheKey = request.OpenToken;
 
                     await new LiveStreamHelper(_mediaEncoder, _logger, _appPaths)
-                        .AddMediaInfoWithProbe(mediaSource, isAudio, cacheKey, true, cancellationToken)
+                        .AddMediaInfoWithProbe(mediaSource, false, cacheKey, true, cancellationToken)
                         .ConfigureAwait(false);
                 }
             }
             catch (Exception ex)
             {
                 _logger.LogError(ex, "Error probing live tv stream");
-                AddMediaInfo(mediaSource, isAudio);
+                AddMediaInfo(mediaSource);
             }
 
             // TODO: @bond Fix
@@ -536,7 +527,7 @@ namespace Emby.Server.Implementations.Library
             return new Tuple<LiveStreamResponse, IDirectStreamProvider>(new LiveStreamResponse(clone), liveStream as IDirectStreamProvider);
         }
 
-        private static void AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio)
+        private static void AddMediaInfo(MediaSourceInfo mediaSource)
         {
             mediaSource.DefaultSubtitleStreamIndex = null;
 
@@ -855,9 +846,7 @@ namespace Emby.Server.Implementations.Library
             return (provider, keyId);
         }
 
-        /// <summary>
-        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-        /// </summary>
+        /// <inheritdoc />
         public void Dispose()
         {
             Dispose(true);

+ 0 - 7
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -30,13 +30,6 @@ namespace MediaBrowser.Controller.Library
         /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
         List<MediaStream> GetMediaStreams(Guid itemId);
 
-        /// <summary>
-        /// Gets the media streams.
-        /// </summary>
-        /// <param name="mediaSourceId">The media source identifier.</param>
-        /// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
-        List<MediaStream> GetMediaStreams(string mediaSourceId);
-
         /// <summary>
         /// Gets the media streams.
         /// </summary>

+ 32 - 0
tests/Jellyfin.Server.Implementations.Tests/Library/MediaSourceManagerTests.cs

@@ -0,0 +1,32 @@
+using AutoFixture;
+using AutoFixture.AutoMoq;
+using Emby.Server.Implementations.IO;
+using Emby.Server.Implementations.Library;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.MediaInfo;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Library
+{
+    public class MediaSourceManagerTests
+    {
+        private readonly MediaSourceManager _mediaSourceManager;
+
+        public MediaSourceManagerTests()
+        {
+            IFixture fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
+            fixture.Inject<IFileSystem>(fixture.Create<ManagedFileSystem>());
+            _mediaSourceManager = fixture.Create<MediaSourceManager>();
+        }
+
+        [Theory]
+        [InlineData(@"C:\mydir\myfile.ext", MediaProtocol.File)]
+        [InlineData("/mydir/myfile.ext", MediaProtocol.File)]
+        [InlineData("file:///mydir/myfile.ext", MediaProtocol.File)]
+        [InlineData("http://example.com/stream.m3u8", MediaProtocol.Http)]
+        [InlineData("https://example.com/stream.m3u8", MediaProtocol.Http)]
+        [InlineData("rtsp://media.example.com:554/twister/audiotrack", MediaProtocol.Rtsp)]
+        public void GetPathProtocol_ValidArg_Correct(string path, MediaProtocol expected)
+            => Assert.Equal(expected, _mediaSourceManager.GetPathProtocol(path));
+    }
+}