Upload via GUI (186 Dateien)
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace DeskCore;
|
||||
|
||||
public class UsageEntry
|
||||
{
|
||||
public int Count { get; set; }
|
||||
public DateTime Last { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merkt sich, was wie oft und wann zuletzt über DeskCore gestartet wurde (für „Meistgenutzt“, „Zuletzt benutzt“
|
||||
/// und die Schnellstart-Suche). Liegt getrennt von den Einstellungen in usage.json, weil es sich ständig ändert.
|
||||
/// </summary>
|
||||
public static class Usage
|
||||
{
|
||||
/// <summary>Schlüssel-Präfix für Start-Gruppen (die keinen Dateipfad haben).</summary>
|
||||
public const string GroupPrefix = "gruppe:";
|
||||
|
||||
private static readonly string FilePath = Path.Combine(AppSettings.Folder, "usage.json");
|
||||
private static readonly Dictionary<string, UsageEntry> _data = Load();
|
||||
private static DispatcherTimer? _saveTimer;
|
||||
|
||||
/// <summary>Etwas wurde gestartet (z. B. damit „Zuletzt benutzt“-Boxen sich aktualisieren).</summary>
|
||||
public static event Action? Changed;
|
||||
|
||||
private static Dictionary<string, UsageEntry> Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(FilePath) &&
|
||||
JsonSerializer.Deserialize<Dictionary<string, UsageEntry>>(File.ReadAllText(FilePath)) is { } d)
|
||||
return new(d, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { }
|
||||
return new(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>Programm/Datei starten und den Start mitzählen. Wirft bei Fehlern wie Process.Start.</summary>
|
||||
public static void Start(string path)
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
|
||||
Record(path);
|
||||
}
|
||||
|
||||
public static void Record(string key)
|
||||
{
|
||||
if (!_data.TryGetValue(key, out var e)) _data[key] = e = new UsageEntry();
|
||||
e.Count++;
|
||||
e.Last = DateTime.Now;
|
||||
ScheduleSave();
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
public static int Count(string key) => _data.TryGetValue(key, out var e) ? e.Count : 0;
|
||||
|
||||
/// <summary>
|
||||
/// Wie „beliebt“ etwas ist: Anzahl der Starts, mit der Zeit abnehmend gewichtet –
|
||||
/// was du früher oft, aber seit Wochen nicht mehr benutzt hast, rutscht langsam nach hinten.
|
||||
/// </summary>
|
||||
public static double Score(string key)
|
||||
{
|
||||
if (!_data.TryGetValue(key, out var e)) return 0;
|
||||
double days = Math.Max(0, (DateTime.Now - e.Last).TotalDays);
|
||||
return e.Count / (1 + days / 30);
|
||||
}
|
||||
|
||||
/// <summary>Zuletzt gestartete Dateien, die es noch gibt (neueste zuerst).</summary>
|
||||
public static List<string> Recent(int max) => _data
|
||||
.Where(kv => !kv.Key.StartsWith(GroupPrefix) && (File.Exists(kv.Key) || Directory.Exists(kv.Key)))
|
||||
.OrderByDescending(kv => kv.Value.Last)
|
||||
.Take(max)
|
||||
.Select(kv => kv.Key)
|
||||
.ToList();
|
||||
|
||||
/// <summary>Datei wurde umbenannt/verschoben → Zählung mitnehmen.</summary>
|
||||
public static void Rename(string oldKey, string newKey)
|
||||
{
|
||||
if (!_data.Remove(oldKey, out var e)) return;
|
||||
if (_data.TryGetValue(newKey, out var existing))
|
||||
{
|
||||
existing.Count += e.Count;
|
||||
if (e.Last > existing.Last) existing.Last = e.Last;
|
||||
}
|
||||
else _data[newKey] = e;
|
||||
ScheduleSave();
|
||||
}
|
||||
|
||||
public static void Forget(string key)
|
||||
{
|
||||
if (_data.Remove(key)) { ScheduleSave(); Changed?.Invoke(); }
|
||||
}
|
||||
|
||||
private static void ScheduleSave()
|
||||
{
|
||||
_saveTimer ??= new DispatcherTimer(TimeSpan.FromSeconds(2), DispatcherPriority.Background, (_, _) => Flush(),
|
||||
Dispatcher.CurrentDispatcher);
|
||||
_saveTimer.Stop();
|
||||
_saveTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>Sofort speichern (z. B. beim Beenden).</summary>
|
||||
public static void Flush()
|
||||
{
|
||||
_saveTimer?.Stop();
|
||||
try
|
||||
{
|
||||
// Nicht mehr vorhandene Einträge, die lange nicht benutzt wurden, aufräumen
|
||||
foreach (var key in _data.Where(kv => kv.Value.Last < DateTime.Now.AddDays(-180) && !kv.Key.StartsWith(GroupPrefix)
|
||||
&& !File.Exists(kv.Key) && !Directory.Exists(kv.Key)).Select(kv => kv.Key).ToList())
|
||||
_data.Remove(key);
|
||||
Directory.CreateDirectory(AppSettings.Folder);
|
||||
File.WriteAllText(FilePath, JsonSerializer.Serialize(_data));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user