From 7b9498bccc9e97186bc6a78d9c8ed426bfe84aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Constantin=20F=C3=BCrst?= Date: Sat, 2 Jul 2022 12:12:37 +0200 Subject: [PATCH] add basic construct for libconv.py --- libconv.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 libconv.py diff --git a/libconv.py b/libconv.py new file mode 100644 index 0000000..e3da86f --- /dev/null +++ b/libconv.py @@ -0,0 +1,124 @@ +CONFIG_FILE: str = "libconv.ini" +CUE_SHEET_EXTENSION: str = ".cue" + +import os +import shutil +import logging +import subprocess +from configparser import ConfigParser +from copy import deepcopy +from pathlib import Path +from typing import List, Optional, Tuple + +LOGGER = logging.getLogger(__name__) + +config = ConfigParser() +config.read(CONFIG_FILE) +source_folder: str = config.get("libconv", "source_folder") +destination_folder: str = config.get("libconv", "destination_folder") +source_file_extensions: List[str] = config.get("libconv", "source_file_extensions").split(",") +destination_extension: str = config.get("libconv", "destination_extension") +ffmpeg_options: str = config.get("libconv", "ffmpeg_options") +ffmpeg_location: str = config.get("libconv", "ffmpeg_location") +folder_icon_extensions: List[str] = config.get("libconv", "folder_icon_extensions").split(",") +overwrite: bool = config.get("libconv", "overwrite_files") == "true" +dry_run: bool = config.get("libconv", "dry_run") != "false" + +# ----------------------------------------------------------------- # +# file and folder operations + +def copy(src: str, dst: str): + if (dry_run): + LOGGER.debug(f"copy {src} to {dst}") + else: + shutil.copyfile(src, dst, follow_symlinks=True) + +def mkdir(path: str): + if (dry_run): + LOGGER.debug(f"mkdir -r {path}") + else: + os.makedirs(path, exist_ok=True) + +def execute(command: str): + if (dry_run): + LOGGER.debug(f"execute: {command}") + else: + subprocess.run(command) + +# ----------------------------------------------------------------- # +# cue sheet processing + +def cue_sheet_processor(path: str): + dst_folder = prepare_destination(path) + sheet = get_files_with_ext(path, [CUE_SHEET_EXTENSION]) + + if (len(sheet) != 1): + LOGGER.debug(f"ERR: Expected exactly one but {path} contains {len(sheet)} cue sheets") + exit(-1) + +# ----------------------------------------------------------------- # +# basic "folder contains audio files" processing + +def file_processor(path: str): + dst_folder = prepare_destination(path) + files = get_files_with_ext(path, source_file_extensions) + + for file in files: + filename = get_filename(file, path) + execute(f"{ffmpeg_location} -i {file} {ffmpeg_options} {dst_folder + filename}.{destination_extension}") + +# ----------------------------------------------------------------- # +# Iteration over library folders and preparation + +def contains_extension(path: str, extensions: List[str]) -> bool: + for root, dirs, files in os.walk(path): + for file in files: + for ext in extensions: + if file.endswith(ext): + return True + return False + +def get_files_with_ext(path: str, extensions: List[str]) -> List[str]: + files = [] + for root, dirs, files in os.walk(path): + for file in files: + for ext in extensions: + if file.endswith(ext): + files.append(os.path.join(root, file)) + return files + +def prepare_destination(path: str) -> str: + images = get_files_with_ext(path, folder_icon_extensions) + + sub_path = path.replace(source_folder, "") + new_path = destination_folder + sub_path + mkdir(new_path) + + for img in images: + img_name = img.replace(path, "") + new_img_path = new_path + img_name + copy(img, new_img_path) + + return new_path + +def get_filename(file: str, path: str) -> str: + fname = file.replace(path, "") + for ext in source_file_extensions: + fname = fname.replace("." + ext, "") + return fname + +def scan_folder(path: str): + for root, dirs, files in os.walk(path): + for directory in dirs: + process_folder(os.path.join(root, directory)) + +def process_folder(path: str): + if contains_extension(path, [CUE_SHEET_EXTENSION]): + cue_sheet_processor(path) + elif contains_extension(path, source_file_extensions): + file_processor(path) + else: + scan_folder(path) + +if __name__ == "__main__": + process_folder(source_folder) \ No newline at end of file