rangement/index.mjs

224 lines
6.5 KiB
JavaScript
Raw Normal View History

2023-07-01 12:35:33 +02:00
/**---------------------
* @name tykayn Rangement
* @description Rangement sorts and rename files depending on their exif data
* @contact contact@cipherbliss.com
2023-07-04 15:26:27 +02:00
--------------------- */
2023-07-01 12:35:33 +02:00
/** ---------------------
2023-07-04 15:26:27 +02:00
libs
--------------------- */
2023-07-01 12:35:33 +02:00
import fs from 'node-fs'
import minimist from 'minimist'
2023-07-04 12:08:05 +02:00
import log from 'loglevel';
2023-07-04 15:26:27 +02:00
import path from "node:path";
2023-07-01 12:35:33 +02:00
/** ---------------------
2023-07-04 15:26:27 +02:00
custom utilities and configuration
2023-07-01 12:35:33 +02:00
--------------------- */
2023-07-04 15:26:27 +02:00
import rangement_instance from './configs.mjs'
2023-07-01 12:35:33 +02:00
import {
2023-07-04 15:26:27 +02:00
TestFindFormattedDate,
TestScreenShotIsFoundAndRenamed,
TestTagsAreDetectedInFileName
2023-07-01 12:35:33 +02:00
} from './testFunctions.mjs'
import finder from './finder.mjs'
2023-07-04 15:26:27 +02:00
import exiftool from "node-exiftool";
2023-07-01 12:35:33 +02:00
let mini_arguments
2023-07-04 15:26:27 +02:00
log.setLevel(rangement_instance.log_level)
2023-07-04 12:08:05 +02:00
log.info(' ')
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
function parseArguments() {
mini_arguments = minimist(process.argv.slice(2))
log.debug('arguments', mini_arguments)
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function addOriginalFileNameIfMissing(originalFileName, fileMixedNewName) {
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
const ep = new exiftool.ExiftoolProcess()
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
ep
.open(fileMixedNewName)
.then(() => ep.writeMetadata(fileMixedNewName, {
'OriginalFileName+': originalFileName,
}))
.then(console.log, console.error)
.then(() => ep.close())
.catch(console.error)
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function renameFile(originalFileName, fileMixedNewName) {
fs.rename(originalFileName, fileMixedNewName, function (err) {
log.info('name changed', fileMixedNewName)
if (err) {
log.info('rename ERROR: ' + err)
} else {
addOriginalFileNameIfMissing(originalFileName, fileMixedNewName)
rangement_instance.statistics['filesModified']++
}
})
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function appendFileName(fileProperties, newText) {
fileProperties.freeText = finder.cleanSpaces(fileProperties.freeText + ' ' + newText)
return fileProperties
}
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
function prependFileName(fileProperties, newText) {
fileProperties.freeText = finder.cleanSpaces(newText + ' ' + fileProperties.freeText)
return fileProperties
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function makeFileNameFromProperties(fileProperties) {
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
let tagPlace = ''
if (fileProperties.tags.length) {
tagPlace = ' ' + rangement_instance.tagSectionSeparator + ' '
}
return '' + fileProperties.dateStampExif + ' ' + fileProperties.freeText + tagPlace + fileProperties.tags.join(tagSeparator) + fileProperties.extension
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function shouldWeChangeName(structureForFile) {
log.info(' ______ allez hop fini la recherche on fait un nouveau nom')
log.info('structureForFile', structureForFile)
let newName = makeFileNameFromProperties(structureForFile)
if (structureForFile.fileNameOriginal !== newName) {
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
log.info('\n ancien nom :', structureForFile.fileNameOriginal)
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
log.info(' nouveau nom:', newName)
if (!mini_arguments['dry-run']) {
renameFile(structureForFile.fullPath, structureForFile.folderPath + newName)
} else {
log.info('no renaming for real, this is a dry run')
}
} else {
log.info(' rien à changer')
}
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
}
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
/**
* guess file name on one file which is not a directory
* @param fullPath
*/
function guessFileNameOnOnefile(fullPath) {
fs.stat(fullPath, (err, stats) => {
if (err) {
log.error('échec fichier', err)
log.error('ce fichier n existe pas: ', fullPath)
return;
} else {
let structureForFile = finder.destructurateFileName(fullPath)
// examiner les infos exif de chaque fichier pour proposer un nouveau nom
if (!structureForFile.dateStampInFileNameOriginal) {
log.debug(' le nom de fichier ne contient pas de date formatée au début')
finder.findExifCreationDate(structureForFile.fullPath)
.then(data => {
log.debug(' ... chercher la date de création')
let foundDate = finder.findEarliestDateInExifData(data)
log.info(' =>>>>>>> foundDate : ', foundDate)
if (foundDate) {
structureForFile.dateStampExif = foundDate
shouldWeChangeName(structureForFile)
} else {
log.info('pas de date trouvée dans le nom')
}
}
,
(error) => {
log.warn('/////////// Error in reading exif of file: ' + error.message)
return ''
})
}
}
})
}
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
let expandedFileList = []
let cwd = path.dirname(process.cwd()) + '/' + path.basename(process.cwd());
console.log('cwd', cwd)
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
function guessFileNameOnAllFilesFromArguments() {
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
// parcourir les fichiers
log.debug('liste des fichiers', mini_arguments._)
let fileList = mini_arguments._
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
// test file exists
fileList.forEach(fullPath => {
// parcourir les dossiers
isFolderOrFile(`${fullPath}`)
}
)
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
log.info('expanded file list :', expandedFileList)
expandedFileList.forEach(filePath => guessFileNameOnOnefile(filePath))
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
}
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
function readSubdirectories(baseDir) {
const newGlob = baseDir;
let fileList = [];
fs.readdir(baseDir, (err, files) => {
if (err) throw err;
console.log('files', files)
files.forEach((subDirOrFile) => {
const newFullPath = path.resolve(baseDir, subDirOrFile);
if (fs.existsSync(newFullPath)) {
const s = fs.statSync(newFullPath);
if (s.isFile()) {
fileList.push(cwd+'/'+subDirOrFile)
}
}
});
return fileList
});
return fileList
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
function isFolderOrFile(fileName) {
const stat = fs.statSync(cwd + '/' + fileName);
if (stat.isDirectory()) {
let fileList = readSubdirectories(fileName);
console.log('fileList in directory ',fileName, '\n', fileList)
if (fileList) {
expandedFileList.push(...fileList)
}
}
else if (stat.isFile()) {
expandedFileList.push(cwd + '/' + fileName)
}
}
parseArguments()
2023-07-01 12:35:33 +02:00
guessFileNameOnAllFilesFromArguments()
2023-07-04 15:26:27 +02:00
2023-07-01 12:35:33 +02:00
// run tests
2023-07-04 15:26:27 +02:00
if (rangement_instance.enableTestsLocally) {
2023-07-01 12:35:33 +02:00
2023-07-04 15:26:27 +02:00
TestTagsAreDetectedInFileName()
TestFindFormattedDate()
TestScreenShotIsFoundAndRenamed()
2023-07-01 12:35:33 +02:00
}
2023-07-04 15:26:27 +02:00
if (rangement_instance.reportStatistics || mini_arguments.stats) {
finder.reportStatistics()
2023-07-01 12:35:33 +02:00
}