340 lines
10 KiB
C#
340 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Windows;
|
|
|
|
namespace AxCopilot.Services;
|
|
|
|
public static class QuoteService
|
|
{
|
|
private record FamousQuote(string Text, string Author);
|
|
|
|
private record MovieQuote(string Text, string Movie, int Year, string? Character, long? Audience);
|
|
|
|
private static readonly Lazy<string[]> _motivational = new Lazy<string[]>(LoadMotivational);
|
|
|
|
private static readonly Lazy<FamousQuote[]> _famous = new Lazy<FamousQuote[]>(LoadFamous);
|
|
|
|
private static readonly Lazy<string[]> _displaySemi = new Lazy<string[]>(() => LoadSimple("display_semiconductor.json"));
|
|
|
|
private static readonly Lazy<string[]> _itAi = new Lazy<string[]>(() => LoadSimple("it_ai.json"));
|
|
|
|
private static readonly Lazy<string[]> _science = new Lazy<string[]>(() => LoadSimple("science.json"));
|
|
|
|
private static readonly Lazy<string[]> _history = new Lazy<string[]>(() => LoadSimple("history.json"));
|
|
|
|
private static readonly Lazy<string[]> _english = new Lazy<string[]>(() => LoadSimple("english.json"));
|
|
|
|
private static readonly Lazy<MovieQuote[]> _movies = new Lazy<MovieQuote[]>(LoadMovies);
|
|
|
|
private static readonly Lazy<Dictionary<string, string[]>> _todayEvents = new Lazy<Dictionary<string, string[]>>(LoadTodayEvents);
|
|
|
|
public static readonly (string Key, string Label, Func<int> Count)[] Categories = new(string, string, Func<int>)[9]
|
|
{
|
|
("motivational", "격려 문구", () => _motivational.Value.Length),
|
|
("famous", "유명 명언", () => _famous.Value.Length),
|
|
("display_semiconductor", "디스플레이/반도체 상식", () => _displaySemi.Value.Length),
|
|
("it_ai", "IT, AI 기술", () => _itAi.Value.Length),
|
|
("science", "일반 과학", () => _science.Value.Length),
|
|
("history", "역사", () => _history.Value.Length),
|
|
("english", "생활영어", () => _english.Value.Length),
|
|
("movies", "드라마/영화 명대사", () => _movies.Value.Length),
|
|
("today_events", "오늘의 역사/기념일", () => GetTodayEventCount())
|
|
};
|
|
|
|
private static Dictionary<string, string[]>? _greetingsCache;
|
|
|
|
private static DateTime _greetingsCacheTime;
|
|
|
|
public static int TotalCount => _motivational.Value.Length + _famous.Value.Length + _displaySemi.Value.Length + _itAi.Value.Length + _science.Value.Length + _history.Value.Length + _english.Value.Length + _movies.Value.Length;
|
|
|
|
private static string[] LoadMotivational()
|
|
{
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/motivational.json");
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream == null)
|
|
{
|
|
return Array.Empty<string>();
|
|
}
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
return JsonSerializer.Deserialize<string[]>(streamReader.ReadToEnd()) ?? Array.Empty<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("격려 문구 로드 실패: " + ex.Message);
|
|
return Array.Empty<string>();
|
|
}
|
|
}
|
|
|
|
private static FamousQuote[] LoadFamous()
|
|
{
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/famous.json");
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream == null)
|
|
{
|
|
return Array.Empty<FamousQuote>();
|
|
}
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
JsonSerializerOptions options = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
return JsonSerializer.Deserialize<FamousQuote[]>(streamReader.ReadToEnd(), options) ?? Array.Empty<FamousQuote>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("명언 로드 실패: " + ex.Message);
|
|
return Array.Empty<FamousQuote>();
|
|
}
|
|
}
|
|
|
|
private static string[] LoadSimple(string fileName)
|
|
{
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/" + fileName);
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream == null)
|
|
{
|
|
return Array.Empty<string>();
|
|
}
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
return JsonSerializer.Deserialize<string[]>(streamReader.ReadToEnd()) ?? Array.Empty<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn(fileName + " 로드 실패: " + ex.Message);
|
|
return Array.Empty<string>();
|
|
}
|
|
}
|
|
|
|
private static MovieQuote[] LoadMovies()
|
|
{
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/movies.json");
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream == null)
|
|
{
|
|
return Array.Empty<MovieQuote>();
|
|
}
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
JsonSerializerOptions options = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
return JsonSerializer.Deserialize<MovieQuote[]>(streamReader.ReadToEnd(), options) ?? Array.Empty<MovieQuote>();
|
|
}
|
|
catch
|
|
{
|
|
return Array.Empty<MovieQuote>();
|
|
}
|
|
}
|
|
|
|
private static Dictionary<string, string[]> LoadTodayEvents()
|
|
{
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/today_events.json");
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream == null)
|
|
{
|
|
return new Dictionary<string, string[]>();
|
|
}
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
return JsonSerializer.Deserialize<Dictionary<string, string[]>>(streamReader.ReadToEnd()) ?? new Dictionary<string, string[]>();
|
|
}
|
|
catch
|
|
{
|
|
return new Dictionary<string, string[]>();
|
|
}
|
|
}
|
|
|
|
public static (string Text, string? Author) GetRandom(IEnumerable<string>? enabledCategories = null)
|
|
{
|
|
HashSet<string> hashSet = enabledCategories?.ToHashSet<string>(StringComparer.OrdinalIgnoreCase) ?? new HashSet<string> { "motivational" };
|
|
string timeGreeting = GetTimeGreeting();
|
|
if (hashSet.Contains("today_events"))
|
|
{
|
|
string key = DateTime.Now.ToString("MM-dd");
|
|
if (_todayEvents.Value.TryGetValue(key, out string[] value) && value.Length != 0)
|
|
{
|
|
string text = value[Random.Shared.Next(value.Length)];
|
|
return (Text: timeGreeting + text, Author: "오늘의 역사");
|
|
}
|
|
}
|
|
List<(string, string)> list = new List<(string, string)>();
|
|
if (hashSet.Contains("motivational"))
|
|
{
|
|
string[] value2 = _motivational.Value;
|
|
foreach (string item in value2)
|
|
{
|
|
list.Add((item, null));
|
|
}
|
|
}
|
|
if (hashSet.Contains("famous"))
|
|
{
|
|
FamousQuote[] value3 = _famous.Value;
|
|
foreach (FamousQuote famousQuote in value3)
|
|
{
|
|
list.Add((famousQuote.Text, famousQuote.Author));
|
|
}
|
|
}
|
|
if (hashSet.Contains("display_semiconductor"))
|
|
{
|
|
string[] value4 = _displaySemi.Value;
|
|
foreach (string item2 in value4)
|
|
{
|
|
list.Add((item2, "디스플레이/반도체"));
|
|
}
|
|
}
|
|
if (hashSet.Contains("it_ai"))
|
|
{
|
|
string[] value5 = _itAi.Value;
|
|
foreach (string item3 in value5)
|
|
{
|
|
list.Add((item3, "IT/AI"));
|
|
}
|
|
}
|
|
if (hashSet.Contains("science"))
|
|
{
|
|
string[] value6 = _science.Value;
|
|
foreach (string item4 in value6)
|
|
{
|
|
list.Add((item4, "과학"));
|
|
}
|
|
}
|
|
if (hashSet.Contains("history"))
|
|
{
|
|
string[] value7 = _history.Value;
|
|
foreach (string item5 in value7)
|
|
{
|
|
list.Add((item5, "역사"));
|
|
}
|
|
}
|
|
if (hashSet.Contains("english"))
|
|
{
|
|
string[] value8 = _english.Value;
|
|
foreach (string item6 in value8)
|
|
{
|
|
list.Add((item6, "생활영어"));
|
|
}
|
|
}
|
|
if (hashSet.Contains("movies"))
|
|
{
|
|
MovieQuote[] value9 = _movies.Value;
|
|
foreach (MovieQuote movieQuote in value9)
|
|
{
|
|
string value10 = ((movieQuote.Audience >= 10000000) ? " \ud83e\udd47" : ((movieQuote.Audience >= 7000000) ? " \ud83e\udd48" : ((movieQuote.Audience >= 5000000) ? " \ud83e\udd49" : "")));
|
|
string item7 = $"《{movieQuote.Movie}》({movieQuote.Year}){((movieQuote.Character != null) ? (" — " + movieQuote.Character) : "")}{value10}";
|
|
list.Add(("\"" + movieQuote.Text + "\"", item7));
|
|
}
|
|
}
|
|
if (list.Count == 0)
|
|
{
|
|
return (Text: timeGreeting + "오늘도 열심히 해주셔서 고맙습니다!", Author: null);
|
|
}
|
|
var (text2, item8) = list[Random.Shared.Next(list.Count)];
|
|
return (Text: timeGreeting + text2, Author: item8);
|
|
}
|
|
|
|
private static string GetTimeGreeting()
|
|
{
|
|
int hour = DateTime.Now.Hour;
|
|
string key;
|
|
if (hour < 9)
|
|
{
|
|
key = "morning";
|
|
}
|
|
else if (hour >= 12 && hour < 15)
|
|
{
|
|
key = "lunch";
|
|
}
|
|
else
|
|
{
|
|
if (hour < 18)
|
|
{
|
|
return "";
|
|
}
|
|
key = "evening";
|
|
}
|
|
Dictionary<string, string[]> dictionary = LoadGreetings();
|
|
if (dictionary.TryGetValue(key, out var value) && value.Length != 0)
|
|
{
|
|
return value[Random.Shared.Next(value.Length)] + "\n\n";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private static Dictionary<string, string[]> LoadGreetings()
|
|
{
|
|
if (_greetingsCache != null && (DateTime.Now - _greetingsCacheTime).TotalMinutes < 5.0)
|
|
{
|
|
return _greetingsCache;
|
|
}
|
|
JsonSerializerOptions options = new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
try
|
|
{
|
|
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "Quotes", "greetings.json");
|
|
if (File.Exists(path))
|
|
{
|
|
string json = File.ReadAllText(path, Encoding.UTF8);
|
|
Dictionary<string, string[]> dictionary = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json, options);
|
|
if (dictionary != null)
|
|
{
|
|
_greetingsCache = dictionary;
|
|
_greetingsCacheTime = DateTime.Now;
|
|
return dictionary;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("외부 인사문구 로드 실패: " + ex.Message);
|
|
}
|
|
try
|
|
{
|
|
Uri uriResource = new Uri("pack://application:,,,/Assets/Quotes/greetings.json");
|
|
Stream stream = Application.GetResourceStream(uriResource)?.Stream;
|
|
if (stream != null)
|
|
{
|
|
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
|
|
Dictionary<string, string[]> dictionary2 = JsonSerializer.Deserialize<Dictionary<string, string[]>>(streamReader.ReadToEnd(), options);
|
|
if (dictionary2 != null)
|
|
{
|
|
_greetingsCache = dictionary2;
|
|
_greetingsCacheTime = DateTime.Now;
|
|
return dictionary2;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
LogService.Warn("내장 인사문구 로드 실패: " + ex2.Message);
|
|
}
|
|
return _greetingsCache = new Dictionary<string, string[]>();
|
|
}
|
|
|
|
private static int GetTodayEventCount()
|
|
{
|
|
return _todayEvents.Value.Values.Sum((string[] v) => v.Length);
|
|
}
|
|
|
|
public static int GetTodayMatchCount()
|
|
{
|
|
string key = DateTime.Now.ToString("MM-dd");
|
|
string[] value;
|
|
return _todayEvents.Value.TryGetValue(key, out value) ? value.Length : 0;
|
|
}
|
|
}
|