forked from sim0n00ps/OF-DL
Download Single Paid Message also download Preview Media
This commit is contained in:
parent
d5aa568afb
commit
bd0a2b6de6
@ -14,5 +14,8 @@ namespace OF_DL.Entities.Purchased
|
||||
public Dictionary<long, string> SingleMessages = new Dictionary<long, string>();
|
||||
public List<SingleMessage> SingleMessageObjects = new List<SingleMessage>();
|
||||
public List<Medium> SingleMessageMedia = new List<Medium>();
|
||||
|
||||
public Dictionary<long, string> PreviewSingleMessages = new Dictionary<long, string>();
|
||||
public List<Medium> PreviewSingleMessageMedia = new List<Medium>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1787,6 +1787,32 @@ public class APIHelper : IAPIHelper
|
||||
singlePaidMessageCollection.SingleMessageMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
else if (messagePreviewIds.Contains(medium.id) && medium.canView && medium.files != null && medium.files.full != null && !string.IsNullOrEmpty(medium.files.full.url) && !medium.files.full.url.Contains("upload"))
|
||||
{
|
||||
if (medium.type == "photo" && !config.DownloadImages)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "video" && !config.DownloadVideos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "gif" && !config.DownloadVideos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "audio" && !config.DownloadAudios)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!singlePaidMessageCollection.PreviewSingleMessages.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, message.id, medium.files.full.url, null, null, null, "Messages", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), messagePreviewIds.Contains(medium.id) ? true : false, false, null);
|
||||
singlePaidMessageCollection.PreviewSingleMessages.Add(medium.id, medium.files.full.url.ToString());
|
||||
singlePaidMessageCollection.PreviewSingleMessageMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
else if (!messagePreviewIds.Contains(medium.id) && medium.canView && medium.files != null && medium.files.drm != null)
|
||||
{
|
||||
if (medium.type == "photo" && !config.DownloadImages)
|
||||
@ -1813,6 +1839,32 @@ public class APIHelper : IAPIHelper
|
||||
singlePaidMessageCollection.SingleMessageMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
else if (messagePreviewIds.Contains(medium.id) && medium.canView && medium.files != null && medium.files.drm != null)
|
||||
{
|
||||
if (medium.type == "photo" && !config.DownloadImages)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "video" && !config.DownloadVideos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "gif" && !config.DownloadVideos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (medium.type == "audio" && !config.DownloadAudios)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!singlePaidMessageCollection.PreviewSingleMessages.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, message.id, medium.files.drm.manifest.dash, null, null, null, "Messages", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), messagePreviewIds.Contains(medium.id) ? true : false, false, null);
|
||||
singlePaidMessageCollection.PreviewSingleMessages.Add(medium.id, $"{medium.files.drm.manifest.dash},{medium.files.drm.signature.dash.CloudFrontPolicy},{medium.files.drm.signature.dash.CloudFrontSignature},{medium.files.drm.signature.dash.CloudFrontKeyPairId},{medium.id},{message.id}");
|
||||
singlePaidMessageCollection.PreviewSingleMessageMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using static OF_DL.Entities.Lists.UserList;
|
||||
using static OF_DL.Entities.Messages.Messages;
|
||||
using FromUser = OF_DL.Entities.Messages.FromUser;
|
||||
|
||||
namespace OF_DL.Helpers;
|
||||
|
||||
@ -659,7 +660,26 @@ public class DownloadHelper : IDownloadHelper
|
||||
Log.Debug("FFREPORT disabled (cwd: {Cwd})", Environment.CurrentDirectory);
|
||||
}
|
||||
|
||||
string parameters = $"{logLevelArgs} -cenc_decryption_key {decKey} -headers \"Cookie:CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {sess} Origin: https://onlyfans.com Referer: https://onlyfans.com User-Agent: {user_agent}\" -y -i \"{url}\" -map 0:v:{streamIndex} -map 0:a? -codec copy \"{tempFilename}\"".Trim();
|
||||
string cookieHeader =
|
||||
"Cookie: " +
|
||||
$"CloudFront-Policy={policy}; " +
|
||||
$"CloudFront-Signature={signature}; " +
|
||||
$"CloudFront-Key-Pair-Id={kvp}; " +
|
||||
$"{sess}";
|
||||
|
||||
string parameters =
|
||||
$"{logLevelArgs} " +
|
||||
$"-cenc_decryption_key {decKey} " +
|
||||
$"-headers \"{cookieHeader}\" " +
|
||||
$"-user_agent \"{user_agent}\" " +
|
||||
"-referer \"https://onlyfans.com\" " +
|
||||
"-rw_timeout 20000000 " +
|
||||
"-reconnect 1 -reconnect_streamed 1 -reconnect_on_network_error 1 -reconnect_delay_max 10 " +
|
||||
"-y " +
|
||||
$"-i \"{url}\" " +
|
||||
$"-map 0:v:{streamIndex} -map 0:a? " +
|
||||
"-c copy " +
|
||||
$"\"{tempFilename}\"";
|
||||
|
||||
Log.Debug($"Calling FFMPEG with Parameters: {parameters}");
|
||||
|
||||
@ -763,6 +783,23 @@ public class DownloadHelper : IDownloadHelper
|
||||
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename);
|
||||
}
|
||||
|
||||
public async Task<bool> DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Messages.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users)
|
||||
{
|
||||
string path;
|
||||
if (downloadConfig.FolderPerMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null)
|
||||
{
|
||||
path = $"/Messages/Free/{messageInfo.id} {messageInfo.createdAt.Value:yyyy-MM-dd HH-mm-ss}";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = "/Messages/Free";
|
||||
}
|
||||
Uri uri = new(url);
|
||||
string filename = System.IO.Path.GetFileNameWithoutExtension(uri.LocalPath);
|
||||
string resolvedFilename = await GenerateCustomFileName(filename, filenameFormat, messageInfo, messageMedia, fromUser, folder.Split("/")[^1], users, _FileNameHelper, CustomFileNameOption.ReturnOriginal);
|
||||
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename);
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> DownloadArchivedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Archived.List? messageInfo, Archived.Medium? messageMedia, Archived.Author? author, Dictionary<string, long> users)
|
||||
{
|
||||
@ -1116,6 +1153,113 @@ public class DownloadHelper : IDownloadHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> DownloadSingleMessagePreviewDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Messages.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users)
|
||||
{
|
||||
try
|
||||
{
|
||||
string customFileName = string.Empty;
|
||||
string path;
|
||||
Uri uri = new(url);
|
||||
string filename = System.IO.Path.GetFileName(uri.LocalPath).Split(".")[0];
|
||||
if (downloadConfig.FolderPerMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null)
|
||||
{
|
||||
path = $"/Messages/Free/{messageInfo.id} {messageInfo.createdAt.Value:yyyy-MM-dd HH-mm-ss}/Videos";
|
||||
}
|
||||
else
|
||||
{
|
||||
path = "/Messages/Free/Videos";
|
||||
}
|
||||
if (!Directory.Exists(folder + path))
|
||||
{
|
||||
Directory.CreateDirectory(folder + path);
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(filenameFormat) && messageInfo != null && messageMedia != null)
|
||||
{
|
||||
List<string> properties = new();
|
||||
string pattern = @"\{(.*?)\}";
|
||||
MatchCollection matches = Regex.Matches(filenameFormat, pattern);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
properties.Add(match.Groups[1].Value);
|
||||
}
|
||||
Dictionary<string, string> values = await _FileNameHelper.GetFilename(messageInfo, messageMedia, fromUser, properties, folder.Split("/")[^1],users);
|
||||
customFileName = await _FileNameHelper.BuildFilename(filenameFormat, values);
|
||||
}
|
||||
|
||||
if (!await m_DBHelper.CheckDownloaded(folder, media_id, api_type))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customFileName) ? !File.Exists(folder + path + "/" + customFileName + ".mp4") : !File.Exists(folder + path + "/" + filename + "_source.mp4"))
|
||||
{
|
||||
return await DownloadDrmMedia(auth.USER_AGENT, policy, signature, kvp, auth.COOKIE, url, decryptionKey, folder, lastModified, media_id, api_type, task, customFileName, filename, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
long fileSizeInBytes = new FileInfo(!string.IsNullOrEmpty(customFileName) ? folder + path + "/" + customFileName + ".mp4" : folder + path + "/" + filename + "_source.mp4").Length;
|
||||
if (downloadConfig.ShowScrapeSize)
|
||||
{
|
||||
task.Increment(fileSizeInBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
task.Increment(1);
|
||||
}
|
||||
await m_DBHelper.UpdateMedia(folder, media_id, api_type, folder + path, !string.IsNullOrEmpty(customFileName) ? customFileName + "mp4" : filename + "_source.mp4", fileSizeInBytes, true, lastModified);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customFileName))
|
||||
{
|
||||
if (downloadConfig.RenameExistingFilesWhenCustomFormatIsSelected && (filename + "_source" != customFileName))
|
||||
{
|
||||
string fullPathWithTheServerFileName = $"{folder}{path}/{filename}_source.mp4";
|
||||
string fullPathWithTheNewFileName = $"{folder}{path}/{customFileName}.mp4";
|
||||
if (!File.Exists(fullPathWithTheServerFileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
File.Move(fullPathWithTheServerFileName, fullPathWithTheNewFileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An error occurred: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
long size = await m_DBHelper.GetStoredFileSize(folder, media_id, api_type);
|
||||
await m_DBHelper.UpdateMedia(folder, media_id, api_type, folder + path, customFileName + ".mp4", size, true, lastModified);
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadConfig.ShowScrapeSize)
|
||||
{
|
||||
long size = await m_DBHelper.GetStoredFileSize(folder, media_id, api_type);
|
||||
task.Increment(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
task.Increment(1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
|
||||
Log.Error("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
Console.WriteLine("\nInner Exception:");
|
||||
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.InnerException.Message, ex.InnerException.StackTrace);
|
||||
Log.Error("Inner Exception: {0}\n\nStackTrace: {1}", ex.InnerException.Message, ex.InnerException.StackTrace);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> DownloadPurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? messageInfo, Medium? messageMedia, Purchased.FromUser? fromUser, Dictionary<string, long> users)
|
||||
{
|
||||
|
||||
@ -6,6 +6,7 @@ using OF_DL.Entities.Purchased;
|
||||
using OF_DL.Entities.Streams;
|
||||
using Spectre.Console;
|
||||
using static OF_DL.Entities.Messages.Messages;
|
||||
using FromUser = OF_DL.Entities.Messages.FromUser;
|
||||
|
||||
namespace OF_DL.Helpers
|
||||
{
|
||||
@ -32,5 +33,13 @@ namespace OF_DL.Helpers
|
||||
Task<bool> DownloadStoryMedia(string url, string folder, long media_id, string api_type, ProgressTask task);
|
||||
Task<bool> DownloadStreamMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, long> users);
|
||||
Task<bool> DownloadStreamsDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Streams.List streamInfo, Streams.Medium streamMedia, Streams.Author author, Dictionary<string, long> users);
|
||||
Task<bool> DownloadSingleMessagePreviewDRMVideo(string policy, string signature, string kvp, string url,
|
||||
string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type,
|
||||
ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia,
|
||||
FromUser? fromUser, Dictionary<string, long> users);
|
||||
|
||||
Task<bool> DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type,
|
||||
ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia,
|
||||
FromUser? fromUser, Dictionary<string, long> users);
|
||||
}
|
||||
}
|
||||
|
||||
114
OF DL/Program.cs
114
OF DL/Program.cs
@ -2559,8 +2559,122 @@ public class Program
|
||||
AnsiConsole.Markup($"[red]Getting Paid Message\n[/]");
|
||||
|
||||
SinglePaidMessageCollection singlePaidMessageCollection = await downloadContext.ApiHelper.GetPaidMessage($"/messages/{message_id.ToString()}", path, downloadContext.DownloadConfig!);
|
||||
int oldPreviewPaidMessagesCount = 0;
|
||||
int newPreviewPaidMessagesCount = 0;
|
||||
int oldPaidMessagesCount = 0;
|
||||
int newPaidMessagesCount = 0;
|
||||
if (singlePaidMessageCollection != null && singlePaidMessageCollection.PreviewSingleMessages.Count > 0)
|
||||
{
|
||||
AnsiConsole.Markup($"[red]Found {singlePaidMessageCollection.PreviewSingleMessages.Count} Preview Media from {singlePaidMessageCollection.SingleMessageObjects.Count} Paid Messages\n[/]");
|
||||
Log.Debug($"Found {singlePaidMessageCollection.PreviewSingleMessages.Count} Preview Media from {singlePaidMessageCollection.SingleMessageObjects.Count} Paid Messages");
|
||||
paidMessagesCount = singlePaidMessageCollection.SingleMessages.Count;
|
||||
long totalSize = 0;
|
||||
if (downloadContext.DownloadConfig.ShowScrapeSize)
|
||||
{
|
||||
totalSize = await downloadContext.DownloadHelper.CalculateTotalFileSize(singlePaidMessageCollection.PreviewSingleMessages.Values.ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
totalSize = paidMessagesCount;
|
||||
}
|
||||
await AnsiConsole.Progress()
|
||||
.Columns(GetProgressColumns(downloadContext.DownloadConfig.ShowScrapeSize))
|
||||
.StartAsync(async ctx =>
|
||||
{
|
||||
// Define tasks
|
||||
var task = ctx.AddTask($"[red]Downloading {singlePaidMessageCollection.PreviewSingleMessages.Count} Preview Paid Messages[/]", autoStart: false);
|
||||
Log.Debug($"Downloading {singlePaidMessageCollection.PreviewSingleMessages.Count} Paid Messages");
|
||||
task.MaxValue = totalSize;
|
||||
task.StartTask();
|
||||
foreach (KeyValuePair<long, string> paidMessageKVP in singlePaidMessageCollection.PreviewSingleMessages)
|
||||
{
|
||||
bool isNew;
|
||||
if (paidMessageKVP.Value.Contains("cdn3.onlyfans.com/dash/files"))
|
||||
{
|
||||
string[] messageUrlParsed = paidMessageKVP.Value.Split(',');
|
||||
string mpdURL = messageUrlParsed[0];
|
||||
string policy = messageUrlParsed[1];
|
||||
string signature = messageUrlParsed[2];
|
||||
string kvp = messageUrlParsed[3];
|
||||
string mediaId = messageUrlParsed[4];
|
||||
string messageId = messageUrlParsed[5];
|
||||
string? licenseURL = null;
|
||||
string? pssh = await downloadContext.ApiHelper.GetDRMMPDPSSH(mpdURL, policy, signature, kvp);
|
||||
if (pssh != null)
|
||||
{
|
||||
DateTime lastModified = await downloadContext.ApiHelper.GetDRMMPDLastModified(mpdURL, policy, signature, kvp);
|
||||
Dictionary<string, string> drmHeaders = downloadContext.ApiHelper.GetDynamicHeaders($"/api2/v2/users/media/{mediaId}/drm/message/{messageId}", "?type=widevine");
|
||||
string decryptionKey;
|
||||
if (clientIdBlobMissing || devicePrivateKeyMissing)
|
||||
{
|
||||
decryptionKey = await downloadContext.ApiHelper.GetDecryptionKeyOFDL(drmHeaders, $"https://onlyfans.com/api2/v2/users/media/{mediaId}/drm/message/{messageId}?type=widevine", pssh);
|
||||
}
|
||||
else
|
||||
{
|
||||
decryptionKey = await downloadContext.ApiHelper.GetDecryptionKeyCDM(drmHeaders, $"https://onlyfans.com/api2/v2/users/media/{mediaId}/drm/message/{messageId}?type=widevine", pssh);
|
||||
}
|
||||
|
||||
Medium? mediaInfo = singlePaidMessageCollection.PreviewSingleMessageMedia.FirstOrDefault(m => m.id == paidMessageKVP.Key);
|
||||
SingleMessage? messageInfo = singlePaidMessageCollection.SingleMessageObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true);
|
||||
|
||||
isNew = await downloadContext.DownloadHelper.DownloadSingleMessagePreviewDRMVideo(
|
||||
policy: policy,
|
||||
signature: signature,
|
||||
kvp: kvp,
|
||||
url: mpdURL,
|
||||
decryptionKey: decryptionKey,
|
||||
folder: path,
|
||||
lastModified: lastModified,
|
||||
media_id: paidMessageKVP.Key,
|
||||
api_type: "Messages",
|
||||
task: task,
|
||||
filenameFormat: downloadContext.FileNameFormatConfig.PaidMessageFileNameFormat ?? string.Empty,
|
||||
messageInfo: messageInfo,
|
||||
messageMedia: mediaInfo,
|
||||
fromUser: messageInfo?.fromUser,
|
||||
users: hasSelectedUsersKVP.Value);
|
||||
|
||||
if (isNew)
|
||||
{
|
||||
newPreviewPaidMessagesCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldPreviewPaidMessagesCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Medium? mediaInfo = singlePaidMessageCollection.PreviewSingleMessageMedia.FirstOrDefault(m => m.id == paidMessageKVP.Key);
|
||||
SingleMessage? messageInfo = singlePaidMessageCollection.SingleMessageObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true);
|
||||
|
||||
isNew = await downloadContext.DownloadHelper.DownloadMessagePreviewMedia(
|
||||
url: paidMessageKVP.Value,
|
||||
folder: path,
|
||||
media_id: paidMessageKVP.Key,
|
||||
api_type: "Messages",
|
||||
task: task,
|
||||
filenameFormat: downloadContext.FileNameFormatConfig.PaidMessageFileNameFormat ?? string.Empty,
|
||||
messageInfo: messageInfo,
|
||||
messageMedia: mediaInfo,
|
||||
fromUser: messageInfo?.fromUser,
|
||||
users: hasSelectedUsersKVP.Value);
|
||||
if (isNew)
|
||||
{
|
||||
newPreviewPaidMessagesCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldPreviewPaidMessagesCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
task.StopTask();
|
||||
});
|
||||
AnsiConsole.Markup($"[red]Preview Paid Messages Already Downloaded: {oldPreviewPaidMessagesCount} New Preview Paid Messages Downloaded: {newPreviewPaidMessagesCount}[/]\n");
|
||||
Log.Debug($"Preview Paid Messages Already Downloaded: {oldPreviewPaidMessagesCount} New Preview Paid Messages Downloaded: {newPreviewPaidMessagesCount}");
|
||||
}
|
||||
if (singlePaidMessageCollection != null && singlePaidMessageCollection.SingleMessages.Count > 0)
|
||||
{
|
||||
AnsiConsole.Markup($"[red]Found {singlePaidMessageCollection.SingleMessages.Count} Media from {singlePaidMessageCollection.SingleMessageObjects.Count} Paid Messages\n[/]");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user