96 lines
3.2 KiB
Plaintext
96 lines
3.2 KiB
Plaintext
|
#!/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)
|
||
|
|
||
|
|