소스 검색

version du 01/02/2025

Jacques Chodorowski 1 개월 전
부모
커밋
e429fcb20c
3개의 변경된 파일209개의 추가작업 그리고 3개의 파일을 삭제
  1. 2 0
      .gitignore
  2. 1 3
      README.md
  3. 206 0
      renamer.py

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+.venv
+.idea

+ 1 - 3
README.md

@@ -1,3 +1 @@
-# renamer
-
-renommer les fichier d'un repertoire
+# Un script ___PYTHON___ pour renommer les fichiers en série

+ 206 - 0
renamer.py

@@ -0,0 +1,206 @@
+#!/usr/bin/env python3
+# coding: utf-8
+"""
+Created on Wed Jul  13 10:52:12 2024
+
+@author: ajco7475
+"""
+import sys
+import os
+import re
+import getopt
+from colorama import init, Fore, Style
+import random
+import logging
+import platform
+
+logger = logging.getLogger("RENAMER")
+logging.basicConfig()
+
+init(autoreset=True)
+
+
+def color_text(text, color):
+    return f"{color}{text}{Fore.RESET}"
+
+
+# =============================================================================
+# usage
+#
+# - afficher le message d'aide
+# =============================================================================
+def set_log_level(log_level):
+    if log_level == "CRITICAL":
+        logger.setLevel(logging.CRITICAL)
+    elif log_level == "ERROR":
+        logger.setLevel(logging.ERROR)
+    elif log_level == "WARNING":
+        logger.setLevel(logging.WARNING)
+    elif log_level == "INFO":
+        logger.setLevel(logging.INFO)
+    else:
+        if log_level is None:
+            print("INFO: log level is set to 'DEBUG' by default")
+        elif log_level != "DEBUG":
+            print(
+                "INFO: specified log_level value ({}) is incorrect, use CRITICAL, ERROR, WARNING, INFO or DEBUG. log "
+                "level is set to 'DEBUG' by default".format(log_level))
+        logger.setLevel(logging.DEBUG)
+
+
+# =============================================================================
+# clean_file_name
+#
+# - afficher le message d'aide
+# =============================================================================
+def clean_file_name(old_filename):
+    new_filename = None
+    parts = old_filename.rsplit('.', 1)  # Divise à partir du dernier point
+    if len(parts) == 2:
+        # Remplace tous les points dans la première partie
+        parts[0] = re.sub(r'\.', ' ', parts[0])
+        new_filename = parts[0] + '.' + parts[1]
+    else:
+        # S'il n'y a pas de point, ou juste un à la fin, retourne la chaîne inchangée
+        new_filename = old_filename
+    # remplacement de DVDRip et marques suivantes
+    new_filename = re.sub(r'(.*)\s+DVDRip\b.*\.(\w+)$', r'\1.\2', new_filename)
+    # nettoyage de 1080p ... et 720p ...
+    new_filename = re.sub(r'(.*)(\d\d\d+p).*\.(\w+)$', r'\1\2.\3', new_filename)
+    # ntettoyage de x264 ... x265 ...
+    new_filename = re.sub(r'(.*)(\s+x26\d).*\.(\w+)$', r'\1.\3', new_filename)
+    # ntettoyage de ... - ...
+    new_filename = re.sub(r'\s+-\s+', ' ', new_filename)
+    # mise en parenthéses de l'année
+    new_filename = re.sub(r'\b(\d\d\d\d)\b', r'(\1)', new_filename)
+    # suppression des blancs au debut
+    new_filename = re.sub(r'^\s+', '', new_filename)
+    # suppression des blancs à la fin
+    new_filename = re.sub(r'\s+$', '', new_filename)
+    # remplacement d'un planc par un seul underscore
+    new_filename = re.sub(r'\s+', '_', new_filename)
+    # remplacement de plusieures parentheses ouvrantes
+    new_filename = re.sub(r'\(\(+', '(', new_filename)
+    # remplacement de plusieures parentheses fermantes
+    new_filename = re.sub(r'\)\)+', ')', new_filename)
+    logger.debug(f"old_filename=<{old_filename}> new_filename=<{new_filename}>")
+    return new_filename
+
+
+# =============================================================================
+# rename_files_in_directory
+#
+# - afficher le message d'aide
+# =============================================================================
+def rename_files_in_directory(
+        directory_path,
+        pattern=None,
+        new_prefix=None,
+        no_underscore=False,
+        test=False):
+    """
+    Renomme les fichiers dans le répertoire spécifié selon un certain motif.
+
+    :param directory_path: Chemin du répertoire à parcourir.
+    :param pattern: Motif regex pour correspondre les noms de fichiers actuels.
+    :param new_pattern: Motif pour renommer les fichiers.
+    """
+    # Vérifier si le répertoire existe
+    if not os.path.isdir(directory_path):
+        print(f"Le répertoire {directory_path} n'existe pas.")
+        return
+
+    if pattern is None:
+        pattern = r".*"
+    logger.debug(f"pattern=<{pattern}> new_prefix=<{new_prefix}> no_underscore=<{no_underscore}>")
+
+    # Parcourir tous les fichiers dans le répertoire
+    for filename in os.listdir(directory_path):
+        # Chemin complet du fichier
+        file_path = os.path.join(directory_path, filename)
+
+        # Vérifier si c'est un fichier
+        if os.path.isfile(file_path):
+            logger.debug(f"file_path=<{file_path}>")
+            # Utiliser l'expression régulière pour correspondre le nom de fichier
+            match = re.match(pattern, filename)
+            if match:
+                # Construire le nouveau nom de fichier
+                new_filename = clean_file_name(filename)
+                if new_prefix is not None:
+                    pattern = re.compile(r'(?i)^(.*?)(S(\d+)E(\d+))')
+                    match = re.search(pattern, new_filename)
+                    logger.debug(f"<<{match.group()}>> {match.lastindex} ---> {new_prefix}")
+                    saison = "{:02}".format(int(match.group(3)))
+                    episode = "{:02}".format(int(match.group(4)))
+                    logger.debug(
+                        "saison : " + color_text(saison, Fore.BLUE) + "   episode : " + color_text(episode, Fore.RED))
+                    new_filename = pattern.sub(f'{new_prefix}_S{saison}E{episode}', new_filename)
+                # si demandé enlever les underscores
+                if no_underscore:
+                    new_filename = new_filename.replace('_',' ')
+                # Renommer le fichier
+                new_file_path = os.path.join(directory_path, new_filename)
+                if not test:
+                    os.rename(file_path, new_file_path)
+                print("<<< " + color_text(file_path, Fore.BLUE) + "\n>>> " + color_text(new_file_path, Fore.RED))
+
+
+# =============================================================================
+# usage
+#
+# - afficher le message d'aide
+# =============================================================================
+def usage():
+    script_name = os.path.basename(__file__)
+    print(f"{script_name}  : () facultative item, <> : mandatory item\n"
+          "    (--prefix=<prefix string>) : prefixe a placer devant SxxExx\n"
+          "    (--rd=<prefix string>) : repertoire à parcourir\n"
+          "    (--nu) : supprimer le 'underscore' du nom final du fichier cible\n"
+          "    (--test) : afficher les transformations sans effectuer le rennomage\n"          
+          "    (--ll=<log level:CRITICAL|ERROR|WARNING|INFO|DEBUG>)\n"
+          "    (-h) : this help\n")
+
+
+# =============================================================================
+# MAIN
+# =============================================================================
+
+if __name__ == '__main__':
+    # nouveau prefix
+    prefix = None
+    # niveau de logs par défaut
+    ll = 'INFO'
+    # repertoire à addresser
+    ren_dir = None
+    # supprimer le 'underscore' du nom final du fichier cible
+    no_underscore = False
+    # afficher les transformations sans effectuer le rennomage
+    do_test = False
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "h",
+                                   ["prefix=", "rd=", "nu", "test", "ll="])
+    except getopt.GetoptError as err:
+        logger.error(err)
+        usage()
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt == '-h':
+            usage()
+            sys.exit()
+        elif opt in "--prefix":
+            prefix = arg
+        elif opt in "--rd":
+            ren_dir = arg
+        elif opt in "--nu":
+            no_underscore = True
+        elif opt in "--test":
+            do_test = True
+        elif opt in "--ll":
+            if arg in ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]:
+                ll = arg
+    # log level
+    set_log_level(ll)
+    if ren_dir is None:
+        ren_dir = os.getcwd()
+    rename_files_in_directory(ren_dir, new_prefix=prefix, no_underscore=no_underscore,test=do_test)