dotfiles/.config/waybar/scripts/roon_debug.js
2025-05-28 18:27:10 +02:00

120 lines
4.4 KiB
JavaScript

const { RoonExtension } = require('roon-kit');
const fs = require('fs');
const { exec } = require('child_process');
const lyricsScriptPath = "/home/teraflops/.config/waybar/scripts/get_lyrics.py";
function log(msg) {
const timestamp = new Date().toISOString();
const fullMsg = `[${timestamp}] ${msg}`;
console.log(fullMsg);
fs.appendFileSync('/tmp/roon_debug.log', fullMsg + '\n');
}
const extension = new RoonExtension({
description: {
extension_id: 'roon-kit-now-playing',
display_name: "Roon Kit Now Playing",
display_version: "0.2.0",
publisher: 'roon-kit',
email: 'stevenic@microsoft.com',
website: 'https://github.com/Stevenic/roon-kit'
},
RoonApiBrowse: 'not_required',
RoonApiImage: 'required',
RoonApiTransport: 'required',
subscribe_outputs: false,
subscribe_zones: true,
log_level: 'none'
});
function cleanTitle(title) {
return title.replace(/^[A-Za-z0-9]{1,3}\s+/, '').replace(/[$#@!%^&*(){}\[\]<>?/\\|`~]/g, '').trim();
}
function getLyrics(artist, title, callback) {
const cmd = `python3 ${lyricsScriptPath} "${artist}" "${title}"`;
log(`🎤 Ejecutando: ${cmd}`);
exec(cmd, (error, stdout, stderr) => {
if (error) {
log(`❌ Error en getLyrics: ${stderr}`);
callback("Letras no disponibles.");
} else {
const lyrics = stdout.trim();
log(`✅ Letras obtenidas (${lyrics.length} chars)`);
callback(lyrics || "Letras no encontradas.");
}
});
}
extension.on("subscribe_zones", async (core, response, body) => {
log("🔄 Evento subscribe_zones recibido");
log(JSON.stringify(body, null, 2));
const changedZones = body.zones_changed ?? [];
const addedZones = body.zones_added ?? [];
const removedZones = body.zones_removed ?? [];
if (removedZones.length > 0) {
log("🧹 Zona eliminada, limpiando /tmp/waybar_roon_info.json");
fs.writeFileSync('/tmp/waybar_roon_info.json', JSON.stringify({ text: '', tooltip: '' }));
exec("/usr/bin/pkill -RTMIN+3 waybar");
}
for (const zone of [...addedZones, ...changedZones]) {
log(`🎧 Zona: ${zone.display_name}, estado: ${zone.state}`);
if (zone.state === 'playing') {
const track = cleanTitle(zone.now_playing?.one_line?.line1 || '');
const artist = zone.now_playing?.one_line?.line2 || '';
const album = zone.now_playing?.three_line?.line3 || '';
log(`🎵 Reproduciendo: ${track} - ${artist} (${album})`);
getLyrics(artist, track, async (lyrics) => {
const displayText = `${track} - ${artist}`;
const tooltip = `🎵 ${track}\n👤 ${artist}\n💿 ${album}\n\n${lyrics}`;
const data = {
text: displayText,
tooltip: tooltip
};
log(`✍️ Escribiendo JSON para Waybar: ${JSON.stringify(data)}`);
fs.writeFileSync('/tmp/waybar_roon_info.json', JSON.stringify(data));
exec("/usr/bin/pkill -RTMIN+3 waybar");
const image_key = zone.now_playing?.image_key;
if (image_key) {
try {
const imageData = await core.services.RoonApiImage.get_image(image_key, { width: 300, height: 300 });
const coverPath = '/tmp/roon_album_cover.jpg';
fs.writeFileSync(coverPath, imageData.image);
exec(`notify-send -i ${coverPath} "Now Playing" "${displayText}"`);
log("✅ Notificación enviada con carátula");
} catch (error) {
log(`⚠️ Error obteniendo imagen: ${error}`);
exec(`notify-send "Now Playing" "${displayText}"`);
}
} else {
exec(`notify-send "Now Playing" "${displayText}"`);
}
});
}
}
});
extension.start_discovery();
extension.set_status('Esperando conexión al Core de Roon...');
log("🔍 Buscando Core...");
(async () => {
const core = await extension.get_core();
if (core) {
log("✅ Core emparejado correctamente");
extension.set_status('Emparejado con el Core de Roon');
} else {
log("❌ No se emparejó con ningún Core");
}
})();