Initial commit to new repository
This commit is contained in:
132
src/AxCopilot/Handlers/JournalHandler.cs
Normal file
132
src/AxCopilot/Handlers/JournalHandler.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using AxCopilot.SDK;
|
||||
using AxCopilot.Services;
|
||||
using AxCopilot.Themes;
|
||||
|
||||
namespace AxCopilot.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 업무 일지 자동 생성 핸들러. "journal" 프리픽스로 사용합니다.
|
||||
/// UsageStatisticsService 데이터를 기반으로 오늘/지정일의 업무 요약을 자동 생성합니다.
|
||||
/// 예: journal → 오늘의 업무 일지 생성
|
||||
/// journal 2026-03-25 → 해당 날짜 일지
|
||||
/// Enter → 마크다운 형식으로 클립보드에 복사.
|
||||
/// </summary>
|
||||
public class JournalHandler : IActionHandler
|
||||
{
|
||||
public string? Prefix => "journal";
|
||||
|
||||
public PluginMetadata Metadata => new(
|
||||
"Journal",
|
||||
"업무 일지 자동 생성 — journal",
|
||||
"1.0",
|
||||
"AX");
|
||||
|
||||
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
||||
{
|
||||
var q = query.Trim();
|
||||
DateTime targetDate;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(q))
|
||||
targetDate = DateTime.Today;
|
||||
else if (DateTime.TryParse(q, out var parsed))
|
||||
targetDate = parsed.Date;
|
||||
else
|
||||
{
|
||||
return Task.FromResult<IEnumerable<LauncherItem>>(
|
||||
[
|
||||
new LauncherItem("날짜 형식 오류", "예: journal 2026-03-25 또는 journal (오늘)",
|
||||
null, null, Symbol: Symbols.Warning)
|
||||
]);
|
||||
}
|
||||
|
||||
// 날짜 범위 계산 (오늘~targetDate 간 차이)
|
||||
var daysAgo = (DateTime.Today - targetDate).Days;
|
||||
var allStats = UsageStatisticsService.GetStats(Math.Max(daysAgo + 1, 1));
|
||||
var stats = allStats.FirstOrDefault(s => s.Date == targetDate.ToString("yyyy-MM-dd"));
|
||||
var items = new List<LauncherItem>();
|
||||
|
||||
if (stats == null)
|
||||
{
|
||||
items.Add(new LauncherItem(
|
||||
$"{targetDate:yyyy-MM-dd} — 기록 없음",
|
||||
"해당 날짜의 사용 기록이 없습니다",
|
||||
null, null, Symbol: Symbols.Info));
|
||||
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
||||
}
|
||||
|
||||
// 요약 생성
|
||||
var activeHours = stats.ActiveSeconds / 3600.0;
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"## 업무 일지 — {targetDate:yyyy-MM-dd} ({targetDate:dddd})");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"- **PC 활성 시간**: {activeHours:F1}시간");
|
||||
sb.AppendLine($"- **런처 호출**: {stats.LauncherOpens}회");
|
||||
|
||||
if (stats.CommandUsage.Count > 0)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("### 사용한 명령어");
|
||||
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(10))
|
||||
sb.AppendLine($"- `{kv.Key}` — {kv.Value}회");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("---");
|
||||
sb.AppendLine($"*AX Copilot 자동 생성 · {DateTime.Now:HH:mm}*");
|
||||
|
||||
var journal = sb.ToString();
|
||||
|
||||
// 요약 카드
|
||||
var topCmds = stats.CommandUsage.OrderByDescending(x => x.Value).Take(3)
|
||||
.Select(x => x.Key);
|
||||
var cmdPreview = stats.CommandUsage.Count > 0
|
||||
? $"주요 명령: {string.Join(", ", topCmds)}"
|
||||
: "명령어 사용 기록 없음";
|
||||
|
||||
items.Add(new LauncherItem(
|
||||
$"{targetDate:yyyy-MM-dd} 업무 일지 — 클립보드로 복사",
|
||||
$"활성 {activeHours:F1}h · 런처 {stats.LauncherOpens}회 · {cmdPreview}",
|
||||
null, journal,
|
||||
Symbol: Symbols.Note));
|
||||
|
||||
items.Add(new LauncherItem(
|
||||
$"PC 활성 시간: {activeHours:F1}시간",
|
||||
"잠금 해제 시간 기준 누적",
|
||||
null, $"PC 활성 시간: {activeHours:F1}시간",
|
||||
Symbol: Symbols.Clock));
|
||||
|
||||
items.Add(new LauncherItem(
|
||||
$"런처 호출: {stats.LauncherOpens}회",
|
||||
"Alt+Space 또는 트레이 클릭",
|
||||
null, $"런처 호출: {stats.LauncherOpens}회",
|
||||
Symbol: Symbols.Search));
|
||||
|
||||
if (stats.CommandUsage.Count > 0)
|
||||
{
|
||||
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(5))
|
||||
{
|
||||
items.Add(new LauncherItem(
|
||||
$"{kv.Key} — {kv.Value}회",
|
||||
"Enter로 복사",
|
||||
null, $"{kv.Key}: {kv.Value}회",
|
||||
Symbol: Symbols.Terminal));
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
||||
{
|
||||
if (item.Data is string text && !string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
try { Application.Current?.Dispatcher.Invoke(() => Clipboard.SetText(text)); }
|
||||
catch { }
|
||||
NotificationService.Notify("업무 일지", "클립보드에 복사되었습니다");
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user