Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
18 changes: 18 additions & 0 deletions test/test_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""マニフェストのテスト"""

from pathlib import Path

from voicevox_engine.engine_manifest import ManifestContainer


def test_ManifestContainer_init() -> None:
"""`ManifestContainer.from_file()` でインスタンスが生成される。"""
ManifestContainer.from_file(Path("engine_manifest.json"))
assert True


def test_ManifestContainer_relative_path() -> None:
"""`ManifestContainer.root` を用いてマニフェスト内の相対パスが解決できる。"""
container = ManifestContainer.from_file(Path("engine_manifest.json"))
tos_path = container.root / container.terms_of_service
assert tos_path.exists()
8 changes: 4 additions & 4 deletions voicevox_engine/app/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from voicevox_engine.app.routers.user_dict import generate_user_dict_router
from voicevox_engine.cancellable_engine import CancellableEngine
from voicevox_engine.core.core_initializer import CoreManager
from voicevox_engine.engine_manifest import EngineManifest
from voicevox_engine.engine_manifest import ManifestContainer
from voicevox_engine.library.library_manager import LibraryManager
from voicevox_engine.metas.MetasStore import MetasStore
from voicevox_engine.preset.preset_manager import PresetManager
Expand All @@ -36,7 +36,7 @@ def generate_app(
setting_loader: SettingHandler,
preset_manager: PresetManager,
user_dict: UserDictionary,
engine_manifest: EngineManifest,
engine_manifest: ManifestContainer,
cancellable_engine: CancellableEngine | None = None,
speaker_info_dir: Path | None = None,
cors_policy_mode: CorsPolicyMode = CorsPolicyMode.localapps,
Expand All @@ -60,7 +60,7 @@ def generate_app(

library_manager = LibraryManager(
get_save_dir() / "installed_libraries",
engine_manifest.supported_vvlib_manifest_version,
None,
engine_manifest.brand_name,
engine_manifest.name,
engine_manifest.uuid,
Expand All @@ -78,7 +78,7 @@ def generate_app(
app.include_router(
generate_speaker_router(core_manager, metas_store, speaker_info_dir)
)
if engine_manifest.supported_features.manage_library:
if engine_manifest.supported_features.manage_library.value:
app.include_router(generate_library_router(engine_manifest, library_manager))
app.include_router(generate_user_dict_router(user_dict))
app.include_router(generate_engine_info_router(core_manager, engine_manifest))
Expand Down
10 changes: 7 additions & 3 deletions voicevox_engine/app/routers/engine_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
from voicevox_engine import __version__
from voicevox_engine.core.core_adapter import DeviceSupport
from voicevox_engine.core.core_initializer import CoreManager
from voicevox_engine.engine_manifest import EngineManifest
from voicevox_engine.engine_manifest import (
EngineManifest,
ManifestContainer,
generate_api_manifest,
)


class SupportedDevicesInfo(BaseModel):
Expand All @@ -32,7 +36,7 @@ def generate_from(cls, device_support: DeviceSupport) -> Self:


def generate_engine_info_router(
core_manager: CoreManager, engine_manifest_data: EngineManifest
core_manager: CoreManager, engine_manifest_data: ManifestContainer
) -> APIRouter:
"""エンジン情報 API Router を生成する"""
router = APIRouter(tags=["その他"])
Expand Down Expand Up @@ -61,6 +65,6 @@ def supported_devices(core_version: str | None = None) -> SupportedDevicesInfo:
@router.get("/engine_manifest", response_model=EngineManifest)
async def engine_manifest() -> EngineManifest:
"""エンジンマニフェストを取得します。"""
return engine_manifest_data
return generate_api_manifest(engine_manifest_data)

return router
12 changes: 6 additions & 6 deletions voicevox_engine/app/routers/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

from fastapi import APIRouter, Depends, HTTPException, Path, Request

from voicevox_engine.engine_manifest import EngineManifest
from voicevox_engine.engine_manifest import ManifestContainer
from voicevox_engine.library.library_manager import LibraryManager
from voicevox_engine.library.model import DownloadableLibraryInfo, InstalledLibraryInfo

from ..dependencies import check_disabled_mutable_api


def generate_library_router(
engine_manifest_data: EngineManifest, library_manager: LibraryManager
engine_manifest_data: ManifestContainer, library_manager: LibraryManager
) -> APIRouter:
"""音声ライブラリ API Router を生成する"""
router = APIRouter(tags=["音声ライブラリ管理"])
Expand All @@ -27,7 +27,7 @@ def downloadable_libraries() -> list[DownloadableLibraryInfo]:
"""
ダウンロード可能な音声ライブラリの情報を返します。
"""
if not engine_manifest_data.supported_features.manage_library:
if not engine_manifest_data.supported_features.manage_library.value:
raise HTTPException(status_code=404, detail="この機能は実装されていません")
return library_manager.downloadable_libraries()

Expand All @@ -39,7 +39,7 @@ def installed_libraries() -> dict[str, InstalledLibraryInfo]:
"""
インストールした音声ライブラリの情報を返します。
"""
if not engine_manifest_data.supported_features.manage_library:
if not engine_manifest_data.supported_features.manage_library.value:
raise HTTPException(status_code=404, detail="この機能は実装されていません")
return library_manager.installed_libraries()

Expand All @@ -56,7 +56,7 @@ async def install_library(
音声ライブラリをインストールします。
音声ライブラリのZIPファイルをリクエストボディとして送信してください。
"""
if not engine_manifest_data.supported_features.manage_library:
if not engine_manifest_data.supported_features.manage_library.value:
raise HTTPException(status_code=404, detail="この機能は実装されていません")
archive = BytesIO(await request.body())
loop = asyncio.get_event_loop()
Expand All @@ -75,7 +75,7 @@ def uninstall_library(
"""
音声ライブラリをアンインストールします。
"""
if not engine_manifest_data.supported_features.manage_library:
if not engine_manifest_data.supported_features.manage_library.value:
raise HTTPException(status_code=404, detail="この機能は実装されていません")
library_manager.uninstall_library(library_uuid)

Expand Down
24 changes: 20 additions & 4 deletions voicevox_engine/engine_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import json
from base64 import b64encode
from pathlib import Path
from typing import TypeAlias
from typing import Self, TypeAlias

from pydantic import BaseModel, Field

Expand Down Expand Up @@ -54,6 +54,17 @@ class EngineManifestJson(BaseModel):
supported_features: SupportedFeaturesJson


class ManifestContainer(EngineManifestJson):
root: Path # エンジンマニフェストに記述された相対パスのルート

@classmethod
def from_file(cls, manifest_path: Path) -> Self:
"""指定ファイルからインスタンスを生成する。"""
manifest = EngineManifestJson.parse_file(manifest_path)
manifest_root = manifest_path.parent
return cls(root=manifest_root, **manifest.dict())


class UpdateInfo(BaseModel):
"""
エンジンのアップデート情報
Expand Down Expand Up @@ -122,11 +133,16 @@ class EngineManifest(BaseModel):
supported_features: SupportedFeatures = Field(title="エンジンが持つ機能")


def load_manifest(manifest_path: Path) -> EngineManifest:
def load_manifest(manifest_path: Path) -> ManifestContainer:
"""エンジンマニフェストを指定ファイルから読み込む。"""
return ManifestContainer.from_file(manifest_path)


def generate_api_manifest(manifest_container: ManifestContainer) -> EngineManifest:
"""API 向けのエンジンマニフェストを生成する。"""
root_dir = manifest_container.root
manifest = manifest_container.dict()

root_dir = manifest_path.parent
manifest = EngineManifestJson.parse_file(manifest_path).dict()
return EngineManifest(
manifest_version=manifest["manifest_version"],
name=manifest["name"],
Expand Down