Voici un projet que je propose pour ceux qui sont passionnés et qui auraient envie d'améliorer cette solution pour le renommage des fichiers téléchargés via youtube-dl.
En effet je ne sais pas si c'est un réflexe de "Geek" mais je ne supportes pas quand un fichier contient un titre suivi de -xxxxxxxxx.mp4.

Du coup, je me suis fait mon petit outil pour renommer les fichiers en fonction d'un "pattern" donné "-" suivi de 4 caractères alphanumériques minimum, se terminant par ".mp4" (il est possible de modifier l'extension si nécessaire).

Ce programme utilise une librairie qui gère des listes chaînées que j'ai développé pour mes classes depuis un moment... elle est disponible sur github... (https://github.com/truesoundlord/saintmartin)

J'ai joint le code source (je développe essentiellement dans netbeans).

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/* 
 * File:   renametubes.c
 * Author: Dimitri "Hurukan" <soundlord@gmail.com>
 *
 * Créé le August 17, 2020, 12:59 AM
 */
 
// ****************************************************************************
// HISTORIQUE
// ****************************************************************************
 
// **************************************************************************** 
// Fichiers de définitions
// **************************************************************************** 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
 
#include <dirent.h>
#include <wchar.h>
#include <regex.h>
#include <unistd.h>
 
#include <locale.h>
#include <errno.h>
 
#include <linkedlist.h>
 
 
// **************************************************************************** 
// Déclaration des constantes symboliques
// **************************************************************************** 
#define REGEX "\\-[[:alnum:]]{4,15}"								// \-[[:alnum:]]{1,}[_]{1}[[:alnum:]]{1,}.mp4 encore mieux -> \-([[:alnum:]]{1,}[_]{1}[[:alnum:]]{1,}){1,}.mp4
#define STDEXT ".mp4"
 
#define ANSIGREEN "\x1b[38;2;0;255;0;1m"
#define ANSINTFND "\x1b[38;2;225;225;225;1m"
#define ANSITURK	"\x1b[38;2;0;225;225;1m"
#define ANSIRENMD "\x1b[38;2;255;170;0;1m"
#define ANSIRST	"\x1b[0m"
 
#define CONFDIR "/etc/renametubes"
#define EXCLFL	"exclusions.conf"
 
#define DEBUG
 
// **************************************************************************** 
// Déclaration des variables globales, externes, ...
// **************************************************************************** 
 
bool bStats=false;
 
int cptFichiers;
int cptModifs;
 
ListeChainee *pListeEX;
char strEXT[5];
 
// ****************************************************************************
// SECTION : prototypes des fonctions en test pour CE code source
// ****************************************************************************
 
void BrowseFiles(struct dirent*,char*);
void GetExclusionPatterns(LinkedList*); 
bool DoIExclude(LinkedList*,char*);
 
/*
 * FONCTION PRINCIPALE
 */
int main(int argc,char** argv)
{
	regex_t regexcomp;
 
	DIR           *desc_REP;	
	struct dirent *fichier;
 
	char strREGEX[255];
 
	setlocale(LC_ALL,"fr_BE.utf8");	
	desc_REP = opendir(".");
 
	// USAGE: -d directory -e extension
 
	strcpy(strREGEX,REGEX);
	strcpy(strEXT,STDEXT);
 
	//***************************************************************************
	// TRAITEMENT DES EVENTUELS PARAMETRES
	//***************************************************************************
 
	int cptParam=argc-1;
	while(argv[cptParam]!=NULL && cptParam>=1)
	{
		if(strcmp(argv[cptParam],"-d")==0 && argv[cptParam+1]!=NULL)
		{
			desc_REP = opendir(argv[cptParam+1]);
			chdir(argv[cptParam+1]);
		}
		if(strcmp(argv[cptParam],"-e")==0 && argv[cptParam+1]!=NULL)
		{
			if(argv[cptParam+1][0]!='.')	
			{
				strEXT[0]='\0';
				strcat(strEXT,".");
				strcat(strEXT,argv[cptParam+1]);
			}
			else strcpy(strEXT,argv[cptParam+1]);
		}
		if(strcmp(argv[cptParam],"-s")==0)
		{
			bStats=true;
		}
		if(strcmp(argv[cptParam],"-p")==0 && argv[cptParam+1]!=NULL)
		{
			char pattern=argv[cptParam+1][0];
			sprintf(strREGEX,"\\-([[:alnum:]]{1,}[%c]{1}[[:alnum:]]{1,}){1,}",pattern);				// gestion des saloperies avec un ou plusieurs caractères de type ponctuation (Qip_HOnF0_g.mp4)
		}
		cptParam--;
	}
 
	if(argc>1)
	{
		if(strcmp(argv[1],"--help")==0)
		{
			wprintf(L"USAGE: renametubes\n\t[-d] folder\n\t[-e] extension (mp4/avi/mkv/...)\n\t[-s] display statistics\n\t[-p] specify pattern (./_/...)\n\n");
			exit(EXIT_FAILURE);
		}
	}
 
	//***************************************************************************
	// DEBUT DU TRAITEMENT
	//***************************************************************************
 
	strcat(strREGEX,strEXT);																											// ajoute l'extension à l'expression rationnelle
	pListeEX=lc_init();
 
	if(desc_REP)
	{
		GetExclusionPatterns(pListeEX);																							// Générer la liste des noms de fichier à exclure
		fichier = readdir(desc_REP);																								// obtention d'une entrée du répertoire cible
		if(fichier!=NULL) 
		{
			BrowseFiles(fichier,strREGEX);																						// parcours des fichiers du répertoire
		}
		closedir(desc_REP);
	}
	else
	{
		wprintf(L"Erreur: %s\n",strerror(errno));
		return(EXIT_FAILURE);
	}
 
	if(bStats)
	{
		wprintf(L"\n%-30s\t%05d\n","Nombre de fichiers traités:",cptFichiers);
		wprintf(L"%-30s\t%05d\n","Nombre de fichiers renommés:",cptModifs);
	}
	lc_empty(pListeEX);
	return(EXIT_SUCCESS);
}
 
// ****************************************************************************
// SECTION : implémentation des fonctions
// ****************************************************************************
 
/*
 * /!\ this function is not thread safe nore reentrant /!\
 * uses global variables
 * + pListEx
 * + strEXT
 */
 
void BrowseFiles(struct dirent *target,char *paramREGEX)
{
	DIR *basedir;
	struct dirent *repFile;
 
	char buffer[FILENAME_MAX]="\0";
	regex_t regexcomp;
	ListeChainee *int_Reps;
 
	// Je pars du principe que target est un folder/répertoire
 
	getcwd(buffer,FILENAME_MAX);																											// récupérer le chemin du répertoire courant
 
	//wprintf(L"[DEBUG] (%s) %s\n",buffer,target->d_name);
 
	if(strcmp(target->d_name,".") && strcmp(target->d_name,".."))
	{
#ifdef DEBUG
		wprintf(L"%s[%s]%s\n",ANSITURK,target->d_name,ANSIRST);
#endif
		strcat(buffer,"/");						
		strcat(buffer,target->d_name);
	}
	chdir(buffer);																																		// je change de répertoire (chemin absolu)
 
	if(DoIExclude(pListeEX,buffer)) return;																						// dois-je l'exclure ?
 
	//***************************************************************************
	// CORE
	//***************************************************************************
 
	basedir=opendir(".");																															// obtenir un descripteur sur le répertoire courant
	if(basedir)
	{
		int_Reps=lc_init();																															// initialiser la liste des répertoires...
		while((repFile=readdir(basedir)) != NULL)																				// lire toutes les entrées du répertoire...
		{
			if(repFile->d_type==DT_DIR)																										// si c'est un répertoire...
			{
				if(strcmp(repFile->d_name,".") && strcmp(repFile->d_name,".."))
				{
					lc_add(repFile,int_Reps,cssmuserdef,sizeof(struct dirent));								// ...l'ajouter dans la liste des répertoires à traiter			
				}
			}
			else																																					// sinon
			{
#ifdef DEBUG
				wprintf(L"(%s) %s",buffer,repFile->d_name);
#endif
				if(bStats) cptFichiers++;
 
				// regex !!
				int coderetour=regcomp(&regexcomp,paramREGEX,REG_EXTENDED);										// compiler l'expression régulière 
				if(coderetour==-1) 
				{
					wprintf(L"regcomp() -- error \n");
					return;
				}
 
				coderetour=regexec(&regexcomp,repFile->d_name,0,NULL,0);										// exécuter l'expression régulière
 
				if(coderetour!=REG_NOMATCH)																									// PATTERN trouvé
				{
					wprintf(L" %s[Pattern trouvé] :)%s\n",ANSIGREEN,ANSIRST);
 
					if(DoIExclude(pListeEX,repFile->d_name)) continue;												// dois-je l'exclure ?
 
					// renommage
 
					char copie[FILENAME_MAX];
					char *pBegin=strrchr(repFile->d_name,'-');
 
#ifdef DEBUG
					wprintf(L"EXTRACT: %s\n",pBegin);
#endif
 
					int position=pBegin-repFile->d_name;
 
					strcpy(copie,repFile->d_name);
 
					repFile->d_name[position]='\0';
					//strcat(repFile->d_name,".mp4");
					strcat(repFile->d_name,strEXT);
 
					FILE *tmp=fopen(repFile->d_name,"r");																			// est-ce que le fichier existe déjà ?
 
					//wprintf(L"[DEBUG] %s %p\n",repFile->d_name,tmp);
 
					if(tmp==NULL)													// si pas trouvé le fichier n'existe pas... nous pouvons le renommer sans détruire tout comme le 26 oct 2020 !!!
					{
						coderetour=rename(copie,repFile->d_name);																// renommer le fichier
						if(coderetour==-1)
						{
							wprintf(L"MERDE !! (%s)\n",strerror(errno));
						}
						if(bStats) cptModifs++;
#ifdef DEBUG
						wprintf(L"%sRENAMED: %s%s\n",ANSIRENMD,ANSIRST,repFile->d_name);
#endif
					}
					else fclose(tmp);																													// fermer le descripteur	
				}
#ifdef DEBUG
				else
					wprintf(L" %s[Pattern non trouvé] :{%s\n",ANSINTFND,ANSIRST);						
#endif
				regfree(&regexcomp);																												// libérer l'expression régulière...
			}
		} // endwhile
	}
 
	//***************************************************************************
	// TRAITEMENT DES EVENTUELS REPERTOIRES TROUVES
	//***************************************************************************
 
	while(int_Reps->NbElem)
	{
		lc_Datas *tmp=lc_pop(int_Reps);
		struct dirent *pRepertoireAScanner=(struct dirent*)tmp->value;
 
		// sur le disque externe je ne sais pas comment c'est possible mais je "switche" sur /usr/lib64 et même / !!!
		// HEUREUSEMENT il n'y a pas eu de dégâts...
 
		BrowseFiles(pRepertoireAScanner,paramREGEX);																		// POINT DE RECURSION
	}
	chdir("..");																																			// remonter d'un niveau dans le système de fichiers
	closedir(basedir);																																// fermer le descripteur de répertoire
}
 
void GetExclusionPatterns(LinkedList *Exclusions)
{
	FILE *fichierconf;
	char current[FILENAME_MAX];
	char *buffer;
	char *exclusion;
	long taillefichier;
 
	getcwd(current,FILENAME_MAX);
	int rc=chdir(CONFDIR);
	if(rc==-1) return;
 
	fichierconf=fopen(EXCLFL,"r");
	if(!fichierconf) return;
 
	fseek(fichierconf,0L,SEEK_END);	
	taillefichier=ftell(fichierconf);
	if(taillefichier<=0L) return;
 
	fseek(fichierconf,0L,SEEK_SET);
	buffer=calloc(taillefichier+1,sizeof(char));
 
	fread(buffer,taillefichier,1,fichierconf);
	fclose(fichierconf);
 
	char *pSeek;
	while((pSeek=strchr(buffer,'\n'))!=NULL)
	{
		exclusion=calloc((pSeek-buffer)+1,sizeof(char));
		strncpy(exclusion,buffer,pSeek-buffer);
		//wprintf(L"[%s](%d)[%p]\n",__func__,exclusion[0],pSeek); // bug oct 2020
		if(exclusion[0]!=0) lc_add(exclusion,Exclusions,cssmuserdef,sizeof(char*));
		pSeek++;
		buffer=pSeek;
	}
	chdir(current);
}
 
bool DoIExclude(LinkedList *exclusions,char *pModel)
{
	//char *pStrDatas=calloc(FILENAME_MAX,sizeof(char)); // merci valgrind ^^ 
 
	char *pStrDatas;
 
	if(exclusions!=NULL) 
	{
		lc_Datas *tmp=exclusions->pHead;
		while(tmp!=NULL)
		{
			pStrDatas=calloc(strlen((char*)tmp->value),sizeof(char));
			pStrDatas=(char*)tmp->value;
 
			//wprintf(L"[%s](%s) [%p]\n",__func__,pStrDatas,strstr(pModel,pStrDatas));
 
			if(strstr(pModel,pStrDatas)!=NULL) return true;
			tmp=tmp->pNext;
		}
	}
	return false;
}
Pour l'instant il "ne fonctionne" que sous Linux, et je n'ai pas encore fait les tests de portabilité ni sous Windows ni sous Mac OS X.

Dans un avenir proche je tenterais un "front end" graphique (GTK3+ sous Windows étant assez pénible à faire fonctionner (https://www.developpez.net/forums/d2...-vers-windows/), je ne sais pas encore quelle librairie utiliser pour le faire) je n'ai pas de Mac OS X du coup je pars du principe que GTK3+ est disponible sous Mac OS X.

voilà, je reviens je suis à la bourre pour partir au boulot :{