Work done so far
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user