aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/Library/LibraryStructureService.cs
diff options
context:
space:
mode:
authorcrobibero <cody@robibe.ro>2020-07-20 14:28:33 -0600
committercrobibero <cody@robibe.ro>2020-07-20 14:28:33 -0600
commit13850644973b1223bbeb2271e42ad252d43a10bf (patch)
tree5373b3953dabd692ae937483078569cb0525772e /MediaBrowser.Api/Library/LibraryStructureService.cs
parent352dab701866b37d0dd5dcaa6343ccc256d7e837 (diff)
parent0750357916b600a4b4c27bc4babd2adcc6390473 (diff)
Merge remote-tracking branch 'upstream/master' into api-migration-merge
Diffstat (limited to 'MediaBrowser.Api/Library/LibraryStructureService.cs')
-rw-r--r--MediaBrowser.Api/Library/LibraryStructureService.cs412
1 files changed, 412 insertions, 0 deletions
diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs
new file mode 100644
index 000000000..b69550ed1
--- /dev/null
+++ b/MediaBrowser.Api/Library/LibraryStructureService.cs
@@ -0,0 +1,412 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Services;
+using Microsoft.Extensions.Logging;
+
+namespace MediaBrowser.Api.Library
+{
+ /// <summary>
+ /// Class GetDefaultVirtualFolders.
+ /// </summary>
+ [Route("/Library/VirtualFolders", "GET")]
+ public class GetVirtualFolders : IReturn<List<VirtualFolderInfo>>
+ {
+ /// <summary>
+ /// Gets or sets the user id.
+ /// </summary>
+ /// <value>The user id.</value>
+ public string UserId { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders", "POST")]
+ public class AddVirtualFolder : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the collection.
+ /// </summary>
+ /// <value>The type of the collection.</value>
+ public string CollectionType { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether [refresh library].
+ /// </summary>
+ /// <value><c>true</c> if [refresh library]; otherwise, <c>false</c>.</value>
+ public bool RefreshLibrary { get; set; }
+
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <value>The path.</value>
+ public string[] Paths { get; set; }
+
+ public LibraryOptions LibraryOptions { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders", "DELETE")]
+ public class RemoveVirtualFolder : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether [refresh library].
+ /// </summary>
+ /// <value><c>true</c> if [refresh library]; otherwise, <c>false</c>.</value>
+ public bool RefreshLibrary { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders/Name", "POST")]
+ public class RenameVirtualFolder : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string NewName { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether [refresh library].
+ /// </summary>
+ /// <value><c>true</c> if [refresh library]; otherwise, <c>false</c>.</value>
+ public bool RefreshLibrary { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders/Paths", "POST")]
+ public class AddMediaPath : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Path { get; set; }
+
+ public MediaPathInfo PathInfo { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether [refresh library].
+ /// </summary>
+ /// <value><c>true</c> if [refresh library]; otherwise, <c>false</c>.</value>
+ public bool RefreshLibrary { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders/Paths/Update", "POST")]
+ public class UpdateMediaPath : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ public MediaPathInfo PathInfo { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders/Paths", "DELETE")]
+ public class RemoveMediaPath : IReturnVoid
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Path { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether [refresh library].
+ /// </summary>
+ /// <value><c>true</c> if [refresh library]; otherwise, <c>false</c>.</value>
+ public bool RefreshLibrary { get; set; }
+ }
+
+ [Route("/Library/VirtualFolders/LibraryOptions", "POST")]
+ public class UpdateLibraryOptions : IReturnVoid
+ {
+ public string Id { get; set; }
+
+ public LibraryOptions LibraryOptions { get; set; }
+ }
+
+ /// <summary>
+ /// Class LibraryStructureService.
+ /// </summary>
+ [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
+ public class LibraryStructureService : BaseApiService
+ {
+ /// <summary>
+ /// The _app paths.
+ /// </summary>
+ private readonly IServerApplicationPaths _appPaths;
+
+ /// <summary>
+ /// The _library manager.
+ /// </summary>
+ private readonly ILibraryManager _libraryManager;
+ private readonly ILibraryMonitor _libraryMonitor;
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LibraryStructureService" /> class.
+ /// </summary>
+ public LibraryStructureService(
+ ILogger<LibraryStructureService> logger,
+ IServerConfigurationManager serverConfigurationManager,
+ IHttpResultFactory httpResultFactory,
+ ILibraryManager libraryManager,
+ ILibraryMonitor libraryMonitor)
+ : base(logger, serverConfigurationManager, httpResultFactory)
+ {
+ _appPaths = serverConfigurationManager.ApplicationPaths;
+ _libraryManager = libraryManager;
+ _libraryMonitor = libraryMonitor;
+ }
+
+ /// <summary>
+ /// Gets the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>System.Object.</returns>
+ public object Get(GetVirtualFolders request)
+ {
+ var result = _libraryManager.GetVirtualFolders(true);
+
+ return ToOptimizedResult(result);
+ }
+
+ public void Post(UpdateLibraryOptions request)
+ {
+ var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(request.Id);
+
+ collectionFolder.UpdateLibraryOptions(request.LibraryOptions);
+ }
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public Task Post(AddVirtualFolder request)
+ {
+ var libraryOptions = request.LibraryOptions ?? new LibraryOptions();
+
+ if (request.Paths != null && request.Paths.Length > 0)
+ {
+ libraryOptions.PathInfos = request.Paths.Select(i => new MediaPathInfo { Path = i }).ToArray();
+ }
+
+ return _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, libraryOptions, request.RefreshLibrary);
+ }
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public void Post(RenameVirtualFolder request)
+ {
+ if (string.IsNullOrWhiteSpace(request.Name))
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ if (string.IsNullOrWhiteSpace(request.NewName))
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ var rootFolderPath = _appPaths.DefaultUserViewsPath;
+
+ var currentPath = Path.Combine(rootFolderPath, request.Name);
+ var newPath = Path.Combine(rootFolderPath, request.NewName);
+
+ if (!Directory.Exists(currentPath))
+ {
+ throw new FileNotFoundException("The media collection does not exist");
+ }
+
+ if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && Directory.Exists(newPath))
+ {
+ throw new ArgumentException("Media library already exists at " + newPath + ".");
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ // Changing capitalization. Handle windows case insensitivity
+ if (string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase))
+ {
+ var tempPath = Path.Combine(rootFolderPath, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
+ Directory.Move(currentPath, tempPath);
+ currentPath = tempPath;
+ }
+
+ Directory.Move(currentPath, newPath);
+ }
+ finally
+ {
+ CollectionFolder.OnCollectionFolderChange();
+
+ Task.Run(() =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (request.RefreshLibrary)
+ {
+ _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ var task = Task.Delay(1000);
+ // Have to block here to allow exceptions to bubble
+ Task.WaitAll(task);
+
+ _libraryMonitor.Start();
+ }
+ });
+ }
+ }
+
+ /// <summary>
+ /// Deletes the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public Task Delete(RemoveVirtualFolder request)
+ {
+ return _libraryManager.RemoveVirtualFolder(request.Name, request.RefreshLibrary);
+ }
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public void Post(AddMediaPath request)
+ {
+ if (string.IsNullOrWhiteSpace(request.Name))
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ var mediaPath = request.PathInfo ?? new MediaPathInfo
+ {
+ Path = request.Path
+ };
+
+ _libraryManager.AddMediaPath(request.Name, mediaPath);
+ }
+ finally
+ {
+ Task.Run(() =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (request.RefreshLibrary)
+ {
+ _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ var task = Task.Delay(1000);
+ // Have to block here to allow exceptions to bubble
+ Task.WaitAll(task);
+
+ _libraryMonitor.Start();
+ }
+ });
+ }
+ }
+
+ /// <summary>
+ /// Posts the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public void Post(UpdateMediaPath request)
+ {
+ if (string.IsNullOrWhiteSpace(request.Name))
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ _libraryManager.UpdateMediaPath(request.Name, request.PathInfo);
+ }
+
+ /// <summary>
+ /// Deletes the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public void Delete(RemoveMediaPath request)
+ {
+ if (string.IsNullOrWhiteSpace(request.Name))
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
+
+ _libraryMonitor.Stop();
+
+ try
+ {
+ _libraryManager.RemoveMediaPath(request.Name, request.Path);
+ }
+ finally
+ {
+ Task.Run(() =>
+ {
+ // No need to start if scanning the library because it will handle it
+ if (request.RefreshLibrary)
+ {
+ _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None);
+ }
+ else
+ {
+ // Need to add a delay here or directory watchers may still pick up the changes
+ var task = Task.Delay(1000);
+ // Have to block here to allow exceptions to bubble
+ Task.WaitAll(task);
+
+ _libraryMonitor.Start();
+ }
+ });
+ }
+ }
+ }
+}