Skip to content

Commit

Permalink
Add preliminary fm server functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
joinemm committed Oct 14, 2023
1 parent 8768ec9 commit e007278
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 14 deletions.
105 changes: 93 additions & 12 deletions cogs/fm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import urllib.parse
from dataclasses import dataclass
from enum import Enum, auto
from typing import TYPE_CHECKING, Annotated, Callable, Literal, Optional, Union
from typing import TYPE_CHECKING, Annotated, Any, Callable, Literal, Optional, Union

import arrow
import discord
Expand Down Expand Up @@ -179,11 +179,11 @@ def parse(self, argument: str):
class LastFm(commands.Cog):
"""LastFM commands"""

ICON = "🎵"
LASTFM_RED = "e31c23"
LASTFM_ICON_URL = "https://i.imgur.com/dMeDkPH.jpg"

def __init__(self, bot):
self.icon = "🎵"
self.bot: MisoBot = bot
self.api = LastFmApi(bot)

Expand Down Expand Up @@ -654,7 +654,10 @@ async def artist_overview(self, ctx: MisoContext, timeframe: Period, artist: str
soup = await self.api.scrape_page(url, authenticated=True)

try:
albumsdiv, tracksdiv = soup.select(".chartlist", limit=2)
chartlists = soup.select(".chartlist")
# there are "ghost" chartlists that mess up web scraping
albumsdiv = chartlists[1]
tracksdiv = chartlists[3]
except ValueError:
return raise_no_artist_plays(artist, timeframe)

Expand All @@ -674,7 +677,7 @@ async def artist_overview(self, ctx: MisoContext, timeframe: Period, artist: str

username = util.displayname(ctx.lfm.target_user, escape=False)
content.set_author(
name=f"{username} {formatted_name} — "
name=f"{username} | {formatted_name} — "
+ (
f"{timeframe.display().capitalize()} overview"
if timeframe != timeframe.OVERALL
Expand Down Expand Up @@ -750,13 +753,12 @@ def filter_artist(ta_data: dict):
inline=render_inline,
)

content.description = (
artistinfo["bio"]["summary"]
.split("<a href")[0]
.strip()
.replace("\n\n\n", "\n\n")
+ f" [read more]({artistinfo['url']})"
)
artist_bio = artistinfo["bio"]["summary"].split("<a href")[0].strip()
if artist_bio:
content.description = (
artist_bio.replace("\n\n\n", "\n\n")
+ f" [read more]({artistinfo['url']})"
)

content.set_footer(
text=", ".join([x["name"] for x in artistinfo["tags"]["tag"]])
Expand Down Expand Up @@ -1015,7 +1017,7 @@ async def chart(
)

username = util.displayname(ctx.lfm.target_user)
caption = f"**{username} {timeframe.display()} {size} {chart_title} collage**"
caption = f"**{username} | {timeframe.display()} {size} {chart_title} collage**"
filename = (
f"miso_collage_{ctx.lfm.username}_"
f"{timeframe}_{arrow.now().int_timestamp}.jpg"
Expand Down Expand Up @@ -1122,6 +1124,80 @@ async def server_lastfm_usernames(

return data

async def task_for_each_server_member(
self, guild: discord.Guild, task: asyncio.Future, *args, **kwargs
):
tasks = []
for user_id, lastfm_username in await self.server_lastfm_usernames(guild):
member = guild.get_member(user_id)
if member is None:
continue

tasks.append(
task_wrapper(
task(lastfm_username, *args, **kwargs),
member,
)
)

if not tasks:
return None

return await asyncio.gather(*tasks)

@fm.group(aliases=["s"])
@commands.guild_only()
@is_small_server()
@commands.cooldown(2, 60, type=commands.BucketType.user)
async def server(
self,
ctx: MisoContext,
):
await util.command_group_help(ctx)

@server.command(name="nowplaying", aliases=["np"])
async def server_nowplaying(self, ctx: MisoContext):
"""What this server is currently listening to"""
data = await self.task_for_each_server_member(
ctx.guild, self.api.user_get_now_playing
)

if data is None:
return await ctx.send(
"Nobody on this server has connected their Last.fm account yet!"
)

rows = []
for member_data, member in data:
if not member_data["nowplaying"]:
continue

artist_name = member_data["artist"]["#text"]
track_name = member_data["name"]

rows.append(
f"{util.displayname(member)} | **{escape_markdown(artist_name)}** "
f"— ***{escape_markdown(track_name)}***"
)

if not rows:
return await ctx.send(
"Nobody on this server is listening to anything at the moment!"
)

content = (
discord.Embed(color=int(self.LASTFM_RED, 16))
.set_author(
name=f"What is {ctx.guild.name} listening to?",
icon_url=ctx.guild.icon,
)
.set_footer(
text=f"{len(rows)} / {len(data)} Members are listening to music"
)
)

await RowPaginator(content, rows).run(ctx)

async def user_ranking(
self, ctx: MisoContext, playcount_fn: Callable, ranking_of: str
):
Expand Down Expand Up @@ -1524,3 +1600,8 @@ def raise_no_artist_plays(artist: str, timeframe: Period):
if timeframe == Period.OVERALL
else f"You have not listened to **{artist_escaped}** in the past {timeframe}!"
)


async def task_wrapper(task: asyncio.Future, ref: Any):
result = await task
return result, ref
3 changes: 3 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ def main():
extensions=extensions + ([] if developer_mode else infrastructure_extensions),
default_prefix=prefix,
)
if developer_mode:
bot.debug = True

bot.run(TOKEN, log_handler=None)


Expand Down
3 changes: 2 additions & 1 deletion modules/lastfm.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ async def api_request(self, method: str, params: dict) -> dict:
"format": "json",
} | {k: v for k, v in params.items() if v is not None}

print(request_params)
if self.bot.debug:
logger.info(request_params)

async with self.bot.session.get(
self.API_BASE_URL, params=request_params
Expand Down
5 changes: 4 additions & 1 deletion modules/misobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def __init__(
self.db = maria.MariaDB()
self.cache = cache.Cache(self)
self.keychain = Keychain()
self.debug = False
self.version = "5.1"
self.extensions_loaded = False
self.redis: Redis = Redis()
Expand Down Expand Up @@ -191,7 +192,9 @@ async def cooldown_check(ctx: MisoContext):
bucket = ctx.bot.global_cd.get_bucket(ctx.message)
if bucket:
if retry_after := bucket.update_rate_limit():
raise commands.CommandOnCooldown(bucket, retry_after, commands.BucketType.member)
raise commands.CommandOnCooldown(
bucket, retry_after, commands.BucketType.member
)
return True

@property
Expand Down

0 comments on commit e007278

Please sign in to comment.