Compare commits

...

5 commits

Author SHA1 Message Date
823bb11b83 Updated App
Added Last Update stamp, for when the last update was in the database,
to see if we have newer events to process.
Applied settings for enabling/disabling syncers on startup.
Updated SyncMonitor() to use new Update check, before iterating through
all the syncers and fetching them.
Added logging messages for when we are updating settings to reflect what
has been changed.
2025-07-31 14:28:36 -05:00
a88da7f6d0 Updated Syncer
Added GetLastUpdated() to ISyncer interface.
Updated code to use new /ping endpoint.
Added GetLastUpdated() REST API call to fetch when the database was last
updated.
Clarified logging for when an Update is from a file, or from the REST
API Server.
Added logging for when a nw File Entry is processed, or when a File
Entry is Updated.
2025-07-31 14:26:20 -05:00
0e07f21ffe Updated CSProj
Removed Views, as is not needed.
2025-07-31 14:24:32 -05:00
c9e4cc694b Added Ping and UpdateCheck models.
Added Ping and UpdateCheck models for quick pings for service being
alive, and when the database was last updated.
2025-07-31 14:24:10 -05:00
b3e6d2e844 Updated DBSyncWatcher
Removed logging of changes detected in files.
2025-07-31 14:23:33 -05:00
6 changed files with 108 additions and 18 deletions

View file

@ -32,6 +32,7 @@ public partial class App : Application
private string? _oldSettings; private string? _oldSettings;
private static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1); private static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
private TimeSpan _checkInterval; private TimeSpan _checkInterval;
private DateTime _lastUpdated;
public event EventHandler? SettingsChanged; public event EventHandler? SettingsChanged;
@ -67,10 +68,15 @@ public partial class App : Application
_watcher = new DBSyncWatcher(path); _watcher = new DBSyncWatcher(path);
_historySyncer = new Syncer<History>(_watcher, Path.Join(path, "history.db"), "history.db", _settings.RestBaseUrl, "/history"); _historySyncer = new Syncer<History>(_watcher, Path.Join(path, "history.db"), "history.db", _settings.RestBaseUrl, "/history");
_historySyncer.SetEnabled(_settings.SyncHistory);
_playlistSyncer = new Syncer<Playlist>(_watcher, Path.Join(path, "playlists.db"), "playlists.db", _settings.RestBaseUrl, "/playlist"); _playlistSyncer = new Syncer<Playlist>(_watcher, Path.Join(path, "playlists.db"), "playlists.db", _settings.RestBaseUrl, "/playlist");
_playlistSyncer.SetEnabled(_settings.SyncPlaylist);
_profileSyncer = new Syncer<Profile>(_watcher, Path.Join(path, "profiles.db"), "profiles.db", _settings.RestBaseUrl, "/profile"); _profileSyncer = new Syncer<Profile>(_watcher, Path.Join(path, "profiles.db"), "profiles.db", _settings.RestBaseUrl, "/profile");
_profileSyncer.SetEnabled(_settings.SyncProfile);
_searchHistorySyncer = new Syncer<SearchHistory>(_watcher, Path.Join(path, "search-history.db"), "search-history.db", _settings.RestBaseUrl, "/searchHistory"); _searchHistorySyncer = new Syncer<SearchHistory>(_watcher, Path.Join(path, "search-history.db"), "search-history.db", _settings.RestBaseUrl, "/searchHistory");
_searchHistorySyncer.SetEnabled(_settings.SyncSearchHistory);
_settingSyncer = new Syncer<Setting>(_watcher, Path.Join(path, "settings.db"), "settings.db", _settings.RestBaseUrl, "/settings"); _settingSyncer = new Syncer<Setting>(_watcher, Path.Join(path, "settings.db"), "settings.db", _settings.RestBaseUrl, "/settings");
_settingSyncer.SetEnabled(_settings.SyncSettings);
_syncers = _syncers =
[ [
_historySyncer, _historySyncer,
@ -155,6 +161,8 @@ public partial class App : Application
await syncer.FetchDatabase(); await syncer.FetchDatabase();
} }
_lastUpdated = await _syncers[0].GetLastUpdated();
_semaphoreSlim.Release(); _semaphoreSlim.Release();
break; break;
} }
@ -173,8 +181,15 @@ public partial class App : Application
var start = DateTime.Now; var start = DateTime.Now;
// TODO: Replace with Logger // TODO: Replace with Logger
Console.WriteLine("Checking for updates..."); Console.WriteLine("Checking for updates...");
foreach (var syncer in _syncers) var updateCheck = await _syncers[0].GetLastUpdated();
await syncer.FetchDatabase(); if (_lastUpdated < updateCheck)
{
// TODO: Replace with Logger
Console.WriteLine($"Update Found, fetching updates...");
_lastUpdated = updateCheck;
foreach (var syncer in _syncers)
await syncer.FetchDatabase();
}
lastCheck = DateTime.Now; lastCheck = DateTime.Now;
var end = DateTime.Now - start; var end = DateTime.Now - start;
_semaphoreSlim.Release(); _semaphoreSlim.Release();
@ -207,20 +222,64 @@ public partial class App : Application
private async void HandleSettingsChanged(object? sender, EventArgs e) private async void HandleSettingsChanged(object? sender, EventArgs e)
{ {
// TODO: Replace with Logger
Console.WriteLine("Settings have changed. Updating Settings...");
await _semaphoreSlim.WaitAsync(); await _semaphoreSlim.WaitAsync();
var old = JsonSerializer.Deserialize<AppSettings>(_oldSettings!); var old = JsonSerializer.Deserialize<AppSettings>(_oldSettings!);
if (_settings!.RestBaseUrl != old!.RestBaseUrl) if (_settings!.RestBaseUrl != old!.RestBaseUrl)
{ {
// TODO: Replace with Logger
Console.WriteLine($"Updating syncers with new URL: {_settings.RestBaseUrl}.");
foreach (var syncer in _syncers!) foreach (var syncer in _syncers!)
syncer.UpdateBaseUrl(_settings.RestBaseUrl); syncer.UpdateBaseUrl(_settings.RestBaseUrl);
} }
if (old.CheckInterval != _settings.CheckInterval) _checkInterval = TimeSpan.FromSeconds(_settings.CheckInterval); if (old.CheckInterval != _settings.CheckInterval)
if (old.SyncHistory != _settings.SyncHistory) _historySyncer!.SetEnabled(_settings.SyncHistory); {
if (old.SyncPlaylist != _settings.SyncPlaylist) _playlistSyncer!.SetEnabled(_settings.SyncPlaylist); // TODO: Replace with Logger
if (old.SyncProfile != _settings.SyncProfile) _profileSyncer!.SetEnabled(_settings.SyncProfile); Console.WriteLine($"Updating Check Interval to {_settings.CheckInterval}.");
if (old.SyncSearchHistory != _settings.SyncSearchHistory) _searchHistorySyncer!.SetEnabled(_settings.SyncSearchHistory); _checkInterval = TimeSpan.FromSeconds(_settings.CheckInterval);
if (old.SyncSettings != _settings.SyncSettings) _settingSyncer!.SetEnabled(_settings.SyncSettings); }
if (old.SyncHistory != _settings.SyncHistory)
{
// TODO: Replace with Logger
Console.WriteLine("History Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
_historySyncer!.SetEnabled(_settings.SyncHistory);
await _historySyncer.FetchDatabase();
}
if (old.SyncPlaylist != _settings.SyncPlaylist)
{
// TODO: Replace with Logger
Console.WriteLine("Playlist Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
_playlistSyncer!.SetEnabled(_settings.SyncPlaylist);
await _playlistSyncer.FetchDatabase();
}
if (old.SyncProfile != _settings.SyncProfile)
{
// TODO: Replace with Logger
Console.WriteLine("Profile Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
_profileSyncer!.SetEnabled(_settings.SyncProfile);
await _profileSyncer.FetchDatabase();
}
if (old.SyncSearchHistory != _settings.SyncSearchHistory)
{
// TODO: Replace with Logger
Console.WriteLine("Search History Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
_searchHistorySyncer!.SetEnabled(_settings.SyncSearchHistory);
await _searchHistorySyncer.FetchDatabase();
}
if (old.SyncSettings != _settings.SyncSettings)
{
// TODO: Replace with Logger
Console.WriteLine("Settings Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
_settingSyncer!.SetEnabled(_settings.SyncSettings);
await _settingSyncer.FetchDatabase();
}
_semaphoreSlim.Release(); _semaphoreSlim.Release();
} }

View file

@ -26,7 +26,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="Assets\" /> <Folder Include="Assets\" />
<Folder Include="Views\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -43,8 +43,6 @@ public class DBSyncWatcher
var dbName = Path.GetFileName(e.FullPath); var dbName = Path.GetFileName(e.FullPath);
if (!WatchFiles.Keys.Contains(dbName)) return; if (!WatchFiles.Keys.Contains(dbName)) return;
Console.WriteLine("New Change in {0}", dbName);
var data = File.ReadAllText(e.FullPath); var data = File.ReadAllText(e.FullPath);
foreach (var line in data.Split('\n')) foreach (var line in data.Split('\n'))

View file

@ -0,0 +1,6 @@
namespace FreeTubeSyncer.Models.DatabaseModels;
public class Ping
{
public string AppVersion { get; set; }
}

View file

@ -0,0 +1,8 @@
using System;
namespace FreeTubeSyncer.Models.DatabaseModels;
public class UpdateCheck
{
public DateTime LastUpdated { get; set; }
}

View file

@ -27,6 +27,7 @@ public interface ISyncer
void UpdateBaseUrl(string baseUrl); void UpdateBaseUrl(string baseUrl);
void SetEnabled(bool enabled); void SetEnabled(bool enabled);
Task<bool> PingApi(); Task<bool> PingApi();
Task<DateTime> GetLastUpdated();
} }
public class Syncer<T> : ISyncer where T : class, IDataModel, new() public class Syncer<T> : ISyncer where T : class, IDataModel, new()
@ -71,11 +72,18 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
Console.WriteLine($"Pinging API at {_client.BuildUri(new RestRequest("/ping"))}..."); Console.WriteLine($"Pinging API at {_client.BuildUri(new RestRequest("/ping"))}...");
try try
{ {
var res = await _client.ExecuteHeadAsync(new RestRequest("/ping")); var res = await _client.GetAsync<Ping>(new RestRequest("/ping"));
if (res.StatusCode == HttpStatusCode.NotFound) if (res == null)
{ {
// TODO: Replace with Logger // TODO: Replace with Logger
Console.WriteLine($"Ping response 404 Not Found, Server Online!"); Console.WriteLine($"Ping returned null, not the server we are looking for!");
return false;
}
if (res.AppVersion == "0.1.3")
{
// TODO: Replace with Logger
Console.WriteLine($"Server Online! {res.AppVersion}");
return true; return true;
} }
} }
@ -91,6 +99,12 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
return false; return false;
} }
public async Task<DateTime> GetLastUpdated()
{
var res = await _client.GetAsync<UpdateCheck>("/ping/lastUpdated");
return res?.LastUpdated ?? DateTime.MinValue;
}
public async Task ReadDatabase() public async Task ReadDatabase()
{ {
if (!_enabled) return; if (!_enabled) return;
@ -115,7 +129,7 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
_entries.RemoveAll(x => x.EqualId(item.Id())); _entries.RemoveAll(x => x.EqualId(item.Id()));
_entries.Add(item); _entries.Add(item);
// TODO: Replace with Logger // TODO: Replace with Logger
Console.WriteLine($"Posting {item.Id()}"); Console.WriteLine($"Posting to REST: {item.Id()}");
await _client.PostJsonAsync<T>(_restEndpoint, item); await _client.PostJsonAsync<T>(_restEndpoint, item);
} }
} }
@ -134,13 +148,13 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
if (data.Equals(entry)) continue; if (data.Equals(entry)) continue;
// TODO: Replace with Logger // TODO: Replace with Logger
Console.WriteLine($"Updated Entry for {_dbName} - {entry.Id()}"); Console.WriteLine($"Updated Entry from REST for {_dbName} - {entry.Id()}");
_entries.RemoveAll(x => x.EqualId(entry.Id())); _entries.RemoveAll(x => x.EqualId(entry.Id()));
} }
else else
{ {
// TODO: Replace with Logger // TODO: Replace with Logger
Console.WriteLine($"New Entry for {_dbName} - {entry.Id()}"); Console.WriteLine($"New Entry from REST for {_dbName} - {entry.Id()}");
} }
_entries.Add(entry); _entries.Add(entry);
@ -185,9 +199,15 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
{ {
var data = _entries.First(x => x.EqualId(entry.Id())); var data = _entries.First(x => x.EqualId(entry.Id()));
if (data.Equals(entry)) return; if (data.Equals(entry)) return;
// TODO: Replace with Logger
Console.WriteLine($"File Entry {entry.Id()} updated for {_dbName}");
_entries.RemoveAll(x => x.EqualId(entry.Id())); _entries.RemoveAll(x => x.EqualId(entry.Id()));
} }
else
{
// TODO: Replace with Logger
Console.WriteLine($"New File Entry {entry.Id()} for {_dbName}");
}
_entries.Add(entry); _entries.Add(entry);
await _client.PostJsonAsync<T>(_restEndpoint, entry); await _client.PostJsonAsync<T>(_restEndpoint, entry);