Added deviceId in addition to inode to uniquely identify files

This commit is contained in:
Jason Axley 2025-08-15 09:09:06 -07:00
parent d8f07eb956
commit 3a4aacb7bf
17 changed files with 1445 additions and 227 deletions

View file

@ -113,7 +113,7 @@ class Task {
/**
* Set task as finished
*
* @param {TaskString} [newDescriptionString] update description
* @param {TaskString | null} [newDescriptionString] update description
* @param {boolean} [clearDescription] clear description
*/
setFinished(newDescriptionString = null, clearDescription = false) {

View file

@ -6,6 +6,7 @@ class AudioFile {
constructor(data) {
this.index = null
this.ino = null
this.deviceId = null
/** @type {FileMetadata} */
this.metadata = null
this.addedAt = null
@ -44,6 +45,7 @@ class AudioFile {
return {
index: this.index,
ino: this.ino,
deviceId: this.deviceId,
metadata: this.metadata.toJSON(),
addedAt: this.addedAt,
updatedAt: this.updatedAt,
@ -72,6 +74,7 @@ class AudioFile {
construct(data) {
this.index = data.index
this.ino = data.ino
this.deviceId = data.dev
this.metadata = new FileMetadata(data.metadata || {})
this.addedAt = data.addedAt
this.updatedAt = data.updatedAt
@ -112,6 +115,7 @@ class AudioFile {
// New scanner creates AudioFile from AudioFileScanner
setDataFromProbe(libraryFile, probeData) {
this.ino = libraryFile.ino || null
this.deviceId = libraryFile.deviceId || null
if (libraryFile.metadata instanceof FileMetadata) {
this.metadata = libraryFile.metadata.clone()
@ -137,7 +141,7 @@ class AudioFile {
syncChapters(updatedChapters) {
if (this.chapters.length !== updatedChapters.length) {
this.chapters = updatedChapters.map(ch => ({ ...ch }))
this.chapters = updatedChapters.map((ch) => ({ ...ch }))
return true
} else if (updatedChapters.length === 0) {
if (this.chapters.length > 0) {
@ -154,7 +158,7 @@ class AudioFile {
}
}
if (hasUpdates) {
this.chapters = updatedChapters.map(ch => ({ ...ch }))
this.chapters = updatedChapters.map((ch) => ({ ...ch }))
}
return hasUpdates
}
@ -164,8 +168,8 @@ class AudioFile {
}
/**
*
* @param {AudioFile} scannedAudioFile
*
* @param {AudioFile} scannedAudioFile
* @returns {boolean} true if updates were made
*/
updateFromScan(scannedAudioFile) {
@ -196,4 +200,4 @@ class AudioFile {
return hasUpdated
}
}
module.exports = AudioFile
module.exports = AudioFile

View file

@ -3,6 +3,7 @@ const FileMetadata = require('../metadata/FileMetadata')
class EBookFile {
constructor(file) {
this.ino = null
this.deviceId = null
this.metadata = null
this.ebookFormat = null
this.addedAt = null
@ -15,6 +16,7 @@ class EBookFile {
construct(file) {
this.ino = file.ino
this.deviceId = file.dev
this.metadata = new FileMetadata(file.metadata)
this.ebookFormat = file.ebookFormat || this.metadata.format
this.addedAt = file.addedAt
@ -24,6 +26,7 @@ class EBookFile {
toJSON() {
return {
ino: this.ino,
deviceId: this.deviceId,
metadata: this.metadata.toJSON(),
ebookFormat: this.ebookFormat,
addedAt: this.addedAt,
@ -37,6 +40,7 @@ class EBookFile {
setData(libraryFile) {
this.ino = libraryFile.ino
this.deviceId = libraryFile.deviceId
this.metadata = libraryFile.metadata.clone()
this.ebookFormat = libraryFile.metadata.format
this.addedAt = Date.now()
@ -58,4 +62,4 @@ class EBookFile {
return hasUpdated
}
}
module.exports = EBookFile
module.exports = EBookFile

View file

@ -1,11 +1,12 @@
const Path = require('path')
const { getFileTimestampsWithIno, filePathToPOSIX } = require('../../utils/fileUtils')
const fileUtils = require('../../utils/fileUtils')
const globals = require('../../utils/globals')
const FileMetadata = require('../metadata/FileMetadata')
class LibraryFile {
constructor(file) {
this.ino = null
this.deviceId = null
this.metadata = null
this.isSupplementary = null
this.addedAt = null
@ -18,6 +19,7 @@ class LibraryFile {
construct(file) {
this.ino = file.ino
this.deviceId = file.deviceId
this.metadata = new FileMetadata(file.metadata)
this.isSupplementary = file.isSupplementary === undefined ? null : file.isSupplementary
this.addedAt = file.addedAt
@ -27,7 +29,8 @@ class LibraryFile {
toJSON() {
return {
ino: this.ino,
metadata: this.metadata.toJSON(),
deviceId: this.deviceId,
metadata: this.metadata ? this.metadata.toJSON() : null,
isSupplementary: this.isSupplementary,
addedAt: this.addedAt,
updatedAt: this.updatedAt,
@ -40,11 +43,13 @@ class LibraryFile {
}
get fileType() {
if (globals.SupportedImageTypes.includes(this.metadata.format)) return 'image'
if (globals.SupportedAudioTypes.includes(this.metadata.format)) return 'audio'
if (globals.SupportedEbookTypes.includes(this.metadata.format)) return 'ebook'
if (globals.TextFileTypes.includes(this.metadata.format)) return 'text'
if (globals.MetadataFileTypes.includes(this.metadata.format)) return 'metadata'
if (this.metadata) {
if (globals.SupportedImageTypes.includes(this.metadata.format)) return 'image'
if (globals.SupportedAudioTypes.includes(this.metadata.format)) return 'audio'
if (globals.SupportedEbookTypes.includes(this.metadata.format)) return 'ebook'
if (globals.TextFileTypes.includes(this.metadata.format)) return 'text'
if (globals.MetadataFileTypes.includes(this.metadata.format)) return 'metadata'
}
return 'unknown'
}
@ -61,14 +66,15 @@ class LibraryFile {
}
async setDataFromPath(path, relPath) {
var fileTsData = await getFileTimestampsWithIno(path)
var fileTsData = await fileUtils.getFileTimestampsWithIno(path)
var fileMetadata = new FileMetadata()
fileMetadata.setData(fileTsData)
fileMetadata.filename = Path.basename(relPath)
fileMetadata.path = filePathToPOSIX(path)
fileMetadata.relPath = filePathToPOSIX(relPath)
fileMetadata.path = fileUtils.filePathToPOSIX(path)
fileMetadata.relPath = fileUtils.filePathToPOSIX(relPath)
fileMetadata.ext = Path.extname(relPath)
this.ino = fileTsData.ino
this.deviceId = fileTsData.dev
this.metadata = fileMetadata
this.addedAt = Date.now()
this.updatedAt = Date.now()