Files
meeting-assistant/MeetingAssistant/Summary/BoundMeetingProjectResolver.cs
T
codex 689df3dbcb
PR and Push Build/Test / build-and-test (push) Successful in 10m54s
Fix past meeting summary tool edge cases
2026-05-29 10:38:31 +02:00

82 lines
2.6 KiB
C#

using MeetingAssistant.MeetingNotes;
using YamlDotNet.Serialization;
namespace MeetingAssistant.Summary;
public sealed record BoundMeetingProject(string Name, string Path);
public sealed class BoundMeetingProjectResolver
{
private static readonly IDeserializer YamlDeserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
private readonly MeetingAssistantOptions options;
public BoundMeetingProjectResolver(MeetingAssistantOptions options)
{
this.options = options;
}
public string ProjectsRoot => VaultPath.Resolve(options.Vault, options.Vault.ProjectsFolder);
public async Task<List<BoundMeetingProject>> GetBoundProjectsAsync(
MeetingSessionArtifacts artifacts,
CancellationToken cancellationToken = default)
{
if (!Directory.Exists(ProjectsRoot))
{
return [];
}
var projectNames = await ReadMeetingProjectNamesAsync(artifacts, cancellationToken);
if (projectNames.Count == 0)
{
return [];
}
return Directory.EnumerateDirectories(ProjectsRoot)
.Select(path => new BoundMeetingProject(Path.GetFileName(path), path))
.Where(project => projectNames.Contains(project.Name))
.OrderBy(project => project.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
}
public Task<HashSet<string>> ReadMeetingProjectNamesAsync(
MeetingSessionArtifacts artifacts,
CancellationToken cancellationToken = default)
{
return ReadMeetingProjectNamesAsync(artifacts.MeetingNotePath, cancellationToken);
}
private static async Task<HashSet<string>> ReadMeetingProjectNamesAsync(
string meetingNotePath,
CancellationToken cancellationToken)
{
if (!File.Exists(meetingNotePath))
{
return [];
}
var content = await File.ReadAllTextAsync(meetingNotePath, cancellationToken);
var document = MarkdownDocumentParser.SplitOptional(content);
if (!document.HasFrontmatter)
{
return [];
}
var frontmatter = YamlDeserializer.Deserialize<ProjectFrontmatter>(document.Frontmatter)
?? new ProjectFrontmatter();
return (frontmatter.Projects ?? [])
.Where(project => !string.IsNullOrWhiteSpace(project))
.Select(project => project.Trim())
.ToHashSet(StringComparer.OrdinalIgnoreCase);
}
private sealed class ProjectFrontmatter
{
[YamlMember(Alias = "projects")]
public List<string>? Projects { get; set; }
}
}