Files
Painobar-helper/PianobarEventMonitor.cs
2026-08-11 22:42:01 -04:00

133 lines
4.0 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
namespace PainoBar_Helper
{
/// <summary>
/// Monitors Pianobar event output file for song changes and metadata updates
/// </summary>
public class PianobarEventMonitor : IDisposable
{
private FileSystemWatcher? _watcher;
private string? _eventFilePath;
private bool _disposed;
public event EventHandler<PianobarEventData>? EventReceived;
public void StartMonitoring(string eventFilePath)
{
if (string.IsNullOrEmpty(eventFilePath))
throw new ArgumentException("Event file path cannot be empty", nameof(eventFilePath));
StopMonitoring();
_eventFilePath = eventFilePath;
// Ensure the directory exists
var directory = Path.GetDirectoryName(eventFilePath);
if (!string.IsNullOrEmpty(directory))
Directory.CreateDirectory(directory);
// Create initial file if it doesn't exist
if (!File.Exists(eventFilePath))
File.WriteAllText(eventFilePath, "{}");
// Set up file watcher
_watcher = new FileSystemWatcher
{
Path = directory!,
Filter = Path.GetFileName(eventFilePath),
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size
};
_watcher.Changed += OnFileChanged;
_watcher.EnableRaisingEvents = true;
}
public void StopMonitoring()
{
if (_watcher != null)
{
_watcher.EnableRaisingEvents = false;
_watcher.Changed -= OnFileChanged;
_watcher.Dispose();
_watcher = null;
}
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
try
{
// Give the file a moment to finish writing
Thread.Sleep(50);
if (string.IsNullOrEmpty(_eventFilePath) || !File.Exists(_eventFilePath))
return;
string json = File.ReadAllText(_eventFilePath);
if (string.IsNullOrWhiteSpace(json))
return;
var eventData = JsonSerializer.Deserialize<PianobarEventData>(json);
if (eventData != null)
{
EventReceived?.Invoke(this, eventData);
}
}
catch
{
// Ignore file read errors (file might be locked, etc.)
}
}
public void Dispose()
{
if (_disposed)
return;
StopMonitoring();
_disposed = true;
}
}
/// <summary>
/// Represents event data from Pianobar
/// </summary>
public class PianobarEventData
{
[JsonPropertyName("event")]
public string Event { get; set; } = string.Empty;
[JsonPropertyName("timestamp")]
public string Timestamp { get; set; } = string.Empty;
[JsonPropertyName("artist")]
public string Artist { get; set; } = string.Empty;
[JsonPropertyName("title")]
public string Title { get; set; } = string.Empty;
[JsonPropertyName("album")]
public string Album { get; set; } = string.Empty;
[JsonPropertyName("coverArt")]
public string CoverArt { get; set; } = string.Empty;
[JsonPropertyName("stationName")]
public string StationName { get; set; } = string.Empty;
[JsonPropertyName("songDuration")]
public string SongDuration { get; set; } = string.Empty;
[JsonPropertyName("songPlayed")]
public string SongPlayed { get; set; } = string.Empty;
[JsonPropertyName("rating")]
public string Rating { get; set; } = string.Empty;
[JsonPropertyName("detailUrl")]
public string DetailUrl { get; set; } = string.Empty;
}
}