Compare commits
4 commits
823bb11b83
...
145c863fbe
| Author | SHA1 | Date | |
|---|---|---|---|
| 145c863fbe | |||
| d8e650deec | |||
| c94b709145 | |||
| 725a37d9cf |
4 changed files with 103 additions and 83 deletions
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
|
|
@ -13,6 +14,10 @@ using FreeTubeSyncer.Library;
|
|||
using FreeTubeSyncer.Models;
|
||||
using FreeTubeSyncer.Models.DatabaseModels;
|
||||
using FreeTubeSyncer.REST;
|
||||
using Serilog;
|
||||
using Serilog.Sinks.File.GzArchive;
|
||||
using Serilog.Sinks.FileEx;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
namespace FreeTubeSyncer;
|
||||
|
||||
|
|
@ -45,6 +50,7 @@ public partial class App : Application
|
|||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
SetupLogger();
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
var path = "";
|
||||
|
|
@ -59,7 +65,7 @@ public partial class App : Application
|
|||
path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".var", "app", "io.freetubeapp.FreeTube", "config",
|
||||
"FreeTube");
|
||||
if (!Path.Exists(path))
|
||||
Console.WriteLine("Failed to find Path for FreeTube!");
|
||||
Log.Error("Failed to find Path for FreeTube!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,9 +118,8 @@ public partial class App : Application
|
|||
var path = GetSettingsPath();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
if (!Directory.Exists(GetAppFolder()))
|
||||
Directory.CreateDirectory(GetAppFolder());
|
||||
}
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(_settings));
|
||||
_settings!.SettingsDirty = false;
|
||||
|
|
@ -129,20 +134,35 @@ public partial class App : Application
|
|||
_settings = new AppSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
var data = File.ReadAllText(path);
|
||||
_settings = JsonSerializer.Deserialize<AppSettings>(data);
|
||||
}
|
||||
|
||||
private string GetSettingsPath() => OperatingSystem.IsLinux()
|
||||
? Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FreeTubeSyncer", "settings.json")
|
||||
: Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config", "FreeTubeSyncer", "settings.json");
|
||||
|
||||
private string GetAppFolder() => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FreeTubeSyncer");
|
||||
private string GetSettingsPath() => Path.Join(GetAppFolder(), "settings.json");
|
||||
|
||||
private void SetupLogger()
|
||||
{
|
||||
var path = Path.Join(GetAppFolder(), "logs");
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
var log = new LoggerConfiguration()
|
||||
.WriteTo.Console(theme: AnsiConsoleTheme.Code,
|
||||
outputTemplate: "[{Timestamp:hh:mm:ss t} {Level:u4}] {Message:lj}{NewLine}{Exception}")
|
||||
.WriteTo.FileEx(Path.Join(path, "activity.log"), "MM-dd-yy",
|
||||
rollingInterval: RollingInterval.Day,
|
||||
outputTemplate: "[{Timestamp:MM/dd/yy - hh:mm:ss t}] [{Level:u4}] {Message:lj}{NewLine}{Exception}",
|
||||
hooks: new FileArchiveRollingHooks(CompressionLevel.SmallestSize, path))
|
||||
.CreateLogger();
|
||||
Log.Logger = log;
|
||||
Log.Information("Log Started.");
|
||||
}
|
||||
|
||||
private async Task SyncMonitor()
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Sync Monitor Starting Up.");
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Starting API Validation Check.");
|
||||
Log.Information("Sync Monitor Starting Up.");
|
||||
Log.Information("Starting API Validation Check.");
|
||||
while (_isRunning)
|
||||
{
|
||||
await _semaphoreSlim.WaitAsync();
|
||||
|
|
@ -154,8 +174,7 @@ public partial class App : Application
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Fetching initial data from Database.");
|
||||
Log.Information("Fetching initial data from REST API.");
|
||||
foreach (var syncer in _syncers!)
|
||||
{
|
||||
await syncer.FetchDatabase();
|
||||
|
|
@ -167,8 +186,7 @@ public partial class App : Application
|
|||
break;
|
||||
}
|
||||
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Starting Filesystem Sync Monitoring.");
|
||||
Log.Information("Starting Filesystem Sync Monitoring.");
|
||||
var lastCheck = DateTime.Now;
|
||||
while (_isRunning)
|
||||
{
|
||||
|
|
@ -179,13 +197,11 @@ public partial class App : Application
|
|||
{
|
||||
await _semaphoreSlim.WaitAsync();
|
||||
var start = DateTime.Now;
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Checking for updates...");
|
||||
Log.Information("Checking for updates...");
|
||||
var updateCheck = await _syncers[0].GetLastUpdated();
|
||||
if (_lastUpdated < updateCheck)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Update Found, fetching updates...");
|
||||
Log.Information("Update Found, fetching updates...");
|
||||
_lastUpdated = updateCheck;
|
||||
foreach (var syncer in _syncers)
|
||||
await syncer.FetchDatabase();
|
||||
|
|
@ -193,8 +209,7 @@ public partial class App : Application
|
|||
lastCheck = DateTime.Now;
|
||||
var end = DateTime.Now - start;
|
||||
_semaphoreSlim.Release();
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Check Completed. Total Time: {end}");
|
||||
Log.Information("Check Completed. Total Time: {EndTime}", end);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -202,8 +217,7 @@ public partial class App : Application
|
|||
|
||||
var procs = Process.GetProcessesByName("FreeTube");
|
||||
if (procs.Length > 0) continue;
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("FreeTube closed, and we have writes to make...");
|
||||
Log.Information("FreeTube instance closed, and we have writes to make...");
|
||||
await Task.Delay(1500);
|
||||
|
||||
await _semaphoreSlim.WaitAsync();
|
||||
|
|
@ -212,71 +226,61 @@ public partial class App : Application
|
|||
syncer.Sync();
|
||||
var syncEnd = DateTime.Now - syncStart;
|
||||
_semaphoreSlim.Release();
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Sync completed in {syncEnd}.");
|
||||
Log.Information("Sync Completed. Total Time: {EndTime}", syncEnd);
|
||||
}
|
||||
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Filesystem Sync Monitor Shutdown.");
|
||||
Log.Information("Filesystem Sync Monitor shutdown.");
|
||||
}
|
||||
|
||||
private async void HandleSettingsChanged(object? sender, EventArgs e)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Settings have changed. Updating Settings...");
|
||||
Log.Information("Settings have changed. Updating Settings...");
|
||||
await _semaphoreSlim.WaitAsync();
|
||||
var old = JsonSerializer.Deserialize<AppSettings>(_oldSettings!);
|
||||
if (_settings!.RestBaseUrl != old!.RestBaseUrl)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Updating syncers with new URL: {_settings.RestBaseUrl}.");
|
||||
Log.Information("Updating syncers with new URL: {SettingsRestBaseUrl}.", _settings.RestBaseUrl);
|
||||
foreach (var syncer in _syncers!)
|
||||
syncer.UpdateBaseUrl(_settings.RestBaseUrl);
|
||||
}
|
||||
|
||||
if (old.CheckInterval != _settings.CheckInterval)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Updating Check Interval to {_settings.CheckInterval}.");
|
||||
Log.Information("Updating Check Interval to {SettingsCheckInterval}.", _settings.CheckInterval);
|
||||
_checkInterval = TimeSpan.FromSeconds(_settings.CheckInterval);
|
||||
}
|
||||
|
||||
if (old.SyncHistory != _settings.SyncHistory)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("History Syncer: " + (_settings.SyncHistory ? "Enabled" : "Disabled"));
|
||||
Log.Information("History Syncer: {Status}",(_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"));
|
||||
Log.Information("Playlist Syncer: {Status}",(_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"));
|
||||
Log.Information("Profile Syncer: {Status}", (_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"));
|
||||
Log.Information("Search History Syncer: {Status}", (_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"));
|
||||
Log.Information("Settings Syncer: {Status}",(_settings.SyncHistory ? "Enabled" : "Disabled"));
|
||||
_settingSyncer!.SetEnabled(_settings.SyncSettings);
|
||||
await _settingSyncer.FetchDatabase();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<LangVersion>latestmajor</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -21,6 +22,10 @@
|
|||
</PackageReference>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File.GzArchive" Version="1.1.10" />
|
||||
<PackageReference Include="Serilog.Sinks.FileEx" Version="5.1.8" />
|
||||
<PackageReference Include="SukiUI" Version="6.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using Serilog;
|
||||
|
||||
namespace FreeTubeSyncer.Library;
|
||||
|
||||
|
|
@ -44,8 +45,15 @@ public class DBSyncWatcher
|
|||
|
||||
if (!WatchFiles.Keys.Contains(dbName)) return;
|
||||
|
||||
var data = File.ReadAllText(e.FullPath);
|
||||
foreach (var line in data.Split('\n'))
|
||||
Log.Information("Database File Changed: {DbName}", dbName);
|
||||
|
||||
var data = new List<string>();
|
||||
|
||||
using var fh = File.OpenText(e.FullPath);
|
||||
while (!fh.EndOfStream)
|
||||
data.Add(fh.ReadLine() ?? string.Empty);
|
||||
|
||||
foreach (var line in data)
|
||||
{
|
||||
if (line == "") continue;
|
||||
var type = WatchFiles[dbName];
|
||||
|
|
@ -56,11 +64,27 @@ public class DBSyncWatcher
|
|||
private void HandleCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (e.ChangeType != WatcherChangeTypes.Created) return;
|
||||
var dbName = Path.GetFileName(e.FullPath);
|
||||
if (!WatchFiles.Keys.Contains(dbName)) return;
|
||||
var data = File.ReadAllText(e.FullPath);
|
||||
foreach (var line in data.Split('\n'))
|
||||
|
||||
while (Locked)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
var dbName = Path.GetFileName(e.FullPath);
|
||||
|
||||
if (!WatchFiles.Keys.Contains(dbName)) return;
|
||||
|
||||
Log.Information("Database File Created: {DbName}", dbName);
|
||||
|
||||
var data = new List<string>();
|
||||
using var fh = File.OpenText(e.FullPath);
|
||||
|
||||
while (!fh.EndOfStream)
|
||||
data.Add(fh.ReadLine() ?? string.Empty);
|
||||
|
||||
foreach (var line in data)
|
||||
{
|
||||
if (line == "") continue;
|
||||
var type = WatchFiles[dbName];
|
||||
OnDatabaseChange?.Invoke(dbName, line);
|
||||
}
|
||||
|
|
@ -68,6 +92,6 @@ public class DBSyncWatcher
|
|||
|
||||
private void HandleError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
Console.WriteLine("Error: {0}\n{1}", e.GetException().Message, e.GetException().StackTrace);
|
||||
Log.Error("Error: {Message}\n{StackTrace}", e.GetException().Message, e.GetException().StackTrace);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,8 @@ using System.Threading.Tasks;
|
|||
using FreeTubeSyncer.Library;
|
||||
using FreeTubeSyncer.Models.DatabaseModels;
|
||||
using RestSharp;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
|
||||
namespace FreeTubeSyncer.REST;
|
||||
|
||||
|
|
@ -68,34 +70,29 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
|
||||
public async Task<bool> PingApi()
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Pinging API at {_client.BuildUri(new RestRequest("/ping"))}...");
|
||||
Log.Information("Pinging API at {BuildUri}...", _client.BuildUri(new RestRequest("/ping")));
|
||||
try
|
||||
{
|
||||
var res = await _client.GetAsync<Ping>(new RestRequest("/ping"));
|
||||
if (res == null)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Ping returned null, not the server we are looking for!");
|
||||
Log.Information("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}");
|
||||
Log.Information("Server Online! {AppVersion}", res.AppVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Network Error: {ex.Message}, API not alive.");
|
||||
Log.Error("API not alive. Network Error: {Message}", ex.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine("Responded with something other then 404, API not what we expected.");
|
||||
|
||||
Log.Error("Responded with something other then Ping. This is not the server we are looking for...");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -128,8 +125,7 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
if (_entries.Any(x => x.EqualId(item.Id())))
|
||||
_entries.RemoveAll(x => x.EqualId(item.Id()));
|
||||
_entries.Add(item);
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Posting to REST: {item.Id()}");
|
||||
Log.Information("Posting to REST: {ItemId}", item.Id());
|
||||
await _client.PostJsonAsync<T>(_restEndpoint, item);
|
||||
}
|
||||
}
|
||||
|
|
@ -147,15 +143,11 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
|
||||
if (data.Equals(entry)) continue;
|
||||
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Updated Entry from REST for {_dbName} - {entry.Id()}");
|
||||
Log.Information("Updated Entry from REST for {DbName} - {EntryId}", _dbName, entry.Id());
|
||||
_entries.RemoveAll(x => x.EqualId(entry.Id()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"New Entry from REST for {_dbName} - {entry.Id()}");
|
||||
}
|
||||
Log.Information("New Entry from REST for {DbName} - {EntryId}", _dbName, entry.Id());
|
||||
|
||||
_entries.Add(entry);
|
||||
_isDirty = true;
|
||||
|
|
@ -186,8 +178,8 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
}
|
||||
catch (Exception iex)
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Failed to parse line: {entryObject}\nMessage: {iex.Message}");
|
||||
Log.Error("Failed to parse line: {EntryLine}", entryObject);
|
||||
Log.Error("Error Message: {Messsage}", iex.Message);
|
||||
entry = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -199,15 +191,11 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
{
|
||||
var data = _entries.First(x => x.EqualId(entry.Id()));
|
||||
if (data.Equals(entry)) return;
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"File Entry {entry.Id()} updated for {_dbName}");
|
||||
Log.Information("Updated File Entry {EntryId} updated for {DbName}", entry.Id(), _dbName);
|
||||
_entries.RemoveAll(x => x.EqualId(entry.Id()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"New File Entry {entry.Id()} for {_dbName}");
|
||||
}
|
||||
Log.Information("New File Entry {EntryId} for {DbName}", entry.Id(), _dbName);
|
||||
|
||||
_entries.Add(entry);
|
||||
await _client.PostJsonAsync<T>(_restEndpoint, entry);
|
||||
|
|
@ -219,8 +207,8 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
if (!_isDirty)
|
||||
return;
|
||||
_syncing = true;
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Syncing {_dbPath}...");
|
||||
Log.Information("Syncing {DbName}...", _dbPath);
|
||||
var start = DateTime.Now;
|
||||
var json = new List<string>();
|
||||
foreach (var entry in _entries)
|
||||
json.Add(entry.JsonData());
|
||||
|
|
@ -233,8 +221,7 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
|
|||
fh.Close();
|
||||
}
|
||||
_watcher.Locked = false;
|
||||
// TODO: Replace with Logger
|
||||
Console.WriteLine($"Updated {_dbPath}.");
|
||||
Log.Information("Updated {DbName}, completed in {TimeSpan}", _dbName, DateTime.Now - start);
|
||||
_isDirty = false;
|
||||
_syncing = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue