68 lines
3 KiB
C#
68 lines
3 KiB
C#
using System.Text.Json;
|
|
|
|
namespace VideoDownloader.App.Browser;
|
|
|
|
/// <summary>즐겨찾기/히스토리 JSON 영속화 (%AppData%/VideoDownloader).
|
|
/// #5 저장/로드 실패를 조용 삼킴하지 않고 browserstore.log 에 기록하며,
|
|
/// 손상 파일은 백업 후 빈 목록을 반환(다음 저장이 원본을 덮어쓰는 데이터 손실 방지).</summary>
|
|
public static class BrowserStore
|
|
{
|
|
private static string Dir => Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "VideoDownloader");
|
|
private static string BookmarksPath => Path.Combine(Dir, "bookmarks.json");
|
|
private static string HistoryPath => Path.Combine(Dir, "history.json");
|
|
private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true };
|
|
|
|
public static List<Bookmark> LoadBookmarks()
|
|
{
|
|
try { if (File.Exists(BookmarksPath)) return JsonSerializer.Deserialize<List<Bookmark>>(File.ReadAllText(BookmarksPath)) ?? new(); }
|
|
catch (Exception e) { LogLoadFail(BookmarksPath, e); }
|
|
return new();
|
|
}
|
|
|
|
public static void SaveBookmarks(List<Bookmark> bookmarks)
|
|
{
|
|
try { Directory.CreateDirectory(Dir); File.WriteAllText(BookmarksPath, JsonSerializer.Serialize(bookmarks, JsonOpts)); }
|
|
catch (Exception e) { LogFail("저장", BookmarksPath, e); } // 디스크 가득/권한/잠금 → UI 스레드 전파 대신 로그
|
|
}
|
|
|
|
public static List<HistoryEntry> LoadHistory()
|
|
{
|
|
try { if (File.Exists(HistoryPath)) return JsonSerializer.Deserialize<List<HistoryEntry>>(File.ReadAllText(HistoryPath)) ?? new(); }
|
|
catch (Exception e) { LogLoadFail(HistoryPath, e); }
|
|
return new();
|
|
}
|
|
|
|
public static void SaveHistory(List<HistoryEntry> history)
|
|
{
|
|
try { Directory.CreateDirectory(Dir); File.WriteAllText(HistoryPath, JsonSerializer.Serialize(history, JsonOpts)); }
|
|
catch (Exception e) { LogFail("저장", HistoryPath, e); }
|
|
}
|
|
|
|
/// <summary>로드 실패(손상/권한/잠금) 시 원본을 .corrupt 백업한 뒤 로그.
|
|
/// 빈 목록을 반환하더라도 원본이 남아 다음 저장이 사용자 데이터를 덮어쓰지 않게 한다.</summary>
|
|
private static void LogLoadFail(string path, Exception e)
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(path))
|
|
File.Move(path, $"{path}.corrupt.{DateTime.Now:yyyyMMddHHmmss}.bak", overwrite: true);
|
|
}
|
|
catch { /* best-effort 백업 — 실패해도 계속 진행 */ }
|
|
LogFail("로드", path, e);
|
|
}
|
|
|
|
private static void LogFail(string op, string path, Exception e)
|
|
=> Log($"{op} 실패({Path.GetFileName(path)}): {e.GetType().Name}: {e.Message}");
|
|
|
|
private static void Log(string msg)
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Dir);
|
|
File.AppendAllText(Path.Combine(Dir, "browserstore.log"),
|
|
$"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {msg}{Environment.NewLine}");
|
|
}
|
|
catch { /* 로그마저 실패하면 조용히 */ }
|
|
}
|
|
}
|