/
/
/
1"""
2NicovideoMusicProviderCoreMixin: Core functionality not belonging to specific domains.
3
4This mixin handles core functionality that doesn't belong to any specific feature area:
5- Instance management (adapter, config)
6- Authentication and session management
7- Provider lifecycle management (initialization/cleanup)
8- Basic provider properties
9"""
10
11from __future__ import annotations
12
13from typing import Any, override
14
15from music_assistant_models.enums import MediaType
16from music_assistant_models.errors import LoginFailed
17
18from music_assistant.providers.nicovideo.config import NicovideoConfig
19from music_assistant.providers.nicovideo.provider_mixins.base import (
20 NicovideoMusicProviderMixinBase,
21)
22from music_assistant.providers.nicovideo.services.manager import NicovideoServiceManager
23
24
25class NicovideoMusicProviderCoreMixin(NicovideoMusicProviderMixinBase):
26 """Core mixin handling instance management and provider lifecycle."""
27
28 def __init__(self, *args: Any, **kwargs: Any) -> None:
29 """Initialize the core mixin."""
30 super().__init__(*args, **kwargs)
31 self._nicovideo_config = NicovideoConfig(self)
32 self._service_manager = NicovideoServiceManager(self, self.nicovideo_config)
33
34 @property
35 @override
36 def nicovideo_config(self) -> NicovideoConfig:
37 """Get the config helper instance."""
38 return self._nicovideo_config
39
40 @property
41 @override
42 def service_manager(self) -> NicovideoServiceManager:
43 """Get the nicovideo service manager instance."""
44 return self._service_manager
45
46 @property
47 @override
48 def is_streaming_provider(self) -> bool:
49 """Return True if the provider is a streaming provider."""
50 # For streaming providers return True here but for local file based providers return False.
51 return True
52
53 @property
54 @override
55 def supported_media_types(self) -> set[MediaType]:
56 """Return the media types this provider can serve."""
57 # tracks and albums are served through search, but cannot be listed as library items
58 return {MediaType.ARTIST, MediaType.ALBUM, MediaType.TRACK, MediaType.PLAYLIST}
59
60 @override
61 async def handle_async_init_for_mixin(self) -> None:
62 """Handle async initialization of the provider."""
63 try:
64 # Check if login credentials are provided
65 has_credentials = bool(
66 self.nicovideo_config.auth.user_session
67 or (self.nicovideo_config.auth.mail and self.nicovideo_config.auth.password)
68 )
69
70 if has_credentials:
71 # Try login if credentials are provided
72 login_success = await self.service_manager.auth.try_login()
73 if not login_success:
74 raise LoginFailed("Login failed with provided credentials")
75 self.service_manager.auth.start_periodic_relogin_task()
76 self.logger.debug("nicovideo provider initialized successfully with login")
77 else:
78 # No credentials provided - initialize without login
79 self.logger.debug("nicovideo provider initialized successfully without login")
80 except Exception as err:
81 self.logger.error("Failed to initialize nicovideo provider: %s", err)
82 raise
83
84 @override
85 async def unload_for_mixin(self, is_removed: bool = False) -> None:
86 """Handle unload/close of the provider."""
87 try:
88 # Stop the periodic relogin task
89 self.service_manager.auth.stop_periodic_relogin_task()
90 self.logger.debug("nicovideo provider unloaded successfully")
91 except Exception as err:
92 self.logger.warning("Error during nicovideo provider unload: %s", err)
93