18 Commits

Author SHA1 Message Date
Jamie Hardt
88add2da85 Update pyproject.toml
Set explicit Trove descriptors for python version
2024-07-07 22:25:29 -07:00
Jamie Hardt
fd228493c6 Update README.md
Oops extra wheel badge
2024-07-07 22:22:55 -07:00
Jamie Hardt
11405ef06c Update pylint.yml
Added 3.12 to the test matrix
2024-07-07 22:22:00 -07:00
Jamie Hardt
229467c408 Update README.md
Added badges
2024-07-07 22:21:27 -07:00
Jamie Hardt
dc1c6cc742 Update pylint.yml
Tweaking
2024-07-07 22:16:46 -07:00
Jamie Hardt
d7a30275d1 Update pylint.yml
Added testing to the workflow
2024-07-07 22:15:07 -07:00
Jamie Hardt
61458660c9 pylint 2024-07-07 22:12:35 -07:00
Jamie Hardt
d286c4e6c7 Implemented some more tests 2024-07-07 22:11:40 -07:00
Jamie Hardt
8d299e2335 pylint 2024-07-07 15:21:24 -07:00
Jamie Hardt
e0431da6df Merge branch 'main' of https://github.com/iluvcapra/mfbatch 2024-07-07 15:15:14 -07:00
Jamie Hardt
d334181dc8 Test implementation 2024-07-07 15:15:01 -07:00
Jamie Hardt
0d765f9d84 Adding some tests 2024-07-07 14:40:52 -07:00
Jamie Hardt
ce6542b64d Updated version, gitignore 2024-07-07 13:50:23 -07:00
Jamie Hardt
5a47985154 Improved docs 2024-07-07 13:44:53 -07:00
Jamie Hardt
649427dd33 Made a fix that should work better 2024-07-07 13:44:10 -07:00
Jamie Hardt
21277aff15 Improved reset/key unset logic
Patterns and incrs are now unset as well
2024-07-07 13:42:24 -07:00
Jamie Hardt
1b044025ea Tweaked documentation 2024-07-07 13:35:55 -07:00
Jamie Hardt
2078c1559a Fixed bug in argparser help generation 2024-07-07 13:28:23 -07:00
7 changed files with 103 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
name: Pylint name: Lint and Test
on: [push] on: [push]
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.9", "3.10", "3.11", "3.12"]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
@@ -22,3 +22,7 @@ jobs:
- name: Analysing the code with pylint - name: Analysing the code with pylint
run: | run: |
pylint $(git ls-files '*.py') pylint $(git ls-files '*.py')
- name: Testing with unittest
run: |
python -m unittest tests

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.DS_Store .DS_Store
dist/ dist/
*.pyc *.pyc
poetry.lock

View File

@@ -1,3 +1,8 @@
![GitHub last commit](https://img.shields.io/github/last-commit/iluvcapra/mfbatch)
![](https://img.shields.io/github/license/iluvcapra/mfbatch.svg) ![](https://img.shields.io/pypi/pyversions/mfbatch.svg) [![](https://img.shields.io/pypi/v/mfbatch.svg)](https://pypi.org/project/mfbatch/) ![](https://img.shields.io/pypi/wheel/mfbatch.svg)
[![Lint and Test](https://github.com/iluvcapra/mfbatch/actions/workflows/pylint.yml/badge.svg)](https://github.com/iluvcapra/mfbatch/actions/workflows/pylint.yml)
# mfbatch # mfbatch
`mfbatch` is a command-line tool for batch-editing FLAC audio file metadata. `mfbatch` is a command-line tool for batch-editing FLAC audio file metadata.

View File

@@ -14,7 +14,7 @@ import inspect
from tqdm import tqdm from tqdm import tqdm
from mfbatch.util import readline_with_escaped_newlines from mfbatch.util import readline_with_escaped_newlines
import mfbatch.metaflac as flac import mfbatch.metaflac as metadata_funcs
from mfbatch.commands import BatchfileParser from mfbatch.commands import BatchfileParser
@@ -40,7 +40,7 @@ def create_batch_list(command_file: str, recursive=True):
flac_files = glob('./**/*.flac', recursive=recursive) flac_files = glob('./**/*.flac', recursive=recursive)
flac_files = sorted(flac_files) flac_files = sorted(flac_files)
for path in tqdm(flac_files, unit='File', desc='Scanning FLAC files'): for path in tqdm(flac_files, unit='File', desc='Scanning FLAC files'):
this_file_metadata = flac.read_metadata(path) this_file_metadata = metadata_funcs.read_metadata(path)
for this_key, this_value in this_file_metadata.items(): for this_key, this_value in this_file_metadata.items():
if this_key not in metadatums: if this_key not in metadatums:
f.write(f":set {this_key} " f.write(f":set {this_key} "
@@ -66,7 +66,8 @@ def main():
""" """
Entry point implementation Entry point implementation
""" """
op = ArgumentParser(usage="%prog (-c | -e | -W) [options]") op = ArgumentParser(
prog='mfbatch', usage='%(prog)s (-c | -e | -W) [options]')
op.add_argument('-c', '--create', default=False, op.add_argument('-c', '--create', default=False,
action='store_true', action='store_true',

View File

@@ -11,7 +11,7 @@ import os.path
from typing import Dict, Tuple, Optional from typing import Dict, Tuple, Optional
import mfbatch.metaflac as flac from mfbatch.metaflac import write_metadata as flac
class UnrecognizedCommandError(Exception): class UnrecognizedCommandError(Exception):
@@ -64,6 +64,18 @@ class CommandEnv:
self.incr.pop(k, None) self.incr.pop(k, None)
self.patterns.pop(k, None) self.patterns.pop(k, None)
def reset_keys(self):
"""
Reset all keys in the environment
"""
all_keys = list(self.metadatums.keys())
for key in all_keys:
self.unset_key(key)
self.patterns = {}
self.incr = {}
def set_pattern(self, to: str, frm: str, pattern: str, repl: str): def set_pattern(self, to: str, frm: str, pattern: str, repl: str):
""" """
Establish a pattern replacement in the environment Establish a pattern replacement in the environment
@@ -128,7 +140,7 @@ class BatchfileParser:
""" """
A batchfile is a text file of lines. Lines either begin with a '#' to denote a A batchfile is a text file of lines. Lines either begin with a '#' to denote a
comment, a ':' to denote a Command, and if neither of these are present, the comment, a ':' to denote a Command, and if neither of these are present, the
are interpreted as a file path to act upon. Empty lines are ignored. line is interpreted as a file path to act upon. Empty lines are ignored.
If a line ends with a backslash '\\', the backslash is deleted and the contents If a line ends with a backslash '\\', the backslash is deleted and the contents
of the following line are appended to the end of the present line. of the following line are appended to the end of the present line.
@@ -147,6 +159,7 @@ they appear in the batchfile.
def __init__(self): def __init__(self):
self.dry_run = True self.dry_run = True
self.env = CommandEnv() self.env = CommandEnv()
self.write_metadata_f = flac
def eval(self, line: str, lineno: int, interactive: bool): def eval(self, line: str, lineno: int, interactive: bool):
""" """
@@ -181,7 +194,7 @@ they appear in the batchfile.
print("DRY RUN would write metadata here.") print("DRY RUN would write metadata here.")
else: else:
sys.stdout.write("Writing metadata... ") sys.stdout.write("Writing metadata... ")
flac.write_metadata(line, self.env.metadatums) self.write_metadata_f(line, self.env.metadatums)
sys.stdout.write("Complete!") sys.stdout.write("Complete!")
self.env.increment_all() self.env.increment_all()
@@ -267,7 +280,7 @@ they appear in the batchfile.
""" """
reset reset
All keys in the environment will be reset, subsequent files will have All keys in the environment will be reset, subsequent files will have
no keys set. no keys set, including keys set by the `setinc` and `setp` commands.
""" """
all_keys = list(self.env.metadatums.keys()) all_keys = list(self.env.metadatums.keys())
for k in all_keys: for k in all_keys:

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "mfbatch" name = "mfbatch"
version = "0.4.0" version = "0.4.1"
description = "MetaFlac batch editor" description = "MetaFlac batch editor"
authors = ["Jamie Hardt <jamiehardt@me.com>"] authors = ["Jamie Hardt <jamiehardt@me.com>"]
readme = "README.md" readme = "README.md"
@@ -13,6 +13,10 @@ classifiers = [
'Environment :: Console', 'Environment :: Console',
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Topic :: Multimedia :: Sound/Audio :: Editors', 'Topic :: Multimedia :: Sound/Audio :: Editors',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.9',
] ]
[tool.poetry.dependencies] [tool.poetry.dependencies]

65
tests/__init__.py Normal file
View File

@@ -0,0 +1,65 @@
"mfbatch tests"
import unittest
from unittest.mock import MagicMock
from typing import cast
from mfbatch.commands import BatchfileParser
class BatchfileParserTests(unittest.TestCase):
"""
Tests the BatchfileParser class
"""
def setUp(self):
self.command_parser = BatchfileParser()
self.command_parser.dry_run = False
self.command_parser.write_metadata_f = MagicMock()
def tearDown(self):
pass
def test_set_without_write(self):
"Test setting a key without writing"
self.command_parser.set(['TYPE', 'Everything'])
self.assertFalse(cast(MagicMock,
self.command_parser.write_metadata_f).called)
self.assertEqual(self.command_parser.env.metadatums['TYPE'],
'Everything')
def test_set_command(self):
"Test set command"
self.command_parser.set(['X', 'Y'])
self.command_parser.eval("./testfile.flac", lineno=1,
interactive=False)
self.assertTrue(cast(MagicMock,
self.command_parser.write_metadata_f).called)
self.assertEqual(cast(MagicMock,
self.command_parser.write_metadata_f).call_args.args,
('./testfile.flac', {'X': 'Y'}))
def test_unset_command(self):
"Test unset command"
self.command_parser.set(['A', '1'])
self.assertEqual(self.command_parser.env.metadatums['A'], '1')
self.command_parser.unset(['A'])
self.assertNotIn('A', self.command_parser.env.metadatums.keys())
def test_setp(self):
"Test setp command"
self.command_parser.set(['VAL', 'ABC123'])
self.command_parser.setp(['DONE', 'VAL', r"([A-Z]+)123", r"X\1"])
self.command_parser.eval("./testfile.flac", lineno=1,
interactive=False)
self.assertTrue(cast(MagicMock,
self.command_parser.write_metadata_f).called)
self.assertEqual(cast(MagicMock,
self.command_parser.write_metadata_f).call_args.args,
("./testfile.flac", {'VAL': 'ABC123', 'DONE': 'XABC'}))
def test_eval(self):
"Test eval"
self.command_parser.eval(":set A 1", 1, False)
self.assertEqual(self.command_parser.env.metadatums['A'], '1')