wakka/Feels.cs
2025-05-17 19:17:45 -05:00

158 lines
5.1 KiB
C#

using Microsoft.UI.Xaml;
using Renci.SshNet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
using Windows.ApplicationModel.VoiceCommands;
using Windows.Storage.Search;
namespace wakka
{
public class FeelsPost
{
[JsonPropertyName("user")]
public required string User { get; set; }
[JsonPropertyName("path")]
public required string Path { get; set; }
[JsonPropertyName("m_time")]
public required long M_Time { get; set; }
[JsonPropertyName("reported_date")]
public required long ReportedDate { get; set; }
public string TimeString { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public int WordCount { get; set; } = 0;
}
public static class Feels
{
public static readonly ObservableCollection<FeelsPost> LoadedFeelsPosts = [];
private static DispatcherTimer? Timer = null;
private static List<List<FeelsPost>>? LoadTimeMetadata = null;
private static int CurrentChunk = 0;
public static void Initialize()
{
if (Timer == null)
StartTimer();
if (LoadTimeMetadata == null)
{
var feels = AllFeels();
if (feels != null)
{
LoadTimeMetadata = (List<List<FeelsPost>>)feels.Chunk(10).Select(chunk => chunk.ToList()).ToList();
LoadFeelsChunk();
}
}
}
public static void LoadFeelsChunk()
{
if (LoadTimeMetadata == null)
return;
var chunk = LoadTimeMetadata[CurrentChunk];
foreach (var feel in chunk)
{
ConstructFeel(feel);
LoadedFeelsPosts.Add(feel);
}
CurrentChunk++;
}
private static void StartTimer()
{
Timer = new DispatcherTimer();
Timer.Interval = TimeSpan.FromSeconds(20);
Timer.Tick += Timer_Tick;
Timer.Start();
}
private static void Timer_Tick(object? sender, object? e)
{
GetNewFeels();
}
public static void GetNewFeels()
{
var newFeels = FeelsAfter(LoadedFeelsPosts[0].M_Time);
if (newFeels != null)
{
var additions = new List<FeelsPost>();
foreach (var newFeel in newFeels)
{
ConstructFeel(newFeel);
FeelsPost? toRemove = null;
foreach (var liveFeel in LoadedFeelsPosts)
{
if (liveFeel.Path.Equals(newFeel.Path))
{
toRemove = liveFeel;
break;
}
}
if (toRemove != null)
LoadedFeelsPosts.Remove(toRemove);
additions.Add(newFeel);
}
additions.Reverse();
foreach (var feel in additions)
{
LoadedFeelsPosts.Insert(0, feel);
}
}
}
public static string GetTodayFeelPath()
{
var dateString = DateTime.Now.ToString("yyyyMMdd");
return $"/home/{SshConnection.User}/.ttbp/entries/{dateString}.txt";
}
public static string GetTodayFeelBody()
{
return SshConnection.RunCommand($"cat {GetTodayFeelPath()}");
}
public static void PostFeel(string body)
{
SshConnection.RunCommandWithInput($"cat > {GetTodayFeelPath()}", body);
}
public static List<FeelsPost>? AllFeels()
{
return JsonSerializer.Deserialize<List<FeelsPost>>(SshConnection.RunCommand("~nebula/bin/dumpfeels"));
}
public static List<FeelsPost>? FeelsAfter(long TimeStamp)
{
return JsonSerializer.Deserialize<List<FeelsPost>>(SshConnection.RunCommand($"~nebula/bin/dumpfeels --after {TimeStamp}"));
}
public static List<FeelsPost>? FeelsFromUser(string User, List<FeelsPost> Feels)
{
return Feels.FindAll(i => i.User == User);
}
public static string GetFeelsBody(FeelsPost Post)
{
return SshConnection.RunCommand($"cat {Post.Path}");
}
private static void ConstructFeel(FeelsPost feel)
{
var date = DateTimeOffset.FromUnixTimeSeconds(feel.M_Time).DateTime.ToLocalTime();
feel.TimeString = date.ToString("HH:mm (dddd, MMMM dd, yyyy)");
var body = GetFeelsBody(feel);
char[] delimiters = new char[] { ' ', '\n' };
feel.WordCount = body.Split(delimiters, StringSplitOptions.RemoveEmptyEntries).Length;
feel.Body = body;
}
}
}