Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

音声ライブラリ管理APIのエラーにライブラリIDを含める #705

Merged
merged 2 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions test/test_downloadable_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,25 @@ def test_installed_libraries(self):

def test_install_library(self):
# エンジンが把握していないライブラリのテスト
invalid_uuid = "52398bd5-3cc3-406c-a159-dfec5ace4bab"
with self.assertRaises(HTTPException) as e:
self.library_manger.install_library(
"52398bd5-3cc3-406c-a159-dfec5ace4bab", self.library_file
)
self.assertEqual(e.exception.detail, "指定された音声ライブラリが見つかりません。")
self.library_manger.install_library(invalid_uuid, self.library_file)
self.assertEqual(e.exception.detail, f"指定された音声ライブラリ {invalid_uuid} が見つかりません。")

# 不正なZIPファイルのテスト
with self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, BytesIO())
self.assertEqual(e.exception.detail, "不正なZIPファイルです。")
self.assertEqual(e.exception.detail, f"音声ライブラリ {self.library_uuid} は不正なファイルです。")

# vvlib_manifestの存在確認のテスト
invalid_vvlib_name = "test/invalid.vvlib"
self.create_vvlib_without_manifest(invalid_vvlib_name)
with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(e.exception.detail, "指定された音声ライブラリにvvlib_manifest.jsonが存在しません。")
self.assertEqual(
e.exception.detail,
f"指定された音声ライブラリ {self.library_uuid} にvvlib_manifest.jsonが存在しません。",
)

# vvlib_manifestのパースのテスト
# Duplicate name: 'vvlib_manifest.json'とWarningを吐かれるので、毎回作り直す
Expand All @@ -100,7 +102,10 @@ def test_install_library(self):

with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(e.exception.detail, "指定された音声ライブラリのvvlib_manifest.jsonは不正です。")
self.assertEqual(
e.exception.detail,
f"指定された音声ライブラリ {self.library_uuid} のvvlib_manifest.jsonは不正です。",
)

# vvlib_manifestのパースのテスト
invalid_vvlib_manifest = self.create_vvlib_manifest(version=10)
Expand All @@ -111,7 +116,8 @@ def test_install_library(self):
with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(
e.exception.detail, "指定された音声ライブラリのvvlib_manifest.jsonに不正なデータが含まれています。"
e.exception.detail,
f"指定された音声ライブラリ {self.library_uuid} のvvlib_manifest.jsonに不正なデータが含まれています。",
)

# vvlib_manifestの不正なversionのテスト
Expand All @@ -122,7 +128,9 @@ def test_install_library(self):

with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(e.exception.detail, "指定された音声ライブラリのversionが不正です。")
self.assertEqual(
e.exception.detail, f"指定された音声ライブラリ {self.library_uuid} のversionが不正です。"
)

# vvlib_manifestの不正なmanifest_versionのテスト
invalid_vvlib_manifest = self.create_vvlib_manifest(manifest_version="10")
Expand All @@ -132,7 +140,10 @@ def test_install_library(self):

with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(e.exception.detail, "指定された音声ライブラリのmanifest_versionが不正です。")
self.assertEqual(
e.exception.detail,
f"指定された音声ライブラリ {self.library_uuid} のmanifest_versionが不正です。",
)

# vvlib_manifestの未対応のmanifest_versionのテスト
invalid_vvlib_manifest = self.create_vvlib_manifest(
Expand All @@ -144,7 +155,9 @@ def test_install_library(self):

with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(e.exception.detail, "指定された音声ライブラリは未対応です。")
self.assertEqual(
e.exception.detail, f"指定された音声ライブラリ {self.library_uuid} は未対応です。"
)

# vvlib_manifestのインストール先エンジンの検証のテスト
invalid_vvlib_manifest = self.create_vvlib_manifest(
Expand All @@ -157,7 +170,8 @@ def test_install_library(self):
with open(invalid_vvlib_name, "br") as f, self.assertRaises(HTTPException) as e:
self.library_manger.install_library(self.library_uuid, f)
self.assertEqual(
e.exception.detail, f"指定された音声ライブラリは{self.engine_name}向けではありません。"
e.exception.detail,
f"指定された音声ライブラリ {self.library_uuid} は{self.engine_name}向けではありません。",
)

# 正しいライブラリをインストールして問題が起きないか
Expand All @@ -174,7 +188,9 @@ def test_uninstall_library(self):
# TODO: アンインストール出来ないライブラリをテストできるようにしたい
with self.assertRaises(HTTPException) as e:
self.library_manger.uninstall_library(self.library_uuid)
self.assertEqual(e.exception.detail, "指定された音声ライブラリはインストールされていません。")
self.assertEqual(
e.exception.detail, f"指定された音声ライブラリ {self.library_uuid} はインストールされていません。"
)

self.library_manger.install_library(self.library_uuid, self.library_file)
self.library_manger.uninstall_library(self.library_uuid)
43 changes: 30 additions & 13 deletions voicevox_engine/downloadable_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,23 @@ def install_library(self, library_id: str, file: BytesIO):
library_info = downloadable_library.dict()
break
else:
raise HTTPException(status_code=404, detail="指定された音声ライブラリが見つかりません。")
raise HTTPException(
status_code=404, detail=f"指定された音声ライブラリ {library_id} が見つかりません。"
)
library_dir = self.library_root_dir / library_id
library_dir.mkdir(exist_ok=True)
with open(library_dir / INFO_FILE, "w", encoding="utf-8") as f:
json.dump(library_info, f, indent=4, ensure_ascii=False)
if not zipfile.is_zipfile(file):
raise HTTPException(status_code=422, detail="不正なZIPファイルです。")
raise HTTPException(
status_code=422, detail=f"音声ライブラリ {library_id} は不正なファイルです。"
)

with zipfile.ZipFile(file) as zf:
if zf.testzip() is not None:
raise HTTPException(status_code=422, detail="不正なZIPファイルです。")
raise HTTPException(
status_code=422, detail=f"音声ライブラリ {library_id} は不正なファイルです。"
)

# validate manifest version
vvlib_manifest = None
Expand All @@ -111,24 +117,26 @@ def install_library(self, library_id: str, file: BytesIO):
)
except KeyError:
raise HTTPException(
status_code=422, detail="指定された音声ライブラリにvvlib_manifest.jsonが存在しません。"
status_code=422,
detail=f"指定された音声ライブラリ {library_id} にvvlib_manifest.jsonが存在しません。",
)
except Exception:
raise HTTPException(
status_code=422, detail="指定された音声ライブラリのvvlib_manifest.jsonは不正です。"
status_code=422,
detail=f"指定された音声ライブラリ {library_id} のvvlib_manifest.jsonは不正です。",
)

try:
VvlibManifest.validate(vvlib_manifest)
except ValidationError:
raise HTTPException(
status_code=422,
detail="指定された音声ライブラリのvvlib_manifest.jsonに不正なデータが含まれています。",
detail=f"指定された音声ライブラリ {library_id} のvvlib_manifest.jsonに不正なデータが含まれています。",
)

if not Version.is_valid(vvlib_manifest["version"]):
raise HTTPException(
status_code=422, detail="指定された音声ライブラリのversionが不正です。"
status_code=422, detail=f"指定された音声ライブラリ {library_id} のversionが不正です。"
)

try:
Expand All @@ -138,15 +146,18 @@ def install_library(self, library_id: str, file: BytesIO):
except ValueError:
raise HTTPException(
status_code=422,
detail="指定された音声ライブラリのmanifest_versionが不正です。",
detail=f"指定された音声ライブラリ {library_id} のmanifest_versionが不正です。",
)

if vvlib_manifest_version > self.supported_vvlib_version:
raise HTTPException(status_code=422, detail="指定された音声ライブラリは未対応です。")
raise HTTPException(
status_code=422, detail=f"指定された音声ライブラリ {library_id} は未対応です。"
)

if vvlib_manifest["engine_uuid"] != self.engine_uuid:
raise HTTPException(
status_code=422, detail=f"指定された音声ライブラリは{self.engine_name}向けではありません。"
status_code=422,
detail=f"指定された音声ライブラリ {library_id} は{self.engine_name}向けではありません。",
)

zf.extractall(library_dir)
Expand All @@ -155,12 +166,18 @@ def install_library(self, library_id: str, file: BytesIO):
def uninstall_library(self, library_id: str):
installed_libraries = self.installed_libraries()
if library_id not in installed_libraries.keys():
raise HTTPException(status_code=404, detail="指定された音声ライブラリはインストールされていません。")
raise HTTPException(
status_code=404, detail=f"指定された音声ライブラリ {library_id} はインストールされていません。"
)

if not installed_libraries[library_id]["uninstallable"]:
raise HTTPException(status_code=403, detail="指定された音声ライブラリはアンインストールできません。")
raise HTTPException(
status_code=403, detail=f"指定された音声ライブラリ {library_id} はアンインストールできません。"
)

try:
shutil.rmtree(self.library_root_dir / library_id)
except Exception:
raise HTTPException(status_code=500, detail="ライブラリの削除に失敗しました。")
raise HTTPException(
status_code=500, detail=f"指定された音声ライブラリ {library_id} の削除に失敗しました。"
)