Compare commits
24 Commits
OFDLV1.9.7
...
master
Author | SHA1 | Date | |
---|---|---|---|
3a944c112d | |||
5e433f6568 | |||
cd60d3092d | |||
b36ecd4f5b | |||
f5ca6d8eb2 | |||
69be3607a0 | |||
0a34f81510 | |||
![]() |
8106f690e0 | ||
![]() |
442cc646d6 | ||
![]() |
e77f8abff6 | ||
ec751480e1 | |||
8578c40c20 | |||
b12ef22406 | |||
6a42dbe53e | |||
44890f51ee | |||
7f2849e5fd | |||
![]() |
21d0e37bda | ||
dd2b7cd82c | |||
4abbf1162d | |||
09c14be5dd | |||
0eb2a6dbeb | |||
530157bc85 | |||
f452fee64a | |||
3b1138d44c |
48
.gitea/workflows/publish-docker.yml
Normal file
@ -0,0 +1,48 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'OFDLV*'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: Build and push Docker image to Gitea Registry
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract tag name and version
|
||||
id: version
|
||||
run: |
|
||||
FULL_REF="${{ gitea.ref }}"
|
||||
TAG="${FULL_REF##refs/tags/}"
|
||||
VERSION="${TAG#OFDLV}"
|
||||
echo "Tag: $TAG"
|
||||
echo "Version: $VERSION"
|
||||
echo "tag=$TAG" >> "$GITEA_OUTPUT"
|
||||
echo "version=$VERSION" >> "$GITEA_OUTPUT"
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Gitea Docker Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.ofdl.tools
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
git.ofdl.tools/sim0n00ps/of-dl:latest
|
||||
git.ofdl.tools/sim0n00ps/of-dl:${{ steps.version.outputs.version }}
|
||||
build-args: |
|
||||
VERSION=${{ steps.version.outputs.version }}
|
36
.gitea/workflows/publish-docs.yml
Normal file
@ -0,0 +1,36 @@
|
||||
name: Publish docs
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'OFDLV*'
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- '.gitea/workflows/publish-docs.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Install MkDocs
|
||||
run: |
|
||||
pip install mkdocs-material
|
||||
|
||||
- name: Build site
|
||||
run: |
|
||||
mkdocs build --clean
|
||||
|
||||
- name: Deploy site
|
||||
run: |
|
||||
sudo rm -rf /var/www/mkdocs/*
|
||||
sudo cp -r site/* /var/www/mkdocs/
|
||||
sudo chown -R www-data:www-data /var/www/mkdocs/
|
5
.gitignore
vendored
@ -367,4 +367,7 @@ FodyWeavers.xsd
|
||||
/OF DL/device_private_key
|
||||
|
||||
# Allow node_modules inside custom actions
|
||||
!.gitea-actions/**/node_modules/
|
||||
!.gitea-actions/**/node_modules/
|
||||
|
||||
# venv
|
||||
venv/
|
@ -97,6 +97,12 @@ namespace OF_DL.Entities
|
||||
|
||||
[ToggleableConfig]
|
||||
public bool IgnoreOwnMessages { get; set; } = false;
|
||||
|
||||
[ToggleableConfig]
|
||||
public bool DisableBrowserAuth { get; set; } = false;
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public VideoResolution DownloadVideoResolution { get; set; } = VideoResolution.source;
|
||||
}
|
||||
|
||||
public class CreatorConfig : IFileNameFormatConfig
|
||||
|
@ -17,6 +17,8 @@ namespace OF_DL.Entities
|
||||
bool DownloadVideos { get; set; }
|
||||
bool DownloadAudios { get; set; }
|
||||
|
||||
VideoResolution DownloadVideoResolution { get; set; }
|
||||
|
||||
int? Timeout { get; set; }
|
||||
bool FolderPerPaidPost { get; set; }
|
||||
bool FolderPerPost { get; set; }
|
||||
|
9
OF DL/Entities/LatestReleaseAPIResponse.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace OF_DL.Entities;
|
||||
|
||||
public class LatestReleaseAPIResponse
|
||||
{
|
||||
[JsonProperty(PropertyName = "tag_name")]
|
||||
public string TagName { get; set; } = "";
|
||||
}
|
@ -150,10 +150,10 @@ namespace OF_DL.Entities.Post
|
||||
public class VideoSources
|
||||
{
|
||||
[JsonProperty("720")]
|
||||
public object _720 { get; set; }
|
||||
public string _720 { get; set; }
|
||||
|
||||
[JsonProperty("240")]
|
||||
public object _240 { get; set; }
|
||||
public string _240 { get; set; }
|
||||
}
|
||||
public class Dash
|
||||
{
|
||||
|
15
OF DL/Enumerations/VideoResolution.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OF_DL.Enumerations
|
||||
{
|
||||
public enum VideoResolution
|
||||
{
|
||||
_240,
|
||||
_720,
|
||||
source
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using OF_DL.Entities.Post;
|
||||
using OF_DL.Entities.Purchased;
|
||||
using OF_DL.Entities.Stories;
|
||||
using OF_DL.Entities.Streams;
|
||||
using OF_DL.Enumerations;
|
||||
using OF_DL.Enumurations;
|
||||
using Serilog;
|
||||
using Spectre.Console;
|
||||
@ -26,6 +27,7 @@ public class APIHelper : IAPIHelper
|
||||
{
|
||||
private static readonly JsonSerializerSettings m_JsonSerializerSettings;
|
||||
private readonly IDBHelper m_DBHelper;
|
||||
private readonly IDownloadConfig downloadConfig;
|
||||
private readonly Auth auth;
|
||||
private static DateTime? cachedDynamicRulesExpiration;
|
||||
private static DynamicRules? cachedDynamicRules;
|
||||
@ -42,6 +44,7 @@ public class APIHelper : IAPIHelper
|
||||
{
|
||||
this.auth = auth;
|
||||
m_DBHelper = new DBHelper(downloadConfig);
|
||||
this.downloadConfig = downloadConfig;
|
||||
}
|
||||
|
||||
|
||||
@ -1130,29 +1133,51 @@ public class APIHelper : IAPIHelper
|
||||
}
|
||||
if (medium.canView && medium.files?.drm == null)
|
||||
{
|
||||
if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url))
|
||||
switch (downloadConfig.DownloadVideoResolution)
|
||||
{
|
||||
if (!medium.files!.full.url.Contains("upload"))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
case VideoResolution.source:
|
||||
if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files!.full.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.files!.full.url);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
if (!medium.files!.full.url.Contains("upload"))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files!.full.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.files!.full.url);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (medium.files.preview != null && medium.files!.full == null)
|
||||
{
|
||||
if (!medium.files.preview.url.Contains("upload"))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
break;
|
||||
case VideoResolution._240:
|
||||
if(medium.videoSources != null)
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files.preview.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.files.preview.url);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
if (!string.IsNullOrEmpty(medium.videoSources._240))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.videoSources._240, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.videoSources._240);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VideoResolution._720:
|
||||
if (medium.videoSources != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(medium.videoSources._720))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.videoSources._720, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.videoSources._720);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (medium.canView && medium.files != null && medium.files.drm != null)
|
||||
@ -1167,6 +1192,18 @@ public class APIHelper : IAPIHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (medium.files.preview != null && medium.files!.full == null)
|
||||
{
|
||||
if (!medium.files.preview.url.Contains("upload"))
|
||||
{
|
||||
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
|
||||
{
|
||||
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files.preview.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
|
||||
singlePostCollection.SinglePosts.Add(medium.id, medium.files.preview.url);
|
||||
singlePostCollection.SinglePostMedia.Add(medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2807,7 +2844,7 @@ public class APIHelper : IAPIHelper
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://raw.githubusercontent.com/deviint/onlyfans-dynamic-rules/main/dynamicRules.json");
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://git.ofdl.tools/sim0n00ps/dynamic-rules/raw/branch/main/rules.json");
|
||||
using var response = client.Send(request);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
|
@ -12,6 +12,7 @@ using OF_DL.Enumerations;
|
||||
using OF_DL.Utils;
|
||||
using Org.BouncyCastle.Asn1.Tsp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Tsp;
|
||||
using Serilog;
|
||||
using Spectre.Console;
|
||||
using System;
|
||||
@ -25,6 +26,7 @@ using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using static OF_DL.Entities.Lists.UserList;
|
||||
using static OF_DL.Entities.Messages.Messages;
|
||||
|
||||
@ -602,9 +604,33 @@ public class DownloadHelper : IDownloadHelper
|
||||
decKey = decryptionKey.Substring(pos1 + 1);
|
||||
}
|
||||
|
||||
int streamIndex = 0;
|
||||
string tempFilename = $"{folder}{path}/{filename}_source.mp4";
|
||||
|
||||
string parameters = $"-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}\" -codec copy \"{tempFilename}\"";
|
||||
//int? streamIndex = await GetVideoStreamIndexFromMpd(url, policy, signature, kvp, downloadConfig.DownloadVideoResolution);
|
||||
|
||||
//if (streamIndex == null)
|
||||
// throw new Exception($"Could not find video stream for resolution {downloadConfig.DownloadVideoResolution}");
|
||||
|
||||
//string tempFilename;
|
||||
|
||||
//switch (downloadConfig.DownloadVideoResolution)
|
||||
//{
|
||||
// case VideoResolution.source:
|
||||
// tempFilename = $"{folder}{path}/{filename}_source.mp4";
|
||||
// break;
|
||||
// case VideoResolution._240:
|
||||
// tempFilename = $"{folder}{path}/{filename}_240.mp4";
|
||||
// break;
|
||||
// case VideoResolution._720:
|
||||
// tempFilename = $"{folder}{path}/{filename}_720.mp4";
|
||||
// break;
|
||||
// default:
|
||||
// tempFilename = $"{folder}{path}/{filename}_source.mp4";
|
||||
// break;
|
||||
//}
|
||||
|
||||
string parameters = $"-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}\"";
|
||||
|
||||
Log.Debug($"Calling FFMPEG with Parameters: {parameters}");
|
||||
|
||||
@ -1787,4 +1813,45 @@ public class DownloadHelper : IDownloadHelper
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private async Task <int?> GetVideoStreamIndexFromMpd(string mpdUrl, string policy, string signature, string kvp, VideoResolution resolution)
|
||||
{
|
||||
HttpClient client = new();
|
||||
HttpRequestMessage request = new(HttpMethod.Get, mpdUrl);
|
||||
request.Headers.Add("user-agent", auth.USER_AGENT);
|
||||
request.Headers.Add("Accept", "*/*");
|
||||
request.Headers.Add("Cookie", $"CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {auth.COOKIE};");
|
||||
using (var response = await client.SendAsync(request))
|
||||
{
|
||||
response.EnsureSuccessStatusCode();
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
XDocument doc = XDocument.Parse(body);
|
||||
XNamespace ns = "urn:mpeg:dash:schema:mpd:2011";
|
||||
XNamespace cenc = "urn:mpeg:cenc:2013";
|
||||
var videoAdaptationSet = doc
|
||||
.Descendants(ns + "AdaptationSet")
|
||||
.FirstOrDefault(e => (string)e.Attribute("mimeType") == "video/mp4");
|
||||
|
||||
if (videoAdaptationSet == null)
|
||||
return null;
|
||||
|
||||
string targetHeight = resolution switch
|
||||
{
|
||||
VideoResolution._240 => "240",
|
||||
VideoResolution._720 => "720",
|
||||
VideoResolution.source => "1280",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(resolution))
|
||||
};
|
||||
|
||||
var representations = videoAdaptationSet.Elements(ns + "Representation").ToList();
|
||||
|
||||
for (int i = 0; i < representations.Count; i++)
|
||||
{
|
||||
if ((string)representations[i].Attribute("height") == targetHeight)
|
||||
return i; // this is the index FFmpeg will use for `-map 0:v:{i}`
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
52
OF DL/Helpers/VersionHelper.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using Newtonsoft.Json;
|
||||
using OF_DL.Entities;
|
||||
using Serilog;
|
||||
|
||||
namespace OF_DL.Helpers;
|
||||
|
||||
public static class VersionHelper
|
||||
{
|
||||
public static string? GetLatestReleaseTag()
|
||||
{
|
||||
Log.Debug("Calling GetLatestReleaseTag");
|
||||
try
|
||||
{
|
||||
HttpClient client = new();
|
||||
HttpRequestMessage request = new(HttpMethod.Get, "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest");
|
||||
using var response = client.Send(request);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Log.Debug("GetLatestReleaseTag did not return a Success Status Code");
|
||||
return null;
|
||||
}
|
||||
|
||||
var body = response.Content.ReadAsStringAsync().Result;
|
||||
|
||||
Log.Debug("GetLatestReleaseTag API Response: ");
|
||||
Log.Debug(body);
|
||||
|
||||
var versionCheckResponse = JsonConvert.DeserializeObject<LatestReleaseAPIResponse>(body);
|
||||
|
||||
if (versionCheckResponse == null || versionCheckResponse.TagName == "")
|
||||
{
|
||||
Log.Debug("GetLatestReleaseTag did not return a valid tag name");
|
||||
return null;
|
||||
}
|
||||
|
||||
return versionCheckResponse.TagName;
|
||||
}
|
||||
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 null;
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Octokit" Version="14.0.0" />
|
||||
<PackageReference Include="protobuf-net" Version="3.2.46" />
|
||||
<PackageReference Include="PuppeteerSharp" Version="20.1.3" />
|
||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||
|
146
OF DL/Program.cs
@ -9,7 +9,6 @@ using OF_DL.Entities.Streams;
|
||||
using OF_DL.Enumerations;
|
||||
using OF_DL.Enumurations;
|
||||
using OF_DL.Helpers;
|
||||
using Octokit;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
@ -161,6 +160,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -251,6 +251,9 @@ public class Program
|
||||
|
||||
config = new Entities.Config
|
||||
{
|
||||
//Auth
|
||||
DisableBrowserAuth = hoconConfig.GetBoolean("DisableBrowserAuth"),
|
||||
|
||||
// FFmpeg Settings
|
||||
FFmpegPath = hoconConfig.GetString("External.FFmpegPath"),
|
||||
|
||||
@ -277,9 +280,10 @@ public class Program
|
||||
DownloadDateSelection = Enum.Parse<DownloadDateSelection>(hoconConfig.GetString("Download.DownloadDateSelection"), true),
|
||||
CustomDate = !string.IsNullOrWhiteSpace(hoconConfig.GetString("Download.CustomDate")) ? DateTime.Parse(hoconConfig.GetString("Download.CustomDate")) : null,
|
||||
ShowScrapeSize = hoconConfig.GetBoolean("Download.ShowScrapeSize"),
|
||||
DownloadVideoResolution = ParseVideoResolution(hoconConfig.GetString("Download.DownloadVideoResolution", "source")),
|
||||
|
||||
// File Settings
|
||||
PaidPostFileNameFormat = hoconConfig.GetString("File.PaidPostFileNameFormat"),
|
||||
// File Settings
|
||||
PaidPostFileNameFormat = hoconConfig.GetString("File.PaidPostFileNameFormat"),
|
||||
PostFileNameFormat = hoconConfig.GetString("File.PostFileNameFormat"),
|
||||
PaidMessageFileNameFormat = hoconConfig.GetString("File.PaidMessageFileNameFormat"),
|
||||
MessageFileNameFormat = hoconConfig.GetString("File.MessageFileNameFormat"),
|
||||
@ -363,6 +367,8 @@ public class Program
|
||||
{
|
||||
Entities.Config jsonConfig = new Entities.Config();
|
||||
var hoconConfig = new StringBuilder();
|
||||
hoconConfig.AppendLine("# Auth");
|
||||
hoconConfig.AppendLine($"DisableBrowserAuth = {jsonConfig.DisableBrowserAuth.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine("# External Tools");
|
||||
hoconConfig.AppendLine("External {");
|
||||
hoconConfig.AppendLine($" FFmpegPath = \"{jsonConfig.FFmpegPath}\"");
|
||||
@ -394,6 +400,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -507,37 +514,42 @@ public class Program
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
// Only run the version check if not in DEBUG mode
|
||||
#if !DEBUG
|
||||
Version localVersion = Assembly.GetEntryAssembly()?.GetName().Version; //Only tested with numeric values.
|
||||
String? latestReleaseTag = VersionHelper.GetLatestReleaseTag();
|
||||
|
||||
// Get all releases from GitHub
|
||||
GitHubClient client = new GitHubClient(new ProductHeaderValue("SomeName"));
|
||||
IReadOnlyList<Release> releases = await client.Repository.Release.GetAll("sim0n00ps", "OF-DL");
|
||||
if (latestReleaseTag == null)
|
||||
{
|
||||
AnsiConsole.Markup("[yellow]Failed to verify that OF-DL is up-to-date.\n[/]");
|
||||
Log.Error("Failed to get the latest release tag.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Version latestGiteaRelease = new Version(latestReleaseTag.Replace("OFDLV", ""));
|
||||
|
||||
// Setup the versions
|
||||
Version latestGitHubVersion = new Version(releases[0].TagName.Replace("OFDLV", ""));
|
||||
// Compare the Versions
|
||||
int versionComparison = localVersion.CompareTo(latestGiteaRelease);
|
||||
if (versionComparison < 0)
|
||||
{
|
||||
// The version on GitHub is more up to date than this local release.
|
||||
AnsiConsole.Markup("[red]You are running OF-DL version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}\n[/]");
|
||||
AnsiConsole.Markup("[red]Please update to the current release, " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}: [link]https://git.ofdl.tools/sim0n00ps/OF-DL/releases[/]\n[/]");
|
||||
Log.Debug("Detected outdated client running version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}");
|
||||
Log.Debug("Latest release version " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// This local version is greater than the release version on GitHub.
|
||||
AnsiConsole.Markup("[green]You are running OF-DL version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}\n[/]");
|
||||
AnsiConsole.Markup("[green]Latest Release version: " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}\n[/]");
|
||||
Log.Debug("Detected client running version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}");
|
||||
Log.Debug("Latest release version " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}");
|
||||
}
|
||||
}
|
||||
|
||||
// Compare the Versions
|
||||
int versionComparison = localVersion.CompareTo(latestGitHubVersion);
|
||||
if (versionComparison < 0)
|
||||
{
|
||||
// The version on GitHub is more up to date than this local release.
|
||||
AnsiConsole.Markup("[red]You are running OF-DL version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}\n[/]");
|
||||
AnsiConsole.Markup("[red]Please update to the current release on GitHub, " + $"{latestGitHubVersion.Major}.{latestGitHubVersion.Minor}.{latestGitHubVersion.Build}: {releases[0].HtmlUrl}\n[/]");
|
||||
Log.Debug("Detected outdated client running version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}");
|
||||
Log.Debug("Latest GitHub release version " + $"{latestGitHubVersion.Major}.{latestGitHubVersion.Minor}.{latestGitHubVersion.Build}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// This local version is greater than the release version on GitHub.
|
||||
AnsiConsole.Markup("[green]You are running OF-DL version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}\n[/]");
|
||||
AnsiConsole.Markup("[green]Latest GitHub Release version: " + $"{latestGitHubVersion.Major}.{latestGitHubVersion.Minor}.{latestGitHubVersion.Build}\n[/]");
|
||||
Log.Debug("Detected client running version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}");
|
||||
Log.Debug("Latest GitHub release version " + $"{latestGitHubVersion.Major}.{latestGitHubVersion.Minor}.{latestGitHubVersion.Build}");
|
||||
}
|
||||
#else
|
||||
AnsiConsole.Markup("[yellow]Running in Debug/Local mode. Version check skipped.\n[/]");
|
||||
Log.Debug("Running in Debug/Local mode. Version check skipped.");
|
||||
@ -550,7 +562,8 @@ public class Program
|
||||
Log.Error("Error checking latest release on GitHub.", e.Message);
|
||||
}
|
||||
|
||||
if (File.Exists("auth.json"))
|
||||
|
||||
if (File.Exists("auth.json"))
|
||||
{
|
||||
AnsiConsole.Markup("[green]auth.json located successfully!\n[/]");
|
||||
Log.Debug("Auth file found");
|
||||
@ -562,8 +575,11 @@ public class Program
|
||||
catch (Exception _)
|
||||
{
|
||||
Log.Information("Auth file found but could not be deserialized");
|
||||
Log.Debug("Deleting auth.json");
|
||||
File.Delete("auth.json");
|
||||
if (!config!.DisableBrowserAuth)
|
||||
{
|
||||
Log.Debug("Deleting auth.json");
|
||||
File.Delete("auth.json");
|
||||
}
|
||||
|
||||
if (cliNonInteractive)
|
||||
{
|
||||
@ -576,8 +592,22 @@ public class Program
|
||||
Environment.Exit(2);
|
||||
}
|
||||
|
||||
await LoadAuthFromBrowser();
|
||||
}
|
||||
|
||||
if (!config!.DisableBrowserAuth)
|
||||
{
|
||||
await LoadAuthFromBrowser();
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.MarkupLine($"\n[red]auth.json is missing. The file can be generated automatically when OF-DL is run in the standard, interactive mode.[/]\n");
|
||||
AnsiConsole.MarkupLine($"[red]You may also want to try using the browser extension which is documented here:[/]\n");
|
||||
AnsiConsole.MarkupLine($"[link]https://sim0n00ps.github.io/OF-DL/docs/config/auth#browser-extension[/]\n");
|
||||
AnsiConsole.MarkupLine($"[red]Press any key to exit.[/]");
|
||||
|
||||
Console.ReadKey();
|
||||
Environment.Exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -592,7 +622,20 @@ public class Program
|
||||
Environment.Exit(2);
|
||||
}
|
||||
|
||||
await LoadAuthFromBrowser();
|
||||
if (!config!.DisableBrowserAuth)
|
||||
{
|
||||
await LoadAuthFromBrowser();
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.MarkupLine($"\n[red]auth.json is missing. The file can be generated automatically when OF-DL is run in the standard, interactive mode.[/]\n");
|
||||
AnsiConsole.MarkupLine($"[red]You may also want to try using the browser extension which is documented here:[/]\n");
|
||||
AnsiConsole.MarkupLine($"[link]https://sim0n00ps.github.io/OF-DL/docs/config/auth#browser-extension[/]\n");
|
||||
AnsiConsole.MarkupLine($"[red]Press any key to exit.[/]");
|
||||
|
||||
Console.ReadKey();
|
||||
Environment.Exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
//Added to stop cookie being filled with un-needed headers
|
||||
@ -746,15 +789,18 @@ public class Program
|
||||
Log.Error("Auth failed");
|
||||
|
||||
auth = null;
|
||||
if (File.Exists("auth.json"))
|
||||
{
|
||||
File.Delete("auth.json");
|
||||
}
|
||||
if (!config!.DisableBrowserAuth)
|
||||
{
|
||||
if (File.Exists("auth.json"))
|
||||
{
|
||||
File.Delete("auth.json");
|
||||
}
|
||||
}
|
||||
|
||||
if (!cliNonInteractive)
|
||||
if (!cliNonInteractive && !config!.DisableBrowserAuth)
|
||||
{
|
||||
await LoadAuthFromBrowser();
|
||||
}
|
||||
await LoadAuthFromBrowser();
|
||||
}
|
||||
|
||||
if (auth == null)
|
||||
{
|
||||
@ -1639,7 +1685,7 @@ public class Program
|
||||
{
|
||||
archived = await downloadContext.ApiHelper.GetArchived($"/users/{user.Value}/posts", path, downloadContext.DownloadConfig!, ctx);
|
||||
});
|
||||
|
||||
|
||||
int oldArchivedCount = 0;
|
||||
int newArchivedCount = 0;
|
||||
if (archived != null && archived.ArchivedPosts.Count > 0)
|
||||
@ -1772,7 +1818,7 @@ public class Program
|
||||
{
|
||||
posts = await downloadContext.ApiHelper.GetPosts($"/users/{user.Value}/posts", path, downloadContext.DownloadConfig!, paid_post_ids, ctx);
|
||||
});
|
||||
|
||||
|
||||
int oldPostCount = 0;
|
||||
int newPostCount = 0;
|
||||
if (posts == null || posts.Posts.Count <= 0)
|
||||
@ -2294,7 +2340,7 @@ public class Program
|
||||
{
|
||||
streams = await downloadContext.ApiHelper.GetStreams($"/users/{user.Value}/posts/streams", path, downloadContext.DownloadConfig!, paid_post_ids, ctx);
|
||||
});
|
||||
|
||||
|
||||
int oldStreamsCount = 0;
|
||||
int newStreamsCount = 0;
|
||||
if (streams == null || streams.Streams.Count <= 0)
|
||||
@ -2825,6 +2871,8 @@ public class Program
|
||||
}
|
||||
|
||||
var hoconConfig = new StringBuilder();
|
||||
hoconConfig.AppendLine("# Auth");
|
||||
hoconConfig.AppendLine($"DisableBrowserAuth = {newConfig.DisableBrowserAuth.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine("# External Tools");
|
||||
hoconConfig.AppendLine("External {");
|
||||
hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\"");
|
||||
@ -2856,6 +2904,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -2981,6 +3030,8 @@ public class Program
|
||||
Log.Debug(configString);
|
||||
|
||||
var hoconConfig = new StringBuilder();
|
||||
hoconConfig.AppendLine("# Auth");
|
||||
hoconConfig.AppendLine($"DisableBrowserAuth = {newConfig.DisableBrowserAuth.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine("# External Tools");
|
||||
hoconConfig.AppendLine("External {");
|
||||
hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\"");
|
||||
@ -3012,6 +3063,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -3230,4 +3282,12 @@ public class Program
|
||||
Environment.Exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
public static VideoResolution ParseVideoResolution(string value)
|
||||
{
|
||||
if (value.Equals("source", StringComparison.OrdinalIgnoreCase))
|
||||
return VideoResolution.source;
|
||||
|
||||
return Enum.Parse<VideoResolution>("_" + value, ignoreCase: true);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ Scrape all the media from an OnlyFans account
|
||||
Join the discord [here](https://discord.com/invite/6bUW8EJ53j)
|
||||
|
||||
# Documentation
|
||||
Please refer to https://sim0n00ps.github.io/OF-DL/ for instructions on:
|
||||
Please refer to https://docs.ofdl.tools/ for instructions on:
|
||||
- Requirements
|
||||
- Installing the Program
|
||||
- Running the Program
|
||||
|
2
docs/.gitignore
vendored
@ -18,3 +18,5 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
venv/
|
@ -1 +0,0 @@
|
||||
20.16.0
|
@ -1,41 +0,0 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ yarn
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
### Build
|
||||
|
||||
```
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
### Deployment
|
||||
|
||||
Using SSH:
|
||||
|
||||
```
|
||||
$ USE_SSH=true yarn deploy
|
||||
```
|
||||
|
||||
Not using SSH:
|
||||
|
||||
```
|
||||
$ GIT_USER=<Your GitHub username> yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
@ -10,18 +10,14 @@ OF DL allows you to log in to your OnlyFans account directly. This simplifies th
|
||||
When prompted by the application, log into your OnlyFans account. Do not close the opened window, tab, or navigate away to another webpage.
|
||||
The new window will close automatically when the authentication process has finished.
|
||||
|
||||
:::warning
|
||||
!!! warning
|
||||
|
||||
Some users have reported that "Sign in with Google" has not been working with this authentication method.
|
||||
If you use the Google sign-in option to log into your OnlyFans account, use one of the [legacy authentication methods](#legacy-methods) described below.
|
||||
Some users have reported that "Sign in with Google" has not been working with this authentication method.
|
||||
If you use the Google sign-in option to log into your OnlyFans account, use one of the [legacy authentication methods](#legacy-methods) described below.
|
||||
|
||||
:::
|
||||
!!! info
|
||||
|
||||
:::info
|
||||
|
||||
If you are using docker, follow the special [authentication instructions documented](/docs/installation/docker) to authenticate OF-DL
|
||||
|
||||
:::
|
||||
If you are using docker, follow the special [authentication instructions documented](/installation/docker) to authenticate OF-DL
|
||||
|
||||
## Legacy Methods
|
||||
|
@ -265,7 +265,7 @@ Default: `""`
|
||||
|
||||
Allowed values: Any valid string
|
||||
|
||||
Description: Please refer to [custom filename formats](/docs/config/custom-filename-formats#paidpostfilenameformat) page to see what fields you can use.
|
||||
Description: Please refer to [custom filename formats](/config/custom-filename-formats#paidpostfilenameformat) page to see what fields you can use.
|
||||
|
||||
## PostFileNameFormat
|
||||
|
||||
@ -275,7 +275,7 @@ Default: `""`
|
||||
|
||||
Allowed values: Any valid string
|
||||
|
||||
Description: Please refer to the [custom filename formats](/docs/config/custom-filename-formats#postfilenameformat) page to see what fields you can use.
|
||||
Description: Please refer to the [custom filename formats](/config/custom-filename-formats#postfilenameformat) page to see what fields you can use.
|
||||
|
||||
## PaidMessageFileNameFormat
|
||||
|
||||
@ -285,7 +285,7 @@ Default: `""`
|
||||
|
||||
Allowed values: Any valid string
|
||||
|
||||
Description: Please refer to [custom filename formats](/docs/config/custom-filename-formats#paidmessagefilenameformat) page to see what fields you can use.
|
||||
Description: Please refer to [custom filename formats](/config/custom-filename-formats#paidmessagefilenameformat) page to see what fields you can use.
|
||||
|
||||
## MessageFileNameFormat
|
||||
|
||||
@ -295,7 +295,7 @@ Default: `""`
|
||||
|
||||
Allowed values: Any valid string
|
||||
|
||||
Description: Please refer to [custom filename formats](/docs/config/custom-filename-formats#messagefilenameformat) page to see what fields you can use.
|
||||
Description: Please refer to [custom filename formats](/config/custom-filename-formats#messagefilenameformat) page to see what fields you can use.
|
||||
|
||||
## RenameExistingFilesWhenCustomFormatIsSelected
|
||||
|
||||
@ -322,7 +322,7 @@ Description: This configuration options allows you to set file name formats for
|
||||
This is useful if you want to have different file name formats for different creators. The values set here will override the global values set in the config file
|
||||
(see [PaidPostFileNameFormat](#paidpostfilenameformat), [PostFileNameFormat](#postfilenameformat),
|
||||
[PaidMessageFileNAmeFormat](#paidmessagefilenameformat), and [MessageFileNameFormat](#messagefilenameformat)).
|
||||
For more information on the file name formats, see the [custom filename formats](/docs/config/custom-filename-formats) page.
|
||||
For more information on the file name formats, see the [custom filename formats](/config/custom-filename-formats) page.
|
||||
|
||||
Example:
|
||||
```
|
||||
@ -435,15 +435,13 @@ Description: If set to `true`, the program will run without any input from the u
|
||||
(unless [NonInteractiveModeListName](#noninteractivemodelistname) or [NonInteractiveModePurchasedTab](#noninteractivemodepurchasedtab) are configured).
|
||||
If set to `false`, the default behaviour will apply, and you will be able to choose an option from the menu.
|
||||
|
||||
:::warning
|
||||
!!! warning
|
||||
|
||||
If NonInteractiveMode is enabled, you will be unable to authenticate OF-DL using the standard authentication method.
|
||||
Before you can run OF-DL in NonInteractiveMode, you must either
|
||||
If NonInteractiveMode is enabled, you will be unable to authenticate OF-DL using the standard authentication method.
|
||||
Before you can run OF-DL in NonInteractiveMode, you must either
|
||||
|
||||
1. Generate an auth.json file by running OF-DL with NonInteractiveMode disabled and authenticating OF-DL using the standard method **OR**
|
||||
2. Generate an auth.json file by using a [legacy authentication method](/docs/config/auth#legacy-methods)
|
||||
|
||||
:::
|
||||
1. Generate an auth.json file by running OF-DL with NonInteractiveMode disabled and authenticating OF-DL using the standard method **OR**
|
||||
2. Generate an auth.json file by using a [legacy authentication method](/config/auth#legacy-methods)
|
||||
|
||||
## NonInteractiveModeListName
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"label": "Configuration",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Configuration options and information for OF-DL"
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"label": "Installation",
|
||||
"position": 1,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Installation instructions for OF-DL"
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
// @ts-check
|
||||
// `@type` JSDoc annotations allow editor autocompletion and type checking
|
||||
// (when paired with `@ts-check`).
|
||||
// There are various equivalent ways to declare your Docusaurus config.
|
||||
// See: https://docusaurus.io/docs/api/docusaurus-config
|
||||
|
||||
import {themes as prismThemes} from 'prism-react-renderer';
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'OF-DL',
|
||||
tagline: 'A media scraper for OnlyFans with DRM video support',
|
||||
favicon: 'img/logo.png',
|
||||
|
||||
// Set the production url of your site here
|
||||
url: 'https://sim0n00ps.github.io',
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: '/OF-DL/',
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: 'sim0n00ps', // Usually your GitHub org/user name.
|
||||
projectName: 'OF-DL', // Usually your repo name.
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
// Even if you don't use internationalization, you can use this field to set
|
||||
// useful metadata like html lang. For example, if your site is Chinese, you
|
||||
// may want to replace "en" with "zh-Hans".
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
sidebarPath: './sidebars.js',
|
||||
},
|
||||
blog: false,
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
colorMode: {
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
navbar: {
|
||||
title: 'OF-DL',
|
||||
logo: {
|
||||
alt: 'OF-DL Logo',
|
||||
src: 'img/logo.png',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'generatedSidebar',
|
||||
position: 'left',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/sim0n00ps/OF-DL',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Installation',
|
||||
to: '/docs/installation/windows',
|
||||
},
|
||||
{
|
||||
label: 'Configuration',
|
||||
to: '/docs/config/auth',
|
||||
},
|
||||
{
|
||||
label: 'Running the Program',
|
||||
to: '/docs/running-the-program',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
label: 'Discord',
|
||||
href: 'https://discord.com/invite/6bUW8EJ53j',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/sim0n00ps/OF-DL',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export default config;
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
BIN
docs/img/logo.ico
Normal file
After Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
8
docs/index.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Welcome to OF-DL
|
||||
|
||||
C# console app to download all of the media from Onlyfans accounts with DRM video downloading support.
|
||||
|
||||
!!! info "PLEASE READ BEFORE DOWNLOADING"
|
||||
THIS TOOL CANNOT BYPASS PAYWALLS, IT CAN ONLY DOWNLOAD CONTENT YOU HAVE ACCESS TO, PLEASE DO NOT DOWNLOAD THIS TOOL THINKING YOU CAN BYPASS PAYING FOR THINGS!!!!!
|
||||
|
||||
Join the discord [here](https://discord.com/invite/6bUW8EJ53j)
|
@ -18,7 +18,7 @@ To run OF-DL in a docker container, follow these steps:
|
||||
Adjust `$HOME/ofdl` as desired (including in the commands below) if you want the files stored elsewhere.
|
||||
4. Run the following command to start the docker container:
|
||||
```bash
|
||||
docker run --rm -it -v $HOME/ofdl/data/:/data -v $HOME/ofdl/config/:/config -p 8080:8080 ghcr.io/sim0n00ps/of-dl:latest
|
||||
docker run --rm -it -v $HOME/ofdl/data/:/data -v $HOME/ofdl/config/:/config -p 8080:8080 git.ofdl.tools/sim0n00ps/of-dl:latest
|
||||
```
|
||||
If `config.json` and/or `rules.json` don't exist in the `config` directory, files with default values will be created when you run the docker container.
|
||||
If you have your own Widevine keys, those files should be placed under `$HOME/ofdl/config/cdm/devices/chrome_1610/`.
|
||||
@ -29,14 +29,14 @@ To run OF-DL in a docker container, follow these steps:
|
||||
When a new version of OF-DL is released, you can download the latest docker image by executing:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/sim0n00ps/of-dl:latest
|
||||
docker pull git.ofdl.tools/sim0n00ps/of-dl:latest
|
||||
```
|
||||
|
||||
You can then run the new version of OF-DL by executing the `docker run` command in the [Running OF-DL](#running-of-dl) section above.
|
||||
|
||||
## Building the Docker Image (Optional)
|
||||
|
||||
Since official docker images are provided for OF-DL through GitHub Container Registry (ghcr.io), you do not need to build the docker image yourself.
|
||||
Since official docker images are provided for OF-DL through Gitea (git.ofdl.tools), you do not need to build the docker image yourself.
|
||||
If you would like to build the docker image yourself, however, start by cloning the OF-DL repository and opening a terminal in the root directory of the repository.
|
||||
Then, execute the following command while replacing `x.x.x` with the current version of OF-DL:
|
||||
|
||||
@ -45,4 +45,4 @@ VERSION="x.x.x" docker build --build-arg VERSION=$VERSION -t of-dl .
|
||||
```
|
||||
|
||||
You can then run a container using the image you just built by executing the `docker run` command in the
|
||||
[Running OF-DL](#running-of-dl) section above while replacing `ghcr.io/sim0n00ps/of-dl:latest` with `of-dl`.
|
||||
[Running OF-DL](#running-of-dl) section above while replacing `git.ofdl.tools/sim0n00ps/of-dl:latest` with `of-dl`.
|
@ -5,7 +5,7 @@ sidebar_position: 3
|
||||
# Linux
|
||||
|
||||
A Linux release of OF-DL is not available at this time, however you can run OF-DL on Linux using Docker.
|
||||
Please refer to the [Docker](/docs/installation/docker) page for instructions on how to run OF-DL in a Docker container.
|
||||
Please refer to the [Docker](/installation/docker) page for instructions on how to run OF-DL in a Docker container.
|
||||
If you do not have Docker installed, you can download it from [here](https://docs.docker.com/desktop/install/linux-install/).
|
||||
If you would like to run OF-DL natively on Linux, you can build it from source by following the instructions below.
|
||||
|
||||
@ -27,7 +27,7 @@ sudo apt-get install libicu-dev
|
||||
- Clone the repo
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sim0n00ps/OF-DL.git
|
||||
git clone https://git.ofdl.tools/sim0n00ps/OF-DL.git
|
||||
cd 'OF-DL'
|
||||
```
|
||||
|
@ -5,5 +5,5 @@ sidebar_position: 4
|
||||
# macOS
|
||||
|
||||
macOS releases of OF-DL are not available at this time, however you can run OF-DL on macOS using Docker.
|
||||
Please refer to the [Docker](/docs/installation/docker) page for instructions on how to run OF-DL in a Docker container.
|
||||
Please refer to the [Docker](/installation/docker) page for instructions on how to run OF-DL in a Docker container.
|
||||
If you do not have Docker installed, you can download it from [here](https://docs.docker.com/desktop/install/mac-install/).
|
@ -11,11 +11,11 @@ sidebar_position: 1
|
||||
You will need to download FFmpeg. You can download it from [here](https://www.gyan.dev/ffmpeg/builds/).
|
||||
Make sure you download `ffmpeg-release-essentials.zip`. Unzip it anywhere on your computer. You only need `ffmpeg.exe`, and you can ignore the rest.
|
||||
Move `ffmpeg.exe` to the same folder as `OF DL.exe` (downloaded in the installation steps below). If you choose to move `ffmpeg.exe` to a different folder,
|
||||
you will need to specify the path to `ffmpeg.exe` in the config file (see the `FFmpegPath` [config option](/docs/config/configuration#ffmpegpath)).
|
||||
you will need to specify the path to `ffmpeg.exe` in the config file (see the `FFmpegPath` [config option](/config/configuration#ffmpegpath)).
|
||||
|
||||
## Installation
|
||||
|
||||
1. Navigate to the OF-DL [releases page](https://github.com/sim0n00ps/OF-DL/releases), and download the latest release zip file. The zip file will be named `OFDLVx.x.x.zip` where `x.x.x` is the version number.
|
||||
1. Navigate to the OF-DL [releases page](https://git.ofdl.tools/sim0n00ps/OF-DL/releases), and download the latest release zip file. The zip file will be named `OFDLVx.x.x.zip` where `x.x.x` is the version number.
|
||||
2. Unzip the downloaded file. The destination folder can be anywhere on your computer, preferably somewhere where you want to download content to/already have content downloaded.
|
||||
3. Your folder should contain a folder named `cdm` as well as the following files:
|
||||
- OF DL.exe
|
15550
docs/package-lock.json
generated
@ -1,44 +0,0 @@
|
||||
{
|
||||
"name": "of-dl",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.4.0",
|
||||
"@docusaurus/preset-classic": "3.4.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.4.0",
|
||||
"@docusaurus/types": "3.4.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 3 chrome version",
|
||||
"last 3 firefox version",
|
||||
"last 5 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ sidebar_position: 3
|
||||
|
||||
# Running the Program
|
||||
|
||||
Once you are happy you have filled everything in [auth.json](/docs/config/auth) correctly, you can double click OF-DL.exe and you should see a command prompt window appear, it should look something like this:
|
||||
Once you are happy you have filled everything in [auth.json](/config/auth) correctly, you can double click OF-DL.exe and you should see a command prompt window appear, it should look something like this:
|
||||
|
||||

|
||||
|
@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
generatedSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
|
||||
// But you can create a sidebar manually
|
||||
/*
|
||||
tutorialSidebar: [
|
||||
'intro',
|
||||
'hello',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorial',
|
||||
items: ['tutorial-basics/create-a-document'],
|
||||
},
|
||||
],
|
||||
*/
|
||||
};
|
||||
|
||||
export default sidebars;
|
@ -1,39 +0,0 @@
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import Layout from '@theme/Layout';
|
||||
|
||||
import Heading from '@theme/Heading';
|
||||
import styles from './index.module.css';
|
||||
|
||||
function HomepageHeader() {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
return (
|
||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||
<div className="container">
|
||||
<Heading as="h1" className="hero__title">
|
||||
{siteConfig.title}
|
||||
</Heading>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--secondary button--lg"
|
||||
to="docs/installation/windows">
|
||||
Installation
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
return (
|
||||
<Layout
|
||||
title={siteConfig.title}
|
||||
description={siteConfig.tagline}>
|
||||
<HomepageHeader />
|
||||
</Layout>
|
||||
);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 996px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
0
docs/static/.nojekyll
vendored
BIN
docs/static/img/logo.png
vendored
Before Width: | Height: | Size: 769 B |
46
mkdocs.yml
Normal file
@ -0,0 +1,46 @@
|
||||
site_name: OF-DL Docs
|
||||
site_url: https://docs.ofdl.tools
|
||||
theme:
|
||||
name: material
|
||||
features:
|
||||
- navigation.tabs
|
||||
- navigation.top
|
||||
- navigation.instant
|
||||
- navigation.expand
|
||||
- navigation.sections
|
||||
- navigation.tracking
|
||||
- navigation.search.highlight
|
||||
- navigation.search.suggest
|
||||
- navigation.search.share
|
||||
- navigation.search.suggest
|
||||
- navigation.search.share
|
||||
- navigation.search.suggest
|
||||
- navigation.search.share
|
||||
language: en
|
||||
palette:
|
||||
- scheme: default
|
||||
toggle:
|
||||
icon: material/toggle-switch-off-outline
|
||||
name: Switch to dark mode
|
||||
primary: dark-blue
|
||||
accent: white
|
||||
- scheme: slate
|
||||
toggle:
|
||||
icon: material/toggle-switch
|
||||
name: Switch to light mode
|
||||
primary: dark-blue
|
||||
accent: white
|
||||
font:
|
||||
text: Roboto
|
||||
code: Roboto Mono
|
||||
logo: img/logo.ico
|
||||
favicon: img/logo.ico
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
- pymdownx.details
|
||||
- pymdownx.superfences
|
||||
extra:
|
||||
social:
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.com/invite/6bUW8EJ53j
|
||||
copyright: "© 2025 OF-DL. All rights reserved."
|