133 lines
4.0 KiB
C#
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;
|
|
}
|
|
}
|