113 lines
3.2 KiB
Python
113 lines
3.2 KiB
Python
from musicutil.utils.do_replaygain import do_replaygain
|
|
from ..types import File
|
|
from ..utils.scan_for_music import scan_for_music
|
|
from ..utils.load_tag_information import load_tag_information
|
|
from ..utils.substitutions import reduce_to_ascii_and_substitute
|
|
|
|
from copy import deepcopy as deep_copy
|
|
from os import rename as rename_file
|
|
|
|
|
|
class ProcessCommandState:
|
|
files: list[File] = []
|
|
|
|
|
|
class ProcessCommandArgs:
|
|
src: str
|
|
dry_run: bool
|
|
replaygain: str
|
|
|
|
def add_process_command(subparsers):
|
|
process_parser = subparsers.add_parser('process')
|
|
process_parser.add_argument(
|
|
'src',
|
|
type=str,
|
|
help='src base music directory')
|
|
process_parser.add_argument(
|
|
'--dry-run', action='store_true')
|
|
process_parser.add_argument(
|
|
'--replaygain',
|
|
type=str,
|
|
default="skip_existing",
|
|
help="skip,skip_existing,force"
|
|
)
|
|
|
|
|
|
def get_process_args(args) -> ProcessCommandArgs:
|
|
command_args = ProcessCommandArgs()
|
|
command_args.src = args.src
|
|
command_args.dry_run = args.dry_run
|
|
command_args.replaygain = args.replaygain
|
|
return command_args
|
|
|
|
|
|
class ProcessCommand():
|
|
def __init__(self, args: ProcessCommandArgs):
|
|
self.args = args
|
|
self.state = ProcessCommandState()
|
|
|
|
def run(self):
|
|
print("Renaming")
|
|
self.scan_for_music()
|
|
self.load_tag_information()
|
|
self.rename_files()
|
|
if not self.args.dry_run:
|
|
if self.args.replaygain != "skip":
|
|
self.add_replaygain_tags()
|
|
|
|
def scan_for_music(self):
|
|
print("Scanning For Music")
|
|
self.state.files = scan_for_music(self.args.src)
|
|
|
|
def load_tag_information(self):
|
|
print("Loading Tag Information")
|
|
|
|
for file in self.state.files:
|
|
tags = load_tag_information(file)
|
|
file.tags = tags
|
|
|
|
def _rename_file(self, file: File) -> File:
|
|
filename = file.filename
|
|
artist = file.tags.artist.replace("\n", "")
|
|
title = file.tags.title.replace("\n", "")
|
|
|
|
proper_filename = reduce_to_ascii_and_substitute(
|
|
f"{artist} - {title}")
|
|
|
|
if filename != proper_filename:
|
|
print(f"Renaming \"{filename}\"", "to " +
|
|
f"\"{proper_filename}\"" + "\n")
|
|
|
|
new_file = deep_copy(file)
|
|
new_file.filename = proper_filename
|
|
|
|
if not self.args.dry_run:
|
|
rename_file(
|
|
file.join_path_to(),
|
|
new_file.join_path_to())
|
|
# so that other steps after read the new file and not
|
|
# the orig pre-rename file when not dry run
|
|
return new_file
|
|
else:
|
|
return file
|
|
|
|
def rename_files(self):
|
|
print("Renaming files")
|
|
|
|
for file in self.state.files:
|
|
index = self.state.files.index(file)
|
|
self.state.files[index] = self._rename_file(
|
|
file)
|
|
|
|
def add_replaygain_tags(self):
|
|
print("Adding ReplayGain Tags")
|
|
|
|
for file in self.state.files:
|
|
if self.args.replaygain == "skip_existing":
|
|
if file.tags.has_replaygain:
|
|
continue
|
|
print(
|
|
f"Adding ReplayGain Tags to \"{file.filename}.{file.extension}\"")
|
|
|
|
do_replaygain(file)
|