Prepare Linux deployment with yt-dlp and persistent downloads
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TuneRipper.Api.Configuration;
|
||||
|
||||
namespace TuneRipper.Api.Health;
|
||||
|
||||
public sealed class ExternalToolsHealthCheck(IOptions<YtDlpOptions> options) : IHealthCheck
|
||||
{
|
||||
public async Task<HealthCheckResult> CheckHealthAsync(
|
||||
HealthCheckContext context,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var ytDlp = await ProbeAsync(options.Value.ExecutablePath, "--version", cancellationToken);
|
||||
if (!ytDlp.Success)
|
||||
{
|
||||
return HealthCheckResult.Unhealthy($"yt-dlp is unavailable: {ytDlp.Message}");
|
||||
}
|
||||
|
||||
var ffmpeg = await ProbeAsync(options.Value.FfmpegExecutablePath, "-version", cancellationToken);
|
||||
if (!ffmpeg.Success)
|
||||
{
|
||||
return HealthCheckResult.Unhealthy($"ffmpeg is unavailable: {ffmpeg.Message}");
|
||||
}
|
||||
|
||||
return HealthCheckResult.Healthy($"yt-dlp {ytDlp.Message}; ffmpeg available");
|
||||
}
|
||||
|
||||
private static async Task<(bool Success, string Message)> ProbeAsync(
|
||||
string executable,
|
||||
string argument,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = executable,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
startInfo.ArgumentList.Add(argument);
|
||||
|
||||
using var process = Process.Start(startInfo);
|
||||
if (process is null)
|
||||
{
|
||||
return (false, "process could not be started");
|
||||
}
|
||||
|
||||
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
timeout.CancelAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var outputTask = process.StandardOutput.ReadLineAsync(timeout.Token).AsTask();
|
||||
await process.WaitForExitAsync(timeout.Token);
|
||||
var output = (await outputTask)?.Trim();
|
||||
|
||||
return process.ExitCode == 0
|
||||
? (true, string.IsNullOrWhiteSpace(output) ? "available" : output)
|
||||
: (false, $"exit code {process.ExitCode}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user