Source code for ebook_homebrew.rename

# -*- coding: utf-8 -*-
"""Rename file name.
"""
import os
import os.path
import re

from .core import Common
from .exceptions import InvalidNumberParameterType, \
    ChangeFileNameOSError, InvalidImageParameterType, TargetSrcFileNotFoundError
from .utils.logging import get_logger

logger = get_logger("change_filename")


[docs]class ChangeFilename(Common): """Change file name to only digit name. """ def __init__(self, directory_path, digits, extension): """Constructor Args: directory_path (str): Target directory path. digits (str): Regex target digit. extension (str): Target file extension. """ super().__init__() self.__directory_path = directory_path self.__digits = digits self.__exist_files = [] self.__extension = self._convert_extension_with_dot(extension) self.__regex_ext = re.compile(self.__extension) os.chdir(self.__directory_path) @staticmethod def _create_new_name(num, digit, extension): """Create only digit file name. Args: num (Match): Match object digit (int): digit number extension (str): File Extension like ".jpg" Returns: str: Only digit file name. Raises: InvalidNumberParameterType: If input digit is not Match object. """ try: return num.group().zfill(digit) + extension except AttributeError as e: logger.exception(e) raise InvalidNumberParameterType() def __check_exist_file(self, new_name, old_name, append_list): """Check current directory and exists same name file, return true. Args: new_name (str): Target file name. old_name (str): before name append_list (bool): If true, make duplicate name list Returns: bool: If success, return true Raises: ChangeFileNameOSError: If input a bad filename or path. """ try: if os.path.isfile(new_name): logger.info("File Exist: {filename}".format(filename=new_name)) if old_name != new_name and append_list: logger.debug("Append exist files list: {filename}".format(filename=old_name)) self.__exist_files.append(old_name) return True else: return False except OSError as e: logger.exception(e) raise ChangeFileNameOSError() def __input_new_file_name(self, old_name, overwrite): """Provide input command prompt. Args: old_name (str): Old name overwrite (bool): If true, ignore exist file name. Returns: str: new file name. """ logger.info("Input new name? {old_name} =>".format(old_name=old_name)) new_name = input() while self.__check_exist_file(new_name, new_name, False) and not overwrite: logger.warn("Already file exist: {new_name} " "Input Another file name {old_name} => ?".format(new_name=new_name, old_name=old_name)) new_name = input() return new_name
[docs] def filename_to_digit_number(self): """Change file name to only digit name. Change file name contains digit like "foo001bar.txt" to only digit file name like "001.txt". Returns: List[str]: Skipping files list by exists same name. """ count = 0 try: files = os.listdir(self.__directory_path) except FileNotFoundError: raise TargetSrcFileNotFoundError() logger.info("Target directory: {directory_path}".format(directory_path=self.__directory_path)) logger.info("Digit: {digits}".format(digits=self.__digits)) logger.info("Extension: {extension}".format(extension=self.__extension)) logger.info("-" * 55) max_digit = self._check_digit_format(self.__digits) for file in files: num = self._check_serial_number(file, self.__digits) if not num: logger.debug("Skip(No number): {filename}".format(filename=file)) elif not self.__regex_ext.search(file): logger.debug("Skip(No target extension): {filename}".format(filename=file)) else: new_name = self._create_new_name(num, max_digit, self.__extension) if not self.__check_exist_file(new_name, file, True): self._rename_file(file, new_name) count += 1 logger.info("-" * 55) logger.info("Finished! Rename file count: {count}".format(count=count)) return self.__exist_files
[docs] def change_name_manually(self, overwrite=False): """Change filename manually looking exist_file list. After changing file name for filename_to_digit_number() method, duplicate file name change manually. Args: overwrite (bool): If true, overwrite file name even if exist same name file. Returns: bool: If success, return True. """ logger.info("-" * 55) logger.info("Manually determine file names duplicated by the serial number\n") for file in self.__exist_files: logger.info("File name: {file_name} " "Does it rename? (y/n/r)".format(file_name=file)) # y="Yes" n="No" r="Remove" flag = input() if flag == "y" or flag == "Y": new_name = self.__input_new_file_name(file, overwrite) self._rename_file(file, new_name) logger.info("Rename: {old_name} => {new_name} \n".format(old_name=file, new_name=new_name)) elif flag == "r": logger.info("Will be {file} deleted?" " OK? (y/n/c/r)".format(file=file)) # y="Yes" n="No" c="check" r="rename" flag = input() if flag == "c": try: self._check_image_file(file) except InvalidImageParameterType as e: logger.warn(e) logger.info("Skip..") if flag == "Y" or flag == "y": self._remove_file(file) elif flag == "r": new_name = self.__input_new_file_name(file, overwrite) self._rename_file(file, new_name) else: logger.info("Leave file: {file}\n".format(file=file)) else: logger.info("Leave file: {file}\n".format(file=file)) logger.info("Finished.") return True
[docs] def add_before_after_str(self, before, after): """Add file name specify string. After changing file name for filename_to_digit_number() method, add specify string before or after file name. Args: before (str): String before file name after (str): String after file name Returns: bool: If success, return True. """ logger.info("-" * 55) files = os.listdir(self.__directory_path) if before is not None: logger.info("Add {before} before serial digit".format(before=before)) else: before = "" if after is not None: logger.info("Add {after} before serial digit".format(after=after)) else: after = "" for file in files: num = self._check_serial_number(file, self.__digits) if not num: logger.debug("Skip(No number): {filename}".format(filename=str(file))) else: if self.__regex_ext.search(file): _, center, _ = self._split_dir_root_ext(file) new_name = before + center + after + self.__extension if self.__check_exist_file(new_name, new_name, False): pass else: self._rename_file(file, new_name) return True