159 lines
6.3 KiB
Python
159 lines
6.3 KiB
Python
import asyncio
|
|
from typing import Optional
|
|
|
|
import discord
|
|
from redbot.core.utils.chat_formatting import escape
|
|
from redbot.core.utils.menus import DEFAULT_CONTROLS, menu
|
|
|
|
from .abc import MixinMeta
|
|
from .exceptions import *
|
|
from .fmmixin import FMMixin
|
|
|
|
command_fm = FMMixin.command_fm
|
|
command_fm_server = FMMixin.command_fm_server
|
|
|
|
|
|
class NowPlayingMixin(MixinMeta):
|
|
"""NowPlaying Commands"""
|
|
|
|
@command_fm.command(name="nowplaying", aliases=["np"])
|
|
async def command_nowplaying(self, ctx, user: Optional[discord.Member] = None):
|
|
"""Currently playing song or most recent song."""
|
|
user = user or ctx.author
|
|
async with ctx.typing():
|
|
conf = await self.config.user(user).all()
|
|
self.check_if_logged_in(conf, user == ctx.author)
|
|
data = await self.api_request(
|
|
ctx,
|
|
{
|
|
"user": conf["lastfm_username"],
|
|
"method": "user.getrecenttracks",
|
|
"limit": 1,
|
|
},
|
|
)
|
|
user_attr = data["recenttracks"]["@attr"]
|
|
tracks = data["recenttracks"]["track"]
|
|
|
|
if not tracks:
|
|
return await ctx.send("You have not listened to anything yet!")
|
|
try:
|
|
artist = tracks[0]["artist"]["#text"]
|
|
album = tracks[0]["album"]["#text"]
|
|
track = tracks[0]["name"]
|
|
image_url = tracks[0]["image"][-1]["#text"]
|
|
url = tracks[0]["url"]
|
|
except KeyError:
|
|
artist = tracks["artist"]["#text"]
|
|
album = tracks["album"]["#text"]
|
|
track = tracks["name"]
|
|
image_url = tracks["image"][-1]["#text"]
|
|
url = tracks["url"]
|
|
|
|
content = discord.Embed(color=await self.bot.get_embed_color(ctx.channel), url=url)
|
|
|
|
content.description = f"**{escape(album, formatting=True)}**" if album else ""
|
|
content.title = (
|
|
f"**{escape(artist, formatting=True)}** — ***{escape(track, formatting=True)} ***"
|
|
)
|
|
content.set_thumbnail(url=image_url)
|
|
|
|
# tags and playcount
|
|
trackdata = await self.api_request(
|
|
ctx,
|
|
{
|
|
"user": conf["lastfm_username"],
|
|
"method": "track.getInfo",
|
|
"artist": artist,
|
|
"track": track,
|
|
},
|
|
)
|
|
if trackdata is not None:
|
|
loved = trackdata["track"].get("userloved", "0") == "1"
|
|
if loved:
|
|
content.title += " :heart:"
|
|
tags = []
|
|
try:
|
|
trackdata = trackdata["track"]
|
|
playcount = int(trackdata["userplaycount"])
|
|
if playcount > 0:
|
|
content.description += f"\n> {playcount} {self.format_plays(playcount)}"
|
|
if isinstance(trackdata["toptags"], dict):
|
|
for tag in trackdata["toptags"]["tag"]:
|
|
if "name" in tag:
|
|
tags.append(tag["name"])
|
|
else:
|
|
tags.append(tag)
|
|
if tags:
|
|
content.set_footer(text=", ".join(tags))
|
|
except KeyError:
|
|
pass
|
|
|
|
# play state
|
|
state = "— Most recent track"
|
|
try:
|
|
if "@attr" in tracks[0]:
|
|
if "nowplaying" in tracks[0]["@attr"]:
|
|
state = "— Now Playing"
|
|
except KeyError:
|
|
if "@attr" in tracks:
|
|
if "nowplaying" in tracks["@attr"]:
|
|
state = "— Now Playing"
|
|
|
|
content.set_author(
|
|
name=f"{user_attr['user']} {state}",
|
|
icon_url=user.display_avatar.url,
|
|
)
|
|
if state == "— Most recent track":
|
|
msg = "You aren't currently listening to anything, here is the most recent song found."
|
|
else:
|
|
msg = None
|
|
await ctx.send(msg if msg is not None else None, embed=content)
|
|
|
|
@command_fm_server.command(name="nowplaying", aliases=["np"])
|
|
async def command_servernp(self, ctx):
|
|
"""What people on this server are listening to at the moment."""
|
|
listeners = []
|
|
tasks = []
|
|
async with ctx.typing():
|
|
userlist = await self.config.all_users()
|
|
guildusers = [x.id for x in ctx.guild.members]
|
|
userslist = [user for user in userlist if user in guildusers]
|
|
for user in userslist:
|
|
lastfm_username = userlist[user]["lastfm_username"]
|
|
if lastfm_username is None:
|
|
continue
|
|
member = ctx.guild.get_member(user)
|
|
if member is None:
|
|
continue
|
|
|
|
tasks.append(self.get_current_track(ctx, lastfm_username, member, True))
|
|
|
|
total_linked = len(tasks)
|
|
if tasks:
|
|
data = await asyncio.gather(*tasks)
|
|
data = [i for i in data if i]
|
|
for name, artist, album, image, ref in data:
|
|
if name is not None:
|
|
listeners.append((name, artist, ref))
|
|
else:
|
|
return await ctx.send("Nobody on this server has connected their last.fm account yet!")
|
|
|
|
if not listeners:
|
|
return await ctx.send("Nobody on this server is listening to anything at the moment!")
|
|
|
|
total_listening = len(listeners)
|
|
rows = []
|
|
for name, artist, member in listeners:
|
|
rows.append(f"{member.mention} **{artist}** — ***{name}***")
|
|
|
|
content = discord.Embed(color=await ctx.embed_color())
|
|
content.set_author(
|
|
name=f"What is {ctx.guild.name} listening to?",
|
|
icon_url=ctx.guild.icon.url if ctx.guild.icon else None,
|
|
)
|
|
content.set_footer(text=f"{total_listening} / {total_linked} Members")
|
|
pages = await self.create_pages(content, rows)
|
|
if len(pages) > 1:
|
|
await menu(ctx, pages, DEFAULT_CONTROLS)
|
|
else:
|
|
await ctx.send(embed=pages[0])
|