Persist upload queue and uploaded cache
This commit is contained in:
@@ -40,6 +40,7 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_settings = _settingsStore.Load();
|
_settings = _settingsStore.Load();
|
||||||
|
EnsureSettingsCollections();
|
||||||
_settings.BaseUrl = NormalizeBaseUrl(_settings.BaseUrl) ?? DefaultBaseUrl;
|
_settings.BaseUrl = NormalizeBaseUrl(_settings.BaseUrl) ?? DefaultBaseUrl;
|
||||||
if (_settings.MaxConcurrentUploads <= 0)
|
if (_settings.MaxConcurrentUploads <= 0)
|
||||||
{
|
{
|
||||||
@@ -226,6 +227,7 @@ public partial class MainWindow : Window
|
|||||||
ResetCounters();
|
ResetCounters();
|
||||||
_uploadService.Start(_settings, OnQueued, OnUploading, OnSuccess, OnFailure);
|
_uploadService.Start(_settings, OnQueued, OnUploading, OnSuccess, OnFailure);
|
||||||
StartWatcher(_settings.WatchFolder);
|
StartWatcher(_settings.WatchFolder);
|
||||||
|
RestorePendingUploads();
|
||||||
UpdateSteps();
|
UpdateSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +253,11 @@ public partial class MainWindow : Window
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShouldSkipUpload(e.FullPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_uploadService.Enqueue(e.FullPath, OnQueued);
|
_uploadService.Enqueue(e.FullPath, OnQueued);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,6 +268,11 @@ public partial class MainWindow : Window
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShouldSkipUpload(e.FullPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_uploadService.Enqueue(e.FullPath, OnQueued);
|
_uploadService.Enqueue(e.FullPath, OnQueued);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +292,7 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
Interlocked.Increment(ref _queuedCount);
|
Interlocked.Increment(ref _queuedCount);
|
||||||
UpdateUpload(path, UploadStatus.Queued);
|
UpdateUpload(path, UploadStatus.Queued);
|
||||||
|
AddPendingUpload(path);
|
||||||
UpdateStatusIfAllowed($"Wartet: {Path.GetFileName(path)}", false);
|
UpdateStatusIfAllowed($"Wartet: {Path.GetFileName(path)}", false);
|
||||||
UpdateCountersText();
|
UpdateCountersText();
|
||||||
}
|
}
|
||||||
@@ -299,6 +312,8 @@ public partial class MainWindow : Window
|
|||||||
Interlocked.Decrement(ref _uploadingCount);
|
Interlocked.Decrement(ref _uploadingCount);
|
||||||
_lastSuccessAt = DateTimeOffset.Now;
|
_lastSuccessAt = DateTimeOffset.Now;
|
||||||
UpdateUpload(path, UploadStatus.Success);
|
UpdateUpload(path, UploadStatus.Success);
|
||||||
|
RemovePendingUpload(path);
|
||||||
|
MarkUploaded(path);
|
||||||
UpdateStatusIfAllowed($"Hochgeladen: {Path.GetFileName(path)}", false);
|
UpdateStatusIfAllowed($"Hochgeladen: {Path.GetFileName(path)}", false);
|
||||||
UpdateCountersText();
|
UpdateCountersText();
|
||||||
UpdateLiveStatus();
|
UpdateLiveStatus();
|
||||||
@@ -310,6 +325,7 @@ public partial class MainWindow : Window
|
|||||||
Interlocked.Decrement(ref _uploadingCount);
|
Interlocked.Decrement(ref _uploadingCount);
|
||||||
Interlocked.Increment(ref _failedCount);
|
Interlocked.Increment(ref _failedCount);
|
||||||
UpdateUpload(path, UploadStatus.Failed);
|
UpdateUpload(path, UploadStatus.Failed);
|
||||||
|
RemovePendingUpload(path);
|
||||||
UpdateStatusIfAllowed($"Upload fehlgeschlagen: {Path.GetFileName(path)}", true);
|
UpdateStatusIfAllowed($"Upload fehlgeschlagen: {Path.GetFileName(path)}", true);
|
||||||
SetLastError($"{Path.GetFileName(path)} – {message}");
|
SetLastError($"{Path.GetFileName(path)} – {message}");
|
||||||
UpdateRetryButton();
|
UpdateRetryButton();
|
||||||
@@ -398,6 +414,92 @@ public partial class MainWindow : Window
|
|||||||
ReconnectButton.IsEnabled = enabled;
|
ReconnectButton.IsEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RestorePendingUploads()
|
||||||
|
{
|
||||||
|
EnsureSettingsCollections();
|
||||||
|
|
||||||
|
if (_settings.PendingUploads.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pending = _settings.PendingUploads.ToList();
|
||||||
|
var changed = false;
|
||||||
|
|
||||||
|
foreach (var path in pending)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path) || ShouldSkipUpload(path))
|
||||||
|
{
|
||||||
|
_settings.PendingUploads.Remove(path);
|
||||||
|
changed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_uploadService.Enqueue(path, OnQueued);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
_settingsStore.Save(_settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldSkipUpload(string path)
|
||||||
|
{
|
||||||
|
var signature = GetUploadSignature(path);
|
||||||
|
if (signature is null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _settings.UploadedFiles.TryGetValue(path, out var recorded) && recorded == signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? GetUploadSignature(string path)
|
||||||
|
{
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = new FileInfo(path);
|
||||||
|
return $"{info.Length}:{info.LastWriteTimeUtc.Ticks}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPendingUpload(string path)
|
||||||
|
{
|
||||||
|
EnsureSettingsCollections();
|
||||||
|
|
||||||
|
if (!_settings.PendingUploads.Contains(path))
|
||||||
|
{
|
||||||
|
_settings.PendingUploads.Add(path);
|
||||||
|
_settingsStore.Save(_settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemovePendingUpload(string path)
|
||||||
|
{
|
||||||
|
EnsureSettingsCollections();
|
||||||
|
|
||||||
|
if (_settings.PendingUploads.Remove(path))
|
||||||
|
{
|
||||||
|
_settingsStore.Save(_settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MarkUploaded(string path)
|
||||||
|
{
|
||||||
|
var signature = GetUploadSignature(path);
|
||||||
|
if (signature is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureSettingsCollections();
|
||||||
|
_settings.UploadedFiles[path] = signature;
|
||||||
|
_settingsStore.Save(_settings);
|
||||||
|
}
|
||||||
|
|
||||||
private void TitleText_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
|
private void TitleText_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.ClickCount < 2)
|
if (e.ClickCount < 2)
|
||||||
@@ -706,4 +808,10 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
return code.Length == 6 && code.All(ch => ch is >= '0' and <= '9');
|
return code.Length == 6 && code.All(ch => ch is >= '0' and <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EnsureSettingsCollections()
|
||||||
|
{
|
||||||
|
_settings.PendingUploads ??= new List<string>();
|
||||||
|
_settings.UploadedFiles ??= new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace PhotoboothUploader.Models;
|
namespace PhotoboothUploader.Models;
|
||||||
|
|
||||||
public sealed class PhotoboothSettings
|
public sealed class PhotoboothSettings
|
||||||
@@ -9,6 +12,8 @@ public sealed class PhotoboothSettings
|
|||||||
public string? Password { get; set; }
|
public string? Password { get; set; }
|
||||||
public string? ResponseFormat { get; set; }
|
public string? ResponseFormat { get; set; }
|
||||||
public string? WatchFolder { get; set; }
|
public string? WatchFolder { get; set; }
|
||||||
|
public List<string> PendingUploads { get; set; } = new();
|
||||||
|
public Dictionary<string, string> UploadedFiles { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||||
public string? LastError { get; set; }
|
public string? LastError { get; set; }
|
||||||
public string? LastErrorAt { get; set; }
|
public string? LastErrorAt { get; set; }
|
||||||
public int MaxConcurrentUploads { get; set; } = 2;
|
public int MaxConcurrentUploads { get; set; } = 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user