VideoStudy/VideoStudy.UI/Services/PersistenceService.cs
Ricardo Carneiro c49ec3d5a5 refactor: limpeza geral e troca de Puppeteer por FFmpeg
- Remove projetos mortos: VideoStudy.Native (MAUI), Controllers/LicenseController
- Remove serviços não usados: FFmpegService, HardwareIdService, LicenseManager,
  PdfGeneratorService, ScreenshotService, TranscriptionService do UI
- Remove dependências pesadas do UI: Whisper.net, YoutubeExplode, QuestPDF
- Remove PuppeteerSharp e SkiaSharp do API (150MB Chromium não é mais necessário)
- Screenshots agora usam FFmpeg diretamente (mais simples, mais confiável)
- YouTubeService reescrito para chamar /api/video-info em vez de YoutubeExplode
- Adiciona campo UserContext em AnalysisRequest (contexto livre do usuário)
- UI traduzida para português; aba de arquivo local removida (nunca funcionou)
- YouTubeProcessor simplificado: sem modo Advanced/Whisper
- GetYtDlpPath busca yt-dlp.exe subindo até 7 níveis de diretório
- Cookies do yt-dlp configuráveis via YtDlp:CookiesBrowser no appsettings
- Chave Groq agora lida de env var GROQ_API_KEY (appsettings.json sem segredos)
- VideoStudy.Linux (Photino) adicionado à solução como host multiplataforma
- yt-dlp atualizado de 2025.01.26 para 2026.03.17 (fix do nsig extraction)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 14:08:05 -03:00

101 lines
3.0 KiB
C#

using LiteDB;
using VideoStudy.Shared;
namespace VideoStudy.UI.Services;
public class PersistenceService
{
private readonly string _basePath;
private readonly string _dbPath;
public PersistenceService()
{
_basePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "MeuVideoStudy");
_dbPath = Path.Combine(_basePath, "videostudy.db");
if (!Directory.Exists(_basePath))
{
Directory.CreateDirectory(_basePath);
}
}
public string GetBasePath() => _basePath;
public List<string> GetFolders()
{
return Directory.GetDirectories(_basePath)
.Select(Path.GetFileName)
.Where(name => name != null)
.ToList()!;
}
public void CreateFolder(string folderName)
{
var path = Path.Combine(_basePath, folderName);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
public void RenameFolder(string oldName, string newName)
{
var oldPath = Path.Combine(_basePath, oldName);
var newPath = Path.Combine(_basePath, newName);
if (Directory.Exists(oldPath) && !Directory.Exists(newPath))
{
Directory.Move(oldPath, newPath);
}
}
public async Task<VideoStudySession> SaveSessionAsync(byte[] pdfData, string title, string? youtubeId, string folderName = "Geral")
{
var folderPath = Path.Combine(_basePath, folderName);
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
var safeTitle = string.Join("_", title.Split(Path.GetInvalidFileNameChars()));
var fileName = $"{safeTitle}_{DateTime.Now:yyyyMMdd_HHmmss}.pdf";
var filePath = Path.Combine(folderPath, fileName);
await File.WriteAllBytesAsync(filePath, pdfData);
using var db = new LiteDatabase(_dbPath);
var collection = db.GetCollection<VideoStudySession>("sessions");
var session = new VideoStudySession
{
Title = title,
YouTubeId = youtubeId ?? "local",
FilePath = filePath,
FolderName = folderName,
CreatedAt = DateTime.Now
};
collection.Insert(session);
collection.EnsureIndex(x => x.Title);
return session;
}
public List<VideoStudySession> GetAllSessions()
{
using var db = new LiteDatabase(_dbPath);
return db.GetCollection<VideoStudySession>("sessions")
.FindAll()
.OrderByDescending(x => x.CreatedAt)
.ToList();
}
public List<VideoStudySession> GetSessionsByFolder(string folderName)
{
using var db = new LiteDatabase(_dbPath);
return db.GetCollection<VideoStudySession>("sessions")
.Find(x => x.FolderName == folderName)
.OrderByDescending(x => x.CreatedAt)
.ToList();
}
}