add decision making on tag change
This commit is contained in:
parent
e41eaa0966
commit
51731aad08
@ -1,11 +1,13 @@
|
|||||||
import mainTemplates from './mainTemplates.mjs'
|
import mainTemplates from './mainTemplates.mjs'
|
||||||
import constants from './folders.js'
|
import constants from './folders.js'
|
||||||
|
import cv from './controlled_vocabulary.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* configuration générale à importer dans les utilitaires
|
* configuration générale à importer dans les utilitaires
|
||||||
*/
|
*/
|
||||||
class config_rangement {
|
class config_rangement {
|
||||||
log_level = 'info' // 'debug' | 'warn' |'info'
|
log_level = 'debug' // 'debug' | 'warn' |'info'
|
||||||
|
|
||||||
version = '1.0.0'
|
version = '1.0.0'
|
||||||
iso_date_format = 'yyyy-MM-DDTHH.mm.ss' // target format for dates in file names
|
iso_date_format = 'yyyy-MM-DDTHH.mm.ss' // target format for dates in file names
|
||||||
tagSeparator = ' '
|
tagSeparator = ' '
|
||||||
@ -15,17 +17,20 @@ class config_rangement {
|
|||||||
replaceUnderscoreWithSpaces = true
|
replaceUnderscoreWithSpaces = true
|
||||||
renameFolders = false
|
renameFolders = false
|
||||||
enableTestsLocally = false
|
enableTestsLocally = false
|
||||||
reportStatistics = false
|
reportStatistics = true
|
||||||
|
controlled_vocabulary = cv
|
||||||
constants = constants
|
constants = constants
|
||||||
base_archive_folder = constants.base_archive_folder
|
base_archive_folder = constants.base_archive_folder
|
||||||
templates = mainTemplates;
|
templates = mainTemplates;
|
||||||
|
statistics= {};
|
||||||
|
keepOriginalNameInRename=true;
|
||||||
|
log_actions=true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* override config if we want
|
* override config if we want
|
||||||
* @param overridingConfig
|
* @param overridingConfig
|
||||||
*/
|
*/
|
||||||
constructor (overridingConfig) {
|
constructor (overridingConfig) {
|
||||||
console.log('overridingConfig', overridingConfig)
|
|
||||||
let keys = Object.keys(overridingConfig)
|
let keys = Object.keys(overridingConfig)
|
||||||
let self = this;
|
let self = this;
|
||||||
keys.forEach(elem=>{
|
keys.forEach(elem=>{
|
||||||
|
39
conf/controlled_vocabulary.js
Normal file
39
conf/controlled_vocabulary.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const cv = `
|
||||||
|
amis
|
||||||
|
animaux
|
||||||
|
animaux
|
||||||
|
bâtiment
|
||||||
|
brouillon final
|
||||||
|
carte
|
||||||
|
chantier
|
||||||
|
claire
|
||||||
|
dodo
|
||||||
|
doudou
|
||||||
|
famille
|
||||||
|
festival
|
||||||
|
fête
|
||||||
|
gopro
|
||||||
|
gopro-back
|
||||||
|
gopro-front
|
||||||
|
graph
|
||||||
|
gull
|
||||||
|
has_no_tag
|
||||||
|
illustration
|
||||||
|
maison
|
||||||
|
manif
|
||||||
|
matériel
|
||||||
|
nourriture
|
||||||
|
papier
|
||||||
|
plan
|
||||||
|
portrait
|
||||||
|
public private
|
||||||
|
sélection
|
||||||
|
sexy
|
||||||
|
taiga
|
||||||
|
tykayn
|
||||||
|
voiture
|
||||||
|
voyage
|
||||||
|
`.split('\n')
|
||||||
|
|
||||||
|
// TODO handle exclusive tags that are spectified on one line
|
||||||
|
export default cv;
|
47
index.mjs
47
index.mjs
@ -18,8 +18,8 @@ import {
|
|||||||
TestFindFormattedDate,
|
TestFindFormattedDate,
|
||||||
TestScreenShotIsFoundAndRenamed,
|
TestScreenShotIsFoundAndRenamed,
|
||||||
TestTagsAreDetectedInFileName
|
TestTagsAreDetectedInFileName
|
||||||
} from './testFunctions.mjs'
|
} from './utils/testFunctions.mjs'
|
||||||
import finder from './finder.mjs'
|
import finder from './utils/finder.mjs'
|
||||||
|
|
||||||
let mini_arguments
|
let mini_arguments
|
||||||
|
|
||||||
@ -31,21 +31,26 @@ function parseArguments () {
|
|||||||
log.debug('arguments', mini_arguments)
|
log.debug('arguments', mini_arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if there is no original file name free text into the new name, append it to the free text part
|
||||||
|
* @param originalFileName
|
||||||
|
* @param fileMixedNewName
|
||||||
|
*/
|
||||||
function addOriginalFileNameIfMissing (originalFileName, fileMixedNewName) {
|
function addOriginalFileNameIfMissing (originalFileName, fileMixedNewName) {
|
||||||
|
|
||||||
// const ep = new exiftool.ExiftoolProcess()
|
if (!fileMixedNewName.includes(originalFileName)) {
|
||||||
//
|
let properties = finder.destructurateFileName(fileMixedNewName)
|
||||||
// ep
|
return properties.freeText + ' ' + originalFileName
|
||||||
// .open(fileMixedNewName)
|
} else {
|
||||||
// .then(() => ep.writeMetadata(fileMixedNewName, {
|
return fileMixedNewName
|
||||||
// 'OriginalFileName+': originalFileName,
|
}
|
||||||
// }))
|
|
||||||
// .then(console.log, console.error)
|
|
||||||
// .then(() => ep.close())
|
|
||||||
// .catch(console.error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renameFile (originalFileName, fileMixedNewName) {
|
function renameFile (originalFileName, fileMixedNewName) {
|
||||||
|
if (rangement_instance.keepOriginalNameInRename) {
|
||||||
|
fileMixedNewName = addOriginalFileNameIfMissing(originalFileName, fileMixedNewName)
|
||||||
|
}
|
||||||
|
|
||||||
fs.rename(originalFileName, fileMixedNewName, function (err) {
|
fs.rename(originalFileName, fileMixedNewName, function (err) {
|
||||||
log.info('name changed', fileMixedNewName)
|
log.info('name changed', fileMixedNewName)
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -54,8 +59,7 @@ function renameFile (originalFileName, fileMixedNewName) {
|
|||||||
// otherRenames.push(originalFileName)
|
// otherRenames.push(originalFileName)
|
||||||
otherRenames.push(fileMixedNewName)
|
otherRenames.push(fileMixedNewName)
|
||||||
|
|
||||||
addOriginalFileNameIfMissing(originalFileName, fileMixedNewName)
|
finder.statistics['filesModified']++
|
||||||
// rangement_instance.statistics['filesModified']++
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -96,16 +100,17 @@ function shouldWeChangeName (structureForFile) {
|
|||||||
|
|
||||||
log.info(' nouveau nom:', newName)
|
log.info(' nouveau nom:', newName)
|
||||||
if (!mini_arguments['dry-run']) {
|
if (!mini_arguments['dry-run']) {
|
||||||
|
|
||||||
renameFile(structureForFile.fullPath, structureForFile.folderPath + newName)
|
renameFile(structureForFile.fullPath, structureForFile.folderPath + newName)
|
||||||
} else {
|
} else {
|
||||||
log.info('no renaming for real, this is a dry run')
|
log.info('no renaming for real, this is a dry run')
|
||||||
|
finder.statistics['filesNotModified']++
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info(' rien à changer')
|
log.info(' rien à changer')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* guess file name on one file which is not a directory
|
* guess file name on one file which is not a directory
|
||||||
* @param fullPath
|
* @param fullPath
|
||||||
@ -163,6 +168,7 @@ function guessFileNameOnAllFilesFromArguments () {
|
|||||||
|
|
||||||
// test file exists
|
// test file exists
|
||||||
fileList.forEach(fullPath => {
|
fileList.forEach(fullPath => {
|
||||||
|
log.debug('file list element: ', fullPath)
|
||||||
// parcourir les dossiers
|
// parcourir les dossiers
|
||||||
isFolderOrFile(`${fullPath}`)
|
isFolderOrFile(`${fullPath}`)
|
||||||
}
|
}
|
||||||
@ -171,6 +177,10 @@ function guessFileNameOnAllFilesFromArguments () {
|
|||||||
log.info('expanded file list :', expandedFileList)
|
log.info('expanded file list :', expandedFileList)
|
||||||
expandedFileList.forEach(filePath => guessFileNameOnOnefile(filePath))
|
expandedFileList.forEach(filePath => guessFileNameOnOnefile(filePath))
|
||||||
|
|
||||||
|
if (rangement_instance.reportStatistics || mini_arguments.stats) {
|
||||||
|
finder.reportStatistics()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readSubdirectories (baseDir) {
|
function readSubdirectories (baseDir) {
|
||||||
@ -194,7 +204,6 @@ function readSubdirectories (baseDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isFolderOrFile (fileName) {
|
function isFolderOrFile (fileName) {
|
||||||
// const stat = fs.statSync(cwd + '/' + fileName);
|
|
||||||
const stat = fs.statSync(fileName)
|
const stat = fs.statSync(fileName)
|
||||||
|
|
||||||
if (stat.isDirectory()) {
|
if (stat.isDirectory()) {
|
||||||
@ -204,7 +213,7 @@ function isFolderOrFile (fileName) {
|
|||||||
expandedFileList.push(...fileList)
|
expandedFileList.push(...fileList)
|
||||||
}
|
}
|
||||||
} else if (stat.isFile()) {
|
} else if (stat.isFile()) {
|
||||||
expandedFileList.push(cwd + '/' + fileName)
|
expandedFileList.push(fileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +228,4 @@ if (rangement_instance.enableTestsLocally) {
|
|||||||
TestFindFormattedDate()
|
TestFindFormattedDate()
|
||||||
TestScreenShotIsFoundAndRenamed()
|
TestScreenShotIsFoundAndRenamed()
|
||||||
}
|
}
|
||||||
if (rangement_instance.reportStatistics || mini_arguments.stats) {
|
|
||||||
finder.reportStatistics()
|
|
||||||
}
|
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -1,4 +1,4 @@
|
|||||||
import finder from '../finder.mjs'
|
import finder from '../utils/finder.mjs'
|
||||||
import { makeFileNameFromProperties } from '../index'
|
import { makeFileNameFromProperties } from '../index'
|
||||||
import { expect } from '@jest/globals'
|
import { expect } from '@jest/globals'
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import finder from "../finder.mjs";
|
import finder from "../utils/finder.mjs";
|
||||||
import { Jest as mockUpload } from '@jest/environment'
|
import { Jest as mockUpload } from '@jest/environment'
|
||||||
|
|
||||||
xdescribe('rangement file detection', () => {
|
xdescribe('rangement file detection', () => {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* la classe qui repère des patterns
|
* la classe qui repère des patterns
|
||||||
*/
|
*/
|
||||||
import rangement_instance from './conf/configs'
|
|
||||||
import exifr from 'exifr'
|
import exifr from 'exifr'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import log from 'loglevel'
|
import log from 'loglevel'
|
||||||
|
import rangement_instance from '../conf/configs.js'
|
||||||
|
|
||||||
log.setLevel(rangement_instance.log_level)
|
log.setLevel(rangement_instance.log_level)
|
||||||
|
|
||||||
@ -15,10 +15,11 @@ export default class finder {
|
|||||||
|
|
||||||
static statistics = {
|
static statistics = {
|
||||||
filesModified: 0,
|
filesModified: 0,
|
||||||
|
filesNotModified: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
static reportStatistics () {
|
static reportStatistics () {
|
||||||
log.info('statistics',
|
log.info('\n --------- statistics',
|
||||||
this.statistics)
|
this.statistics)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ export default class finder {
|
|||||||
return listOfTags
|
return listOfTags
|
||||||
}
|
}
|
||||||
|
|
||||||
static removeTagInProperties(properties, tagName) {
|
static removeTagInProperties (properties, tagName) {
|
||||||
|
|
||||||
let foundTagNameIndex = properties.tags.indexOf(tagName)
|
let foundTagNameIndex = properties.tags.indexOf(tagName)
|
||||||
if (foundTagNameIndex) {
|
if (foundTagNameIndex) {
|
||||||
@ -140,6 +141,45 @@ export default class finder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines if we must add or remove new tags
|
||||||
|
* @param tagCommand
|
||||||
|
* @returns {{tagsToAdd: [], tagCommand: *, tagsToRemove: []}}
|
||||||
|
*/
|
||||||
|
static addOrRemoveTagsParsing (tagCommand) {
|
||||||
|
let tagsToAdd = []
|
||||||
|
let tagsToRemove = []
|
||||||
|
|
||||||
|
// split all tags
|
||||||
|
let listOfTags = tagCommand.split(' ')
|
||||||
|
listOfTags.forEach(elem => {
|
||||||
|
// remove when a minus is present*
|
||||||
|
if (elem.indexOf('-')) {
|
||||||
|
tagsToRemove.push(elem)
|
||||||
|
} else {
|
||||||
|
// add tag otherwise
|
||||||
|
tagsToAdd.push(elem)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { tagCommand, tagsToAdd, tagsToRemove }
|
||||||
|
}
|
||||||
|
|
||||||
|
static applyTagChangesOnProperties(tagChange, properties){
|
||||||
|
|
||||||
|
properties.tags = [...properties.tags, tagChange.tagsToAdd]
|
||||||
|
properties.tags.filter(elem=>{
|
||||||
|
return tagChange.tagsToRemove.includes(elem)
|
||||||
|
})
|
||||||
|
return properties
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a tag and gives new filename with extension
|
||||||
|
* @param tagName
|
||||||
|
* @param fileName
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
static addTagInFileName (tagName, fileName) {
|
static addTagInFileName (tagName, fileName) {
|
||||||
|
|
||||||
let tags = this.findTagSectionInString(fileName)
|
let tags = this.findTagSectionInString(fileName)
|
||||||
@ -148,7 +188,7 @@ export default class finder {
|
|||||||
tags.push(tagName)
|
tags.push(tagName)
|
||||||
let uniqueArray = [...new Set(tags)]
|
let uniqueArray = [...new Set(tags)]
|
||||||
|
|
||||||
let newFileName = firstPart + ' ' + rangement_instance.tagSectionSeparator + ' ' + tags.join(rangement_instance.tagSeparator)
|
let newFileName = firstPart + ' ' + rangement_instance.tagSectionSeparator + ' ' + uniqueArray.join(rangement_instance.tagSeparator)
|
||||||
newFileName = newFileName.replace(/ {*}/, '') + this.findFileExtension(fileName)
|
newFileName = newFileName.replace(/ {*}/, '') + this.findFileExtension(fileName)
|
||||||
return this.cleanSpaces(newFileName)
|
return this.cleanSpaces(newFileName)
|
||||||
}
|
}
|
||||||
@ -232,15 +272,12 @@ export default class finder {
|
|||||||
// test all templates from configuration
|
// test all templates from configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static appendFileName (fileProperties, newText) {
|
||||||
|
|
||||||
|
|
||||||
static appendFileName(fileProperties, newText) {
|
|
||||||
fileProperties.freeText = finder.cleanSpaces(fileProperties.freeText + ' ' + newText)
|
fileProperties.freeText = finder.cleanSpaces(fileProperties.freeText + ' ' + newText)
|
||||||
return fileProperties
|
return fileProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
static prependFileName(fileProperties, newText) {
|
static prependFileName (fileProperties, newText) {
|
||||||
fileProperties.freeText = finder.cleanSpaces(newText + ' ' + fileProperties.freeText)
|
fileProperties.freeText = finder.cleanSpaces(newText + ' ' + fileProperties.freeText)
|
||||||
return fileProperties
|
return fileProperties
|
||||||
}
|
}
|
@ -50,11 +50,17 @@ function getStatisticsOnArchiveFolder (fileFullPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all tags
|
||||||
|
* @param fileFullPath
|
||||||
|
* @returns {[]}
|
||||||
|
*/
|
||||||
function getControlledVocabularyFromFiles (fileFullPath) {
|
function getControlledVocabularyFromFiles (fileFullPath) {
|
||||||
|
|
||||||
let controlledVocabulary = ['TODO']
|
|
||||||
// find all tags
|
// find all tags
|
||||||
return controlledVocabulary
|
let listOfTags = []
|
||||||
|
|
||||||
|
return listOfTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveToSortingFolder (fileFullPath) {
|
function moveToSortingFolder (fileFullPath) {
|
||||||
@ -117,3 +123,4 @@ function testthings(){
|
|||||||
}
|
}
|
||||||
console.log('convertedToName', convertedToName)
|
console.log('convertedToName', convertedToName)
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
création de la config
|
création de la config
|
||||||
*/
|
*/
|
||||||
// import i18next from 'i18next'
|
// import i18next from 'i18next'
|
||||||
import config_rangement from "./conf/configs.js";
|
import config_rangement from "../../conf/configs.js";
|
||||||
|
|
||||||
const { stdin, stdout } = process;
|
const { stdin, stdout } = process;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user