mirror of
https://github.com/Phantop/dotfiles
synced 2024-11-23 15:23:15 +00:00
138 lines
6.3 KiB
Plaintext
138 lines
6.3 KiB
Plaintext
|
#!/usr/bin/python3
|
||
|
__author__ = 'Dominik Krupke, dserv01.de'
|
||
|
|
||
|
#
|
||
|
# While you want to listen to lossless music on your computer you may not be able to also listen to it mobile because
|
||
|
# it takes too much space. A 32GB-SDCard does not suffice for your full music library so you only have the options to
|
||
|
# either only hearing to a subset mobile or converting the music to a lossy format. This script is for the second
|
||
|
# option.
|
||
|
# * Of course you don't want the lossy files on your computer because you already have your perfect lossless music there.
|
||
|
# * If you extend your music library you want a simple way to also have them mobile.
|
||
|
# * You don't want to convert already converted music twice
|
||
|
# This script synchronizes a lossless library folder (e.g. your music folder on your computer) to a lossy library
|
||
|
# folder (e.g. the music folder of your mobile device) by checking if for all music files in your lossless folder there
|
||
|
# is a converted version in your lossy folder. If this is not the case the file is converted. On the other side it
|
||
|
# checks if you still have the lossless file for each lossy file in your library, otherwise this file is removed (so
|
||
|
# removing a file from your lossless library also removes it from your lossy library)
|
||
|
#
|
||
|
# You can use your own commands for converting specific files. These commands have to convert a single file (check the
|
||
|
# commands-array).
|
||
|
#
|
||
|
# The configuration is done with the from_path and the to_path, as well as with the commands-array.
|
||
|
|
||
|
|
||
|
import os
|
||
|
import subprocess
|
||
|
|
||
|
##### CONFIGURATION ###########################################################################################
|
||
|
|
||
|
# This is the path of your lossless libray, e.g. '/home/YOURNAME/Music/'
|
||
|
FROM_PATH = '/home/glados/Music/HiFi/'
|
||
|
# This is the path of your lossy library, e.g. /mnt/SDCARD0/Music/'
|
||
|
TO_PATH = '/home/glados/Music/LoFi/'
|
||
|
|
||
|
# Use [INPUT] and [OUTPUT] to build your commands. Both will be replaced by the full path but without the file extension,
|
||
|
# e.g. /home/doms/Music/Beethoven/FuerElise.flac -> /home/doms/Music/Beethoven/FuerElise
|
||
|
# You need to add the new and old fileextension for checking if the file is already converted and to remove old files
|
||
|
COMMANDS = [['flac', 'opus', 'opusenc --bitrate 72 [INPUT].flac [OUTPUT].opus'],
|
||
|
['mp3', 'opus', 'ffmpeg -i [INPUT].mp3 -c:v copy -f flac - | opusenc --bitrate 72 - [OUTPUT].opus'],
|
||
|
['m4a', 'opus', 'ffmpeg -i [INPUT].m4a -c:v copy -f flac - | opusenc --bitrate 72 - [OUTPUT].opus'],
|
||
|
['opus', 'opus', 'ffmpeg -i [INPUT].opus -c:v copy -f flac - | opusenc --bitrate 72 - [OUTPUT].opus'],
|
||
|
['jpg', 'jpg', 'cp [INPUT].jpg [OUTPUT].jpg'],
|
||
|
['png', 'jpg', 'convert [INPUT].png [OUTPUT].jpg']
|
||
|
]
|
||
|
|
||
|
# Remove files that are not in the original library
|
||
|
SYNC_DELETIONS = True
|
||
|
ASK_BEFORE_DELETE = False
|
||
|
|
||
|
###############################################################################################################
|
||
|
|
||
|
# Check path format
|
||
|
if (FROM_PATH[-1] != '/' or TO_PATH[-1] != '/'):
|
||
|
exit(1)
|
||
|
|
||
|
# Create library paths if not existence
|
||
|
try:
|
||
|
if (not os.path.exists(TO_PATH)):
|
||
|
os.makedirs(TO_PATH)
|
||
|
elif (os.path.isfile(TO_PATH)):
|
||
|
raise Exception("Directory is file?!")
|
||
|
except Exception as e:
|
||
|
exit(1)
|
||
|
|
||
|
|
||
|
# Create folders if not existing
|
||
|
def createFolder(subpath):
|
||
|
if (os.path.exists(TO_PATH + subpath) and os.path.isdir(TO_PATH + subpath)):
|
||
|
return True
|
||
|
try:
|
||
|
os.makedirs(TO_PATH + subpath)
|
||
|
return True
|
||
|
except Exception as e:
|
||
|
return False
|
||
|
|
||
|
|
||
|
# Escape the paths for the os.system
|
||
|
def escapePath(s):
|
||
|
return s.replace(" ", "\ ").replace(")", "\)").replace("(", "\(").replace("&", "\&").replace("'", "\\\'")
|
||
|
|
||
|
|
||
|
# Go through all files and convert
|
||
|
for root, dirs, files in os.walk(FROM_PATH, topdown=False):
|
||
|
subpath = root[len(FROM_PATH):] + "/"
|
||
|
|
||
|
if (createFolder(subpath)):
|
||
|
for name in files:
|
||
|
filename_without_extension = os.path.splitext(name)[0]
|
||
|
file_extension = os.path.splitext(name)[1][1:]
|
||
|
|
||
|
source_path_without_extension = FROM_PATH + subpath + filename_without_extension
|
||
|
converted_path_without_extension = TO_PATH + subpath + filename_without_extension
|
||
|
|
||
|
# Get command tripple - sure you can do this more efficient with a hashmap but there will only be a few entries
|
||
|
command_tripple = None
|
||
|
for tripple in COMMANDS:
|
||
|
if (tripple[0] == file_extension):
|
||
|
command_tripple = tripple
|
||
|
break
|
||
|
|
||
|
if (not command_tripple):
|
||
|
continue
|
||
|
|
||
|
source_path = source_path_without_extension + "." + command_tripple[0]
|
||
|
goal_path = converted_path_without_extension + "." + command_tripple[1]
|
||
|
if (os.path.isfile(source_path)):
|
||
|
# If goal file does not exists or is older than source
|
||
|
if (not os.path.exists(goal_path) or os.path.getctime(source_path) > os.path.getctime(goal_path)):
|
||
|
os.system(command_tripple[2].replace("[INPUT]", escapePath(source_path_without_extension)).replace(
|
||
|
"[OUTPUT]", escapePath(converted_path_without_extension)))
|
||
|
|
||
|
# Remove old files
|
||
|
if (SYNC_DELETIONS):
|
||
|
for root, dirs, files in os.walk(TO_PATH, topdown=False):
|
||
|
subpath = root[len(TO_PATH):] + "/"
|
||
|
|
||
|
for name in files:
|
||
|
filename_without_extension = os.path.splitext(name)[0]
|
||
|
file_extension = os.path.splitext(name)[1][1:]
|
||
|
|
||
|
source_path_without_extension = FROM_PATH + subpath + filename_without_extension
|
||
|
converted_path_without_extension = TO_PATH + subpath + filename_without_extension
|
||
|
|
||
|
original_exists = False
|
||
|
for tripple in COMMANDS:
|
||
|
if (tripple[1] == file_extension and os.path.exists(source_path_without_extension + "." + tripple[0])):
|
||
|
original_exists = True
|
||
|
break
|
||
|
|
||
|
if (not original_exists):
|
||
|
filepath_to_delete = escapePath(converted_path_without_extension) + "." + file_extension
|
||
|
os.system("rm " + ("-i " if ASK_BEFORE_DELETE else "") + filepath_to_delete)
|
||
|
|
||
|
# Remove old empty folders
|
||
|
for folder in dirs:
|
||
|
subpath = root[len(TO_PATH):] + "/"
|
||
|
if not os.path.exists(FROM_PATH + subpath + folder):
|
||
|
os.system("rmdir " + escapePath(TO_PATH + subpath + folder))
|