mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-05 13:53:20 +01:00
add more methods to file system interface
This commit is contained in:
@@ -46,6 +46,18 @@ namespace MediaBrowser.Api
|
||||
public bool IncludeHidden { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Environment/NetworkShares", "GET")]
|
||||
[Api(Description = "Gets shares from a network device")]
|
||||
public class GetNetworkShares : IReturn<List<FileSystemEntryInfo>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
[ApiMember(Name = "Path", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class GetDrives
|
||||
/// </summary>
|
||||
@@ -64,11 +76,25 @@ namespace MediaBrowser.Api
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/Environment/ParentPath", "GET")]
|
||||
[Api(Description = "Gets the parent path of a given path")]
|
||||
public class GetParentPath : IReturn<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
[ApiMember(Name = "Path", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class EnvironmentService
|
||||
/// </summary>
|
||||
public class EnvironmentService : BaseApiService
|
||||
{
|
||||
const char UncSeparator = '\\';
|
||||
|
||||
/// <summary>
|
||||
/// The _network manager
|
||||
/// </summary>
|
||||
@@ -105,13 +131,9 @@ namespace MediaBrowser.Api
|
||||
throw new ArgumentNullException("Path");
|
||||
}
|
||||
|
||||
// If it's not a drive trim trailing slashes.
|
||||
if (!path.EndsWith(":\\"))
|
||||
{
|
||||
path = path.TrimEnd('\\');
|
||||
}
|
||||
var networkPrefix = UncSeparator.ToString(CultureInfo.InvariantCulture) + UncSeparator.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (path.StartsWith(NetworkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf('\\') == 1)
|
||||
if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1)
|
||||
{
|
||||
return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
|
||||
}
|
||||
@@ -119,6 +141,15 @@ namespace MediaBrowser.Api
|
||||
return ToOptimizedResult(GetFileSystemEntries(request).OrderBy(i => i.Path).ToList());
|
||||
}
|
||||
|
||||
public object Get(GetNetworkShares request)
|
||||
{
|
||||
var path = request.Path;
|
||||
|
||||
var shares = GetNetworkShares(path).OrderBy(i => i.Path).ToList();
|
||||
|
||||
return ToOptimizedResult(shares);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified request.
|
||||
/// </summary>
|
||||
@@ -154,25 +185,13 @@ namespace MediaBrowser.Api
|
||||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetNetworkDevices request)
|
||||
{
|
||||
var result = GetNetworkDevices().OrderBy(i => i.Path).ToList();
|
||||
var result = _networkManager.GetNetworkDevices()
|
||||
.OrderBy(i => i.Path)
|
||||
.ToList();
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the network computers.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{FileSystemEntryInfo}.</returns>
|
||||
private IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
|
||||
{
|
||||
return _networkManager.GetNetworkDevices().Select(c => new FileSystemEntryInfo
|
||||
{
|
||||
Name = c,
|
||||
Path = NetworkPrefix + c,
|
||||
Type = FileSystemEntryType.NetworkComputer
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
@@ -223,7 +242,7 @@ namespace MediaBrowser.Api
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -236,13 +255,27 @@ namespace MediaBrowser.Api
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the network prefix.
|
||||
/// </summary>
|
||||
/// <value>The network prefix.</value>
|
||||
private string NetworkPrefix
|
||||
public object Get(GetParentPath request)
|
||||
{
|
||||
get { return Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture) + Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture); }
|
||||
var parent = Path.GetDirectoryName(request.Path);
|
||||
|
||||
if (string.IsNullOrEmpty(parent))
|
||||
{
|
||||
// Check if unc share
|
||||
var index = request.Path.LastIndexOf(UncSeparator);
|
||||
|
||||
if (index != -1 && request.Path.IndexOf(UncSeparator) == 0)
|
||||
{
|
||||
parent = request.Path.Substring(0, index);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(parent.TrimStart(UncSeparator)))
|
||||
{
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,11 @@ namespace MediaBrowser.Api.Images
|
||||
[ApiMember(Name = "AddPlayedIndicator", Description = "Optional. Add a played indicator", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool AddPlayedIndicator { get; set; }
|
||||
|
||||
[ApiMember(Name = "PercentPlayed", Description = "Optional percent to render for the percent played overlay", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public int? PercentPlayed { get; set; }
|
||||
[ApiMember(Name = "PercentPlayed", Description = "Optional percent to render for the percent played overlay", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public double? PercentPlayed { get; set; }
|
||||
|
||||
[ApiMember(Name = "UnplayedCount", Description = "Optional unplayed count overlay to render", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public int? UnplayedCount { get; set; }
|
||||
|
||||
[ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string BackgroundColor { get; set; }
|
||||
|
||||
@@ -91,6 +91,7 @@ namespace MediaBrowser.Api.Images
|
||||
OutputFormat = Request.Format,
|
||||
AddPlayedIndicator = Request.AddPlayedIndicator,
|
||||
PercentPlayed = Request.PercentPlayed,
|
||||
UnplayedCount = Request.UnplayedCount,
|
||||
BackgroundColor = Request.BackgroundColor
|
||||
};
|
||||
|
||||
|
||||
@@ -65,17 +65,10 @@ namespace MediaBrowser.Api.Library
|
||||
throw new DirectoryNotFoundException("The path does not exist.");
|
||||
}
|
||||
|
||||
// Strip off trailing slash, but not on drives
|
||||
path = path.TrimEnd(Path.DirectorySeparatorChar);
|
||||
if (path.EndsWith(":", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
path += Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
var rootFolderPath = user != null ? user.RootFolderPath : appPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
||||
ValidateNewMediaPath(fileSystem, rootFolderPath, path, appPaths);
|
||||
ValidateNewMediaPath(fileSystem, rootFolderPath, path);
|
||||
|
||||
var shortcutFilename = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
@@ -96,25 +89,18 @@ namespace MediaBrowser.Api.Library
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="currentViewRootFolderPath">The current view root folder path.</param>
|
||||
/// <param name="mediaPath">The media path.</param>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// </exception>
|
||||
private static void ValidateNewMediaPath(IFileSystem fileSystem, string currentViewRootFolderPath, string mediaPath, IServerApplicationPaths appPaths)
|
||||
private static void ValidateNewMediaPath(IFileSystem fileSystem, string currentViewRootFolderPath, string mediaPath)
|
||||
{
|
||||
var duplicate = Directory.EnumerateFiles(appPaths.RootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => !IsNewPathValid(mediaPath, p, false));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
{
|
||||
throw new ArgumentException(string.Format("The path cannot be added to the library because {0} already exists.", duplicate));
|
||||
}
|
||||
var pathsInCurrentVIew = Directory.EnumerateFiles(currentViewRootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.ToList();
|
||||
|
||||
// Don't allow duplicate sub-paths within the same user library, or it will result in duplicate items
|
||||
// See comments in IsNewPathValid
|
||||
duplicate = Directory.EnumerateFiles(currentViewRootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => !IsNewPathValid(mediaPath, p, true));
|
||||
var duplicate = pathsInCurrentVIew
|
||||
.FirstOrDefault(p => !IsNewPathValid(fileSystem, mediaPath, p));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
{
|
||||
@@ -122,9 +108,8 @@ namespace MediaBrowser.Api.Library
|
||||
}
|
||||
|
||||
// Make sure the current root folder doesn't already have a shortcut to the same path
|
||||
duplicate = Directory.EnumerateFiles(currentViewRootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => mediaPath.Equals(p, StringComparison.OrdinalIgnoreCase));
|
||||
duplicate = pathsInCurrentVIew
|
||||
.FirstOrDefault(p => string.Equals(mediaPath, p, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
{
|
||||
@@ -135,30 +120,30 @@ namespace MediaBrowser.Api.Library
|
||||
/// <summary>
|
||||
/// Validates that a new path can be added based on an existing path
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="newPath">The new path.</param>
|
||||
/// <param name="existingPath">The existing path.</param>
|
||||
/// <param name="enforceSubPathRestriction">if set to <c>true</c> [enforce sub path restriction].</param>
|
||||
/// <returns><c>true</c> if [is new path valid] [the specified new path]; otherwise, <c>false</c>.</returns>
|
||||
private static bool IsNewPathValid(string newPath, string existingPath, bool enforceSubPathRestriction)
|
||||
private static bool IsNewPathValid(IFileSystem fileSystem, string newPath, string existingPath)
|
||||
{
|
||||
// Example: D:\Movies is the existing path
|
||||
// D:\ cannot be added
|
||||
// Neither can D:\Movies\Kids
|
||||
// A D:\Movies duplicate is ok here since that will be caught later
|
||||
|
||||
if (newPath.Equals(existingPath, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(newPath, existingPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If enforceSubPathRestriction is true, validate the D:\Movies\Kids scenario
|
||||
if (enforceSubPathRestriction && newPath.StartsWith(existingPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
|
||||
if (fileSystem.ContainsSubPath(existingPath, newPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the D:\ scenario
|
||||
if (existingPath.StartsWith(newPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
|
||||
if (fileSystem.ContainsSubPath(newPath, existingPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ namespace MediaBrowser.Api.LiveTv
|
||||
|
||||
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsRecording", Description = "Optional filter by recordings that are currently active, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsRecording { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/Recordings/Groups", "GET")]
|
||||
@@ -274,7 +277,8 @@ namespace MediaBrowser.Api.LiveTv
|
||||
UserId = request.UserId,
|
||||
GroupId = request.GroupId,
|
||||
StartIndex = request.StartIndex,
|
||||
Limit = request.Limit
|
||||
Limit = request.Limit,
|
||||
IsRecording = request.IsRecording
|
||||
|
||||
}, CancellationToken.None).Result;
|
||||
|
||||
|
||||
@@ -197,10 +197,6 @@ namespace MediaBrowser.Api.Playback
|
||||
{
|
||||
args += string.Format("-map 0:{0}", state.VideoStream.Index);
|
||||
}
|
||||
else if (!state.HasMediaStreams)
|
||||
{
|
||||
args += string.Format("-map 0:{0}", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
args += "-map -0:v";
|
||||
@@ -210,10 +206,6 @@ namespace MediaBrowser.Api.Playback
|
||||
{
|
||||
args += string.Format(" -map 0:{0}", state.AudioStream.Index);
|
||||
}
|
||||
else if (!state.HasMediaStreams)
|
||||
{
|
||||
args += string.Format(" -map 0:{0}", 1);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
@@ -871,7 +863,7 @@ namespace MediaBrowser.Api.Playback
|
||||
RequestedUrl = url
|
||||
};
|
||||
|
||||
BaseItem item;
|
||||
Guid itemId;
|
||||
|
||||
if (string.Equals(request.Type, "Recording", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -900,7 +892,7 @@ namespace MediaBrowser.Api.Playback
|
||||
state.IsRemote = true;
|
||||
}
|
||||
|
||||
item = recording;
|
||||
itemId = recording.Id;
|
||||
}
|
||||
else if (string.Equals(request.Type, "Channel", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -916,11 +908,11 @@ namespace MediaBrowser.Api.Playback
|
||||
|
||||
state.IsRemote = true;
|
||||
|
||||
item = channel;
|
||||
itemId = channel.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = DtoService.GetItemByDtoId(request.Id);
|
||||
var item = DtoService.GetItemByDtoId(request.Id);
|
||||
|
||||
state.MediaPath = item.Path;
|
||||
state.IsRemote = item.LocationType == LocationType.Remote;
|
||||
@@ -937,13 +929,15 @@ namespace MediaBrowser.Api.Playback
|
||||
? new List<string>()
|
||||
: video.PlayableStreamFileNames.ToList();
|
||||
}
|
||||
|
||||
itemId = item.Id;
|
||||
}
|
||||
|
||||
var videoRequest = request as VideoStreamRequest;
|
||||
|
||||
var mediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
ItemId = item.Id
|
||||
ItemId = itemId
|
||||
|
||||
}).ToList();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user