audiometa-python 0.6.0__py3-none-any.whl
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/__init__.py +1297 -0
- audiometa/__main__.py +6 -0
- audiometa/_audio_file.py +607 -0
- audiometa/cli.py +476 -0
- audiometa/exceptions.py +167 -0
- audiometa/manager/_MetadataManager.py +768 -0
- audiometa/manager/__init__.py +1 -0
- audiometa/manager/_rating_supporting/_RatingSupportingMetadataManager.py +250 -0
- audiometa/manager/_rating_supporting/__init__.py +1 -0
- audiometa/manager/_rating_supporting/id3v2/_Id3v2Manager.py +1032 -0
- audiometa/manager/_rating_supporting/id3v2/__init__.py +25 -0
- audiometa/manager/_rating_supporting/id3v2/_id3v2_constants.py +11 -0
- audiometa/manager/_rating_supporting/riff/_RiffManager.py +1002 -0
- audiometa/manager/_rating_supporting/riff/__init__.py +25 -0
- audiometa/manager/_rating_supporting/riff/_riff_constants.py +17 -0
- audiometa/manager/_rating_supporting/vorbis/_VorbisManager.py +542 -0
- audiometa/manager/_rating_supporting/vorbis/__init__.py +17 -0
- audiometa/manager/_rating_supporting/vorbis/_vorbis_constants.py +6 -0
- audiometa/manager/id3v1/_Id3v1Manager.py +512 -0
- audiometa/manager/id3v1/__init__.py +1 -0
- audiometa/manager/id3v1/_constants.py +8 -0
- audiometa/manager/id3v1/id3v1_raw_metadata.py +242 -0
- audiometa/manager/id3v1/id3v1_raw_metadata_key.py +13 -0
- audiometa/test/__init__.py +1 -0
- audiometa/test/assets/create_test_files.py +72 -0
- audiometa/test/helpers/__init__.py +51 -0
- audiometa/test/helpers/common/__init__.py +6 -0
- audiometa/test/helpers/common/audio_file_creator.py +68 -0
- audiometa/test/helpers/common/external_tool_runner.py +74 -0
- audiometa/test/helpers/id3v1/__init__.py +8 -0
- audiometa/test/helpers/id3v1/id3v1_header_verifier.py +18 -0
- audiometa/test/helpers/id3v1/id3v1_metadata_deleter.py +37 -0
- audiometa/test/helpers/id3v1/id3v1_metadata_getter.py +61 -0
- audiometa/test/helpers/id3v1/id3v1_metadata_setter.py +82 -0
- audiometa/test/helpers/id3v2/__init__.py +28 -0
- audiometa/test/helpers/id3v2/id3v2_frame_manual_creator.py +349 -0
- audiometa/test/helpers/id3v2/id3v2_header_verifier.py +38 -0
- audiometa/test/helpers/id3v2/id3v2_metadata_deleter.py +56 -0
- audiometa/test/helpers/id3v2/id3v2_metadata_getter.py +189 -0
- audiometa/test/helpers/id3v2/id3v2_metadata_setter.py +506 -0
- audiometa/test/helpers/riff/__init__.py +8 -0
- audiometa/test/helpers/riff/riff_header_verifier.py +85 -0
- audiometa/test/helpers/riff/riff_manual_metadata_creator.py +298 -0
- audiometa/test/helpers/riff/riff_metadata_deleter.py +56 -0
- audiometa/test/helpers/riff/riff_metadata_getter.py +219 -0
- audiometa/test/helpers/riff/riff_metadata_setter.py +374 -0
- audiometa/test/helpers/scripts/__init__.py +0 -0
- audiometa/test/helpers/technical_info_inspector.py +115 -0
- audiometa/test/helpers/temp_file_with_metadata.py +82 -0
- audiometa/test/helpers/vorbis/__init__.py +8 -0
- audiometa/test/helpers/vorbis/vorbis_header_verifier.py +31 -0
- audiometa/test/helpers/vorbis/vorbis_metadata_deleter.py +49 -0
- audiometa/test/helpers/vorbis/vorbis_metadata_getter.py +67 -0
- audiometa/test/helpers/vorbis/vorbis_metadata_setter.py +221 -0
- audiometa/test/tests/__init__.py +0 -0
- audiometa/test/tests/conftest.py +276 -0
- audiometa/test/tests/e2e/__init__.py +0 -0
- audiometa/test/tests/e2e/cli/__init__.py +0 -0
- audiometa/test/tests/e2e/cli/error_handling/__init__.py +1 -0
- audiometa/test/tests/e2e/cli/error_handling/test_command_structure_errors.py +77 -0
- audiometa/test/tests/e2e/cli/error_handling/test_file_access_errors.py +130 -0
- audiometa/test/tests/e2e/cli/error_handling/test_format_output_errors.py +118 -0
- audiometa/test/tests/e2e/cli/error_handling/test_input_validation_errors.py +172 -0
- audiometa/test/tests/e2e/cli/error_handling/test_missing_fields_validation.py +49 -0
- audiometa/test/tests/e2e/cli/error_handling/test_multiple_files_errors.py +160 -0
- audiometa/test/tests/e2e/cli/error_handling/test_rating_validation.py +90 -0
- audiometa/test/tests/e2e/cli/error_handling/test_year_validation.py +51 -0
- audiometa/test/tests/e2e/cli/read/__init__.py +0 -0
- audiometa/test/tests/e2e/cli/read/test_basic.py +58 -0
- audiometa/test/tests/e2e/cli/read/test_comprehensive.py +240 -0
- audiometa/test/tests/e2e/cli/read/test_formats.py +55 -0
- audiometa/test/tests/e2e/cli/read/test_metadata_content.py +164 -0
- audiometa/test/tests/e2e/cli/read/test_multiple_files.py +149 -0
- audiometa/test/tests/e2e/cli/read/test_options.py +88 -0
- audiometa/test/tests/e2e/cli/read/test_unified.py +84 -0
- audiometa/test/tests/e2e/cli/test_delete.py +20 -0
- audiometa/test/tests/e2e/cli/test_formatting.py +31 -0
- audiometa/test/tests/e2e/cli/test_help.py +41 -0
- audiometa/test/tests/e2e/cli/write/__init__.py +0 -0
- audiometa/test/tests/e2e/cli/write/test_basic.py +51 -0
- audiometa/test/tests/e2e/cli/write/test_comprehensive.py +210 -0
- audiometa/test/tests/e2e/cli/write/test_force_format.py +336 -0
- audiometa/test/tests/e2e/cli/write/test_integer_fields.py +145 -0
- audiometa/test/tests/e2e/cli/write/test_list_fields.py +107 -0
- audiometa/test/tests/e2e/cli/write/test_rating.py +74 -0
- audiometa/test/tests/e2e/cli/write/test_string_fields.py +54 -0
- audiometa/test/tests/e2e/cli/write/test_validation.py +85 -0
- audiometa/test/tests/e2e/scenarios/__init__.py +0 -0
- audiometa/test/tests/e2e/scenarios/test_user_scenarios.py +166 -0
- audiometa/test/tests/e2e/workflows/__init__.py +0 -0
- audiometa/test/tests/e2e/workflows/test_core_workflows.py +166 -0
- audiometa/test/tests/e2e/workflows/test_deletion_workflows.py +318 -0
- audiometa/test/tests/e2e/workflows/test_error_handling_workflows.py +165 -0
- audiometa/test/tests/e2e/workflows/test_format_specific_workflows.py +129 -0
- audiometa/test/tests/e2e/workflows/test_rating_workflows.py +124 -0
- audiometa/test/tests/integration/__init__.py +0 -0
- audiometa/test/tests/integration/audio_format/__init__.py +0 -0
- audiometa/test/tests/integration/audio_format/flac/__init__.py +0 -0
- audiometa/test/tests/integration/audio_format/flac/test_flac_delete_all.py +108 -0
- audiometa/test/tests/integration/audio_format/flac/test_flac_reading_all.py +61 -0
- audiometa/test/tests/integration/audio_format/flac/test_flac_reading_field.py +65 -0
- audiometa/test/tests/integration/audio_format/flac/test_flac_writing.py +69 -0
- audiometa/test/tests/integration/audio_format/mp3/__init__.py +0 -0
- audiometa/test/tests/integration/audio_format/mp3/test_mp3_delete_all.py +79 -0
- audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_all.py +61 -0
- audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_field.py +67 -0
- audiometa/test/tests/integration/audio_format/mp3/test_mp3_writing.py +60 -0
- audiometa/test/tests/integration/audio_format/wav/__init__.py +0 -0
- audiometa/test/tests/integration/audio_format/wav/test_wav_delete_all.py +87 -0
- audiometa/test/tests/integration/audio_format/wav/test_wav_reading_all.py +62 -0
- audiometa/test/tests/integration/audio_format/wav/test_wav_reading_field.py +57 -0
- audiometa/test/tests/integration/audio_format/wav/test_wav_with_id3v2_tags.py +83 -0
- audiometa/test/tests/integration/audio_format/wav/test_wav_writing.py +62 -0
- audiometa/test/tests/integration/conftest.py +29 -0
- audiometa/test/tests/integration/delete_all_metadata/__init__.py +1 -0
- audiometa/test/tests/integration/delete_all_metadata/test_audio_format_all.py +102 -0
- audiometa/test/tests/integration/delete_all_metadata/test_audio_format_header_deletion.py +77 -0
- audiometa/test/tests/integration/delete_all_metadata/test_basic_functionality.py +47 -0
- audiometa/test/tests/integration/delete_all_metadata/test_error_handling.py +24 -0
- audiometa/test/tests/integration/encoding/__init__.py +1 -0
- audiometa/test/tests/integration/encoding/test_encoding.py +88 -0
- audiometa/test/tests/integration/encoding/test_special_characters_edge_cases.py +223 -0
- audiometa/test/tests/integration/get_full_metadata/__init__.py +0 -0
- audiometa/test/tests/integration/get_full_metadata/test_audio_formats.py +122 -0
- audiometa/test/tests/integration/get_full_metadata/test_binary_data_filtering.py +250 -0
- audiometa/test/tests/integration/get_full_metadata/test_consistency.py +67 -0
- audiometa/test/tests/integration/get_full_metadata/test_edge_cases.py +123 -0
- audiometa/test/tests/integration/get_full_metadata/test_error_handling.py +40 -0
- audiometa/test/tests/integration/get_full_metadata/test_get_full_metadata.py +43 -0
- audiometa/test/tests/integration/get_full_metadata/test_options.py +207 -0
- audiometa/test/tests/integration/get_full_metadata/test_performance.py +95 -0
- audiometa/test/tests/integration/get_full_metadata/test_riff_bext.py +128 -0
- audiometa/test/tests/integration/get_full_metadata/test_structure.py +161 -0
- audiometa/test/tests/integration/metadata_field/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/album/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/album/test_deleting.py +73 -0
- audiometa/test/tests/integration/metadata_field/album/test_reading.py +36 -0
- audiometa/test/tests/integration/metadata_field/album/test_writing.py +50 -0
- audiometa/test/tests/integration/metadata_field/album_artists/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/album_artists/test_deleting.py +83 -0
- audiometa/test/tests/integration/metadata_field/album_artists/test_reading.py +38 -0
- audiometa/test/tests/integration/metadata_field/album_artists/test_writing.py +52 -0
- audiometa/test/tests/integration/metadata_field/artists/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/artists/test_deleting.py +68 -0
- audiometa/test/tests/integration/metadata_field/artists/test_reading.py +36 -0
- audiometa/test/tests/integration/metadata_field/artists/test_writing.py +46 -0
- audiometa/test/tests/integration/metadata_field/bpm/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/bpm/test_deleting.py +75 -0
- audiometa/test/tests/integration/metadata_field/bpm/test_reading.py +32 -0
- audiometa/test/tests/integration/metadata_field/bpm/test_writing.py +56 -0
- audiometa/test/tests/integration/metadata_field/comment/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/comment/test_deleting.py +68 -0
- audiometa/test/tests/integration/metadata_field/comment/test_reading.py +36 -0
- audiometa/test/tests/integration/metadata_field/comment/test_writing.py +49 -0
- audiometa/test/tests/integration/metadata_field/composer/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/composer/test_deleting.py +75 -0
- audiometa/test/tests/integration/metadata_field/composer/test_reading.py +34 -0
- audiometa/test/tests/integration/metadata_field/composer/test_writing.py +41 -0
- audiometa/test/tests/integration/metadata_field/copyright/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/copyright/test_deleting.py +81 -0
- audiometa/test/tests/integration/metadata_field/copyright/test_reading.py +35 -0
- audiometa/test/tests/integration/metadata_field/copyright/test_writing.py +41 -0
- audiometa/test/tests/integration/metadata_field/disc_number/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/disc_number/test_deleting.py +97 -0
- audiometa/test/tests/integration/metadata_field/disc_number/test_reading.py +92 -0
- audiometa/test/tests/integration/metadata_field/disc_number/test_writing.py +153 -0
- audiometa/test/tests/integration/metadata_field/field_not_supported/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/field_not_supported/test_deleting.py +56 -0
- audiometa/test/tests/integration/metadata_field/field_not_supported/test_reading.py +54 -0
- audiometa/test/tests/integration/metadata_field/field_not_supported/test_writing.py +61 -0
- audiometa/test/tests/integration/metadata_field/genre/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v1_reading.py +65 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v2_reading.py +25 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_riff_reading.py +58 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_vorbis_reading.py +61 -0
- audiometa/test/tests/integration/metadata_field/genre/reading/test_smart_reading.py +191 -0
- audiometa/test/tests/integration/metadata_field/genre/test_deleting.py +62 -0
- audiometa/test/tests/integration/metadata_field/genre/test_writing.py +64 -0
- audiometa/test/tests/integration/metadata_field/isrc/__init__.py +1 -0
- audiometa/test/tests/integration/metadata_field/isrc/test_deleting.py +31 -0
- audiometa/test/tests/integration/metadata_field/isrc/test_reading.py +35 -0
- audiometa/test/tests/integration/metadata_field/isrc/test_writing.py +165 -0
- audiometa/test/tests/integration/metadata_field/language/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/language/test_deleting.py +75 -0
- audiometa/test/tests/integration/metadata_field/language/test_reading.py +39 -0
- audiometa/test/tests/integration/metadata_field/language/test_writing.py +43 -0
- audiometa/test/tests/integration/metadata_field/lyrics/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/lyrics/test_deleting.py +129 -0
- audiometa/test/tests/integration/metadata_field/lyrics/test_reading.py +57 -0
- audiometa/test/tests/integration/metadata_field/lyrics/test_writing.py +59 -0
- audiometa/test/tests/integration/metadata_field/publisher/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/publisher/test_deleting.py +88 -0
- audiometa/test/tests/integration/metadata_field/publisher/test_reading.py +32 -0
- audiometa/test/tests/integration/metadata_field/publisher/test_writing.py +47 -0
- audiometa/test/tests/integration/metadata_field/rating/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/rating/reading/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/rating/reading/test_base_100_proportional.py +81 -0
- audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_non_proportional.py +33 -0
- audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_proportional.py +58 -0
- audiometa/test/tests/integration/metadata_field/rating/test_deleting.py +117 -0
- audiometa/test/tests/integration/metadata_field/rating/test_error_handling.py +137 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_id3v2.py +77 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_riff.py +55 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_vorbis.py +57 -0
- audiometa/test/tests/integration/metadata_field/rating/writing/test_comprehensive.py +192 -0
- audiometa/test/tests/integration/metadata_field/release_date/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/release_date/test_deleting.py +74 -0
- audiometa/test/tests/integration/metadata_field/release_date/test_error_handling.py +82 -0
- audiometa/test/tests/integration/metadata_field/release_date/test_reading.py +59 -0
- audiometa/test/tests/integration/metadata_field/release_date/test_writing.py +49 -0
- audiometa/test/tests/integration/metadata_field/test_metadata_field_validation.py +135 -0
- audiometa/test/tests/integration/metadata_field/title/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/title/test_deleting.py +73 -0
- audiometa/test/tests/integration/metadata_field/title/test_error_handling.py +47 -0
- audiometa/test/tests/integration/metadata_field/title/test_reading.py +36 -0
- audiometa/test/tests/integration/metadata_field/title/test_writing.py +64 -0
- audiometa/test/tests/integration/metadata_field/track_number/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/track_number/reading/__init__.py +0 -0
- audiometa/test/tests/integration/metadata_field/track_number/reading/test_edge_cases.py +43 -0
- audiometa/test/tests/integration/metadata_field/track_number/reading/test_metadata_format.py +32 -0
- audiometa/test/tests/integration/metadata_field/track_number/test_deleting.py +59 -0
- audiometa/test/tests/integration/metadata_field/track_number/test_writing.py +73 -0
- audiometa/test/tests/integration/multiple_values/__init__.py +1 -0
- audiometa/test/tests/integration/multiple_values/reading/__init__.py +1 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/__init__.py +1 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v1.py +23 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_3.py +92 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_4.py +216 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_riff.py +84 -0
- audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_vorbis.py +169 -0
- audiometa/test/tests/integration/multiple_values/reading/test_performance_large_data.py +209 -0
- audiometa/test/tests/integration/multiple_values/reading/test_smart_parsing_scenarios.py +198 -0
- audiometa/test/tests/integration/multiple_values/reading/test_unicode_handling.py +24 -0
- audiometa/test/tests/integration/multiple_values/writing/__init__.py +1 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/__init__.py +1 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v1.py +62 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_3.py +36 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_4.py +34 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_riff.py +32 -0
- audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_vorbis.py +54 -0
- audiometa/test/tests/integration/multiple_values/writing/test_error_handling.py +42 -0
- audiometa/test/tests/integration/multiple_values/writing/test_large_values.py +98 -0
- audiometa/test/tests/integration/reading/__init__.py +1 -0
- audiometa/test/tests/integration/reading/test_read_multiple_metadata.py +80 -0
- audiometa/test/tests/integration/reading/test_reading_error_handling.py +36 -0
- audiometa/test/tests/integration/real_audio_files/__init__.py +0 -0
- audiometa/test/tests/integration/real_audio_files/test_reading.py +146 -0
- audiometa/test/tests/integration/real_audio_files/test_writing.py +198 -0
- audiometa/test/tests/integration/technical_info/__init__.py +0 -0
- audiometa/test/tests/integration/technical_info/flac_md5/__init__.py +0 -0
- audiometa/test/tests/integration/technical_info/flac_md5/conftest.py +103 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/__init__.py +0 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_audio_data_corruption.py +21 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_flipped_md5.py +29 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_non_flac_error.py +13 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_partial_md5.py +29 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_random_md5.py +29 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_invalid_md5/test_unset_md5.py +56 -0
- audiometa/test/tests/integration/technical_info/flac_md5/test_valid_md5.py +21 -0
- audiometa/test/tests/integration/technical_info/test_bitrate.py +79 -0
- audiometa/test/tests/integration/technical_info/test_channels.py +38 -0
- audiometa/test/tests/integration/technical_info/test_duration_in_sec.py +38 -0
- audiometa/test/tests/integration/technical_info/test_sample_rate.py +40 -0
- audiometa/test/tests/integration/test_audio_file.py +35 -0
- audiometa/test/tests/integration/test_audio_format_readable_after_update_all_metadata_formats.py +95 -0
- audiometa/test/tests/integration/writing/__init__.py +0 -0
- audiometa/test/tests/integration/writing/test_error_handling.py +44 -0
- audiometa/test/tests/integration/writing/test_forced_format.py +224 -0
- audiometa/test/tests/integration/writing/test_multiple_format_preservation.py +223 -0
- audiometa/test/tests/integration/writing/test_partial_update.py +36 -0
- audiometa/test/tests/integration/writing/writing_strategies/__init__.py +0 -0
- audiometa/test/tests/integration/writing/writing_strategies/test_cleanup_strategy.py +79 -0
- audiometa/test/tests/integration/writing/writing_strategies/test_preserve_strategy.py +76 -0
- audiometa/test/tests/integration/writing/writing_strategies/test_sync_strategy.py +215 -0
- audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/__init__.py +0 -0
- audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_fail_behavior.py +42 -0
- audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_no_writing_on_failure.py +93 -0
- audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_strategy_specific.py +99 -0
- audiometa/test/tests/unit/__init__.py +0 -0
- audiometa/test/tests/unit/audio_file/__init__.py +0 -0
- audiometa/test/tests/unit/audio_file/technical_info/__init__.py +0 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_bitrate.py +26 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_channels.py +31 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_duration_in_sec.py +38 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_error_handling.py +190 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_file_size.py +51 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_format_name.py +28 -0
- audiometa/test/tests/unit/audio_file/technical_info/test_sample_rate.py +31 -0
- audiometa/test/tests/unit/audio_file/test_context_manager.py +30 -0
- audiometa/test/tests/unit/audio_file/test_file_validation.py +40 -0
- audiometa/test/tests/unit/audio_file/test_is_audio_file.py +49 -0
- audiometa/test/tests/unit/audio_file/test_operations.py +20 -0
- audiometa/test/tests/unit/audio_file/test_path_handling.py +23 -0
- audiometa/test/tests/unit/cli/__init__.py +0 -0
- audiometa/test/tests/unit/cli/test_expand_file_patterns.py +234 -0
- audiometa/test/tests/unit/metadata_managers/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/conftest.py +142 -0
- audiometa/test/tests/unit/metadata_managers/header_info/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/header_info/test_id3v1.py +49 -0
- audiometa/test/tests/unit/metadata_managers/header_info/test_id3v2.py +66 -0
- audiometa/test/tests/unit/metadata_managers/header_info/test_riff.py +343 -0
- audiometa/test/tests/unit/metadata_managers/header_info/test_vorbis.py +53 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/test_smart_parsing.py +186 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_separator_selection.py +142 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_value_filtering.py +76 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_normalization.py +152 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_profiles_values.py +23 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/test_rating_validation.py +77 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/__init__.py +0 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_configuration_error.py +43 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_validation.py +151 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_writing_profiles.py +61 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_date_format_validation.py +135 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_disc_number_validation.py +75 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_isrc_format_validation.py +121 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_isrc_type_validation.py +30 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_track_number_validation.py +46 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_type_validation_exception.py +22 -0
- audiometa/test/tests/unit/metadata_managers/metadata_field/test_validation.py +83 -0
- audiometa/test/tests/unit/metadata_managers/test_metadata_format_managers_write_and_read.py +74 -0
- audiometa/test/tests/unit/metadata_managers/test_riff_configuration_error.py +26 -0
- audiometa/utils/__init__.py +1 -0
- audiometa/utils/id3v1_genre_code_map.py +205 -0
- audiometa/utils/metadata_format.py +31 -0
- audiometa/utils/metadata_writing_strategy.py +16 -0
- audiometa/utils/mutagen_exception_handler.py +24 -0
- audiometa/utils/os_dependencies_checker/__init__.py +24 -0
- audiometa/utils/os_dependencies_checker/base.py +62 -0
- audiometa/utils/os_dependencies_checker/config.py +77 -0
- audiometa/utils/os_dependencies_checker/macos.py +236 -0
- audiometa/utils/os_dependencies_checker/ubuntu.py +95 -0
- audiometa/utils/os_dependencies_checker/windows.py +227 -0
- audiometa/utils/rating_profiles.py +110 -0
- audiometa/utils/tool_path_resolver.py +135 -0
- audiometa/utils/types.py +82 -0
- audiometa/utils/unified_metadata_key.py +87 -0
- audiometa_python-0.6.0.dist-info/METADATA +1593 -0
- audiometa_python-0.6.0.dist-info/RECORD +352 -0
- audiometa_python-0.6.0.dist-info/WHEEL +5 -0
- audiometa_python-0.6.0.dist-info/entry_points.txt +2 -0
- audiometa_python-0.6.0.dist-info/licenses/LICENSE +202 -0
- audiometa_python-0.6.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.test.helpers.id3v1 import ID3v1MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.id3v2 import ID3v2MetadataSetter
|
|
6
|
+
from audiometa.test.helpers.riff import RIFFMetadataSetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
8
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
9
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.integration
|
|
13
|
+
class TestAlbumReading:
|
|
14
|
+
def test_id3v1(self):
|
|
15
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file:
|
|
16
|
+
ID3v1MetadataSetter.set_max_metadata(test_file)
|
|
17
|
+
album = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM)
|
|
18
|
+
assert album == "a" * 30
|
|
19
|
+
|
|
20
|
+
def test_id3v2(self):
|
|
21
|
+
with temp_file_with_metadata({"title": "Test Song"}, "mp3") as test_file:
|
|
22
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
23
|
+
album = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM)
|
|
24
|
+
assert album == "a" * 1000
|
|
25
|
+
|
|
26
|
+
def test_vorbis(self):
|
|
27
|
+
with temp_file_with_metadata({"title": "Test Song"}, "flac") as test_file:
|
|
28
|
+
VorbisMetadataSetter.set_max_metadata(test_file)
|
|
29
|
+
album = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM)
|
|
30
|
+
assert album == "a" * 1000
|
|
31
|
+
|
|
32
|
+
def test_riff(self):
|
|
33
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
34
|
+
RIFFMetadataSetter.set_max_metadata(test_file)
|
|
35
|
+
album = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM)
|
|
36
|
+
assert album == "a" * 1000
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata, update_metadata
|
|
4
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
5
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
6
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.integration
|
|
10
|
+
class TestAlbumWriting:
|
|
11
|
+
def test_id3v2(self):
|
|
12
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
13
|
+
test_album = "Test Album ID3v2"
|
|
14
|
+
test_metadata = {UnifiedMetadataKey.ALBUM: test_album}
|
|
15
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
16
|
+
metadata = get_unified_metadata(test_file)
|
|
17
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM) == test_album
|
|
18
|
+
|
|
19
|
+
def test_riff(self):
|
|
20
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
21
|
+
test_album = "Test Album RIFF"
|
|
22
|
+
test_metadata = {UnifiedMetadataKey.ALBUM: test_album}
|
|
23
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
24
|
+
metadata = get_unified_metadata(test_file)
|
|
25
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM) == test_album
|
|
26
|
+
|
|
27
|
+
def test_vorbis(self):
|
|
28
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
29
|
+
test_album = "Test Album Vorbis"
|
|
30
|
+
test_metadata = {UnifiedMetadataKey.ALBUM: test_album}
|
|
31
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
32
|
+
metadata = get_unified_metadata(test_file)
|
|
33
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM) == test_album
|
|
34
|
+
|
|
35
|
+
def test_id3v1(self):
|
|
36
|
+
with temp_file_with_metadata({}, "id3v1") as test_file:
|
|
37
|
+
test_album = "Test Album ID3v1"
|
|
38
|
+
test_metadata = {UnifiedMetadataKey.ALBUM: test_album}
|
|
39
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V1)
|
|
40
|
+
metadata = get_unified_metadata(test_file)
|
|
41
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM) == test_album
|
|
42
|
+
|
|
43
|
+
def test_invalid_type_raises(self):
|
|
44
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
45
|
+
|
|
46
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
47
|
+
# pass an int where a string is expected
|
|
48
|
+
bad_metadata = {UnifiedMetadataKey.ALBUM: 123}
|
|
49
|
+
with pytest.raises(InvalidMetadataFieldTypeError):
|
|
50
|
+
update_metadata(test_file, bad_metadata)
|
|
File without changes
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.id3v2 import ID3v2MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
6
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
7
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
8
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.mark.integration
|
|
12
|
+
class TestAlbumArtistsDeleting:
|
|
13
|
+
def test_delete_album_artists_id3v2(self):
|
|
14
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
15
|
+
# Set metadata using max metadata method (includes album artists)
|
|
16
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
17
|
+
# Verify album artists are set
|
|
18
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
19
|
+
assert album_artists is not None
|
|
20
|
+
|
|
21
|
+
# Delete metadata by setting to None
|
|
22
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
23
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
24
|
+
|
|
25
|
+
def test_delete_album_artists_riff(self):
|
|
26
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
27
|
+
# Set album artists using the unified API
|
|
28
|
+
update_metadata(
|
|
29
|
+
test_file,
|
|
30
|
+
{UnifiedMetadataKey.ALBUM_ARTISTS: ["Test Album Artist"]},
|
|
31
|
+
metadata_format=MetadataFormat.RIFF,
|
|
32
|
+
)
|
|
33
|
+
# Verify album artists are set
|
|
34
|
+
album_artists = get_unified_metadata_field(
|
|
35
|
+
test_file, UnifiedMetadataKey.ALBUM_ARTISTS, metadata_format=MetadataFormat.RIFF
|
|
36
|
+
)
|
|
37
|
+
assert album_artists == ["Test Album Artist"]
|
|
38
|
+
|
|
39
|
+
# Delete metadata by setting to None
|
|
40
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.RIFF)
|
|
41
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
42
|
+
|
|
43
|
+
def test_delete_album_artists_vorbis(self):
|
|
44
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
45
|
+
# Set metadata using max metadata method (includes album artists)
|
|
46
|
+
VorbisMetadataSetter.set_max_metadata(test_file)
|
|
47
|
+
# Verify album artists are set
|
|
48
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
49
|
+
assert album_artists is not None
|
|
50
|
+
|
|
51
|
+
# Delete metadata by setting to None
|
|
52
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.VORBIS)
|
|
53
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
54
|
+
|
|
55
|
+
def test_delete_album_artists_preserves_other_fields(self):
|
|
56
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
57
|
+
# Set metadata using max metadata method (includes album artists and other fields)
|
|
58
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
59
|
+
# Verify album artists are set
|
|
60
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
61
|
+
assert album_artists is not None
|
|
62
|
+
|
|
63
|
+
# Delete only album artists
|
|
64
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
65
|
+
|
|
66
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
67
|
+
# Verify other fields are preserved
|
|
68
|
+
title = get_unified_metadata_field(test_file, UnifiedMetadataKey.TITLE)
|
|
69
|
+
assert title is not None
|
|
70
|
+
|
|
71
|
+
def test_delete_album_artists_already_none(self):
|
|
72
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
73
|
+
# Try to delete album artists that don't exist
|
|
74
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
75
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
76
|
+
|
|
77
|
+
def test_delete_album_artists_with_existing_metadata(self):
|
|
78
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
79
|
+
# Set metadata using max metadata method (includes album artists)
|
|
80
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
81
|
+
# Delete the album artists
|
|
82
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
83
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS) is None
|
|
@@ -0,0 +1,38 @@
|
|
|
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.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
6
|
+
from audiometa.test.helpers.riff.riff_metadata_setter import RIFFMetadataSetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
8
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_setter import VorbisMetadataSetter
|
|
9
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.integration
|
|
13
|
+
class TestAlbumArtistsReading:
|
|
14
|
+
def test_id3v1(self):
|
|
15
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file:
|
|
16
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
17
|
+
assert album_artists is None
|
|
18
|
+
|
|
19
|
+
def test_id3v2(self):
|
|
20
|
+
with temp_file_with_metadata({"title": "Test Song"}, "mp3") as test_file:
|
|
21
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
22
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
23
|
+
assert album_artists == ["a" * 1000]
|
|
24
|
+
|
|
25
|
+
def test_vorbis(self):
|
|
26
|
+
with temp_file_with_metadata({"title": "Test Song"}, "flac") as test_file:
|
|
27
|
+
VorbisMetadataSetter.set_max_metadata(test_file)
|
|
28
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
29
|
+
assert album_artists == ["a" * 1000]
|
|
30
|
+
|
|
31
|
+
def test_riff(self):
|
|
32
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
33
|
+
RIFFMetadataSetter.set_multiple_album_artists(test_file, ["Test Album Artist"])
|
|
34
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
35
|
+
assert "TAG:IAAR=Test Album Artist" in raw_metadata
|
|
36
|
+
|
|
37
|
+
album_artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM_ARTISTS)
|
|
38
|
+
assert album_artists == ["Test Album Artist"]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata, update_metadata
|
|
4
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
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 TestAlbumArtistsWriting:
|
|
12
|
+
def test_id3v2(self):
|
|
13
|
+
test_album_artists = ["Album Artist 1", "Album Artist 2"]
|
|
14
|
+
test_metadata = {UnifiedMetadataKey.ALBUM_ARTISTS: test_album_artists}
|
|
15
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
16
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
17
|
+
metadata = get_unified_metadata(test_file)
|
|
18
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM_ARTISTS) == test_album_artists
|
|
19
|
+
|
|
20
|
+
def test_riff(self):
|
|
21
|
+
test_album_artists = ["RIFF Album Artist 1", "RIFF Album Artist 2"]
|
|
22
|
+
test_metadata = {UnifiedMetadataKey.ALBUM_ARTISTS: test_album_artists}
|
|
23
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
24
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
25
|
+
metadata = get_unified_metadata(test_file)
|
|
26
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM_ARTISTS) == test_album_artists
|
|
27
|
+
|
|
28
|
+
def test_vorbis(self):
|
|
29
|
+
test_album_artists = ["Vorbis Album Artist 1", "Vorbis Album Artist 2"]
|
|
30
|
+
test_metadata = {UnifiedMetadataKey.ALBUM_ARTISTS: test_album_artists}
|
|
31
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
32
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
33
|
+
metadata = get_unified_metadata(test_file)
|
|
34
|
+
assert metadata.get(UnifiedMetadataKey.ALBUM_ARTISTS) == test_album_artists
|
|
35
|
+
|
|
36
|
+
def test_id3v1(self):
|
|
37
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
38
|
+
|
|
39
|
+
test_album_artists = ["ID3v1 Album Artist"]
|
|
40
|
+
test_metadata = {UnifiedMetadataKey.ALBUM_ARTISTS: test_album_artists}
|
|
41
|
+
with (
|
|
42
|
+
temp_file_with_metadata({}, "mp3") as test_file,
|
|
43
|
+
pytest.raises(
|
|
44
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
45
|
+
match="UnifiedMetadataKey.ALBUM_ARTISTS metadata not supported by ID3v1 format",
|
|
46
|
+
),
|
|
47
|
+
):
|
|
48
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V1)
|
|
49
|
+
|
|
50
|
+
def test_invalid_type_raises(self):
|
|
51
|
+
with temp_file_with_metadata({}, "mp3") as test_file, pytest.raises(InvalidMetadataFieldTypeError):
|
|
52
|
+
update_metadata(test_file, {UnifiedMetadataKey.ALBUM_ARTISTS: "Single Album Artist"})
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.id3v1 import ID3v1MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.id3v2 import ID3v2MetadataSetter
|
|
6
|
+
from audiometa.test.helpers.riff import RIFFMetadataSetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
8
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
9
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
10
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.integration
|
|
14
|
+
class TestArtistsDeleting:
|
|
15
|
+
def test_delete_artists_id3v2(self):
|
|
16
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
17
|
+
ID3v2MetadataSetter.set_artists(test_file, "Artist 1; Artist 2")
|
|
18
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Artist 1", "Artist 2"]
|
|
19
|
+
|
|
20
|
+
# Delete metadata using library API
|
|
21
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
22
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
23
|
+
|
|
24
|
+
def test_delete_artists_id3v1(self):
|
|
25
|
+
with temp_file_with_metadata({}, "id3v1") as test_file:
|
|
26
|
+
ID3v1MetadataSetter.set_artist(test_file, "Artist 1")
|
|
27
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Artist 1"]
|
|
28
|
+
|
|
29
|
+
# Delete metadata using library API
|
|
30
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.ID3V1)
|
|
31
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
32
|
+
|
|
33
|
+
def test_delete_artists_riff(self):
|
|
34
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
35
|
+
RIFFMetadataSetter.set_artist(test_file, "Artist 1")
|
|
36
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Artist 1"]
|
|
37
|
+
|
|
38
|
+
# Delete metadata using library API
|
|
39
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.RIFF)
|
|
40
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
41
|
+
|
|
42
|
+
def test_delete_artists_vorbis(self):
|
|
43
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
44
|
+
VorbisMetadataSetter.set_artists(test_file, ["Artist 1", "Artist 2"])
|
|
45
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Artist 1", "Artist 2"]
|
|
46
|
+
|
|
47
|
+
# Delete metadata using library API
|
|
48
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.VORBIS)
|
|
49
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
50
|
+
|
|
51
|
+
def test_delete_artists_preserves_other_fields(self):
|
|
52
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
53
|
+
ID3v2MetadataSetter.set_artists(test_file, "Test Artist")
|
|
54
|
+
ID3v2MetadataSetter.set_title(test_file, "Test Title")
|
|
55
|
+
ID3v2MetadataSetter.set_album(test_file, "Test Album")
|
|
56
|
+
|
|
57
|
+
# Delete only artists using library API
|
|
58
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
59
|
+
|
|
60
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
61
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.TITLE) == "Test Title"
|
|
62
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ALBUM) == "Test Album"
|
|
63
|
+
|
|
64
|
+
def test_delete_artists_already_none(self):
|
|
65
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
66
|
+
# Try to delete artists that don't exist
|
|
67
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: None}, metadata_format=MetadataFormat.ID3V2)
|
|
68
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) is None
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.test.helpers.id3v1 import ID3v1MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.id3v2 import ID3v2MetadataSetter
|
|
6
|
+
from audiometa.test.helpers.riff import RIFFMetadataSetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
8
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
9
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.integration
|
|
13
|
+
class TestArtistsReading:
|
|
14
|
+
def test_id3v1(self):
|
|
15
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file:
|
|
16
|
+
ID3v1MetadataSetter.set_max_metadata(test_file)
|
|
17
|
+
artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS)
|
|
18
|
+
assert artists == ["a" * 30]
|
|
19
|
+
|
|
20
|
+
def test_id3v2(self):
|
|
21
|
+
with temp_file_with_metadata({"title": "Test Song"}, "mp3") as test_file:
|
|
22
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
23
|
+
artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS)
|
|
24
|
+
assert artists == ["a" * 1000]
|
|
25
|
+
|
|
26
|
+
def test_vorbis(self):
|
|
27
|
+
with temp_file_with_metadata({"title": "Test Song"}, "flac") as test_file:
|
|
28
|
+
VorbisMetadataSetter.set_max_metadata(test_file)
|
|
29
|
+
artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS)
|
|
30
|
+
assert artists == ["a" * 1000]
|
|
31
|
+
|
|
32
|
+
def test_riff(self):
|
|
33
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
34
|
+
RIFFMetadataSetter.set_max_metadata(test_file)
|
|
35
|
+
artists = get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS)
|
|
36
|
+
assert artists == ["a" * 1000]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata, update_metadata
|
|
4
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
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 TestArtistsWriting:
|
|
12
|
+
def test_id3v2(self):
|
|
13
|
+
test_artists = ["Test Artist 1", "Test Artist 2"]
|
|
14
|
+
test_metadata = {UnifiedMetadataKey.ARTISTS: test_artists}
|
|
15
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
16
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
17
|
+
metadata = get_unified_metadata(test_file)
|
|
18
|
+
assert metadata.get(UnifiedMetadataKey.ARTISTS) == test_artists
|
|
19
|
+
|
|
20
|
+
def test_riff(self):
|
|
21
|
+
test_artists = ["RIFF Artist 1", "RIFF Artist 2"]
|
|
22
|
+
test_metadata = {UnifiedMetadataKey.ARTISTS: test_artists}
|
|
23
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
24
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
25
|
+
metadata = get_unified_metadata(test_file)
|
|
26
|
+
assert metadata.get(UnifiedMetadataKey.ARTISTS) == test_artists
|
|
27
|
+
|
|
28
|
+
def test_vorbis(self):
|
|
29
|
+
test_artists = ["Vorbis Artist 1", "Vorbis Artist 2"]
|
|
30
|
+
test_metadata = {UnifiedMetadataKey.ARTISTS: test_artists}
|
|
31
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
32
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
33
|
+
metadata = get_unified_metadata(test_file)
|
|
34
|
+
assert metadata.get(UnifiedMetadataKey.ARTISTS) == test_artists
|
|
35
|
+
|
|
36
|
+
def test_id3v1(self):
|
|
37
|
+
test_artists = ["ID3v1 Artist"]
|
|
38
|
+
test_metadata = {UnifiedMetadataKey.ARTISTS: test_artists}
|
|
39
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
40
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V1)
|
|
41
|
+
metadata = get_unified_metadata(test_file)
|
|
42
|
+
assert metadata.get(UnifiedMetadataKey.ARTISTS) == test_artists
|
|
43
|
+
|
|
44
|
+
def test_invalid_type_raises(self):
|
|
45
|
+
with temp_file_with_metadata({}, "mp3") as test_file, pytest.raises(InvalidMetadataFieldTypeError):
|
|
46
|
+
update_metadata(test_file, {UnifiedMetadataKey.ARTISTS: "Single Artist"})
|
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.id3v2 import ID3v2MetadataSetter
|
|
5
|
+
from audiometa.test.helpers.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
6
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
7
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
8
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
9
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.integration
|
|
13
|
+
class TestBpmDeleting:
|
|
14
|
+
def test_delete_bpm_id3v2(self):
|
|
15
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
16
|
+
ID3v2MetadataSetter.set_bpm(test_file, 120)
|
|
17
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) == 120
|
|
18
|
+
|
|
19
|
+
# Delete metadata using library API
|
|
20
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.ID3V2)
|
|
21
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) is None
|
|
22
|
+
|
|
23
|
+
def test_delete_bpm_id3v1(self):
|
|
24
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
25
|
+
|
|
26
|
+
with (
|
|
27
|
+
temp_file_with_metadata({}, "mp3") as test_file,
|
|
28
|
+
pytest.raises(MetadataFieldNotSupportedByMetadataFormatError),
|
|
29
|
+
):
|
|
30
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.ID3V1)
|
|
31
|
+
|
|
32
|
+
def test_delete_bpm_riff(self):
|
|
33
|
+
with temp_file_with_metadata({"bpm": 120}, "wav") as test_file:
|
|
34
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
35
|
+
assert "ibpm=120" in raw_metadata
|
|
36
|
+
|
|
37
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.RIFF)
|
|
38
|
+
raw_metadata_after = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
39
|
+
assert "ibpm=120" not in raw_metadata_after
|
|
40
|
+
|
|
41
|
+
def test_delete_bpm_vorbis(self):
|
|
42
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
43
|
+
VorbisMetadataSetter.set_bpm(test_file, 120)
|
|
44
|
+
assert (
|
|
45
|
+
get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM, metadata_format=MetadataFormat.VORBIS)
|
|
46
|
+
== 120
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.VORBIS)
|
|
50
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) is None
|
|
51
|
+
|
|
52
|
+
def test_delete_bpm_preserves_other_fields(self):
|
|
53
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
54
|
+
ID3v2MetadataSetter.set_bpm(test_file, 120)
|
|
55
|
+
ID3v2MetadataSetter.set_title(test_file, "Test Title")
|
|
56
|
+
ID3v2MetadataSetter.set_artists(test_file, "Test Artist")
|
|
57
|
+
|
|
58
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.ID3V2)
|
|
59
|
+
|
|
60
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) is None
|
|
61
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.TITLE) == "Test Title"
|
|
62
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Test Artist"]
|
|
63
|
+
|
|
64
|
+
def test_delete_bpm_already_none(self):
|
|
65
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
66
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.ID3V2)
|
|
67
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) is None
|
|
68
|
+
|
|
69
|
+
def test_delete_bpm_zero(self):
|
|
70
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
71
|
+
ID3v2MetadataSetter.set_bpm(test_file, 0)
|
|
72
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) == 0
|
|
73
|
+
|
|
74
|
+
update_metadata(test_file, {UnifiedMetadataKey.BPM: None}, metadata_format=MetadataFormat.ID3V2)
|
|
75
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM) is None
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
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 TestBpmReading:
|
|
12
|
+
def test_id3v1(self):
|
|
13
|
+
with (
|
|
14
|
+
temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file,
|
|
15
|
+
pytest.raises(MetadataFieldNotSupportedByMetadataFormatError),
|
|
16
|
+
):
|
|
17
|
+
get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM, metadata_format=MetadataFormat.ID3V1)
|
|
18
|
+
|
|
19
|
+
def test_id3v2(self):
|
|
20
|
+
with temp_file_with_metadata({"title": "Test Song", "bpm": 999}, "id3v2.4") as test_file:
|
|
21
|
+
bpm = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM, metadata_format=MetadataFormat.ID3V2)
|
|
22
|
+
assert bpm == 999
|
|
23
|
+
|
|
24
|
+
def test_vorbis(self):
|
|
25
|
+
with temp_file_with_metadata({"title": "Test Song", "bpm": 999}, "flac") as test_file:
|
|
26
|
+
bpm = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM, metadata_format=MetadataFormat.VORBIS)
|
|
27
|
+
assert bpm == 999
|
|
28
|
+
|
|
29
|
+
def test_riff(self):
|
|
30
|
+
with temp_file_with_metadata({"title": "Test Song", "bpm": 999}, "wav") as test_file:
|
|
31
|
+
bpm = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM, metadata_format=MetadataFormat.RIFF)
|
|
32
|
+
assert bpm == 999
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
5
|
+
from audiometa.utils.metadata_format import MetadataFormat
|
|
6
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.integration
|
|
10
|
+
class TestBpmWriting:
|
|
11
|
+
def test_id3v2(self):
|
|
12
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
13
|
+
test_bpm = 128
|
|
14
|
+
test_metadata = {UnifiedMetadataKey.BPM: test_bpm}
|
|
15
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
16
|
+
bpm = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM)
|
|
17
|
+
assert bpm == test_bpm
|
|
18
|
+
|
|
19
|
+
def test_riff(self):
|
|
20
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
21
|
+
test_bpm = 120
|
|
22
|
+
test_metadata = {UnifiedMetadataKey.BPM: test_bpm}
|
|
23
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
24
|
+
|
|
25
|
+
raw_metadata = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM)
|
|
26
|
+
assert raw_metadata == test_bpm
|
|
27
|
+
|
|
28
|
+
def test_vorbis(self):
|
|
29
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
30
|
+
test_bpm = 140
|
|
31
|
+
test_metadata = {UnifiedMetadataKey.BPM: test_bpm}
|
|
32
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
33
|
+
bpm = get_unified_metadata_field(test_file, UnifiedMetadataKey.BPM)
|
|
34
|
+
assert bpm == test_bpm
|
|
35
|
+
|
|
36
|
+
def test_id3v1(self):
|
|
37
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
38
|
+
|
|
39
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
40
|
+
test_bpm = 128
|
|
41
|
+
test_metadata = {UnifiedMetadataKey.BPM: test_bpm}
|
|
42
|
+
|
|
43
|
+
# ID3v1 format raises exception for unsupported metadata when format is forced
|
|
44
|
+
with pytest.raises(
|
|
45
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
46
|
+
match="UnifiedMetadataKey.BPM metadata not supported by ID3v1 format",
|
|
47
|
+
):
|
|
48
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V1)
|
|
49
|
+
|
|
50
|
+
def test_invalid_type_raises(self):
|
|
51
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
52
|
+
|
|
53
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
54
|
+
bad_metadata = {UnifiedMetadataKey.BPM: "not-an-int"}
|
|
55
|
+
with pytest.raises(InvalidMetadataFieldTypeError):
|
|
56
|
+
update_metadata(test_file, bad_metadata)
|
|
File without changes
|