audiometa-python 1.3.0__tar.gz → 1.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {audiometa_python-1.3.0/audiometa_python.egg-info → audiometa_python-1.3.3}/PKG-INFO +3 -1
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/README.md +2 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_MetadataManager.py +5 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_Id3v2Manager.py +3 -12
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/vorbis/_VorbisManager.py +48 -0
- audiometa_python-1.3.3/audiometa/test/tests/integration/metadata_field/disc_number/test_reading.py +191 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/track_number/reading/test_edge_cases.py +28 -15
- audiometa_python-1.3.3/audiometa/test/tests/integration/metadata_field/track_number/reading/test_metadata_format.py +76 -0
- audiometa_python-1.3.3/audiometa/test/tests/unit/utils/test_disc_number_read.py +66 -0
- audiometa_python-1.3.3/audiometa/utils/disc_number_read.py +30 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3/audiometa_python.egg-info}/PKG-INFO +3 -1
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa_python.egg-info/SOURCES.txt +2 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/pyproject.toml +3 -1
- audiometa_python-1.3.0/audiometa/test/tests/integration/metadata_field/disc_number/test_reading.py +0 -92
- audiometa_python-1.3.0/audiometa/test/tests/integration/metadata_field/track_number/reading/test_metadata_format.py +0 -32
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/LICENSE +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/__main__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/_audio_file.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/cli.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/exceptions.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/_RatingSupportingMetadataManager.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_id3v1_preserver.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_id3v2_constants.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_id3v2_flac_handler.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_id3v2_reader.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/id3v2/_id3v2_writer.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/_RiffManager.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/_riff_bext_chunk.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/_riff_constants.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/_riff_file_structure.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/riff/_riff_info_chunk.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/vorbis/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/_rating_supporting/vorbis/_vorbis_constants.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/id3v1/_Id3v1Manager.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/id3v1/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/id3v1/_constants.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/id3v1/id3v1_raw_metadata.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/manager/id3v1/id3v1_raw_metadata_key.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/assets/create_test_files.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/common/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/common/audio_file_creator.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/common/external_tool_runner.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v1/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v1/id3v1_header_verifier.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v1/id3v1_metadata_deleter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v1/id3v1_metadata_getter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v1/id3v1_metadata_setter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/id3v2_frame_manual_creator.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/id3v2_header_verifier.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/id3v2_metadata_deleter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/id3v2_metadata_getter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/id3v2/id3v2_metadata_setter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/riff_header_verifier.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/riff_manual_metadata_creator.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/riff_metadata_deleter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/riff_metadata_getter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/riff/riff_metadata_setter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/scripts/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/technical_info_inspector.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/temp_file_with_metadata.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/vorbis/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/vorbis/vorbis_header_verifier.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/vorbis/vorbis_metadata_deleter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/vorbis/vorbis_metadata_getter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/helpers/vorbis/vorbis_metadata_setter.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/conftest.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_command_structure_errors.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_file_access_errors.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_format_output_errors.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_input_validation_errors.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_missing_fields_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_multiple_files_errors.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_rating_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/error_handling/test_year_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_basic.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_comprehensive.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_formats.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_metadata_content.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_multiple_files.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_options.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/read/test_unified.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/test_delete.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/test_formatting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/test_help.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_basic.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_comprehensive.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_force_format.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_integer_fields.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_list_fields.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_rating.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_string_fields.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/cli/write/test_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/scenarios/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/scenarios/test_user_scenarios.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/test_core_workflows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/test_deletion_workflows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/test_error_handling_workflows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/test_format_specific_workflows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/e2e/workflows/test_rating_workflows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/flac/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/flac/test_flac_delete_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/flac/test_flac_reading_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/flac/test_flac_reading_field.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/flac/test_flac_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/mp3/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_delete_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_field.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/wav/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/wav/test_wav_delete_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/wav/test_wav_reading_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/wav/test_wav_reading_field.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/audio_format/wav/test_wav_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/conftest.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/delete_all_metadata/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/delete_all_metadata/test_audio_format_all.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/delete_all_metadata/test_audio_format_header_deletion.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/delete_all_metadata/test_basic_functionality.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/delete_all_metadata/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/encoding/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/encoding/test_encoding.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/encoding/test_special_characters_edge_cases.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/options/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/options/test_include_headers.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/options/test_include_technical.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_audio_formats.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_binary_data_filtering.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_consistency.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_edge_cases.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_get_full_metadata.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_performance.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_raw_metadata_includes_unsupported_tags.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_riff_bext.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/get_full_metadata/test_structure.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album_artists/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album_artists/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album_artists/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/album_artists/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/artists/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/artists/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/artists/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/artists/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/bpm/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/bpm/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/bpm/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/bpm/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/comment/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/comment/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/comment/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/comment/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/composer/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/composer/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/composer/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/composer/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/copyright/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/copyright/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/copyright/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/copyright/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/description/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/description/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/description/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/description/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/disc_number/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/disc_number/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/disc_number/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/field_not_supported/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v1_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v2_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_riff_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_vorbis_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/reading/test_smart_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/genre/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/isrc/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/isrc/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/isrc/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/isrc/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/language/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/language/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/language/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/language/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/lyrics/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/lyrics/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/lyrics/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/lyrics/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/originator/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/originator/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/originator/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/originator/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/publisher/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/publisher/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/publisher/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/publisher/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_100_proportional.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_non_proportional.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_proportional.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_id3v2.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/rating/writing/test_comprehensive.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/release_date/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/release_date/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/release_date/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/release_date/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/release_date/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/test_metadata_field_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/title/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/title/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/title/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/title/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/title/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/track_number/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/track_number/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/track_number/test_deleting.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/metadata_field/track_number/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v1.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_3.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_4.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/test_performance_large_data.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/test_smart_parsing_scenarios.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/reading/test_unicode_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v1.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_3.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_4.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/multiple_values/writing/test_large_values.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/reading/test_read_multiple_metadata.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/reading/test_reading_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/real_audio_files/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/real_audio_files/test_reading.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/real_audio_files/test_writing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/conftest.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_audio_data_corruption.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_file.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_invalid_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_invalid_with_metadata_combinations.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_state_precedence.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_unset_with_metadata_combinations.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_fails_with_id3v1.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_with_id3v2_only.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_works_without_id3v1.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_with_metadata_combinations.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_unset_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_delete_original.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_flipped_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_partial_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_random_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_md5_repair_with_metadata.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_non_flac_error.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_unset_md5.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/test_bitrate.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/test_channels.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/test_duration_in_sec.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/technical_info/test_sample_rate.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/test_audio_file.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/test_audio_format_readable_after_update_all_metadata_formats.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/test_forced_format.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/test_multiple_format_preservation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/test_partial_update.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_flac_sync.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_mp3_sync.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_wav_sync.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/test_cleanup_strategy.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/test_preserve_strategy.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_fail_behavior.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_no_writing_on_failure.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_strategy_specific.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_bitrate.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_channels.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_duration_in_sec.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_error_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_file_size.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_format_name.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/technical_info/test_sample_rate.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/test_context_manager.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/test_file_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/test_is_audio_file.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/test_operations.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/audio_file/test_path_handling.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/cli/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/cli/test_cli_colorize.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/cli/test_expand_file_patterns.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/conftest.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/test_id3v1.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/test_id3v2.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/test_riff.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/test_riff_info_chunk_fourcc.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/header_info/test_vorbis.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/disc_number/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/disc_number/test_disc_number_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/test_isrc_format_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/test_isrc_type_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/test_smart_parsing.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_separator_selection.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_value_filtering.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/test_musicbrainz_artistid_format_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/test_musicbrainz_artistid_type_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/test_musicbrainz_trackid_format_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/test_musicbrainz_trackid_type_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_uuid/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_uuid/test_uuid_format_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_normalization.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_profiles_values.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/test_rating_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_configuration_error.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_writing_profiles.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/release_date/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/release_date/test_date_format_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/test_type_validation_exception.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/test_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/test_track_number_validation.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/test_metadata_format_managers_write_and_read.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/metadata_managers/test_riff_configuration_error.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/utils/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/test/tests/unit/utils/test_raw_metadata_sanitizer.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/flac_md5_state.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/id3v1_genre_code_map.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/metadata_format.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/metadata_writing_strategy.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/mutagen_exception_handler.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/__init__.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/base.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/config.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/macos.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/ubuntu.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/os_dependencies_checker/windows.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/rating_profiles.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/raw_metadata_sanitizer.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/tool_path_resolver.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/types.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa/utils/unified_metadata_key.py +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa_python.egg-info/dependency_links.txt +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa_python.egg-info/entry_points.txt +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa_python.egg-info/requires.txt +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/audiometa_python.egg-info/top_level.txt +0 -0
- {audiometa_python-1.3.0 → audiometa_python-1.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: audiometa-python
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: A comprehensive Python library for reading and writing audio metadata across multiple formats
|
|
5
5
|
Author: AudioMeta Python Contributors
|
|
6
6
|
Author-email: Andreas Garcia <garcia.andreas.1991@gmail.com>
|
|
@@ -55,6 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
|
|
56
56
|
A powerful, unified Python library for reading and writing audio metadata across multiple formats. AudioMeta supports MP3, FLAC, and WAV audio files, working seamlessly with ID3v1, ID3v2, Vorbis, and RIFF metadata formats through a single, consistent API.
|
|
57
57
|
|
|
58
|
+
**Try it**: A demo web app is available at [audiometa.themusictree.org](https://audiometa.themusictree.org).
|
|
59
|
+
|
|
58
60
|
**Author**: [Andreas Garcia](https://github.com/BehindTheMusicTree)
|
|
59
61
|
|
|
60
62
|
## ⭐ Show Your Support
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
A powerful, unified Python library for reading and writing audio metadata across multiple formats. AudioMeta supports MP3, FLAC, and WAV audio files, working seamlessly with ID3v1, ID3v2, Vorbis, and RIFF metadata formats through a single, consistent API.
|
|
15
15
|
|
|
16
|
+
**Try it**: A demo web app is available at [audiometa.themusictree.org](https://audiometa.themusictree.org).
|
|
17
|
+
|
|
16
18
|
**Author**: [Andreas Garcia](https://github.com/BehindTheMusicTree)
|
|
17
19
|
|
|
18
20
|
## ⭐ Show Your Support
|
|
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, TypeVar, Union, cast
|
|
|
5
5
|
from mutagen._file import FileType as MutagenMetadata
|
|
6
6
|
|
|
7
7
|
from audiometa.exceptions import InvalidMetadataFieldFormatError, InvalidMetadataFieldTypeError
|
|
8
|
+
from audiometa.utils.disc_number_read import parse_disc_number_from_combined_str
|
|
8
9
|
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
@@ -698,6 +699,10 @@ class _MetadataManager:
|
|
|
698
699
|
return track_str
|
|
699
700
|
return None
|
|
700
701
|
|
|
702
|
+
# DISCNUMBER / TPOS-style "n", "n/m", "n-m" (formats using the base read path)
|
|
703
|
+
if unified_metadata_key == UnifiedMetadataKey.DISC_NUMBER:
|
|
704
|
+
return parse_disc_number_from_combined_str(str(value[0]))
|
|
705
|
+
|
|
701
706
|
from typing import get_args, get_origin
|
|
702
707
|
|
|
703
708
|
origin = get_origin(unified_metadata_key_optional_type)
|
|
@@ -30,6 +30,7 @@ from mutagen.id3._frames import (
|
|
|
30
30
|
)
|
|
31
31
|
from mutagen.id3._util import ID3NoHeaderError
|
|
32
32
|
|
|
33
|
+
from audiometa.utils.disc_number_read import parse_disc_number_from_combined_str, parse_disc_total_from_combined_str
|
|
33
34
|
from audiometa.utils.raw_metadata_sanitizer import sanitize_id3v2_raw_info
|
|
34
35
|
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
35
36
|
|
|
@@ -415,12 +416,7 @@ class _Id3v2Manager(_RatingSupportingMetadataManager):
|
|
|
415
416
|
if tpos_value is None or len(tpos_value) == 0:
|
|
416
417
|
return None
|
|
417
418
|
tpos_str = str(tpos_value[0])
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
match = re.match(r"^(\d+)(?:/(\d+))?$", tpos_str)
|
|
421
|
-
if match:
|
|
422
|
-
return int(match.group(1))
|
|
423
|
-
return None
|
|
419
|
+
return parse_disc_number_from_combined_str(tpos_str)
|
|
424
420
|
if unified_metadata_key == UnifiedMetadataKey.DISC_TOTAL:
|
|
425
421
|
tpos_key = self.Id3TextFrame.DISC_NUMBER
|
|
426
422
|
if tpos_key not in raw_clean_metadata:
|
|
@@ -429,12 +425,7 @@ class _Id3v2Manager(_RatingSupportingMetadataManager):
|
|
|
429
425
|
if tpos_value is None or len(tpos_value) == 0:
|
|
430
426
|
return None
|
|
431
427
|
tpos_str = str(tpos_value[0])
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
match = re.match(r"^(\d+)/(\d+)$", tpos_str)
|
|
435
|
-
if match:
|
|
436
|
-
return int(match.group(2))
|
|
437
|
-
return None
|
|
428
|
+
return parse_disc_total_from_combined_str(tpos_str)
|
|
438
429
|
msg = f"Metadata key not handled: {unified_metadata_key}"
|
|
439
430
|
raise MetadataFieldNotSupportedByMetadataFormatError(msg)
|
|
440
431
|
|
|
@@ -6,6 +6,11 @@ from typing import TYPE_CHECKING, Any, TypeVar, cast
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from ...._audio_file import _AudioFile
|
|
8
8
|
from ....exceptions import FileCorruptedError, InvalidRatingValueError, MetadataFieldNotSupportedByMetadataFormatError
|
|
9
|
+
from ....utils.disc_number_read import (
|
|
10
|
+
parse_disc_number_from_combined_str,
|
|
11
|
+
parse_disc_total_from_combined_str,
|
|
12
|
+
parse_explicit_non_negative_disctotal,
|
|
13
|
+
)
|
|
9
14
|
from ....utils.rating_profiles import RatingWriteProfile
|
|
10
15
|
from ....utils.raw_metadata_sanitizer import sanitize_vorbis_raw_info
|
|
11
16
|
from ....utils.tool_path_resolver import get_tool_path
|
|
@@ -260,6 +265,49 @@ class _VorbisManager(_RatingSupportingMetadataManager):
|
|
|
260
265
|
# Cast to RawMetadataDict since RawMetadataKey is str, Enum and string keys work
|
|
261
266
|
self.raw_clean_metadata_uppercase_keys = cast(RawMetadataDict, result_dict)
|
|
262
267
|
|
|
268
|
+
def get_unified_metadata_field(self, unified_metadata_key: UnifiedMetadataKey) -> UnifiedMetadataValue:
|
|
269
|
+
if unified_metadata_key not in (
|
|
270
|
+
UnifiedMetadataKey.DISC_NUMBER,
|
|
271
|
+
UnifiedMetadataKey.DISC_TOTAL,
|
|
272
|
+
):
|
|
273
|
+
return super().get_unified_metadata_field(unified_metadata_key)
|
|
274
|
+
|
|
275
|
+
if self.raw_clean_metadata_uppercase_keys is None:
|
|
276
|
+
self._extract_raw_clean_metadata_uppercase_keys_from_file()
|
|
277
|
+
keys = self.raw_clean_metadata_uppercase_keys
|
|
278
|
+
if keys is None:
|
|
279
|
+
return None
|
|
280
|
+
|
|
281
|
+
disc_number_key = self.VorbisKey.DISC_NUMBER
|
|
282
|
+
disc_total_key = self.VorbisKey.DISC_TOTAL
|
|
283
|
+
|
|
284
|
+
def _first_string(raw_key: RawMetadataKey) -> str | None:
|
|
285
|
+
if raw_key not in keys:
|
|
286
|
+
return None
|
|
287
|
+
vals = keys[raw_key]
|
|
288
|
+
if not vals or len(vals) == 0:
|
|
289
|
+
return None
|
|
290
|
+
v = vals[0]
|
|
291
|
+
if v is None or v == "":
|
|
292
|
+
return None
|
|
293
|
+
return str(v)
|
|
294
|
+
|
|
295
|
+
d = _first_string(disc_number_key)
|
|
296
|
+
t = _first_string(disc_total_key)
|
|
297
|
+
|
|
298
|
+
if unified_metadata_key == UnifiedMetadataKey.DISC_NUMBER:
|
|
299
|
+
if d is None:
|
|
300
|
+
return None
|
|
301
|
+
return parse_disc_number_from_combined_str(d)
|
|
302
|
+
|
|
303
|
+
if t is not None:
|
|
304
|
+
explicit = parse_explicit_non_negative_disctotal(t)
|
|
305
|
+
if explicit is not None:
|
|
306
|
+
return explicit
|
|
307
|
+
if d is None:
|
|
308
|
+
return None
|
|
309
|
+
return parse_disc_total_from_combined_str(d)
|
|
310
|
+
|
|
263
311
|
def _get_raw_rating_by_traktor_or_not(self, raw_clean_metadata: RawMetadataDict) -> tuple[int | None, bool]:
|
|
264
312
|
if self.VorbisKey.RATING in raw_clean_metadata:
|
|
265
313
|
rating_list = raw_clean_metadata[self.VorbisKey.RATING]
|
audiometa_python-1.3.3/audiometa/test/tests/integration/metadata_field/disc_number/test_reading.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.test.helpers.id3v2.id3v2_metadata_setter import ID3v2MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
6
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_setter import VorbisMetadataSetter
|
|
7
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.integration
|
|
11
|
+
class TestDiscNumberReading:
|
|
12
|
+
def test_id3v2_with_total(self):
|
|
13
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
14
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "1/2"})
|
|
15
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
16
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
17
|
+
assert disc_number == 1
|
|
18
|
+
assert disc_total == 2
|
|
19
|
+
|
|
20
|
+
def test_id3v2_without_total(self):
|
|
21
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
22
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "1"})
|
|
23
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
24
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
25
|
+
assert disc_number == 1
|
|
26
|
+
assert disc_total is None
|
|
27
|
+
|
|
28
|
+
def test_id3v2_max_value(self):
|
|
29
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
30
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "99/99"})
|
|
31
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
32
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
33
|
+
assert disc_number == 99
|
|
34
|
+
assert disc_total == 99
|
|
35
|
+
|
|
36
|
+
def test_id3v2_hyphen_separator_read(self):
|
|
37
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
38
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "1-2"})
|
|
39
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
40
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
41
|
+
assert disc_number == 1
|
|
42
|
+
assert disc_total == 2
|
|
43
|
+
|
|
44
|
+
def test_id3v2_invalid_tpos_multiple_slashes_returns_none(self):
|
|
45
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
46
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "1/2/3"})
|
|
47
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
48
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
49
|
+
assert disc_number is None
|
|
50
|
+
assert disc_total is None
|
|
51
|
+
|
|
52
|
+
def test_id3v2_read_tpos_above_255_not_clamped(self):
|
|
53
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
54
|
+
ID3v2MetadataSetter.set_metadata(test_file, {"disc_number": "256/300"})
|
|
55
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
56
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
57
|
+
assert disc_number == 256
|
|
58
|
+
assert disc_total == 300
|
|
59
|
+
|
|
60
|
+
def test_vorbis_with_total(self):
|
|
61
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
62
|
+
VorbisMetadataSetter.set_metadata(test_file, {"disc_number": "1", "disc_total": "2"})
|
|
63
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
64
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
65
|
+
assert disc_number == 1
|
|
66
|
+
assert disc_total == 2
|
|
67
|
+
|
|
68
|
+
def test_vorbis_without_total(self):
|
|
69
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
70
|
+
VorbisMetadataSetter.set_metadata(test_file, {"disc_number": "2"})
|
|
71
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
72
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
73
|
+
assert disc_number == 2
|
|
74
|
+
assert disc_total is None
|
|
75
|
+
|
|
76
|
+
def test_vorbis_disc_number_combined_slash_form(self):
|
|
77
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
78
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "3/5")
|
|
79
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
80
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
81
|
+
assert disc_number == 3
|
|
82
|
+
assert disc_total == 5
|
|
83
|
+
|
|
84
|
+
def test_vorbis_discnumber_combined_slash_via_set_metadata(self):
|
|
85
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
86
|
+
VorbisMetadataSetter.set_metadata(test_file, {"disc_number": "1/2"})
|
|
87
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
88
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
89
|
+
assert disc_number == 1
|
|
90
|
+
assert disc_total == 2
|
|
91
|
+
|
|
92
|
+
def test_vorbis_disc_number_hyphen_form(self):
|
|
93
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
94
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "1-2")
|
|
95
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
96
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
97
|
+
assert disc_number == 1
|
|
98
|
+
assert disc_total == 2
|
|
99
|
+
|
|
100
|
+
def test_vorbis_disctotal_overrides_embedded_total(self):
|
|
101
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
102
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "1/3")
|
|
103
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCTOTAL", "2")
|
|
104
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
105
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
106
|
+
assert disc_number == 1
|
|
107
|
+
assert disc_total == 2
|
|
108
|
+
|
|
109
|
+
def test_vorbis_discnumber_slash_with_matching_disctotal(self):
|
|
110
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
111
|
+
VorbisMetadataSetter.set_metadata(test_file, {"disc_number": "1/2", "disc_total": "2"})
|
|
112
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
113
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
114
|
+
assert disc_number == 1
|
|
115
|
+
assert disc_total == 2
|
|
116
|
+
|
|
117
|
+
def test_vorbis_invalid_disctotal_falls_back_to_discnumber_slash(self):
|
|
118
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
119
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "1/2")
|
|
120
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCTOTAL", "bogus")
|
|
121
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
122
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
123
|
+
assert disc_number == 1
|
|
124
|
+
assert disc_total == 2
|
|
125
|
+
|
|
126
|
+
def test_vorbis_negative_disctotal_falls_back_to_discnumber_slash(self):
|
|
127
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
128
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "1/2")
|
|
129
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCTOTAL", "-1")
|
|
130
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
131
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
132
|
+
assert disc_number == 1
|
|
133
|
+
assert disc_total == 2
|
|
134
|
+
|
|
135
|
+
def test_vorbis_invalid_combined_discnumber(self):
|
|
136
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
137
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCNUMBER", "1/2/3")
|
|
138
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
139
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
140
|
+
assert disc_number is None
|
|
141
|
+
assert disc_total is None
|
|
142
|
+
|
|
143
|
+
def test_vorbis_disctotal_only(self):
|
|
144
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
145
|
+
VorbisMetadataSetter.set_tag(test_file, "DISCTOTAL", "2")
|
|
146
|
+
disc_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_NUMBER)
|
|
147
|
+
disc_total = get_unified_metadata_field(test_file, UnifiedMetadataKey.DISC_TOTAL)
|
|
148
|
+
assert disc_number is None
|
|
149
|
+
assert disc_total == 2
|
|
150
|
+
|
|
151
|
+
def test_id3v1_not_supported(self):
|
|
152
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
153
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
154
|
+
|
|
155
|
+
with temp_file_with_metadata({}, "id3v1") as test_file:
|
|
156
|
+
with pytest.raises(
|
|
157
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
158
|
+
match="UnifiedMetadataKey.DISC_NUMBER metadata not supported by ID3v1 format",
|
|
159
|
+
):
|
|
160
|
+
get_unified_metadata_field(
|
|
161
|
+
test_file, UnifiedMetadataKey.DISC_NUMBER, metadata_format=MetadataFormat.ID3V1
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
with pytest.raises(
|
|
165
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
166
|
+
match="UnifiedMetadataKey.DISC_TOTAL metadata not supported by ID3v1 format",
|
|
167
|
+
):
|
|
168
|
+
get_unified_metadata_field(
|
|
169
|
+
test_file, UnifiedMetadataKey.DISC_TOTAL, metadata_format=MetadataFormat.ID3V1
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def test_riff_not_supported(self):
|
|
173
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
174
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
175
|
+
|
|
176
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
177
|
+
with pytest.raises(
|
|
178
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
179
|
+
match="UnifiedMetadataKey.DISC_NUMBER metadata not supported by RIFF format",
|
|
180
|
+
):
|
|
181
|
+
get_unified_metadata_field(
|
|
182
|
+
test_file, UnifiedMetadataKey.DISC_NUMBER, metadata_format=MetadataFormat.RIFF
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
with pytest.raises(
|
|
186
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
187
|
+
match="UnifiedMetadataKey.DISC_TOTAL metadata not supported by RIFF format",
|
|
188
|
+
):
|
|
189
|
+
get_unified_metadata_field(
|
|
190
|
+
test_file, UnifiedMetadataKey.DISC_TOTAL, metadata_format=MetadataFormat.RIFF
|
|
191
|
+
)
|
|
@@ -7,37 +7,50 @@ from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
|
7
7
|
|
|
8
8
|
@pytest.mark.integration
|
|
9
9
|
class TestTrackNumberReadingEdgeCases:
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
11
|
+
def test_trailing_slash(self, fmt):
|
|
12
|
+
with temp_file_with_metadata({"track_number": "5/"}, fmt) as test_file:
|
|
12
13
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
13
14
|
assert track_number == "5/"
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
17
|
+
def test_leading_slash_no_track(self, fmt):
|
|
18
|
+
with temp_file_with_metadata({"track_number": "/12"}, fmt) as test_file:
|
|
17
19
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
18
20
|
assert track_number is None
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
23
|
+
def test_non_numeric_values(self, fmt):
|
|
24
|
+
with temp_file_with_metadata({"track_number": "abc/def"}, fmt) as test_file:
|
|
22
25
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
23
26
|
assert track_number is None
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
@pytest.mark.parametrize(
|
|
29
|
+
("fmt", "expected"),
|
|
30
|
+
[
|
|
31
|
+
("mp3", None),
|
|
32
|
+
("flac", ""),
|
|
33
|
+
],
|
|
34
|
+
)
|
|
35
|
+
def test_empty_string(self, fmt, expected):
|
|
36
|
+
with temp_file_with_metadata({"track_number": ""}, fmt) as test_file:
|
|
27
37
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
28
|
-
assert track_number
|
|
38
|
+
assert track_number == expected
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
41
|
+
def test_multiple_slashes(self, fmt):
|
|
42
|
+
with temp_file_with_metadata({"track_number": "5/12/15"}, fmt) as test_file:
|
|
32
43
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
33
44
|
assert track_number is None
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
47
|
+
def test_different_separator(self, fmt):
|
|
48
|
+
with temp_file_with_metadata({"track_number": "5-12"}, fmt) as test_file:
|
|
37
49
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
38
50
|
assert track_number == "5-12"
|
|
39
51
|
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
@pytest.mark.parametrize("fmt", ["mp3", "flac"])
|
|
53
|
+
def test_leading_zeros_preserved(self, fmt):
|
|
54
|
+
with temp_file_with_metadata({"track_number": "01"}, fmt) as test_file:
|
|
42
55
|
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
43
56
|
assert track_number == "01"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.id3v1.id3v1_metadata_getter import ID3v1MetadataGetter
|
|
5
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
6
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
7
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.integration
|
|
11
|
+
class TestTrackNumberReading:
|
|
12
|
+
def test_id3v1_1(self):
|
|
13
|
+
with temp_file_with_metadata({"title": "Test Song", "track": "99"}, "id3v1") as test_file:
|
|
14
|
+
raw_metadata = ID3v1MetadataGetter.get_raw_metadata(test_file)
|
|
15
|
+
assert raw_metadata.get("track") == 99
|
|
16
|
+
|
|
17
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
18
|
+
assert track_number == "99"
|
|
19
|
+
|
|
20
|
+
def test_id3v2(self):
|
|
21
|
+
with temp_file_with_metadata({"title": "Test Song", "track_number": "99/99"}, "mp3") as test_file:
|
|
22
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
23
|
+
assert track_number == "99/99"
|
|
24
|
+
|
|
25
|
+
def test_vorbis(self):
|
|
26
|
+
with temp_file_with_metadata({"title": "Test Song", "track_number": "99"}, "flac") as test_file:
|
|
27
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
28
|
+
assert track_number == "99"
|
|
29
|
+
|
|
30
|
+
@pytest.mark.parametrize(
|
|
31
|
+
("raw", "expected"),
|
|
32
|
+
[
|
|
33
|
+
("5/12", "5/12"),
|
|
34
|
+
("4/11", "4/11"),
|
|
35
|
+
("5-12", "5-12"),
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
def test_vorbis_track_number_combined_or_hyphen(self, raw, expected):
|
|
39
|
+
with temp_file_with_metadata({"title": "Test Song", "track_number": raw}, "flac") as test_file:
|
|
40
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
41
|
+
assert track_number == expected
|
|
42
|
+
|
|
43
|
+
def test_riff(self):
|
|
44
|
+
with temp_file_with_metadata({"title": "Test Song", "track_number": None}, "wav") as test_file:
|
|
45
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
46
|
+
assert track_number is None
|
|
47
|
+
|
|
48
|
+
@pytest.mark.parametrize(
|
|
49
|
+
("written", "expected"),
|
|
50
|
+
[
|
|
51
|
+
("5/12", "5/12"),
|
|
52
|
+
("4/11", "4/11"),
|
|
53
|
+
("5-12", "5-12"),
|
|
54
|
+
],
|
|
55
|
+
)
|
|
56
|
+
def test_riff_track_number_reads_like_shared_rule_after_unified_write(self, written, expected):
|
|
57
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
58
|
+
update_metadata(
|
|
59
|
+
test_file,
|
|
60
|
+
{UnifiedMetadataKey.TRACK_NUMBER: written},
|
|
61
|
+
metadata_format=MetadataFormat.RIFF,
|
|
62
|
+
)
|
|
63
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
64
|
+
assert track_number == expected
|
|
65
|
+
|
|
66
|
+
@pytest.mark.parametrize(
|
|
67
|
+
("raw", "expected"),
|
|
68
|
+
[
|
|
69
|
+
("5/12", "5/12"),
|
|
70
|
+
("5-12", "5-12"),
|
|
71
|
+
],
|
|
72
|
+
)
|
|
73
|
+
def test_id3v2_track_number_combined_or_hyphen(self, raw, expected):
|
|
74
|
+
with temp_file_with_metadata({"title": "Test Song", "track_number": raw}, "mp3") as test_file:
|
|
75
|
+
track_number = get_unified_metadata_field(test_file, UnifiedMetadataKey.TRACK_NUMBER)
|
|
76
|
+
assert track_number == expected
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa.utils.disc_number_read import (
|
|
4
|
+
parse_disc_number_from_combined_str,
|
|
5
|
+
parse_disc_total_from_combined_str,
|
|
6
|
+
parse_explicit_non_negative_disctotal,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.unit
|
|
11
|
+
class TestDiscNumberReadParsing:
|
|
12
|
+
@pytest.mark.parametrize(
|
|
13
|
+
("s", "expected"),
|
|
14
|
+
[
|
|
15
|
+
("1", 1),
|
|
16
|
+
("01", 1),
|
|
17
|
+
("1/2", 1),
|
|
18
|
+
("1-2", 1),
|
|
19
|
+
("99/100", 99),
|
|
20
|
+
],
|
|
21
|
+
)
|
|
22
|
+
def test_parse_disc_number_ok(self, s, expected):
|
|
23
|
+
assert parse_disc_number_from_combined_str(s) == expected
|
|
24
|
+
|
|
25
|
+
@pytest.mark.parametrize(
|
|
26
|
+
"s",
|
|
27
|
+
["", "1/2/3", "x", "1-", "-1", "1/"],
|
|
28
|
+
)
|
|
29
|
+
def test_parse_disc_number_none(self, s):
|
|
30
|
+
assert parse_disc_number_from_combined_str(s) is None
|
|
31
|
+
|
|
32
|
+
@pytest.mark.parametrize(
|
|
33
|
+
("s", "expected"),
|
|
34
|
+
[
|
|
35
|
+
("1/2", 2),
|
|
36
|
+
("1-2", 2),
|
|
37
|
+
("0/5", 5),
|
|
38
|
+
],
|
|
39
|
+
)
|
|
40
|
+
def test_parse_disc_total_from_combined_ok(self, s, expected):
|
|
41
|
+
assert parse_disc_total_from_combined_str(s) == expected
|
|
42
|
+
|
|
43
|
+
@pytest.mark.parametrize(
|
|
44
|
+
"s",
|
|
45
|
+
["1", "1/2/3", "", "x"],
|
|
46
|
+
)
|
|
47
|
+
def test_parse_disc_total_from_combined_none(self, s):
|
|
48
|
+
assert parse_disc_total_from_combined_str(s) is None
|
|
49
|
+
|
|
50
|
+
@pytest.mark.parametrize(
|
|
51
|
+
("s", "expected"),
|
|
52
|
+
[
|
|
53
|
+
("0", 0),
|
|
54
|
+
("2", 2),
|
|
55
|
+
("42", 42),
|
|
56
|
+
],
|
|
57
|
+
)
|
|
58
|
+
def test_parse_explicit_disctotal_ok(self, s, expected):
|
|
59
|
+
assert parse_explicit_non_negative_disctotal(s) == expected
|
|
60
|
+
|
|
61
|
+
@pytest.mark.parametrize(
|
|
62
|
+
"s",
|
|
63
|
+
["", "bogus", "-1", "1.5"],
|
|
64
|
+
)
|
|
65
|
+
def test_parse_explicit_disctotal_none(self, s):
|
|
66
|
+
assert parse_explicit_non_negative_disctotal(s) is None
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Parse combined disc index/total strings (ID3v2 TPOS-style) for unified metadata read."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
_DISC_NUMBER_RE = re.compile(r"^(\d+)(?:[-/](\d+))?$")
|
|
6
|
+
_DISC_TOTAL_FROM_COMBINED_RE = re.compile(r"^(\d+)[-/](\d+)$")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def parse_disc_number_from_combined_str(value: str) -> int | None:
|
|
10
|
+
m = _DISC_NUMBER_RE.match(value)
|
|
11
|
+
if m:
|
|
12
|
+
return int(m.group(1))
|
|
13
|
+
return None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def parse_disc_total_from_combined_str(value: str) -> int | None:
|
|
17
|
+
m = _DISC_TOTAL_FROM_COMBINED_RE.match(value)
|
|
18
|
+
if m:
|
|
19
|
+
return int(m.group(2))
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def parse_explicit_non_negative_disctotal(value: str) -> int | None:
|
|
24
|
+
try:
|
|
25
|
+
n = int(value)
|
|
26
|
+
except (ValueError, TypeError):
|
|
27
|
+
return None
|
|
28
|
+
if n < 0:
|
|
29
|
+
return None
|
|
30
|
+
return n
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: audiometa-python
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: A comprehensive Python library for reading and writing audio metadata across multiple formats
|
|
5
5
|
Author: AudioMeta Python Contributors
|
|
6
6
|
Author-email: Andreas Garcia <garcia.andreas.1991@gmail.com>
|
|
@@ -55,6 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
|
|
56
56
|
A powerful, unified Python library for reading and writing audio metadata across multiple formats. AudioMeta supports MP3, FLAC, and WAV audio files, working seamlessly with ID3v1, ID3v2, Vorbis, and RIFF metadata formats through a single, consistent API.
|
|
57
57
|
|
|
58
|
+
**Try it**: A demo web app is available at [audiometa.themusictree.org](https://audiometa.themusictree.org).
|
|
59
|
+
|
|
58
60
|
**Author**: [Andreas Garcia](https://github.com/BehindTheMusicTree)
|
|
59
61
|
|
|
60
62
|
## ⭐ Show Your Support
|
|
@@ -389,8 +389,10 @@ audiometa/test/tests/unit/metadata_managers/metadata_field/release_date/test_dat
|
|
|
389
389
|
audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/__init__.py
|
|
390
390
|
audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/test_track_number_validation.py
|
|
391
391
|
audiometa/test/tests/unit/utils/__init__.py
|
|
392
|
+
audiometa/test/tests/unit/utils/test_disc_number_read.py
|
|
392
393
|
audiometa/test/tests/unit/utils/test_raw_metadata_sanitizer.py
|
|
393
394
|
audiometa/utils/__init__.py
|
|
395
|
+
audiometa/utils/disc_number_read.py
|
|
394
396
|
audiometa/utils/flac_md5_state.py
|
|
395
397
|
audiometa/utils/id3v1_genre_code_map.py
|
|
396
398
|
audiometa/utils/metadata_format.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "audiometa-python"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.3"
|
|
8
8
|
description = "A comprehensive Python library for reading and writing audio metadata across multiple formats"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -107,6 +107,8 @@ ignore = ["N999", "PLR0911", "PLR0912", "PLR0913", "PLR0914", "PLR0915", "TRY301
|
|
|
107
107
|
# T201 (print) is acceptable in demo scripts - they are CLI/demo tools, not library code
|
|
108
108
|
"scripts/run_demo_tape.py" = ["T201"]
|
|
109
109
|
"scripts/demo_repl.py" = ["T201"]
|
|
110
|
+
# Release script: CLI tool; relax exception/literal and magic-number rules for clarity
|
|
111
|
+
"scripts/prepare_release.py" = ["TRY003", "EM101", "EM102", "PLR2004", "DTZ011", "RUF005", "T201"]
|
|
110
112
|
|
|
111
113
|
[tool.mypy]
|
|
112
114
|
python_version = "3.12"
|