From 0246af9b69faff5b5839ba1e09374b638673a5dc Mon Sep 17 00:00:00 2001 From: Andy <88590076+AAndyProgram@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:10:02 +0300 Subject: [PATCH] 2023.12.27.0 API.OnlyFans: add OF-Scraper support ProfileSaved: save files when adding new data --- Changelog.md | 14 ++ .../SettingsGlobalNotifications.png | Bin 12496 -> 13434 bytes ProgramsComparison.md | 17 +- SCrawler/API/Base/ProfileSaved.vb | 2 +- SCrawler/API/OnlyFans/OFResources.Designer.vb | 77 ++++++++ SCrawler/API/OnlyFans/OFResources.resx | 124 ++++++++++++ .../API/OnlyFans/OFScraperConfigPattern.json | 61 ++++++ SCrawler/API/OnlyFans/SiteSettings.vb | 60 +++++- SCrawler/API/OnlyFans/UserData.vb | 184 +++++++++++++++++- SCrawler/Download/TDownloader.vb | 14 +- SCrawler/MainFrameObjects.vb | 2 +- SCrawler/My Project/AssemblyInfo.vb | 4 +- SCrawler/SCrawler.vbproj | 11 ++ 13 files changed, 542 insertions(+), 28 deletions(-) create mode 100644 SCrawler/API/OnlyFans/OFResources.Designer.vb create mode 100644 SCrawler/API/OnlyFans/OFResources.resx create mode 100644 SCrawler/API/OnlyFans/OFScraperConfigPattern.json diff --git a/Changelog.md b/Changelog.md index 1b2280b..920162d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,17 @@ +# 2023.12.27.0 + +*2023-12-27* + +- Added + - Notification of new log data + - OnlyFans: **OF-Scrapper support to download DRM protected videos** + - Other improvements +- Fixed + - The default options are changed (`Favorite`, `Temporary`, etc.) when changing an account for a created user + - When changing the account for a created user, the new account does not apply to that user until SCrawler is restarted + - Saved posts: session file is not updated when new data is added + - Minor bugs + # 2023.12.15.0 *2023-12-15* diff --git a/ProgramScreenshots/SettingsGlobalNotifications.png b/ProgramScreenshots/SettingsGlobalNotifications.png index 20da7f9d32b77f2c8085770ae23bd63b442dfa7b..87686aabbb47cf70bee405270dc7642b6b0e6abe 100644 GIT binary patch literal 13434 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 diff --git a/ProgramsComparison.md b/ProgramsComparison.md index 67a1066..1669f22 100644 --- a/ProgramsComparison.md +++ b/ProgramsComparison.md @@ -6,11 +6,19 @@ https://github.com/yt-dlp/yt-dlp/ SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare. +# gallery-dl + +https://github.com/mikf/gallery-dl + +**Great powerful CLI tool that supports hundreds of sites.** + +SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare. + # 4K Video Downloader https://www.4kdownload.com/-plbrz/video-downloader -| Option | SCrawler | 4K Stogram | +| Option | SCrawler | 4K Video Downloader | | ---- | ---- | ---- | | User managament | **Advanced** | No | | Automatic downloads | **Yes** | No | @@ -121,10 +129,3 @@ https://github.com/RipMeApp/ripme | Other sites support | **Yes** | No | | Still supported | **Yes** | **No (last release date May 4, 2021)** | -# gallery-dl - -https://github.com/mikf/gallery-dl - -**CLI tool** - -SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare. \ No newline at end of file diff --git a/SCrawler/API/Base/ProfileSaved.vb b/SCrawler/API/Base/ProfileSaved.vb index e9e1f60..ffa067a 100644 --- a/SCrawler/API/Base/ProfileSaved.vb +++ b/SCrawler/API/Base/ProfileSaved.vb @@ -47,7 +47,7 @@ Namespace API.Base Progress.InformationTemporary = $"{HOST.Name} ({c - s}/{c}) Images: {_TotalImages}; Videos: {_TotalVideos}" End If End If - If _FeedDataExists Then Downloader.Files.Sort() + If _FeedDataExists Then Downloader.Files.Sort() : Downloader.FilesSave() End Sub Private Overloads Sub Download(ByVal Host As SettingsHost, ByVal Number As Integer, ByVal Count As Integer, ByVal Token As CancellationToken, ByVal Multiple As Boolean) diff --git a/SCrawler/API/OnlyFans/OFResources.Designer.vb b/SCrawler/API/OnlyFans/OFResources.Designer.vb new file mode 100644 index 0000000..138578b --- /dev/null +++ b/SCrawler/API/OnlyFans/OFResources.Designer.vb @@ -0,0 +1,77 @@ +'------------------------------------------------------------------------------ +' +' This code was generated by a tool. +' Runtime Version:4.0.30319.42000 +' +' Changes to this file may cause incorrect behavior and will be lost if +' the code is regenerated. +' +'------------------------------------------------------------------------------ + +Option Strict On +Option Explicit On + +Imports System + +Namespace My.Resources + + 'This class was auto-generated by the StronglyTypedResourceBuilder + 'class via a tool like ResGen or Visual Studio. + 'To add or remove a member, edit your .ResX file then rerun ResGen + 'with the /str option, or rebuild your VS project. + '''

+ ''' A strongly-typed resource class, for looking up localized strings, etc. + ''' + _ + Friend Class OFResources + + Private Shared resourceMan As Global.System.Resources.ResourceManager + + Private Shared resourceCulture As Global.System.Globalization.CultureInfo + + _ + Friend Sub New() + MyBase.New + End Sub + + ''' + ''' Returns the cached ResourceManager instance used by this class. + ''' + _ + Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager + Get + If Object.ReferenceEquals(resourceMan, Nothing) Then + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SCrawler.OFResources", GetType(OFResources).Assembly) + resourceMan = temp + End If + Return resourceMan + End Get + End Property + + ''' + ''' Overrides the current thread's CurrentUICulture property for all + ''' resource lookups using this strongly typed resource class. + ''' + _ + Friend Shared Property Culture() As Global.System.Globalization.CultureInfo + Get + Return resourceCulture + End Get + Set + resourceCulture = value + End Set + End Property + + ''' + ''' Looks up a localized resource of type System.Byte[]. + ''' + Friend Shared ReadOnly Property OFScraperConfigPattern() As Byte() + Get + Dim obj As Object = ResourceManager.GetObject("OFScraperConfigPattern", resourceCulture) + Return CType(obj,Byte()) + End Get + End Property + End Class +End Namespace diff --git a/SCrawler/API/OnlyFans/OFResources.resx b/SCrawler/API/OnlyFans/OFResources.resx new file mode 100644 index 0000000..31b7c00 --- /dev/null +++ b/SCrawler/API/OnlyFans/OFResources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + OFScraperConfigPattern.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SCrawler/API/OnlyFans/OFScraperConfigPattern.json b/SCrawler/API/OnlyFans/OFScraperConfigPattern.json new file mode 100644 index 0000000..98780e4 --- /dev/null +++ b/SCrawler/API/OnlyFans/OFScraperConfigPattern.json @@ -0,0 +1,61 @@ +{ + "config": { + "main_profile": "main_profile", + "metadata": "{configpath}/{profile}/.data/{model_username}_{model_id}", + "discord": "", + "file_options": { + "save_location": "", + "dir_format": "", + "file_format": "{filename}.{ext}", + "textlength": 0, + "space-replacer": " ", + "date": "YYYY-MM-DD" + }, + "download_options": { + "file_size_limit": 0, + "file_size_min": 0, + "filter": [ + "Images", + "Audios", + "Videos" + ], + "auto_resume": false + }, + "binary_options": { + "mp4decrypt": "", + "ffmpeg": "" + }, + "cdm_options": { + "private-key": null, + "client-id": null, + "key-mode-default": "cdrm", + "keydb_api": "" + }, + "performance_options": { + "download-sems": 6, + "maxfile-sem": 0, + "threads": 5 + }, + "advanced_options": { + "code-execution": false, + "dynamic-mode-default": "deviint", + "backend": "aio", + "downloadbars": false, + "cache-mode": "sqlite", + "appendlog": true, + "custom": null, + "sanitize_text": false, + "avatar": true + }, + "responsetype": { + "timeline": "Posts", + "message": "Messages", + "archived": "Archived", + "paid": "Messages", + "stories": "Stories", + "highlights": "Stories", + "profile": "Profile", + "pinned": "Posts" + } + } +} \ No newline at end of file diff --git a/SCrawler/API/OnlyFans/SiteSettings.vb b/SCrawler/API/OnlyFans/SiteSettings.vb index 0883b5c..8fab91d 100644 --- a/SCrawler/API/OnlyFans/SiteSettings.vb +++ b/SCrawler/API/OnlyFans/SiteSettings.vb @@ -26,8 +26,8 @@ Namespace API.OnlyFans #Region "Headers" Private Const HeaderBrowser As String = "sec-ch-ua" Private Const HeaderUserID As String = "User-Id" - Private Const HeaderXBC As String = "X-Bc" - Private Const HeaderAppToken As String = "App-Token" + Friend Const HeaderXBC As String = "X-Bc" + Friend Const HeaderAppToken As String = "App-Token" Friend ReadOnly Property HH_USER_ID As PropertyValue @@ -37,7 +37,7 @@ Namespace API.OnlyFans Private ReadOnly Property HH_BROWSER As PropertyValue - Private ReadOnly Property UserAgent As PropertyValue + Friend ReadOnly Property UserAgent As PropertyValue Private Sub UpdateHeader(ByVal PropertyName As String, ByVal Value As String) Dim hName$ = String.Empty Dim isUserAgent As Boolean = False @@ -78,6 +78,42 @@ Namespace API.OnlyFans "Change this value only if you know what you are doing."), PXML, PClonable> Friend ReadOnly Property DynamicRules As PropertyValue #End Region +#Region "OFScraper" + Private ReadOnly Property OFScraperPath_XML As PropertyValue + + Friend ReadOnly Property OFScraperPath As PropertyValue + Get + If Not DefaultInstance Is Nothing Then + Return DirectCast(DefaultInstance, SiteSettings).OFScraperPath_XML + Else + Return OFScraperPath_XML + End If + End Get + End Property + Private ReadOnly Property OFScraperMP4decrypt_XML As PropertyValue + + Friend ReadOnly Property OFScraperMP4decrypt As PropertyValue + Get + If Not DefaultInstance Is Nothing Then + Return DirectCast(DefaultInstance, SiteSettings).OFScraperMP4decrypt_XML + Else + Return OFScraperMP4decrypt_XML + End If + End Get + End Property + Friend Const KeyModeDefault_Default As String = "cdrm" + Private ReadOnly Property KeyModeDefault_XML As PropertyValue + + Friend ReadOnly Property KeyModeDefault As PropertyValue + Get + If Not DefaultInstance Is Nothing Then + Return DirectCast(DefaultInstance, SiteSettings).KeyModeDefault_XML + Else + Return KeyModeDefault_XML + End If + End Get + End Property +#End Region #End Region #Region "Initializer" Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) @@ -117,6 +153,21 @@ Namespace API.OnlyFans DynamicRulesUpdateIntervalProvider = New FieldsCheckerProviderSimple(Function(v) IIf(AConvert(Of Integer)(v, 0) > 0, v, Nothing), "The value of [{0}] field must be greater than 0") DynamicRules = New PropertyValue(String.Empty, GetType(String)) + OFScraperPath_XML = New PropertyValue(String.Empty, GetType(String)) + If ACheck(OFScraperPath_XML.Value) Then + Dim f As SFile = OFScraperPath_XML.Value + If Not f.Exists AndAlso f.Exists(SFO.Path, False) Then + With SFile.GetFiles(f, "*.exe",, EDP.ReturnValue) + If .ListExists Then + f = .FirstOrDefault(Function(ff) ff.Name.StringToLower.StartsWith("ofscraper")) + If f.Exists Then OFScraperPath_XML.Value = f.ToString + End If + End With + End If + End If + OFScraperMP4decrypt_XML = New PropertyValue(String.Empty, GetType(String)) + KeyModeDefault_XML = New PropertyValue(KeyModeDefault_Default) + UserRegex = RParams.DMS("onlyfans.com/([\w\._]+)", 1, EDP.ReturnValue) UrlPatternUser = "https://onlyfans.com/{0}" ImageVideoContains = "onlyfans.com" @@ -151,6 +202,7 @@ Namespace API.OnlyFans End Sub #End Region #Region "GetUserUrl, GetUserPostUrl, UserOptions" + Friend Const UserPostPattern As String = "https://onlyfans.com/{0}/{1}" Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String Return String.Format(UrlPatternUser, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}")) End Function @@ -168,7 +220,7 @@ Namespace API.OnlyFans If p.IsEmptyString Then Return GetUserUrl(User) Else - Return String.Format("https://onlyfans.com/{0}/{1}", p, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}")) + Return String.Format(UserPostPattern, p, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}")) End If Else Return String.Empty diff --git a/SCrawler/API/OnlyFans/UserData.vb b/SCrawler/API/OnlyFans/UserData.vb index e5a93a2..8bf09b5 100644 --- a/SCrawler/API/OnlyFans/UserData.vb +++ b/SCrawler/API/OnlyFans/UserData.vb @@ -7,10 +7,12 @@ ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY Imports System.Threading +Imports System.Text.RegularExpressions Imports SCrawler.API.Base Imports SCrawler.API.YouTube.Objects Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.RegularExpressions +Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools.Web.Clients Imports PersonalUtilities.Tools.Web.Clients.EventArguments Imports PersonalUtilities.Tools.Web.Cookies @@ -65,11 +67,20 @@ Namespace API.OnlyFans #Region "Initializer" Friend Sub New() HighlightsList = New List(Of String) + UseInternalDownloadFileFunction = True End Sub #End Region #Region "Download functions" + Private _OFScraperExists As Boolean = False + Private OFSCache As CacheKeeper = Nothing + Private _AbsMediaIndex As Integer = 0 + Private Sub ValidateOFScraper() + _OFScraperExists = ACheck(MySettings.OFScraperPath.Value) AndAlso CStr(MySettings.OFScraperPath.Value).CSFile.Exists + End Sub Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken) If Not MySettings.SessionAborted Then + ValidateOFScraper() + _AbsMediaIndex = 0 If Not CCookie Is Nothing Then CCookie.Dispose() CCookie = Responser.Cookies.Copy Responser.Cookies.Clear() @@ -307,8 +318,8 @@ Namespace API.OnlyFans #End Region Private Function TryCreateMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal PostDate As String = Nothing, Optional ByRef Result As Boolean = False, Optional ByVal IsHL As Boolean = False, - Optional ByVal SpecFolder As String = Nothing) As List(Of UserMedia) - Dim postUrl$, ext$ + Optional ByVal SpecFolder As String = Nothing, Optional ByVal PostUserID As String = Nothing) As List(Of UserMedia) + Dim postUrl$, postUrlBase$, ext$ Dim t As UTypes Dim mList As New List(Of UserMedia) Result = False @@ -320,16 +331,27 @@ Namespace API.OnlyFans Else postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full")) End If + postUrlBase = String.Empty Select Case m.Value("type") Case "photo" : t = UTypes.Picture : ext = "jpg" - Case "video" : t = UTypes.Video : ext = "mp4" + Case "video" + t = UTypes.Video + ext = "mp4" + If postUrl.IsEmptyString And Not IsHL Then + t = UTypes.VideoPre + _AbsMediaIndex += 1 + If Not PostUserID.IsEmptyString And IsSingleObjectDownload Then _ + postUrlBase = String.Format(SiteSettings.UserPostPattern, PostID, $"u{PostUserID}") + End If Case Else : t = UTypes.Undefined : ext = String.Empty End Select - If Not t = UTypes.Undefined And Not postUrl.IsEmptyString Then - Dim media As New UserMedia(postUrl, t) With { + If Not t = UTypes.Undefined And (Not postUrl.IsEmptyString Or t = UTypes.VideoPre) Then + Dim media As New UserMedia(postUrl.IfNullOrEmpty(IIf(t = UTypes.VideoPre, $"{t}{_AbsMediaIndex}", String.Empty)), t) With { .Post = New UserPost(PostID, AConvert(Of Date)(PostDate, DateProvider, Nothing)), .SpecialFolder = SpecFolder } + If postUrlBase.IsEmptyString And Not IsSingleObjectDownload Then postUrlBase = GetPostUrl(Me, media) + If Not postUrlBase.IsEmptyString Then media.URL_BASE = postUrlBase media.File.Extension = ext Result = True mList.Add(media) @@ -387,7 +409,7 @@ Namespace API.OnlyFans End Function Dim mList As List(Of UserMedia) Dim mediaResult As Boolean - Dim r$, path$, postDate$ + Dim r$, path$, postDate$, postUserID$ Dim j As EContainer ProgressPre.ChangeMax(_ContentList.Count) For i% = 0 To _ContentList.Count - 1 @@ -404,8 +426,9 @@ Namespace API.OnlyFans j = JsonDocument.Parse(r) If Not j Is Nothing Then postDate = j.Value("postedAt") + postUserID = j.Value({"author"}, "id") mediaResult = False - mList = TryCreateMedia(j, m.Post.ID, postDate, mediaResult) + mList = TryCreateMedia(j, m.Post.ID, postDate, mediaResult,,, postUserID) If mediaResult Then _TempMediaList.ListAddList(mList.ListForEachCopy(stateRefill, True), LNC) rList.Add(i) @@ -531,10 +554,145 @@ Namespace API.OnlyFans Return result End Function #End Region +#Region "OFScraper support" + Private Function OFS_DownloadFile(ByVal URL As String, ByVal Token As CancellationToken) As List(Of SFile) + Try + Const requestPattern$ = """{0}"" manual --config ""{1}"" --url {2}" + Dim conf As SFile = OFS_CreateConfig() + If conf.Exists Then + Dim command$ = String.Format(requestPattern, MySettings.OFScraperPath.Value, conf, URL) + '#If DEBUG Then + 'Debug.WriteLine(command) + '#End If + Using b As New TokenBatch(Token) : b.Execute(command) : End Using + Return SFile.GetFiles(conf, "*.mp4", IO.SearchOption.AllDirectories, EDP.ReturnValue) + End If + Return Nothing + Catch ex As Exception + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "OnlyFans.UserData.OFS_DownloadFile", Nothing) + End Try + End Function + Private Function OFS_CreateConfig() As SFile + Try + Const confMainPattern$ = "{0}"": ""([^""]*)""" + If OFSCache Is Nothing Then OFSCache = If(IsSingleObjectDownload, Settings.Cache.NewInstance, CreateCache()) + Dim currentCache As CacheKeeper = OFSCache.NewInstance + currentCache.Validate() + Dim cacheRoot As SFile = currentCache.NewPath + cacheRoot.Exists(SFO.Path, True, EDP.ThrowException) + Dim f As SFile = $"{SettingsFolderName}\OFScraperConfigPattern.json" + Dim configText$ + If Not f.Exists Then + configText = Text.Encoding.UTF8.GetString(My.Resources.OFResources.OFScraperConfigPattern) + TextSaver.SaveTextToFile(configText, f, True) + End If + If f.Exists Then + Dim replaceValue$ = String.Empty + Dim rp As RParams = RParams.DMS(String.Empty, 1, RegexReturn.Replace, RegexOptions.IgnoreCase, + CType(Function(input) replaceValue, Func(Of String, String)), String.Empty, EDP.ReturnValue) + Dim ff As SFile + configText = f.GetText + Dim updateConf As Action(Of String, String) = Sub(ByVal patternValue As String, ByVal __replaceValue As String) + rp.Pattern = String.Format(confMainPattern, patternValue) + rp.Nothing = configText + replaceValue = __replaceValue + configText = RegexReplace(configText, rp) + End Sub + If Not configText.IsEmptyString Then + updateConf("save_location", cacheRoot.PathNoSeparator.Replace("\", "/")) + If ACheck(MySettings.OFScraperMP4decrypt.Value) Then + ff = CStr(MySettings.OFScraperMP4decrypt.Value) + If ff.Exists Then updateConf("mp4decrypt", ff.ToString.Replace("\", "/")) + End If + If Settings.FfmpegFile.Exists Then updateConf("ffmpeg", Settings.FfmpegFile.File.ToString.Replace("\", "/")) + updateConf("key-mode-default", CStr(MySettings.KeyModeDefault.Value).IfNullOrEmpty(SiteSettings.KeyModeDefault_Default)) + f = currentCache + f.Name = "config" + f.Extension = "json" + If TextSaver.SaveTextToFile(configText, f, True).Exists AndAlso OFS_CreateAuth(currentCache) Then Return f + End If + End If + Return Nothing + Catch ex As Exception + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "OnlyFans.UserData.OFS_CreateConfig", Nothing) + End Try + End Function + Private Function OFS_CreateAuth(ByVal DestinationPath As SFile) As Boolean + Const authText$ = """user_agent"": ""{0}"",""app-token"": ""{1}"",""x-bc"": ""{2}"",""auth_id"": ""{3}"",""sess"": ""{4}"",""auth_uid_"": ""{3}"",""cookie"": ""{5}""" + Try + Dim sess$ = If(If(CCookie, Responser.Cookies).FirstOrDefault(Function(c) c.Name.StringToLower = "sess")?.Value, String.Empty) + Dim outText$ = "{""auth"":{" & + String.Format(authText, + MySettings.UserAgent.Value, + Responser.Headers.Value(SiteSettings.HeaderAppToken), + Responser.Headers.Value(SiteSettings.HeaderXBC), + MySettings.HH_USER_ID.Value, + sess, + If(CCookie, Responser.Cookies).ToString()) & + "}}" + If DestinationPath.Exists(SFO.Path, False) Then + Dim f As SFile = $"{DestinationPath.PathWithSeparator}main_profile\auth.json" + Return TextSaver.SaveTextToFile(outText, f, True).Exists + End If + Return False + Catch ex As Exception + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "OnlyFans.UserData.OFS_CreateAuth", False) + End Try + End Function +#End Region #Region "DownloadContent" + Private OFSPostFiles As Dictionary(Of String, List(Of SFile)) = Nothing Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken) DownloadContentDefault(Token) + OFSCache.DisposeIfReady + OFSPostFiles.ListClearDispose End Sub + Protected Overrides Function ValidateDownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByRef Interrupt As Boolean) As Boolean + Return Media.Type = UTypes.VideoPre + End Function + Protected Overrides Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, + ByVal Token As CancellationToken) As SFile + ValidateOFScraper() + If _OFScraperExists Then + If OFSPostFiles Is Nothing Then OFSPostFiles = New Dictionary(Of String, List(Of SFile)) + If IsSingleObjectDownload Then + URL = Media.URL_BASE + Else + URL = GetPostUrl(Me, Media) + End If + If Not URL.IsEmptyString Then + Dim f As SFile = Nothing + If OFSPostFiles.Count > 0 AndAlso OFSPostFiles.ContainsKey(Media.Post.ID) AndAlso OFSPostFiles(Media.Post.ID).Count > 0 Then + f = OFSPostFiles(Media.Post.ID)(0) + OFSPostFiles(Media.Post.ID).RemoveAt(0) + Else + Dim files As List(Of SFile) = OFS_DownloadFile(URL, Token) + If files.ListExists Then + Dim ff As SFile + For i% = files.Count - 1 To 0 Step -1 + ff = files(i) + DestinationFile.Name = ff.Name + DestinationFile.Extension = ff.Extension + If SFile.Move(ff, DestinationFile,,,, EDP.ThrowException) Then + files(i) = DestinationFile + Else + files.RemoveAt(i) + End If + Next + If files.Count > 0 Then + f = files(0) + files.RemoveAt(0) + If files.Count > 0 Then OFSPostFiles.Add(Media.Post.ID, files) + End If + End If + End If + Return f + End If + Return Nothing + Else + Throw New InvalidProgramException("OF-Scraper not found") + End If + End Function #End Region #Region "DownloadingException" Private _DownloadingException_AuthFileUpdate As Boolean = False @@ -546,7 +704,7 @@ Namespace API.OnlyFans Return 2 Else MySettings.SessionAborted = True - MyMainLOG = $"{ToStringForLog()}: OnlyFans credentials expired" + MyMainLOG = $"{ToStringForLog()} [{CInt(Responser.StatusCode)}]: OnlyFans credentials expired" Return 1 End If ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then '404 @@ -558,7 +716,7 @@ Namespace API.OnlyFans Return 1 ElseIf Responser.StatusCode = Net.HttpStatusCode.Unauthorized Then '401 MySettings.SessionAborted = True - MyMainLOG = $"{ToStringForLog()}: OnlyFans credentials expired" + MyMainLOG = $"{ToStringForLog()} [{CInt(Responser.StatusCode)}]: OnlyFans credentials expired" Return 1 Else Return 0 @@ -567,7 +725,13 @@ Namespace API.OnlyFans #End Region #Region "IDisposable Support" Protected Overrides Sub Dispose(ByVal disposing As Boolean) - If Not disposedValue And disposing Then CCookie.DisposeIfReady(False) : CCookie = Nothing : HighlightsList.Clear() + If Not disposedValue And disposing Then + CCookie.DisposeIfReady(False) + CCookie = Nothing + HighlightsList.Clear() + OFSCache.DisposeIfReady + OFSPostFiles.ListClearDispose + End If MyBase.Dispose(disposing) End Sub #End Region diff --git a/SCrawler/Download/TDownloader.vb b/SCrawler/Download/TDownloader.vb index 334dd51..e4d821b 100644 --- a/SCrawler/Download/TDownloader.vb +++ b/SCrawler/Download/TDownloader.vb @@ -122,7 +122,14 @@ Namespace DownloadObjects Return _FilesSessionActual End Get End Property + Private _FilesSaving As Boolean = False Friend Sub FilesSave() + While _FilesSaving Or _FilesUpdating : Thread.Sleep(100) : End While + Dim i% = 0 + While Not FilesSaveImpl() And i < 10 : i += 1 : End While + End Sub + Private Function FilesSaveImpl() As Boolean + _FilesSaving = True Try If Settings.FeedStoreSessionsData And Files.Count > 0 Then ClearSessions() @@ -131,10 +138,13 @@ Namespace DownloadObjects x.Save(FilesSessionActual) End Using End If + Return True Catch ex As Exception - ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadObjects.TDownloader.FilesSave]") + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadObjects.TDownloader.FilesSave]", False) + Finally + _FilesSaving = False End Try - End Sub + End Function Private _FilesUpdating As Boolean = False Friend Sub FilesUpdatePendingUsers() _FilesUpdating = True diff --git a/SCrawler/MainFrameObjects.vb b/SCrawler/MainFrameObjects.vb index 13d300a..dcd50ee 100644 --- a/SCrawler/MainFrameObjects.vb +++ b/SCrawler/MainFrameObjects.vb @@ -99,7 +99,7 @@ Friend Class MainFrameObjects : Implements INotificator Case $"{NotificationInternalKey}_{NotifyObj.Channels}" : MF.MyChannels.FormShowS() Case $"{NotificationInternalKey}_{NotifyObj.SavedPosts}" : MF.MySavedPosts.FormShowS() Case $"{NotificationInternalKey}_{NotifyObj.STDownloader}" : VideoDownloader.FormShowS() - Case $"{NotificationInternalKey}_{NotifyObj.LOG}" : ShowLog() + Case $"{NotificationInternalKey}_{NotifyObj.LOG}" : ControlInvokeFast(MF, AddressOf ShowLog, EDP.LogMessageValue) Case Else : Focus(True) End Select ElseIf Settings.Automation Is Nothing OrElse Not Settings.Automation.NotificationClicked(Key, found, activateForm) Then diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb index f1bdf57..e697e86 100644 --- a/SCrawler/My Project/AssemblyInfo.vb +++ b/SCrawler/My Project/AssemblyInfo.vb @@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj index de66db4..78d5314 100644 --- a/SCrawler/SCrawler.vbproj +++ b/SCrawler/SCrawler.vbproj @@ -194,6 +194,11 @@ + + True + True + OFResources.resx + @@ -490,6 +495,11 @@ InternalSettingsForm.vb + + My.Resources + ResXFileCodeGenerator + OFResources.Designer.vb + RedditViewSettingsForm.vb @@ -588,6 +598,7 @@ +