diff --git a/eyed3/plugins/jsontag.py b/eyed3/plugins/jsontag.py index 52b76d77..69a9f891 100644 --- a/eyed3/plugins/jsontag.py +++ b/eyed3/plugins/jsontag.py @@ -1,7 +1,9 @@ import base64 import inspect +import dataclasses from json import dumps +import eyed3.core import eyed3.plugins import eyed3.id3.tag import eyed3.id3.headers @@ -33,14 +35,10 @@ def handleFile(self, f, *args, **kwargs): def audioFileToJson(audio_file): tag = audio_file.tag - tdict = {"path": audio_file.path} - - info = {"time_secs": int(audio_file.info.time_secs * 100.0) / 100.0, - "size_bytes": int(audio_file.info.size_bytes)} - tdict["info"] = info + tdict = dict(path=audio_file.path, info=dataclasses.asdict(audio_file.info)) # Tag fields - for name in [m for m in dir(tag) if not m.startswith("_") and m not in _tag_exclusions]: + for name in [m for m in sorted(dir(tag)) if not m.startswith("_") and m not in _tag_exclusions]: member = getattr(tag, name) if name not in _tag_map: @@ -63,6 +61,9 @@ def audioFileToJson(audio_file): tdict[name] = base64.b64encode(member).decode("ascii") elif isinstance(member, eyed3.id3.tag.ArtistOrigin): ... # TODO + elif isinstance(member, (eyed3.core.CountAndTotalTuple,)): + if any(member): + tdict[name] = member._asdict() elif isinstance(member, (list, tuple)): ... # TODO elif isinstance(member, eyed3.id3.tag.AccessorBase): @@ -95,7 +96,7 @@ def audioFileToJson(audio_file): 'commercial_url': str, 'composer': str, 'copyright_url': str, - 'disc_num': tuple, + 'disc_num': eyed3.core.CountAndTotalTuple, 'encoding_date': eyed3.core.Date, 'extended_header': eyed3.id3.headers.ExtendedTagHeader, 'file_info': eyed3.id3.tag.FileInfo, @@ -120,7 +121,7 @@ def audioFileToJson(audio_file): 'tagging_date': eyed3.core.Date, 'terms_of_use': str, 'title': str, - 'track_num': tuple, + 'track_num': eyed3.core.CountAndTotalTuple, 'unique_file_ids': eyed3.id3.tag.UniqueFileIdAccessor, 'user_text_frames': eyed3.id3.tag.UserTextsAccessor, 'user_url_frames': eyed3.id3.tag.UserUrlsAccessor, diff --git a/tests/test_jsonyaml_plugin.py b/tests/test_jsonyaml_plugin.py new file mode 100644 index 00000000..1565ec0d --- /dev/null +++ b/tests/test_jsonyaml_plugin.py @@ -0,0 +1,76 @@ +import os +import stat +from eyed3 import main, version +from . import RedirectStdStreams + +def _initTag(afile): + afile.initTag() + afile.tag.artist = "Bad Religion" + afile.tag.title = "Suffer" + afile.tag.album = "Suffer" + afile.tag.release_date = "1988" + afile.tag.recording_date = "1987" + afile.tag.track_num = (9, 15) + afile.tag.save() + +def _runPlugin(afile, plugin) -> str: + with RedirectStdStreams() as plugin_out: + args, _, config = main.parseCommandLine(["-P", plugin, str(afile.path)]) + assert main.main(args, config) == 0 + + stdout = plugin_out.stdout.read().strip() + print(stdout) + return stdout + + +def _assertFormat(plugin: str, audio_file, format: str): + output = _runPlugin(audio_file, plugin) + print(output) + size_bytes = os.stat(audio_file.path)[stat.ST_SIZE] + assert output.strip() == format.strip() % dict(path=audio_file.path, version=version, + size_bytes=size_bytes) + + +def testJsonPlugin(audiofile): + _initTag(audiofile) + _assertFormat("json", audiofile, """ +{ + "path": "%(path)s", + "info": { + "time_secs": 10.68, + "size_bytes": %(size_bytes)d + }, + "album": "Suffer", + "artist": "Bad Religion", + "best_release_date": "1988", + "recording_date": "1987", + "release_date": "1988", + "title": "Suffer", + "track_num": { + "count": 9, + "total": 15 + }, + "_eyeD3": "%(version)s" +} +""") + + +def testYamlPlugin(audiofile): + _initTag(audiofile) + _assertFormat("yaml", audiofile, """ +--- +_eyeD3: %(version)s +album: Suffer +artist: Bad Religion +best_release_date: '1988' +info: + size_bytes: %(size_bytes)d + time_secs: 10.68 +path: %(path)s +recording_date: '1987' +release_date: '1988' +title: Suffer +track_num: + count: 9 + total: 15 +""")