HRVC / src /ultimate_rvc /core /exceptions.py
SpyC0der77's picture
Upload folder using huggingface_hub
1a942eb verified
"""
Module which defines custom exception and enumerations used when
instiating and re-raising those exceptions.
"""
from enum import StrEnum
from ultimate_rvc.typing_extra import StrPath
class Entity(StrEnum):
"""Enumeration of entities that can be provided."""
DIRECTORY = "directory"
DIRECTORIES = "directories"
FILE = "file"
FILES = "files"
URL = "URL"
MODEL_NAME = "model name"
MODEL_NAMES = "model names"
MODEL_FILE = "model file"
SOURCE = "source"
SONG_DIR = "song directory"
AUDIO_TRACK = "audio track"
AUDIO_TRACK_GAIN_PAIRS = "pairs of audio track and gain"
SONG = "song"
VOCALS_TRACK = "vocals track"
INSTRUMENTALS_TRACK = "instrumentals track"
BACKUP_VOCALS_TRACK = "backup vocals track"
MAIN_VOCALS_TRACK = "main vocals track"
class Location(StrEnum):
"""Enumeration of locations where entities can be found."""
INTERMEDIATE_AUDIO_ROOT = "the root of the intermediate audio base directory"
OUTPUT_AUDIO_ROOT = "the root of the output audio directory"
EXTRACTED_ZIP_FILE = "extracted zip file"
class UIMessage(StrEnum):
"""
Enumeration of messages that can be displayed in the UI
in place of core exception messages.
"""
NO_AUDIO_TRACK = "No audio tracks provided."
NO_SONG_DIR = "No song directory selected."
NO_SONG_DIRS = (
"No song directories selected. Please select one or more song directories"
" containing intermediate audio files to delete."
)
NO_OUTPUT_AUDIO_FILES = (
"No files selected. Please select one or more output audio files to delete."
)
NO_UPLOADED_FILES = "No files selected."
NO_VOICE_MODEL = "No voice model selected."
NO_VOICE_MODELS = "No voice models selected."
NO_SOURCE = (
"No source provided. Please provide a valid Youtube URL, local audio file"
" or song directory."
)
class NotProvidedError(ValueError):
"""Raised when an entity is not provided."""
def __init__(self, entity: Entity, ui_msg: UIMessage | None = None) -> None:
"""
Initialize a NotProvidedError instance.
Exception message will be formatted as:
"No `<entity>` provided."
Parameters
----------
entity : Entity
The entity that was not provided.
ui_msg : UIMessage, default=None
Message which, if provided, is displayed in the UI
instead of the default exception message.
"""
super().__init__(f"No {entity} provided.")
self.ui_msg = ui_msg
class NotFoundError(OSError):
"""Raised when an entity is not found."""
def __init__(
self,
entity: Entity,
location: StrPath | Location,
is_path: bool = True,
) -> None:
"""
Initialize a NotFoundError instance.
Exception message will be formatted as:
"`<entity>` not found `(`in `|` as:`)` `<location>`."
Parameters
----------
entity : Entity
The entity that was not found.
location : StrPath | Location
The location where the entity was not found.
is_path : bool, default=True
Whether the location is a path to the entity.
"""
proposition = "at:" if is_path else "in"
entity_cap = entity.capitalize() if not entity.isupper() else entity
super().__init__(
f"{entity_cap} not found {proposition} {location}",
)
class VoiceModelNotFoundError(OSError):
"""Raised when a voice model is not found."""
def __init__(self, name: str) -> None:
r"""
Initialize a VoiceModelNotFoundError instance.
Exception message will be formatted as:
'Voice model with name "`<name>`" not found.'
Parameters
----------
name : str
The name of the voice model that was not found.
"""
super().__init__(f'Voice model with name "{name}" not found.')
class VoiceModelExistsError(OSError):
"""Raised when a voice model already exists."""
def __init__(self, name: str) -> None:
r"""
Initialize a VoiceModelExistsError instance.
Exception message will be formatted as:
"Voice model with name '`<name>`' already exists. Please provide
a different name for your voice model."
Parameters
----------
name : str
The name of the voice model that already exists.
"""
super().__init__(
f'Voice model with name "{name}" already exists. Please provide a different'
" name for your voice model.",
)
class InvalidLocationError(OSError):
"""Raised when an entity is in a wrong location."""
def __init__(self, entity: Entity, location: Location, path: StrPath) -> None:
r"""
Initialize an InvalidLocationError instance.
Exception message will be formatted as:
"`<entity>` should be located in `<location>` but found at:
`<path>`"
Parameters
----------
entity : Entity
The entity that is in a wrong location.
location : Location
The correct location for the entity.
path : StrPath
The path to the entity.
"""
entity_cap = entity.capitalize() if not entity.isupper() else entity
super().__init__(
f"{entity_cap} should be located in {location} but found at: {path}",
)
class HttpUrlError(OSError):
"""Raised when a HTTP-based URL is invalid."""
def __init__(self, url: str) -> None:
"""
Initialize a HttpUrlError instance.
Exception message will be formatted as:
"Invalid HTTP-based URL: `<url>`"
Parameters
----------
url : str
The invalid HTTP-based URL.
"""
super().__init__(
f"Invalid HTTP-based URL: {url}",
)
class YoutubeUrlError(OSError):
"""
Raised when an URL does not point to a YouTube video or
, potentially, a Youtube playlist.
"""
def __init__(self, url: str, playlist: bool) -> None:
"""
Initialize a YoutubeURlError instance.
Exception message will be formatted as:
"URL does not point to a YouTube video `[`or playlist`]`:
`<url>`"
Parameters
----------
url : str
The URL that does not point to a YouTube video or playlist.
playlist : bool
Whether the URL might point to a YouTube playlist.
"""
suffix = "or playlist" if playlist else ""
super().__init__(
f"Not able to access Youtube video {suffix} at: {url}",
)
class UploadLimitError(ValueError):
"""Raised when the upload limit for an entity is exceeded."""
def __init__(self, entity: Entity, limit: str | float) -> None:
"""
Initialize an UploadLimitError instance.
Exception message will be formatted as:
"At most `<limit>` `<entity>` can be uploaded."
Parameters
----------
entity : Entity
The entity for which the upload limit was exceeded.
limit : str
The upload limit.
"""
super().__init__(f"At most {limit} {entity} can be uploaded.")
class UploadFormatError(ValueError):
"""
Raised when one or more uploaded entities have an invalid format
.
"""
def __init__(self, entity: Entity, formats: list[str], multiple: bool) -> None:
"""
Initialize an UploadFileFormatError instance.
Exception message will be formatted as:
"Only `<entity>` with the following formats can be uploaded
`(`by themselves | together`)`: `<formats>`."
Parameters
----------
entity : Entity
The entity that was uploaded with an invalid format.
formats : list[str]
Valid formats.
multiple : bool
Whether multiple entities are uploaded.
"""
suffix = "by themselves" if not multiple else "together (at most one of each)"
super().__init__(
f"Only {entity} with the following formats can be uploaded {suffix}:"
f" {', '.join(formats)}.",
)