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,39 @@
|
|
|
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.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
8
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
9
|
+
from audiometa.test.helpers.vorbis import VorbisMetadataSetter
|
|
10
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.integration
|
|
14
|
+
class TestLanguageReading:
|
|
15
|
+
def test_id3v1(self):
|
|
16
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file:
|
|
17
|
+
ID3v1MetadataSetter.set_max_metadata(test_file)
|
|
18
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
19
|
+
assert language is None
|
|
20
|
+
|
|
21
|
+
def test_id3v2(self):
|
|
22
|
+
with temp_file_with_metadata({"title": "Test Song"}, "mp3") as test_file:
|
|
23
|
+
ID3v2MetadataSetter.set_max_metadata(test_file)
|
|
24
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
25
|
+
assert language == "a" * 1000
|
|
26
|
+
|
|
27
|
+
def test_vorbis(self):
|
|
28
|
+
with temp_file_with_metadata({"title": "Test Song"}, "flac") as test_file:
|
|
29
|
+
VorbisMetadataSetter.set_max_metadata(test_file)
|
|
30
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
31
|
+
assert language == "a" * 1000
|
|
32
|
+
|
|
33
|
+
def test_riff(self):
|
|
34
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
35
|
+
RIFFMetadataSetter.set_language(test_file, "en")
|
|
36
|
+
assert "TAG:language=en" in RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
37
|
+
|
|
38
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
39
|
+
assert language == "en"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field, update_metadata
|
|
4
|
+
from audiometa.test.helpers.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
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 TestLanguageWriting:
|
|
12
|
+
def test_id3v2(self):
|
|
13
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
14
|
+
test_language = "en"
|
|
15
|
+
test_metadata = {UnifiedMetadataKey.LANGUAGE: test_language}
|
|
16
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
17
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
18
|
+
assert language == test_language
|
|
19
|
+
|
|
20
|
+
def test_riff(self):
|
|
21
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
22
|
+
test_language = "fr"
|
|
23
|
+
test_metadata = {UnifiedMetadataKey.LANGUAGE: test_language}
|
|
24
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
25
|
+
|
|
26
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
27
|
+
assert "TAG:language=fr" in raw_metadata
|
|
28
|
+
|
|
29
|
+
def test_vorbis(self):
|
|
30
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
31
|
+
test_language = "de"
|
|
32
|
+
test_metadata = {UnifiedMetadataKey.LANGUAGE: test_language}
|
|
33
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
34
|
+
language = get_unified_metadata_field(test_file, UnifiedMetadataKey.LANGUAGE)
|
|
35
|
+
assert language == test_language
|
|
36
|
+
|
|
37
|
+
def test_invalid_type_raises(self):
|
|
38
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
39
|
+
|
|
40
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
41
|
+
bad_metadata = {UnifiedMetadataKey.LANGUAGE: 123}
|
|
42
|
+
with pytest.raises(InvalidMetadataFieldTypeError):
|
|
43
|
+
update_metadata(test_file, bad_metadata)
|
|
File without changes
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import update_metadata
|
|
4
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
5
|
+
from audiometa.test.helpers.id3v2.id3v2_metadata_getter import ID3v2MetadataGetter
|
|
6
|
+
from audiometa.test.helpers.id3v2.id3v2_metadata_setter import ID3v2MetadataSetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
8
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_getter import VorbisMetadataGetter
|
|
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 TestLyricsDeleting:
|
|
15
|
+
def test_delete_lyrics_id3v1(self):
|
|
16
|
+
with (
|
|
17
|
+
temp_file_with_metadata({}, "mp3") as test_file,
|
|
18
|
+
pytest.raises(
|
|
19
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
20
|
+
match="UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS metadata not supported by ID3v1 format",
|
|
21
|
+
),
|
|
22
|
+
):
|
|
23
|
+
update_metadata(
|
|
24
|
+
test_file,
|
|
25
|
+
{UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: "Test lyrics"},
|
|
26
|
+
metadata_format=MetadataFormat.ID3V1,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def test_delete_lyrics_id3v2_3(self):
|
|
30
|
+
with temp_file_with_metadata({}, "id3v2.3") as test_file:
|
|
31
|
+
ID3v2MetadataSetter.set_lyrics(test_file, "Test lyrics", version="2.3")
|
|
32
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.3")
|
|
33
|
+
# 4 null bytes because of missing language
|
|
34
|
+
assert raw_metadata["USLT"] == ["\x00\x00\x00\x00Test lyrics"]
|
|
35
|
+
|
|
36
|
+
update_metadata(
|
|
37
|
+
test_file,
|
|
38
|
+
{UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None},
|
|
39
|
+
metadata_format=MetadataFormat.ID3V2,
|
|
40
|
+
id3v2_version=(2, 3, 0),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.3")
|
|
44
|
+
assert raw_metadata.get("USLT") is None
|
|
45
|
+
|
|
46
|
+
def test_delete_lyrics_id3v2_4(self):
|
|
47
|
+
with temp_file_with_metadata({}, "id3v2.4") as test_file:
|
|
48
|
+
ID3v2MetadataSetter.set_lyrics(test_file, "Test lyrics", version="2.4")
|
|
49
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.4")
|
|
50
|
+
assert raw_metadata["USLT"] == ["eng\x00Test lyrics"]
|
|
51
|
+
|
|
52
|
+
update_metadata(
|
|
53
|
+
test_file,
|
|
54
|
+
{UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None},
|
|
55
|
+
metadata_format=MetadataFormat.ID3V2,
|
|
56
|
+
id3v2_version=(2, 4, 0),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.4")
|
|
60
|
+
assert raw_metadata.get("USLT") is None
|
|
61
|
+
|
|
62
|
+
def test_delete_lyrics_riff(self):
|
|
63
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
64
|
+
from audiometa.test.helpers.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
65
|
+
from audiometa.test.helpers.riff.riff_metadata_setter import RIFFMetadataSetter
|
|
66
|
+
|
|
67
|
+
RIFFMetadataSetter.set_lyrics(test_file, "Test lyrics")
|
|
68
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
69
|
+
assert "TAG:lyrics=Test lyrics" in raw_metadata
|
|
70
|
+
|
|
71
|
+
update_metadata(
|
|
72
|
+
test_file, {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None}, metadata_format=MetadataFormat.RIFF
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
76
|
+
assert "TAG:lyrics=" not in raw_metadata
|
|
77
|
+
|
|
78
|
+
def test_delete_lyrics_vorbis(self):
|
|
79
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
80
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_setter import VorbisMetadataSetter
|
|
81
|
+
|
|
82
|
+
VorbisMetadataSetter.set_lyrics(test_file, "Test lyrics")
|
|
83
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
84
|
+
assert "LYRICS=Test lyrics" in raw_metadata
|
|
85
|
+
|
|
86
|
+
update_metadata(
|
|
87
|
+
test_file, {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None}, metadata_format=MetadataFormat.VORBIS
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
91
|
+
assert "LYRICS=" not in raw_metadata
|
|
92
|
+
|
|
93
|
+
def test_delete_lyrics_preserves_other_fields(self):
|
|
94
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
95
|
+
# Set multiple metadata fields using helper methods
|
|
96
|
+
ID3v2MetadataSetter.set_lyrics(test_file, "Test lyrics")
|
|
97
|
+
ID3v2MetadataSetter.set_title(test_file, "Test Title")
|
|
98
|
+
ID3v2MetadataSetter.set_artists(test_file, "Test Artist")
|
|
99
|
+
|
|
100
|
+
# Delete only lyrics using library API
|
|
101
|
+
update_metadata(
|
|
102
|
+
test_file, {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None}, metadata_format=MetadataFormat.ID3V2
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file)
|
|
106
|
+
assert raw_metadata is None
|
|
107
|
+
|
|
108
|
+
def test_delete_lyrics_already_none(self):
|
|
109
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
110
|
+
# Try to delete lyrics that don't exist
|
|
111
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
112
|
+
assert "LYRICS=" not in raw_metadata
|
|
113
|
+
|
|
114
|
+
update_metadata(
|
|
115
|
+
test_file, {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: None}, metadata_format=MetadataFormat.VORBIS
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
119
|
+
assert "LYRICS=" not in raw_metadata
|
|
120
|
+
|
|
121
|
+
def test_delete_lyrics_empty_string(self):
|
|
122
|
+
from audiometa import get_unified_metadata_field
|
|
123
|
+
|
|
124
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
125
|
+
update_metadata(
|
|
126
|
+
test_file, {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: ""}, metadata_format=MetadataFormat.ID3V2
|
|
127
|
+
)
|
|
128
|
+
lyrics = get_unified_metadata_field(test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS)
|
|
129
|
+
assert lyrics is None
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
5
|
+
from audiometa.test.helpers.id3v2.id3v2_metadata_setter import ID3v2MetadataSetter
|
|
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.metadata_format import MetadataFormat
|
|
10
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.mark.integration
|
|
14
|
+
class TestLyricsReading:
|
|
15
|
+
def test_id3v1(self):
|
|
16
|
+
with (
|
|
17
|
+
temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file,
|
|
18
|
+
pytest.raises(
|
|
19
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
20
|
+
match="UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS metadata not supported by ID3v1 format",
|
|
21
|
+
),
|
|
22
|
+
):
|
|
23
|
+
get_unified_metadata_field(
|
|
24
|
+
test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS, metadata_format=MetadataFormat.ID3V1
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def test_id3v2_3(self):
|
|
28
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v2.3") as test_file:
|
|
29
|
+
ID3v2MetadataSetter.set_lyrics(test_file, "a" * 4000, version="2.3")
|
|
30
|
+
lyrics = get_unified_metadata_field(
|
|
31
|
+
test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS, metadata_format=MetadataFormat.ID3V2
|
|
32
|
+
)
|
|
33
|
+
assert lyrics == "a" * 4000
|
|
34
|
+
|
|
35
|
+
def test_id3v2_4(self):
|
|
36
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v2.4") as test_file:
|
|
37
|
+
ID3v2MetadataSetter.set_lyrics(test_file, "a" * 4000, version="2.4")
|
|
38
|
+
lyrics = get_unified_metadata_field(
|
|
39
|
+
test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS, metadata_format=MetadataFormat.ID3V2
|
|
40
|
+
)
|
|
41
|
+
assert lyrics == "a" * 4000
|
|
42
|
+
|
|
43
|
+
def test_vorbis(self):
|
|
44
|
+
with temp_file_with_metadata({"title": "Test Song"}, "flac") as test_file:
|
|
45
|
+
VorbisMetadataSetter.set_lyrics(test_file, "a" * 4000)
|
|
46
|
+
lyrics = get_unified_metadata_field(
|
|
47
|
+
test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS, metadata_format=MetadataFormat.VORBIS
|
|
48
|
+
)
|
|
49
|
+
assert lyrics == "a" * 4000
|
|
50
|
+
|
|
51
|
+
def test_riff(self):
|
|
52
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
53
|
+
RIFFMetadataSetter.set_lyrics(test_file, "a" * 4000)
|
|
54
|
+
lyrics = get_unified_metadata_field(
|
|
55
|
+
test_file, UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS, metadata_format=MetadataFormat.RIFF
|
|
56
|
+
)
|
|
57
|
+
assert lyrics == "a" * 4000
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import update_metadata
|
|
4
|
+
from audiometa.test.helpers.id3v2.id3v2_header_verifier import ID3v2HeaderVerifier
|
|
5
|
+
from audiometa.test.helpers.id3v2.id3v2_metadata_getter import ID3v2MetadataGetter
|
|
6
|
+
from audiometa.test.helpers.riff.riff_metadata_getter import RIFFMetadataGetter
|
|
7
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
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 TestLyricsWriting:
|
|
14
|
+
def test_id3v2_3_default_en(self):
|
|
15
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
16
|
+
test_lyrics = "These are test lyrics\nWith multiple lines\nFor testing purposes"
|
|
17
|
+
test_metadata = {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: test_lyrics}
|
|
18
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2, id3v2_version=(2, 3, 0))
|
|
19
|
+
|
|
20
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.3")
|
|
21
|
+
assert [f"eng\x00{test_lyrics}"] == raw_metadata["USLT"]
|
|
22
|
+
|
|
23
|
+
def test_id3v2_4_default_en(self):
|
|
24
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
25
|
+
test_lyrics = "These are test lyrics\nWith multiple lines\nFor testing purposes"
|
|
26
|
+
test_metadata = {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: test_lyrics}
|
|
27
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2, id3v2_version=(2, 4, 0))
|
|
28
|
+
|
|
29
|
+
assert ID3v2HeaderVerifier.get_id3v2_version(test_file) == (2, 4, 0)
|
|
30
|
+
raw_metadata = ID3v2MetadataGetter.get_raw_metadata(test_file, version="2.4")
|
|
31
|
+
assert [f"eng\x00{test_lyrics}"] == raw_metadata["USLT"]
|
|
32
|
+
|
|
33
|
+
def test_riff(self):
|
|
34
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
35
|
+
test_lyrics = "RIFF test lyrics\nWith multiple lines\nFor testing purposes"
|
|
36
|
+
test_metadata = {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: test_lyrics}
|
|
37
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
38
|
+
|
|
39
|
+
raw_metadata = RIFFMetadataGetter.get_raw_metadata(test_file)
|
|
40
|
+
assert f"TAG:lyrics={test_lyrics}" in raw_metadata
|
|
41
|
+
|
|
42
|
+
def test_vorbis(self):
|
|
43
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_getter import VorbisMetadataGetter
|
|
44
|
+
|
|
45
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
46
|
+
test_lyrics = "Vorbis test lyrics\nWith multiple lines\nFor testing purposes"
|
|
47
|
+
test_metadata = {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: test_lyrics}
|
|
48
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
49
|
+
|
|
50
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
51
|
+
assert f"LYRICS={test_lyrics}" in raw_metadata
|
|
52
|
+
|
|
53
|
+
def test_invalid_type_raises(self):
|
|
54
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
55
|
+
|
|
56
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
57
|
+
bad_metadata = {UnifiedMetadataKey.UNSYNCHRONIZED_LYRICS: 12345}
|
|
58
|
+
with pytest.raises(InvalidMetadataFieldTypeError):
|
|
59
|
+
update_metadata(test_file, bad_metadata)
|
|
File without changes
|
|
@@ -0,0 +1,88 @@
|
|
|
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 TestPublisherDeleting:
|
|
11
|
+
def test_delete_publisher_id3v2(self):
|
|
12
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
13
|
+
update_metadata(
|
|
14
|
+
test_file, {UnifiedMetadataKey.PUBLISHER: "Test Publisher"}, metadata_format=MetadataFormat.ID3V2
|
|
15
|
+
)
|
|
16
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) == "Test Publisher"
|
|
17
|
+
|
|
18
|
+
update_metadata(test_file, {UnifiedMetadataKey.PUBLISHER: None}, metadata_format=MetadataFormat.ID3V2)
|
|
19
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) is None
|
|
20
|
+
|
|
21
|
+
def test_delete_publisher_id3v1(self):
|
|
22
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
23
|
+
|
|
24
|
+
with (
|
|
25
|
+
temp_file_with_metadata({}, "mp3") as test_file,
|
|
26
|
+
pytest.raises(
|
|
27
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
28
|
+
match="UnifiedMetadataKey.PUBLISHER metadata not supported by ID3v1 format",
|
|
29
|
+
),
|
|
30
|
+
):
|
|
31
|
+
update_metadata(
|
|
32
|
+
test_file,
|
|
33
|
+
{UnifiedMetadataKey.PUBLISHER: "Test Publisher"},
|
|
34
|
+
metadata_format=MetadataFormat.ID3V1,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def test_delete_publisher_riff(self):
|
|
38
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
39
|
+
|
|
40
|
+
with (
|
|
41
|
+
temp_file_with_metadata({}, "wav") as test_file,
|
|
42
|
+
pytest.raises(
|
|
43
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
44
|
+
match="UnifiedMetadataKey.PUBLISHER metadata not supported by RIFF format",
|
|
45
|
+
),
|
|
46
|
+
):
|
|
47
|
+
update_metadata(
|
|
48
|
+
test_file,
|
|
49
|
+
{UnifiedMetadataKey.PUBLISHER: "Test Publisher"},
|
|
50
|
+
metadata_format=MetadataFormat.RIFF,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def test_delete_publisher_vorbis(self):
|
|
54
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
55
|
+
update_metadata(
|
|
56
|
+
test_file, {UnifiedMetadataKey.PUBLISHER: "Test Publisher"}, metadata_format=MetadataFormat.VORBIS
|
|
57
|
+
)
|
|
58
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) == "Test Publisher"
|
|
59
|
+
|
|
60
|
+
update_metadata(test_file, {UnifiedMetadataKey.PUBLISHER: None}, metadata_format=MetadataFormat.VORBIS)
|
|
61
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) is None
|
|
62
|
+
|
|
63
|
+
def test_delete_publisher_preserves_other_fields(self):
|
|
64
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
65
|
+
update_metadata(
|
|
66
|
+
test_file,
|
|
67
|
+
{
|
|
68
|
+
UnifiedMetadataKey.PUBLISHER: "Test Publisher",
|
|
69
|
+
UnifiedMetadataKey.TITLE: "Test Title",
|
|
70
|
+
UnifiedMetadataKey.ARTISTS: ["Test Artist"],
|
|
71
|
+
},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
update_metadata(test_file, {UnifiedMetadataKey.PUBLISHER: None})
|
|
75
|
+
|
|
76
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) is None
|
|
77
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.TITLE) == "Test Title"
|
|
78
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.ARTISTS) == ["Test Artist"]
|
|
79
|
+
|
|
80
|
+
def test_delete_publisher_already_none(self):
|
|
81
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
82
|
+
update_metadata(test_file, {UnifiedMetadataKey.PUBLISHER: None})
|
|
83
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) is None
|
|
84
|
+
|
|
85
|
+
def test_delete_publisher_empty_string(self):
|
|
86
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
87
|
+
update_metadata(test_file, {UnifiedMetadataKey.PUBLISHER: ""}, metadata_format=MetadataFormat.ID3V2)
|
|
88
|
+
assert get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER) is None
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from audiometa import get_unified_metadata_field
|
|
4
|
+
from audiometa.test.helpers.temp_file_with_metadata import temp_file_with_metadata
|
|
5
|
+
from audiometa.test.helpers.vorbis.vorbis_metadata_getter import VorbisMetadataGetter
|
|
6
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.integration
|
|
10
|
+
class TestPublisherReading:
|
|
11
|
+
def test_id3v1(self):
|
|
12
|
+
with temp_file_with_metadata({"title": "Test Song"}, "id3v1") as test_file:
|
|
13
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
14
|
+
assert publisher is None
|
|
15
|
+
|
|
16
|
+
def test_id3v2(self):
|
|
17
|
+
with temp_file_with_metadata({"title": "Test Song", "publisher": "Test Publisher"}, "mp3") as test_file:
|
|
18
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
19
|
+
assert publisher == "Test Publisher"
|
|
20
|
+
|
|
21
|
+
def test_vorbis(self):
|
|
22
|
+
with temp_file_with_metadata({"title": "Test Song", "publisher": "Test Publisher"}, "flac") as test_file:
|
|
23
|
+
raw_metadata = VorbisMetadataGetter.get_raw_metadata(test_file)
|
|
24
|
+
assert "PUBLISHER=Test Publisher" in raw_metadata
|
|
25
|
+
|
|
26
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
27
|
+
assert publisher == "Test Publisher"
|
|
28
|
+
|
|
29
|
+
def test_riff(self):
|
|
30
|
+
with temp_file_with_metadata({"title": "Test Song"}, "wav") as test_file:
|
|
31
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
32
|
+
assert publisher is None
|
|
@@ -0,0 +1,47 @@
|
|
|
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 TestPublisherWriting:
|
|
11
|
+
def test_id3v2(self):
|
|
12
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
13
|
+
test_publisher = "Test Publisher ID3v2"
|
|
14
|
+
test_metadata = {UnifiedMetadataKey.PUBLISHER: test_publisher}
|
|
15
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.ID3V2)
|
|
16
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
17
|
+
assert publisher == test_publisher
|
|
18
|
+
|
|
19
|
+
def test_riff(self):
|
|
20
|
+
from audiometa.exceptions import MetadataFieldNotSupportedByMetadataFormatError
|
|
21
|
+
|
|
22
|
+
with temp_file_with_metadata({}, "wav") as test_file:
|
|
23
|
+
test_publisher = "Test Publisher RIFF"
|
|
24
|
+
test_metadata = {UnifiedMetadataKey.PUBLISHER: test_publisher}
|
|
25
|
+
|
|
26
|
+
# RIFF format raises exception for unsupported metadata
|
|
27
|
+
with pytest.raises(
|
|
28
|
+
MetadataFieldNotSupportedByMetadataFormatError,
|
|
29
|
+
match="UnifiedMetadataKey.PUBLISHER metadata not supported by RIFF format",
|
|
30
|
+
):
|
|
31
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.RIFF)
|
|
32
|
+
|
|
33
|
+
def test_vorbis(self):
|
|
34
|
+
with temp_file_with_metadata({}, "flac") as test_file:
|
|
35
|
+
test_publisher = "Test Publisher Vorbis"
|
|
36
|
+
test_metadata = {UnifiedMetadataKey.PUBLISHER: test_publisher}
|
|
37
|
+
update_metadata(test_file, test_metadata, metadata_format=MetadataFormat.VORBIS)
|
|
38
|
+
publisher = get_unified_metadata_field(test_file, UnifiedMetadataKey.PUBLISHER)
|
|
39
|
+
assert publisher == test_publisher
|
|
40
|
+
|
|
41
|
+
def test_invalid_type_raises(self):
|
|
42
|
+
from audiometa.exceptions import InvalidMetadataFieldTypeError
|
|
43
|
+
|
|
44
|
+
with temp_file_with_metadata({}, "mp3") as test_file:
|
|
45
|
+
bad_metadata = {UnifiedMetadataKey.PUBLISHER: 123}
|
|
46
|
+
with pytest.raises(InvalidMetadataFieldTypeError):
|
|
47
|
+
update_metadata(test_file, bad_metadata)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from audiometa import get_unified_metadata
|
|
6
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.integration
|
|
10
|
+
class TestBase100Proportional:
|
|
11
|
+
@pytest.mark.parametrize(
|
|
12
|
+
("star_rating", "expected_normalized_rating"),
|
|
13
|
+
[
|
|
14
|
+
(0, 0),
|
|
15
|
+
(0.5, 10),
|
|
16
|
+
(1, 20),
|
|
17
|
+
(1.5, 30),
|
|
18
|
+
(2, 40),
|
|
19
|
+
(2.5, 50),
|
|
20
|
+
(3, 60),
|
|
21
|
+
(3.5, 70),
|
|
22
|
+
(4, 80),
|
|
23
|
+
(4.5, 90),
|
|
24
|
+
(5, 100),
|
|
25
|
+
],
|
|
26
|
+
)
|
|
27
|
+
def test_vorbis(self, assets_dir: Path, star_rating, expected_normalized_rating):
|
|
28
|
+
file_path = assets_dir / f"rating_vorbis={star_rating} star.flac"
|
|
29
|
+
metadata = get_unified_metadata(file_path, normalized_rating_max_value=100)
|
|
30
|
+
rating = metadata.get(UnifiedMetadataKey.RATING)
|
|
31
|
+
assert rating is not None
|
|
32
|
+
assert isinstance(rating, int | float)
|
|
33
|
+
assert rating == expected_normalized_rating
|
|
34
|
+
|
|
35
|
+
@pytest.mark.parametrize(
|
|
36
|
+
("star_rating", "expected_normalized_rating"),
|
|
37
|
+
[
|
|
38
|
+
(0, 0),
|
|
39
|
+
(0.5, 10),
|
|
40
|
+
(1, 20),
|
|
41
|
+
(1.5, 30),
|
|
42
|
+
(2, 40),
|
|
43
|
+
(2.5, 50),
|
|
44
|
+
(3, 60),
|
|
45
|
+
(3.5, 70),
|
|
46
|
+
(4, 80),
|
|
47
|
+
(4.5, 90),
|
|
48
|
+
(5, 100),
|
|
49
|
+
],
|
|
50
|
+
)
|
|
51
|
+
def test_id3v2(self, assets_dir: Path, star_rating, expected_normalized_rating):
|
|
52
|
+
file_path = assets_dir / f"rating_id3v2_base 100={star_rating} star.wav"
|
|
53
|
+
metadata = get_unified_metadata(file_path, normalized_rating_max_value=100)
|
|
54
|
+
rating = metadata.get(UnifiedMetadataKey.RATING)
|
|
55
|
+
assert rating is not None
|
|
56
|
+
assert isinstance(rating, int | float)
|
|
57
|
+
assert rating == expected_normalized_rating
|
|
58
|
+
|
|
59
|
+
@pytest.mark.parametrize(
|
|
60
|
+
("star_rating", "expected_normalized_rating"),
|
|
61
|
+
[
|
|
62
|
+
(1, 20),
|
|
63
|
+
(2, 40),
|
|
64
|
+
(3, 60),
|
|
65
|
+
(4, 80),
|
|
66
|
+
(5, 100),
|
|
67
|
+
],
|
|
68
|
+
)
|
|
69
|
+
def test_wav_riff(self, assets_dir: Path, star_rating, expected_normalized_rating):
|
|
70
|
+
file_path = assets_dir / f"rating_riff_base 100_kid3={star_rating} star.wav"
|
|
71
|
+
metadata = get_unified_metadata(file_path, normalized_rating_max_value=100)
|
|
72
|
+
rating = metadata.get(UnifiedMetadataKey.RATING)
|
|
73
|
+
assert rating is not None
|
|
74
|
+
assert isinstance(rating, int | float)
|
|
75
|
+
assert rating == expected_normalized_rating
|
|
76
|
+
|
|
77
|
+
def test_none_rating_wav_riff(self, assets_dir: Path):
|
|
78
|
+
file_path = assets_dir / "rating_riff_kid3=none.wav"
|
|
79
|
+
metadata = get_unified_metadata(file_path, normalized_rating_max_value=100)
|
|
80
|
+
rating = metadata.get(UnifiedMetadataKey.RATING)
|
|
81
|
+
assert rating is None
|
audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_non_proportional.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from audiometa import get_unified_metadata
|
|
6
|
+
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.mark.integration
|
|
10
|
+
class TestBase255NonProportional:
|
|
11
|
+
@pytest.mark.parametrize(
|
|
12
|
+
("star_rating", "expected_normalized_rating"),
|
|
13
|
+
[
|
|
14
|
+
(0, 0),
|
|
15
|
+
(0.5, 10),
|
|
16
|
+
(1, 20),
|
|
17
|
+
(1.5, 30),
|
|
18
|
+
(2, 40),
|
|
19
|
+
(2.5, 50),
|
|
20
|
+
(3, 60),
|
|
21
|
+
(3.5, 70),
|
|
22
|
+
(4, 80),
|
|
23
|
+
(4.5, 90),
|
|
24
|
+
(5, 100),
|
|
25
|
+
],
|
|
26
|
+
)
|
|
27
|
+
def test_id3v2_mp3(self, assets_dir: Path, star_rating, expected_normalized_rating):
|
|
28
|
+
file_path = assets_dir / f"rating_id3v2={star_rating} star.mp3"
|
|
29
|
+
metadata = get_unified_metadata(file_path, normalized_rating_max_value=100)
|
|
30
|
+
rating = metadata.get(UnifiedMetadataKey.RATING)
|
|
31
|
+
assert rating is not None
|
|
32
|
+
assert isinstance(rating, int | float)
|
|
33
|
+
assert rating == expected_normalized_rating
|