Constantin Fürst
2 years ago
1 changed files with 124 additions and 0 deletions
-
124libconv.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) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue