feat: add playlist models
This commit is contained in:
parent
33a728f8ec
commit
b719fa461c
|
|
@ -2,6 +2,8 @@ import pydantic
|
|||
from pydantic import ConfigDict
|
||||
|
||||
from .events import *
|
||||
from .music import *
|
||||
from .payloads 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 LavalinkVersion4Type
|
||||
|
||||
__all__ = ("ResumePayload", "ResumePayloadV3", "ResumePayloadV4")
|
||||
__all__ = (
|
||||
"ResumePayload",
|
||||
"ResumePayloadV3",
|
||||
"ResumePayloadV4",
|
||||
"ResumePayloadType",
|
||||
"ResumePayloadTypeAdapter",
|
||||
)
|
||||
|
||||
|
||||
class ResumePayload(BaseModel):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Spotify module for Pomice, made possible by cloudwithax 2023"""
|
||||
from .client import Client
|
||||
from .client import *
|
||||
from .exceptions import *
|
||||
from .models 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