diff --git a/OF DL.Core/Services/DownloadOrchestrationService.cs b/OF DL.Core/Services/DownloadOrchestrationService.cs index c821c31..2a27c79 100644 --- a/OF DL.Core/Services/DownloadOrchestrationService.cs +++ b/OF DL.Core/Services/DownloadOrchestrationService.cs @@ -433,7 +433,7 @@ public class DownloadOrchestrationService( : purchasedTabCollection.PaidPosts.PaidPosts.Count; DownloadResult postResult = await eventHandler.WithProgressAsync( - $"Downloading {purchasedTabCollection.PaidPosts.PaidPosts.Count} Paid Posts", + $"Downloading {purchasedTabCollection.PaidPosts.PaidPosts.Count} Media from {purchasedTabCollection.PaidPosts.PaidPostObjects.Count} Paid Posts", totalSize, config.ShowScrapeSize, async reporter => await downloadService.DownloadPaidPostsPurchasedTab( purchasedTabCollection.Username, path, users, @@ -461,7 +461,7 @@ public class DownloadOrchestrationService( : purchasedTabCollection.PaidMessages.PaidMessages.Count; DownloadResult msgResult = await eventHandler.WithProgressAsync( - $"Downloading {purchasedTabCollection.PaidMessages.PaidMessages.Count} Paid Messages", + $"Downloading {purchasedTabCollection.PaidMessages.PaidMessages.Count} Media from {purchasedTabCollection.PaidMessages.PaidMessageObjects.Count} Paid Messages", totalSize, config.ShowScrapeSize, async reporter => await downloadService.DownloadPaidMessagesPurchasedTab( purchasedTabCollection.Username, path, users, @@ -502,48 +502,77 @@ public class DownloadOrchestrationService( PurchasedEntities.SinglePaidMessageCollection singlePaidMessageCollection = await apiService.GetPaidMessage($"/messages/{messageId}", path); - if (singlePaidMessageCollection.SingleMessages.Count == 0) + if (singlePaidMessageCollection.SingleMessages.Count == 0 && + singlePaidMessageCollection.PreviewSingleMessages.Count == 0) { eventHandler.OnNoContentFound("Paid Messages"); return; } Config config = configService.CurrentConfig; + int messageCount = singlePaidMessageCollection.SingleMessageObjects.Count; + string messageLabel = messageCount == 1 ? "Paid Message" : "Paid Messages"; + int previewCount = singlePaidMessageCollection.PreviewSingleMessages.Count; + int paidCount = singlePaidMessageCollection.SingleMessages.Count; + int totalCount = previewCount + paidCount; - // Handle preview messages - if (singlePaidMessageCollection.PreviewSingleMessages.Count > 0) + // Handle mixed paid + preview message media. + if (previewCount > 0 && paidCount > 0) + { + eventHandler.OnContentFound("Paid Messages", + totalCount, + singlePaidMessageCollection.SingleMessageObjects.Count); + + List allMessageUrls = []; + allMessageUrls.AddRange(singlePaidMessageCollection.PreviewSingleMessages.Values); + allMessageUrls.AddRange(singlePaidMessageCollection.SingleMessages.Values); + + long totalSize = config.ShowScrapeSize + ? await downloadService.CalculateTotalFileSize(allMessageUrls) + : totalCount; + + DownloadResult result = await eventHandler.WithProgressAsync( + $"Downloading {totalCount} Media from {messageCount} {messageLabel} ({paidCount} Paid + {previewCount} Preview)", + totalSize, config.ShowScrapeSize, + async reporter => await downloadService.DownloadSinglePaidMessage(username, path, users, + clientIdBlobMissing, devicePrivateKeyMissing, singlePaidMessageCollection, reporter)); + + eventHandler.OnDownloadComplete("Paid Messages", result); + } + // Handle preview-only message media. + else if (previewCount > 0) { eventHandler.OnContentFound("Preview Paid Messages", - singlePaidMessageCollection.PreviewSingleMessages.Count, + previewCount, singlePaidMessageCollection.SingleMessageObjects.Count); long previewSize = config.ShowScrapeSize ? await downloadService.CalculateTotalFileSize( singlePaidMessageCollection.PreviewSingleMessages.Values.ToList()) - : singlePaidMessageCollection.PreviewSingleMessages.Count; + : previewCount; DownloadResult previewResult = await eventHandler.WithProgressAsync( - $"Downloading {singlePaidMessageCollection.PreviewSingleMessages.Count} Preview Paid Messages", + $"Downloading {previewCount} Preview Media from {messageCount} {messageLabel}", previewSize, config.ShowScrapeSize, async reporter => await downloadService.DownloadSinglePaidMessage(username, path, users, clientIdBlobMissing, devicePrivateKeyMissing, singlePaidMessageCollection, reporter)); eventHandler.OnDownloadComplete("Paid Messages", previewResult); } - else if (singlePaidMessageCollection.SingleMessages.Count > 0) + else if (paidCount > 0) { // Only actual paid messages, no preview eventHandler.OnContentFound("Paid Messages", - singlePaidMessageCollection.SingleMessages.Count, + paidCount, singlePaidMessageCollection.SingleMessageObjects.Count); long totalSize = config.ShowScrapeSize ? await downloadService.CalculateTotalFileSize( singlePaidMessageCollection.SingleMessages.Values.ToList()) - : singlePaidMessageCollection.SingleMessages.Count; + : paidCount; DownloadResult result = await eventHandler.WithProgressAsync( - $"Downloading {singlePaidMessageCollection.SingleMessages.Count} Paid Messages", + $"Downloading {paidCount} Paid Media from {messageCount} {messageLabel}", totalSize, config.ShowScrapeSize, async reporter => await downloadService.DownloadSinglePaidMessage(username, path, users, clientIdBlobMissing, devicePrivateKeyMissing, singlePaidMessageCollection, reporter)); @@ -607,7 +636,7 @@ public class DownloadOrchestrationService( : mediaCount; DownloadResult result = await eventHandler.WithProgressAsync( - $"Downloading {mediaCount} {contentType}", totalSize, config.ShowScrapeSize, + $"Downloading {mediaCount} Media from {objectCount} {contentType}", totalSize, config.ShowScrapeSize, async reporter => await downloadData(data, reporter)); eventHandler.OnDownloadComplete(contentType, result); diff --git a/OF DL.Core/Services/DownloadService.cs b/OF DL.Core/Services/DownloadService.cs index 631fb20..5fedd5a 100644 --- a/OF DL.Core/Services/DownloadService.cs +++ b/OF DL.Core/Services/DownloadService.cs @@ -146,10 +146,10 @@ public class DownloadService( if (logLevelArgs.Contains("-report", StringComparison.OrdinalIgnoreCase)) { - // Direct ffmpeg report files into the same logs directory Serilog uses (relative to current working directory) - string logDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "logs")); + // Use a relative path so FFREPORT parsing works on Windows (drive-letter ':' breaks option parsing). + string logDir = Path.Combine(Environment.CurrentDirectory, "logs"); Directory.CreateDirectory(logDir); - string ffReportPath = Path.Combine(logDir, "ffmpeg-%p-%t.log"); // ffmpeg will replace %p/%t + string ffReportPath = Path.Combine("logs", "ffmpeg-%p-%t.log").Replace("\\", "/"); Environment.SetEnvironmentVariable("FFREPORT", $"file={ffReportPath}:level=32"); Log.Debug("FFREPORT enabled at: {FFREPORT} (cwd: {Cwd})", Environment.GetEnvironmentVariable("FFREPORT"), Environment.CurrentDirectory); diff --git a/OF DL.Tests/Services/DownloadOrchestrationServiceTests.cs b/OF DL.Tests/Services/DownloadOrchestrationServiceTests.cs index 9167b52..1e04fb9 100644 --- a/OF DL.Tests/Services/DownloadOrchestrationServiceTests.cs +++ b/OF DL.Tests/Services/DownloadOrchestrationServiceTests.cs @@ -196,7 +196,7 @@ public class DownloadOrchestrationServiceTests await service.DownloadSinglePaidMessageAsync("creator", 5, "/tmp", new Dictionary(), true, true, eventHandler); - Assert.Contains(eventHandler.ContentFound, entry => entry.contentType == "Preview Paid Messages"); + Assert.Contains(eventHandler.ContentFound, entry => entry.contentType == "Paid Messages"); Assert.True(downloadService.SinglePaidMessageCalled); }