diff --git a/discstore/adapters/inbound/api/__init__.py b/discstore/adapters/inbound/api/__init__.py deleted file mode 100644 index 3aaf672b..00000000 --- a/discstore/adapters/inbound/api/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -from discstore.adapters.inbound.api.current_tag_router import build_current_tag_router -from discstore.adapters.inbound.api.discs_router import build_discs_router -from discstore.adapters.inbound.api.models import ( - CurrentTagDiscOutput, - CurrentTagStatusOutput, - DiscInput, - DiscOutput, - DiscPatchInput, - SettingsPatchInput, - SettingsResetInput, -) -from discstore.adapters.inbound.api.settings_router import build_settings_router - -__all__ = [ - "CurrentTagDiscOutput", - "CurrentTagStatusOutput", - "DiscInput", - "DiscOutput", - "DiscPatchInput", - "SettingsPatchInput", - "SettingsResetInput", - "build_current_tag_router", - "build_discs_router", - "build_settings_router", -] diff --git a/discstore/adapters/outbound/json_library_adapter.py b/discstore/adapters/outbound/json_library_adapter.py deleted file mode 100644 index be5696b1..00000000 --- a/discstore/adapters/outbound/json_library_adapter.py +++ /dev/null @@ -1,3 +0,0 @@ -from jukebox.adapters.outbound.json_library_adapter import JsonLibraryAdapter - -__all__ = ["JsonLibraryAdapter"] diff --git a/discstore/adapters/outbound/text_current_tag_adapter.py b/discstore/adapters/outbound/text_current_tag_adapter.py deleted file mode 100644 index 6ecd82f4..00000000 --- a/discstore/adapters/outbound/text_current_tag_adapter.py +++ /dev/null @@ -1,3 +0,0 @@ -from jukebox.adapters.outbound.text_current_tag_adapter import TextCurrentTagAdapter - -__all__ = ["TextCurrentTagAdapter"] diff --git a/discstore/di_container.py b/discstore/di_container.py deleted file mode 100644 index cc34f1bb..00000000 --- a/discstore/di_container.py +++ /dev/null @@ -1,42 +0,0 @@ -from discstore.adapters.inbound.cli_controller import CLIController -from discstore.adapters.inbound.interactive_cli_controller import ( - InteractiveCLIController, -) -from discstore.adapters.outbound.json_library_adapter import JsonLibraryAdapter -from discstore.adapters.outbound.text_current_tag_adapter import TextCurrentTagAdapter -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc -from discstore.domain.use_cases.resolve_tag_id import ResolveTagId -from discstore.domain.use_cases.search_discs import SearchDiscs -from jukebox.shared.config_utils import get_current_tag_path - - -def build_cli_controller(library_path: str): - repository = JsonLibraryAdapter(library_path) - current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) - get_current_tag_status = GetCurrentTagStatus(current_tag_repository, repository) - return CLIController( - AddDisc(repository), - ListDiscs(repository), - RemoveDisc(repository), - EditDisc(repository), - GetDisc(repository), - SearchDiscs(repository), - ResolveTagId(get_current_tag_status), - ) - - -def build_interactive_cli_controller(library_path: str): - repository = JsonLibraryAdapter(library_path) - current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) - return InteractiveCLIController( - AddDisc(repository), - ListDiscs(repository), - RemoveDisc(repository), - EditDisc(repository), - GetCurrentTagStatus(current_tag_repository, repository), - ) diff --git a/discstore/domain/entities/__init__.py b/discstore/domain/entities/__init__.py deleted file mode 100644 index 56da5db2..00000000 --- a/discstore/domain/entities/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from jukebox.domain.entities.disc import Disc, DiscMetadata, DiscOption -from jukebox.domain.entities.library import Library - -from .current_tag_status import CurrentTagStatus - -__all__ = ["CurrentTagStatus", "Disc", "DiscMetadata", "DiscOption", "Library"] diff --git a/discstore/domain/repositories/__init__.py b/discstore/domain/repositories/__init__.py deleted file mode 100644 index 4e8cdaa3..00000000 --- a/discstore/domain/repositories/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from jukebox.domain.repositories.current_tag_repository import CurrentTagRepository -from jukebox.domain.repositories.library_repository import LibraryRepository - -__all__ = ["CurrentTagRepository", "LibraryRepository"] diff --git a/discstore/domain/use_cases/__init__.py b/discstore/domain/use_cases/__init__.py deleted file mode 100644 index d4e64393..00000000 --- a/discstore/domain/use_cases/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from .add_disc import AddDisc -from .edit_disc import EditDisc -from .get_current_tag_status import GetCurrentTagStatus -from .get_disc import GetDisc -from .list_discs import ListDiscs -from .remove_disc import RemoveDisc -from .resolve_tag_id import ResolveTagId -from .search_discs import SearchDiscs - -__all__ = [ - "AddDisc", - "EditDisc", - "GetDisc", - "GetCurrentTagStatus", - "ListDiscs", - "RemoveDisc", - "ResolveTagId", - "SearchDiscs", -] diff --git a/discstore/__init__.py b/jukebox/adapters/inbound/admin/__init__.py similarity index 100% rename from discstore/__init__.py rename to jukebox/adapters/inbound/admin/__init__.py diff --git a/discstore/adapters/__init__.py b/jukebox/adapters/inbound/admin/api/__init__.py similarity index 100% rename from discstore/adapters/__init__.py rename to jukebox/adapters/inbound/admin/api/__init__.py diff --git a/discstore/adapters/inbound/api/current_tag_router.py b/jukebox/adapters/inbound/admin/api/current_tag_router.py similarity index 92% rename from discstore/adapters/inbound/api/current_tag_router.py rename to jukebox/adapters/inbound/admin/api/current_tag_router.py index 4ae447bb..7788399b 100644 --- a/discstore/adapters/inbound/api/current_tag_router.py +++ b/jukebox/adapters/inbound/admin/api/current_tag_router.py @@ -3,19 +3,19 @@ from fastapi import APIRouter, HTTPException, Response, status from pydantic import ValidationError -from discstore.adapters.inbound.api.models import ( +from jukebox.adapters.inbound.admin.api.models import ( CurrentTagDiscOutput, CurrentTagStatusOutput, DiscInput, DiscOutput, DiscPatchInput, ) -from discstore.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc def build_current_tag_router( diff --git a/discstore/adapters/inbound/api/discs_router.py b/jukebox/adapters/inbound/admin/api/discs_router.py similarity index 85% rename from discstore/adapters/inbound/api/discs_router.py rename to jukebox/adapters/inbound/admin/api/discs_router.py index a9ab4f81..d373abf5 100644 --- a/discstore/adapters/inbound/api/discs_router.py +++ b/jukebox/adapters/inbound/admin/api/discs_router.py @@ -1,13 +1,13 @@ from fastapi import APIRouter, HTTPException, Response, status from pydantic import ValidationError -from discstore.adapters.inbound.api.models import DiscInput, DiscOutput, DiscPatchInput -from discstore.domain.entities import Disc, DiscMetadata, DiscOption -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.adapters.inbound.admin.api.models import DiscInput, DiscOutput, DiscPatchInput +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc def build_discs_router( diff --git a/discstore/adapters/inbound/api/models.py b/jukebox/adapters/inbound/admin/api/models.py similarity index 93% rename from discstore/adapters/inbound/api/models.py rename to jukebox/adapters/inbound/admin/api/models.py index d2bd1ab2..87fd64fc 100644 --- a/discstore/adapters/inbound/api/models.py +++ b/jukebox/adapters/inbound/admin/api/models.py @@ -2,7 +2,7 @@ from pydantic import BaseModel, RootModel -from discstore.domain.entities import CurrentTagStatus, Disc +from jukebox.domain.entities import CurrentTagStatus, Disc class DiscInput(Disc): diff --git a/discstore/adapters/inbound/api/settings_router.py b/jukebox/adapters/inbound/admin/api/settings_router.py similarity index 95% rename from discstore/adapters/inbound/api/settings_router.py rename to jukebox/adapters/inbound/admin/api/settings_router.py index a266caff..75f958a8 100644 --- a/discstore/adapters/inbound/api/settings_router.py +++ b/jukebox/adapters/inbound/admin/api/settings_router.py @@ -2,7 +2,7 @@ from fastapi import APIRouter, HTTPException -from discstore.adapters.inbound.api.models import SettingsPatchInput, SettingsResetInput +from jukebox.adapters.inbound.admin.api.models import SettingsPatchInput, SettingsResetInput from jukebox.settings.errors import SettingsError from jukebox.settings.service_protocols import SettingsService from jukebox.settings.types import JsonObject diff --git a/discstore/adapters/inbound/api_controller.py b/jukebox/adapters/inbound/admin/api_controller.py similarity index 89% rename from discstore/adapters/inbound/api_controller.py rename to jukebox/adapters/inbound/admin/api_controller.py index 2f4442b4..bdd6d52a 100644 --- a/discstore/adapters/inbound/api_controller.py +++ b/jukebox/adapters/inbound/admin/api_controller.py @@ -5,9 +5,9 @@ try: from fastapi import FastAPI, HTTPException - from discstore.adapters.inbound.api.current_tag_router import build_current_tag_router - from discstore.adapters.inbound.api.discs_router import build_discs_router - from discstore.adapters.inbound.api.models import ( + from jukebox.adapters.inbound.admin.api.current_tag_router import build_current_tag_router + from jukebox.adapters.inbound.admin.api.discs_router import build_discs_router + from jukebox.adapters.inbound.admin.api.models import ( CurrentTagDiscOutput, CurrentTagStatusOutput, DiscInput, @@ -16,19 +16,19 @@ SettingsPatchInput, SettingsResetInput, ) - from discstore.adapters.inbound.api.settings_router import build_settings_router + from jukebox.adapters.inbound.admin.api.settings_router import build_settings_router except ModuleNotFoundError as e: if e.name != "fastapi": raise raise ModuleNotFoundError( optional_extra_dependency_message("The `api_controller` module", "api", "jukebox-admin api") ) from e -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc from jukebox.settings.entities import SelectedSonosGroupSettings from jukebox.settings.selected_sonos_group_repository import SettingsSelectedSonosGroupRepository from jukebox.settings.service_protocols import SettingsService diff --git a/discstore/adapters/inbound/cli_controller.py b/jukebox/adapters/inbound/admin/cli_controller.py similarity index 86% rename from discstore/adapters/inbound/cli_controller.py rename to jukebox/adapters/inbound/admin/cli_controller.py index bfd56385..b0406279 100644 --- a/discstore/adapters/inbound/cli_controller.py +++ b/jukebox/adapters/inbound/admin/cli_controller.py @@ -1,7 +1,7 @@ import logging -from discstore.adapters.inbound.cli_display import display_library_line, display_library_table -from discstore.commands import ( +from jukebox.adapters.inbound.admin.cli_display import display_library_line, display_library_table +from jukebox.admin.library_commands import ( CliAddCommand, CliEditCommand, CliGetCommand, @@ -9,14 +9,14 @@ CliRemoveCommand, CliSearchCommand, ) -from discstore.domain.entities import Disc, DiscMetadata, DiscOption -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc -from discstore.domain.use_cases.resolve_tag_id import ResolveTagId -from discstore.domain.use_cases.search_discs import SearchDiscs +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc +from jukebox.domain.use_cases.library.resolve_tag_id import ResolveTagId +from jukebox.domain.use_cases.library.search_discs import SearchDiscs LOGGER = logging.getLogger("discstore") diff --git a/discstore/adapters/inbound/cli_display.py b/jukebox/adapters/inbound/admin/cli_display.py similarity index 97% rename from discstore/adapters/inbound/cli_display.py rename to jukebox/adapters/inbound/admin/cli_display.py index 76272269..c7447089 100644 --- a/discstore/adapters/inbound/cli_display.py +++ b/jukebox/adapters/inbound/admin/cli_display.py @@ -1,4 +1,4 @@ -from discstore.domain.entities import Disc +from jukebox.domain.entities import Disc MAX_COL_WIDTH = 20 diff --git a/discstore/adapters/inbound/interactive_cli_controller.py b/jukebox/adapters/inbound/admin/interactive_cli_controller.py similarity index 89% rename from discstore/adapters/inbound/interactive_cli_controller.py rename to jukebox/adapters/inbound/admin/interactive_cli_controller.py index 9aaa23fc..1af699c1 100644 --- a/discstore/adapters/inbound/interactive_cli_controller.py +++ b/jukebox/adapters/inbound/admin/interactive_cli_controller.py @@ -1,12 +1,12 @@ import logging -from discstore.adapters.inbound.cli_display import display_library_line, display_library_table -from discstore.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.adapters.inbound.admin.cli_display import display_library_line, display_library_table +from jukebox.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc LOGGER = logging.getLogger("discstore") diff --git a/discstore/adapters/inbound/ui_controller.py b/jukebox/adapters/inbound/admin/ui_controller.py similarity index 96% rename from discstore/adapters/inbound/ui_controller.py rename to jukebox/adapters/inbound/admin/ui_controller.py index db291c5d..9c79020b 100644 --- a/discstore/adapters/inbound/ui_controller.py +++ b/jukebox/adapters/inbound/admin/ui_controller.py @@ -17,17 +17,17 @@ from pydantic import BaseModel, Field -from discstore.adapters.inbound.api_controller import APIController -from discstore.adapters.inbound.ui_pages.library import DiscForm, DiscTable, LibraryUIPageBuilder -from discstore.adapters.inbound.ui_pages.settings import SettingsUIPageBuilder -from discstore.adapters.inbound.ui_pages.sonos import SonosSelectionForm, SonosUIPageBuilder -from discstore.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.adapters.inbound.admin.api_controller import APIController +from jukebox.adapters.inbound.admin.ui_pages.library import DiscForm, DiscTable, LibraryUIPageBuilder +from jukebox.adapters.inbound.admin.ui_pages.settings import SettingsUIPageBuilder +from jukebox.adapters.inbound.admin.ui_pages.sonos import SonosSelectionForm, SonosUIPageBuilder +from jukebox.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc from jukebox.settings.definitions import ( EditableSettingDisplay, get_setting_definition, diff --git a/discstore/adapters/inbound/__init__.py b/jukebox/adapters/inbound/admin/ui_pages/__init__.py similarity index 100% rename from discstore/adapters/inbound/__init__.py rename to jukebox/adapters/inbound/admin/ui_pages/__init__.py diff --git a/discstore/adapters/inbound/ui_pages/library.py b/jukebox/adapters/inbound/admin/ui_pages/library.py similarity index 98% rename from discstore/adapters/inbound/ui_pages/library.py rename to jukebox/adapters/inbound/admin/ui_pages/library.py index a0f0528b..c562e1d8 100644 --- a/discstore/adapters/inbound/ui_pages/library.py +++ b/jukebox/adapters/inbound/admin/ui_pages/library.py @@ -8,10 +8,10 @@ from fastui.events import BackEvent, GoToEvent, PageEvent from pydantic import BaseModel, Field -from discstore.domain.entities import CurrentTagStatus, DiscMetadata, DiscOption -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs +from jukebox.domain.entities import CurrentTagStatus, DiscMetadata, DiscOption +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs class DiscTable(DiscMetadata, DiscOption): diff --git a/discstore/adapters/inbound/ui_pages/settings.py b/jukebox/adapters/inbound/admin/ui_pages/settings.py similarity index 100% rename from discstore/adapters/inbound/ui_pages/settings.py rename to jukebox/adapters/inbound/admin/ui_pages/settings.py diff --git a/discstore/adapters/inbound/ui_pages/sonos.py b/jukebox/adapters/inbound/admin/ui_pages/sonos.py similarity index 100% rename from discstore/adapters/inbound/ui_pages/sonos.py rename to jukebox/adapters/inbound/admin/ui_pages/sonos.py diff --git a/jukebox/admin/app.py b/jukebox/admin/app.py index e812013a..540f0b7d 100644 --- a/jukebox/admin/app.py +++ b/jukebox/admin/app.py @@ -5,8 +5,8 @@ import typer from pydantic import ValidationError -from discstore.command_handlers import execute_library_command -from discstore.commands import ( +from jukebox.admin.library_command_handlers import execute_library_command +from jukebox.admin.library_commands import ( CliAddCommand, CliEditCommand, CliGetCommand, @@ -16,7 +16,6 @@ CliSearchCommand, InteractiveCliCommand, ) -from discstore.di_container import build_cli_controller, build_interactive_cli_controller from jukebox.settings.errors import SettingsError from jukebox.shared.config_utils import get_package_version from jukebox.shared.logger import set_logger @@ -41,7 +40,14 @@ is_settings_command, is_sonos_command, ) -from .di_container import build_admin_api_app, build_admin_services, build_admin_ui_app, build_settings_service +from .di_container import ( + build_admin_api_app, + build_admin_services, + build_admin_ui_app, + build_cli_controller, + build_interactive_cli_controller, + build_settings_service, +) from .pn532_command_handlers import execute_pn532_command from .pn532_commands import Pn532ProbeCommand, Pn532ProfilesCommand, Pn532SelectCommand, is_pn532_command from .sonos_households import GroupedSonosHousehold diff --git a/jukebox/admin/di_container.py b/jukebox/admin/di_container.py index 21ed3c9d..e4ac8b6c 100644 --- a/jukebox/admin/di_container.py +++ b/jukebox/admin/di_container.py @@ -1,12 +1,14 @@ -from discstore.adapters.outbound.json_library_adapter import JsonLibraryAdapter -from discstore.adapters.outbound.text_current_tag_adapter import TextCurrentTagAdapter -from discstore.domain.use_cases.add_disc import AddDisc -from discstore.domain.use_cases.edit_disc import EditDisc -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus -from discstore.domain.use_cases.get_disc import GetDisc -from discstore.domain.use_cases.list_discs import ListDiscs -from discstore.domain.use_cases.remove_disc import RemoveDisc +from jukebox.adapters.outbound.json_library_adapter import JsonLibraryAdapter from jukebox.adapters.outbound.sonos_discovery_adapter import SoCoSonosDiscoveryAdapter +from jukebox.adapters.outbound.text_current_tag_adapter import TextCurrentTagAdapter +from jukebox.domain.use_cases.library.add_disc import AddDisc +from jukebox.domain.use_cases.library.edit_disc import EditDisc +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_disc import GetDisc +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc +from jukebox.domain.use_cases.library.resolve_tag_id import ResolveTagId +from jukebox.domain.use_cases.library.search_discs import SearchDiscs from jukebox.settings.file_settings_repository import FileSettingsRepository from jukebox.settings.resolve import SettingsService as SettingsServiceImpl from jukebox.settings.resolve import build_environment_settings_overrides @@ -56,7 +58,7 @@ def build_admin_api_app(library_path: str, services: AdminServices): repository = JsonLibraryAdapter(library_path) current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) - from discstore.adapters.inbound.api_controller import APIController + from jukebox.adapters.inbound.admin.api_controller import APIController return APIController( AddDisc(repository), @@ -74,7 +76,7 @@ def build_admin_ui_app(library_path: str, services: AdminServices): repository = JsonLibraryAdapter(library_path) current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) - from discstore.adapters.inbound.ui_controller import UIController + from jukebox.adapters.inbound.admin.ui_controller import UIController return UIController( AddDisc(repository), @@ -90,3 +92,36 @@ def build_admin_ui_app(library_path: str, services: AdminServices): def build_sonos_service() -> SonosService: return DefaultSonosService(SoCoSonosDiscoveryAdapter()) + + +def build_cli_controller(library_path: str): + repository = JsonLibraryAdapter(library_path) + current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) + get_current_tag_status = GetCurrentTagStatus(current_tag_repository, repository) + + from jukebox.adapters.inbound.admin.cli_controller import CLIController + + return CLIController( + AddDisc(repository), + ListDiscs(repository), + RemoveDisc(repository), + EditDisc(repository), + GetDisc(repository), + SearchDiscs(repository), + ResolveTagId(get_current_tag_status), + ) + + +def build_interactive_cli_controller(library_path: str): + repository = JsonLibraryAdapter(library_path) + current_tag_repository = TextCurrentTagAdapter(get_current_tag_path(library_path)) + + from jukebox.adapters.inbound.admin.interactive_cli_controller import InteractiveCLIController + + return InteractiveCLIController( + AddDisc(repository), + ListDiscs(repository), + RemoveDisc(repository), + EditDisc(repository), + GetCurrentTagStatus(current_tag_repository, repository), + ) diff --git a/discstore/command_handlers.py b/jukebox/admin/library_command_handlers.py similarity index 94% rename from discstore/command_handlers.py rename to jukebox/admin/library_command_handlers.py index 50a2a7ab..de7e20a7 100644 --- a/discstore/command_handlers.py +++ b/jukebox/admin/library_command_handlers.py @@ -3,7 +3,7 @@ from jukebox.settings.service_protocols import SettingsService -from .commands import InteractiveCliCommand +from .library_commands import InteractiveCliCommand class LibraryController(Protocol): diff --git a/discstore/commands.py b/jukebox/admin/library_commands.py similarity index 100% rename from discstore/commands.py rename to jukebox/admin/library_commands.py diff --git a/jukebox/domain/entities/__init__.py b/jukebox/domain/entities/__init__.py index d0b4e1e2..ab41acaa 100644 --- a/jukebox/domain/entities/__init__.py +++ b/jukebox/domain/entities/__init__.py @@ -1,4 +1,5 @@ from .current_tag_action import CurrentTagAction +from .current_tag_status import CurrentTagStatus from .disc import Disc, DiscMetadata, DiscOption from .library import Library from .playback_action import PlaybackAction @@ -7,6 +8,7 @@ __all__ = [ "CurrentTagAction", + "CurrentTagStatus", "PlaybackAction", "PlaybackSession", "TagEvent", diff --git a/discstore/domain/entities/current_tag_status.py b/jukebox/domain/entities/current_tag_status.py similarity index 100% rename from discstore/domain/entities/current_tag_status.py rename to jukebox/domain/entities/current_tag_status.py diff --git a/discstore/adapters/inbound/ui_pages/__init__.py b/jukebox/domain/use_cases/library/__init__.py similarity index 100% rename from discstore/adapters/inbound/ui_pages/__init__.py rename to jukebox/domain/use_cases/library/__init__.py diff --git a/discstore/domain/use_cases/add_disc.py b/jukebox/domain/use_cases/library/add_disc.py similarity index 69% rename from discstore/domain/use_cases/add_disc.py rename to jukebox/domain/use_cases/library/add_disc.py index 05c746cc..701ebdb1 100644 --- a/discstore/domain/use_cases/add_disc.py +++ b/jukebox/domain/use_cases/library/add_disc.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc +from jukebox.domain.repositories import LibraryRepository class AddDisc: diff --git a/discstore/domain/use_cases/edit_disc.py b/jukebox/domain/use_cases/library/edit_disc.py similarity index 90% rename from discstore/domain/use_cases/edit_disc.py rename to jukebox/domain/use_cases/library/edit_disc.py index 5e20a02b..97e77d35 100644 --- a/discstore/domain/use_cases/edit_disc.py +++ b/jukebox/domain/use_cases/library/edit_disc.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc, DiscMetadata, DiscOption -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.domain.repositories import LibraryRepository class EditDisc: diff --git a/discstore/domain/use_cases/get_current_tag_status.py b/jukebox/domain/use_cases/library/get_current_tag_status.py similarity index 77% rename from discstore/domain/use_cases/get_current_tag_status.py rename to jukebox/domain/use_cases/library/get_current_tag_status.py index e6c35eab..b84deb1f 100644 --- a/discstore/domain/use_cases/get_current_tag_status.py +++ b/jukebox/domain/use_cases/library/get_current_tag_status.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import CurrentTagStatus -from discstore.domain.repositories import CurrentTagRepository, LibraryRepository +from jukebox.domain.entities import CurrentTagStatus +from jukebox.domain.repositories import CurrentTagRepository, LibraryRepository class GetCurrentTagStatus: diff --git a/discstore/domain/use_cases/get_disc.py b/jukebox/domain/use_cases/library/get_disc.py similarity index 75% rename from discstore/domain/use_cases/get_disc.py rename to jukebox/domain/use_cases/library/get_disc.py index 0fcd3588..482e7a1f 100644 --- a/discstore/domain/use_cases/get_disc.py +++ b/jukebox/domain/use_cases/library/get_disc.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc +from jukebox.domain.repositories import LibraryRepository class GetDisc: diff --git a/discstore/domain/use_cases/list_discs.py b/jukebox/domain/use_cases/library/list_discs.py similarity index 65% rename from discstore/domain/use_cases/list_discs.py rename to jukebox/domain/use_cases/library/list_discs.py index 24249dfc..fad79aad 100644 --- a/discstore/domain/use_cases/list_discs.py +++ b/jukebox/domain/use_cases/library/list_discs.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc +from jukebox.domain.repositories import LibraryRepository class ListDiscs: diff --git a/discstore/domain/use_cases/remove_disc.py b/jukebox/domain/use_cases/library/remove_disc.py similarity index 77% rename from discstore/domain/use_cases/remove_disc.py rename to jukebox/domain/use_cases/library/remove_disc.py index e2633f10..85411733 100644 --- a/discstore/domain/use_cases/remove_disc.py +++ b/jukebox/domain/use_cases/library/remove_disc.py @@ -1,4 +1,4 @@ -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.repositories import LibraryRepository class RemoveDisc: diff --git a/discstore/domain/use_cases/resolve_tag_id.py b/jukebox/domain/use_cases/library/resolve_tag_id.py similarity index 89% rename from discstore/domain/use_cases/resolve_tag_id.py rename to jukebox/domain/use_cases/library/resolve_tag_id.py index 40332f0c..706c5bf1 100644 --- a/discstore/domain/use_cases/resolve_tag_id.py +++ b/jukebox/domain/use_cases/library/resolve_tag_id.py @@ -1,4 +1,4 @@ -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus class ResolveTagId: diff --git a/discstore/domain/use_cases/search_discs.py b/jukebox/domain/use_cases/library/search_discs.py similarity index 89% rename from discstore/domain/use_cases/search_discs.py rename to jukebox/domain/use_cases/library/search_discs.py index d61d415a..b5a8e5f4 100644 --- a/discstore/domain/use_cases/search_discs.py +++ b/jukebox/domain/use_cases/library/search_discs.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc +from jukebox.domain.repositories import LibraryRepository class SearchDiscs: diff --git a/pyproject.toml b/pyproject.toml index f57b56fe..cc2d2eab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ requires = ["uv_build>=0.8.7,<0.12.0"] build-backend = "uv_build" [tool.uv.build-backend] -module-name = ["jukebox", "discstore", "pn532"] +module-name = ["jukebox", "pn532"] module-root = "" [project.scripts] diff --git a/tests/discstore/__init__.py b/tests/discstore/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/discstore/adapters/__init__.py b/tests/discstore/adapters/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/discstore/adapters/inbound/__init__.py b/tests/discstore/adapters/inbound/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/discstore/domain/__init__.py b/tests/discstore/domain/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/discstore/domain/use_cases/__init__.py b/tests/discstore/domain/use_cases/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/discstore/adapters/outbound/__init__.py b/tests/jukebox/adapters/inbound/admin/__init__.py similarity index 100% rename from discstore/adapters/outbound/__init__.py rename to tests/jukebox/adapters/inbound/admin/__init__.py diff --git a/tests/discstore/adapters/inbound/test_api_controller.py b/tests/jukebox/adapters/inbound/admin/test_api_controller.py similarity index 99% rename from tests/discstore/adapters/inbound/test_api_controller.py rename to tests/jukebox/adapters/inbound/admin/test_api_controller.py index 495d4ca4..69dffbaa 100644 --- a/tests/discstore/adapters/inbound/test_api_controller.py +++ b/tests/jukebox/adapters/inbound/admin/test_api_controller.py @@ -11,7 +11,7 @@ from fastapi import HTTPException from fastapi.routing import APIRoute - from discstore.adapters.inbound.api.models import ( + from jukebox.adapters.inbound.admin.api.models import ( DiscInput, DiscPatchInput, DiscPatchMetadataInput, @@ -19,12 +19,12 @@ SettingsPatchInput, SettingsResetInput, ) - from discstore.adapters.inbound.api_controller import ( + from jukebox.adapters.inbound.admin.api_controller import ( APIController, SonosSelectionInput, ) - from discstore.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption - from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption + from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus from jukebox.settings.errors import InvalidSettingsError from jukebox.sonos.discovery import DiscoveredSonosSpeaker, SonosDiscoveryError from jukebox.sonos.service import InspectedSelectedSonosGroup @@ -121,11 +121,11 @@ def build_inspected_group( def test_dependencies_import_failure(mocker): - sys.modules.pop("discstore.adapters.inbound.api_controller", None) + sys.modules.pop("jukebox.adapters.inbound.admin.api_controller", None) mocker.patch.dict("sys.modules", {"fastapi": None}) with pytest.raises(ModuleNotFoundError) as err: - import discstore.adapters.inbound.api_controller # noqa: F401 + import jukebox.adapters.inbound.admin.api_controller # noqa: F401 assert "The `api_controller` module requires the optional `api` dependencies." in str(err.value) assert "pip install 'gukebox[api]'" in str(err.value) diff --git a/tests/discstore/adapters/inbound/test_cli_controller.py b/tests/jukebox/adapters/inbound/admin/test_cli_controller.py similarity index 95% rename from tests/discstore/adapters/inbound/test_cli_controller.py rename to tests/jukebox/adapters/inbound/admin/test_cli_controller.py index e44aca28..5b7a95b6 100644 --- a/tests/discstore/adapters/inbound/test_cli_controller.py +++ b/tests/jukebox/adapters/inbound/admin/test_cli_controller.py @@ -2,9 +2,9 @@ import pytest -from discstore.adapters.inbound.cli_controller import CLIController -from discstore.commands import CliAddCommand, CliEditCommand, CliGetCommand, CliRemoveCommand -from discstore.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.adapters.inbound.admin.cli_controller import CLIController +from jukebox.admin.library_commands import CliAddCommand, CliEditCommand, CliGetCommand, CliRemoveCommand +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption def build_controller(): diff --git a/tests/discstore/adapters/inbound/test_cli_display.py b/tests/jukebox/adapters/inbound/admin/test_cli_display.py similarity index 91% rename from tests/discstore/adapters/inbound/test_cli_display.py rename to tests/jukebox/adapters/inbound/admin/test_cli_display.py index 633f564d..7f45e591 100644 --- a/tests/discstore/adapters/inbound/test_cli_display.py +++ b/tests/jukebox/adapters/inbound/admin/test_cli_display.py @@ -3,8 +3,8 @@ import pytest -from discstore.adapters.inbound.cli_display import display_library_line, display_library_table -from discstore.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.adapters.inbound.admin.cli_display import display_library_line, display_library_table +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption @pytest.fixture diff --git a/tests/discstore/adapters/inbound/test_interactive_cli_controller.py b/tests/jukebox/adapters/inbound/admin/test_interactive_cli_controller.py similarity index 95% rename from tests/discstore/adapters/inbound/test_interactive_cli_controller.py rename to tests/jukebox/adapters/inbound/admin/test_interactive_cli_controller.py index 2a713633..36bed8a2 100644 --- a/tests/discstore/adapters/inbound/test_interactive_cli_controller.py +++ b/tests/jukebox/adapters/inbound/admin/test_interactive_cli_controller.py @@ -1,7 +1,7 @@ from unittest.mock import MagicMock, patch -from discstore.adapters.inbound.interactive_cli_controller import InteractiveCLIController -from discstore.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption +from jukebox.adapters.inbound.admin.interactive_cli_controller import InteractiveCLIController +from jukebox.domain.entities import CurrentTagStatus, Disc, DiscMetadata, DiscOption def build_controller(): diff --git a/tests/discstore/adapters/inbound/test_ui_controller.py b/tests/jukebox/adapters/inbound/admin/test_ui_controller.py similarity index 96% rename from tests/discstore/adapters/inbound/test_ui_controller.py rename to tests/jukebox/adapters/inbound/admin/test_ui_controller.py index 54702809..da076917 100644 --- a/tests/discstore/adapters/inbound/test_ui_controller.py +++ b/tests/jukebox/adapters/inbound/admin/test_ui_controller.py @@ -21,11 +21,11 @@ def build_speaker(uid, name, host, household_id): def test_dependencies_import_failure(mocker): - sys.modules.pop("discstore.adapters.inbound.ui_controller", None) + sys.modules.pop("jukebox.adapters.inbound.admin.ui_controller", None) mocker.patch.dict("sys.modules", {"fastui": None}) with pytest.raises(ModuleNotFoundError) as err: - import discstore.adapters.inbound.ui_controller # noqa: F401 + import jukebox.adapters.inbound.admin.ui_controller # noqa: F401 assert "The `ui_controller` module requires the optional `ui` dependencies." in str(err.value) assert "pip install 'gukebox[ui]'" in str(err.value) @@ -34,7 +34,7 @@ def test_dependencies_import_failure(mocker): def build_controller(): - from discstore.adapters.inbound.ui_controller import UIController + from jukebox.adapters.inbound.admin.ui_controller import UIController from jukebox.sonos.service import InspectedSelectedSonosGroup, SonosService settings_service = MagicMock() @@ -135,7 +135,7 @@ def walk_components(components): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_ui_controller_registers_fastui_routes_and_page_structure(): - from discstore.domain.entities import Disc, DiscMetadata, DiscOption + from jukebox.domain.entities import Disc, DiscMetadata, DiscOption controller = build_controller() controller.list_discs.execute.return_value = { @@ -442,7 +442,7 @@ def test_sonos_edit_page_renders_speaker_and_coordinator_selects(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_sonos_selection_saves_and_redirects(): - from discstore.adapters.inbound.ui_controller import SonosSelectionForm + from jukebox.adapters.inbound.admin.ui_controller import SonosSelectionForm controller = build_controller() controller.settings_service.patch_persisted_settings.return_value = { @@ -481,7 +481,7 @@ async def test_update_sonos_selection_saves_and_redirects(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_sonos_selection_returns_field_error_for_invalid_coordinator(): - from discstore.adapters.inbound.ui_controller import SonosSelectionForm + from jukebox.adapters.inbound.admin.ui_controller import SonosSelectionForm controller = build_controller() route = next( @@ -537,7 +537,7 @@ def test_sonos_edit_page_renders_error_banner_and_preserves_submitted_values(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_sonos_selection_saves_single_speaker_selection(): - from discstore.adapters.inbound.ui_controller import SonosSelectionForm + from jukebox.adapters.inbound.admin.ui_controller import SonosSelectionForm controller = build_controller() controller.settings_service.patch_persisted_settings.return_value = {"message": "Settings saved."} @@ -572,7 +572,7 @@ async def test_update_sonos_selection_saves_single_speaker_selection(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_sonos_selection_redirects_when_write_succeeds_but_effective_settings_stay_invalid(): - from discstore.adapters.inbound.ui_controller import SonosSelectionForm + from jukebox.adapters.inbound.admin.ui_controller import SonosSelectionForm from jukebox.settings.errors import InvalidSettingsError controller = build_controller() @@ -747,7 +747,7 @@ def test_settings_edit_page_renders_empty_object_field_with_placeholder_when_no_ @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_setting_builds_scalar_patch_and_redirects_with_service_message(): - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm controller = build_controller() controller.settings_service.patch_persisted_settings.return_value = { @@ -771,7 +771,7 @@ async def test_update_setting_builds_scalar_patch_and_redirects_with_service_mes @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_setting_builds_object_patch_from_json_text(): - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm controller = build_controller() controller.settings_service.patch_persisted_settings.return_value = {"message": "Settings saved."} @@ -806,7 +806,7 @@ async def test_update_setting_builds_object_patch_from_json_text(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_setting_treats_blank_object_text_as_none(): - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm controller = build_controller() controller.settings_service.patch_persisted_settings.return_value = {"message": "Settings saved."} @@ -836,7 +836,7 @@ async def test_update_setting_treats_blank_object_text_as_none(): async def test_update_setting_returns_field_error_for_invalid_json(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm controller = build_controller() route = next( @@ -864,7 +864,7 @@ async def test_update_setting_returns_field_error_for_invalid_json(): async def test_update_setting_returns_field_error_for_non_object_json(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm controller = build_controller() route = next( @@ -890,7 +890,7 @@ async def test_update_setting_returns_field_error_for_non_object_json(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_setting_redirects_when_write_succeeds_but_effective_settings_stay_invalid(): - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm from jukebox.settings.errors import InvalidSettingsError controller = build_controller() @@ -935,7 +935,7 @@ def raise_after_persist(patch): async def test_update_setting_returns_field_error_for_shared_validation_failure(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import SettingValueForm + from jukebox.adapters.inbound.admin.ui_controller import SettingValueForm from jukebox.settings.errors import InvalidSettingsError controller = build_controller() @@ -1060,7 +1060,7 @@ def test_ui_controller_does_not_register_get_reset_setting_route(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_disc_library_components_render_empty_and_editable_states(): - from discstore.adapters.inbound.ui_controller import DiscTable + from jukebox.adapters.inbound.admin.ui_controller import DiscTable controller = build_controller() empty_components = controller._build_disc_library_components([]) @@ -1089,7 +1089,7 @@ def test_disc_library_components_render_empty_and_editable_states(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_current_tag_banner_for_unknown_disc_offers_add_cta(): - from discstore.domain.entities import CurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus controller = build_controller() @@ -1107,7 +1107,7 @@ def test_current_tag_banner_for_unknown_disc_offers_add_cta(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_current_tag_banner_for_known_disc_is_informational_only(): - from discstore.domain.entities import CurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus controller = build_controller() @@ -1136,7 +1136,7 @@ def test_new_disc_form_components_render_blank_add_form(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_new_disc_form_components_can_prefill_current_tag(): - from discstore.domain.entities import CurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus controller = build_controller() controller.get_current_tag_status.execute.return_value = CurrentTagStatus(tag_id="tag-123", known_in_library=False) @@ -1151,7 +1151,7 @@ def test_new_disc_form_components_can_prefill_current_tag(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_edit_disc_form_components_prefill_existing_disc(): - from discstore.domain.entities import Disc, DiscMetadata, DiscOption + from jukebox.domain.entities import Disc, DiscMetadata, DiscOption controller = build_controller() controller.get_disc.execute.return_value = Disc( @@ -1177,7 +1177,7 @@ def test_edit_disc_form_components_prefill_existing_disc(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") def test_disc_form_helpers_return_errors_for_invalid_current_tag_state_or_missing_edit_target(): - from discstore.domain.entities import CurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus controller = build_controller() @@ -1213,7 +1213,7 @@ def test_form_page_components_include_back_link_and_form(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_current_tag_banner_event_stream_emits_serialized_updates(): - from discstore.domain.entities import CurrentTagStatus + from jukebox.domain.entities import CurrentTagStatus controller = build_controller() controller.get_current_tag_status.execute.side_effect = [CurrentTagStatus(tag_id="tag-123", known_in_library=False)] @@ -1231,8 +1231,8 @@ async def test_current_tag_banner_event_stream_emits_serialized_updates(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_create_disc_returns_success_toast(): - from discstore.adapters.inbound.ui_controller import DiscForm - from discstore.domain.entities import Disc, DiscMetadata, DiscOption + from jukebox.adapters.inbound.admin.ui_controller import DiscForm + from jukebox.domain.entities import Disc, DiscMetadata, DiscOption controller = build_controller() route = next(route for route in controller.app.routes if getattr(route, "path", None) == "/api/ui/discs") @@ -1259,7 +1259,7 @@ async def test_create_disc_returns_success_toast(): async def test_create_disc_returns_conflict_when_add_fails(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import DiscForm + from jukebox.adapters.inbound.admin.ui_controller import DiscForm controller = build_controller() controller.add_disc.execute.side_effect = ValueError("Already existing tag") @@ -1282,8 +1282,8 @@ async def test_create_disc_returns_conflict_when_add_fails(): @pytest.mark.skipif(not FASTUI_INSTALLED, reason="FastUI dependencies are not installed") @pytest.mark.anyio async def test_update_disc_uses_edit_path(): - from discstore.adapters.inbound.ui_controller import DiscForm - from discstore.domain.entities import DiscMetadata, DiscOption + from jukebox.adapters.inbound.admin.ui_controller import DiscForm + from jukebox.domain.entities import DiscMetadata, DiscOption controller = build_controller() route = next( @@ -1312,7 +1312,7 @@ async def test_update_disc_uses_edit_path(): async def test_update_disc_rejects_tag_changes(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import DiscForm + from jukebox.adapters.inbound.admin.ui_controller import DiscForm controller = build_controller() route = next( @@ -1340,7 +1340,7 @@ async def test_update_disc_rejects_tag_changes(): async def test_update_disc_returns_field_error_when_edit_target_is_missing(): from fastapi import HTTPException - from discstore.adapters.inbound.ui_controller import DiscForm + from jukebox.adapters.inbound.admin.ui_controller import DiscForm controller = build_controller() controller.edit_disc.execute.side_effect = ValueError("Tag does not exist: tag_id='tag-123'") diff --git a/tests/jukebox/admin/test_app.py b/tests/jukebox/admin/test_app.py index 450792e6..aee37d0d 100644 --- a/tests/jukebox/admin/test_app.py +++ b/tests/jukebox/admin/test_app.py @@ -5,16 +5,6 @@ from pydantic import ValidationError from typer.testing import CliRunner -from discstore.commands import ( - CliAddCommand, - CliEditCommand, - CliGetCommand, - CliListCommand, - CliListCommandModes, - CliRemoveCommand, - CliSearchCommand, - InteractiveCliCommand, -) from jukebox.admin.app import _prompt_for_sonos_household_selection, app from jukebox.admin.commands import ( ApiCommand, @@ -26,6 +16,16 @@ SonosShowCommand, UiCommand, ) +from jukebox.admin.library_commands import ( + CliAddCommand, + CliEditCommand, + CliGetCommand, + CliListCommand, + CliListCommandModes, + CliRemoveCommand, + CliSearchCommand, + InteractiveCliCommand, +) from jukebox.admin.pn532_commands import Pn532ProbeCommand, Pn532ProfilesCommand, Pn532SelectCommand from jukebox.admin.sonos_households import GroupedSonosHousehold from jukebox.sonos.discovery import DiscoveredSonosSpeaker diff --git a/tests/jukebox/admin/test_di_container.py b/tests/jukebox/admin/test_di_container.py index 6777c4a8..7b99cdee 100644 --- a/tests/jukebox/admin/test_di_container.py +++ b/tests/jukebox/admin/test_di_container.py @@ -93,7 +93,8 @@ def test_build_admin_api_app_wiring(mocker, bootstrap_mocks): mock_api_instance = MagicMock() mock_api_controller_class = MagicMock(return_value=mock_api_instance) mocker.patch.dict( - "sys.modules", {"discstore.adapters.inbound.api_controller": MagicMock(APIController=mock_api_controller_class)} + "sys.modules", + {"jukebox.adapters.inbound.admin.api_controller": MagicMock(APIController=mock_api_controller_class)}, ) services = AdminServices(settings=MagicMock(), sonos=MagicMock()) @@ -118,7 +119,8 @@ def test_build_admin_ui_app_wiring(mocker, bootstrap_mocks): mock_ui_instance = MagicMock() mock_ui_controller_class = MagicMock(return_value=mock_ui_instance) mocker.patch.dict( - "sys.modules", {"discstore.adapters.inbound.ui_controller": MagicMock(UIController=mock_ui_controller_class)} + "sys.modules", + {"jukebox.adapters.inbound.admin.ui_controller": MagicMock(UIController=mock_ui_controller_class)}, ) services = AdminServices(settings=MagicMock(), sonos=MagicMock()) diff --git a/tests/discstore/test_command_handlers.py b/tests/jukebox/admin/test_library_command_handlers.py similarity index 91% rename from tests/discstore/test_command_handlers.py rename to tests/jukebox/admin/test_library_command_handlers.py index 1ce9b489..326dc33f 100644 --- a/tests/discstore/test_command_handlers.py +++ b/tests/jukebox/admin/test_library_command_handlers.py @@ -1,7 +1,11 @@ from unittest.mock import MagicMock, create_autospec -from discstore.command_handlers import InteractiveLibraryController, LibraryController, execute_library_command -from discstore.commands import CliSearchCommand, InteractiveCliCommand +from jukebox.admin.library_command_handlers import ( + InteractiveLibraryController, + LibraryController, + execute_library_command, +) +from jukebox.admin.library_commands import CliSearchCommand, InteractiveCliCommand from jukebox.settings.entities import ResolvedAdminRuntimeConfig from jukebox.settings.service_protocols import SettingsService diff --git a/tests/jukebox/domain/entities/test_disc_metadata.py b/tests/jukebox/domain/entities/test_disc_metadata.py index f272e731..79de797f 100644 --- a/tests/jukebox/domain/entities/test_disc_metadata.py +++ b/tests/jukebox/domain/entities/test_disc_metadata.py @@ -1,4 +1,4 @@ -from discstore.domain.entities import DiscMetadata +from jukebox.domain.entities import DiscMetadata def test_all_fields_optional(): diff --git a/tests/jukebox/domain/entities/test_disc_option.py b/tests/jukebox/domain/entities/test_disc_option.py index abad822e..ce4c2f0b 100644 --- a/tests/jukebox/domain/entities/test_disc_option.py +++ b/tests/jukebox/domain/entities/test_disc_option.py @@ -1,4 +1,4 @@ -from discstore.domain.entities import DiscOption +from jukebox.domain.entities import DiscOption def test_default_values(): diff --git a/tests/jukebox/domain/entities/test_discs.py b/tests/jukebox/domain/entities/test_discs.py index 5dea88c1..5c1db1b0 100644 --- a/tests/jukebox/domain/entities/test_discs.py +++ b/tests/jukebox/domain/entities/test_discs.py @@ -1,7 +1,7 @@ import pytest from pydantic import ValidationError -from discstore.domain.entities import Disc, DiscMetadata, DiscOption +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption def test_minimal_disc(): diff --git a/tests/jukebox/domain/entities/test_library.py b/tests/jukebox/domain/entities/test_library.py index 2e31dad4..3a50e3d0 100644 --- a/tests/jukebox/domain/entities/test_library.py +++ b/tests/jukebox/domain/entities/test_library.py @@ -1,4 +1,4 @@ -from discstore.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.entities import Disc, DiscMetadata, Library def test_library(): diff --git a/discstore/domain/__init__.py b/tests/jukebox/domain/use_cases/library/__init__.py similarity index 100% rename from discstore/domain/__init__.py rename to tests/jukebox/domain/use_cases/library/__init__.py diff --git a/tests/discstore/domain/use_cases/mock_repo.py b/tests/jukebox/domain/use_cases/library/mock_repo.py similarity index 93% rename from tests/discstore/domain/use_cases/mock_repo.py rename to tests/jukebox/domain/use_cases/library/mock_repo.py index 3cf49d8f..042f57a5 100644 --- a/tests/discstore/domain/use_cases/mock_repo.py +++ b/tests/jukebox/domain/use_cases/library/mock_repo.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc, Library -from discstore.domain.repositories import LibraryRepository +from jukebox.domain.entities import Disc, Library +from jukebox.domain.repositories import LibraryRepository class MockRepo(LibraryRepository): diff --git a/tests/discstore/domain/use_cases/test_add_disc.py b/tests/jukebox/domain/use_cases/library/test_add_disc.py similarity index 85% rename from tests/discstore/domain/use_cases/test_add_disc.py rename to tests/jukebox/domain/use_cases/library/test_add_disc.py index 2aeba4fd..ec0bb77e 100644 --- a/tests/discstore/domain/use_cases/test_add_disc.py +++ b/tests/jukebox/domain/use_cases/library/test_add_disc.py @@ -1,8 +1,8 @@ import pytest -from discstore.domain.entities import Disc, DiscMetadata, Library -from discstore.domain.use_cases.add_disc import AddDisc -from tests.discstore.domain.use_cases.mock_repo import MockRepo +from jukebox.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.use_cases.library.add_disc import AddDisc +from tests.jukebox.domain.use_cases.library.mock_repo import MockRepo @pytest.fixture diff --git a/tests/discstore/domain/use_cases/test_edit_disc.py b/tests/jukebox/domain/use_cases/library/test_edit_disc.py similarity index 98% rename from tests/discstore/domain/use_cases/test_edit_disc.py rename to tests/jukebox/domain/use_cases/library/test_edit_disc.py index e987264b..cb0e58c4 100644 --- a/tests/discstore/domain/use_cases/test_edit_disc.py +++ b/tests/jukebox/domain/use_cases/library/test_edit_disc.py @@ -1,7 +1,7 @@ import pytest -from discstore.domain.entities import Disc, DiscMetadata, DiscOption, Library -from discstore.domain.use_cases.edit_disc import EditDisc +from jukebox.domain.entities import Disc, DiscMetadata, DiscOption, Library +from jukebox.domain.use_cases.library.edit_disc import EditDisc from .mock_repo import MockRepo diff --git a/tests/discstore/domain/use_cases/test_get_current_tag_status.py b/tests/jukebox/domain/use_cases/library/test_get_current_tag_status.py similarity index 90% rename from tests/discstore/domain/use_cases/test_get_current_tag_status.py rename to tests/jukebox/domain/use_cases/library/test_get_current_tag_status.py index 05ff432a..89512980 100644 --- a/tests/discstore/domain/use_cases/test_get_current_tag_status.py +++ b/tests/jukebox/domain/use_cases/library/test_get_current_tag_status.py @@ -1,7 +1,7 @@ from unittest.mock import MagicMock -from discstore.domain.entities import CurrentTagStatus -from discstore.domain.use_cases.get_current_tag_status import GetCurrentTagStatus +from jukebox.domain.entities import CurrentTagStatus +from jukebox.domain.use_cases.library.get_current_tag_status import GetCurrentTagStatus def test_get_current_tag_status_returns_none_without_current_tag(): diff --git a/tests/discstore/domain/use_cases/test_get_disc.py b/tests/jukebox/domain/use_cases/library/test_get_disc.py similarity index 77% rename from tests/discstore/domain/use_cases/test_get_disc.py rename to tests/jukebox/domain/use_cases/library/test_get_disc.py index 4ddef676..ea2b9671 100644 --- a/tests/discstore/domain/use_cases/test_get_disc.py +++ b/tests/jukebox/domain/use_cases/library/test_get_disc.py @@ -1,8 +1,8 @@ import pytest -from discstore.domain.entities import Disc, DiscMetadata, Library -from discstore.domain.use_cases.get_disc import GetDisc -from tests.discstore.domain.use_cases.mock_repo import MockRepo +from jukebox.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.use_cases.library.get_disc import GetDisc +from tests.jukebox.domain.use_cases.library.mock_repo import MockRepo def test_get_existing_disc(): diff --git a/tests/discstore/domain/use_cases/test_list_discs.py b/tests/jukebox/domain/use_cases/library/test_list_discs.py similarity index 64% rename from tests/discstore/domain/use_cases/test_list_discs.py rename to tests/jukebox/domain/use_cases/library/test_list_discs.py index d87c817c..c8411e74 100644 --- a/tests/discstore/domain/use_cases/test_list_discs.py +++ b/tests/jukebox/domain/use_cases/library/test_list_discs.py @@ -1,6 +1,6 @@ -from discstore.domain.entities import Disc, DiscMetadata, Library -from discstore.domain.use_cases.list_discs import ListDiscs -from tests.discstore.domain.use_cases.mock_repo import MockRepo +from jukebox.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.use_cases.library.list_discs import ListDiscs +from tests.jukebox.domain.use_cases.library.mock_repo import MockRepo def test_list_discs_returns_all_discs(): diff --git a/tests/discstore/domain/use_cases/test_remove_disc.py b/tests/jukebox/domain/use_cases/library/test_remove_disc.py similarity index 76% rename from tests/discstore/domain/use_cases/test_remove_disc.py rename to tests/jukebox/domain/use_cases/library/test_remove_disc.py index 8094dcf6..2da22c00 100644 --- a/tests/discstore/domain/use_cases/test_remove_disc.py +++ b/tests/jukebox/domain/use_cases/library/test_remove_disc.py @@ -1,8 +1,8 @@ import pytest -from discstore.domain.entities import Disc, DiscMetadata, Library -from discstore.domain.use_cases.remove_disc import RemoveDisc -from tests.discstore.domain.use_cases.mock_repo import MockRepo +from jukebox.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.use_cases.library.remove_disc import RemoveDisc +from tests.jukebox.domain.use_cases.library.mock_repo import MockRepo @pytest.fixture diff --git a/tests/discstore/domain/use_cases/test_resolve_tag_id.py b/tests/jukebox/domain/use_cases/library/test_resolve_tag_id.py similarity index 92% rename from tests/discstore/domain/use_cases/test_resolve_tag_id.py rename to tests/jukebox/domain/use_cases/library/test_resolve_tag_id.py index 30b56eb3..79a5a0a1 100644 --- a/tests/discstore/domain/use_cases/test_resolve_tag_id.py +++ b/tests/jukebox/domain/use_cases/library/test_resolve_tag_id.py @@ -2,8 +2,8 @@ import pytest -from discstore.domain.entities import CurrentTagStatus -from discstore.domain.use_cases.resolve_tag_id import ResolveTagId +from jukebox.domain.entities import CurrentTagStatus +from jukebox.domain.use_cases.library.resolve_tag_id import ResolveTagId def test_resolve_tag_id_returns_explicit_tag_without_loading_current_tag_status(): diff --git a/tests/discstore/domain/use_cases/test_search_discs.py b/tests/jukebox/domain/use_cases/library/test_search_discs.py similarity index 96% rename from tests/discstore/domain/use_cases/test_search_discs.py rename to tests/jukebox/domain/use_cases/library/test_search_discs.py index a37f8e50..696ab9e7 100644 --- a/tests/discstore/domain/use_cases/test_search_discs.py +++ b/tests/jukebox/domain/use_cases/library/test_search_discs.py @@ -1,5 +1,5 @@ -from discstore.domain.entities import Disc, DiscMetadata, Library -from discstore.domain.use_cases.search_discs import SearchDiscs +from jukebox.domain.entities import Disc, DiscMetadata, Library +from jukebox.domain.use_cases.library.search_discs import SearchDiscs from .mock_repo import MockRepo