- 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>
101 lines
3.0 KiB
C#
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();
|
|
}
|
|
}
|