Change bar colors with album cover in the most retarded way possible
This commit is contained in:
parent
79dcfa7b83
commit
62285d572b
2
deps.sh
2
deps.sh
|
@ -1 +1,3 @@
|
||||||
npm install axios sharp get-image-colors pm2
|
npm install axios sharp get-image-colors pm2
|
||||||
|
pip3 install libqtile --break-system-packages
|
||||||
|
pip3 install pyautogui --break-system-packages
|
||||||
|
|
86
main.js
86
main.js
|
@ -1,27 +1,22 @@
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
const getColors = require('get-image-colors');
|
const rp = require('request-promise');
|
||||||
const rp = require("request-promise");
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
const config = JSON.parse(fs.readFileSync("config.json"));
|
const config = JSON.parse(fs.readFileSync("config.json"));
|
||||||
const updateInterval = 5000;
|
const updateInterval = 5000;
|
||||||
|
|
||||||
async function processAlbumCover(url) {
|
async function processAlbumCover(url) {
|
||||||
try {
|
try {
|
||||||
console.log(`Processing album cover from URL: ${url}`);
|
console.log(`Processing album cover from URL: ${url}`);
|
||||||
|
|
||||||
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
||||||
const imageBuffer = Buffer.from(response.data, 'binary');
|
const imageBuffer = Buffer.from(response.data, 'binary');
|
||||||
|
|
||||||
const imageSharp = sharp(imageBuffer);
|
const imageSharp = sharp(imageBuffer);
|
||||||
const metadata = await imageSharp.metadata();
|
const metadata = await imageSharp.metadata();
|
||||||
|
|
||||||
if (metadata.format !== 'jpeg' && metadata.format !== 'jpg' && metadata.format !== 'png') {
|
|
||||||
throw new Error('Not a supported image format');
|
|
||||||
}
|
|
||||||
|
|
||||||
const dominantColor = await getDominantColor(imageBuffer);
|
const dominantColor = await getDominantColor(imageBuffer);
|
||||||
|
|
||||||
const resizedBuffer = await imageSharp
|
const resizedBuffer = await imageSharp
|
||||||
|
@ -29,7 +24,7 @@ async function processAlbumCover(url) {
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
const resizedMetadata = await sharp(resizedBuffer).metadata();
|
const resizedMetadata = await sharp(resizedBuffer).metadata();
|
||||||
|
|
||||||
const extendByX = Math.round((1920 - resizedMetadata.width) / 2);
|
const extendByX = Math.round((1920 - resizedMetadata.width) / 2);
|
||||||
const extendByY = Math.round((1080 - resizedMetadata.height) / 2);
|
const extendByY = Math.round((1080 - resizedMetadata.height) / 2);
|
||||||
|
|
||||||
|
@ -43,10 +38,12 @@ async function processAlbumCover(url) {
|
||||||
})
|
})
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
return outputBuffer;
|
console.log('Processed album cover successfully.');
|
||||||
|
return { outputBuffer, dominantColor };
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error processing album cover from URL: ${url}`, error);
|
console.error(`Failed to process album cover from URL: ${url}`, error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +55,7 @@ async function getDominantColor(imageBuffer) {
|
||||||
const greenAvg = channels[1].mean;
|
const greenAvg = channels[1].mean;
|
||||||
const blueAvg = channels[2].mean;
|
const blueAvg = channels[2].mean;
|
||||||
|
|
||||||
|
console.log(`Determined dominant color: r=${Math.round(redAvg)}, g=${Math.round(greenAvg)}, b=${Math.round(blueAvg)}`);
|
||||||
return {
|
return {
|
||||||
r: Math.round(redAvg),
|
r: Math.round(redAvg),
|
||||||
g: Math.round(greenAvg),
|
g: Math.round(greenAvg),
|
||||||
|
@ -65,34 +63,46 @@ async function getDominantColor(imageBuffer) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setAsWallpaper(buffer) {
|
async function setAsWallpaper(buffer, dominantColor) {
|
||||||
try {
|
try {
|
||||||
await fs.promises.writeFile('/tmp/current_album_cover.png', buffer);
|
await fs.promises.writeFile('/tmp/current_album_cover.png', buffer, 'binary');
|
||||||
exec('feh --bg-center /tmp/current_album_cover.png');
|
|
||||||
console.log("Wallpaper set using feh.");
|
const colorString = `#${dominantColor.r.toString(16).padStart(2, '0')}${dominantColor.g.toString(16).padStart(2, '0')}${dominantColor.b.toString(16).padStart(2, '0')}`;
|
||||||
|
|
||||||
|
console.log(`Sending color string to Python script: ${colorString}`);
|
||||||
|
|
||||||
|
const command = `python3 ./tap_in.py '${colorString}'`;
|
||||||
|
console.log("Running command:", command);
|
||||||
|
|
||||||
|
exec(command, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`Error running the command: ${error}`);
|
||||||
|
}
|
||||||
|
console.log(`Python stdout: ${stdout}`);
|
||||||
|
console.log(`Python stderr: ${stderr}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
exec('feh --bg-center /tmp/current_album_cover.png');
|
||||||
|
|
||||||
|
console.log('Wallpaper and Qtile colors successfully updated.');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error setting wallpaper:", error);
|
console.error("Failed to set wallpaper and update Qtile colors:", error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchCurrentScrobble(user) {
|
async function fetchCurrentScrobble(user) {
|
||||||
let lastTrackName;
|
|
||||||
let lastArtist;
|
|
||||||
try {
|
try {
|
||||||
|
console.log("Fetching current scrobble...");
|
||||||
|
|
||||||
const optionsGetTrack = {
|
const optionsGetTrack = {
|
||||||
uri: `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${config.apiKey}&format=json&limit=1`,
|
uri: `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${config.apiKey}&format=json&limit=1`,
|
||||||
json: true
|
json: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const lastTrack = await rp(optionsGetTrack);
|
const lastTrack = await rp(optionsGetTrack);
|
||||||
|
const lastArtist = lastTrack.recenttracks.track[0].artist["#text"];
|
||||||
if (!lastTrack.recenttracks || !lastTrack.recenttracks.track || !lastTrack.recenttracks.track[0]) {
|
const lastTrackName = lastTrack.recenttracks.track[0].name;
|
||||||
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;
|
const images = lastTrack.recenttracks.track[0].image;
|
||||||
|
|
||||||
|
@ -103,28 +113,32 @@ async function fetchCurrentScrobble(user) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverURL) {
|
|
||||||
coverURL = coverURL.replace('300x300', '1000x1000');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (coverURL) {
|
if (coverURL) {
|
||||||
const processedCover = await processAlbumCover(coverURL);
|
const { outputBuffer, dominantColor } = await processAlbumCover(coverURL);
|
||||||
await setAsWallpaper(processedCover);
|
await setAsWallpaper(outputBuffer, dominantColor);
|
||||||
console.log("Wallpaper updated to album cover of: " + lastTrackName);
|
console.log("Successfully fetched current scrobble.");
|
||||||
|
return { outputBuffer, dominantColor };
|
||||||
} else {
|
} else {
|
||||||
console.error(`Cover URL not found for track: ${lastTrackName}`);
|
console.error(`Cover URL not found for track: ${lastTrackName}`);
|
||||||
|
throw new Error('Cover URL not found');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to fetch current scrobble`, error);
|
console.error(`Failed to fetch current scrobble:`, error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startFetching() {
|
function startFetching() {
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
await fetchCurrentScrobble(config.username);
|
try {
|
||||||
|
console.log('Initiating fetch sequence.');
|
||||||
|
await fetchCurrentScrobble(config.username);
|
||||||
|
console.log('Fetch sequence completed.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed in startFetching:`, error);
|
||||||
|
}
|
||||||
}, updateInterval);
|
}, updateInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
startFetching();
|
startFetching();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"file-type": "^18.5.0",
|
"file-type": "^18.5.0",
|
||||||
"get-image-colors": "^4.0.1",
|
"get-image-colors": "^4.0.1",
|
||||||
|
"pm2": "^5.3.0",
|
||||||
"request-promise": "^4.2.6",
|
"request-promise": "^4.2.6",
|
||||||
"sharp": "^0.32.6"
|
"sharp": "^0.32.6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import pyautogui
|
||||||
|
|
||||||
|
print("Arguments received:", sys.argv)
|
||||||
|
|
||||||
|
def write_color_to_file(color):
|
||||||
|
with open("/tmp/bar_color.txt", "w") as f:
|
||||||
|
f.write(color)
|
||||||
|
print(f"Successfully wrote color {color} to /tmp/bar_color.txt")
|
||||||
|
|
||||||
|
def simulate_f7_keypress():
|
||||||
|
time.sleep(1) # Give a little time for the file to be written
|
||||||
|
pyautogui.press('f7')
|
||||||
|
print("Simulated F7 keypress")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python tap_in.py <color>")
|
||||||
|
else:
|
||||||
|
color = sys.argv[1]
|
||||||
|
write_color_to_file(color)
|
||||||
|
simulate_f7_keypress()
|
Loading…
Reference in New Issue