Compare commits

...

3 commits

Author SHA1 Message Date
d4a9b88cc0 Updated program
Some minor fixes, will be getting rid of this in favor of UI setup.
2025-07-30 14:51:21 -05:00
7128bfad65 Updated Syncer
Removed reading database from file when starting up.
Changed writting to hand-written write, instead of using WriteAllLines()
static function on File.
2025-07-30 14:50:55 -05:00
73a54b91ff Update all Models
Made all models implement IEquatable<> generic, allowing for validating
of equality of data.
2025-07-30 14:49:59 -05:00
9 changed files with 208 additions and 14 deletions

View file

@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json; using System.Text.Json;
using FreeTubeSyncer.Library; using FreeTubeSyncer.Library;
@ -5,7 +6,7 @@ using FreeTubeSyncer.Library;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class History : IDataModel public class History : IDataModel, IEquatable<History>
{ {
public string _id { get; set; } = string.Empty; public string _id { get; set; } = string.Empty;
public string videoId { get; set; } = string.Empty; public string videoId { get; set; } = string.Empty;
@ -52,4 +53,45 @@ public class History : IDataModel
{ {
return JsonSerializer.Serialize(this); return JsonSerializer.Serialize(this);
} }
public bool Equals(History? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return _id == other._id && videoId == other.videoId && title == other.title && author == other.author &&
authorId == other.authorId && published == other.published && description == other.description &&
viewCount == other.viewCount && lengthSeconds == other.lengthSeconds &&
watchProgress.Equals(other.watchProgress) && timeWatched == other.timeWatched &&
isLive == other.isLive && type == other.type && lastViewedPlaylistType == other.lastViewedPlaylistType &&
lastViewedPlaylistItemId == other.lastViewedPlaylistItemId;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((History)obj);
}
public override int GetHashCode()
{
var hashCode = new HashCode();
hashCode.Add(_id);
hashCode.Add(videoId);
hashCode.Add(title);
hashCode.Add(author);
hashCode.Add(authorId);
hashCode.Add(published);
hashCode.Add(description);
hashCode.Add(viewCount);
hashCode.Add(lengthSeconds);
hashCode.Add(watchProgress);
hashCode.Add(timeWatched);
hashCode.Add(isLive);
hashCode.Add(type);
hashCode.Add(lastViewedPlaylistType);
hashCode.Add(lastViewedPlaylistItemId);
return hashCode.ToHashCode();
}
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json; using System.Text.Json;
@ -6,7 +7,7 @@ using FreeTubeSyncer.Library;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class Playlist : IDataModel public class Playlist : IDataModel, IEquatable<Playlist>
{ {
public string _id { get; set; } = string.Empty; public string _id { get; set; } = string.Empty;
public string playlistName { get; set; } = string.Empty; public string playlistName { get; set; } = string.Empty;
@ -34,4 +35,25 @@ public class Playlist : IDataModel
{ {
return JsonSerializer.Serialize(this); return JsonSerializer.Serialize(this);
} }
public bool Equals(Playlist? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return _id == other._id && playlistName == other.playlistName && @protected == other.@protected &&
videos.Equals(other.videos) && createdAt == other.createdAt && lastUpdatedAt == other.lastUpdatedAt;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Playlist)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(_id, playlistName, @protected, videos, createdAt, lastUpdatedAt);
}
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json; using System.Text.Json;
@ -6,7 +7,7 @@ using FreeTubeSyncer.Library;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class Profile : IDataModel public class Profile : IDataModel, IEquatable<Profile>
{ {
public string _id { get; set; } = string.Empty; public string _id { get; set; } = string.Empty;
public string name { get; set; } = string.Empty; public string name { get; set; } = string.Empty;
@ -32,4 +33,25 @@ public class Profile : IDataModel
{ {
return JsonSerializer.Serialize(this); return JsonSerializer.Serialize(this);
} }
public bool Equals(Profile? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return _id == other._id && name == other.name && bgColor == other.bgColor && textColor == other.textColor &&
subscriptions.Equals(other.subscriptions);
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Profile)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(_id, name, bgColor, textColor, subscriptions);
}
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json; using System.Text.Json;
using FreeTubeSyncer.Library; using FreeTubeSyncer.Library;
@ -5,7 +6,7 @@ using FreeTubeSyncer.Library;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class SearchHistory : IDataModel public class SearchHistory : IDataModel, IEquatable<SearchHistory>
{ {
public string _id { get; set; } = string.Empty; public string _id { get; set; } = string.Empty;
public long lastUpdatedAt { get; set; } public long lastUpdatedAt { get; set; }
@ -25,4 +26,24 @@ public class SearchHistory : IDataModel
{ {
return JsonSerializer.Serialize(this); return JsonSerializer.Serialize(this);
} }
public bool Equals(SearchHistory? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return _id == other._id && lastUpdatedAt == other.lastUpdatedAt;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((SearchHistory)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(_id, lastUpdatedAt);
}
} }

View file

@ -1,10 +1,11 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json; using System.Text.Json;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class Setting : IDataModel public class Setting : IDataModel, IEquatable<Setting>
{ {
#pragma warning disable CS8618 #pragma warning disable CS8618
public string _id { get; set; } = string.Empty; public string _id { get; set; } = string.Empty;
@ -23,4 +24,24 @@ public class Setting : IDataModel
{ {
return value; return value;
} }
public bool Equals(Setting? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return _id == other._id && value == other.value;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Setting)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(_id, value);
}
} }

View file

@ -1,11 +1,32 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class Subscription public class Subscription : IEquatable<Subscription>
{ {
public required string id { get; set; } public required string id { get; set; }
public required string name { get; set; } public required string name { get; set; }
public string? thumbnail { get; set; } public string? thumbnail { get; set; }
public bool Equals(Subscription? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return id == other.id && name == other.name && thumbnail == other.thumbnail;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Subscription)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(id, name, thumbnail);
}
} }

View file

@ -1,9 +1,10 @@
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace FreeTubeSyncer.Models.DatabaseModels; namespace FreeTubeSyncer.Models.DatabaseModels;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public class Video public class Video : IEquatable<Video>
{ {
public string videoId { get; set; } = string.Empty; public string videoId { get; set; } = string.Empty;
public string title { get; set; } = string.Empty; public string title { get; set; } = string.Empty;
@ -14,4 +15,36 @@ public class Video
public long timeAdded { get; set; } public long timeAdded { get; set; }
public string playlistItemId { get; set; } = string.Empty; public string playlistItemId { get; set; } = string.Empty;
public string type { get; set; } = string.Empty; public string type { get; set; } = string.Empty;
public bool Equals(Video? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return videoId == other.videoId && title == other.title && author == other.author &&
authorId == other.authorId && lengthSeconds == other.lengthSeconds && pubished == other.pubished &&
timeAdded == other.timeAdded && playlistItemId == other.playlistItemId && type == other.type;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Video)obj);
}
public override int GetHashCode()
{
var hashCode = new HashCode();
hashCode.Add(videoId);
hashCode.Add(title);
hashCode.Add(author);
hashCode.Add(authorId);
hashCode.Add(lengthSeconds);
hashCode.Add(pubished);
hashCode.Add(timeAdded);
hashCode.Add(playlistItemId);
hashCode.Add(type);
return hashCode.ToHashCode();
}
} }

View file

@ -61,12 +61,14 @@ class Program
settingsSyncer settingsSyncer
}; };
var lastTime = DateTime.Now; var lastTime = DateTime.Now;
var checkInterval = TimeSpan.FromSeconds(30);
while (true) while (true)
{ {
if (syncers.Any(x => x != null && x.IsDirty() )) if (syncers.Any(x => x != null && x.IsDirty() ))
{ {
Thread.Sleep(100); Thread.Sleep(100);
if (lastTime - DateTime.Now > TimeSpan.FromSeconds(30)) var lastCheck = DateTime.Now - lastTime;
if (lastCheck > checkInterval)
{ {
var start = DateTime.Now; var start = DateTime.Now;
Console.WriteLine("Checking for updates..."); Console.WriteLine("Checking for updates...");
@ -76,7 +78,9 @@ class Program
var end = DateTime.Now - start; var end = DateTime.Now - start;
Console.WriteLine($"Check completed. Total Time: {end}"); Console.WriteLine($"Check completed. Total Time: {end}");
} }
if (Process.GetProcessesByName("FreeTube").Length > 0) continue;
var procs = Process.GetProcessesByName("FreeTube");
if (procs.Length > 0) continue;
Console.WriteLine("FreeTube has closed and we have updates, we're going to try and update."); Console.WriteLine("FreeTube has closed and we have updates, we're going to try and update.");
Thread.Sleep(1500); Thread.Sleep(1500);
@ -94,7 +98,8 @@ class Program
else else
{ {
Thread.Sleep(100); Thread.Sleep(100);
if (lastTime - DateTime.Now <= TimeSpan.FromSeconds(30)) continue; var lastCheck = DateTime.Now - lastTime;
if (lastCheck < checkInterval) continue;
var start = DateTime.Now; var start = DateTime.Now;
Console.WriteLine("Checking for updates..."); Console.WriteLine("Checking for updates...");
foreach (var syncer in syncers) foreach (var syncer in syncers)

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -40,7 +41,6 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
_dbName = dbName; _dbName = dbName;
_restEndpoint = restEndpoint; _restEndpoint = restEndpoint;
FetchDatabase().Wait(); FetchDatabase().Wait();
ReadDatabase().Wait();
} }
public bool IsDirty() => _isDirty; public bool IsDirty() => _isDirty;
@ -84,11 +84,11 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
if (data.Equals(entry)) continue; if (data.Equals(entry)) continue;
Console.WriteLine($"Updated Entry for {_dbName}"); Console.WriteLine($"Updated Entry for {_dbName} - {entry.Id()}");
_entries.RemoveAll(x => x.EqualId(entry.Id())); _entries.RemoveAll(x => x.EqualId(entry.Id()));
} }
else else
Console.WriteLine($"New Entry for {_dbName}"); Console.WriteLine($"New Entry for {_dbName} - {entry.Id()}");
_entries.Add(entry); _entries.Add(entry);
_isDirty = true; _isDirty = true;
} }
@ -98,6 +98,7 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
{ {
if (dbName != _dbName) if (dbName != _dbName)
return; return;
if (_syncing) if (_syncing)
return; return;
@ -137,7 +138,13 @@ public class Syncer<T> : ISyncer where T : class, IDataModel, new()
var json = new List<string>(); var json = new List<string>();
foreach (var entry in _entries) foreach (var entry in _entries)
json.Add(entry.JsonData()); json.Add(entry.JsonData());
File.WriteAllLines(_dbPath, json); using (var fh = File.OpenWrite(_dbPath))
{
foreach (var line in json)
fh.Write(Encoding.UTF8.GetBytes(line + "\n"));
fh.Flush();
fh.Close();
}
Console.WriteLine($"Updated {_dbPath}."); Console.WriteLine($"Updated {_dbPath}.");
_isDirty = false; _isDirty = false;
_syncing = false; _syncing = false;