feat(ads/seo/release): v1.2.0 with live Google Ads, isolated ad profile, ads.txt, and SEO/AEO/GEO optimization
This commit is contained in:
parent
a88aafa1e5
commit
0e568f1f0a
975 changed files with 130593 additions and 16783 deletions
125
tests/Paca.Tests/Infrastructure/GrandUnifiedPipeline.cs
Normal file
125
tests/Paca.Tests/Infrastructure/GrandUnifiedPipeline.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
using System.IO;
|
||||
using Paca.App.Core;
|
||||
using Paca.App.ViewModels;
|
||||
using Paca.Browser;
|
||||
using Paca.Browser.Tabs;
|
||||
using Paca.Core.Config;
|
||||
using Paca.Core.Detection;
|
||||
using Paca.Core.Platform;
|
||||
using Paca.Core.Utils;
|
||||
|
||||
namespace Paca.Tests.Infrastructure;
|
||||
|
||||
public sealed class MockPipelineProcessRunner : IProcessRunner
|
||||
{
|
||||
public List<ProcessSpec> Specs { get; } = new();
|
||||
|
||||
public Task<ProcessResult> RunAsync(ProcessSpec spec, Action<string, string>? onLine, CancellationToken ct)
|
||||
{
|
||||
Specs.Add(spec);
|
||||
return Task.FromResult(new ProcessResult(0, "OK", ""));
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MockPipelineCloudStorageClient : ICloudStorageClient
|
||||
{
|
||||
public List<string> UploadedList { get; } = new();
|
||||
|
||||
public Task<bool> UploadAsync(string localFilePath, string remoteDestination, Action<long, long>? onProgress, CancellationToken ct)
|
||||
{
|
||||
UploadedList.Add($"{localFilePath} -> {remoteDestination}");
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<bool> ExistsAsync(string remoteDestination, CancellationToken ct)
|
||||
{
|
||||
return Task.FromResult(UploadedList.Any(u => u.EndsWith(remoteDestination)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 40개 마일스톤 전 영역 통합 오케스트레이션 파이프라인 하네스.
|
||||
/// </summary>
|
||||
public sealed class GrandUnifiedPipeline : IDisposable
|
||||
{
|
||||
public string TempDir { get; }
|
||||
public AppConfig Config { get; }
|
||||
public TabManager TabManager { get; }
|
||||
public AdBlockRuleEngine AdBlockEngine { get; }
|
||||
public MemoryTurboGuard MemoryGuard { get; }
|
||||
public DownloadManager DownloadManager { get; }
|
||||
public VideoDeduplicator Deduplicator { get; }
|
||||
public QoSTrafficShaper TrafficShaper { get; }
|
||||
public ChaosMonkeyStressDefense ChaosDefense { get; }
|
||||
public AudioNormalizer AudioNormalizer { get; }
|
||||
public HdrToneMapper HdrToneMapper { get; }
|
||||
public ChapterSplitter ChapterSplitter { get; }
|
||||
public DualSubtitleEngine DualSubtitleEngine { get; }
|
||||
public CloudSyncGateway CloudGateway { get; }
|
||||
public MockPipelineProcessRunner ProcessRunner { get; }
|
||||
public MockPipelineCloudStorageClient CloudClient { get; }
|
||||
|
||||
private readonly List<DownloadItemViewModel> _detectedItems = new();
|
||||
|
||||
private GrandUnifiedPipeline()
|
||||
{
|
||||
TempDir = Path.Combine(Path.GetTempPath(), "VD_Grand_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(TempDir);
|
||||
|
||||
Config = new AppConfig
|
||||
{
|
||||
OutputFolder = Path.Combine(TempDir, "downloads")
|
||||
};
|
||||
Directory.CreateDirectory(Config.OutputFolder);
|
||||
|
||||
ProcessRunner = new MockPipelineProcessRunner();
|
||||
CloudClient = new MockPipelineCloudStorageClient();
|
||||
|
||||
TabManager = new TabManager(() => new TabItem(), _ => { });
|
||||
AdBlockEngine = new AdBlockRuleEngine();
|
||||
MemoryGuard = new MemoryTurboGuard(TimeSpan.FromMinutes(10));
|
||||
|
||||
DownloadManager = new DownloadManager(
|
||||
Config,
|
||||
_ => Task.FromResult(new List<Microsoft.Web.WebView2.Core.CoreWebView2Cookie>()),
|
||||
_ => { });
|
||||
|
||||
DownloadManager.ItemDetected += item => _detectedItems.Add(item);
|
||||
|
||||
Deduplicator = new VideoDeduplicator(maxHammingThreshold: 5);
|
||||
TrafficShaper = new QoSTrafficShaper(maxBandwidthBytesPerSec: 10_000_000);
|
||||
ChaosDefense = new ChaosMonkeyStressDefense(failureRate: 0.3);
|
||||
AudioNormalizer = new AudioNormalizer(ProcessRunner);
|
||||
HdrToneMapper = new HdrToneMapper(ProcessRunner);
|
||||
ChapterSplitter = new ChapterSplitter(ProcessRunner);
|
||||
DualSubtitleEngine = new DualSubtitleEngine();
|
||||
CloudGateway = new CloudSyncGateway(CloudClient);
|
||||
}
|
||||
|
||||
public static GrandUnifiedPipeline Create() => new();
|
||||
|
||||
public IReadOnlyList<DownloadItemViewModel> DetectedItems => _detectedItems;
|
||||
|
||||
public void SimulateWebRequest(string url, MediaKind? mediaKind = null, string? pageUrl = null)
|
||||
{
|
||||
var uri = new Uri(url);
|
||||
|
||||
// 1. 광고 차단 검사
|
||||
if (AdBlockEngine.ShouldBlock(uri))
|
||||
return;
|
||||
|
||||
// 2. 미디어 감지
|
||||
if (mediaKind.HasValue)
|
||||
{
|
||||
DownloadManager.OnDetected(new DetectionContext(url, pageUrl ?? "https://test.local", mediaKind.Value));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(TempDir))
|
||||
{
|
||||
try { Directory.Delete(TempDir, true); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue