"""Model for ows-product.""" from http import HTTPStatus from typing import Any from owsrequest import request from video import config from video.constants import service from video.exceptions import ProductOwnershipError, ReleaseNotFound def generate_placeholder_upc() -> str: """Generate a placeholder upc value. Returns: str: placeholder upc value Raises: requests.exceptions.HTTPError: if the upstream service returns an error. """ upc_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="POST", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path="/upc/placeholder", ) upc_response.raise_for_status() return upc_response.json()["placeholder_upc"] def check_product_ownership( product_id: int, account_type: int | str | None = None, account_id: int | str | None = None, ) -> None: """Check product ownership. Args: product_id (int): product id. account_type (str): Grass account type. account_id (str): Grass account id. Raises: ProductOwnershipError: if the upstream service denies access. """ if not account_type and not account_id: return request_url = "/{ACCOUNT_TYPE}/{ACCOUNT_ID}/product/{PRODUCT_ID}".format( ACCOUNT_TYPE=account_type, ACCOUNT_ID=account_id, PRODUCT_ID=product_id ) ownership_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="HEAD", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=request_url, ) if ownership_response.status_code == HTTPStatus.NOT_FOUND: raise ReleaseNotFound() if not ownership_response.ok: raise ProductOwnershipError() def check_product_code_exists( product_code: int | str, account_type: int | str, account_id: int | str, exclude_product_id: int, ) -> bool: """Check product code usage. Returns: bool: True if the product code is in use, False if not. """ request_url = ( "/{ACCOUNT_TYPE}/" "{ACCOUNT_ID}/" "product_code/" "{PRODUCT_CODE}?exclude_product_id={PRODUCT_ID}" ).format( ACCOUNT_TYPE=account_type, ACCOUNT_ID=account_id, PRODUCT_CODE=product_code, PRODUCT_ID=exclude_product_id, ) usage_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="HEAD", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=request_url, ) if usage_response.status_code == HTTPStatus.NOT_FOUND: return False usage_response.raise_for_status() return True def create_subgenre(product_id: int, data: dict[str, Any]) -> dict[str, Any]: """Create a subgenre.""" subgenre_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="POST", service_name=service.OWS_PRODUCT, path=f"/product/{product_id}/subgenre", uwsgi_cache_enabled=True, json=data, ) subgenre_response.raise_for_status() return subgenre_response.json() def update_subgenre(product_id: int, data: dict[str, Any]) -> dict[str, Any]: """Update a subgenre.""" subgenre_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="PUT", service_name=service.OWS_PRODUCT, path=f"/product/{product_id}/subgenre", uwsgi_cache_enabled=True, json=data, ) subgenre_response.raise_for_status() return subgenre_response.json() def get_subgenre(product_id: int) -> dict[str, Any]: """Get a subgenre. Returns: dict[str, Any]: subgenre data, or {} if not found (404). """ subgenre_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="GET", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/subgenre", ) if subgenre_response.status_code == HTTPStatus.NOT_FOUND: return {} subgenre_response.raise_for_status() return subgenre_response.json() def delete_subgenre(product_id: int) -> None: """Delete a subgenre.""" subgenre_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="DELETE", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/subgenre", ) subgenre_response.raise_for_status() def create_contributor(product_id: int, data: dict[str, Any]) -> dict[str, Any]: """Create an artist.""" artist_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="POST", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/artist", json=data, ) artist_response.raise_for_status() return artist_response.json() def update_artist(product_id: int, data: dict[str, Any]) -> dict[str, Any]: """Update an artist.""" artist_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="PUT", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/artist", json=data, ) artist_response.raise_for_status() return artist_response.json() def get_artist(product_id: int) -> dict[str, Any]: """Get an artist.""" artist_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="GET", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/artist", ) artist_response.raise_for_status() return artist_response.json() def delete_contributors(product_id: int) -> None: """Delete contributors.""" artist_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="DELETE", service_name=service.OWS_PRODUCT, uwsgi_cache_enabled=True, path=f"/product/{product_id}/artist", ) artist_response.raise_for_status() def get_provisioned_upc(mark_used: bool = False) -> str: """Get a provisioned upc value. Args: mark_used (bool): default is False but when True UPC status updates to used. Returns: str: upc value Raises: requests.exceptions.HTTPError: if the upstream service returns an error. """ upc_response = request.process( application=config.SERVICE_NAME, environment=config.ENVIRONMENT, method="POST", service_name=service.OWS_PRODUCT, path="/upc/provision", uwsgi_cache_enabled=True, json={"mark_used": mark_used}, ) upc_response.raise_for_status() return upc_response.json()["upc"]