Skip to content

Commit

Permalink
Rework ID3v2 user text frame abstractions [#22]
Browse files Browse the repository at this point in the history
* Add ``ID3v2UserText`` class.
* Change ``ID3v2UserTextFrame`` to have only value attribute.
  that contains a single user text object.
* Change ``ID3v2Frames`` to present a list of user text
  objects for ``TXXX`` key.
  • Loading branch information
thebigmunch committed Mar 5, 2020
1 parent f39bc1b commit 56f7aca
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ This project adheres to [Semantic Versioning](https://semver.org).
* ``ID3v2GeneralEncapsulatedObject``.
* ``ID3v2PrivateInfo``.
* ``ID3v2UserURLLink``.
* ``ID3v2UserText``.

### Changed

Expand Down Expand Up @@ -71,6 +72,12 @@ This project adheres to [Semantic Versioning](https://semver.org).
that contains a single user URL link object.
* Change ``ID3v2Frames`` to present a list of user URL link
objects for ``WXXX`` key.
* Rework ID3v2 user text frame abstractions.
* Add ``ID3v2UserText`` class.
* Change ``ID3v2UserTextFrame`` to have only value attribute.
that contains a single user text object.
* Change ``ID3v2Frames`` to present a list of user text
objects for ``TXXX`` key.

### Removed

Expand Down
7 changes: 1 addition & 6 deletions src/audio_metadata/formats/id3v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def parse(cls, data, id3_version):
f"Ignoring '{frame.id}' frame with value '{frame.value}'.\n"
f"'{frame.id}' is not supported in the ID3v2.{id3_version.value[1]} specification.\n"
),
AudioMetadataWarning
AudioMetadataWarning,
)
continue

Expand All @@ -264,11 +264,6 @@ def parse(cls, data, id3_version):
),
):
frames[f'{frame.id}:{frame.description}:{frame.language}'].append(frame.value)
elif isinstance(
frame,
ID3v2UserTextFrame,
):
frames[f'{frame.id}:{frame.description}'].append(frame.value)
elif isinstance(
frame,
(
Expand Down
27 changes: 19 additions & 8 deletions src/audio_metadata/formats/id3v2_frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
'ID3v2TimestampFrame',
'ID3v2UnsynchronizedLyricsFrame',
'ID3v2URLLinkFrame',
'ID3v2UserText',
'ID3v2UserTextFrame',
'ID3v2UserURLLink',
'ID3v2UserURLLinkFrame',
Expand Down Expand Up @@ -111,6 +112,15 @@ class ID3v2PrivateInfo(AttrMapping):
data = attrib()


@attrs(
repr=False,
kw_only=True,
)
class ID3v2UserText(AttrMapping):
description = attrib()
text = attrib()


@attrs(
repr=False,
kw_only=True,
Expand Down Expand Up @@ -319,7 +329,6 @@ class ID3v2UserURLLinkFrame(ID3v2BaseFrame):
kw_only=True,
)
class ID3v2UserTextFrame(ID3v2BaseFrame):
description = attrib()
value = attrib()


Expand Down Expand Up @@ -711,6 +720,14 @@ def parse(cls, data, struct_pattern, size_len, per_byte):
kwargs['value'] = decode_bytestring(description, encoding)
elif frame_type is ID3v2URLLinkFrame:
kwargs['value'] = unquote(decode_bytestring(frame_data))
elif frame_type is ID3v2UserTextFrame:
encoding = determine_encoding(frame_data)

description, text = split_encoded(frame_data[1:], encoding)
kwargs['value'] = ID3v2UserText(
description=decode_bytestring(description, encoding),
text=decode_bytestring(text, encoding),
)
elif frame_type is ID3v2UserURLLinkFrame:
encoding = determine_encoding(frame_data)

Expand All @@ -719,13 +736,7 @@ def parse(cls, data, struct_pattern, size_len, per_byte):
description=decode_bytestring(description, encoding),
url=unquote(decode_bytestring(url)),
)
elif issubclass(
frame_type,
(
ID3v2NumberFrame,
ID3v2UserTextFrame,
),
):
elif issubclass(frame_type, ID3v2NumberFrame):
encoding = determine_encoding(frame_data[0:1])
kwargs['value'] = decode_bytestring(frame_data[1:], encoding)
elif issubclass(
Expand Down

0 comments on commit 56f7aca

Please sign in to comment.