Updated Code

Fixed possible issue where integers were both strings and ints.  Now
properly converting them to integers to be stored.
Fixed issue where lengths were being reported as either integers, or
String stamps.  Now properly converting to string stamps to integers.
This commit is contained in:
Mario Steele 2025-07-22 17:05:17 -05:00
parent 24fae2b7ac
commit 595c93f50e
4 changed files with 83 additions and 1 deletions

View file

@ -0,0 +1,12 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace FreeTubeSyncer.Library;
public static class GlobalJsonOptions
{
public static JsonSerializerOptions Options { get; } = new JsonSerializerOptions
{
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
}

View file

@ -0,0 +1,69 @@
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace FreeTubeSyncer.Library;
public class StringToLongJsonConverter : JsonConverter<long>
{
private readonly bool _writeValueAsString;
static string[] formats = {
@"m\:ss", @"mm\:ss"
};
public StringToLongJsonConverter(bool writeValueAsString)
{
_writeValueAsString = writeValueAsString;
}
/// <summary>
/// Reads long value from quoted string
/// </summary>
public override long Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
if (Utf8Parser.TryParse(span, out long number, out var bytesConsumed) && span.Length == bytesConsumed)
return number;
var strNumber = reader.GetString();
if (strNumber.Contains(':'))
{
TimeSpan tspan;
if (TimeSpan.TryParseExact(strNumber, formats, CultureInfo.InvariantCulture, out tspan))
return (long)tspan.TotalSeconds;
}
if (long.TryParse(strNumber, out number))
return number;
throw new InvalidOperationException($"{strNumber} is not a correct long value!")
{
/*
* Here is a source from internal const System.Text.Json.ThrowHelper.ExceptionSourceValueToRethrowAsJsonException
* to restore a detailed info about current json context (line number and path)
*/
Source = "System.Text.Json.Rethrowable"
};
}
return reader.GetInt64();
}
/// <summary>
/// Writes a long value as number if <see cref="_writeValueAsString" /> is false
/// or as string if <see cref="_writeValueAsString" /> is true
/// </summary>
public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
{
if (_writeValueAsString)
writer.WriteStringValue(value.ToString());
else
writer.WriteNumberValue(value);
}
}

View file

@ -20,6 +20,7 @@ class Program
[STAThread]
public static void Main(string[] args)
{
GlobalJsonOptions.Options.Converters.Add(new StringToLongJsonConverter(false));
var path = "/home/eumario/.var/app/io.freetubeapp.FreeTube/config/FreeTube/";
var dbWatcher = new DBSyncWatcher(path);
var historySyncer = new Syncer<History>(dbWatcher, Path.Join(path, "history.db"), "history.db", "/history");

View file

@ -38,7 +38,7 @@ public class Syncer<T> where T : class, IDataModel
if (entry == "") continue;
try
{
var item = JsonSerializer.Deserialize<T>(entry);
var item = JsonSerializer.Deserialize<T>(entry, GlobalJsonOptions.Options);
if (item == null) continue;
if (_entries.Any(x => x.EqualId(item.Id())))
_entries.RemoveAll(x => x.EqualId(item.Id()));