Compare commits

...

2 commits

Author SHA1 Message Date
829aa55c9f Updated Syncer
Updated syncer to new API 0.1.5.
Change ID Comparison to string comparison, instead of EqualId()
function.
Updated RemoveAll() to use string comparison, instead of EqualId() to
remove.
Added Try Catch retry 1 after delay.  This happens when we post multiple
copies of the same DB line entry, when it doesn't exist, and is added to
the REST Server, while the REST server processes it in one thread, but
it isn't updated properly in the new thread, and it fails, cause the
item is in the database backend, and fails to process.  Solution is to
wait for a small delay, before attempting the post request again.  If it
fails a second time, then there's something majorly wrong.
2025-08-09 04:18:11 -05:00
4f93a21098 Updated UI/App Settings
Changed interval check from a Numeric spin box, to a pre-defined option
selector.
Now have 1/2 minute, 1 Minute, 30 Minutes, 1 hour, 6 hours, 12 hours and
24 hour intervals.
2025-08-09 04:11:25 -05:00
4 changed files with 56 additions and 7 deletions

View file

@ -125,6 +125,7 @@ public partial class App : Application
_settings.SyncSearchHistory = @new.SyncSearchHistory;
_settings.SyncSettings = @new.SyncSettings;
_settings.SettingsDirty = false;
_settings.UpdateInterval();
}
public void SaveSettings()
@ -146,11 +147,13 @@ public partial class App : Application
if (!File.Exists(path))
{
_settings = new AppSettings();
_settings.UpdateInterval();
return;
}
var data = File.ReadAllText(path);
_settings = JsonSerializer.Deserialize<AppSettings>(data);
_settings!.UpdateInterval();
}
private string GetAppFolder() => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FreeTubeSyncer");

View file

@ -24,7 +24,13 @@
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Text="REST API Backend Server: " FontWeight="Bold"/>
<TextBox Grid.Row="0" Grid.Column="1" Watermark="http://localhost:8080" Text="{Binding RestBaseUrl, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Text="Refresh Interval: " FontWeight="Bold"/>
<NumericUpDown Grid.Row="1" Grid.Column="1" Watermark="30" suki:NumericUpDownExtensions.Unit="seconds" FormatString="N0" Value="{Binding CheckInterval, Mode=TwoWay}"/>
<ComboBox Grid.Row="1" Grid.Column="1" SelectedValue="{Binding SelectedOption}" ItemsSource="{Binding CheckIntervalOptions}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Label}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
<Grid
ColumnDefinitions="170,*"

View file

@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using CommunityToolkit.Mvvm.ComponentModel;
using DynamicData;
namespace FreeTubeSyncer.Models;
@ -13,6 +15,16 @@ public partial class AppSettings : ObservableObject
[ObservableProperty] [property: JsonInclude] private bool _syncSearchHistory = true;
[ObservableProperty] [property: JsonInclude] private bool _syncSettings = true;
[ObservableProperty] [property: JsonIgnore] private bool _settingsDirty = false;
[ObservableProperty] [property: JsonIgnore] private CheckIntervalOption? _selectedOption = null;
[ObservableProperty] [property: JsonIgnore] private List<CheckIntervalOption> _checkIntervalOptions = [
new CheckIntervalOption("1/2 Minute", 30),
new CheckIntervalOption("1 Minute", 60),
new CheckIntervalOption("30 Minutes", 1800),
new CheckIntervalOption("1 Hour", 3600),
new CheckIntervalOption("6 Hours", 21600),
new CheckIntervalOption("12 Hours", 43200),
new CheckIntervalOption("24 Hours", 86400),
];
public AppSettings()
{
@ -21,7 +33,19 @@ public partial class AppSettings : ObservableObject
if (args.PropertyName == nameof(SettingsDirty))
return;
if (args.PropertyName == nameof(SelectedOption))
_checkInterval = SelectedOption?.Interval ?? 30;
SettingsDirty = true;
};
}
}
public void UpdateInterval()
{
int[] intervals = [30, 60, 1800, 3600, 21600, 43200, 86400];
var i = intervals.IndexOf(CheckInterval);
SelectedOption = CheckIntervalOptions[i];
}
}
public record CheckIntervalOption(string Label, int Interval);

View file

@ -82,7 +82,7 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
return false;
}
if (res.AppVersion == "0.1.4")
if (res.AppVersion == "0.1.5")
{
Log.Information("Server Online! {AppVersion}", res.AppVersion);
return true;
@ -197,18 +197,34 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
if (entry == null) continue;
entry.MarshalData(entry.Id(), entryObject);
if (_entries.Any(x => x.EqualId(entry.Id())))
if (_entries.Any(x => x.Id() == entry.Id()))
{
var data = _entries.First(x => x.EqualId(entry.Id()));
var data = _entries.First(x => x.Id() == entry.Id());
if (data.Equals(entry)) continue;
Log.Information("Updated File Entry {EntryId} updated for {DbName}", entry.Id(), _dbName);
_entries.RemoveAll(x => x.EqualId(entry.Id()));
_entries.RemoveAll(x => x.Id() == entry.Id());
}
else
Log.Information("New File Entry {EntryId} for {DbName}", entry.Id(), _dbName);
_entries.Add(entry);
await _client.PostJsonAsync<T>(_restEndpoint, entry);
try
{
await _client.PostJsonAsync<T>(_restEndpoint, entry);
}
catch (Exception ex)
{
await Task.Delay(500);
try
{
await _client.PostJsonAsync<T>(_restEndpoint, entry);
}
catch (Exception iex)
{
Log.Error("Failed to sync entry {id} to REST Database.", entry.Id());
}
}
_lastLineCount = i;
}
}