From 8e11507b494e41df963bfe8840f4acfea55b0f46 Mon Sep 17 00:00:00 2001 From: albion2000 Date: Sat, 13 Jan 2018 22:02:03 +0100 Subject: [PATCH] $CODE & DOC : use only tabs. no more need for command line. Just doubleclick on .py files. --- README.md | 20 +++++ installation_instructions.txt | 17 +++- tools/check_jpegs.py | 3 +- tools/naming_conventions.py | 17 +++- tools/naming_conventions_do_rename.py | 7 ++ tools/readme_check_jpegs.txt | 10 +-- tools/readme_naming_conventions.txt | 58 ++++++++---- tools/scandir2pdf.py | 122 ++++++++++++++------------ 8 files changed, 167 insertions(+), 87 deletions(-) create mode 100644 tools/naming_conventions_do_rename.py diff --git a/README.md b/README.md index c695f0e..ca44bad 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,24 @@ One purpose is to keep the tools as simple as possible (KISS), refraining from f In short : +## naming_conventions.py & naming_conventions_do_rename.py + +Read the installation_instructions.txt and readme_naming_conventions.txt + +Copy 'naming_conventions.py' & 'naming_conventions_do_rename.py' to the root directory of your file tree. + +The primary purpose of this tool is to ensure a longer lifetime to a directry tree by reducing the risk of it being corrupted over transfers between file systems. + +It recursively parses sub directories +It is able to rename the directories in order to follow some strict conventions. + +mode for simulation, with no effect on the name of the directories, for validation purposes: +naming_conventions.py +mode for renaming effectively: +naming_conventions_do_rename.py + +The use of this tool is optional, and would be typically used before using scandir2pdf.py + ## check_jpegs.py @@ -23,6 +41,8 @@ It quickly checks that the files are not corrupted. It is, on purpose, a fast check in order to help detect rapidly bad files. Only the headers are checked, the images are not decompressed. +This is a quick way to detect bad jpeg files, before using scandir2pdf.py + Each '.' shows that one more directory was parsed When a file is reported corrupted, it does not mean that it is lost. Try to open it in your favorite image sw and save it back (using the best quality, in order to reduce compression losses). It is often enough. diff --git a/installation_instructions.txt b/installation_instructions.txt index ea9ced1..47f0826 100644 --- a/installation_instructions.txt +++ b/installation_instructions.txt @@ -34,6 +34,7 @@ under windows, in the search bar, type "cmd" in that new window, type pip install img2pdf +pip install unidecode pip install pillow ========================================================================= @@ -61,11 +62,15 @@ Non recommand IMPORTANT : à la première étape de l'installation, il vous faut absolument cocher la case "Add Python 3.6 to PATH" IMPORTANT : à la dernière étape de l'installation, cliquer sur "Disable path length limit for python" -Ensuite, il faut effectuer deux commandes. +Ensuite, il faut effectuer deux commandes, en utilisant l'invite de commande windows : -Sous windows : dans la barre de recherche, tapez 'cmd' enter +Sous windows 10 : clicker sur l'icone 'fenêtre windows' tout en bas à gauche, puis tapez 'cmd' puis appuyez sur enter (tapez même si ce que vous tapez n'apparait nulle part) -cela ouvre une fenêtre de commande noire. +cela ouvre une fenêtre "invite de commande" noire. + +autre façon de faire : ouvrir un explorateur de fichiers, dans la barre de chemin, tapez 'cmd' puis appuyez sur enter + +Dans la fenêtre noire : Tapez @@ -75,6 +80,12 @@ attendez la fin du processus de t tapez +pip install unidecode + +attendez la fin du processus de téléchargement et installation (complètement automatique) + +tapez + pip install pillow attendez la fin du processus de téléchargement et installation (complètement automatique) diff --git a/tools/check_jpegs.py b/tools/check_jpegs.py index 4005021..6d0b1d8 100644 --- a/tools/check_jpegs.py +++ b/tools/check_jpegs.py @@ -48,9 +48,10 @@ print('\r\n') if (badFilesCount>0) : - print('found %i bad files' % badFilesCount); + print('found %i bad file(s)' % badFilesCount); else : print('All %i jpeg files in %i directories (containing jpeg images) passed the sanity check. No problem.' % (allJPGFilesCount,allDirCount)); # BELL print('\a') +os.system("pause") \ No newline at end of file diff --git a/tools/naming_conventions.py b/tools/naming_conventions.py index 8abdbce..c957719 100644 --- a/tools/naming_conventions.py +++ b/tools/naming_conventions.py @@ -9,7 +9,7 @@ # rules def accentsTidy(s) : -# tries to convert as best as it can anything in ascii characters (° becomes deg !) +# tries to convert as best as it can anything in ascii characters ('°' becomes 'deg' !) r = unidecode.unidecode(s) # go lower case r = r.lower(); @@ -36,7 +36,8 @@ def accentsTidy(s) : r = re.sub('_$','',r); return r; -logFile = open('logRename.txt','a') +logFileName = 'logRename.txt' +logFile = open(logFileName,'a') def printandlog(str): print(str) @@ -72,6 +73,8 @@ def process(do_rename) : nbDir = 0 for dirName, subdirList, fileList in os.walk(rootDir): for subdir in subdirList : + if subdir == '__pycache__' : + continue stripped = accentsTidy(subdir) nbDir = nbDir + 1 if (same_string(stripped,subdir)) : @@ -91,6 +94,8 @@ def process(do_rename) : continue if dirName == '..' : continue + if dirName == '.\\__pycache__' : + continue stripped = accentsTidy(dirName) nbDir = nbDir + 1 if (same_string(stripped,dirName)) : @@ -122,7 +127,9 @@ def process(do_rename) : printandlog("%i change(s) done in a total of %i directories" % (nbChanges,nbDir)) else: printandlog("%i change(s) needed in a total of %i directories" % (nbChanges,nbDir)) - printandlog("this was a simulation, if you are happy with this renaming proposal, do 'naming_conventions -w'"); + printandlog("this was a simulation, if you are happy with this renaming proposal, do 'naming_conventions.py -w'"); + print("\nAll this was logged at the end of the file "+logFileName); + def test() : s = 'æÃÀÂÄÃÅÇÉÈÊËÃÃÎÌÑÓÒÔÖÕÚÙÛÜÃÅ“- áàâäãåçéèêëíìîïñóòôöõúùûüý ÿ' @@ -139,11 +146,13 @@ def print_syntax() : print('naming_conventions.py') print('syntax for renaming effectively:') print('naming_conventions.py -w') + os.system("pause") def main(argv) : if (len(sys.argv)==1): process(0) + os.system("pause") else : try: opts, args = getopt.getopt(argv,"hw") @@ -156,9 +165,11 @@ def main(argv) : sys.exit() elif opt == '-w': process(1) + os.system("pause") sys.exit() else : print("ignored"); + os.system("pause") sys.exit() print_syntax() diff --git a/tools/naming_conventions_do_rename.py b/tools/naming_conventions_do_rename.py new file mode 100644 index 0000000..1621be8 --- /dev/null +++ b/tools/naming_conventions_do_rename.py @@ -0,0 +1,7 @@ +# coding: utf-8 + +import os +import naming_conventions + +naming_conventions.process(1) +os.system("pause") diff --git a/tools/readme_check_jpegs.txt b/tools/readme_check_jpegs.txt index f5b514e..867ed96 100644 --- a/tools/readme_check_jpegs.txt +++ b/tools/readme_check_jpegs.txt @@ -15,6 +15,7 @@ ACTION USE * Copy 'check_jpegs.py' to the root directory of your file three. + * Double click on the file 'check_jpegs.py' NOTES * It is, on purpose, a fast check in order to help detect rapidly bad files. @@ -37,14 +38,7 @@ ACTION USAGE * Copier 'check_jpegs.py' dans le répertoire racine de votre arborescence de fichiers. - * Executer ce script (deux façons entre autres) - 1. Lancer une console windows dans votre répertoire, et taper 'check_jpegs.py'. Pour cela : - 1. Lancez l'explorateur windows et allez sur votre répertoire. - 1. Cliquez sur le chemin complet dans l'explorateur, pour le faire apparaître en surbrillance (sélectionné) - 1. Tapez 'cmd' à la place du chemin complet. appuyez sur 'enter' - 1. Cela doit ouvrir une console de ligne de commande dans votre répertoire. Tapez check_jpegs.py puis 'enter' - 1. ou bien (non recommandé) Double cliquer sur le fichier 'check_jpegs.py' dans l'explorateur windows. Cette méthode a le défaut que la fenêtre se ferme dès la fin, ce qui ne laisse pas le temps de lire le rapport final. - * Si vous obtenez immédiatement une erreur du type "n'est pas reconnu en tant que commande interne", cela peut signifier que python n'a pas été ajouté à votre path système. + * Double cliquez sur 'check_jpegs.py' NOTES * Seuls les entêtes de fichiers sont vérifiées, elles ne sont pas décompressées. diff --git a/tools/readme_naming_conventions.txt b/tools/readme_naming_conventions.txt index 3259ad0..bdc5cfb 100644 --- a/tools/readme_naming_conventions.txt +++ b/tools/readme_naming_conventions.txt @@ -1,24 +1,34 @@ ======================================================= FRENCH HERE, ENGLISH BELOW -Typiquement cet outil est utilisé avant scandir2pdf +PRELIMINAIRE + * Lisez et suivez les instructions du fichier installation_instructions.txt pour pouvoir lancer l'outil sur votre machine. -L'objectif principal de cet outil est d'assurer une conservation à plus long terme de la structure de répertoires, qui risque d'être corrompue/modifiée, à l'occasion de transferts entre "file systems/os" systèmes de fichiers et OS. +ACTION + * L'objectif principal de cet outil optionnel est d'assurer une conservation à plus long terme de la structure de répertoires, qui risque d'être corrompue/modifiée, à l'occasion de transferts entre "file systems/os" systèmes de fichiers et OS. + * Mode Simulation : détection des répertoires à problème, affichage du résultat simulé. + * Mode effectif : Renommage effectif, a effectuer si la simulation vous convient. -Reste à faire : - Parce que l'outil peut renommer les répertoires, il vérifie aussi si il ne tombe pas dans la situation où après renommage, deux sous répertoires auraient le même nom. - Dans ce cas, aucun répertoire n'est touché. Les répertoires à problème sont indiqués. Il est laissé à l'utilisateur le soin de renommer un de ces répertoires. - Actuellement, cette situation fera échouer le renommage du second fichier et stoppera les opérations. +USAGE + * Copier 'naming_conventions.py' et 'naming_conventions_do_rename.py' dans le répertoire racine de votre arborescence de fichiers. +2 syntaxes -Rien n'est fait sans validation de l'utilisateur. Pour cela les traitements sont fait en deux étapes. + * Executer ce script (deux façons) + * Pour lancer la simulation (pas de modification réalisée, pas de risque), double cliquez sur le fichier 'naming_conventions.py' dans l'explorateur windows. + * Pour lancer le renommage, double cliquez sur le fichier 'naming_conventions_do_rename.py' dans l'explorateur windows. + * Si vous obtenez immédiatement une erreur du type "n'est pas reconnu en tant que commande interne", cela peut signifier que python n'a pas été ajouté à votre path système. Veuillez suivre les instructions d'installation. -Scrutation, détection des répertoires à problème, affichage du résultat simulé. -Si le résultat simulé affiché est accepté, il faut relancer l'outil avec l'option : -w -Là le renommage sera effectif. +Les résultats sont dans la console et recopiés à la fin du fichier logRename.txt +typiquement cet outil est utilisé avant scandir2pdf +NOTES +Reste à faire : + Parce que l'outil peut renommer les répertoires, il vérifie aussi si il ne tombe pas dans la situation où après renommage, deux sous répertoires auraient le même nom. + Dans ce cas, aucun répertoire n'est touché. Les répertoires à problème sont indiqués. Il est laissé à l'utilisateur le soin de renommer un de ces répertoires. + Actuellement, cette situation fera échouer le renommage du second fichier et stoppera les opérations. Copie de : http://www.ufowaves.org/ltdsp/ltsdp/nommage @@ -58,10 +68,6 @@ lettres de 'A' '_' tiret bas (fait office d'espaces) Oui en effet, il est interdit d'utiliser les caractères accentués. -Je pourrais être plus restrictif, pour donner un aspect plus léché au fond, mais ce n'est pas nécessaire. Au delà, trop de personnes ne font pas l'effort de respecter les règles, juste par flemme ou étourderie. - -Pour commencer, il est possible de faire un renommage automatique de tout ce qui existe déjà pour respecter ces règles. (par un programme informatique) - Les noms de répertoire doivent-être aussi bref que possible. Les systèmes de fichiers Windows ont encore des limitations sur la longueur de chemin complet des fichiers. Il est facile de dépasser le maximum autorisé. Modifier @@ -81,6 +87,12 @@ Les noms de fichiers doivent- ENGLISH +PRELIMINARY + * Read the installation_instructions.txt for being able to run the tool on your machine. + + +ACTION + The primary purpose of this tool is to ensure a longer lifetime to a directry tree by reducing the risk of it being corrupted over transfers between file systems. This is done by enforcing some naming conventions. On directories @@ -89,9 +101,25 @@ justification and general principles : http://www.ufowaves.org/ltdsp/ltsdp/nomma typically, this would be called before scandir2pdf +USE + * Copy 'naming_conventions.py' & 'naming_conventions_do_rename.py' into the root directory of your files. + * Simulation, with no effect on the name of the directories, for validation purposes: double click on naming_conventions.py + * Renaming effectively : double click on naming_conventions_do_rename.py + + To be done : Because the tool can rename the directories, it also checks that it does not fall in the situation where after renaming, two directories would have the same name. - If that is the case, the problematic directories are pointed out, and the user must himself rename one of the faulty directories. +log into file logRename.txt + +rules followed +# tries to convert as best as it can anything in ascii characters +# go lower case +# anything that is neither a letter nor a number is replaced by _ +# æ becomes ae +# œ becomes oe +# 'N°' decomes 'n_' +# remove too many '_' +# remove '_' at start or end of dir name diff --git a/tools/scandir2pdf.py b/tools/scandir2pdf.py index a68e75f..e2405d6 100644 --- a/tools/scandir2pdf.py +++ b/tools/scandir2pdf.py @@ -3,28 +3,28 @@ import img2pdf import sys -logFile = open('logParse.txt','a') +logFileName = 'logParse.txt' + +logFile = open(logFileName,'a') def printandlog(str): - print(str) - logFile.write(str+"\n") - return + print(str) + logFile.write(str+"\n") + return def printandlogNoRC(str): - print(str, end='') - logFile.write(str) - return + print(str, end='') + logFile.write(str) + return def printandlogTuple(tuple): - print(tuple) - logFile.write(''.join(tuple)) - return - -#os.getcwd() + print(tuple) + logFile.write(''.join(tuple)) + return print("A sound will be produced at the end of the processing.") -print("What follows is also logged at the end of the file logParse.txt\r\n") +print("What follows is also logged at the end of the file "+logFileName+"\r\n") print('Press +C to abort') printandlog("########################################") @@ -33,53 +33,61 @@ def printandlogTuple(tuple): failedFiles = (); failedfilesCount = 0 for dirName, subdirList, fileList in os.walk(rootDir): - files = (); - found = 0; - currentPath = os.getcwd(); - nbpages = 0 - for fname in fileList: - thisisajpeg = 0 - extposjpg = fname.find(".jpg") - if (extposjpg == len(fname)-4) : - thisisajpeg = 1 - extposjpg = fname.find(".jpeg") - if (extposjpg == len(fname)-4) : - thisisajpeg = 1 - if (thisisajpeg==1): - found = 1; - nbpages = nbpages + 1 - newTuple = (dirName+'/'+fname,); - files = files + newTuple - if (found==1): -# extract the name of the directory - outfile = dirName+'.pdf'; - printandlogNoRC('-->%s (%i pages)' % (outfile,nbpages)) - with open(outfile,"wb") as f: - try : - f.write(img2pdf.convert(*files)) - f.flush() - f.close() - printandlog(' ') - except MemoryError: - f.close() - printandlog('--->>> **********conversion to pdf failed by lack of memory???**********') - newFailedFilesTuple = (outfile+' ',); - failedFiles = failedFiles + newFailedFilesTuple - failedfilesCount = failedfilesCount+1 - except img2pdf.ImageOpenError: - f.close() - printandlog('--->>> **********conversion to pdf failed due to a bad jpeg file format???**********') - newFailedFilesTuple = (outfile+' ',); - failedFiles = failedFiles + newFailedFilesTuple - failedfilesCount = failedfilesCount+1 - + files = (); + found = 0; + nbpages = 0 + for fname in fileList: + thisisajpeg = 0 + extposjpg = fname.find(".jpg") + if (extposjpg == len(fname)-4) : + thisisajpeg = 1 + extposjpg = fname.find(".jpeg") + if (extposjpg == len(fname)-4) : + thisisajpeg = 1 + if (thisisajpeg==1): + found = 1; + nbpages = nbpages + 1 + newTuple = (dirName+'/'+fname,); + files = files + newTuple + if (found==1): +# extract the name of the directory + outfile = dirName+'.pdf'; + printandlogNoRC('-->%s (%i pages)' % (outfile,nbpages)) + try: + with open(outfile,"wb") as f: + try : + f.write(img2pdf.convert(*files)) + f.flush() + f.close() + printandlog(' ') + except MemoryError: + f.close() + printandlog('--->>> **********conversion to pdf failed by lack of memory, too many files or too long file path ???**********') + newFailedFilesTuple = (outfile+' ',); + failedFiles = failedFiles + newFailedFilesTuple + failedfilesCount = failedfilesCount+1 + except img2pdf.ImageOpenError: + f.close() + printandlog('--->>> **********conversion to pdf failed due to a bad jpeg file format???**********') + newFailedFilesTuple = (outfile+' ',); + failedFiles = failedFiles + newFailedFilesTuple + failedfilesCount = failedfilesCount+1 + except: + printandlog('--->>> **********conversion to pdf failed because we cannot create/replace the pdf file. Is it already open in acrobat reader ? Please close it if that is the case. **********') + newFailedFilesTuple = (outfile+' ',); + failedFiles = failedFiles + newFailedFilesTuple + failedfilesCount = failedfilesCount+1 + if (failedfilesCount>0) : - printandlog('\r\n\r\n%i files could not be converted for some reason, here is the list :' % failedfilesCount) - printandlogTuple(failedFiles) - printandlog('\r\nIf it is by lack of memory you might just try to go parse directly these only. It can work. Using the 64 bits version of python might help also.'); + printandlog('\r\n\r\n%i file(s) could not be converted (see potential reason looking up), here is the list :' % failedfilesCount) + printandlogTuple(failedFiles) + printandlog('\r\nIf it is by lack of memory you might just try to go parse directly these only. It can work. Using the 64 bits version of python might help also.'); else: - printandlog('All files converted with NO ERROR') + printandlog('All files converted with NO ERROR') + +print("See also at the end of the log file "+logFileName+"\r\n") logFile.close() # BELL print('\a') +os.system("pause")