mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Fix:Check if Windows before cleaning file path for POSIX separators #1254
This commit is contained in:
		
							parent
							
								
									f76f9c7f84
								
							
						
					
					
						commit
						9a85ad1f6b
					
				@ -88,7 +88,7 @@ class Logger {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  trace(...args) {
 | 
					  trace(...args) {
 | 
				
			||||||
    if (this.logLevel > LogLevel.TRACE) return
 | 
					    if (this.logLevel > LogLevel.TRACE) return
 | 
				
			||||||
    console.trace(`[${this.timestamp}[ TRACE:`, ...args)
 | 
					    console.trace(`[${this.timestamp}] TRACE:`, ...args)
 | 
				
			||||||
    this.handleLog(LogLevel.TRACE, args)
 | 
					    this.handleLog(LogLevel.TRACE, args)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@ const { version } = require('../package.json')
 | 
				
			|||||||
// Utils
 | 
					// Utils
 | 
				
			||||||
const dbMigration = require('./utils/dbMigration')
 | 
					const dbMigration = require('./utils/dbMigration')
 | 
				
			||||||
const filePerms = require('./utils/filePerms')
 | 
					const filePerms = require('./utils/filePerms')
 | 
				
			||||||
 | 
					const fileUtils = require('./utils/fileUtils')
 | 
				
			||||||
const Logger = require('./Logger')
 | 
					const Logger = require('./Logger')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Auth = require('./Auth')
 | 
					const Auth = require('./Auth')
 | 
				
			||||||
@ -44,16 +45,10 @@ class Server {
 | 
				
			|||||||
    global.isWin = process.platform === 'win32'
 | 
					    global.isWin = process.platform === 'win32'
 | 
				
			||||||
    global.Uid = isNaN(UID) ? 0 : Number(UID)
 | 
					    global.Uid = isNaN(UID) ? 0 : Number(UID)
 | 
				
			||||||
    global.Gid = isNaN(GID) ? 0 : Number(GID)
 | 
					    global.Gid = isNaN(GID) ? 0 : Number(GID)
 | 
				
			||||||
    global.ConfigPath = Path.normalize(CONFIG_PATH)
 | 
					    global.ConfigPath = fileUtils.filePathToPOSIX(Path.normalize(CONFIG_PATH))
 | 
				
			||||||
    global.MetadataPath = Path.normalize(METADATA_PATH)
 | 
					    global.MetadataPath = fileUtils.filePathToPOSIX(Path.normalize(METADATA_PATH))
 | 
				
			||||||
    global.RouterBasePath = ROUTER_BASE_PATH
 | 
					    global.RouterBasePath = ROUTER_BASE_PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Fix backslash if not on Windows
 | 
					 | 
				
			||||||
    if (process.platform !== 'win32') {
 | 
					 | 
				
			||||||
      global.ConfigPath = global.ConfigPath.replace(/\\/g, '/')
 | 
					 | 
				
			||||||
      global.MetadataPath = global.MetadataPath.replace(/\\/g, '/')
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!fs.pathExistsSync(global.ConfigPath)) {
 | 
					    if (!fs.pathExistsSync(global.ConfigPath)) {
 | 
				
			||||||
      fs.mkdirSync(global.ConfigPath)
 | 
					      fs.mkdirSync(global.ConfigPath)
 | 
				
			||||||
      filePerms.setDefaultDirSync(global.ConfigPath, false)
 | 
					      filePerms.setDefaultDirSync(global.ConfigPath, false)
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@ const EventEmitter = require('events')
 | 
				
			|||||||
const Watcher = require('./libs/watcher/watcher')
 | 
					const Watcher = require('./libs/watcher/watcher')
 | 
				
			||||||
const Logger = require('./Logger')
 | 
					const Logger = require('./Logger')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('./utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FolderWatcher extends EventEmitter {
 | 
					class FolderWatcher extends EventEmitter {
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    super()
 | 
					    super()
 | 
				
			||||||
@ -143,23 +145,23 @@ class FolderWatcher extends EventEmitter {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addFileUpdate(libraryId, path, type) {
 | 
					  addFileUpdate(libraryId, path, type) {
 | 
				
			||||||
    path = path.replace(/\\/g, '/')
 | 
					    path = filePathToPOSIX(path)
 | 
				
			||||||
    if (this.pendingFilePaths.includes(path)) return
 | 
					    if (this.pendingFilePaths.includes(path)) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get file library
 | 
					    // Get file library
 | 
				
			||||||
    var libwatcher = this.libraryWatchers.find(lw => lw.id === libraryId)
 | 
					    const libwatcher = this.libraryWatchers.find(lw => lw.id === libraryId)
 | 
				
			||||||
    if (!libwatcher) {
 | 
					    if (!libwatcher) {
 | 
				
			||||||
      Logger.error(`[Watcher] Invalid library id from watcher ${libraryId}`)
 | 
					      Logger.error(`[Watcher] Invalid library id from watcher ${libraryId}`)
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get file folder
 | 
					    // Get file folder
 | 
				
			||||||
    var folder = libwatcher.folders.find(fold => path.startsWith(fold.fullPath.replace(/\\/g, '/')))
 | 
					    const folder = libwatcher.folders.find(fold => path.startsWith(filePathToPOSIX(fold.fullPath)))
 | 
				
			||||||
    if (!folder) {
 | 
					    if (!folder) {
 | 
				
			||||||
      Logger.error(`[Watcher] New file folder not found in library "${libwatcher.name}" with path "${path}"`)
 | 
					      Logger.error(`[Watcher] New file folder not found in library "${libwatcher.name}" with path "${path}"`)
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    var folderFullPath = folder.fullPath.replace(/\\/g, '/')
 | 
					    const folderFullPath = filePathToPOSIX(folder.fullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var relPath = path.replace(folderFullPath, '')
 | 
					    var relPath = path.replace(folderFullPath, '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -189,12 +191,12 @@ class FolderWatcher extends EventEmitter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  checkShouldIgnorePath(path) {
 | 
					  checkShouldIgnorePath(path) {
 | 
				
			||||||
    return !!this.ignoreDirs.find(dirpath => {
 | 
					    return !!this.ignoreDirs.find(dirpath => {
 | 
				
			||||||
      return path.replace(/\\/g, '/').startsWith(dirpath)
 | 
					      return filePathToPOSIX(path).startsWith(dirpath)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cleanDirPath(path) {
 | 
					  cleanDirPath(path) {
 | 
				
			||||||
    var path = path.replace(/\\/g, '/')
 | 
					    path = filePathToPOSIX(path)
 | 
				
			||||||
    if (path.endsWith('/')) path = path.slice(0, -1)
 | 
					    if (path.endsWith('/')) path = path.slice(0, -1)
 | 
				
			||||||
    return path
 | 
					    return path
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ const SocketAuthority = require('../SocketAuthority')
 | 
				
			|||||||
const fs = require('../libs/fsExtra')
 | 
					const fs = require('../libs/fsExtra')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { getPodcastFeed, findMatchingEpisodes } = require('../utils/podcastUtils')
 | 
					const { getPodcastFeed, findMatchingEpisodes } = require('../utils/podcastUtils')
 | 
				
			||||||
const { getFileTimestampsWithIno } = require('../utils/fileUtils')
 | 
					const { getFileTimestampsWithIno, filePathToPOSIX } = require('../utils/fileUtils')
 | 
				
			||||||
const filePerms = require('../utils/filePerms')
 | 
					const filePerms = require('../utils/filePerms')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LibraryItem = require('../objects/LibraryItem')
 | 
					const LibraryItem = require('../objects/LibraryItem')
 | 
				
			||||||
@ -30,7 +30,7 @@ class PodcastController {
 | 
				
			|||||||
      return res.status(404).send('Folder not found')
 | 
					      return res.status(404).send('Folder not found')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var podcastPath = payload.path.replace(/\\/g, '/')
 | 
					    const podcastPath = filePathToPOSIX(payload.path)
 | 
				
			||||||
    if (await fs.pathExists(podcastPath)) {
 | 
					    if (await fs.pathExists(podcastPath)) {
 | 
				
			||||||
      Logger.error(`[PodcastController] Podcast folder already exists "${podcastPath}"`)
 | 
					      Logger.error(`[PodcastController] Podcast folder already exists "${podcastPath}"`)
 | 
				
			||||||
      return res.status(400).send('Podcast already exists')
 | 
					      return res.status(400).send('Podcast already exists')
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ const fs = require('../libs/fsExtra')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const filePerms = require('../utils/filePerms')
 | 
					const filePerms = require('../utils/filePerms')
 | 
				
			||||||
const { secondsToTimestamp } = require('../utils/index')
 | 
					const { secondsToTimestamp } = require('../utils/index')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('../utils/fileUtils')
 | 
				
			||||||
const { writeMetadataFile } = require('../utils/ffmpegHelpers')
 | 
					const { writeMetadataFile } = require('../utils/ffmpegHelpers')
 | 
				
			||||||
const toneHelpers = require('../utils/toneHelpers')
 | 
					const toneHelpers = require('../utils/toneHelpers')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -127,7 +128,7 @@ class AudioMetadataMangaer {
 | 
				
			|||||||
    await writeMetadataFile(libraryItem, metadataFilePath)
 | 
					    await writeMetadataFile(libraryItem, metadataFilePath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (libraryItem.media.coverPath != null) {
 | 
					    if (libraryItem.media.coverPath != null) {
 | 
				
			||||||
      var coverPath = libraryItem.media.coverPath.replace(/\\/g, '/')
 | 
					      var coverPath = filePathToPOSIX(libraryItem.media.coverPath)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const proms = audioFiles.map(af => {
 | 
					    const proms = audioFiles.map(af => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,12 @@
 | 
				
			|||||||
const fs = require('../libs/fsExtra')
 | 
					const fs = require('../libs/fsExtra')
 | 
				
			||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const axios = require('axios')
 | 
					 | 
				
			||||||
const Logger = require('../Logger')
 | 
					const Logger = require('../Logger')
 | 
				
			||||||
const readChunk = require('../libs/readChunk')
 | 
					const readChunk = require('../libs/readChunk')
 | 
				
			||||||
const imageType = require('../libs/imageType')
 | 
					const imageType = require('../libs/imageType')
 | 
				
			||||||
const filePerms = require('../utils/filePerms')
 | 
					const filePerms = require('../utils/filePerms')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const globals = require('../utils/globals')
 | 
					const globals = require('../utils/globals')
 | 
				
			||||||
const { downloadFile } = require('../utils/fileUtils')
 | 
					const { downloadFile, filePathToPOSIX } = require('../utils/fileUtils')
 | 
				
			||||||
const { extractCoverArt } = require('../utils/ffmpegHelpers')
 | 
					const { extractCoverArt } = require('../utils/ffmpegHelpers')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CoverManager {
 | 
					class CoverManager {
 | 
				
			||||||
@ -173,7 +172,7 @@ class CoverManager {
 | 
				
			|||||||
        error: 'Invalid cover path'
 | 
					        error: 'Invalid cover path'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    coverPath = coverPath.replace(/\\/g, '/')
 | 
					    coverPath = filePathToPOSIX(coverPath)
 | 
				
			||||||
    // Cover path already set on media
 | 
					    // Cover path already set on media
 | 
				
			||||||
    if (libraryItem.media.coverPath == coverPath) {
 | 
					    if (libraryItem.media.coverPath == coverPath) {
 | 
				
			||||||
      Logger.debug(`[CoverManager] validate cover path already set "${coverPath}"`)
 | 
					      Logger.debug(`[CoverManager] validate cover path already set "${coverPath}"`)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
const Folder = require('./Folder')
 | 
					const Folder = require('./Folder')
 | 
				
			||||||
const LibrarySettings = require('./settings/LibrarySettings')
 | 
					const LibrarySettings = require('./settings/LibrarySettings')
 | 
				
			||||||
const { getId } = require('../utils/index')
 | 
					const { getId } = require('../utils/index')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('../utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Library {
 | 
					class Library {
 | 
				
			||||||
  constructor(library = null) {
 | 
					  constructor(library = null) {
 | 
				
			||||||
@ -156,8 +157,8 @@ class Library {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  checkFullPathInLibrary(fullPath) {
 | 
					  checkFullPathInLibrary(fullPath) {
 | 
				
			||||||
    fullPath = fullPath.replace(/\\/g, '/')
 | 
					    fullPath = filePathToPOSIX(fullPath)
 | 
				
			||||||
    return this.folders.find(folder => fullPath.startsWith(folder.fullPath.replace(/\\/g, '/')))
 | 
					    return this.folders.find(folder => fullPath.startsWith(filePathToPOSIX(folder.fullPath)))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getFolderById(id) {
 | 
					  getFolderById(id) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const { encodeUriPath } = require('../../utils/index')
 | 
					const { encodeUriPath } = require('../../utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AudioTrack {
 | 
					class AudioTrack {
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const { encodeUriPath } = require('../../utils/index')
 | 
					const { encodeUriPath } = require('../../utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VideoTrack {
 | 
					class VideoTrack {
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ const { areEquivalent, copyValue, cleanStringForSearch } = require('../../utils/
 | 
				
			|||||||
const { parseOpfMetadataXML } = require('../../utils/parsers/parseOpfMetadata')
 | 
					const { parseOpfMetadataXML } = require('../../utils/parsers/parseOpfMetadata')
 | 
				
			||||||
const { parseOverdriveMediaMarkersAsChapters } = require('../../utils/parsers/parseOverdriveMediaMarkers')
 | 
					const { parseOverdriveMediaMarkersAsChapters } = require('../../utils/parsers/parseOverdriveMediaMarkers')
 | 
				
			||||||
const abmetadataGenerator = require('../../utils/abmetadataGenerator')
 | 
					const abmetadataGenerator = require('../../utils/abmetadataGenerator')
 | 
				
			||||||
const { readTextFile } = require('../../utils/fileUtils')
 | 
					const { readTextFile, filePathToPOSIX } = require('../../utils/fileUtils')
 | 
				
			||||||
const AudioFile = require('../files/AudioFile')
 | 
					const AudioFile = require('../files/AudioFile')
 | 
				
			||||||
const AudioTrack = require('../files/AudioTrack')
 | 
					const AudioTrack = require('../files/AudioTrack')
 | 
				
			||||||
const EBookFile = require('../files/EBookFile')
 | 
					const EBookFile = require('../files/EBookFile')
 | 
				
			||||||
@ -182,7 +182,7 @@ class Book {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateCover(coverPath) {
 | 
					  updateCover(coverPath) {
 | 
				
			||||||
    coverPath = coverPath.replace(/\\/g, '/')
 | 
					    coverPath = filePathToPOSIX(coverPath)
 | 
				
			||||||
    if (this.coverPath === coverPath) return false
 | 
					    if (this.coverPath === coverPath) return false
 | 
				
			||||||
    this.coverPath = coverPath
 | 
					    this.coverPath = coverPath
 | 
				
			||||||
    return true
 | 
					    return true
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ const AudioFile = require('../files/AudioFile')
 | 
				
			|||||||
const AudioTrack = require('../files/AudioTrack')
 | 
					const AudioTrack = require('../files/AudioTrack')
 | 
				
			||||||
const MusicMetadata = require('../metadata/MusicMetadata')
 | 
					const MusicMetadata = require('../metadata/MusicMetadata')
 | 
				
			||||||
const { areEquivalent, copyValue } = require('../../utils/index')
 | 
					const { areEquivalent, copyValue } = require('../../utils/index')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('../../utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Music {
 | 
					class Music {
 | 
				
			||||||
  constructor(music) {
 | 
					  constructor(music) {
 | 
				
			||||||
@ -106,7 +107,7 @@ class Music {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateCover(coverPath) {
 | 
					  updateCover(coverPath) {
 | 
				
			||||||
    coverPath = coverPath.replace(/\\/g, '/')
 | 
					    coverPath = filePathToPOSIX(coverPath)
 | 
				
			||||||
    if (this.coverPath === coverPath) return false
 | 
					    if (this.coverPath === coverPath) return false
 | 
				
			||||||
    this.coverPath = coverPath
 | 
					    this.coverPath = coverPath
 | 
				
			||||||
    return true
 | 
					    return true
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ const PodcastEpisode = require('../entities/PodcastEpisode')
 | 
				
			|||||||
const PodcastMetadata = require('../metadata/PodcastMetadata')
 | 
					const PodcastMetadata = require('../metadata/PodcastMetadata')
 | 
				
			||||||
const { areEquivalent, copyValue, cleanStringForSearch } = require('../../utils/index')
 | 
					const { areEquivalent, copyValue, cleanStringForSearch } = require('../../utils/index')
 | 
				
			||||||
const abmetadataGenerator = require('../../utils/abmetadataGenerator')
 | 
					const abmetadataGenerator = require('../../utils/abmetadataGenerator')
 | 
				
			||||||
const { readTextFile } = require('../../utils/fileUtils')
 | 
					const { readTextFile, filePathToPOSIX } = require('../../utils/fileUtils')
 | 
				
			||||||
const { createNewSortInstance } = require('../../libs/fastSort')
 | 
					const { createNewSortInstance } = require('../../libs/fastSort')
 | 
				
			||||||
const naturalSort = createNewSortInstance({
 | 
					const naturalSort = createNewSortInstance({
 | 
				
			||||||
  comparer: new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare
 | 
					  comparer: new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare
 | 
				
			||||||
@ -159,7 +159,7 @@ class Podcast {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateCover(coverPath) {
 | 
					  updateCover(coverPath) {
 | 
				
			||||||
    coverPath = coverPath.replace(/\\/g, '/')
 | 
					    coverPath = filePathToPOSIX(coverPath)
 | 
				
			||||||
    if (this.coverPath === coverPath) return false
 | 
					    if (this.coverPath === coverPath) return false
 | 
				
			||||||
    this.coverPath = coverPath
 | 
					    this.coverPath = coverPath
 | 
				
			||||||
    return true
 | 
					    return true
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ const VideoFile = require('../files/VideoFile')
 | 
				
			|||||||
const VideoTrack = require('../files/VideoTrack')
 | 
					const VideoTrack = require('../files/VideoTrack')
 | 
				
			||||||
const VideoMetadata = require('../metadata/VideoMetadata')
 | 
					const VideoMetadata = require('../metadata/VideoMetadata')
 | 
				
			||||||
const { areEquivalent, copyValue } = require('../../utils/index')
 | 
					const { areEquivalent, copyValue } = require('../../utils/index')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('../../utils/fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Video {
 | 
					class Video {
 | 
				
			||||||
  constructor(video) {
 | 
					  constructor(video) {
 | 
				
			||||||
@ -101,7 +102,7 @@ class Video {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateCover(coverPath) {
 | 
					  updateCover(coverPath) {
 | 
				
			||||||
    coverPath = coverPath.replace(/\\/g, '/')
 | 
					    coverPath = filePathToPOSIX(coverPath)
 | 
				
			||||||
    if (this.coverPath === coverPath) return false
 | 
					    if (this.coverPath === coverPath) return false
 | 
				
			||||||
    this.coverPath = coverPath
 | 
					    this.coverPath = coverPath
 | 
				
			||||||
    return true
 | 
					    return true
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ const SocketAuthority = require('../SocketAuthority')
 | 
				
			|||||||
// Utils
 | 
					// Utils
 | 
				
			||||||
const { groupFilesIntoLibraryItemPaths, getLibraryItemFileData, scanFolder } = require('../utils/scandir')
 | 
					const { groupFilesIntoLibraryItemPaths, getLibraryItemFileData, scanFolder } = require('../utils/scandir')
 | 
				
			||||||
const { comparePaths } = require('../utils/index')
 | 
					const { comparePaths } = require('../utils/index')
 | 
				
			||||||
const { getIno } = require('../utils/fileUtils')
 | 
					const { getIno, filePathToPOSIX } = require('../utils/fileUtils')
 | 
				
			||||||
const { ScanResult, LogLevel } = require('../utils/constants')
 | 
					const { ScanResult, LogLevel } = require('../utils/constants')
 | 
				
			||||||
const { findMatchingEpisodesInFeed, getPodcastFeed } = require('../utils/podcastUtils')
 | 
					const { findMatchingEpisodesInFeed, getPodcastFeed } = require('../utils/podcastUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -554,12 +554,12 @@ class Scanner {
 | 
				
			|||||||
      var firstNest = itemDirNestedFiles[0].split('/').shift()
 | 
					      var firstNest = itemDirNestedFiles[0].split('/').shift()
 | 
				
			||||||
      var altDir = `${itemDir}/${firstNest}`
 | 
					      var altDir = `${itemDir}/${firstNest}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var fullPath = Path.posix.join(folder.fullPath.replace(/\\/g, '/'), itemDir)
 | 
					      var fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir)
 | 
				
			||||||
      var childLibraryItem = this.db.libraryItems.find(li => li.path !== fullPath && li.path.startsWith(fullPath))
 | 
					      var childLibraryItem = this.db.libraryItems.find(li => li.path !== fullPath && li.path.startsWith(fullPath))
 | 
				
			||||||
      if (!childLibraryItem) {
 | 
					      if (!childLibraryItem) {
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      var altFullPath = Path.posix.join(folder.fullPath.replace(/\\/g, '/'), altDir)
 | 
					      var altFullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), altDir)
 | 
				
			||||||
      var altChildLibraryItem = this.db.libraryItems.find(li => li.path !== altFullPath && li.path.startsWith(altFullPath))
 | 
					      var altChildLibraryItem = this.db.libraryItems.find(li => li.path !== altFullPath && li.path.startsWith(altFullPath))
 | 
				
			||||||
      if (altChildLibraryItem) {
 | 
					      if (altChildLibraryItem) {
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
@ -571,13 +571,13 @@ class Scanner {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Second pass: Check for new/updated/removed items
 | 
					    // Second pass: Check for new/updated/removed items
 | 
				
			||||||
    var itemGroupingResults = {}
 | 
					    const itemGroupingResults = {}
 | 
				
			||||||
    for (const itemDir in fileUpdateGroup) {
 | 
					    for (const itemDir in fileUpdateGroup) {
 | 
				
			||||||
      var fullPath = Path.posix.join(folder.fullPath.replace(/\\/g, '/'), itemDir)
 | 
					      const fullPath = Path.posix.join(filePathToPOSIX(folder.fullPath), itemDir)
 | 
				
			||||||
      const dirIno = await getIno(fullPath)
 | 
					      const dirIno = await getIno(fullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Check if book dir group is already an item
 | 
					      // Check if book dir group is already an item
 | 
				
			||||||
      var existingLibraryItem = this.db.libraryItems.find(li => fullPath.startsWith(li.path))
 | 
					      let existingLibraryItem = this.db.libraryItems.find(li => fullPath.startsWith(li.path))
 | 
				
			||||||
      if (!existingLibraryItem) {
 | 
					      if (!existingLibraryItem) {
 | 
				
			||||||
        existingLibraryItem = this.db.libraryItems.find(li => li.ino === dirIno)
 | 
					        existingLibraryItem = this.db.libraryItems.find(li => li.ino === dirIno)
 | 
				
			||||||
        if (existingLibraryItem) {
 | 
					        if (existingLibraryItem) {
 | 
				
			||||||
@ -590,7 +590,7 @@ class Scanner {
 | 
				
			|||||||
      if (existingLibraryItem) {
 | 
					      if (existingLibraryItem) {
 | 
				
			||||||
        // Is the item exactly - check if was deleted
 | 
					        // Is the item exactly - check if was deleted
 | 
				
			||||||
        if (existingLibraryItem.path === fullPath) {
 | 
					        if (existingLibraryItem.path === fullPath) {
 | 
				
			||||||
          var exists = await fs.pathExists(fullPath)
 | 
					          const exists = await fs.pathExists(fullPath)
 | 
				
			||||||
          if (!exists) {
 | 
					          if (!exists) {
 | 
				
			||||||
            Logger.info(`[Scanner] Scanning file update group and library item was deleted "${existingLibraryItem.media.metadata.title}" - marking as missing`)
 | 
					            Logger.info(`[Scanner] Scanning file update group and library item was deleted "${existingLibraryItem.media.metadata.title}" - marking as missing`)
 | 
				
			||||||
            existingLibraryItem.setMissing()
 | 
					            existingLibraryItem.setMissing()
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ const njodb = require('../libs/njodb')
 | 
				
			|||||||
const { SupportedEbookTypes } = require('./globals')
 | 
					const { SupportedEbookTypes } = require('./globals')
 | 
				
			||||||
const { PlayMethod } = require('./constants')
 | 
					const { PlayMethod } = require('./constants')
 | 
				
			||||||
const { getId } = require('./index')
 | 
					const { getId } = require('./index')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('./fileUtils')
 | 
				
			||||||
const Logger = require('../Logger')
 | 
					const Logger = require('../Logger')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Library = require('../objects/Library')
 | 
					const Library = require('../objects/Library')
 | 
				
			||||||
@ -87,8 +88,8 @@ function makeSeriesFromOldAb({ series, volumeNumber }) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getRelativePath(srcPath, basePath) {
 | 
					function getRelativePath(srcPath, basePath) {
 | 
				
			||||||
  srcPath = srcPath.replace(/\\/g, '/')
 | 
					  srcPath = filePathToPOSIX(srcPath)
 | 
				
			||||||
  basePath = basePath.replace(/\\/g, '/')
 | 
					  basePath = filePathToPOSIX(basePath)
 | 
				
			||||||
  return srcPath.replace(basePath, '')
 | 
					  return srcPath.replace(basePath, '')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,11 @@ const fs = require('../libs/fsExtra')
 | 
				
			|||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const package = require('../../package.json')
 | 
					const package = require('../../package.json')
 | 
				
			||||||
const Logger = require('../Logger')
 | 
					const Logger = require('../Logger')
 | 
				
			||||||
 | 
					const { filePathToPOSIX } = require('./fileUtils')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function escapeSingleQuotes(path) {
 | 
					function escapeSingleQuotes(path) {
 | 
				
			||||||
  // return path.replace(/'/g, '\'\\\'\'')
 | 
					  // return path.replace(/'/g, '\'\\\'\'')
 | 
				
			||||||
  return path.replace(/\\/g, '/').replace(/ /g, '\\ ').replace(/'/g, '\\\'')
 | 
					  return filePathToPOSIX(path).replace(/ /g, '\\ ').replace(/'/g, '\\\'')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns first track start time
 | 
					// Returns first track start time
 | 
				
			||||||
 | 
				
			|||||||
@ -80,11 +80,11 @@ function bytesPretty(bytes, decimals = 0) {
 | 
				
			|||||||
module.exports.bytesPretty = bytesPretty
 | 
					module.exports.bytesPretty = bytesPretty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function recurseFiles(path, relPathToReplace = null) {
 | 
					async function recurseFiles(path, relPathToReplace = null) {
 | 
				
			||||||
  path = path.replace(/\\/g, '/')
 | 
					  path = this.filePathToPOSIX(path)
 | 
				
			||||||
  if (!path.endsWith('/')) path = path + '/'
 | 
					  if (!path.endsWith('/')) path = path + '/'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (relPathToReplace) {
 | 
					  if (relPathToReplace) {
 | 
				
			||||||
    relPathToReplace = relPathToReplace.replace(/\\/g, '/')
 | 
					    relPathToReplace = this.filePathToPOSIX(relPathToReplace)
 | 
				
			||||||
    if (!relPathToReplace.endsWith('/')) relPathToReplace += '/'
 | 
					    if (!relPathToReplace.endsWith('/')) relPathToReplace += '/'
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    relPathToReplace = path
 | 
					    relPathToReplace = path
 | 
				
			||||||
@ -244,4 +244,19 @@ module.exports.removeFile = (path) => {
 | 
				
			|||||||
    Logger.error(`[fileUtils] Failed remove file "${path}"`, error)
 | 
					    Logger.error(`[fileUtils] Failed remove file "${path}"`, error)
 | 
				
			||||||
    return false
 | 
					    return false
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* Make sure folder separator is POSIX for Windows file paths. e.g. "C:\Users\Abs" becomes "C:/Users/Abs"
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* @param {String} path - Ugly file path
 | 
				
			||||||
 | 
					* @return {String} Pretty posix file path
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					module.exports.filePathToPOSIX = (path) => {
 | 
				
			||||||
 | 
					  if (!global.isWin || !path) return path
 | 
				
			||||||
 | 
					  return path.replace(/\\/g, '/')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.encodeUriPath = (path) => {
 | 
				
			||||||
 | 
					  return this.filePathToPOSIX(path).replace(/%/g, '%25').replace(/#/g, '%23')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const fs = require('fs')
 | 
					 | 
				
			||||||
const Logger = require('../Logger')
 | 
					const Logger = require('../Logger')
 | 
				
			||||||
const { parseString } = require("xml2js")
 | 
					const { parseString } = require("xml2js")
 | 
				
			||||||
const areEquivalent = require('./areEquivalent')
 | 
					const areEquivalent = require('./areEquivalent')
 | 
				
			||||||
@ -125,10 +124,6 @@ module.exports.copyValue = (val) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.encodeUriPath = (path) => {
 | 
					 | 
				
			||||||
  return path.replace(/\\/g, '/').replace(/%/g, '%25').replace(/#/g, '%23')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports.toNumber = (val, fallback = 0) => {
 | 
					module.exports.toNumber = (val, fallback = 0) => {
 | 
				
			||||||
  if (isNaN(val) || val === null) return fallback
 | 
					  if (isNaN(val) || val === null) return fallback
 | 
				
			||||||
  return Number(val)
 | 
					  return Number(val)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
const Path = require('path')
 | 
					const Path = require('path')
 | 
				
			||||||
const fs = require('../libs/fsExtra')
 | 
					const fs = require('../libs/fsExtra')
 | 
				
			||||||
const Logger = require('../Logger')
 | 
					const Logger = require('../Logger')
 | 
				
			||||||
const { recurseFiles, getFileTimestampsWithIno } = require('./fileUtils')
 | 
					const { recurseFiles, getFileTimestampsWithIno, filePathToPOSIX } = require('./fileUtils')
 | 
				
			||||||
const globals = require('./globals')
 | 
					const globals = require('./globals')
 | 
				
			||||||
const LibraryFile = require('../objects/files/LibraryFile')
 | 
					const LibraryFile = require('../objects/files/LibraryFile')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,7 +176,7 @@ function cleanFileObjects(libraryItemPath, files) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Scan folder
 | 
					// Scan folder
 | 
				
			||||||
async function scanFolder(libraryMediaType, folder, serverSettings = {}) {
 | 
					async function scanFolder(libraryMediaType, folder, serverSettings = {}) {
 | 
				
			||||||
  const folderPath = folder.fullPath.replace(/\\/g, '/')
 | 
					  const folderPath = filePathToPOSIX(folder.fullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const pathExists = await fs.pathExists(folderPath)
 | 
					  const pathExists = await fs.pathExists(folderPath)
 | 
				
			||||||
  if (!pathExists) {
 | 
					  if (!pathExists) {
 | 
				
			||||||
@ -243,7 +243,7 @@ module.exports.scanFolder = scanFolder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Input relative filepath, output all details that can be parsed
 | 
					// Input relative filepath, output all details that can be parsed
 | 
				
			||||||
function getBookDataFromDir(folderPath, relPath, parseSubtitle = false) {
 | 
					function getBookDataFromDir(folderPath, relPath, parseSubtitle = false) {
 | 
				
			||||||
  relPath = relPath.replace(/\\/g, '/')
 | 
					  relPath = filePathToPOSIX(relPath)
 | 
				
			||||||
  var splitDir = relPath.split('/')
 | 
					  var splitDir = relPath.split('/')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var folder = splitDir.pop() // Audio files will always be in the directory named for the title
 | 
					  var folder = splitDir.pop() // Audio files will always be in the directory named for the title
 | 
				
			||||||
@ -333,7 +333,7 @@ function getSubtitle(folder) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getPodcastDataFromDir(folderPath, relPath) {
 | 
					function getPodcastDataFromDir(folderPath, relPath) {
 | 
				
			||||||
  relPath = relPath.replace(/\\/g, '/')
 | 
					  relPath = filePathToPOSIX(relPath)
 | 
				
			||||||
  const splitDir = relPath.split('/')
 | 
					  const splitDir = relPath.split('/')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Audio files will always be in the directory named for the title
 | 
					  // Audio files will always be in the directory named for the title
 | 
				
			||||||
@ -360,8 +360,8 @@ function getDataFromMediaDir(libraryMediaType, folderPath, relPath, serverSettin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Called from Scanner.js
 | 
					// Called from Scanner.js
 | 
				
			||||||
async function getLibraryItemFileData(libraryMediaType, folder, libraryItemPath, isSingleMediaItem, serverSettings = {}) {
 | 
					async function getLibraryItemFileData(libraryMediaType, folder, libraryItemPath, isSingleMediaItem, serverSettings = {}) {
 | 
				
			||||||
  libraryItemPath = libraryItemPath.replace(/\\/g, '/')
 | 
					  libraryItemPath = filePathToPOSIX(libraryItemPath)
 | 
				
			||||||
  const folderFullPath = folder.fullPath.replace(/\\/g, '/')
 | 
					  const folderFullPath = filePathToPOSIX(folder.fullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const libraryItemDir = libraryItemPath.replace(folderFullPath, '').slice(1)
 | 
					  const libraryItemDir = libraryItemPath.replace(folderFullPath, '').slice(1)
 | 
				
			||||||
  let libraryItemData = {}
 | 
					  let libraryItemData = {}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user