feat: add playlist models
This commit is contained in:
parent
33a728f8ec
commit
b719fa461c
|
|
@ -2,6 +2,8 @@ import pydantic
|
||||||
from pydantic import ConfigDict
|
from pydantic import ConfigDict
|
||||||
|
|
||||||
from .events import *
|
from .events import *
|
||||||
|
from .music import *
|
||||||
|
from .payloads import *
|
||||||
from .version import *
|
from .version import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from discord.ext.commands import Context
|
||||||
|
from discord.user import _UserTag
|
||||||
|
from pydantic import Field
|
||||||
|
from pydantic import model_validator
|
||||||
|
|
||||||
|
from pomice.enums import PlaylistType
|
||||||
|
from pomice.enums import SearchType
|
||||||
|
from pomice.enums import TrackType
|
||||||
|
from pomice.filters import Filter
|
||||||
|
from pomice.models import BaseModel
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
"Track",
|
||||||
|
"TrackInfo",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TrackInfo(BaseModel):
|
||||||
|
identifier: str
|
||||||
|
title: str
|
||||||
|
author: str
|
||||||
|
length: int
|
||||||
|
position: int = 0
|
||||||
|
is_stream: bool = Field(default=False, alias="isStream")
|
||||||
|
is_seekable: bool = Field(default=False, alias="isSeekable")
|
||||||
|
uri: Optional[str] = None
|
||||||
|
isrc: Optional[str] = None
|
||||||
|
source_name: Optional[str] = Field(default=None, alias="sourceName")
|
||||||
|
artwork_url: Optional[str] = Field(default=None, alias="artworkUrl")
|
||||||
|
|
||||||
|
|
||||||
|
class Track(BaseModel):
|
||||||
|
"""The base track object. Returns critical track information needed for parsing by Lavalink.
|
||||||
|
You can also pass in commands.Context to get a discord.py Context object in your track.
|
||||||
|
"""
|
||||||
|
|
||||||
|
track_id: str = Field(alias="encoded")
|
||||||
|
track_type: TrackType
|
||||||
|
info: TrackInfo
|
||||||
|
search_type: SearchType = SearchType.YTSEARCH
|
||||||
|
filters: List[Filter] = Field(default_factory=list)
|
||||||
|
timestamp: Optional[float] = None
|
||||||
|
original: Optional[Track] = None
|
||||||
|
ctx: Optional[Context] = None
|
||||||
|
requester: Optional[_UserTag] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def title(self) -> str:
|
||||||
|
return self.info.title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def author(self) -> str:
|
||||||
|
return self.info.author
|
||||||
|
|
||||||
|
@property
|
||||||
|
def uri(self) -> Optional[str]:
|
||||||
|
return self.info.uri
|
||||||
|
|
||||||
|
@property
|
||||||
|
def identifier(self) -> str:
|
||||||
|
return self.info.identifier
|
||||||
|
|
||||||
|
@property
|
||||||
|
def isrc(self) -> Optional[str]:
|
||||||
|
return self.info.isrc
|
||||||
|
|
||||||
|
@property
|
||||||
|
def thumbnail(self) -> Optional[str]:
|
||||||
|
return self.info.artwork_url
|
||||||
|
|
||||||
|
def __eq__(self, other: object) -> bool:
|
||||||
|
if not isinstance(other, Track):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self.track_id == other.track_id
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.info.title
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Pomice.Track title={self.info.title!r} uri=<{self.info.uri!r}> length={self.info.length}>"
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def _set_thumbnail_url(self) -> Track:
|
||||||
|
if self.track_type is TrackType.YOUTUBE and not self.info.artwork_url:
|
||||||
|
self.info.artwork_url = (
|
||||||
|
f"https://img.youtube.com/vi/{self.info.identifier}/mqdefault.jpg"
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class PlaylistInfo(BaseModel):
|
||||||
|
name: str
|
||||||
|
selected_track: int = Field(default=0, alias="selectedTrack")
|
||||||
|
|
||||||
|
|
||||||
|
class Playlist(BaseModel):
|
||||||
|
"""The base playlist object.
|
||||||
|
Returns critical playlist information needed for parsing by Lavalink.
|
||||||
|
"""
|
||||||
|
|
||||||
|
info: PlaylistInfo
|
||||||
|
tracks: List[Track]
|
||||||
|
playlist_type: PlaylistType
|
||||||
|
uri: str
|
||||||
|
artwork_url: Optional[str] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return self.info.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def thumbnail(self) -> Optional[str]:
|
||||||
|
return self.artwork_url
|
||||||
|
|
||||||
|
@property
|
||||||
|
def selected_track(self) -> Optional[Track]:
|
||||||
|
if self.track_count <= 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.tracks[self.info.selected_track]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def track_count(self) -> int:
|
||||||
|
return len(self.tracks)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.info.name
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Pomice.Playlist name={self.info.name!r} total_tracks={self.track_count}>"
|
||||||
|
|
@ -8,7 +8,13 @@ from pomice.models import LavalinkVersion
|
||||||
from pomice.models import LavalinkVersion3Type
|
from pomice.models import LavalinkVersion3Type
|
||||||
from pomice.models import LavalinkVersion4Type
|
from pomice.models import LavalinkVersion4Type
|
||||||
|
|
||||||
__all__ = ("ResumePayload", "ResumePayloadV3", "ResumePayloadV4")
|
__all__ = (
|
||||||
|
"ResumePayload",
|
||||||
|
"ResumePayloadV3",
|
||||||
|
"ResumePayloadV4",
|
||||||
|
"ResumePayloadType",
|
||||||
|
"ResumePayloadTypeAdapter",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ResumePayload(BaseModel):
|
class ResumePayload(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
"""Spotify module for Pomice, made possible by cloudwithax 2023"""
|
"""Spotify module for Pomice, made possible by cloudwithax 2023"""
|
||||||
from .client import Client
|
from .client import *
|
||||||
from .exceptions import *
|
from .exceptions import *
|
||||||
|
from .models import *
|
||||||
from .objects import *
|
from .objects import *
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
from typing import Dict
|
||||||
|
from typing import List
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from discord.ext.commands import Context
|
||||||
|
from discord.user import _UserTag
|
||||||
|
from pydantic import Field
|
||||||
|
|
||||||
|
from pomice.enums import SearchType
|
||||||
|
from pomice.enums import TrackType
|
||||||
|
from pomice.filters import Filter
|
||||||
|
from pomice.models import BaseModel
|
||||||
|
from pomice.models.music import Track
|
||||||
|
from pomice.models.music import TrackInfo
|
||||||
|
|
||||||
|
|
||||||
|
class SpotifyTrackRaw(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
artists: List[Dict[str, str]]
|
||||||
|
duration_ms: float
|
||||||
|
external_ids: Dict[str, str] = Field(default_factory=dict)
|
||||||
|
external_urls: Dict[str, str] = Field(default_factory=dict)
|
||||||
|
album: Dict[str, List[Dict[str, str]]] = Field(default_factory=dict)
|
||||||
|
|
||||||
|
def build_track(
|
||||||
|
self,
|
||||||
|
image: Optional[str] = None,
|
||||||
|
filters: Optional[List[Filter]] = None,
|
||||||
|
ctx: Optional[Context] = None,
|
||||||
|
requester: Optional[_UserTag] = None,
|
||||||
|
) -> Track:
|
||||||
|
if self.album:
|
||||||
|
image = self.album["images"][0]["url"]
|
||||||
|
|
||||||
|
return Track(
|
||||||
|
track_id=self.id,
|
||||||
|
track_type=TrackType.SPOTIFY,
|
||||||
|
search_type=SearchType.YTMSEARCH,
|
||||||
|
filters=filters,
|
||||||
|
ctx=ctx,
|
||||||
|
requester=requester,
|
||||||
|
info=TrackInfo(
|
||||||
|
identifier=self.id,
|
||||||
|
title=self.name,
|
||||||
|
author=", ".join(artist["name"] for artist in self.artists),
|
||||||
|
length=self.duration_ms,
|
||||||
|
is_seekable=True,
|
||||||
|
uri=self.external_urls.get("spotify", ""),
|
||||||
|
artwork_url=image,
|
||||||
|
isrc=self.external_ids.get("isrc"),
|
||||||
|
),
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue