add more methods to file system interface

This commit is contained in:
Luke Pulverenti
2014-01-01 13:26:31 -05:00
parent 88b638fbd6
commit b9d17c9bc7
54 changed files with 737 additions and 459 deletions

View File

@@ -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;
}
}
}

View File

@@ -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; }

View File

@@ -91,6 +91,7 @@ namespace MediaBrowser.Api.Images
OutputFormat = Request.Format,
AddPlayedIndicator = Request.AddPlayedIndicator,
PercentPlayed = Request.PercentPlayed,
UnplayedCount = Request.UnplayedCount,
BackgroundColor = Request.BackgroundColor
};

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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();