diff --git a/libresvip/gui/models/table_models.py b/libresvip/gui/models/table_models.py index 7c11856eb..dceeb31f9 100644 --- a/libresvip/gui/models/table_models.py +++ b/libresvip/gui/models/table_models.py @@ -1,6 +1,5 @@ import re from functools import cache -from gettext import gettext as _ from typing import Any, Optional from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Slot @@ -9,6 +8,7 @@ from libresvip.core.config import LyricsReplacement, LyricsReplaceMode, settings from libresvip.extension.manager import plugin_manager +from libresvip.utils.translation import gettext_lazy as _ class PluginCadidatesTableModel(QAbstractTableModel): diff --git a/libresvip/middlewares/pitch_shift/options.py b/libresvip/middlewares/pitch_shift/options.py index 776557840..ab7b365ae 100644 --- a/libresvip/middlewares/pitch_shift/options.py +++ b/libresvip/middlewares/pitch_shift/options.py @@ -1,7 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class ProcessOptions(BaseModel): key: int = Field( diff --git a/libresvip/middlewares/project_zoom/options.py b/libresvip/middlewares/project_zoom/options.py index 363d1b985..86241e7f0 100644 --- a/libresvip/middlewares/project_zoom/options.py +++ b/libresvip/middlewares/project_zoom/options.py @@ -1,9 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class ProjectZoomOptions(Enum): NONE: Annotated[str, Field(title=_("None"))] = "1/1" diff --git a/libresvip/middlewares/pronounciation_conversion/options.py b/libresvip/middlewares/pronounciation_conversion/options.py index ed013bc95..39134282d 100644 --- a/libresvip/middlewares/pronounciation_conversion/options.py +++ b/libresvip/middlewares/pronounciation_conversion/options.py @@ -1,9 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class PronounciationConversionOptions(Enum): NONE: Annotated[str, Field(title=_("None"))] = "Do nothing" diff --git a/libresvip/middlewares/remove_short_silences/options.py b/libresvip/middlewares/remove_short_silences/options.py index fe6477da0..46c286f67 100644 --- a/libresvip/middlewares/remove_short_silences/options.py +++ b/libresvip/middlewares/remove_short_silences/options.py @@ -1,9 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class NoteLengthOption(Enum): ZERO: Annotated[str, Field(title=_("Zero length note"))] = "0/1" diff --git a/libresvip/middlewares/replace_lyric/options.py b/libresvip/middlewares/replace_lyric/options.py index a66635228..d3c62cbc1 100644 --- a/libresvip/middlewares/replace_lyric/options.py +++ b/libresvip/middlewares/replace_lyric/options.py @@ -1,7 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class ProcessOptions(BaseModel): lyric_replacement_preset_name: str = Field( diff --git a/libresvip/model/option_mixins.py b/libresvip/model/option_mixins.py index 33a8c2d34..a6233e5de 100644 --- a/libresvip/model/option_mixins.py +++ b/libresvip/model/option_mixins.py @@ -1,9 +1,9 @@ import abc -from gettext import gettext as _ from pydantic import BaseModel, Field from libresvip.core.constants import DEFAULT_BPM +from libresvip.utils.translation import gettext_lazy as _ class EnableInstrumentalTrackImportationMixin(BaseModel, abc.ABC): diff --git a/libresvip/plugins/acep/model.py b/libresvip/plugins/acep/model.py index bdb36c960..82cf047c2 100644 --- a/libresvip/plugins/acep/model.py +++ b/libresvip/plugins/acep/model.py @@ -2,10 +2,8 @@ import itertools import math -import pathlib import statistics from enum import Enum -from gettext import gettext as _ from itertools import chain from typing import TYPE_CHECKING, Annotated, Any, Literal, NamedTuple, Optional, Union @@ -22,6 +20,7 @@ from libresvip.core.time_interval import RangeInterval from libresvip.model.base import BaseModel from libresvip.model.point import PointList +from libresvip.utils.audio import audio_path_validator from libresvip.utils.music_math import linear_interpolation from .ace_curve_utils import interpolate_hermite @@ -29,7 +28,8 @@ if TYPE_CHECKING: from collections.abc import Callable - from gettext import gettext as _ + + from libresvip.utils.translation import gettext_lazy as _ class AcepAnchorPoint(NamedTuple): @@ -270,16 +270,7 @@ class AcepAudioPattern(AcepPattern): gain: Optional[float] = None analysed_beat: Optional[AcepAnalysedBeat] = Field(None, alias="analysedBeat") - @field_validator("path", mode="before") - @classmethod - def validate_path(cls, path: str, info: ValidationInfo) -> str: - audio_path = pathlib.Path(path) - if not audio_path.is_absolute() and info.context is not None: - project_path: Optional[pathlib.Path] - if (project_path := info.context.get("path")) and not hasattr(project_path, "protocol"): - audio_path = (project_path.parent / path).resolve() - path = str(audio_path) - return path + validate_path = field_validator("path", mode="before")(audio_path_validator) class AcepVocalPattern(AcepPattern): diff --git a/libresvip/plugins/acep/options.py b/libresvip/plugins/acep/options.py index 1cfa8b951..ca71e07c9 100644 --- a/libresvip/plugins/acep/options.py +++ b/libresvip/plugins/acep/options.py @@ -1,7 +1,6 @@ from __future__ import annotations from enum import Enum -from gettext import gettext as _ from types import SimpleNamespace from typing import Annotated, Literal, Union @@ -14,6 +13,7 @@ EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ from .model import AcepLyricsLanguage from .singers import DEFAULT_SINGER diff --git a/libresvip/plugins/ass/options.py b/libresvip/plugins/ass/options.py index f69f19de9..a5eeab01b 100644 --- a/libresvip/plugins/ass/options.py +++ b/libresvip/plugins/ass/options.py @@ -1,10 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field from libresvip.model.option_mixins import SelectSingleTrackMixin +from libresvip.utils.translation import gettext_lazy as _ class SplitOption(Enum): diff --git a/libresvip/plugins/ccs/options.py b/libresvip/plugins/ccs/options.py index c53c8c32c..828247156 100644 --- a/libresvip/plugins/ccs/options.py +++ b/libresvip/plugins/ccs/options.py @@ -1,11 +1,10 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, BaseModel): diff --git a/libresvip/plugins/ds/options.py b/libresvip/plugins/ds/options.py index 02640a320..b7a7a6847 100644 --- a/libresvip/plugins/ds/options.py +++ b/libresvip/plugins/ds/options.py @@ -1,8 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import EnablePitchImportationMixin, SelectSingleTrackMixin +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(EnablePitchImportationMixin, BaseModel): diff --git a/libresvip/plugins/gj/options.py b/libresvip/plugins/gj/options.py index 83f7ba6d7..b221662af 100644 --- a/libresvip/plugins/gj/options.py +++ b/libresvip/plugins/gj/options.py @@ -1,5 +1,3 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( @@ -7,6 +5,7 @@ EnablePitchImportationMixin, EnableVolumeImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class InputOptions( diff --git a/libresvip/plugins/json/options.py b/libresvip/plugins/json/options.py index 671316a7f..145b57137 100644 --- a/libresvip/plugins/json/options.py +++ b/libresvip/plugins/json/options.py @@ -1,7 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class InputOptions(BaseModel): pass diff --git a/libresvip/plugins/lrc/options.py b/libresvip/plugins/lrc/options.py index 63e03dab3..050bf2905 100644 --- a/libresvip/plugins/lrc/options.py +++ b/libresvip/plugins/lrc/options.py @@ -1,9 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class OffsetPolicyOption(Enum): TIMELINE: Annotated[ diff --git a/libresvip/plugins/mid/options.py b/libresvip/plugins/mid/options.py index 951a6f320..23b86ee64 100644 --- a/libresvip/plugins/mid/options.py +++ b/libresvip/plugins/mid/options.py @@ -1,11 +1,11 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field from libresvip.core.constants import DEFAULT_BPM from libresvip.model.option_mixins import EnablePitchImportationMixin, EnableVolumeImportationMixin +from libresvip.utils.translation import gettext_lazy as _ class MultiChannelOption(Enum): diff --git a/libresvip/plugins/mtp/options.py b/libresvip/plugins/mtp/options.py index afadaa4cc..b7b66ae53 100644 --- a/libresvip/plugins/mtp/options.py +++ b/libresvip/plugins/mtp/options.py @@ -1,11 +1,10 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, BaseModel): diff --git a/libresvip/plugins/nn/options.py b/libresvip/plugins/nn/options.py index 2677dda64..32bd5a663 100644 --- a/libresvip/plugins/nn/options.py +++ b/libresvip/plugins/nn/options.py @@ -1,5 +1,3 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( @@ -7,6 +5,7 @@ SelectSingleTrackMixin, StaticTempoMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(EnablePitchImportationMixin, BaseModel): diff --git a/libresvip/plugins/s5p/model.py b/libresvip/plugins/s5p/model.py index 73929f32e..2400598ca 100644 --- a/libresvip/plugins/s5p/model.py +++ b/libresvip/plugins/s5p/model.py @@ -14,6 +14,7 @@ from libresvip.core.constants import DEFAULT_BPM, DEFAULT_PHONEME from libresvip.model.base import BaseModel from libresvip.model.point import PointList +from libresvip.utils.audio import audio_path_validator class S5pPoint(NamedTuple): @@ -144,6 +145,8 @@ class S5pInstrumental(BaseModel): filename: str = "" offset: float = 0.0 + validate_filename = field_validator("filename", mode="before")(audio_path_validator) + class S5pMixer(BaseModel): gain_instrumental_decibel: float = Field(0.0, alias="gainInstrumentalDecibel") diff --git a/libresvip/plugins/s5p/synthv_editor_converter.py b/libresvip/plugins/s5p/synthv_editor_converter.py index fa1f27a6c..9e4785946 100644 --- a/libresvip/plugins/s5p/synthv_editor_converter.py +++ b/libresvip/plugins/s5p/synthv_editor_converter.py @@ -12,7 +12,9 @@ class SynthVEditorConverter(plugin_base.SVSConverterBase): def load(self, path: pathlib.Path, options: InputOptions) -> Project: - s5p_project = S5pProject.model_validate_json(path.read_bytes().decode("utf-8")) + s5p_project = S5pProject.model_validate_json( + path.read_bytes().decode("utf-8"), context={"path": path} + ) return SynthVEditorParser(options).parse_project(s5p_project) def dump(self, path: pathlib.Path, project: Project, options: OutputOptions) -> None: diff --git a/libresvip/plugins/srt/options.py b/libresvip/plugins/srt/options.py index f69f19de9..a5eeab01b 100644 --- a/libresvip/plugins/srt/options.py +++ b/libresvip/plugins/srt/options.py @@ -1,10 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field from libresvip.model.option_mixins import SelectSingleTrackMixin +from libresvip.utils.translation import gettext_lazy as _ class SplitOption(Enum): diff --git a/libresvip/plugins/svg/options.py b/libresvip/plugins/svg/options.py index 45bdd6a2f..1c2302fd0 100644 --- a/libresvip/plugins/svg/options.py +++ b/libresvip/plugins/svg/options.py @@ -1,11 +1,11 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field from pydantic_extra_types.color import Color from libresvip.model.option_mixins import SelectSingleTrackMixin +from libresvip.utils.translation import gettext_lazy as _ class TextAlignOption(Enum): diff --git a/libresvip/plugins/svip/options.py b/libresvip/plugins/svip/options.py index dd06fb458..c8173f93e 100644 --- a/libresvip/plugins/svip/options.py +++ b/libresvip/plugins/svip/options.py @@ -1,5 +1,4 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field @@ -12,6 +11,7 @@ EnableStrengthImportationMixin, EnableVolumeImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class BinarySvipVersion(Enum): diff --git a/libresvip/plugins/svp/model.py b/libresvip/plugins/svp/model.py index 5a91239ac..6e70aea4b 100644 --- a/libresvip/plugins/svp/model.py +++ b/libresvip/plugins/svp/model.py @@ -22,6 +22,7 @@ from libresvip.core.time_interval import RangeInterval from libresvip.model.base import BaseModel, Note from libresvip.model.point import PointList +from libresvip.utils.audio import audio_path_validator from . import constants from .interval_utils import position_to_ticks @@ -501,6 +502,8 @@ class SVAudio(BaseModel): filename: str = "" duration: float + validate_filename = field_validator("filename", mode="before")(audio_path_validator) + class SVDatabase(BaseModel): name: str = "" diff --git a/libresvip/plugins/svp/options.py b/libresvip/plugins/svp/options.py index 79f2c6733..64878366b 100644 --- a/libresvip/plugins/svp/options.py +++ b/libresvip/plugins/svp/options.py @@ -1,5 +1,4 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated, NamedTuple from pydantic import BaseModel, Field @@ -12,6 +11,7 @@ EnableStrengthImportationMixin, EnableVolumeImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class SynthVLanguagePreset(NamedTuple): diff --git a/libresvip/plugins/svp/synthv_studio_converter.py b/libresvip/plugins/svp/synthv_studio_converter.py index 19357c65f..d836cc3ae 100644 --- a/libresvip/plugins/svp/synthv_studio_converter.py +++ b/libresvip/plugins/svp/synthv_studio_converter.py @@ -15,7 +15,7 @@ def load(self, path: pathlib.Path, options: InputOptions) -> Project: sv_content = ( path.read_bytes().removesuffix(b"\x00").removeprefix("\ufeff".encode()).decode("utf-8") ) - sv_proj = SVProject.model_validate_json(sv_content) + sv_proj = SVProject.model_validate_json(sv_content, context={"path": path}) options.instant = options.instant and sv_proj.instant_mode_enabled return SynthVParser(options=options).parse_project(sv_proj) diff --git a/libresvip/plugins/ust/options.py b/libresvip/plugins/ust/options.py index 7410f9d78..f23ceb05b 100644 --- a/libresvip/plugins/ust/options.py +++ b/libresvip/plugins/ust/options.py @@ -1,9 +1,8 @@ -from gettext import gettext as _ - from pydantic import Field from libresvip.model.base import BaseModel from libresvip.model.option_mixins import EnablePitchImportationMixin, SelectSingleTrackMixin +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(EnablePitchImportationMixin, BaseModel): diff --git a/libresvip/plugins/ustx/model.py b/libresvip/plugins/ustx/model.py index 1ea6c9121..1334fb398 100644 --- a/libresvip/plugins/ustx/model.py +++ b/libresvip/plugins/ustx/model.py @@ -6,10 +6,11 @@ from types import SimpleNamespace from typing import Annotated, Literal, Optional, Union -from pydantic import Field +from pydantic import Field, field_validator from libresvip.core.constants import DEFAULT_BPM, TICKS_IN_BEAT from libresvip.model.base import BaseModel +from libresvip.utils.audio import audio_path_validator from libresvip.utils.music_math import linear_interpolation ParamType = SimpleNamespace( @@ -193,6 +194,8 @@ class UWavePart(UPart): skip_ms: float = 0 trim_ms: float = 0 + validate_relative_path = field_validator("relative_path", mode="before")(audio_path_validator) + class USTXProject(BaseModel): name: str = "New Project" diff --git a/libresvip/plugins/ustx/options.py b/libresvip/plugins/ustx/options.py index 9611e16c9..fe60c41e7 100644 --- a/libresvip/plugins/ustx/options.py +++ b/libresvip/plugins/ustx/options.py @@ -1,5 +1,4 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field @@ -8,6 +7,7 @@ EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ class OpenUtauEnglishPhonemizerCompatibility(Enum): diff --git a/libresvip/plugins/ustx/ustx_converter.py b/libresvip/plugins/ustx/ustx_converter.py index ae813a1ae..933883c86 100644 --- a/libresvip/plugins/ustx/ustx_converter.py +++ b/libresvip/plugins/ustx/ustx_converter.py @@ -14,7 +14,7 @@ class OpenUtauConverter(plugin_base.SVSConverterBase): def load(self, path: pathlib.Path, options: InputOptions) -> Project: proj_text = to_unicode(path.read_bytes()) - ustx_project = USTXProject.model_validate(load_yaml_1_2(proj_text)) + ustx_project = USTXProject.model_validate(load_yaml_1_2(proj_text), context={"path": path}) return UstxParser(options).parse_project(ustx_project) def dump(self, path: pathlib.Path, project: Project, options: OutputOptions) -> None: diff --git a/libresvip/plugins/ustx/ustx_generator.py b/libresvip/plugins/ustx/ustx_generator.py index b6c289602..a85ef78ff 100644 --- a/libresvip/plugins/ustx/ustx_generator.py +++ b/libresvip/plugins/ustx/ustx_generator.py @@ -127,7 +127,6 @@ def generate_wave_part(os_track: InstrumentalTrack, track_no: int) -> Optional[U name=os_track.title, track_no=track_no, position=os_track.offset, - file_path=os_track.audio_file_path, relative_path=os_track.audio_file_path, file_duration_ms=track_info.duration, ) diff --git a/libresvip/plugins/ustx/ustx_parser.py b/libresvip/plugins/ustx/ustx_parser.py index 6ccb0f62d..8e1dd5b45 100644 --- a/libresvip/plugins/ustx/ustx_parser.py +++ b/libresvip/plugins/ustx/ustx_parser.py @@ -186,11 +186,10 @@ def parse_wave_parts( if self.options.import_instrumental_track: for wave_part in wave_parts: ustx_track = tracks[wave_part.track_no] - rel_path = wave_part.relative_path # duration = wave_part.file_duration_ms - wave_part.skip_ms - wave_part.trim_ms track_list.append( InstrumentalTrack( - audio_file_path=rel_path, + audio_file_path=wave_part.relative_path, offset=wave_part.position, title=wave_part.name, mute=ustx_track.mute, diff --git a/libresvip/plugins/vog/options.py b/libresvip/plugins/vog/options.py index 6b3258ab7..d362ed612 100644 --- a/libresvip/plugins/vog/options.py +++ b/libresvip/plugins/vog/options.py @@ -1,8 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import StaticTempoMixin +from libresvip.utils.translation import gettext_lazy as _ class InputOptions(BaseModel): diff --git a/libresvip/plugins/vpr/model.py b/libresvip/plugins/vpr/model.py index 2a888e1fc..75ac11a6e 100644 --- a/libresvip/plugins/vpr/model.py +++ b/libresvip/plugins/vpr/model.py @@ -1,11 +1,11 @@ import enum from dataclasses import dataclass -from gettext import gettext as _ from typing import Annotated, Literal, Optional, Union from pydantic import ConfigDict, Field from libresvip.model.base import BaseModel +from libresvip.utils.translation import gettext_lazy as _ class VocaloidLanguage(enum.IntEnum): diff --git a/libresvip/plugins/vpr/options.py b/libresvip/plugins/vpr/options.py index 3e424294d..0a9b5be67 100644 --- a/libresvip/plugins/vpr/options.py +++ b/libresvip/plugins/vpr/options.py @@ -1,11 +1,10 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ from .model import VocaloidLanguage diff --git a/libresvip/plugins/vshp/options.py b/libresvip/plugins/vshp/options.py index 36caa6c81..ccd70abfc 100644 --- a/libresvip/plugins/vshp/options.py +++ b/libresvip/plugins/vshp/options.py @@ -1,7 +1,7 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field +from libresvip.utils.translation import gettext_lazy as _ + class InputOptions(BaseModel): wave_to_singing: bool = Field(True, title=_("Convert wave pattern to singing pattern")) diff --git a/libresvip/plugins/vsq/options.py b/libresvip/plugins/vsq/options.py index 8777af83a..7384c4944 100644 --- a/libresvip/plugins/vsq/options.py +++ b/libresvip/plugins/vsq/options.py @@ -1,10 +1,10 @@ from enum import Enum -from gettext import gettext as _ from typing import Annotated from pydantic import BaseModel, Field from libresvip.model.option_mixins import EnablePitchImportationMixin +from libresvip.utils.translation import gettext_lazy as _ class BreathOption(Enum): diff --git a/libresvip/plugins/vsqx/enums.py b/libresvip/plugins/vsqx/enums.py index 4fe46db42..5337e3580 100644 --- a/libresvip/plugins/vsqx/enums.py +++ b/libresvip/plugins/vsqx/enums.py @@ -1,9 +1,10 @@ import enum -from gettext import gettext as _ from typing import Annotated from pydantic import Field +from libresvip.utils.translation import gettext_lazy as _ + class VsqxVersion(enum.IntEnum): VSQ3: Annotated[int, Field(title=_("VSQx 3"))] = 3 diff --git a/libresvip/plugins/vsqx/options.py b/libresvip/plugins/vsqx/options.py index 9ffa0df59..116b47354 100644 --- a/libresvip/plugins/vsqx/options.py +++ b/libresvip/plugins/vsqx/options.py @@ -1,11 +1,10 @@ -from gettext import gettext as _ - from pydantic import BaseModel, Field from libresvip.model.option_mixins import ( EnableInstrumentalTrackImportationMixin, EnablePitchImportationMixin, ) +from libresvip.utils.translation import gettext_lazy as _ from .enums import VocaloidLanguage, VsqxVersion diff --git a/libresvip/utils/audio.py b/libresvip/utils/audio.py index 54bedd679..07df6edf3 100644 --- a/libresvip/utils/audio.py +++ b/libresvip/utils/audio.py @@ -3,9 +3,22 @@ import platform from typing import Optional, Union +from pydantic import ValidationInfo + from libresvip.core.warning_types import show_warning from libresvip.utils.translation import gettext_lazy as _ + +def audio_path_validator(path: str, info: ValidationInfo) -> str: + audio_path = pathlib.Path(path) + if not audio_path.is_absolute() and info.context is not None: + project_path: Optional[pathlib.Path] + if (project_path := info.context.get("path")) and not hasattr(project_path, "protocol"): + audio_path = (project_path.parent / path).resolve() + path = str(audio_path) + return path + + if platform.system() != "Emscripten": from pymediainfo import ET, MediaInfo from pymediainfo import Track as MediaInfoTrack