mirror of
https://github.com/iluvcapra/mfbatch.git
synced 2025-12-31 08:50:51 +00:00
First commit of sources
This commit is contained in:
2
mfbatch/__init__.py
Normal file
2
mfbatch/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# mybatch
|
||||||
|
# FLAC Metadata batch editor
|
||||||
165
mfbatch/__main__.py
Normal file
165
mfbatch/__main__.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# __main__.py
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from subprocess import run
|
||||||
|
import os
|
||||||
|
from glob import iglob
|
||||||
|
from re import match
|
||||||
|
from optparse import OptionParser
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
# MFBATCH COMMAND FILE
|
||||||
|
# Every line is processed, the first character decides the kind of command
|
||||||
|
# in the style of mtree.
|
||||||
|
# [a-z] Line is a command
|
||||||
|
# : Line is a file
|
||||||
|
# # is a comment
|
||||||
|
|
||||||
|
# Commands are:
|
||||||
|
# set KEY REST
|
||||||
|
# KEY in each subsequent file is set to REST.
|
||||||
|
# unset KEY
|
||||||
|
# KEY in each subsequent file will be unset.
|
||||||
|
# unset-all
|
||||||
|
# No keys in each subsequent file will be set.
|
||||||
|
# set-incr KEY INITIAL
|
||||||
|
# KEY in next file will be set to INITIAL which will be incremented by
|
||||||
|
# one for each file processed.
|
||||||
|
# set-pattern TO FROM PATTERN
|
||||||
|
# Set key TO to FROM after matching against PATTERN in each subsequent
|
||||||
|
# file.
|
||||||
|
# rename ARGUMENTS
|
||||||
|
# Subsequent files will be renamed using rename(1). ARGUMENTS will be
|
||||||
|
# passed to the command with the old name at the end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
METAFLAC_PATH = '/opt/homebrew/bin/metaflac'
|
||||||
|
COMMAND_PROCHAR = ':'
|
||||||
|
COMMENT_PROCHAR = '#'
|
||||||
|
|
||||||
|
def process_command(metadatums: dict, line: str, dry_run: bool):
|
||||||
|
commandline = line.lstrip(COMMAND_PROCHAR).rstrip("\n")
|
||||||
|
args = shlex.split(commandline)
|
||||||
|
command = args[0]
|
||||||
|
|
||||||
|
if command == 'set':
|
||||||
|
key = args[1]
|
||||||
|
value = args[2]
|
||||||
|
metadatums[key] = value
|
||||||
|
|
||||||
|
elif command == 'unset':
|
||||||
|
key = args[1]
|
||||||
|
del metadatums[key]
|
||||||
|
|
||||||
|
elif command == 'unset-all':
|
||||||
|
all_keys = list(metadatums.keys())
|
||||||
|
for k in all_keys:
|
||||||
|
del metadatums[k]
|
||||||
|
|
||||||
|
elif command == 'set-incr':
|
||||||
|
pass
|
||||||
|
elif command == 'set-pattern':
|
||||||
|
pass
|
||||||
|
elif command == 'rename':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
sys.stderr.write(f"Unrecognized command line: {line}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def process_file(metadatums: dict, line: str, dry_run: bool):
|
||||||
|
line = line.rstrip("\n")
|
||||||
|
if dry_run:
|
||||||
|
sys.stderr.write(f"process_file: {line}\n")
|
||||||
|
sys.stderr.write(f"process_file: {metadatums}\n")
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def execute_batch_list(batch_list_path: str, dry_run: bool):
|
||||||
|
with open(batch_list_path, mode='r') as f:
|
||||||
|
metadatums = {}
|
||||||
|
while True:
|
||||||
|
line = f.readline()
|
||||||
|
if line is None or line == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
if line.startswith(COMMENT_PROCHAR):
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif line.startswith(COMMAND_PROCHAR):
|
||||||
|
process_command(metadatums, line, dry_run)
|
||||||
|
|
||||||
|
elif line == "\n":
|
||||||
|
continue
|
||||||
|
|
||||||
|
else:
|
||||||
|
process_file(metadatums, line, dry_run)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
editor = os.getenv('EDITOR')
|
||||||
|
|
||||||
|
op = OptionParser(usage="%prog [options]")
|
||||||
|
op.add_option('-d', metavar='DIR',
|
||||||
|
help='chdir to DIR before running',
|
||||||
|
default=None)
|
||||||
|
op.add_option('-e', metavar='EDITOR',
|
||||||
|
help="Set editor (default is $EDITOR)",
|
||||||
|
default=editor)
|
||||||
|
op.add_option('-f', metavar='FILE',
|
||||||
|
help="Write batch list file to FILE",
|
||||||
|
default='MFBATCH_LIST')
|
||||||
|
options, args = op.parse_args()
|
||||||
|
|
||||||
|
if options.d is not None:
|
||||||
|
os.chdir(options.d)
|
||||||
|
|
||||||
|
command_file = options.f
|
||||||
|
|
||||||
|
with open(command_file, mode='w') as f:
|
||||||
|
f.write("# mfbatch\n\n")
|
||||||
|
metaflac_command = [METAFLAC_PATH, '--list']
|
||||||
|
metadatums = {}
|
||||||
|
preflight = len(list(iglob('./**/*.flac', recursive=True)))
|
||||||
|
for path in tqdm(iglob('./**/*.flac', recursive=True), total=preflight):
|
||||||
|
result = run(metaflac_command + [path], capture_output=True)
|
||||||
|
this_file_metadata = {}
|
||||||
|
for line in result.stdout.decode('utf-8').splitlines():
|
||||||
|
m = match(r'^\s+comment\[\d\]: ([A-Z]+)=(.*)$', line)
|
||||||
|
if m is not None:
|
||||||
|
this_file_metadata[m[1]] = m[2]
|
||||||
|
|
||||||
|
for this_key in this_file_metadata.keys():
|
||||||
|
if this_key not in metadatums:
|
||||||
|
f.write(f":set {this_key} {shlex.quote(this_file_metadata[this_key])}\n")
|
||||||
|
metadatums[this_key] = this_file_metadata[this_key]
|
||||||
|
else:
|
||||||
|
if this_file_metadata[this_key] != metadatums[this_key]:
|
||||||
|
f.write(f":set {this_key} {shlex.quote(this_file_metadata[this_key])}\n")
|
||||||
|
metadatums[this_key] = this_file_metadata[this_key]
|
||||||
|
|
||||||
|
keys = list(metadatums.keys())
|
||||||
|
for key in keys:
|
||||||
|
if key not in this_file_metadata.keys():
|
||||||
|
f.write(f":unset {key}\n")
|
||||||
|
del metadatums[key]
|
||||||
|
|
||||||
|
f.write(path + "\n\n")
|
||||||
|
|
||||||
|
# list_stat = os.stat(command_file)
|
||||||
|
|
||||||
|
editor_command = [options.e, command_file]
|
||||||
|
run(editor_command)
|
||||||
|
|
||||||
|
execute_batch_list(command_file, dry_run=True)
|
||||||
|
|
||||||
|
# new_stat = os.stat(command_file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
15
pyproject.toml
Normal file
15
pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "mfbatch"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "MetaFlac batch editor"
|
||||||
|
authors = ["Jamie Hardt <jamiehardt@me.com>"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.9"
|
||||||
|
tqdm = "^4.66.4"
|
||||||
|
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
Reference in New Issue
Block a user