Persist upload queue and uploaded cache
This commit is contained in:
@@ -40,6 +40,7 @@ public partial class MainWindow : Window
|
||||
{
|
||||
InitializeComponent();
|
||||
_settings = _settingsStore.Load();
|
||||
EnsureSettingsCollections();
|
||||
_settings.BaseUrl = NormalizeBaseUrl(_settings.BaseUrl) ?? DefaultBaseUrl;
|
||||
if (_settings.MaxConcurrentUploads <= 0)
|
||||
{
|
||||
@@ -226,6 +227,7 @@ public partial class MainWindow : Window
|
||||
ResetCounters();
|
||||
_uploadService.Start(_settings, OnQueued, OnUploading, OnSuccess, OnFailure);
|
||||
StartWatcher(_settings.WatchFolder);
|
||||
RestorePendingUploads();
|
||||
UpdateSteps();
|
||||
}
|
||||
|
||||
@@ -251,6 +253,11 @@ public partial class MainWindow : Window
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShouldSkipUpload(e.FullPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_uploadService.Enqueue(e.FullPath, OnQueued);
|
||||
}
|
||||
|
||||
@@ -261,6 +268,11 @@ public partial class MainWindow : Window
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShouldSkipUpload(e.FullPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_uploadService.Enqueue(e.FullPath, OnQueued);
|
||||
}
|
||||
|
||||
@@ -280,6 +292,7 @@ public partial class MainWindow : Window
|
||||
{
|
||||
Interlocked.Increment(ref _queuedCount);
|
||||
UpdateUpload(path, UploadStatus.Queued);
|
||||
AddPendingUpload(path);
|
||||
UpdateStatusIfAllowed($"Wartet: {Path.GetFileName(path)}", false);
|
||||
UpdateCountersText();
|
||||
}
|
||||
@@ -299,6 +312,8 @@ public partial class MainWindow : Window
|
||||
Interlocked.Decrement(ref _uploadingCount);
|
||||
_lastSuccessAt = DateTimeOffset.Now;
|
||||
UpdateUpload(path, UploadStatus.Success);
|
||||
RemovePendingUpload(path);
|
||||
MarkUploaded(path);
|
||||
UpdateStatusIfAllowed($"Hochgeladen: {Path.GetFileName(path)}", false);
|
||||
UpdateCountersText();
|
||||
UpdateLiveStatus();
|
||||
@@ -310,6 +325,7 @@ public partial class MainWindow : Window
|
||||
Interlocked.Decrement(ref _uploadingCount);
|
||||
Interlocked.Increment(ref _failedCount);
|
||||
UpdateUpload(path, UploadStatus.Failed);
|
||||
RemovePendingUpload(path);
|
||||
UpdateStatusIfAllowed($"Upload fehlgeschlagen: {Path.GetFileName(path)}", true);
|
||||
SetLastError($"{Path.GetFileName(path)} – {message}");
|
||||
UpdateRetryButton();
|
||||
@@ -398,6 +414,92 @@ public partial class MainWindow : Window
|
||||
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)
|
||||
{
|
||||
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');
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public sealed class PhotoboothSettings
|
||||
@@ -9,6 +12,8 @@ public sealed class PhotoboothSettings
|
||||
public string? Password { get; set; }
|
||||
public string? ResponseFormat { 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? LastErrorAt { get; set; }
|
||||
public int MaxConcurrentUploads { get; set; } = 2;
|
||||
|
||||
Reference in New Issue
Block a user