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 constants from './folders.js'
|
||||
import cv from './controlled_vocabulary.js'
|
||||
|
||||
/**
|
||||
* configuration générale à importer dans les utilitaires
|
||||
*/
|
||||
class config_rangement {
|
||||
log_level = 'info' // 'debug' | 'warn' |'info'
|
||||
log_level = 'debug' // 'debug' | 'warn' |'info'
|
||||
|
||||
version = '1.0.0'
|
||||
iso_date_format = 'yyyy-MM-DDTHH.mm.ss' // target format for dates in file names
|
||||
tagSeparator = ' '
|
||||
@ -15,17 +17,20 @@ class config_rangement {
|
||||
replaceUnderscoreWithSpaces = true
|
||||
renameFolders = false
|
||||
enableTestsLocally = false
|
||||
reportStatistics = false
|
||||
reportStatistics = true
|
||||
controlled_vocabulary = cv
|
||||
constants = constants
|
||||
base_archive_folder = constants.base_archive_folder
|
||||
templates = mainTemplates;
|
||||
statistics= {};
|
||||
keepOriginalNameInRename=true;
|
||||
log_actions=true;
|
||||
|
||||
/**
|
||||
* override config if we want
|
||||
* @param overridingConfig
|
||||
*/
|
||||
constructor (overridingConfig) {
|
||||
console.log('overridingConfig', overridingConfig)
|
||||
let keys = Object.keys(overridingConfig)
|
||||
let self = this;
|
||||
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,
|
||||
TestScreenShotIsFoundAndRenamed,
|
||||
TestTagsAreDetectedInFileName
|
||||
} from './testFunctions.mjs'
|
||||
import finder from './finder.mjs'
|
||||
} from './utils/testFunctions.mjs'
|
||||
import finder from './utils/finder.mjs'
|
||||
|
||||
let mini_arguments
|
||||
|
||||
@ -31,21 +31,26 @@ function parseArguments () {
|
||||
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) {
|
||||
|
||||
// const ep = new exiftool.ExiftoolProcess()
|
||||
//
|
||||
// ep
|
||||
// .open(fileMixedNewName)
|
||||
// .then(() => ep.writeMetadata(fileMixedNewName, {
|
||||
// 'OriginalFileName+': originalFileName,
|
||||
// }))
|
||||
// .then(console.log, console.error)
|
||||
// .then(() => ep.close())
|
||||
// .catch(console.error)
|
||||
if (!fileMixedNewName.includes(originalFileName)) {
|
||||
let properties = finder.destructurateFileName(fileMixedNewName)
|
||||
return properties.freeText + ' ' + originalFileName
|
||||
} else {
|
||||
return fileMixedNewName
|
||||
}
|
||||
}
|
||||
|
||||
function renameFile (originalFileName, fileMixedNewName) {
|
||||
if (rangement_instance.keepOriginalNameInRename) {
|
||||
fileMixedNewName = addOriginalFileNameIfMissing(originalFileName, fileMixedNewName)
|
||||
}
|
||||
|
||||
fs.rename(originalFileName, fileMixedNewName, function (err) {
|
||||
log.info('name changed', fileMixedNewName)
|
||||
if (err) {
|
||||
@ -54,8 +59,7 @@ function renameFile (originalFileName, fileMixedNewName) {
|
||||
// otherRenames.push(originalFileName)
|
||||
otherRenames.push(fileMixedNewName)
|
||||
|
||||
addOriginalFileNameIfMissing(originalFileName, fileMixedNewName)
|
||||
// rangement_instance.statistics['filesModified']++
|
||||
finder.statistics['filesModified']++
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -96,16 +100,17 @@ function shouldWeChangeName (structureForFile) {
|
||||
|
||||
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')
|
||||
finder.statistics['filesNotModified']++
|
||||
}
|
||||
} else {
|
||||
log.info(' rien à changer')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* guess file name on one file which is not a directory
|
||||
* @param fullPath
|
||||
@ -163,6 +168,7 @@ function guessFileNameOnAllFilesFromArguments () {
|
||||
|
||||
// test file exists
|
||||
fileList.forEach(fullPath => {
|
||||
log.debug('file list element: ', fullPath)
|
||||
// parcourir les dossiers
|
||||
isFolderOrFile(`${fullPath}`)
|
||||
}
|
||||
@ -171,6 +177,10 @@ function guessFileNameOnAllFilesFromArguments () {
|
||||
log.info('expanded file list :', expandedFileList)
|
||||
expandedFileList.forEach(filePath => guessFileNameOnOnefile(filePath))
|
||||
|
||||
if (rangement_instance.reportStatistics || mini_arguments.stats) {
|
||||
finder.reportStatistics()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function readSubdirectories (baseDir) {
|
||||
@ -194,7 +204,6 @@ function readSubdirectories (baseDir) {
|
||||
}
|
||||
|
||||
function isFolderOrFile (fileName) {
|
||||
// const stat = fs.statSync(cwd + '/' + fileName);
|
||||
const stat = fs.statSync(fileName)
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
@ -204,7 +213,7 @@ function isFolderOrFile (fileName) {
|
||||
expandedFileList.push(...fileList)
|
||||
}
|
||||
} else if (stat.isFile()) {
|
||||
expandedFileList.push(cwd + '/' + fileName)
|
||||
expandedFileList.push(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,6 +228,4 @@ if (rangement_instance.enableTestsLocally) {
|
||||
TestFindFormattedDate()
|
||||
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 { 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'
|
||||
|
||||
xdescribe('rangement file detection', () => {
|
||||
|
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* la classe qui repère des patterns
|
||||
*/
|
||||
import rangement_instance from './conf/configs'
|
||||
import exifr from 'exifr'
|
||||
import moment from 'moment'
|
||||
import log from 'loglevel'
|
||||
import rangement_instance from '../conf/configs.js'
|
||||
|
||||
log.setLevel(rangement_instance.log_level)
|
||||
|
||||
@ -15,10 +15,11 @@ export default class finder {
|
||||
|
||||
static statistics = {
|
||||
filesModified: 0,
|
||||
filesNotModified: 0,
|
||||
}
|
||||
|
||||
static reportStatistics () {
|
||||
log.info('statistics',
|
||||
log.info('\n --------- statistics',
|
||||
this.statistics)
|
||||
}
|
||||
|
||||
@ -103,7 +104,7 @@ export default class finder {
|
||||
return listOfTags
|
||||
}
|
||||
|
||||
static removeTagInProperties(properties, tagName) {
|
||||
static removeTagInProperties (properties, tagName) {
|
||||
|
||||
let foundTagNameIndex = properties.tags.indexOf(tagName)
|
||||
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) {
|
||||
|
||||
let tags = this.findTagSectionInString(fileName)
|
||||
@ -148,7 +188,7 @@ export default class finder {
|
||||
tags.push(tagName)
|
||||
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)
|
||||
return this.cleanSpaces(newFileName)
|
||||
}
|
||||
@ -232,15 +272,12 @@ export default class finder {
|
||||
// test all templates from configuration
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static appendFileName(fileProperties, newText) {
|
||||
static appendFileName (fileProperties, newText) {
|
||||
fileProperties.freeText = finder.cleanSpaces(fileProperties.freeText + ' ' + newText)
|
||||
return fileProperties
|
||||
}
|
||||
|
||||
static prependFileName(fileProperties, newText) {
|
||||
static prependFileName (fileProperties, newText) {
|
||||
fileProperties.freeText = finder.cleanSpaces(newText + ' ' + fileProperties.freeText)
|
||||
return fileProperties
|
||||
}
|
@ -50,11 +50,17 @@ function getStatisticsOnArchiveFolder (fileFullPath) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list all tags
|
||||
* @param fileFullPath
|
||||
* @returns {[]}
|
||||
*/
|
||||
function getControlledVocabularyFromFiles (fileFullPath) {
|
||||
|
||||
let controlledVocabulary = ['TODO']
|
||||
// find all tags
|
||||
return controlledVocabulary
|
||||
let listOfTags = []
|
||||
|
||||
return listOfTags;
|
||||
}
|
||||
|
||||
function moveToSortingFolder (fileFullPath) {
|
||||
@ -116,4 +122,5 @@ function testthings(){
|
||||
convertedToName = convertDateToTimeInFileName(creationDateFound)
|
||||
}
|
||||
console.log('convertedToName', convertedToName)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
création de la config
|
||||
*/
|
||||
// import i18next from 'i18next'
|
||||
import config_rangement from "./conf/configs.js";
|
||||
import config_rangement from "../../conf/configs.js";
|
||||
|
||||
const { stdin, stdout } = process;
|
||||
|
Loading…
Reference in New Issue
Block a user