MusicIndexer/src/local/ParseLocal.py
Шурупов Илья Викторович 5f4bbbaa59 refactor 2
2026-01-04 23:40:41 +03:00

139 lines
3.3 KiB
Python

import json
import re
from src.Library import *
import re
PROTECTED_ARTISTS = {
"Tyler, The Creator",
"The Good, The Bad & The Queen",
}
def split_artists(artist_tag: str) -> list[str]:
if not artist_tag:
return []
placeholder_comma = "§COMMA§"
placeholder_amp = "§AMP§"
protected_map = {}
# Protect known artist names
for artist in PROTECTED_ARTISTS:
protected = (
artist
.replace(",", placeholder_comma)
.replace("&", placeholder_amp)
)
protected_map[protected] = artist
artist_tag = artist_tag.replace(artist, protected)
# Split remaining separators
parts = re.split(r"[,&]", artist_tag)
# Restore protected names and trim spaces
result = []
for part in parts:
part = part.strip()
if not part:
continue
part = (
part
.replace(placeholder_comma, ",")
.replace(placeholder_amp, "&")
)
result.append(part)
return result
class LocalParser:
def __init__(self):
self.track_map: dict[str, Track] = {}
self.artist_map: dict[str, Artist] = {}
self.album_map: dict[str, Album] = {}
self.library = Library()
def parse_artists(self, data: str) -> List[Artist]:
if not data:
data = "unknown"
data = split_artists(data)
artists = []
for artist_data in data:
name = artist_data
artist_id = name
if artist_id in self.artist_map:
artists.append(self.artist_map[artist_id])
continue
artist = Artist()
artist.id = artist_id
artist.title = name
self.artist_map[artist_id] = artist
self.library.artists.append(artist)
artists.append(artist)
return artists
def parse_album(self, data: str) -> Album:
if not data:
data = "unknown"
name = data
album_id = name
if album_id in self.album_map:
return self.album_map[album_id]
album = Album()
album.id = album_id
album.title = name
self.album_map[album_id] = album
self.library.albums.append(album)
return album
def add_tracks_to_albums_and_artists(self):
for track_id, track in self.track_map.items():
for artist in track.artists:
if track not in artist.tracks:
artist.tracks.append(track)
if track not in track.album.tracks:
track.album.tracks.append(track)
def parse(self, tracks_file: Path) -> Library:
tracks_content = json.loads(tracks_file.read_text())
for track_id, data in tracks_content.items():
track = Track()
track.id = track_id
track.title = data.get("name")
track.artists = self.parse_artists(data.get("artist"))
track.album = self.parse_album(data.get("album"))
track.local_path = data.get("path")
self.track_map[track.id] = track
self.library.tracks.append(track)
self.add_tracks_to_albums_and_artists()
return self.library
def parse_track_item(self, id, track: dict[str, Any]) -> Track:
return track