Skip to content

Commit

Permalink
整理: PresetManager 共通処理の関数化・追加コメント (#832)
Browse files Browse the repository at this point in the history
Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
tarepan and Hiroshiba authored Dec 9, 2023
1 parent b997385 commit 5e63e36
Showing 1 changed file with 56 additions and 58 deletions.
114 changes: 56 additions & 58 deletions voicevox_engine/preset/PresetManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,84 +9,88 @@


class PresetManager:
def __init__(
self,
preset_path: Path,
):
self.presets = []
"""
プリセットの管理
プリセットはAudioQuery全体パラメータ(話速・音高・抑揚・音量・無音長)のデフォルト値セットである。
YAMLファイルをSSoTとする簡易データベース方式により、プリセットの管理をおこなう。
"""

def __init__(self, preset_path: Path):
"""
Parameters
----------
preset_path : Path
プリセット情報を一元管理するYAMLファイルへのパス
"""
self.presets: list[Preset] = []
self.last_modified_time = 0
self.preset_path = preset_path

def load_presets(self):
def load_presets(self) -> list[Preset]:
"""
プリセットのYAMLファイルを読み込む
既存プリセットの読み込み
Returns
-------
ret: List[Preset]
プリセットのリスト
ret: list[Preset]
読み込まれたプリセットのリスト
"""

# 設定ファイルのタイムスタンプを確認
# データベース更新の確認(タイムスタンプベース)
try:
_last_modified_time = self.preset_path.stat().st_mtime
if _last_modified_time == self.last_modified_time:
# 更新無し、キャッシュを返す
return self.presets
except OSError:
raise PresetError("プリセットの設定ファイルが見つかりません")

# データベースの読み込み
with open(self.preset_path, mode="r", encoding="utf-8") as f:
obj = yaml.safe_load(f)
if obj is None:
raise PresetError("プリセットの設定ファイルが空の内容です")

try:
_presets = parse_obj_as(List[Preset], obj)
except ValidationError:
raise PresetError("プリセットの設定ファイルにミスがあります")

# idが一意か確認
# 全idの一意性をバリデーション
if len([preset.id for preset in _presets]) != len(
{preset.id for preset in _presets}
):
raise PresetError("プリセットのidに重複があります")

self.presets = _presets
self.last_modified_time = _last_modified_time

return self.presets

def add_preset(self, preset: Preset):
"""
YAMLファイルに新規のプリセットを追加する
新規プリセットの追加
Parameters
----------
preset : Preset
追加するプリセットを渡す
新規プリセット
Returns
-------
ret: int
追加したプリセットのプリセットID
追加されたプリセットのID
"""

# 手動でファイルが更新されているかも知れないので、最新のYAMLファイルを読み直す
# データベース更新の反映
self.load_presets()

# IDが0未満、または存在するIDなら新しいIDを決定し、配列に追加
# 新規プリセットID の発行。IDが0未満、または存在するIDなら新規IDを発行
if preset.id < 0 or preset.id in {preset.id for preset in self.presets}:
preset.id = max([preset.id for preset in self.presets]) + 1
# 新規プリセットの追加
self.presets.append(preset)

# ファイルに書き込み
# 変更の反映。失敗時はリバート。
try:
with open(self.preset_path, mode="w", encoding="utf-8") as f:
yaml.safe_dump(
[preset.dict() for preset in self.presets],
f,
allow_unicode=True,
sort_keys=False,
)
self._write_on_file()
except Exception as err:
self.presets.pop()
if isinstance(err, FileNotFoundError):
Expand All @@ -98,23 +102,21 @@ def add_preset(self, preset: Preset):

def update_preset(self, preset: Preset):
"""
YAMLファイルのプリセットを更新する
既存プリセットの更新
Parameters
----------
preset : Preset
更新するプリセットを渡す
新しい既存プリセット
Returns
-------
ret: int
更新したプリセットのプリセットID
更新されたプリセットのID
"""

# 手動でファイルが更新されているかも知れないので、最新のYAMLファイルを読み直す
# データベース更新の反映
self.load_presets()

# IDが存在するか探索
# 対象プリセットの検索
prev_preset = (-1, None)
for i in range(len(self.presets)):
if self.presets[i].id == preset.id:
Expand All @@ -124,15 +126,9 @@ def update_preset(self, preset: Preset):
else:
raise PresetError("更新先のプリセットが存在しません")

# ファイルに書き込み
# 変更の反映。失敗時はリバート。
try:
with open(self.preset_path, mode="w", encoding="utf-8") as f:
yaml.safe_dump(
[preset.dict() for preset in self.presets],
f,
allow_unicode=True,
sort_keys=False,
)
self._write_on_file()
except Exception as err:
if prev_preset != (-1, None):
self.presets[prev_preset[0]] = prev_preset[1]
Expand All @@ -145,23 +141,21 @@ def update_preset(self, preset: Preset):

def delete_preset(self, id: int):
"""
YAMLファイルのプリセットを削除する
指定したIDのプリセットの削除
Parameters
----------
id: int
削除するプリセットのプリセットIDを渡す
削除対象プリセットのID
Returns
-------
ret: int
削除したプリセットのプリセットID
削除されたプリセットのID
"""

# 手動でファイルが更新されているかも知れないので、最新のYAMLファイルを読み直す
# データベース更新の反映
self.load_presets()

# IDが存在するか探索
# 対象プリセットの検索
buf = None
buf_index = -1
for i in range(len(self.presets)):
Expand All @@ -172,17 +166,21 @@ def delete_preset(self, id: int):
else:
raise PresetError("削除対象のプリセットが存在しません")

# ファイルに書き込み
# 変更の反映。失敗時はリバート。
try:
with open(self.preset_path, mode="w", encoding="utf-8") as f:
yaml.safe_dump(
[preset.dict() for preset in self.presets],
f,
allow_unicode=True,
sort_keys=False,
)
self._write_on_file()
except FileNotFoundError:
self.presets.insert(buf_index, buf)
raise PresetError("プリセットの設定ファイルに書き込み失敗しました")

return id

def _write_on_file(self):
"""プリセット情報のファイル(簡易データベース)書き込み"""
with open(self.preset_path, mode="w", encoding="utf-8") as f:
yaml.safe_dump(
[preset.dict() for preset in self.presets],
f,
allow_unicode=True,
sort_keys=False,
)

0 comments on commit 5e63e36

Please sign in to comment.