parent
c4cd35662e
commit
5073fefe65
@ -0,0 +1,158 @@ |
|||||||
|
from copy import deepcopy |
||||||
|
from typing import Optional, Any |
||||||
|
|
||||||
|
from loguru import logger |
||||||
|
|
||||||
|
from src.url import URLType |
||||||
|
|
||||||
|
|
||||||
|
class StatusCode: |
||||||
|
""" |
||||||
|
For Song, available values are all. |
||||||
|
For others, available values are Waiting, Processing, Done and Failed. |
||||||
|
""" |
||||||
|
Waiting = "WAITING" |
||||||
|
Processing = "PROCESSING" |
||||||
|
Parsing = "PARSING" |
||||||
|
Downloading = "DOWNLOADING" |
||||||
|
Decrypting = "DECRYPTING" |
||||||
|
Saving = "SAVING" |
||||||
|
Done = "Done" |
||||||
|
AlreadyExist = "ALREADY_EXIST" |
||||||
|
Failed = "FAILED" |
||||||
|
|
||||||
|
|
||||||
|
class WarningCode: |
||||||
|
NoAvailableAccountForLyrics = "NO_AVAILABLE_ACCOUNT_FOR_LYRICS" |
||||||
|
UnableGetLyrics = "UNABLE_GET_LYRICS" |
||||||
|
RetryableDecryptFailed = "RETRYABLE_DECRYPT_FAILED" |
||||||
|
|
||||||
|
|
||||||
|
class ErrorCode: |
||||||
|
NotExistInStorefront = "NOT_EXIST_IN_STOREFRONT" |
||||||
|
ForceModeM3U8NotExist = "FORCE_MODE_M3U8_NOT_EXIST" |
||||||
|
AudioNotExist = "AUDIO_NOT_EXIST" |
||||||
|
LosslessAudioNotExist = "LOSSLESS_AUDIO_NOT_EXIST" |
||||||
|
DecryptFailed = "DECRYPT_FAILED" |
||||||
|
|
||||||
|
|
||||||
|
class BaseStatus: |
||||||
|
_type: str |
||||||
|
_current: str = StatusCode.Waiting |
||||||
|
_status_params: dict[str, Any] = {} |
||||||
|
_params: dict[str, Any] = {} |
||||||
|
_warning: str = "" |
||||||
|
_error: str = "" |
||||||
|
children = [] |
||||||
|
|
||||||
|
def __init__(self, status_type: str): |
||||||
|
self._type = status_type |
||||||
|
|
||||||
|
def new(self, status_type): |
||||||
|
new_obj = deepcopy(self) |
||||||
|
new_obj._type = status_type |
||||||
|
new_obj._current = StatusCode |
||||||
|
new_obj._status_params = {} |
||||||
|
new_obj._params = {} |
||||||
|
new_obj._warning = "" |
||||||
|
new_obj._error = "" |
||||||
|
new_obj.children = [] |
||||||
|
return new_obj |
||||||
|
|
||||||
|
def running(self): |
||||||
|
if self._error: |
||||||
|
return False |
||||||
|
if self._current == StatusCode.Waiting or self._current == StatusCode.Done or self._current == StatusCode.AlreadyExist: |
||||||
|
return False |
||||||
|
return True |
||||||
|
|
||||||
|
def set_status(self, status: str, **kwargs): |
||||||
|
self._current = status |
||||||
|
|
||||||
|
def get_status(self) -> str: |
||||||
|
return self._current |
||||||
|
|
||||||
|
def set_warning(self, warning: str, **kwargs): |
||||||
|
self._warning = warning |
||||||
|
|
||||||
|
def get_warning(self): |
||||||
|
return self._warning |
||||||
|
|
||||||
|
def set_error(self, error: str, **kwargs): |
||||||
|
self._error = error |
||||||
|
self._current = StatusCode.Failed |
||||||
|
|
||||||
|
def get_error(self): |
||||||
|
return self._error |
||||||
|
|
||||||
|
def set_progress(self, key: str, now: int, total: int, **kwargs): |
||||||
|
self._status_params[key] = {"now": now, "total": total} |
||||||
|
|
||||||
|
def get_progress(self, key: str) -> Optional[tuple[int, int]]: |
||||||
|
if self._status_params.get(key): |
||||||
|
return self._status_params[key]["now"], self._status_params[key]["total"] |
||||||
|
return None |
||||||
|
|
||||||
|
def set_param(self, **kwargs): |
||||||
|
for param in kwargs.items(): |
||||||
|
self._params[param[0]] = param[1] |
||||||
|
|
||||||
|
|
||||||
|
class LogStatus(BaseStatus): |
||||||
|
def _get_song_name(self) -> str: |
||||||
|
if self._params.get('title'): |
||||||
|
return f"{self._params.get('artist')} - {self._params.get('title')}" |
||||||
|
return self._params.get('artist') |
||||||
|
|
||||||
|
def set_status(self, status: str, **kwargs): |
||||||
|
super().set_status(status, **kwargs) |
||||||
|
match status: |
||||||
|
case StatusCode.Waiting: |
||||||
|
pass |
||||||
|
case StatusCode.Processing: |
||||||
|
if self._type == URLType.Song: |
||||||
|
logger.debug(f"Task of {self._type} id {self._params.get('song_id')} was created") |
||||||
|
else: |
||||||
|
logger.info(f"Ripping {self._type}: {self._get_song_name()}") |
||||||
|
case StatusCode.Parsing: |
||||||
|
logger.info(f"Ripping {self._type}: {self._get_song_name()}") |
||||||
|
case StatusCode.Downloading: |
||||||
|
logger.info(f"Downloading {self._type}: {self._get_song_name()}") |
||||||
|
case StatusCode.Decrypting: |
||||||
|
logger.info(f"Decrypting {self._type}: {self._get_song_name()}") |
||||||
|
case StatusCode.Saving: |
||||||
|
pass |
||||||
|
case StatusCode.Done: |
||||||
|
logger.info( |
||||||
|
f"{self._type.capitalize()} {self._get_song_name()} saved!") |
||||||
|
case StatusCode.AlreadyExist: |
||||||
|
logger.info( |
||||||
|
f"{self._type.capitalize()}: {self._get_song_name()} already exists") |
||||||
|
|
||||||
|
def set_warning(self, warning: str, **kwargs): |
||||||
|
super().set_warning(warning, **kwargs) |
||||||
|
match warning: |
||||||
|
case WarningCode.NoAvailableAccountForLyrics: |
||||||
|
logger.warning(f"No account is available for getting lyrics of storefront {self._params.get('song_storefront').upper()}. " |
||||||
|
f"Use storefront {self._params.get('storefront').upper()} to get lyrics") |
||||||
|
case WarningCode.RetryableDecryptFailed: |
||||||
|
logger.warning(f"Failed to decrypt song: {self._get_song_name()}, {kwargs['action']}") |
||||||
|
case WarningCode.UnableGetLyrics: |
||||||
|
logger.warning(f"Unable to get lyrics of song: {self._get_song_name()}") |
||||||
|
|
||||||
|
def set_error(self, error: str, **kwargs): |
||||||
|
super().set_error(error, **kwargs) |
||||||
|
match error: |
||||||
|
case ErrorCode.AudioNotExist: |
||||||
|
logger.error(f"Failed to download song: {self._get_song_name()}. Audio does not exist") |
||||||
|
case ErrorCode.LosslessAudioNotExist: |
||||||
|
logger.error(f"Failed to download song: {self._get_song_name()}. Lossless audio does not exist") |
||||||
|
case ErrorCode.DecryptFailed: |
||||||
|
logger.error(f"Failed to decrypt song: {self._get_song_name()}") |
||||||
|
case ErrorCode.NotExistInStorefront: |
||||||
|
logger.error( |
||||||
|
f"Unable to download {self._type} {self._get_song_name()}. " |
||||||
|
f"This {self._type} does not exist in storefront {self._params.get('storefront').upper()} " |
||||||
|
f"and no device is available to decrypt it") |
||||||
|
case ErrorCode.ForceModeM3U8NotExist: |
||||||
|
logger.error(f"Failed to get m3u8 from API for song: {self._get_song_name()}") |
Loading…
Reference in new issue