Enforce session-type constraints for media formats

This commit is contained in:
Rafael Moraes
2026-03-26 14:16:00 -03:00
parent 1e438c9008
commit d9b66fa941
3 changed files with 72 additions and 17 deletions
+39 -16
View File
@@ -1,11 +1,15 @@
import asyncio
import logging
from pywidevine.license_protocol_pb2 import WidevinePsshData
from ..api.enums import SessionType
from .base import SpotifyBaseInterface
from .enums import AudioQuality
import asyncio
from .exceptions import VotifyMediaFormatNotAvailableException
from .exceptions import (
VotifyMediaFormatNotAvailableException,
VotifyMediaFormatNotAvailableForSessionTypeException,
)
from .types import DecryptionKey, StreamInfo, StreamInfoAv
logger = logging.getLogger(__name__)
@@ -48,18 +52,31 @@ class SpotifyAudioInterface(SpotifyBaseInterface):
) -> StreamInfoAv:
for audio_quality in self.audio_quality_priority:
if audio_quality.mp4:
stream_info = await self._get_stream_info_web(
media_id=media_id,
media_type=media_type,
skip_pssh=skip_pssh,
audio_quality=audio_quality,
)
else:
stream_info = await self._get_stream_info_librespot(
media_id=media_id,
media_type=media_type,
audio_quality=audio_quality,
)
if self.api.session_type in {SessionType.LIBRESPOT, SessionType.WEB}:
stream_info = await self._get_stream_info_web(
media_id=media_id,
media_type=media_type,
skip_pssh=skip_pssh,
audio_quality=audio_quality,
)
else:
raise VotifyMediaFormatNotAvailableForSessionTypeException(
media_id=media_id,
session_type=self.api.session_type,
)
elif audio_quality.ogg:
if self.api.session_type == SessionType.LIBRESPOT:
stream_info = await self._get_stream_info_librespot(
media_id=media_id,
media_type=media_type,
audio_quality=audio_quality,
)
else:
raise VotifyMediaFormatNotAvailableForSessionTypeException(
media_id=media_id,
session_type=self.api.session_type,
)
if stream_info:
return stream_info
@@ -201,11 +218,17 @@ class SpotifyAudioInterface(SpotifyBaseInterface):
stream_info: StreamInfoAv,
media_id: str,
):
if stream_info.audio_track.widevine_pssh:
if (
self.api.session_type in {SessionType.LIBRESPOT, SessionType.WEB}
and stream_info.audio_track.widevine_pssh
):
return await self.get_widevine_decryption_key(
stream_info.audio_track.widevine_pssh
)
elif stream_info.audio_track.file_id:
elif (
stream_info.audio_track.file_id
and self.api.session_type == SessionType.LIBRESPOT
):
return await self.get_librespot_decryption_key(
media_id=media_id,
file_id=stream_info.audio_track.file_id,
+21
View File
@@ -1,5 +1,6 @@
from typing import Any
from ..api.enums import SessionType
from ..utils import VotiyException
@@ -79,3 +80,23 @@ class VotifyMediaFormatNotAvailableException(VotifyMediaException):
media_id=media_id,
media_metadata=media_metadata,
)
class VotifyMediaFormatNotAvailableForSessionTypeException(
VotifyMediaFormatNotAvailableException
):
def __init__(
self,
media_id: str,
media_metadata: dict | None = None,
session_type: SessionType | None = None,
):
message = "Selected format is not available for session type"
if session_type:
message += f": {session_type.value}"
super().__init__(
media_id=media_id,
media_metadata=media_metadata,
message=message,
)
+12 -1
View File
@@ -3,9 +3,11 @@ import logging
from InquirerPy import inquirer
from InquirerPy.base.control import Choice
from ..api.enums import SessionType
from .base import SpotifyBaseInterface
from .constants import COVER_SIZE_ID_MAP_VIDEO
from .enums import VideoFormat, VideoResolution
from .exceptions import VotifyMediaFormatNotAvailableForSessionTypeException
from .types import DecryptionKey, StreamInfo, StreamInfoAv
logger = logging.getLogger(__name__)
@@ -191,7 +193,16 @@ class SpotifyVideoInterface(SpotifyBaseInterface):
media_id: str,
media_type: str,
playback_info: dict | None = None,
) -> StreamInfoAv | None:
) -> StreamInfoAv:
if (
not self.api.session_type in {SessionType.LIBRESPOT, SessionType.WEB}
and media_type != "episode"
):
raise VotifyMediaFormatNotAvailableForSessionTypeException(
media_id=media_id,
session_type=self.api.session_type,
)
if not playback_info:
playback_info = await self._get_playback_info(
media_id=media_id,