From 3ee2a8020104b91c5bb40fc3c2ff24af3c39a5b6 Mon Sep 17 00:00:00 2001 From: SileNce5k <39550188+SileNce5k@users.noreply.github.com> Date: Sat, 6 Sep 2025 03:32:36 +0200 Subject: [PATCH] Set embed to the average color of the album cover on fm command (#168) And do not set a color in misc/fm.js when there already is one set. --- commands/misc/fm.js | 10 +++--- util/lastfm/getCurrentScrobble.js | 54 +++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/commands/misc/fm.js b/commands/misc/fm.js index 5aa6035..e259f4c 100644 --- a/commands/misc/fm.js +++ b/commands/misc/fm.js @@ -87,11 +87,13 @@ module.exports = { if(sendText.embed != null){ let parse = parseMention(message.author.id, message.guild) let user = message.guild.members.cache.get(parse); - let roleColor = 15788778; - if (user.roles.color) { - roleColor = user.roles.color.color; + if(!sendText.embed.data.color){ + let roleColor = 15788778; + if (user.roles.color) { + roleColor = user.roles.color.color; + } + sendText.embed.setColor(roleColor); } - sendText.embed.setColor(roleColor); message.channel.send({embeds :[sendText.embed]}) }else{ message.channel.send(sendText.text.replaceAll("", prefix)); diff --git a/util/lastfm/getCurrentScrobble.js b/util/lastfm/getCurrentScrobble.js index d1071ff..b503fbb 100644 --- a/util/lastfm/getCurrentScrobble.js +++ b/util/lastfm/getCurrentScrobble.js @@ -2,6 +2,11 @@ const getNickname = require("../getNickname"); const parseMention = require("../parseMention"); const getFmUsername = require("./getFmUsername"); const {EmbedBuilder} = require('discord.js'); +const path = require('path'); +const fs = require('fs'); +const { writeFile } = require('node:fs/promises') +const executeCommand = require('../executeCommand'); +const { Readable } = require('node:stream') require("dotenv").config(); module.exports = async function (userID, guild) { @@ -58,21 +63,56 @@ module.exports = async function (userID, guild) { sendText.text = tracks.errorMsg; return sendText; } + let coverDir = path.resolve(process.cwd(), 'data', 'covers'); + let color = "#C27D0E" + const directory = path.resolve(coverDir, Math.floor(new Date).toString()) + fs.mkdirSync(directory, {recursive: true}) + const coverFile = path.resolve(directory, "cover") + let downloadResult = await downloadImage(tracks[0].cover, coverFile); + if(downloadResult.value === ERROR_CODES.SUCCESS){ + const commandArgs = [`${coverFile}.${downloadResult.ext}`, "-resize", "1x1", "txt:-"] + let res = executeCommand("magick", commandArgs); + if(!res.error) color = res.output.split("\n")[1].split(" ")[3]; + + } const embed = new EmbedBuilder() - .setAuthor({name: `Now playing - ${nickname}`, iconURL: user.user.avatarURL({ dynamic: true, size: 4096 })}) - .setThumbnail(tracks[0].cover) - .setColor(15780145) - .addFields({ - name: `${isCurrentScrobble}:`, value: `${tracks[0].song}\n **${tracks[0].artist} • ** ${tracks[0].album}` - },) + .setAuthor({name: `Now playing - ${nickname}`, iconURL: user.user.avatarURL({ dynamic: true, size: 4096 })}) + .setThumbnail(tracks[0].cover) + .setColor(color) + .addFields({ + name: `${isCurrentScrobble}:`, value: `${tracks[0].song}\n **${tracks[0].artist} • ** ${tracks[0].album}` + },) if (isCurrentScrobble === "Current") { embed.addFields({ name: "Previous:", value: `${tracks[1].song}\n **${tracks[1].artist} • ** ${tracks[1].album}` },) } sendText.embed = embed; + fs.rmSync(`${directory}`, {recursive: true}) } else { sendText.text = "You haven't set your last.fm username yet. Use `fm set ` to set it."; } return sendText; -} \ No newline at end of file +} +const ERROR_CODES = { + SUCCESS: 0, + HTTP_ERROR: 1, + NOT_IMAGE: 2, + FETCH_ERROR: 3 +} +async function downloadImage(url, downloadPath) { + let res; + try { + res = await fetch(url); + } catch (error) { + return {value: ERROR_CODES.FETCH_ERROR, errorMessage: error.cause?.message || error.message}; + } + if(!res.ok) return {value: ERROR_CODES.HTTP_ERROR, errorMessage: res.status.toString()}; + const contentType = res.headers.get('content-type'); + + if(!contentType || !contentType.startsWith("image")) return {value: ERROR_CODES.NOT_IMAGE, errorMessage: contentType || "No content-type header"}; + const fileExt = contentType.split("/")[1] + const stream = Readable.fromWeb(res.body) + await writeFile(`${downloadPath}.${fileExt}`, stream); + return {value: ERROR_CODES.SUCCESS, errorMessage: "", ext: fileExt}; +}