mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-11 15:47:09 -07:00
Added: Allow folders without trailing slashes in file browser
Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
This commit is contained in:
parent
ef107fc63d
commit
36b2942cef
6 changed files with 83 additions and 55 deletions
|
@ -143,22 +143,22 @@ class FileBrowserModalContent extends Component {
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{
|
{
|
||||||
emptyParent &&
|
emptyParent &&
|
||||||
<FileBrowserRow
|
<FileBrowserRow
|
||||||
type="computer"
|
type="computer"
|
||||||
name="My Computer"
|
name="My Computer"
|
||||||
path={parent}
|
path={parent}
|
||||||
onPress={this.onRowPress}
|
onPress={this.onRowPress}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
!emptyParent && parent &&
|
!emptyParent && parent &&
|
||||||
<FileBrowserRow
|
<FileBrowserRow
|
||||||
type="parent"
|
type="parent"
|
||||||
name="..."
|
name="..."
|
||||||
path={parent}
|
path={parent}
|
||||||
onPress={this.onRowPress}
|
onPress={this.onRowPress}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,14 +48,20 @@ class FileBrowserModalContentConnector extends Component {
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchPaths({ path: this.props.value });
|
this.props.fetchPaths({
|
||||||
|
path: this.props.value,
|
||||||
|
allowFoldersWithoutTrailingSlashes: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
onFetchPaths = (path) => {
|
onFetchPaths = (path) => {
|
||||||
this.props.fetchPaths({ path });
|
this.props.fetchPaths({
|
||||||
|
path,
|
||||||
|
allowFoldersWithoutTrailingSlashes: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClearPaths = () => {
|
onClearPaths = () => {
|
||||||
|
|
|
@ -44,15 +44,21 @@ export const actionHandlers = handleThunks({
|
||||||
[FETCH_PATHS]: function(getState, payload, dispatch) {
|
[FETCH_PATHS]: function(getState, payload, dispatch) {
|
||||||
dispatch(set({ section, isFetching: true }));
|
dispatch(set({ section, isFetching: true }));
|
||||||
|
|
||||||
|
const {
|
||||||
|
path,
|
||||||
|
allowFoldersWithoutTrailingSlashes = false
|
||||||
|
} = payload;
|
||||||
|
|
||||||
const promise = $.ajax({
|
const promise = $.ajax({
|
||||||
url: '/filesystem',
|
url: '/filesystem',
|
||||||
data: {
|
data: {
|
||||||
path: payload.path
|
path,
|
||||||
|
allowFoldersWithoutTrailingSlashes
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
promise.done((data) => {
|
promise.done((data) => {
|
||||||
dispatch(updatePaths({ path: payload.path, ...data }));
|
dispatch(updatePaths({ path, ...data }));
|
||||||
|
|
||||||
dispatch(set({
|
dispatch(set({
|
||||||
section,
|
section,
|
||||||
|
|
|
@ -32,9 +32,9 @@ namespace Lidarr.Api.V1.FileSystem
|
||||||
{
|
{
|
||||||
var pathQuery = Request.Query.path;
|
var pathQuery = Request.Query.path;
|
||||||
var includeFiles = Request.GetBooleanQueryParameter("includeFiles");
|
var includeFiles = Request.GetBooleanQueryParameter("includeFiles");
|
||||||
|
var allowFoldersWithoutTrailingSlashes = Request.GetBooleanQueryParameter("allowFoldersWithoutTrailingSlashes");
|
||||||
|
|
||||||
|
return _fileSystemLookupService.LookupContents((string)pathQuery.Value, includeFiles, allowFoldersWithoutTrailingSlashes).AsResponse();
|
||||||
return _fileSystemLookupService.LookupContents((string)pathQuery.Value, includeFiles).AsResponse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetEntityType()
|
private Response GetEntityType()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
@ -49,7 +49,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
||||||
.Returns(_folders);
|
.Returns(_folders);
|
||||||
|
|
||||||
Subject.LookupContents(root, false).Directories.Should().NotContain(Path.Combine(root, RECYCLING_BIN));
|
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, RECYCLING_BIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -62,7 +62,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
||||||
.Returns(_folders);
|
.Returns(_folders);
|
||||||
|
|
||||||
Subject.LookupContents(root, false).Directories.Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
|
Subject.LookupContents(root, false, false).Directories.Should().NotContain(Path.Combine(root, SYSTEM_VOLUME_INFORMATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -75,8 +75,8 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
.Setup(s => s.GetDirectoryInfos(It.IsAny<string>()))
|
||||||
.Returns(_folders);
|
.Returns(_folders);
|
||||||
|
|
||||||
var result = Subject.LookupContents(root, false);
|
var result = Subject.LookupContents(root, false, false);
|
||||||
|
|
||||||
result.Directories.Should().HaveCount(_folders.Count - 3);
|
result.Directories.Should().HaveCount(_folders.Count - 3);
|
||||||
|
|
||||||
result.Directories.Should().NotContain(f => f.Name == RECYCLING_BIN);
|
result.Directories.Should().NotContain(f => f.Name == RECYCLING_BIN);
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace NzbDrone.Common.Disk
|
||||||
{
|
{
|
||||||
public interface IFileSystemLookupService
|
public interface IFileSystemLookupService
|
||||||
{
|
{
|
||||||
FileSystemResult LookupContents(string query, bool includeFiles);
|
FileSystemResult LookupContents(string query, bool includeFiles, bool allowFoldersWithoutTrailingSlashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileSystemLookupService : IFileSystemLookupService
|
public class FileSystemLookupService : IFileSystemLookupService
|
||||||
|
@ -51,14 +51,13 @@ namespace NzbDrone.Common.Disk
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileSystemResult LookupContents(string query, bool includeFiles)
|
public FileSystemResult LookupContents(string query, bool includeFiles, bool allowFoldersWithoutTrailingSlashes)
|
||||||
{
|
{
|
||||||
var result = new FileSystemResult();
|
|
||||||
|
|
||||||
if (query.IsNullOrWhiteSpace())
|
if (query.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
if (OsInfo.IsWindows)
|
if (OsInfo.IsWindows)
|
||||||
{
|
{
|
||||||
|
var result = new FileSystemResult();
|
||||||
result.Directories = GetDrives();
|
result.Directories = GetDrives();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -67,41 +66,23 @@ namespace NzbDrone.Common.Disk
|
||||||
query = "/";
|
query = "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
allowFoldersWithoutTrailingSlashes &&
|
||||||
|
query.IsPathValid() &&
|
||||||
|
_diskProvider.FolderExists(query))
|
||||||
|
{
|
||||||
|
return GetResult(query, includeFiles);
|
||||||
|
}
|
||||||
|
|
||||||
var lastSeparatorIndex = query.LastIndexOf(Path.DirectorySeparatorChar);
|
var lastSeparatorIndex = query.LastIndexOf(Path.DirectorySeparatorChar);
|
||||||
var path = query.Substring(0, lastSeparatorIndex + 1);
|
var path = query.Substring(0, lastSeparatorIndex + 1);
|
||||||
|
|
||||||
if (lastSeparatorIndex != -1)
|
if (lastSeparatorIndex != -1)
|
||||||
{
|
{
|
||||||
try
|
return GetResult(path, includeFiles);
|
||||||
{
|
|
||||||
result.Parent = GetParent(path);
|
|
||||||
result.Directories = GetDirectories(path);
|
|
||||||
|
|
||||||
if (includeFiles)
|
|
||||||
{
|
|
||||||
result.Files = GetFiles(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (DirectoryNotFoundException)
|
|
||||||
{
|
|
||||||
return new FileSystemResult { Parent = GetParent(path) };
|
|
||||||
}
|
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
|
||||||
return new FileSystemResult();
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
return new FileSystemResult { Parent = GetParent(path) };
|
|
||||||
}
|
|
||||||
catch (UnauthorizedAccessException)
|
|
||||||
{
|
|
||||||
return new FileSystemResult { Parent = GetParent(path) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return new FileSystemResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<FileSystemModel> GetDrives()
|
private List<FileSystemModel> GetDrives()
|
||||||
|
@ -117,6 +98,41 @@ namespace NzbDrone.Common.Disk
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FileSystemResult GetResult(string path, bool includeFiles)
|
||||||
|
{
|
||||||
|
var result = new FileSystemResult();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result.Parent = GetParent(path);
|
||||||
|
result.Directories = GetDirectories(path);
|
||||||
|
|
||||||
|
if (includeFiles)
|
||||||
|
{
|
||||||
|
result.Files = GetFiles(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
return new FileSystemResult { Parent = GetParent(path) };
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
return new FileSystemResult();
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
return new FileSystemResult { Parent = GetParent(path) };
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
return new FileSystemResult { Parent = GetParent(path) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private List<FileSystemModel> GetDirectories(string path)
|
private List<FileSystemModel> GetDirectories(string path)
|
||||||
{
|
{
|
||||||
var directories = _diskProvider.GetDirectoryInfos(path)
|
var directories = _diskProvider.GetDirectoryInfos(path)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue