"""Logic for Manager. Manages data retrieval, validation and synchronization """ from types import ModuleType from typing import Any from gridgen.exceptions import ( ReleaseLookupError, ReleaseNotFound, TrackListingNotFound, TrackLookupError, TrackNotFound, ValidateInternalError, ValidateNotFoundError, ) from gridgen.logic import processor from gridgen.models import metadata from gridgen.models.datasource import delphi, orchard from gridgen.models.metadata import ReleaseIdMeta, TrackIdMeta def validate(release_id: int) -> dict[str, Any]: """Logic handler for release validation. Args: release_id (int): the id of the release to validate. Returns: dict: retrieved data and validation errors. """ result: dict[str, Any] = {"system_errors": [], "release": {}, "tracks": {}} release_id_meta = orchard.lookup_release_identifiers(release_id) track_id_list = orchard.lookup_track_list(release_id_meta) try: ar_build = build_release(release_id_meta, orchard, track_id_list) except (ReleaseLookupError, TrackLookupError) as e: result["system_errors"].append( "{}-{}".format(e.name.replace(" ", "_").lower(), e.description) ) raise ValidateInternalError(result) from e try: gras_build = build_release(release_id_meta, delphi, track_id_list) except (ReleaseLookupError, TrackLookupError) as e: result["system_errors"].append( "{}-{}".format(e.name.replace(" ", "_").lower(), e.description) ) raise ValidateInternalError(result) from e if not ar_build.metadata: result["system_errors"].append( "Error locating release from art_relations for {}.".format( release_id_meta.upc ) ) raise ValidateInternalError(result) if ar_build.metadata.format == "digital" and not ar_build.tracks: result["system_errors"].append( "Error locating track list from art_relations for {}".format( release_id_meta.upc ) ) raise ValidateNotFoundError(result) validation = processor.validate_release(ar_build, gras_build) if validation: result["release"] = validation["data"] for track_id_meta in track_id_list: validation = processor.validate_track(ar_build, gras_build, track_id_meta) if validation: result["tracks"][validation["id"]] = validation["data"] return result def synchronize(release_id: int) -> str: """Logic handler for release synchronization. Args: release_id (int): the id of the release to validate. Returns: str: the UPC if a delivery message should be sent, otherwise empty string. """ release_id_meta = orchard.lookup_release_identifiers(release_id) track_id_list = orchard.lookup_track_list(release_id_meta) ar_release = build_release(release_id_meta, orchard, track_id_list) gras_release = build_release(release_id_meta, delphi, track_id_list) send_message = False if not ar_release or not ar_release.metadata: raise ReleaseNotFound(f"{release_id_meta.upc} not found in database.") if ar_release.metadata.format == "digital": # check for the missing track list if not ar_release.tracks: raise TrackListingNotFound( f"Error locating track list for {release_id_meta.upc}." ) for track_id_meta in track_id_list: send_message = ( processor.synch_track(ar_release, gras_release, track_id_meta) or send_message ) if processor.synch_release(ar_release, gras_release) or send_message: return release_id_meta.upc return "" def build_release( meta_id: ReleaseIdMeta, meta_datasource: ModuleType, track_id_list: list[TrackIdMeta] | None = None, ) -> metadata.Release: """Construct a release. Build a release metadata collection object by querying metadata and track list data source modules. Args: meta_id (ReleaseIdMeta): identifier info of release. meta_datasource (impl lookup_track and lookup_release): Source of release and track metadata, likely a module. track_id_list (list): A list of TrackIdMeta values. Returns: Release: the constructed release. """ try: release = metadata.Release(meta_datasource.lookup_release(meta_id)) except ReleaseNotFound: release = metadata.Release(None) except Exception as e: raise ReleaseLookupError( "Error retrieving release info for {}.".format(meta_id.upc) ) from e if track_id_list: for track_id_meta in track_id_list: try: release.add_track(meta_datasource.lookup_track(track_id_meta)) except TrackNotFound: continue except Exception as e: raise TrackLookupError( "Error retrieving track info for {}.".format(track_id_meta.isrc) ) from e return release