From 7d9800806a75de77e185d8e75a765f9a6378dc02 Mon Sep 17 00:00:00 2001 From: Wizzard <25581244+Wizzard@users.noreply.toomuchslop.com> Date: Mon, 16 Oct 2023 16:32:57 -0400 Subject: [PATCH] First commit --- config.example.json | 4 ++ deps.sh | 1 + main.js | 130 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 9 +++ 4 files changed, 144 insertions(+) create mode 100644 config.example.json create mode 100755 deps.sh create mode 100644 main.js create mode 100644 package.json diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..a986e4b --- /dev/null +++ b/config.example.json @@ -0,0 +1,4 @@ +{ + "apiKey": "YOUR_LASTFM_API_KEY", + "username": "YOUR_LASTFM_USERNAME" +} diff --git a/deps.sh b/deps.sh new file mode 100755 index 0000000..697b65a --- /dev/null +++ b/deps.sh @@ -0,0 +1 @@ +npm install axios sharp get-image-colors diff --git a/main.js b/main.js new file mode 100644 index 0000000..c664207 --- /dev/null +++ b/main.js @@ -0,0 +1,130 @@ +const axios = require('axios'); +const sharp = require('sharp'); +const getColors = require('get-image-colors'); +const rp = require("request-promise"); +const fs = require('fs'); +const { exec } = require('child_process'); + +const config = JSON.parse(fs.readFileSync("config.json")); +const updateInterval = 5000; + +async function processAlbumCover(url) { + try { + console.log(`Processing album cover from URL: ${url}`); + + const response = await axios.get(url, { responseType: 'arraybuffer' }); + const imageBuffer = Buffer.from(response.data, 'binary'); + + const imageSharp = sharp(imageBuffer); + const metadata = await imageSharp.metadata(); + + if (metadata.format !== 'jpeg' && metadata.format !== 'jpg') { + throw new Error('Not a JPEG image'); + } + + const dominantColor = await getDominantColor(imageBuffer); + + const resizedBuffer = await imageSharp + .resize({ width: 1920, height: 1080, fit: 'inside' }) + .toBuffer(); + + const resizedMetadata = await sharp(resizedBuffer).metadata(); + + const extendByX = Math.round((1920 - resizedMetadata.width) / 2); + const extendByY = Math.round((1080 - resizedMetadata.height) / 2); + + const outputBuffer = await sharp(resizedBuffer) + .extend({ + top: extendByY, + bottom: extendByY, + left: extendByX, + right: extendByX, + background: dominantColor + }) + .toBuffer(); + + return outputBuffer; + + } catch (error) { + console.error(`Error processing album cover from URL: ${url}`, error); + } +} + +async function getDominantColor(imageBuffer) { + const imageSharp = sharp(imageBuffer); + const { channels } = await imageSharp.stats(); + + const redAvg = channels[0].mean; + const greenAvg = channels[1].mean; + const blueAvg = channels[2].mean; + + return { + r: Math.round(redAvg), + g: Math.round(greenAvg), + b: Math.round(blueAvg) + }; +} + +async function setAsWallpaper(buffer) { + try { + await fs.promises.writeFile('current_album_cover.png', buffer); + exec('feh --bg-center current_album_cover.png'); + console.log("Wallpaper set using feh."); + } catch (error) { + console.error("Error setting wallpaper:", error); + } +} + +async function fetchCurrentScrobble(user) { + let lastTrackName; + let lastArtist; + try { + const optionsGetTrack = { + uri: `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${config.apiKey}&format=json&limit=1`, + json: true + }; + + const lastTrack = await rp(optionsGetTrack); + + if (!lastTrack.recenttracks || !lastTrack.recenttracks.track || !lastTrack.recenttracks.track[0]) { + console.error("No valid track data in recenttracks"); + return null; + } + + lastArtist = lastTrack.recenttracks.track[0].artist["#text"]; + lastTrackName = lastTrack.recenttracks.track[0].name; + + const images = lastTrack.recenttracks.track[0].image; + + let coverURL = null; + for (const img of images) { + if (img.size === 'extralarge' || img.size === 'mega') { + coverURL = img["#text"].trim(); + break; + } + } + + if (coverURL) { + coverURL = coverURL.replace('300x300', '1000x1000'); + } + + if (coverURL) { + const processedCover = await processAlbumCover(coverURL); + await setAsWallpaper(processedCover); + console.log("Wallpaper updated to album cover of: " + lastTrackName); + } else { + console.error(`Cover URL not found for track: ${lastTrackName}`); + } + } catch (error) { + console.error(`Failed to fetch current scrobble`, error); + } +} + +function startFetching() { + setInterval(async () => { + await fetchCurrentScrobble(config.username); + }, updateInterval); +} + +startFetching(); + diff --git a/package.json b/package.json new file mode 100644 index 0000000..adaee65 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "axios": "^1.5.1", + "file-type": "^18.5.0", + "get-image-colors": "^4.0.1", + "request-promise": "^4.2.6", + "sharp": "^0.32.6" + } +}