/** * la classe qui repère des patterns */ import { tagSectionSeparator, tagSeparator } from './configs.mjs' import exifr from 'exifr' import moment from 'moment' import path from 'path' /** * finds patterns for file name */ export default class finder { static statistics = { filesModified: 0, } static patternsFiles = { 'downloaded_pic': /^\-\w{15}\.jpg/, // FyB8cZnWIAc21rw.jpg 'telegram_pic': /^\-\d{19}_\d{4}/, // -4900281569878475578_1109.jpg 'open_camera': /^IMG_OC_\d{8}/i, // IMG_OC_20230617_092120_3.jpg 'screenshot': /^Screenshot/i, // Screenshot 2023-06-15 at 15-26-04 Instance Panoramax OSM-FR.png } static reportStatistics () { console.log('statistics', this.statistics) } static findScreenshot (inputString) { return inputString.match(/screenshot/i) || inputString.match(/capture d'écran/i) } static findFormattedDate (filepath) { let match = filepath.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/ig) // console.log('match findFormattedDate', match) let result = '' if (match && match[0]) { result = match[0] } return result } static findFileExtension (inputString) { let result = inputString.match(/\.\w{3,4}$/i) return result } /** * find the section of file name which contains the free text to describe the picture * @param fileName * @returns {*|string} */ static findFileNameFreeTextPart (fileName) { fileName = fileName.replace(this.findFileExtension(fileName), '') let boom = fileName.split(tagSectionSeparator) if (boom.length) { let freeTextPart = boom[0].trim() console.log('freeTextPart', freeTextPart) return freeTextPart } return fileName.trim() } /** * find an array of tags * @param inputString * @returns {[]} */ static findTagSectionInString (inputString) { let listOfTags = [] // remove extension let extensionFile = finder.findFileExtension(inputString) if (extensionFile) { extensionFile = extensionFile[0] } else { console.log('no extensionFile', extensionFile, inputString) extensionFile = '' } inputString = inputString.replace(extensionFile, '') // console.log('extensionFile', extensionFile) if (inputString.includes(tagSectionSeparator)) { // console.log('inputString', inputString) if (inputString.length) { let boom = inputString.split(tagSectionSeparator) // console.log('boom', boom) if (boom.length) { let fileSectionsName = boom.splice(tagSeparator) listOfTags = [...fileSectionsName[1].trim().split(tagSeparator)] // console.log('listOfTags', listOfTags) } else { console.log('no boom', boom) } } } return listOfTags } static cleanSpaces (inputString) { return inputString.trim().replace(/ *g/, ' ') } static searchAndReplaceInFileName (searchString, replaceString, fileName) { return this.cleanSpaces(fileName.replace(searchString, replaceString)) } /** * search screenshot clues and rename */ static searchAndRenameScreenshots (fileName) { if (finder.findScreenshot(fileName)) { let tags = this.findTagSectionInString(fileName) console.log('tags', tags) if (!tags.includes('screenshot')) { fileName = this.addTagInFileName('screenshot', fileName) fileName = this.searchAndReplaceInFileName('Screenshot', '', fileName) console.log('screenShotMockFileName:', fileName) return this.cleanSpaces(fileName) } console.log('is a screenshot, remove screenshot in name, and add tag screenshot') } else { return null } } static addTagInFileName (tagName, fileName) { let tags = this.findTagSectionInString(fileName) let firstPart = this.findFileNameFreeTextPart(fileName) tags.push(tagName) let uniqueArray = [...new Set(tags)] let newFileName = firstPart + ' ' + tagSectionSeparator + ' ' + tags.join(tagSeparator) newFileName = newFileName.replace(/ {*}/, '') + this.findFileExtension(fileName) return this.cleanSpaces(newFileName) } /** * convertit un nom de fichier en une structure décrivant plusieurs parties correspondant au pattern d'archivage * @param fullPath * @returns {{extension: *, dateStamp: string, freeText: (*|string), tags: *[]}} */ static destructurateFileName (fullPath) { let [folderPath, fileNameOriginal] = this.findFolderPath(fullPath) let dateStampInFileNameOriginal = this.findFormattedDate(fileNameOriginal) return { fullPath, folderPath, fileNameOriginal, dateStampInFileNameOriginal, dateStampExif: '', freeText: this.findFileNameFreeTextPart(fileNameOriginal), tags: this.findTagSectionInString(fileNameOriginal), extension: this.findFileExtension(fileNameOriginal), } } /** * finds the earliest part in several exif date info * @param exifData * @returns {string} */ static findEarliestDateInExifData (exifData) { if (exifData) { let moments = [] // console.log('exif data : ', exifData) // Do something with your data! if (exifData.DateTimeOriginal) { // console.log('image créée le : DateTimeOriginal : ', exifData.DateTimeOriginal) // Do something with your data! moments.push(exifData.DateTimeOriginal) } if (exifData.ModificationDateTime) { // console.log('image créée le : ModificationDateTime : ', exifData.ModificationDateTime) // Do something with your data! moments.push(exifData.ModificationDateTime) } if (exifData.ModifyDate) { // console.log('image créée le : ModifyDate : ', exifData.ModifyDate) // Do something with your data! moments.push(exifData.ModifyDate) } if (exifData.FileAccessDateTime) { moments.push(exifData.FileAccessDateTime) } if (exifData.FileInodeChangeDateTime) { moments.push(exifData.FileInodeChangeDateTime) } if (exifData.FileModificationDateTime) { // console.log('image créée le : FileModificationDateTime : ', exifData.FileModificationDateTime) // Do something with your data! moments.push(exifData.FileModificationDateTime) } if (exifData.CreateDate) { // console.log('image créée le : CreateDate : ', exifData.CreateDate) // Do something with your data! moments.push(exifData.CreateDate) } moments = moments.map(d => { let newdate = moment(d) return newdate }) let minDate = moment.min(moments) // console.log('minDate :::::::::', minDate) console.log('minDate :::::::::', minDate.format('yyyy-MM-DDTHH:mm:ss')) return minDate.format('yyyy-MM-DDTHH:mm:ss') } else { console.log('pas de exif data') return '' } } /** * examine plusieurs propriétés exif de date et retourne la plus ancienne * @param filepath */ static async findExifCreationDate (filepath) { console.log('filepath', filepath) let dateAlreadyInFileName = finder.findFormattedDate(filepath) if (dateAlreadyInFileName) { console.log('------ dateAlreadyInFileName', dateAlreadyInFileName) } return await exifr.parse(filepath) } static findFolderPath (filePath) { let folders = filePath.split('/') let fileName = folders.pop() folders = filePath.replace(fileName, '') console.log('\n - folders', folders) console.log(' - fileName', fileName, '\n') return [folders, fileName] } }