metadata_utils
¶
Metadata Helpers Module.
Provides utility functions for parsing, cleaning, and processing music track metadata. These functions are designed to be independent of specific service instances and can be used across different parts of the application.
Functions:
| Name | Description |
|---|---|
- parse_tracks |
Parses raw AppleScript output into structured track dictionaries. |
- group_tracks_by_artist |
Groups track dictionaries by artist name. |
- determine_dominant_genre_for_artist |
Determines the most likely genre for an artist. |
- remove_parentheses_with_keywords |
Removes specified parenthetical content from strings. |
- clean_names |
Applies cleaning rules to track and album names. |
- is_music_app_running |
Checks if Music.app is currently running. |
AppleScriptFieldIndex
¶
Bases: IntEnum
Field positions in AppleScript output.
These are indices into the field array returned by AppleScript, NOT semantic names for TrackDict fields. The naming reflects what AppleScript actually provides at each position.
AppleScript field order (from fetch_tracks.applescript): {track_id, track_name, track_artist, album_artist, track_album, track_genre, date_added, modification_date, track_status, track_year, release_year, ""}
reset_cleaning_exceptions_log
¶
parse_tracks
¶
Parse raw AppleScript output into a list of track dictionaries.
Uses the Record Separator (U+001E) as the field delimiter and Group Separator (U+001D) as the line delimiter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw_data
|
str
|
Raw string data from AppleScript. |
required |
error_logger
|
Logger
|
Logger for error output. |
required |
Returns:
| Type | Description |
|---|---|
list[TrackDict]
|
List of TrackDict instances parsed from the input data. |
Source code in src/core/models/metadata_utils.py
group_tracks_by_artist
¶
Group tracks by album_artist or normalized artist.
Uses album_artist when available to properly handle collaboration tracks. Falls back to normalized artist when album_artist is empty.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
list[TrackDict]
|
List of track dictionaries to group. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[TrackDict]]
|
Dictionary mapping normalized artist names to lists of their tracks. |
Source code in src/core/models/metadata_utils.py
determine_dominant_genre_for_artist
¶
Determine the dominant genre for an artist based on earliest album.
Algorithm
- Find the earliest track for each album (by date_added).
- Determine the earliest album (by date_added of its earliest track).
- Use the genre of the earliest track in that album as dominant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist_tracks
|
Sequence[TrackDict]
|
List of track dictionaries for a single artist. |
required |
error_logger
|
Logger
|
Logger for error output. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The dominant genre string, or "Unknown" if no tracks or on error. |
Source code in src/core/models/metadata_utils.py
remove_parentheses_with_keywords
¶
Remove any parenthetical segment that contains at least one of the given keywords.
This implementation uses balanced parentheses parsing to properly handle nested parentheses/brackets (e.g., "Album (Reissue (2024))" -> "Album"). It scans for opening brackets, finds the matching closing bracket, and removes the entire segment if it contains any of the keywords (case-insensitive).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The string to process |
required |
keywords
|
list[str]
|
List of keywords to search for in parenthetical segments |
required |
console_logger
|
Logger
|
Logger for debug output |
required |
error_logger
|
Logger
|
Logger for error output |
required |
Returns:
| Type | Description |
|---|---|
str
|
The cleaned string with matching parenthetical segments removed |
Source code in src/core/models/metadata_utils.py
clean_names
¶
Clean track and album names per config: remove remaster segments and suffixes.
Skips artist+album pairs in exceptions list. Collapses excess whitespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name (used for exception checking). |
required |
track_name
|
str
|
Raw track title to clean. |
required |
album_name
|
str
|
Raw album title to clean. |
required |
config
|
AppConfig
|
Typed application configuration. |
required |
console_logger
|
Logger
|
Logger for debug/info output. |
required |
error_logger
|
Logger
|
Logger for error reporting. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str]
|
Tuple of (cleaned_track_name, cleaned_album_name). |
Source code in src/core/models/metadata_utils.py
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | |
is_music_app_running
¶
Check if the Music.app is currently running using subprocess.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error_logger
|
Logger
|
Logger for error output. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if Music.app is running, False otherwise. |