format code
This commit is contained in:
parent
5272a3d356
commit
1c57673dc4
27
main.py
27
main.py
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
|
||||
from musicutil.commands.process_command import ProcessCommand
|
||||
from musicutil.commands.copy_command import CopyCommand
|
||||
|
||||
parser = argparse.ArgumentParser(description='Highly Opinionated Music ')
|
||||
subparsers = parser.add_subparsers(dest="subparser_name")
|
||||
|
||||
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')
|
||||
|
||||
copy_parser = subparsers.add_parser('copy')
|
||||
copy_parser.add_argument('src', type=str, help='src base music directory')
|
||||
copy_parser.add_argument('dest', type=str, help='dest music directory')
|
||||
copy_parser.add_argument('--transcode-level', type=str, help='transcode level', default="copy")
|
||||
copy_parser.add_argument('--skip-existing', action='store_true')
|
||||
copy_parser.add_argument('--single-directory', action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.subparser_name == "process":
|
||||
ProcessCommand(args.src, args.dry_run).run()
|
||||
elif args.subparser_name == "copy":
|
||||
CopyCommand(args.src, args.dest, args.transcode_level, args.single_directory, args.skip_existing).run()
|
52
musicutil/__main__.py
Normal file
52
musicutil/__main__.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
|
||||
from .commands.process_command import ProcessCommand
|
||||
from .commands.copy_command import CopyCommand
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="chaos's musicutil")
|
||||
subparsers = parser.add_subparsers(dest="subparser_name")
|
||||
|
||||
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')
|
||||
|
||||
copy_parser = subparsers.add_parser('copy')
|
||||
copy_parser.add_argument(
|
||||
'src',
|
||||
type=str,
|
||||
help='src base music directory')
|
||||
copy_parser.add_argument(
|
||||
'dest',
|
||||
type=str,
|
||||
help='dest music directory')
|
||||
copy_parser.add_argument(
|
||||
'--transcode-level',
|
||||
type=str,
|
||||
help='transcode level',
|
||||
default="copy")
|
||||
copy_parser.add_argument(
|
||||
'--skip-existing',
|
||||
action='store_true')
|
||||
copy_parser.add_argument(
|
||||
'--single-directory',
|
||||
action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.subparser_name == "process":
|
||||
ProcessCommand(args.src, args.dry_run).run()
|
||||
elif args.subparser_name == "copy":
|
||||
CopyCommand(
|
||||
args.src,
|
||||
args.dest,
|
||||
args.transcode_level,
|
||||
args.single_directory,
|
||||
args.skip_existing
|
||||
).run()
|
|
@ -8,10 +8,12 @@ from shutil import copy as copy_file
|
|||
from copy import deepcopy as deep_copy
|
||||
from subprocess import run as run_command
|
||||
|
||||
|
||||
class CopyCommandState:
|
||||
files: list[File] = []
|
||||
transcoded_files: list[File] = []
|
||||
|
||||
|
||||
class CopyCommand():
|
||||
def __init__(self,
|
||||
src: str,
|
||||
|
@ -65,7 +67,8 @@ class CopyCommand():
|
|||
|
||||
def _transcode_copy(self, file: File):
|
||||
src = file.join_path_to()
|
||||
dest = file.join_filename() if self.single_directory else file.join_path_from_src()
|
||||
dest = file.join_filename(
|
||||
) if self.single_directory else file.join_path_from_src()
|
||||
dest = self.dest + "/" + dest
|
||||
|
||||
exists = path_exists(dest)
|
||||
|
@ -77,7 +80,11 @@ class CopyCommand():
|
|||
dest,
|
||||
)
|
||||
else:
|
||||
print("Skipping", src, "as already is copied at", dest)
|
||||
print(
|
||||
"Skipping",
|
||||
src,
|
||||
"as already is copied at",
|
||||
dest)
|
||||
|
||||
self.state.transcoded_files.append(file)
|
||||
|
||||
|
@ -89,7 +96,8 @@ class CopyCommand():
|
|||
new_file = deep_copy(file)
|
||||
new_file.extension = transcoded_file_extension
|
||||
|
||||
dest_filepath = new_file.join_filename() if self.single_directory else new_file.join_path_from_src()
|
||||
dest_filepath = new_file.join_filename(
|
||||
) if self.single_directory else new_file.join_path_from_src()
|
||||
dest_filepath = self.dest + "/" + dest_filepath
|
||||
|
||||
if (self.skip_existing and path_exists(dest_filepath)):
|
||||
|
@ -135,7 +143,8 @@ class CopyCommand():
|
|||
for file in self.state.files:
|
||||
directories.add(file.path_from_src)
|
||||
for dir in directories:
|
||||
make_directories(self.dest + "/" + dir, exist_ok=True)
|
||||
make_directories(
|
||||
self.dest + "/" + dir, exist_ok=True)
|
||||
|
||||
if self.transcode_level == "copy":
|
||||
for file in self.state.files:
|
||||
|
@ -143,5 +152,5 @@ class CopyCommand():
|
|||
return
|
||||
elif self.transcode_level in ["high", "medium", "low"]:
|
||||
for file in self.state.files:
|
||||
self._transcode_with_level(file, self.transcode_level)
|
||||
|
||||
self._transcode_with_level(
|
||||
file, self.transcode_level)
|
||||
|
|
|
@ -6,9 +6,11 @@ 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 ProcessCommand():
|
||||
def __init__(self, src: str, dry_run: bool):
|
||||
self.src = src
|
||||
|
@ -32,22 +34,25 @@ class ProcessCommand():
|
|||
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}")
|
||||
proper_filename = reduce_to_ascii_and_substitute(
|
||||
f"{artist} - {title}")
|
||||
|
||||
if filename != proper_filename:
|
||||
print(f"Renaming \"{filename}\"", "to" + f"\"{proper_filename}\"" + "\n")
|
||||
print(f"Renaming \"{filename}\"", "to" +
|
||||
f"\"{proper_filename}\"" + "\n")
|
||||
|
||||
new_file = deep_copy(file)
|
||||
new_file.filename = proper_filename
|
||||
|
||||
if not self.dry_run:
|
||||
rename_file(file.join_path_to(), new_file.join_path_to())
|
||||
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
|
||||
|
@ -59,4 +64,5 @@ class ProcessCommand():
|
|||
|
||||
for file in self.state.files:
|
||||
index = self.state.files.index(file)
|
||||
self.state.files[index] = self._rename_file(file)
|
||||
self.state.files[index] = self._rename_file(
|
||||
file)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# All file extensions that are supported and have tag
|
||||
# extraction
|
||||
supported_formats = ["mp3", "flac"]
|
||||
|
||||
sub_char = "_"
|
||||
|
|
|
@ -11,6 +11,7 @@ class Tags:
|
|||
def __repr__(self):
|
||||
return repr(self.to_dict())
|
||||
|
||||
|
||||
class File:
|
||||
filename = ""
|
||||
extension = ""
|
||||
|
|
|
@ -3,6 +3,7 @@ from ..types import File, Tags
|
|||
from mutagen.mp3 import EasyMP3 as MP3
|
||||
from mutagen.flac import FLAC
|
||||
|
||||
|
||||
def load_tag_information(file: File) -> Tags:
|
||||
path = file.join_path_to()
|
||||
tags = Tags()
|
||||
|
|
|
@ -4,13 +4,15 @@ from os.path import relpath
|
|||
from ..types import File
|
||||
from ..meta import supported_formats
|
||||
|
||||
|
||||
def scan_for_music(src: str) -> list[File]:
|
||||
files: list[File] = []
|
||||
for format in supported_formats:
|
||||
for path in Path(src).rglob("*." + format):
|
||||
file = File()
|
||||
file.path_to = str(path.parent)
|
||||
file.path_from_src = relpath(str(path.parent), src)
|
||||
file.path_from_src = relpath(
|
||||
str(path.parent), src)
|
||||
file.filename = path.stem
|
||||
file.extension = path.suffix.replace(".", "")
|
||||
files.append(file)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
from ..meta import sub_char, substitutions
|
||||
from fold_to_ascii import fold
|
||||
|
||||
|
||||
def reduce_to_ascii_and_substitute(filename: str):
|
||||
filename = filename.replace("/", sub_char)
|
||||
filename = filename.replace("\\", sub_char)
|
||||
filename = filename.replace("\n", "")
|
||||
for sub_before in substitutions.keys():
|
||||
filename = filename.replace(sub_before, substitutions[sub_before])
|
||||
filename = filename.replace(
|
||||
sub_before, substitutions[sub_before])
|
||||
filename = fold(filename)
|
||||
return filename
|
||||
|
|
5
pyproject.toml
Normal file
5
pyproject.toml
Normal file
|
@ -0,0 +1,5 @@
|
|||
[tool.autopep8]
|
||||
max_line_length = 60
|
||||
in-place = true
|
||||
recursive = true
|
||||
aggressive = 3
|
|
@ -2,6 +2,6 @@
|
|||
let
|
||||
fold-to-ascii = (py: py.callPackage ./nix-extra-deps/fold-to-ascii.nix { });
|
||||
my_python = pkgs.python39.withPackages
|
||||
(py: with py; [ py.mutagen (fold-to-ascii py) ]);
|
||||
(py: with py; [ py.mutagen (fold-to-ascii py) py.autopep8 ]);
|
||||
|
||||
in pkgs.mkShell { packages = with pkgs; [ my_python ffmpeg ]; }
|
||||
|
|
Loading…
Reference in a new issue