#!/usr/bin/env python3 import os import shutil import subprocess # Constants SOURCE_FOLDER = os.path.join(os.path.expanduser("~"), "Musique") OUTPUT_FOLDER = os.path.join(os.path.expanduser("~"), ".MusiqueCompressed") CONVERSIONS = {"flac": "m4a"} FORBIDDEN_EXTENSIONS = ["jpg", "pdf", "ffs_db"] FORGIVEN_FILENAMES = ["cover.jpg"] IGNORED_EMPTY_FOLDER = [".stfolder"] # Listing files sourceFiles = dict() for root, dirs, files in os.walk(SOURCE_FOLDER): for f in files: fullPath = os.path.join(root, f) path = os.path.relpath(fullPath, SOURCE_FOLDER) sourceFiles[path] = os.path.getctime(fullPath) outputFiles = dict() for root, dirs, files in os.walk(OUTPUT_FOLDER): for f in files: fullPath = os.path.join(root, f) path = os.path.relpath(fullPath, OUTPUT_FOLDER) outputFiles[path] = os.path.getctime(fullPath) # Sorting files remainingConversions = dict() extraFiles = list(outputFiles.keys()) def convertPath(path): filename, extension = os.path.splitext(path) extension = extension[1:].lower() # If the extension isn't allowed if extension in FORBIDDEN_EXTENSIONS: basename = os.path.basename(path) # And the filename is not an exception if basename not in FORGIVEN_FILENAMES: # This file shouldn't be copied nor converted return False # If this needs a conversion elif extension in CONVERSIONS: extension = CONVERSIONS[extension] return filename + "." + extension # In all other case, this is a simple copy return path for sourceFile in sourceFiles: outputFile = convertPath(sourceFile) # If the file should not be converted, do nothing if outputFile == False: continue # If the file already has something as an output elif outputFile in outputFiles: extraFiles.remove(outputFile) # If the output file is newer than the source file, do not initiate a conversion if outputFiles[outputFile] >= sourceFiles[sourceFile]: continue # If the file needs to be converted, do it remainingConversions[sourceFile] = outputFile # Converting files for sourceFile in remainingConversions: outputFile = remainingConversions[sourceFile] # Creating folder if it doesn't exists fullOutputFile = os.path.join(OUTPUT_FOLDER, outputFile) fullOutputDir = os.path.dirname(fullOutputFile) os.makedirs(fullOutputDir, exist_ok=True) # Converting fullSourceFile = os.path.join(SOURCE_FOLDER, sourceFile) print(fullSourceFile, "→", fullOutputFile) if sourceFile == outputFile: # shutil.copy(fullSourceFile, fullOutputFile) os.link(fullSourceFile, fullOutputFile) else: subprocess.run(["ffmpeg", "-y", "-i", fullSourceFile, "-codec:a", "libfdk_aac", "-cutoff", "18000", "-movflags", "+faststart", "-vbr", "5", fullOutputFile]) # Removing extra files for extraFile in extraFiles: fullExtraFile = os.path.join(OUTPUT_FOLDER, extraFile) os.remove(fullExtraFile) # Removing empty dirs for root, dirs, files in os.walk(OUTPUT_FOLDER): if not dirs and not files: dirBasename = os.path.basename(root) if dirBasename not in IGNORED_EMPTY_FOLDER: os.rmdir(root)