Programme de renommage des fichiers pour les élèves utilisant l'ordinateur au collège

Partagez vos scripts, et vos applications AutoIt.
Règles du forum
.
Répondre
marcgforce
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 07 mars 2016 07:20
Status : Hors ligne

Programme de renommage des fichiers pour les élèves utilisant l'ordinateur au collège

#1

Message par marcgforce » ven. 06 janv. 2017 11:13

Étant père d'une enfant ayant un handicap "dys", ma fille dispose d'un ordinateur pour la totalité de ses cours et son temps scolaire au collège , son ergothérapeute m'ayant fait part du temps perdu à renommer les fichiers selon le formalisme : "Année.mois.jour.nom du fichier.extension" j'ai pensé à ce petit bout de code qui automatise cette action pour peu qu'elle prenne la peine d'utiliser l’exécutable.

Tout simplement, ce programme demande via la fonction FileOpenDialog quels sont les fichiers à modifier, il est possible d'en sélectionner plusieurs avec la touche CTRL. Ces fichier sont mis dans un tableau et traités un par un. Le renommage s'effectue en fonction de la date de création du fichier et ne s'opère plus si le fichier possède déjà ces caractéristiques (on ne peut pas renommer un fichier déjà sous cette forme : "Année.mois.jour.nom du fichier.extension")

lorsque le programme a fini sa boucle un message propose à l'utilisateur de continuer (tous les fichiers ne sont peut-être pas dans le même dossier) ou quitte.

Je me suis rendu compte en testant que la mise en forme de l'array d'une sélection simple était différente d'une array de sélection multiple, il a donc fallu créer un contrôle à ce niveau et utiliser la fonction _PathSplit pour mettre en mémoire le chemin du fichier, chose qui n'est pas necessaire dans une sélection multiple puisque le chemin du fichier est splité dans l'array

Le code :
#include <Array.au3>
#include <File.au3>
#include <Date.au3>
#include <FileConstants.au3>
GLOBAL $version = 0.2
$msg=msgbox(4,"RENOME DATE","Ce programme permet de renommer les fichier sélectionnés dans le dossier de son choix avec la date de modification" & @crlf &  "Le renommage est comme suit : AAAA.MM.JJ.fichier.ext " & " (les fichier déjà nommés ne seront pas traités)" & @crlf & @crlf & "Voulez-vous commencer ?")
if $msg=7 then  Exit

While 1
        _Change_name_file()
WEnd

func _Change_name_file()
local $nombre = 0
$Dossier_a_scanner = FileOpenDialog("Selectionnez les fichiers à modifier (Touche CTRL pour une selection multiple)", @ScriptDir,"Tous types (*.*)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)
if @error then
        msgbox(0,"RENOME DATE","Aucun fichier séléctionné... je quitte" & @CRLF & "Merci d'avoir utilisé ce programme",3)
        Exit
EndIf
$tableau_liste_fichiers = StringSplit($Dossier_a_scanner,"|")
if UBound($tableau_liste_fichiers)=2 Then ; ici il n'y a qu'un seul fichier selectionné
        Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = ""
        $apathsplit=_PathSplit($tableau_liste_fichiers[1], $sDrive, $sDir, $sFilename, $sExtension) ; la procedure est differente
        $fichier_en_cours = $apathsplit[3] & $apathsplit[4] ; car l'array est construite differement entre une selection unique et une multiple
        $time_fichier=_ConvertTimeFormat(FileGetTime($apathsplit[0], 0, 1 ))
        $split_date=StringSplit($fichier_en_cours,".")
        if $split_date[0] > 2 then
                $nom_fichier_modifie= $fichier_en_cours
        Else
                $nom_fichier_modifie= $time_fichier & "."& $fichier_en_cours
                $nombre +=1
        EndIf
        FileMove($apathsplit[0],$apathsplit[1] & $apathsplit[2] & $nom_fichier_modifie, 9)
Else
        for $i=2 to UBound($tableau_liste_fichiers)-1 ; si selection multiple
                $fichier_en_cours = $tableau_liste_fichiers[$i]
                $time_fichier=_ConvertTimeFormat(FileGetTime($tableau_liste_fichiers[1] & "\" & $fichier_en_cours, 0, 1 ))
                $split_date=StringSplit($fichier_en_cours,".")
                if $split_date[0] > 2 then
                        $nom_fichier_modifie= $fichier_en_cours
                Else
                        $nom_fichier_modifie= $time_fichier & "."& $fichier_en_cours
                        $nombre +=1
                EndIf
                FileMove($tableau_liste_fichiers[1] & "\" & $fichier_en_cours,$tableau_liste_fichiers[1] & "\" & $nom_fichier_modifie, 9)

        Next
EndIf

$msg2=msgbox(4,"RENOME DATE","Nombre de fichiers renomés : " & $nombre & @CRLF & "voulez vous en modifier d'autres ?")
        if $msg2=7 then
                msgbox(0,"RENOME DATE " & $version, "Merci d'avoir utilisé ce programme", 3)
                Exit
        Else
                Return
        EndIf
EndFunc

Func _ConvertTimeFormat ( $_FileTime ) ; convert 20100716213616 string time format to this time format YYYY/MM/DD HH:MM:SS
    Return StringMid ( $_FileTime, 1 , 4 ) & '.' & StringMid ( $_FileTime, 5 , 2 ) & '.' & StringMid ( $_FileTime, 7 , 2 )
 EndFunc ;==> _ConvertTimeFormat ( )

Avatar du membre
ZDS
Membre émérite
Membre émérite
Messages : 554
Enregistré le : jeu. 10 juin 2010 09:35
Localisation : 22300 Cul-d'chouette Langue-de-vache
Status : Hors ligne

Re: Programme de renommage des fichiers pour les élèves utilisant l'ordinateur au collège

#2

Message par ZDS » sam. 07 janv. 2017 22:38

Bonjour Marcgforce, et tout d'abord merci pour le script.

C'est clair que ce genre de programme peut aider dans le cas d'un handicap. Moi même jouant à certains jeux en ligne avec des personnes à mobilité réduite, j'ai créé certains scripts d'assistanat et de renommage pour eux, et j'étais parti sur une approche sensiblement identique, mais pas tout à fait : Tu peux intégrer ton programme dans le menu contextuel Windows "Envoyer vers...", et ainsi sauter l'étape de la MsgBox, ainsi que la FileOpenDialog qui boucle.

Voici un exemple (à vérifier si le fonctionnement est bien celui que tu attends), il te suffira de le compiler puis de mettre un raccourci "Renommage spécial" vers ton exécutable dans le répertoire "SendTo" (par exemple si tu es sous Windows 10, c'est le dossier "C:\Users\????????\AppData\Roaming\Microsoft\Windows\SendTo"). Ainsi ta fille n'aura plus qu'à sélectionner plusieurs fichiers d'un seul coup dans n'importe quelle fenêtre de l'explorateur Windows, et faire "Clic droit" > "Envoyer vers" > "Renommage spécial".

Code : Tout sélectionner

#include <Array.au3>

; Initialisation
Local $pattern = "^(.*?)\\([^\\]*?)\.([^\.]*?)$"
Local $infos[1][5] = [[0]], $jobList[1][3] = [[0]]
Local $changed = 0, $erreurs = 0, $annulation = False

; Listing des fichiers à renommer
For $i = 1 To $cmdLine[0]
	Local $fichier = $cmdLine[$i], $modified = FileGetTime($fichier)
	If Not @error And FileExists($fichier) And StringRegExp($fichier, $pattern) And Not isFolder($fichier) Then
		$infos[0][0] = $infos[0][0]+1
		ReDim $infos[$infos[0][0]+1][UBound($infos,2)]
		; Structuration
		$infos[$infos[0][0]][0] = StringRegExpReplace($fichier, $pattern, "$1") ; Répertoire
		$infos[$infos[0][0]][1] = StringRegExpReplace($fichier, $pattern, "$2") ; Nom du fichier
		$infos[$infos[0][0]][2] = StringRegExpReplace($fichier, $pattern, "$3") ; Extension
		$infos[$infos[0][0]][3] = getDatePrefixe($modified) ; Date du fichier YYYY.MM.DD
		$infos[$infos[0][0]][4] = StringRegExp($infos[$infos[0][0]][1], "^\d{4}\.\d{2}\.\d{2}\.") <> 0 ; Déjà nomenclaturé
	EndIf
Next

; Pré-Traitement
For $i = 1 To $infos[0][0]
	Local $repertoire = $infos[$i][0], $source = $infos[$i][1], $extension = $infos[$i][2], $date = $infos[$i][3], $cible = ""
	Switch ($infos[$i][4])
		Case False ; Fichier non renommé
			$cible = $date&"."&$source
		Case True ; Fichier déjà renommé
			If $date <> StringLeft($source, StringLen($date)) Then ; Vérification de la date
				$cible = $date&"."&StringTrimLeft($source, StringLen($date)+1)
				$changed += 1
			EndIf
	EndSwitch
	If $cible <> "" Then
		$jobList[0][0] = $jobList[0][0]+1
		ReDim $jobList[$jobList[0][0]+1][UBound($jobList,2)]
		$jobList[$jobList[0][0]][0] = $repertoire&"\"&$source&"."&$extension ; Source
		$jobList[$jobList[0][0]][1] = $repertoire&"\"&$cible&"."&$extension ; Cible
		$jobList[$jobList[0][0]][2] = False ; Renommage effectué
	EndIf
Next

; Renommage des fichiers
For $i = 1 To $jobList[0][0]
	$jobList[$i][2] = FileMove($jobList[$i][0], $jobList[$i][1])
	If Not $jobList[$i][2] Then $erreurs += 1
Next

; Système d'annulation
If $infos[0][0] = 0 Then
	MsgBox(48, @ScriptName, "Aucun fichier n'a été sélectionné", 30)
ElseIf $jobList[0][0] = 0 Then
	MsgBox(48, @ScriptName, "Aucun fichier ne nécessite de renommage", 30)
ElseIf $erreurs = 0 Then ; Pas d'erreur
	Local $reponse = MsgBox(1+64, @ScriptName&" ("&$jobList[0][0]&")", "Procédure de renommage exécutée avec succès ("&$jobList[0][0]&($changed=0?")":" dont "&$changed&" modification"&($changed=1?"":"s")&")") & @CRLF&@CRLF & "[OK] pour conserver (par défaut), [Annuler] pour revenir en arrière", 30)
	$annulation = ($reponse = 2) ; 2 = Clic sur "Annuler"
Else ; Erreur lors du renommage
	Local $reponse = MsgBox(1+32+256, @ScriptName&" ("&$jobList[0][0]&")", "Erreur(s) lors de la procédure de renommage ("&$jobList[0][0]&($changed=0?")":" dont "&$changed&" modification"&($changed=1?"":"s")&")") & @CRLF&@CRLF & "[OK] pour conserver, [Annuler] pour revenir en arrière (par défaut)", 30)
	$annulation = ($reponse <> 1) ; 1 = Clic sur "OK"
EndIf
If $annulation Then
	For $i = 1 To $jobList[0][0]
		FileMove($jobList[$i][1], $jobList[$i][0])
	Next
EndIf

; Fonctions annexes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func isFolder($path)
	Local $types = FileGetAttrib($path)
	If @error Then Return SetError(1, 0, True)
	Return StringInStr($types, "D")
EndFunc

Func getDatePrefixe($date)
	Return $date[0]&"."&$date[1]&"."&$date[2]
EndFunc
J'ai tenté de rendre le code compréhensible, mais si tu as des doutes, n'hésite pas.

A bientôt !
ZDS : Chef de projet du nAiO (logiciel AutoIt gratuit sous licence CC 4.0 BY-NC-SA)
Tout problème a une solution, donc si il y a pas d'solution, c'est qu'il y a pas d'problème !

Avatar du membre
mikell
Modérateur
Modérateur
Messages : 5874
Enregistré le : dim. 29 mai 2011 16:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Programme de renommage des fichiers pour les élèves utilisant l'ordinateur au collège

#3

Message par mikell » dim. 08 janv. 2017 17:11

Une autre manière si on veut le faire intuitif : on drag/drop tous les fichiers à renommer ensemble dans un edit (même s'ils sont dans plusieurs dossiers différents) et on renomme tout d'un coup
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>
#include <EditConstants.au3>

$gui = GUICreate("Rename", 210, 200, -1, 100, -1, $WS_EX_ACCEPTFILES)
$edit = GUICtrlCreateEdit("", 5, 5, 200, 155, $ES_READONLY)
GUICtrlSetBkColor(-1, 0xffffff)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$btn_rename = GUICtrlCreateButton("Renommer", 10, 170, 90, 22)
$btn_exit = GUICtrlCreateButton("Exit", 150, 170, 50, 22)
GUISetState(@SW_SHOWNA)

Global $a_files[0][4], $s0

While 1
$msg = GUIGetMsg()
Switch $msg
        Case $GUI_EVENT_CLOSE, $btn_exit
                Exit
        Case $GUI_EVENT_DROPPED
                $s = GuiCtrlRead($edit)
                $afiles = StringSplit($s, @crlf, 3)
                For $i = 0 to UBound($afiles)-1
                    If not StringInStr($afiles[$i], "\") Then ContinueLoop   ; si ce qui est lu dans l'edit n'est pas un chemin
                    If _ArraySearch($a_files, $afiles[$i]) <> -1 Then ContinueLoop  ; pour ne pas sélectionner le même fichier 2 fois
                    $oldfile = StringRegExpReplace($afiles[$i], '.+\\(.+)', "$1")  ; nom du fichier
                    If StringRegExp($oldfile, '^\d{4}\.\d{2}\.\d{2}\.') Then ContinueLoop  ; si le nom commence déjà par une date
                    $dir = StringRegExpReplace($afiles[$i], '(.+\\)[^\\]+', "$1")  ; chemin
                    $time = _ConvertTimeFormat(FileGetTime($afiles[$i], 0, 1 ))  ; date
                    _ArrayAdd($a_files, $afiles[$i] & "|" & $dir & "|" & $oldfile & "|" & $time)
                    $s0 &= $oldfile & @crlf
                Next
                GuiCtrlSetData($edit, $s0)
                ; _ArrayDisplay($a_files)

        Case $btn_rename
                _Rename()
EndSwitch
WEnd


Func _Rename()
    Local $res
    For $i = 0 to UBound($a_files)-1
           $newfile = $a_files[$i][3] & "." & $a_files[$i][2]
           FileMove($a_files[$i][0], $a_files[$i][1] & $newfile, 1)
           $res &= $newfile & @crlf
    Next
    Msgbox(0,"", UBound($a_files) & " fichiers renommés :" & @crlf&@crlf & $res)
EndFunc

Func _ConvertTimeFormat($_FileTime) ; convert 20100716213616 string time format to this time format YYYY/MM/DD HH:MM:SS
        Return StringMid($_FileTime, 1 , 4) & '.' & StringMid($_FileTime, 5 , 2) & '.' & StringMid($_FileTime, 7 , 2)
EndFunc ;==> _ConvertTimeFormat()
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )

marcgforce
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 07 mars 2016 07:20
Status : Hors ligne

Re: Programme de renommage des fichiers pour les élèves utilisant l'ordinateur au collège

#4

Message par marcgforce » dim. 08 janv. 2017 21:57

Merci ZDS et mikell pour vos solutions, Je n'y avais pas pensé je testerai rapidement pour vous donner un avis, vu que ma fille à besoin du script tous les jours, elle sera ma bêta testeuse. Il est clair qu'en relisant le script de ZDS je ne suis pas à son niveau mais c'est comme ça que je progresse... quant a toi mikell ta solution est aussi intéressante et pique ma curiosité. En tous cas je suis impressionné par la multitude de solutions qui peuvent être mises en œuvre pour arriver au même but et que ces scripts seront utile à quelqu'un qui est dans ce besoin !.

Répondre