mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-05-28 14:21:34 +00:00
Fix issues with symlink directories
This commit is contained in:
parent
8b89b27654
commit
08c568a3fc
5 changed files with 18 additions and 8 deletions
|
|
@ -67,7 +67,8 @@ class FolderWatcher extends EventEmitter {
|
|||
renameTimeout: 2000,
|
||||
recursive: true,
|
||||
ignoreInitial: true,
|
||||
persistent: true
|
||||
persistent: true,
|
||||
followSymlinks: true
|
||||
})
|
||||
watcher
|
||||
.on('add', (path) => {
|
||||
|
|
|
|||
|
|
@ -71,13 +71,13 @@ const Utils = {
|
|||
poll: (targetPath, timeout = constants_1.POLLING_TIMEOUT) => {
|
||||
return ripstat_1.default(targetPath, timeout).catch(Utils.lang.noop);
|
||||
},
|
||||
readdir: async (rootPath, ignore, depth = Infinity, signal, readdirMap) => {
|
||||
readdir: async (rootPath, ignore, depth = Infinity, signal, readdirMap, followSymlinks = false) => {
|
||||
if (readdirMap && depth === 1 && rootPath in readdirMap) { // Reusing cached data
|
||||
const result = readdirMap[rootPath];
|
||||
return [result.directories, result.files];
|
||||
}
|
||||
else { // Retrieving fresh data
|
||||
const result = await tiny_readdir_1.default(rootPath, { depth, ignore, signal });
|
||||
const result = await tiny_readdir_1.default(rootPath, { depth, ignore, signal, followSymlinks });
|
||||
return [result.directories, result.files];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class WatcherHandler {
|
|||
var _a, _b;
|
||||
if (isInitial)
|
||||
return events;
|
||||
const depth = this.options.recursive ? (_a = this.options.depth) !== null && _a !== void 0 ? _a : constants_1.DEPTH : Math.min(1, (_b = this.options.depth) !== null && _b !== void 0 ? _b : constants_1.DEPTH), [directories, files] = await utils_1.default.fs.readdir(targetPath, this.options.ignore, depth, this.watcher._closeSignal), targetSubPaths = [...directories, ...files];
|
||||
const depth = this.options.recursive ? (_a = this.options.depth) !== null && _a !== void 0 ? _a : constants_1.DEPTH : Math.min(1, (_b = this.options.depth) !== null && _b !== void 0 ? _b : constants_1.DEPTH), [directories, files] = await utils_1.default.fs.readdir(targetPath, this.options.ignore, depth, this.watcher._closeSignal, undefined, this.options.followSymlinks), targetSubPaths = [...directories, ...files];
|
||||
await Promise.all(targetSubPaths.map(targetSubPath => {
|
||||
if (this.watcher.isIgnored(targetSubPath, this.options.ignore))
|
||||
return;
|
||||
|
|
@ -229,7 +229,7 @@ class WatcherHandler {
|
|||
await this.onWatcherEvent("change" /* CHANGE */, this.filePath, isInitial);
|
||||
}
|
||||
else { // Multiple initial paths
|
||||
const depth = this.options.recursive && (constants_1.HAS_NATIVE_RECURSION && this.options.native !== false) ? (_a = this.options.depth) !== null && _a !== void 0 ? _a : constants_1.DEPTH : Math.min(1, (_b = this.options.depth) !== null && _b !== void 0 ? _b : constants_1.DEPTH), [directories, files] = await utils_1.default.fs.readdir(this.folderPath, this.options.ignore, depth, this.watcher._closeSignal, this.options.readdirMap), targetPaths = [this.folderPath, ...directories, ...files];
|
||||
const depth = this.options.recursive && (constants_1.HAS_NATIVE_RECURSION && this.options.native !== false) ? (_a = this.options.depth) !== null && _a !== void 0 ? _a : constants_1.DEPTH : Math.min(1, (_b = this.options.depth) !== null && _b !== void 0 ? _b : constants_1.DEPTH), [directories, files] = await utils_1.default.fs.readdir(this.folderPath, this.options.ignore, depth, this.watcher._closeSignal, this.options.readdirMap, this.options.followSymlinks), targetPaths = [this.folderPath, ...directories, ...files];
|
||||
await Promise.all(targetPaths.map(targetPath => {
|
||||
if (this.watcher._poller.stats.has(targetPath))
|
||||
return; // Already polled
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ module.exports.recurseFiles = async (path, relPathToReplace = null) => {
|
|||
ignoreFolders: true,
|
||||
extensions: true,
|
||||
deep: true,
|
||||
realPath: true,
|
||||
realPath: false,
|
||||
normalizePath: false
|
||||
}
|
||||
let list = await rra.list(path, options)
|
||||
|
|
@ -517,7 +517,15 @@ module.exports.getDirectoriesInPath = async (dirPath, level) => {
|
|||
Logger.debug(`Failed to lstat "${fullPath}"`, error)
|
||||
return null
|
||||
})
|
||||
if (!lstat?.isDirectory()) return null
|
||||
if (!lstat) return null
|
||||
|
||||
let isDir = lstat.isDirectory()
|
||||
if (!isDir && lstat.isSymbolicLink()) {
|
||||
// Follow symlink to check if target is a directory
|
||||
const targetStat = await fs.stat(fullPath).catch(() => null)
|
||||
isDir = targetStat?.isDirectory() ?? false
|
||||
}
|
||||
if (!isDir) return null
|
||||
|
||||
return {
|
||||
path: this.filePathToPOSIX(fullPath),
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ describe('fileUtils', () => {
|
|||
// Stub fs.readdir
|
||||
readdirStub = sinon.stub(fs, 'readdir')
|
||||
readdirStub.callsFake((path, callback) => {
|
||||
const contents = mockDirContents.get(path)
|
||||
const normalizedPath = path.replace(/\/+$/, '')
|
||||
const contents = mockDirContents.get(normalizedPath)
|
||||
if (contents) {
|
||||
callback(null, contents)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue