From 12c02580f6093dff5ce9ca8559c351bd5055bfe1 Mon Sep 17 00:00:00 2001 From: Andy <88590076+AAndyProgram@users.noreply.github.com> Date: Thu, 9 Nov 2023 18:10:18 +0300 Subject: [PATCH] 2023.11.9.0 ADD MULTI-ACCOUNT PluginProvider IDownloadableMedia: added 'AccountName' property IPluginContentProvider: added 'AccountName' property ISiteSettings: added properties: 'AccountName', 'Temporary', 'AvailableText', 'DefaultInstance'; added functions: 'Clone', 'Update', 'Delete'; removed 'Load' function; implement 'IDisposable' interface PropertyValue: added functions: 'BeginInit', 'EndInit', 'Clone' YT YouTubeSettings: make the class compatible for multi-acc YouTubeMediaContainerBase: add 'AccountName' property SCrawler IUserData: add properties: 'HostStatic', 'AccountName' ProfileSaved: add the ability to download saved posts from all accounts SiteSettingsBase: add multi-acc support; add 'UserOptionsType' for future purposes; update initializers; update responser initializing; add 'CLONE_PROPERTIES' and 'CloneGetEmptySettingsInstance' functions; 'IDisposable' support UserDataBase: add multi-acc support; change host retrieval method DomainsContainer: implements 'IDisposable' interface API.All sites: add multi-acc support; move the Icon and Image setting to the initializer; update initializer API.Instagram: change some property types API.Reddit: set 'AvailableText'; update 'UpdateRedGifsToken' and 'UserOptions' functions API.Mastodon: remove 'MastodonDomains' class and 'SettingsForm' form; replace 'MastodonDomains' with 'DomainsContainer'; update functions 'IsMyUser' and 'IsMyImageVideo'; update to 'DefaultInstance' environment; update 'UserData.ResetCredentials' function API.XVIDEOS: update to 'DefaultInstance' environment API.Xhamster: update to 'DefaultInstance' environment STDownloader: add multi-acc compatibility SiteEditorForm: add option 'Download saved posts'; update providers; add additional providers; add multi-acc support PluginsEnvironment: add 'PClonableAttribute'; add multi-acc support --- .../Interfaces/IDownloadableMedia.vb | 1 + .../Interfaces/IPluginContentProvider.vb | 1 + .../Interfaces/ISiteSettings.vb | 14 +- .../Objects/PropertyValue.vb | 20 +- SCrawler.YouTube/Base/YouTubeSettings.vb | 15 +- .../Objects/YouTubeMediaContainerBase.vb | 1 + SCrawler/API/Base/IUserData.vb | 2 + SCrawler/API/Base/ProfileSaved.vb | 61 ++- SCrawler/API/Base/SiteSettingsBase.vb | 205 ++++++++- SCrawler/API/Base/UserDataBase.vb | 67 ++- SCrawler/API/BaseObjects/DomainsContainer.vb | 24 +- .../API/BaseObjects/InternalSettingsForm.vb | 20 +- SCrawler/API/Gfycat/Envir.vb | 6 +- SCrawler/API/Instagram/SiteSettings.vb | 99 ++-- SCrawler/API/JustForFans/SiteSettings.vb | 22 +- SCrawler/API/JustForFans/UserData.vb | 2 +- SCrawler/API/LPSG/SiteSettings.vb | 14 +- SCrawler/API/Mastodon/MastodonDomains.vb | 65 --- .../API/Mastodon/SettingsForm.Designer.vb | 165 ------- SCrawler/API/Mastodon/SettingsForm.resx | 292 ------------ SCrawler/API/Mastodon/SettingsForm.vb | 154 ------- SCrawler/API/Mastodon/SiteSettings.vb | 85 ++-- SCrawler/API/Mastodon/UserData.vb | 17 +- SCrawler/API/OnlyFans/SiteSettings.vb | 36 +- SCrawler/API/OnlyFans/UserData.vb | 2 +- SCrawler/API/PathPlugin/SiteSettings.vb | 13 +- SCrawler/API/Pinterest/SiteSettings.vb | 19 +- SCrawler/API/PornHub/SiteSettings.vb | 32 +- SCrawler/API/Reddit/Channel.vb | 21 +- SCrawler/API/Reddit/IRedditView.vb | 8 + .../Reddit/RedditViewSettingsForm.Designer.vb | 100 +++- .../API/Reddit/RedditViewSettingsForm.resx | 184 +++++++- SCrawler/API/Reddit/RedditViewSettingsForm.vb | 49 +- SCrawler/API/Reddit/SiteSettings.vb | 51 +- SCrawler/API/Reddit/UserData.vb | 61 ++- SCrawler/API/Redgifs/SiteSettings.vb | 20 +- SCrawler/API/Redgifs/UserData.vb | 13 +- SCrawler/API/ThisVid/SiteSettings.vb | 22 +- SCrawler/API/ThreadsNet/SiteSettings.vb | 30 +- SCrawler/API/TikTok/SiteSettings.vb | 22 +- SCrawler/API/Twitter/SiteSettings.vb | 38 +- SCrawler/API/XVIDEOS/SiteSettings.vb | 32 +- SCrawler/API/Xhamster/SiteSettings.vb | 30 +- SCrawler/API/YouTube/SiteSettings.vb | 22 +- SCrawler/Channels/ChannelViewForm.vb | 38 +- SCrawler/Download/DownloadProgress.vb | 18 +- SCrawler/Download/DownloadSavedPostsForm.vb | 2 +- .../DownloaderUrlForm.Designer.vb | 45 +- .../STDownloader/DownloaderUrlForm.resx | 90 ++++ .../STDownloader/DownloaderUrlForm.vb | 36 ++ .../DownloaderUrlsArrForm.Designer.vb | 43 +- .../STDownloader/DownloaderUrlsArrForm.resx | 90 ++++ .../STDownloader/DownloaderUrlsArrForm.vb | 40 ++ .../STDownloader/VideoDownloaderForm.vb | 6 +- SCrawler/Download/TDownloader.vb | 126 +++-- .../Editors/GlobalSettingsForm.Designer.vb | 370 ++++++++------- SCrawler/Editors/GlobalSettingsForm.resx | 63 ++- SCrawler/Editors/GlobalSettingsForm.vb | 2 + SCrawler/Editors/SiteEditorForm.Designer.vb | 78 +++- SCrawler/Editors/SiteEditorForm.resx | 24 + SCrawler/Editors/SiteEditorForm.vb | 159 ++++++- SCrawler/Editors/UserCreatorForm.Designer.vb | 87 ++-- SCrawler/Editors/UserCreatorForm.resx | 90 ++++ SCrawler/Editors/UserCreatorForm.vb | 81 +++- SCrawler/MainFrame.vb | 27 +- .../Attributes/Attributes.vb | 4 + .../Hosts/DownloadableMediaHost.vb | 10 +- .../PluginsEnvironment/Hosts/PluginHost.vb | 49 +- .../Hosts/PropertyValueHost.vb | 32 +- .../PluginsEnvironment/Hosts/SettingsHost.vb | 196 +++++++- .../Hosts/SettingsHostCollection.vb | 434 ++++++++++++++++++ .../PluginsEnvironment/Hosts/UserDataHost.vb | 1 + SCrawler/SCrawler.vbproj | 11 +- SCrawler/SettingsCLS.vb | 14 +- SCrawler/UserFinder.vb | 7 +- SCrawler/UserInfo.vb | 22 +- 76 files changed, 2866 insertions(+), 1586 deletions(-) delete mode 100644 SCrawler/API/Mastodon/MastodonDomains.vb delete mode 100644 SCrawler/API/Mastodon/SettingsForm.Designer.vb delete mode 100644 SCrawler/API/Mastodon/SettingsForm.resx delete mode 100644 SCrawler/API/Mastodon/SettingsForm.vb create mode 100644 SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb diff --git a/SCrawler.PluginProvider/Interfaces/IDownloadableMedia.vb b/SCrawler.PluginProvider/Interfaces/IDownloadableMedia.vb index 76de874..aa6b6f1 100644 --- a/SCrawler.PluginProvider/Interfaces/IDownloadableMedia.vb +++ b/SCrawler.PluginProvider/Interfaces/IDownloadableMedia.vb @@ -14,6 +14,7 @@ Namespace Plugin ReadOnly Property SiteIcon As Drawing.Image ReadOnly Property Site As String ReadOnly Property SiteKey As String + Property AccountName As String Property ThumbnailUrl As String Property ThumbnailFile As String Property Title As String diff --git a/SCrawler.PluginProvider/Interfaces/IPluginContentProvider.vb b/SCrawler.PluginProvider/Interfaces/IPluginContentProvider.vb index 0b6e93f..a666861 100644 --- a/SCrawler.PluginProvider/Interfaces/IPluginContentProvider.vb +++ b/SCrawler.PluginProvider/Interfaces/IPluginContentProvider.vb @@ -15,6 +15,7 @@ Namespace Plugin Property Thrower As IThrower Property LogProvider As ILogProvider Property Settings As ISiteSettings + Property AccountName As String Property Name As String Property ID As String Property Options As String diff --git a/SCrawler.PluginProvider/Interfaces/ISiteSettings.vb b/SCrawler.PluginProvider/Interfaces/ISiteSettings.vb index 30ed1f0..b6e1045 100644 --- a/SCrawler.PluginProvider/Interfaces/ISiteSettings.vb +++ b/SCrawler.PluginProvider/Interfaces/ISiteSettings.vb @@ -8,7 +8,7 @@ ' but WITHOUT ANY WARRANTY Imports System.Drawing Namespace Plugin - Public Interface ISiteSettings + Public Interface ISiteSettings : Inherits IDisposable Enum Download As Integer Main = 0 SavedPosts = 1 @@ -17,6 +17,9 @@ Namespace Plugin ReadOnly Property Icon As Icon ReadOnly Property Image As Image ReadOnly Property Site As String + Property AccountName As String + Property Temporary As Boolean + Property DefaultInstance As ISiteSettings ReadOnly Property SubscriptionsAllowed As Boolean Property Logger As ILogProvider Function GetUserUrl(ByVal User As IPluginContentProvider) As String @@ -25,9 +28,6 @@ Namespace Plugin Function GetInstance(ByVal What As Download) As IPluginContentProvider Function GetSingleMediaInstance(ByVal URL As String, ByVal OutputFile As String) As IDownloadableMedia Function GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String -#Region "XML Support" - Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) -#End Region #Region "Initialization" Sub BeginInit() Sub EndInit() @@ -37,6 +37,7 @@ Namespace Plugin Sub EndEdit() #End Region #Region "Site availability" + Property AvailableText As String Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean Function ReadyToDownload(ByVal What As Download) As Boolean #End Region @@ -46,7 +47,10 @@ Namespace Plugin Sub AfterDownload(ByVal User As Object, ByVal What As Download) Sub DownloadDone(ByVal What As Download) #End Region - Sub Update() + Function Clone(ByVal Full As Boolean) As ISiteSettings + Sub Delete() + Overloads Sub Update() + Overloads Sub Update(ByVal Source As ISiteSettings) Sub Reset() Sub OpenSettingsForm() Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) diff --git a/SCrawler.PluginProvider/Objects/PropertyValue.vb b/SCrawler.PluginProvider/Objects/PropertyValue.vb index 98d9088..fd4d956 100644 --- a/SCrawler.PluginProvider/Objects/PropertyValue.vb +++ b/SCrawler.PluginProvider/Objects/PropertyValue.vb @@ -11,6 +11,7 @@ Namespace Plugin Public Event ValueChanged As IPropertyValue.ValueChangedEventHandler Implements IPropertyValue.ValueChanged Public Property [Type] As Type Implements IPropertyValue.Type Public Property OnChangeFunction As IPropertyValue.ValueChangedEventHandler + Private _Initialization As Boolean = False ''' ''' Public Sub New(ByVal InitValue As Object) @@ -41,10 +42,25 @@ Namespace Plugin End Get Set(ByVal NewValue As Object) _Value = NewValue - If Not OnChangeFunction Is Nothing Then OnChangeFunction.Invoke(Value) - RaiseEvent ValueChanged(_Value) + If Not _Initialization Then + If Not OnChangeFunction Is Nothing Then OnChangeFunction.Invoke(Value) + RaiseEvent ValueChanged(_Value) + End If End Set End Property + Public Sub BeginInit() + _Initialization = True + End Sub + Public Sub EndInit() + _Initialization = False + End Sub + Public Sub Clone(ByVal Source As PropertyValue) + _Initialization = True + Type = Source.Type + OnChangeFunction = Source.OnChangeFunction + _Value = Source._Value + _Initialization = False + End Sub End Class Public Interface IPropertyValue ''' Event for internal exchange diff --git a/SCrawler.YouTube/Base/YouTubeSettings.vb b/SCrawler.YouTube/Base/YouTubeSettings.vb index 35dd437..a1b2989 100644 --- a/SCrawler.YouTube/Base/YouTubeSettings.vb +++ b/SCrawler.YouTube/Base/YouTubeSettings.vb @@ -35,6 +35,7 @@ Namespace API.YouTube.Base Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer) Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection + Public Overridable Property AccountName As String #Region "Environment" #Region "Programs" Public Property AccountName As String = String.Empty Implements IDownloadableMedia.AccountName Public Property IsMusic As Boolean = False Implements IYouTubeMediaContainer.IsMusic Public Property IsShorts As Boolean = False Implements IYouTubeMediaContainer.IsShorts Public Property ID As String Implements IYouTubeMediaContainer.ID, IUserMedia.PostID diff --git a/SCrawler/API/Base/IUserData.vb b/SCrawler/API/Base/IUserData.vb index 7a073ac..0ecf299 100644 --- a/SCrawler/API/Base/IUserData.vb +++ b/SCrawler/API/Base/IUserData.vb @@ -50,6 +50,8 @@ Namespace API.Base Property Suspended As Boolean Property ReadyForDownload As Boolean Property HOST As SettingsHost + Property HostStatic As Boolean + Property AccountName As String Property [File] As SFile Property FileExists As Boolean Property DownloadedPictures(ByVal Total As Boolean) As Integer diff --git a/SCrawler/API/Base/ProfileSaved.vb b/SCrawler/API/Base/ProfileSaved.vb index 079a579..52d6015 100644 --- a/SCrawler/API/Base/ProfileSaved.vb +++ b/SCrawler/API/Base/ProfileSaved.vb @@ -12,43 +12,72 @@ Imports PersonalUtilities.Forms.Toolbars Imports PDownload = SCrawler.Plugin.ISiteSettings.Download Namespace API.Base Friend NotInheritable Class ProfileSaved - Private ReadOnly Property HOST As SettingsHost + Private ReadOnly Property HOST As SettingsHostCollection Private ReadOnly Property Progress As MyProgress - Friend Sub New(ByRef h As SettingsHost, ByRef Bar As MyProgress) + Private _Unavailable As Integer, _NotReady As Integer, _ErrorCount As Integer + Private _TotalImages As Integer, _TotalVideos As Integer + Friend Sub New(ByRef h As SettingsHostCollection, ByRef Bar As MyProgress) HOST = h Progress = Bar End Sub - Friend Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean) + Friend Overloads Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean) + Dim n% = 0 + Dim c% = HOST.Sum(Function(h) IIf(h.DownloadSavedPosts, 1, 0)) + _Unavailable = 0 + _NotReady = 0 + _ErrorCount = 0 + _TotalImages = 0 + _TotalVideos = 0 + If c > 0 Then + For i% = 0 To HOST.Count - 1 + If HOST(i).DownloadSavedPosts Then n += 1 : Download(HOST(i), n, c, Token, Multiple) + Next + If c > 1 Then + Dim s% = {_Unavailable, _NotReady, _ErrorCount}.Sum + Progress.InformationTemporary = $"{HOST.Name} ({c - s}/{c}) Images: {_TotalImages}; Videos: {_TotalVideos}" + End If + End If + 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) + Dim aStr$ = String.Empty + If Count > 1 Then aStr = $" ({Number}/{Count})" Try - If HOST.Source.ReadyToDownload(PDownload.SavedPosts) Then - If HOST.Available(PDownload.SavedPosts, Multiple) Then - HOST.DownloadStarted(PDownload.SavedPosts) - Dim u As New UserInfo With {.Plugin = HOST.Key, .Site = HOST.Name, .SpecialPath = HOST.SavedPostsPath} - Using user As IUserData = HOST.GetInstance(PDownload.SavedPosts, Nothing, False, False) + If Host.Source.ReadyToDownload(PDownload.SavedPosts) Then + If Host.Available(PDownload.SavedPosts, Multiple Or Count > 1) Then + Host.DownloadStarted(PDownload.SavedPosts) + If Count > 1 Then Progress.Information = $"{Host.Name} - {Host.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}" + Using user As IUserData = Host.GetInstance(PDownload.SavedPosts, Nothing, False, False) If Not user Is Nothing Then With DirectCast(user, UserDataBase) + .HostStatic = True .IsSavedPosts = True .LoadUserInformation() .Progress = Progress If Not .FileExists Then .UpdateUserInformation() End With - HOST.BeforeStartDownload(user, PDownload.SavedPosts) + Host.BeforeStartDownload(user, PDownload.SavedPosts) user.DownloadData(Token) - Progress.InformationTemporary = $"{HOST.Name} Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}" - HOST.AfterDownload(user, PDownload.SavedPosts) + _TotalImages += user.DownloadedPictures(False) + _TotalVideos += user.DownloadedVideos(False) + Progress.InformationTemporary = $"{Host.Name}{aStr} Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}" + Host.AfterDownload(user, PDownload.SavedPosts) End If End Using Else - Progress.InformationTemporary = $"Host [{HOST.Name}] is unavailable" + _Unavailable += 1 + Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is unavailable" End If Else - Progress.InformationTemporary = $"Host [{HOST.Name}] is not ready" + _NotReady += 1 + Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready" End If Catch ex As Exception - Progress.InformationTemporary = $"{HOST.Name} downloading error" - ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({HOST.Key})]") + _ErrorCount += 1 + Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error" + ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({Host.Key}{aStr})]") Finally - HOST.DownloadDone(PDownload.SavedPosts) + Host.DownloadDone(PDownload.SavedPosts) MainFrameObj.UpdateLogButton() End Try End Sub diff --git a/SCrawler/API/Base/SiteSettingsBase.vb b/SCrawler/API/Base/SiteSettingsBase.vb index e9692a1..e9e223c 100644 --- a/SCrawler/API/Base/SiteSettingsBase.vb +++ b/SCrawler/API/Base/SiteSettingsBase.vb @@ -6,15 +6,32 @@ ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY +Imports System.Reflection Imports SCrawler.Plugin +Imports SCrawler.Plugin.Attributes +Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools.Web.Clients Imports PersonalUtilities.Functions.RegularExpressions Imports Download = SCrawler.Plugin.ISiteSettings.Download Namespace API.Base Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer +#Region "Declarations" Friend ReadOnly Property Site As String Implements ISiteSettings.Site + Protected _Icon As Icon = Nothing Friend Overridable ReadOnly Property Icon As Icon Implements ISiteSettings.Icon + Get + Return _Icon + End Get + End Property + Protected _Image As Image = Nothing Friend Overridable ReadOnly Property Image As Image Implements ISiteSettings.Image + Get + Return _Image + End Get + End Property + Friend Property AccountName As String Implements ISiteSettings.AccountName + Friend Property Temporary As Boolean = False Implements ISiteSettings.Temporary + Friend Property DefaultInstance As ISiteSettings = Nothing Implements ISiteSettings.DefaultInstance Protected _AllowUserAgentUpdate As Boolean = True Protected _SubscriptionsAllowed As Boolean = False Friend ReadOnly Property SubscriptionsAllowed As Boolean Implements ISiteSettings.SubscriptionsAllowed @@ -24,7 +41,25 @@ Namespace API.Base End Property Private Property Logger As ILogProvider = LogConnector Implements ISiteSettings.Logger Friend Overridable ReadOnly Property Responser As Responser + Private _UserOptionsExists As Boolean = False + Private _UserOptionsType As Type = Nothing + Protected Property UserOptionsType As Type + Get + Return _UserOptionsType + End Get + Set(ByVal t As Type) + _UserOptionsType = t + _UserOptionsExists = Not t Is Nothing + End Set + End Property +#End Region +#Region "Responser and cookies support" + Private _CookiesNetscapeFile As SFile = Nothing Friend ReadOnly Property CookiesNetscapeFile As SFile + Get + Return _CookiesNetscapeFile + End Get + End Property Protected CheckNetscapeCookiesOnEndInit As Boolean = False Private _UseNetscapeCookies As Boolean = False Protected Property UseNetscapeCookies As Boolean @@ -47,22 +82,46 @@ Namespace API.Base End Get Set : End Set End Property + Protected Sub UpdateResponserFile() + Dim acc$ = If(Not AccountName.IsEmptyString, $"_{AccountName}", String.Empty) + Responser.File = $"{SettingsFolderName}\Responser_{Site}{acc}.xml" + _CookiesNetscapeFile = Responser.File + _CookiesNetscapeFile.Name &= "_Cookies_Netscape" + _CookiesNetscapeFile.Extension = "txt" + End Sub +#End Region +#Region "GetInstance" Friend MustOverride Function GetInstance(ByVal What As Download) As IPluginContentProvider Implements ISiteSettings.GetInstance - Friend Sub New(ByVal SiteName As String) +#End Region +#Region "Initializers" + Friend Sub New(ByVal SiteName As String, Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing) Site = SiteName - CookiesNetscapeFile = $"{SettingsFolderName}\Responser_{Site}_Cookies_Netscape.txt" + _Icon = __Icon + _Image = __Image + Responser = New Responser With {.DeclaredError = EDP.ThrowException} + UpdateResponserFile() End Sub - Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String) - Me.New(SiteName) - Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml") With {.DeclaredError = EDP.ThrowException} - With Responser - .CookiesDomain = CookiesDomain - .CookiesEncryptKey = SettingsCLS.CookieEncryptKey - If .File.Exists Then .LoadSettings() Else .SaveSettings() - End With - End Sub -#Region "XML" - Friend Overridable Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Implements ISiteSettings.Load + Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean, + Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing) + Me.New(SiteName, __Icon, __Image) + Temporary = Temp + AccountName = AccName + If Temporary Then + With Responser + .File = Nothing + .Cookies.File = Nothing + .CookiesDomain = CookiesDomain + .CookiesEncryptKey = SettingsCLS.CookieEncryptKey + End With + _CookiesNetscapeFile = Nothing + Else + UpdateResponserFile() + With Responser + .CookiesDomain = CookiesDomain + .CookiesEncryptKey = SettingsCLS.CookieEncryptKey + If .File.Exists Then .LoadSettings() Else .SaveSettings() + End With + End If End Sub #End Region #Region "Initialize" @@ -86,7 +145,7 @@ Namespace API.Base If _SiteEditorFormOpened Then DomainsReset() _SiteEditorFormOpened = False End Sub - Friend Overridable Sub Update() Implements ISiteSettings.Update + Friend Overridable Overloads Sub Update() Implements ISiteSettings.Update If _SiteEditorFormOpened Then If UseNetscapeCookies Then Update_SaveCookiesNetscape() If Not Responser Is Nothing Then @@ -98,6 +157,17 @@ Namespace API.Base End If If Not Responser Is Nothing Then Responser.SaveSettings() End Sub + Friend Overridable Overloads Sub Update(ByVal Source As ISiteSettings) Implements ISiteSettings.Update + AccountName = Source.AccountName + If Not Responser Is Nothing Then Responser.Copy(DirectCast(Source, SiteSettingsBase).Responser) : UpdateResponserFile() : Responser.SaveSettings() + Update_CloneProperties(Source) + UpdateImpl(Source) + End Sub + Protected Overridable Sub Update_CloneProperties(ByVal Source As ISiteSettings) + CLONE_PROPERTIES(Source, Me, True) + End Sub + Protected Overridable Sub UpdateImpl(ByVal Source As ISiteSettings) + End Sub Protected Sub Update_SaveCookiesNetscape(Optional ByVal Force As Boolean = False, Optional ByVal IsInit As Boolean = False) If Not Responser Is Nothing Then With Responser @@ -142,6 +212,7 @@ Namespace API.Base End Sub ''' Friend Overridable Sub DownloadDone(ByVal What As Download) Implements ISiteSettings.DownloadDone + AvailableText = String.Empty End Sub #End Region #Region "User info" @@ -184,6 +255,7 @@ Namespace API.Base End Function #End Region #Region "Ready, Available" + Friend Property AvailableText As String Implements ISiteSettings.AvailableText ''' True Friend Overridable Function BaseAuthExists() As Boolean Return True @@ -199,12 +271,115 @@ Namespace API.Base Return True End Function #End Region + Protected Sub CLONE_PROPERTIES(ByVal Source As ISiteSettings, ByVal Destination As ISiteSettings, ByVal IsUpdate As Boolean, + Optional ByVal Full As Boolean = True) + Dim comparer As New MembersDistinctComparer + '0 = update + '1 = clone + '2 = any + Dim filterUC As Func(Of MemberInfo, Byte, Boolean) = Function(ByVal m As MemberInfo, ByVal __mode As Byte) As Boolean + With m.GetCustomAttribute(Of PClonableAttribute) + Return Not .Self Is Nothing AndAlso (__mode = 2 OrElse If(__mode = 0, .Update, .Clone)) + End With + End Function + Dim filterAll As Func(Of MemberInfo, Boolean) = Function(m) filterUC.Invoke(m, 2) + Dim filterC As Func(Of MemberInfo, Boolean) = Function(m) If(Full, filterAll.Invoke(m), filterUC.Invoke(m, 1)) + Dim filterU As Func(Of MemberInfo, Boolean) = Function(m) filterUC.Invoke(m, 0) + Dim membersSource As IEnumerable(Of MemberInfo) = GetObjectMembers(Source, filterAll,, True, comparer) + If membersSource.ListExists Then + Dim membersDest As IEnumerable(Of MemberInfo) = GetObjectMembers(Destination, If(IsUpdate, filterU, filterC),, True, comparer) + If membersDest.ListExists Then + Dim mSource As MemberInfo = Nothing, mDest As MemberInfo = Nothing + Dim destIndx% + Dim isPropertyValue As Boolean + Dim sourceValue As Object + For Each mSource In membersSource + destIndx = membersDest.ListIndexOf(mSource, comparer, EDP.ReturnValue) + If destIndx.ValueBetween(0, membersDest.Count - 1) Then mDest = membersDest(destIndx) Else mDest = Nothing + If Not mDest Is Nothing Then + sourceValue = mSource.GetMemberValue(Source) + If mDest.MemberType = MemberTypes.Property Then + isPropertyValue = DirectCast(mDest, PropertyInfo).PropertyType Is GetType(PropertyValue) + Else + isPropertyValue = DirectCast(mDest, FieldInfo).FieldType Is GetType(PropertyValue) + End If + If isPropertyValue Then + DirectCast(mDest.GetMemberValue(Destination), PropertyValue).Clone(sourceValue) + Else + mDest.SetMemberValue(Destination, sourceValue) + End If + End If + Next + End If + End If + End Sub + Protected Overridable Function CloneGetEmptySettingsInstance() As ISiteSettings + Dim _max% = -1 + Dim c As ConstructorInfo = Nothing + With Me.GetType.GetTypeInfo.DeclaredConstructors + If .ListExists Then + With .Where(Function(m) If(m.GetParameters?.Count, 0).ValueBetween(0, 2)) + If .ListExists Then + _max = .Max(Function(m) If(m.GetParameters?.Count, 0)) + c = .First(Function(m) If(m.GetParameters?.Count, 0) = _max) + End If + End With + End If + Select Case _max + Case 2 : Return c.Invoke({String.Empty, True}) + Case 1 : Return c.Invoke({String.Empty}) + Case 0 : Return c.Invoke(Nothing) + Case Else : Return Activator.CreateInstance(Me.GetType) + End Select + End With + End Function + Friend Overridable Function Clone(ByVal Full As Boolean) As ISiteSettings Implements ISiteSettings.Clone + Dim obj As ISiteSettings = CloneGetEmptySettingsInstance() + CLONE_PROPERTIES(Me, obj, False, Full) + Return obj + End Function + Friend Sub Delete() Implements ISiteSettings.Delete + If Not Responser Is Nothing Then + With Responser + If .File.Exists Then .File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None) + If .Cookies.File.Exists Then .Cookies.File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None) + End With + If _CookiesNetscapeFile.Exists Then _CookiesNetscapeFile.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None) + End If + End Sub Friend Overridable Sub Reset() Implements ISiteSettings.Reset End Sub Friend Overridable Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions - Options = Nothing + If _UserOptionsExists Then + If Options Is Nothing OrElse Not Options.GetType Is _UserOptionsType Then + Options = AConvert(Me, AModes.Var, _UserOptionsType,, True, Nothing) + If Options Is Nothing Then Options = Activator.CreateInstance(_UserOptionsType) + End If + If OpenForm Then + Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using + End If + Else + Options = Nothing + End If End Sub Friend Overridable Sub OpenSettingsForm() Implements ISiteSettings.OpenSettingsForm End Sub +#Region "IDisposable Support" + Protected disposedValue As Boolean = False + Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue Then + If disposing Then Responser.DisposeIfReady + disposedValue = True + End If + End Sub + Protected Overrides Sub Finalize() + Dispose(False) + MyBase.Finalize() + End Sub + Friend Overloads Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + GC.SuppressFinalize(Me) + End Sub +#End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Base/UserDataBase.vb b/SCrawler/API/Base/UserDataBase.vb index 701185a..75590fc 100644 --- a/SCrawler/API/Base/UserDataBase.vb +++ b/SCrawler/API/Base/UserDataBase.vb @@ -126,6 +126,7 @@ Namespace API.Base #Region "XML Declarations" Private Const Name_Site As String = UserInfo.Name_Site Private Const Name_Plugin As String = UserInfo.Name_Plugin + Private Const Name_AccountName As String = UserInfo.Name_AccountName Protected Const Name_IsChannel As String = "IsChannel" Friend Const Name_UserName As String = "UserName" Private Const Name_Model_User As String = UserInfo.Name_Model_User @@ -171,7 +172,48 @@ Namespace API.Base #End Region #Region "Declarations" #Region "Host, Site, Progress" + Friend Property HostCollection As SettingsHostCollection + Private Function HostObtainCollection() As Boolean + If HostCollection Is Nothing Then + Dim k$ = If(_HOST?.Key, _HostKey) + If Not k.IsEmptyString Then HostCollection = Settings(k) + End If + Return Not HostCollection Is Nothing + End Function + Private _HOST As SettingsHost + Private _HostKey As String = String.Empty + Private _HostObtained As Boolean = False Friend Property HOST As SettingsHost Implements IUserData.HOST + Get + If _HostObtained Or HostStatic Then + Return _HOST + ElseIf HostObtainCollection() Then + _HOST = HostCollection(AccountName) + _HostObtained = Not _HOST Is Nothing + Return _HOST + Else + Return Nothing + End If + End Get + Set(ByVal h As SettingsHost) + _HOST = h + _HostKey = h.Key + End Set + End Property + Private Sub ResetHost() + _HostObtained = False + End Sub + Friend Property HostStatic As Boolean = False Implements IUserData.HostStatic + Private _AccountName As String = String.Empty + Friend Overridable Property AccountName As String Implements IUserData.AccountName, IPluginContentProvider.AccountName + Get + Return _AccountName.IfNullOrEmpty(User.AccountName) + End Get + Set(ByVal name As String) + If Not _AccountName = name Then ResetHost() + _AccountName = name + End Set + End Property Friend ReadOnly Property Site As String Implements IUserData.Site Get Return HOST.Name @@ -845,6 +887,7 @@ BlockNullPicture: Friend Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean, Optional ByVal AttachUserInfo As Boolean = True) Implements IUserData.SetEnvironment HOST = h + HostObtainCollection() If AttachUserInfo Then User = u If _LoadUserInformation Then LoadUserInformation() @@ -853,7 +896,7 @@ BlockNullPicture: ''' Friend Shared Function GetInstance(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True) As IUserData If Not u.Plugin.IsEmptyString Then - Return Settings(u.Plugin).GetInstance(ISiteSettings.Download.Main, u, _LoadUserInformation) + Return Settings(u.Plugin).Default.GetInstance(ISiteSettings.Download.Main, u, _LoadUserInformation) Else Throw New ArgumentOutOfRangeException("Plugin", $"Plugin [{u.Plugin}] information does not recognized by loader") End If @@ -865,7 +908,7 @@ BlockNullPicture: With DirectCast(u, UserDataBase) If Not .User.Plugin.IsEmptyString Then uName = .User.Name - Return Settings(.User.Plugin).GetUserPostUrl(.Self, PostData) + Return Settings(.User.Plugin).Default.GetUserPostUrl(.Self, PostData) End If End With End If @@ -937,6 +980,7 @@ BlockNullPicture: Using x As New XmlFile With {.Name = "User"} x.Add(Name_Site, Site) x.Add(Name_Plugin, HOST.Key) + x.Add(Name_AccountName, AccountName) x.Add(Name_UserName, User.Name) x.Add(Name_Model_User, CInt(UserModel)) x.Add(Name_Model_Collection, CInt(CollectionModel)) @@ -1130,11 +1174,13 @@ BlockNullPicture: End If End Sub Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IUserData.DownloadData + ResetHost() __DOWNLOAD_IN_PROGRESS = True OnUserDownloadStateChanged(True) Dim Canceled As Boolean = False TokenQueue = Token Try + If HOST Is Nothing Then Throw New ExitException($"Host '{AccountName}' not found") EnvirDownloadSet() If Not Responser Is Nothing Then Responser.Dispose() Responser = New Responser @@ -1291,7 +1337,12 @@ BlockNullPicture: #Region "DownloadSingleObject" Protected IsSingleObjectDownload As Boolean = False Friend Overridable Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) Implements IUserData.DownloadSingleObject + Dim URL$ = String.Empty Try + ResetHost() + URL = Data.URL + AccountName = Data.AccountName + If HOST Is Nothing Then Throw New ExitException($"Host '{AccountName}' not found") Data.DownloadState = UserMediaStates.Tried Progress = Data.Progress If Not Progress Is Nothing Then Progress.ResetProgressOnMaximumChanges = False @@ -1307,11 +1358,19 @@ BlockNullPicture: DownloadSingleObject_PostProcessing(Data) Catch oex As OperationCanceledException When Token.IsCancellationRequested Data.DownloadState = UserMediaStates.Missing - ErrorsDescriber.Execute(EDP.SendToLog, oex, $"{Site} download canceled: {Data.URL}") + ErrorsDescriber.Execute(EDP.SendToLog, oex, $"{Site} download canceled: {URL}") Catch dex As ObjectDisposedException When Disposed + Catch exit_ex As ExitException + If Not exit_ex.Silent Then + If exit_ex.SimpleLogLine Then + MyMainLOG = $"{URL}: downloading canceled (exit) ({exit_ex.Message})" + Else + ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{URL}: downloading canceled (exit)") + End If + End If Catch ex As Exception Data.DownloadState = UserMediaStates.Missing - ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{Site} single data downloader error: {Data.URL}") + ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{Site} single data downloader error: {URL}") End Try End Sub Protected Overridable Sub DownloadSingleObject_CreateMedia(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) diff --git a/SCrawler/API/BaseObjects/DomainsContainer.vb b/SCrawler/API/BaseObjects/DomainsContainer.vb index 023f132..92ae735 100644 --- a/SCrawler/API/BaseObjects/DomainsContainer.vb +++ b/SCrawler/API/BaseObjects/DomainsContainer.vb @@ -11,7 +11,7 @@ Imports PersonalUtilities.Forms Imports PersonalUtilities.Tools Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons Namespace API.Base - Friend Class DomainsContainer : Implements IEnumerable(Of String), IMyEnumerator(Of String) + Friend Class DomainsContainer : Implements IEnumerable(Of String), IMyEnumerator(Of String), IDisposable Friend Event DomainsUpdated(ByVal Sender As DomainsContainer) Friend ReadOnly Property Domains As List(Of String) Friend ReadOnly Property DomainsTemp As List(Of String) @@ -98,11 +98,33 @@ Namespace API.Base End If End Using End Sub +#Region "IEnumerable Support" Private Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator Return New MyEnumerator(Of String)(Me) End Function Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return GetEnumerator() End Function +#End Region +#Region "IDisposable Support" + Private disposedValue As Boolean = False + Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue Then + If disposing Then + Domains.Clear() + DomainsTemp.Clear() + End If + disposedValue = True + End If + End Sub + Protected Overrides Sub Finalize() + Dispose(False) + MyBase.Finalize() + End Sub + Friend Overloads Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + GC.SuppressFinalize(Me) + End Sub +#End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/BaseObjects/InternalSettingsForm.vb b/SCrawler/API/BaseObjects/InternalSettingsForm.vb index 987821e..4c96cac 100644 --- a/SCrawler/API/BaseObjects/InternalSettingsForm.vb +++ b/SCrawler/API/BaseObjects/InternalSettingsForm.vb @@ -20,7 +20,7 @@ Namespace API.Base Private ReadOnly Property MyMembers As List(Of MemberOption) ''' Default: 200 Friend Property MinimumWidth As Integer = 200 - Private Class MemberOption : Inherits Hosts.PropertyValueHost : Implements IDisposable + Private Class MemberOption : Inherits Hosts.PropertyValueHost Friend ToolTip As String Friend Caption As String Friend ThreeState As Boolean = False @@ -102,24 +102,6 @@ Namespace API.Base CreateControl(TT) If Not Provider Is Nothing Then f.AddControl(Control, Caption, Type, AllowNull, Activator.CreateInstance(Provider)) End Sub -#Region "IDisposable Support" - Private disposedValue As Boolean = False - Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) - If Not disposedValue Then - If disposing Then Control.Dispose() - Control = Nothing - disposedValue = True - End If - End Sub - Protected Overrides Sub Finalize() - Dispose(False) - MyBase.Finalize() - End Sub - Friend Overloads Sub Dispose() Implements IDisposable.Dispose - Dispose(True) - GC.SuppressFinalize(Me) - End Sub -#End Region End Class Friend Sub New(ByVal Obj As Object, ByVal s As ISiteSettings, ByVal _IsSettingsForm As Boolean) InitializeComponent() diff --git a/SCrawler/API/Gfycat/Envir.vb b/SCrawler/API/Gfycat/Envir.vb index 88a5164..17fe8c5 100644 --- a/SCrawler/API/Gfycat/Envir.vb +++ b/SCrawler/API/Gfycat/Envir.vb @@ -39,8 +39,8 @@ Namespace API.Gfycat If Not urlVideo.IsEmptyString Then If urlVideo.Contains("redgifs.com") Then _IsRedGifs = True - DirectCast(Settings(RedGifs.RedGifsSiteKey).Source, RedGifs.SiteSettings).UpdateTokenIfRequired() - Dim newData As IYouTubeMediaContainer = Settings(RedGifs.RedGifsSiteKey).GetSingleMediaInstance(urlVideo, Data.File) + DirectCast(Settings(RedGifs.RedGifsSiteKey).Default.Source, RedGifs.SiteSettings).UpdateTokenIfRequired() + Dim newData As IYouTubeMediaContainer = Settings(RedGifs.RedGifsSiteKey).Default.GetSingleMediaInstance(urlVideo, Data.File) If Not newData Is Nothing Then newData.Progress = Data.Progress newData.Download(Data.UseCookies, Token) @@ -49,7 +49,7 @@ Namespace API.Gfycat With DirectCast(Data, YouTubeMediaContainerBase) .Site = RedGifs.RedGifsSite .SiteKey = RedGifs.RedGifsSiteKey - .SiteIcon = Settings(RedGifs.RedGifsSiteKey).Source.Image + .SiteIcon = Settings(RedGifs.RedGifsSiteKey).Default.Source.Image End With Else Throw New Exception($"Unable to get RedGifs instance{vbCr}{Data.URL}{vbCr}{urlVideo}") diff --git a/SCrawler/API/Instagram/SiteSettings.vb b/SCrawler/API/Instagram/SiteSettings.vb index 888d8ab..071130d 100644 --- a/SCrawler/API/Instagram/SiteSettings.vb +++ b/SCrawler/API/Instagram/SiteSettings.vb @@ -10,9 +10,6 @@ Imports SCrawler.API.Base Imports SCrawler.Plugin Imports SCrawler.Plugin.Attributes Imports PersonalUtilities.Forms -Imports PersonalUtilities.Functions.XML -Imports PersonalUtilities.Functions.XML.Objects -Imports PersonalUtilities.Functions.XML.Base Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Tools.Web.Clients Imports PersonalUtilities.Tools.Web.Cookies @@ -21,18 +18,6 @@ Namespace API.Instagram Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" -#Region "Images" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.InstagramIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.InstagramPic_76 - End Get - End Property -#End Region #Region "Providers" Private Class TimersChecker : Inherits FieldsCheckerProviderBase Private ReadOnly LVProvider As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral} @@ -78,23 +63,23 @@ Namespace API.Instagram Friend Const Header_Browser As String = "Sec-Ch-Ua" Friend Const Header_BrowserExt As String = "Sec-Ch-Ua-Full-Version-List" Friend Const Header_Platform As String = "Sec-Ch-Ua-Platform-Version" - + Friend ReadOnly Property HashTagged As PropertyValue - + Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue - + Friend Property HH_IG_APP_ID As PropertyValue - + Friend Property HH_ASBD_ID As PropertyValue - + Friend Property HH_IG_WWW_CLAIM As PropertyValue - + Private Property HH_BROWSER As PropertyValue - + Private Property HH_BROWSER_EXT As PropertyValue - + Private Property HH_PLATFORM As PropertyValue - + Private Property HH_USER_AGENT As PropertyValue Friend Overrides Function BaseAuthExists() As Boolean Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value) And ACheck(HH_CSRF_TOKEN.Value) @@ -124,68 +109,69 @@ Namespace API.Instagram End Sub #End Region #Region "Download properties" - + Friend ReadOnly Property RequestsWaitTimer As PropertyValue Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider - + Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider - + Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider - + Friend ReadOnly Property GetTimeline As PropertyValue - + Friend ReadOnly Property GetStories As PropertyValue - + Friend ReadOnly Property GetStoriesUser As PropertyValue - + Friend ReadOnly Property GetTagged As PropertyValue + "-1 to disable"), PXML, ControlNumber(27), PClonable> Friend ReadOnly Property TaggedNotifyLimit As PropertyValue Private ReadOnly Property TaggedNotifyLimitProvider As IFormatProvider #End Region #Region "Download ready" - + Friend ReadOnly Property DownloadTimeline As PropertyValue - + Friend ReadOnly Property DownloadStories As PropertyValue - + Friend ReadOnly Property DownloadStoriesUser As PropertyValue - + Friend ReadOnly Property DownloadTagged As PropertyValue #End Region #Region "429 bypass" - Private ReadOnly Property DownloadingErrorDate As XMLValue(Of Date) + + Private ReadOnly Property DownloadingErrorDate As PropertyValue Friend Property LastApplyingValue As Integer? = Nothing Friend ReadOnly Property ReadyForDownload As Boolean Get If SkipUntilNextSession Then Return False With DownloadingErrorDate - If .ValueF.Exists Then - Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10)) < Now + If ACheck(Of Date)(.Value) Then + Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10)) < Now Else Return True End If End With End Get End Property - Private ReadOnly Property LastDownloadDate As XMLValue(Of Date) - Private ReadOnly Property LastRequestsCount As XMLValue(Of Integer) + Private ReadOnly Property LastDownloadDate As PropertyValue + Private ReadOnly Property LastRequestsCount As PropertyValue Private Property LastRequestsCountLabel As PropertyValue Private ReadOnly LastRequestsCountLabelStr As Func(Of Integer, String) = Function(r) $"Number of spent requests: {r.NumToGroupIntegral}" Private TooManyRequestsReadyForCatch As Boolean = True Friend Function GetWaitDate() As Date With DownloadingErrorDate - If .ValueF.Exists Then - Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10)) + If ACheck(Of Date)(.Value) Then + Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10)) Else Return Now End If @@ -194,7 +180,7 @@ Namespace API.Instagram Friend Sub TooManyRequests(ByVal Catched As Boolean) With DownloadingErrorDate If Catched Then - If Not .ValueF.Exists Then + If Not ACheck(Of Date)(.Value) Then .Value = Now If TooManyRequestsReadyForCatch Then LastApplyingValue = If(LastApplyingValue, 0) + 10 @@ -203,7 +189,7 @@ Namespace API.Instagram End If End If Else - .ValueF = Nothing + .Value = Nothing LastApplyingValue = Nothing TooManyRequestsReadyForCatch = True End If @@ -212,8 +198,8 @@ Namespace API.Instagram #End Region #End Region #Region "Initializer" - Friend Sub New(ByRef _XML As XmlFile, ByVal GlobalPath As SFile) - MyBase.New(InstagramSite, "instagram.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New(InstagramSite, "instagram.com", AccName, Temp, My.Resources.SiteResources.InstagramIcon_32, My.Resources.SiteResources.InstagramPic_76) Dim app_id$ = String.Empty Dim www_claim$ = String.Empty @@ -226,7 +212,7 @@ Namespace API.Instagram With Responser .Accept = "*/*" - useragent = .UserAgent + If .UserAgentExists Then useragent = .UserAgent Else .UserAgent = String.Empty With .Headers If .Count > 0 Then token = .Value(Header_CSRF_TOKEN) @@ -250,8 +236,6 @@ Namespace API.Instagram .CookiesExtractedAutoSave = False End With - Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString} - HashTagged = New PropertyValue(String.Empty, GetType(String)) HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v)) HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v)) @@ -281,12 +265,11 @@ Namespace API.Instagram TaggedNotifyLimit = New PropertyValue(200) TaggedNotifyLimitProvider = New TaggedNotifyLimitChecker - DownloadingErrorDate = New XMLValue(Of Date) With {.Provider = New XMLValueConversionProvider(Function(ss, nn, vv, dd) AConvert(Of String)(vv, AModes.Var, Nothing))} - DownloadingErrorDate.SetExtended("InstagramDownloadingErrorDate", Now.AddYears(-10), _XML, n) - LastDownloadDate = New XMLValue(Of Date)("LastDownloadDate", Now.AddDays(-1), _XML, n) - LastRequestsCount = New XMLValue(Of Integer)("LastRequestsCount", 0, _XML, n) + DownloadingErrorDate = New PropertyValue(Nothing, GetType(Date)) + LastDownloadDate = New PropertyValue(Now.AddDays(-1)) + LastRequestsCount = New PropertyValue(0) LastRequestsCountLabel = New PropertyValue(LastRequestsCountLabelStr.Invoke(LastRequestsCount.Value)) - AddHandler LastRequestsCount.ValueChanged, Sub(sender, e) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(DirectCast(sender, XMLValue(Of Integer)).ValueF.Value) + LastRequestsCount.OnChangeFunction = Sub(vv) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(vv) _AllowUserAgentUpdate = False UrlPatternUser = "https://www.instagram.com/{0}/" @@ -329,7 +312,7 @@ Namespace API.Instagram Private _NextTagged As Boolean = True Friend Overrides Sub DownloadStarted(ByVal What As Download) ActiveJobs += 1 - If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0" + If CDate(LastDownloadDate.Value).AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0" End Sub Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download) With DirectCast(User, UserData) @@ -337,8 +320,8 @@ Namespace API.Instagram .WaitNotificationMode = _NextWNM .TaggedCheckSession = _NextTagged End If - If LastDownloadDate.Value.AddMinutes(60) > Now Then - .RequestsCount = LastRequestsCount + If CDate(LastDownloadDate.Value).AddMinutes(60) > Now Then + .RequestsCount = LastRequestsCount.Value Else LastRequestsCount.Value = 0 .RequestsCount = 0 diff --git a/SCrawler/API/JustForFans/SiteSettings.vb b/SCrawler/API/JustForFans/SiteSettings.vb index 3a56955..7887cc3 100644 --- a/SCrawler/API/JustForFans/SiteSettings.vb +++ b/SCrawler/API/JustForFans/SiteSettings.vb @@ -15,32 +15,22 @@ Imports PersonalUtilities.Functions.RegularExpressions Namespace API.JustForFans Friend Class SiteSettings : Inherits SiteSettingsBase - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.JFFIcon_64 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.JFFPic_76 - End Get - End Property Friend Const UserHash4_CookieName As String = "userhash4" - + Friend ReadOnly Property UserID As PropertyValue - + Friend ReadOnly Property UserHash4 As PropertyValue - + Friend ReadOnly Property HeaderAccept As PropertyValue - Friend ReadOnly Property UserAgent As PropertyValue + Friend ReadOnly Property UserAgent As PropertyValue Private Sub UpdateHeader(ByVal HeaderName As String, ByVal HeaderValue As String) Select Case HeaderName Case NameOf(HeaderAccept) : If HeaderValue.IsEmptyString Then Responser.Accept = Nothing Else Responser.Accept = HeaderValue Case NameOf(UserAgent) : If Not HeaderValue.IsEmptyString Then Responser.UserAgent = HeaderValue End Select End Sub - Friend Sub New() - MyBase.New("JustForFans", "justfor.fans") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("JustForFans", "justfor.fans", AccName, Temp, My.Resources.SiteResources.JFFIcon_64, My.Resources.SiteResources.JFFPic_76) With Responser .CookiesExtractMode = Responser.CookiesExtractModes.Any diff --git a/SCrawler/API/JustForFans/UserData.vb b/SCrawler/API/JustForFans/UserData.vb index 788bcd7..233d355 100644 --- a/SCrawler/API/JustForFans/UserData.vb +++ b/SCrawler/API/JustForFans/UserData.vb @@ -297,7 +297,7 @@ Namespace API.JustForFans InitializeFileSerial() Dim r$ Dim m As UserMedia - Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ii As Integer) As UserMedia + Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ByVal ii As Integer) As UserMedia input.State = UserMedia.States.Missing input.Attempts = m.Attempts Return input diff --git a/SCrawler/API/LPSG/SiteSettings.vb b/SCrawler/API/LPSG/SiteSettings.vb index 0b82686..d4a3e7c 100644 --- a/SCrawler/API/LPSG/SiteSettings.vb +++ b/SCrawler/API/LPSG/SiteSettings.vb @@ -12,18 +12,8 @@ Imports PersonalUtilities.Functions.RegularExpressions Namespace API.LPSG Friend Class SiteSettings : Inherits Base.SiteSettingsBase - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.LPSGIcon_48 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.LPSGPic_32 - End Get - End Property - Friend Sub New() - MyBase.New("LPSG", "www.lpsg.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("LPSG", "www.lpsg.com", AccName, Temp, My.Resources.SiteResources.LPSGIcon_48, My.Resources.SiteResources.LPSGPic_32) UrlPatternUser = "https://www.lpsg.com/threads/{0}/" UserRegex = RParams.DMS(".+?lpsg.com/threads/[^/]+?\.(\d+)", 1, EDP.ReturnValue) End Sub diff --git a/SCrawler/API/Mastodon/MastodonDomains.vb b/SCrawler/API/Mastodon/MastodonDomains.vb deleted file mode 100644 index e116f0f..0000000 --- a/SCrawler/API/Mastodon/MastodonDomains.vb +++ /dev/null @@ -1,65 +0,0 @@ -' Copyright (C) 2023 Andy https://github.com/AAndyProgram -' This program is free software: you can redistribute it and/or modify -' it under the terms of the GNU General Public License as published by -' the Free Software Foundation, either version 3 of the License, or -' (at your option) any later version. -' -' This program is distributed in the hope that it will be useful, -' but WITHOUT ANY WARRANTY -Imports SCrawler.Plugin -Imports SCrawler.API.Base -Imports PersonalUtilities.Functions.XML -Namespace API.Mastodon - Friend Class MastodonDomains : Inherits DomainsContainer - Friend ReadOnly Property Credentials As List(Of Credentials) - Friend ReadOnly Property CredentialsTemp As List(Of Credentials) - Private ReadOnly CredentialsFile As SFile = $"{SettingsFolderName}\Responser_Mastodon_DomainsCredentials.xml" - Friend Sub New(ByVal _Instance As ISiteSettings, ByVal DefaultValue As String) - MyBase.New(_Instance, DefaultValue) - Credentials = New List(Of Credentials) - CredentialsTemp = New List(Of Credentials) - If CredentialsFile.Exists Then - Using x As New XmlFile(CredentialsFile,, False) With {.AllowSameNames = True, .XmlReadOnly = True} - x.LoadData() - If x.Count > 0 Then Credentials.ListAddList(x, LAP.IgnoreICopier) - End Using - End If - End Sub - Friend Overrides Function Apply() As Boolean - If Changed Then - Credentials.Clear() - If CredentialsTemp.Count > 0 Then Credentials.AddRange(CredentialsTemp) - CredentialsTemp.Clear() - End If - Return MyBase.Apply() - End Function - Friend Overrides Sub Save() - If Credentials.Count > 0 Then - Using x As New XmlFile With {.AllowSameNames = True} - x.AddRange(Credentials) - x.Name = "DomainsCredentials" - x.Save(CredentialsFile) - End Using - Else - CredentialsFile.Delete(,, EDP.None) - End If - MyBase.Save() - End Sub - Friend Overrides Sub Reset() - CredentialsTemp.Clear() - MyBase.Reset() - End Sub - Friend Overrides Sub OpenSettingsForm() - Using f As New SettingsForm(Instance) - f.ShowDialog() - If f.DialogResult = DialogResult.OK Then - Changed = True - CredentialsTemp.Clear() - If f.MyCredentials.Count > 0 Then CredentialsTemp.AddRange(f.MyCredentials) - DomainsTemp.Clear() - If f.MyDomains.Count > 0 Then DomainsTemp.ListAddList(f.MyDomains, LAP.NotContainsOnly) - End If - End Using - End Sub - End Class -End Namespace \ No newline at end of file diff --git a/SCrawler/API/Mastodon/SettingsForm.Designer.vb b/SCrawler/API/Mastodon/SettingsForm.Designer.vb deleted file mode 100644 index d1d6ad2..0000000 --- a/SCrawler/API/Mastodon/SettingsForm.Designer.vb +++ /dev/null @@ -1,165 +0,0 @@ -' Copyright (C) 2023 Andy https://github.com/AAndyProgram -' This program is free software: you can redistribute it and/or modify -' it under the terms of the GNU General Public License as published by -' the Free Software Foundation, either version 3 of the License, or -' (at your option) any later version. -' -' This program is distributed in the hope that it will be useful, -' but WITHOUT ANY WARRANTY -Namespace API.Mastodon - - Partial Friend Class SettingsForm : Inherits System.Windows.Forms.Form - - Protected Overrides Sub Dispose(ByVal disposing As Boolean) - Try - If disposing AndAlso components IsNot Nothing Then - components.Dispose() - End If - Finally - MyBase.Dispose(disposing) - End Try - End Sub - Private components As System.ComponentModel.IContainer - - Private Sub InitializeComponent() - Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer - Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel - Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SettingsForm)) - Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Me.CMB_DOMAINS = New PersonalUtilities.Forms.Controls.ComboBoxExtended() - Me.TXT_AUTH = New PersonalUtilities.Forms.Controls.TextBoxExtended() - Me.TXT_TOKEN = New PersonalUtilities.Forms.Controls.TextBoxExtended() - CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() - TP_MAIN = New System.Windows.Forms.TableLayoutPanel() - CONTAINER_MAIN.ContentPanel.SuspendLayout() - CONTAINER_MAIN.SuspendLayout() - TP_MAIN.SuspendLayout() - CType(Me.CMB_DOMAINS, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.TXT_AUTH, System.ComponentModel.ISupportInitialize).BeginInit() - CType(Me.TXT_TOKEN, System.ComponentModel.ISupportInitialize).BeginInit() - Me.SuspendLayout() - ' - 'CONTAINER_MAIN - ' - ' - 'CONTAINER_MAIN.ContentPanel - ' - CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 361) - CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill - CONTAINER_MAIN.LeftToolStripPanelVisible = False - CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) - CONTAINER_MAIN.Name = "CONTAINER_MAIN" - CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(384, 361) - CONTAINER_MAIN.TabIndex = 0 - CONTAINER_MAIN.TopToolStripPanelVisible = False - ' - 'TP_MAIN - ' - TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] - TP_MAIN.ColumnCount = 1 - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_MAIN.Controls.Add(Me.CMB_DOMAINS, 0, 0) - TP_MAIN.Controls.Add(Me.TXT_AUTH, 0, 1) - TP_MAIN.Controls.Add(Me.TXT_TOKEN, 0, 2) - TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill - TP_MAIN.Location = New System.Drawing.Point(0, 0) - TP_MAIN.Name = "TP_MAIN" - TP_MAIN.RowCount = 3 - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) - TP_MAIN.Size = New System.Drawing.Size(384, 361) - TP_MAIN.TabIndex = 0 - ' - 'CMB_DOMAINS - ' - ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image) - ActionButton1.Name = "Add" - ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Add - ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image) - ActionButton2.Name = "Delete" - ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Delete - ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image) - ActionButton3.Name = "Clear" - ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image) - ActionButton4.Name = "ArrowDown" - ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown - ActionButton4.Visible = False - Me.CMB_DOMAINS.Buttons.Add(ActionButton1) - Me.CMB_DOMAINS.Buttons.Add(ActionButton2) - Me.CMB_DOMAINS.Buttons.Add(ActionButton3) - Me.CMB_DOMAINS.Buttons.Add(ActionButton4) - Me.CMB_DOMAINS.Dock = System.Windows.Forms.DockStyle.Fill - Me.CMB_DOMAINS.ListDropDownStyle = PersonalUtilities.Forms.Controls.ComboBoxExtended.ListMode.Simple - Me.CMB_DOMAINS.Location = New System.Drawing.Point(4, 4) - Me.CMB_DOMAINS.Name = "CMB_DOMAINS" - Me.CMB_DOMAINS.Size = New System.Drawing.Size(378, 296) - Me.CMB_DOMAINS.TabIndex = 0 - ' - 'TXT_AUTH - ' - ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image) - ActionButton5.Name = "Clear" - ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_AUTH.Buttons.Add(ActionButton5) - Me.TXT_AUTH.CaptionText = "Auth" - Me.TXT_AUTH.CaptionToolTipEnabled = True - Me.TXT_AUTH.CaptionToolTipText = "Bearer token" - Me.TXT_AUTH.CaptionWidth = 50.0R - Me.TXT_AUTH.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_AUTH.Location = New System.Drawing.Point(4, 306) - Me.TXT_AUTH.Name = "TXT_AUTH" - Me.TXT_AUTH.Size = New System.Drawing.Size(376, 22) - Me.TXT_AUTH.TabIndex = 1 - ' - 'TXT_TOKEN - ' - ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image) - ActionButton6.Name = "Clear" - ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_TOKEN.Buttons.Add(ActionButton6) - Me.TXT_TOKEN.CaptionText = "Token" - Me.TXT_TOKEN.CaptionToolTipEnabled = True - Me.TXT_TOKEN.CaptionToolTipText = "csrf token" - Me.TXT_TOKEN.CaptionWidth = 50.0R - Me.TXT_TOKEN.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_TOKEN.Location = New System.Drawing.Point(4, 335) - Me.TXT_TOKEN.Name = "TXT_TOKEN" - Me.TXT_TOKEN.Size = New System.Drawing.Size(376, 22) - Me.TXT_TOKEN.TabIndex = 2 - ' - 'SettingsForm - ' - Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) - Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(384, 361) - Me.Controls.Add(CONTAINER_MAIN) - Me.Icon = Global.SCrawler.My.Resources.SiteResources.MastodonIcon_48 - Me.MinimumSize = New System.Drawing.Size(400, 400) - Me.Name = "SettingsForm" - Me.ShowInTaskbar = False - Me.Text = "Mastodon domains" - CONTAINER_MAIN.ContentPanel.ResumeLayout(False) - CONTAINER_MAIN.ResumeLayout(False) - CONTAINER_MAIN.PerformLayout() - TP_MAIN.ResumeLayout(False) - CType(Me.CMB_DOMAINS, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.TXT_AUTH, System.ComponentModel.ISupportInitialize).EndInit() - CType(Me.TXT_TOKEN, System.ComponentModel.ISupportInitialize).EndInit() - Me.ResumeLayout(False) - - End Sub - Private WithEvents CMB_DOMAINS As PersonalUtilities.Forms.Controls.ComboBoxExtended - Private WithEvents TXT_AUTH As PersonalUtilities.Forms.Controls.TextBoxExtended - Private WithEvents TXT_TOKEN As PersonalUtilities.Forms.Controls.TextBoxExtended - End Class -End Namespace \ No newline at end of file diff --git a/SCrawler/API/Mastodon/SettingsForm.resx b/SCrawler/API/Mastodon/SettingsForm.resx deleted file mode 100644 index da953f2..0000000 --- a/SCrawler/API/Mastodon/SettingsForm.resx +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 - - - False - - - False - - - - - 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 - AAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go - tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX - AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go - tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX - AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - - - \ No newline at end of file diff --git a/SCrawler/API/Mastodon/SettingsForm.vb b/SCrawler/API/Mastodon/SettingsForm.vb deleted file mode 100644 index dbd329c..0000000 --- a/SCrawler/API/Mastodon/SettingsForm.vb +++ /dev/null @@ -1,154 +0,0 @@ -' Copyright (C) 2023 Andy https://github.com/AAndyProgram -' This program is free software: you can redistribute it and/or modify -' it under the terms of the GNU General Public License as published by -' the Free Software Foundation, either version 3 of the License, or -' (at your option) any later version. -' -' This program is distributed in the hope that it will be useful, -' but WITHOUT ANY WARRANTY -Imports PersonalUtilities.Forms -Imports PersonalUtilities.Forms.Controls.Base -Namespace API.Mastodon - Friend Class SettingsForm - Private WithEvents MyDefs As DefaultFormOptions - Friend ReadOnly Property MyCredentials As List(Of Credentials) - Friend ReadOnly Property MyDomains As List(Of String) - Friend Sub New(ByVal s As SiteSettings) - InitializeComponent() - MyCredentials = New List(Of Credentials) - If s.Domains.Credentials.Count > 0 Then MyCredentials.AddRange(s.Domains.Credentials) - MyDomains = New List(Of String) - MyDomains.ListAddList(s.Domains) - MyDefs = New DefaultFormOptions(Me, Settings.Design) - End Sub - Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load - With MyDefs - .MyView = New FormView(Me, Settings.Design, "MastodonSettingsForm") - .MyView.Import() - .MyView.SetFormSize() - .AddOkCancelToolbar() - RefillList() - .EndLoaderOperations() - End With - End Sub - Private Sub SettingsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed - MyCredentials.Clear() - MyDomains.Clear() - End Sub - Private Sub RefillList() - CMB_DOMAINS.Items.Clear() - If MyDomains.Count > 0 Then - MyDomains.Sort() - CMB_DOMAINS.BeginUpdate() - CMB_DOMAINS.Items.AddRange(MyDomains.Select(Function(d) New ListItem(d))) - CMB_DOMAINS.EndUpdate(True) - End If - End Sub - Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick - ApplyCredentials() - If MyCredentials.Count > 0 Then MyCredentials.RemoveAll(Function(c) c.Domain.IsEmptyString Or c.Bearer.IsEmptyString Or c.Csrf.IsEmptyString) - If MyDomains.Count > 0 Then - If MyCredentials.Count > 0 Then - MyCredentials.RemoveAll(Function(c) Not MyDomains.Contains(c.Domain)) - Else - MyCredentials.Clear() - End If - End If - MyDefs.CloseForm() - End Sub - Private Sub CMB_DOMAINS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles CMB_DOMAINS.ActionOnButtonClick - Try - Dim d$ - Dim i% = -1 - Select Case e.DefaultButton - Case ActionButton.DefaultButtons.Add - d = InputBoxE("Enter a new domain using the pattern [mastodon.social]:", "New domain") - If Not d.IsEmptyString Then - If MyDomains.Count > 0 Then i = MyDomains.IndexOf(d) - If i >= 0 Then - MsgBoxE({$"Domain '{d}' already exists", "Add domain"}, vbExclamation) - If i <= CMB_DOMAINS.Count - 1 Then CMB_DOMAINS.SelectedIndex = i - Else - ApplyCredentials() - ClearCredentials() - MyDomains.Add(d) - _Suspended = True - RefillList() - _Suspended = False - i = MyDomains.IndexOf(d) - If i.ValueBetween(0, CMB_DOMAINS.Count - 1) Then - CMB_DOMAINS.SelectedIndex = i - Else - _LatestSelected = -1 - _CurrentCredentialsIndex = -1 - _CurrentDomain = String.Empty - End If - End If - End If - Case ActionButton.DefaultButtons.Delete - If _LatestSelected >= 0 Then - d = CMB_DOMAINS.Items(_LatestSelected).Value(0) - If Not d.IsEmptyString AndAlso MsgBoxE({$"Are you sure you want to delete the [{d}] domain?", - "Removing domains"}, vbYesNo) = vbYes Then - i = MyDomains.IndexOf(d) - Dim l% = _LatestSelected - If i >= 0 Then - ClearCredentials() - MyDomains.RemoveAt(i) - _Suspended = True - RefillList() - _Suspended = False - If (l - 1).ValueBetween(0, CMB_DOMAINS.Count - 1) Then - CMB_DOMAINS.SelectedIndex = l - 1 - Else - _LatestSelected = -1 - _CurrentCredentialsIndex = -1 - _CurrentDomain = String.Empty - End If - End If - End If - End If - End Select - Catch ex As Exception - ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "API.Mastodon.SettingsForm.ActionButtonClick") - End Try - End Sub - Private _LatestSelected As Integer = -1 - Private _CurrentCredentialsIndex As Integer = -1 - Private _CurrentDomain As String = String.Empty - Private _Suspended As Boolean = False - Private Sub CMB_DOMAINS_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_DOMAINS.ActionSelectedItemChanged - If Not MyDefs.Initializing And Not _Suspended Then - Dim DropCredentials As Boolean = True - If Not Item Is Nothing Then - ApplyCredentials() - _LatestSelected = Item.Index - _CurrentDomain = Item.Text - If MyCredentials.Count > 0 And Not _CurrentDomain.IsEmptyString Then - _CurrentCredentialsIndex = MyCredentials.IndexOf(_CurrentDomain) - If _CurrentCredentialsIndex >= 0 Then - With MyCredentials(_CurrentCredentialsIndex) : TXT_AUTH.Text = .Bearer : TXT_TOKEN.Text = .Csrf : End With - DropCredentials = False - End If - Else - _CurrentCredentialsIndex = -1 - End If - End If - If DropCredentials Then ClearCredentials() - End If - End Sub - Private Sub ClearCredentials() - TXT_AUTH.Clear() - TXT_TOKEN.Clear() - End Sub - Private Sub ApplyCredentials() - Try - If _LatestSelected >= 0 And Not _CurrentDomain.IsEmptyString Then - Dim c As New Credentials With {.Domain = _CurrentDomain, .Bearer = TXT_AUTH.Text, .Csrf = TXT_TOKEN.Text} - If _CurrentCredentialsIndex.ValueBetween(0, MyCredentials.Count - 1) Then MyCredentials(_CurrentCredentialsIndex) = c Else MyCredentials.Add(c) - End If - Catch ex As Exception - End Try - End Sub - End Class -End Namespace \ No newline at end of file diff --git a/SCrawler/API/Mastodon/SiteSettings.vb b/SCrawler/API/Mastodon/SiteSettings.vb index 99606d9..5b86e6e 100644 --- a/SCrawler/API/Mastodon/SiteSettings.vb +++ b/SCrawler/API/Mastodon/SiteSettings.vb @@ -18,29 +18,34 @@ Namespace API.Mastodon Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.MastodonIcon_48 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.MastodonPic_48 - End Get - End Property #Region "Domains" - Private ReadOnly Property SiteDomains As PropertyValue - Friend ReadOnly Property Domains As MastodonDomains - Private ReadOnly Property DomainsLastUpdateDate As PropertyValue + Private ReadOnly Property SiteDomains As PropertyValue + Private Shadows ReadOnly Property DefaultInstance As SiteSettings + Get + Return MyBase.DefaultInstance + End Get + End Property + Private ReadOnly _Domains As DomainsContainer + Friend ReadOnly Property Domains As DomainsContainer + Get + Return If(DefaultInstance?.Domains, _Domains) + End Get + End Property + Private ReadOnly Property Base_DomainsLastUpdateDate As PropertyValue + Private ReadOnly Property DomainsLastUpdateDate As PropertyValue + Get + Return If(DefaultInstance?.DomainsLastUpdateDate, Base_DomainsLastUpdateDate) + End Get + End Property #End Region #Region "Auth" + ControlToolTip:="Your account domain without 'https://' (for example, 'mastodon.social')"), PXML, PClonable(Clone:=False)> Friend ReadOnly Property MyDomain As PropertyValue + ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word"), PClonable(Clone:=False)> Friend ReadOnly Property Auth As PropertyValue - + Friend ReadOnly Property Token As PropertyValue Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) If Not PropName.IsEmptyString Then @@ -58,29 +63,29 @@ Namespace API.Mastodon End Sub #End Region #Region "Other properties" - + Friend ReadOnly Property GifsDownload As PropertyValue - + Friend ReadOnly Property GifsSpecialFolder As PropertyValue - + Friend ReadOnly Property GifsPrefix As PropertyValue Private ReadOnly Property GifStringChecker As IFormatProvider - + Friend ReadOnly Property UseMD5Comparison As PropertyValue + ControlToolTip:="Open user profiles and user posts through my domain."), PXML, PClonable> Friend ReadOnly Property UserRelatedToMyDomain As PropertyValue #End Region #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("Mastodon", "mastodon.social") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("Mastodon", "mastodon.social", AccName, Temp, My.Resources.SiteResources.MastodonIcon_48, My.Resources.SiteResources.MastodonPic_48) - Domains = New MastodonDomains(Me, "mastodon.social") + _Domains = New DomainsContainer(Me, "mastodon.social") SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String)) Domains.DestinationProp = SiteDomains - DomainsLastUpdateDate = New PropertyValue(Now.AddYears(-1)) + Base_DomainsLastUpdateDate = New PropertyValue(Now.AddYears(-1)) Auth = New PropertyValue(Responser.Headers.Value(DN.Header_Authorization), GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v)) Token = New PropertyValue(Responser.Headers.Value(DN.Header_CSRFToken), GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v)) @@ -182,20 +187,32 @@ Namespace API.Mastodon #End Region #Region "IsMyUser, IsMyImageVideo" Private Const UserRegexDefault As String = "https?://{0}/@([^/@]+)@?([^/]*)" - Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions + Friend Overloads Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions If Domains.Count > 0 Then - Dim l As List(Of String) + Dim e As ExchangeOptions + If ACheck(MyDomain.Value) Then + e = IsMyUser(UserURL, MyDomain.Value) + If Not e.SiteName.IsEmptyString Then Return e + End If For Each domain$ In Domains - UserRegex.Pattern = String.Format(UserRegexDefault, domain) - l = RegexReplace(UserURL, UserRegex) - If l.ListExists(2) Then Return New ExchangeOptions(Site, $"{l(2).IfNullOrEmpty(domain)}@{l(1)}") + e = IsMyUser(UserURL, domain) + If Not e.SiteName.IsEmptyString Then Return e Next End If Return Nothing End Function + Private Overloads Function IsMyUser(ByVal UserURL As String, ByVal Domain As String) As ExchangeOptions + UserRegex.Pattern = String.Format(UserRegexDefault, Domain) + Dim l As List(Of String) = RegexReplace(UserURL, UserRegex) + If l.ListExists(2) Then Return New ExchangeOptions(Site, $"{l(2).IfNullOrEmpty(Domain)}@{l(1)}") Else Return Nothing + End Function Friend Overrides Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions If Not URL.IsEmptyString And Domains.Count > 0 Then - If Domains.Domains.Exists(Function(d) URL.Contains(d)) Then Return New ExchangeOptions(Site, URL) With {.Exists = True} + Dim urlDomain$ = RegexReplace(URL, RParams.DM("[^/]+", 1, EDP.ReturnValue, String.Empty)) + If Not urlDomain.IsEmptyString Then + urlDomain = urlDomain.StringToLower + If Domains.Domains.Exists(Function(d) urlDomain = d.StringToLower) Then Return New ExchangeOptions(Site, URL) With {.Exists = True} + End If End If Return Nothing End Function @@ -222,6 +239,12 @@ Namespace API.Mastodon ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.Mastodon.SiteSettings.UpdateServersList]") End Try End Sub +#End Region +#Region "IDisposable Support" + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue And disposing Then _Domains.Dispose() + MyBase.Dispose(disposing) + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Mastodon/UserData.vb b/SCrawler/API/Mastodon/UserData.vb index cb02a8f..3c28a3f 100644 --- a/SCrawler/API/Mastodon/UserData.vb +++ b/SCrawler/API/Mastodon/UserData.vb @@ -38,22 +38,7 @@ Namespace API.Mastodon End Property Private MyCredentials As Credentials Private Sub ResetCredentials() - MyCredentials = Nothing - With MySettings - Dim setDef As Boolean = True - If Not IsSavedPosts Then - If ACheck(.MyDomain.Value) AndAlso UserDomain = .MyDomain.Value Then - setDef = True - ElseIf .Domains.Credentials.Count > 0 Then - Dim i% = .Domains.Credentials.IndexOf(UserDomain) - If i >= 0 Then - MyCredentials = .Domains.Credentials(i) - setDef = Not MyCredentials.Exists - End If - End If - End If - If setDef Then MyCredentials = New Credentials With {.Domain = UserDomain, .Bearer = MySettings.Auth.Value, .Csrf = MySettings.Token.Value} - End With + MyCredentials = New Credentials With {.Domain = MySettings.MyDomain.Value, .Bearer = MySettings.Auth.Value, .Csrf = MySettings.Token.Value} With MyCredentials Responser.Headers.Add(DeclaredNames.Header_Authorization, .Bearer) Responser.Headers.Add(DeclaredNames.Header_CSRFToken, .Csrf) diff --git a/SCrawler/API/OnlyFans/SiteSettings.vb b/SCrawler/API/OnlyFans/SiteSettings.vb index 90f036b..0883b5c 100644 --- a/SCrawler/API/OnlyFans/SiteSettings.vb +++ b/SCrawler/API/OnlyFans/SiteSettings.vb @@ -16,23 +16,11 @@ Imports PersonalUtilities.Functions.RegularExpressions Namespace API.OnlyFans Friend Class SiteSettings : Inherits SiteSettingsBase -#Region "Icon" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.OnlyFansIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.OnlyFansPic_32 - End Get - End Property -#End Region #Region "Declarations" #Region "Options" - + Friend Property DownloadHighlights As PropertyValue - + Friend Property DownloadChatMedia As PropertyValue #End Region #Region "Headers" @@ -40,15 +28,15 @@ Namespace API.OnlyFans Private Const HeaderUserID As String = "User-Id" Private Const HeaderXBC As String = "X-Bc" Private Const HeaderAppToken As String = "App-Token" - + Friend ReadOnly Property HH_USER_ID As PropertyValue - + Private ReadOnly Property HH_X_BC As PropertyValue - + Private ReadOnly Property HH_APP_TOKEN As PropertyValue - + Private ReadOnly Property HH_BROWSER As PropertyValue - + Private ReadOnly Property UserAgent As PropertyValue Private Sub UpdateHeader(ByVal PropertyName As String, ByVal Value As String) Dim hName$ = String.Empty @@ -79,21 +67,21 @@ Namespace API.OnlyFans End Property + "Change this value only if you know what you are doing."), PXML, PClonable> Friend ReadOnly Property UseOldAuthRules As PropertyValue - + Friend ReadOnly Property DynamicRulesUpdateInterval As PropertyValue Private ReadOnly Property DynamicRulesUpdateIntervalProvider As IFormatProvider + "Change this value only if you know what you are doing."), PXML, PClonable> Friend ReadOnly Property DynamicRules As PropertyValue #End Region #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("OnlyFans", ".onlyfans.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("OnlyFans", ".onlyfans.com", AccName, Temp, My.Resources.SiteResources.OnlyFansIcon_32, My.Resources.SiteResources.OnlyFansPic_32) With Responser .Accept = "application/json, text/plain, */*" diff --git a/SCrawler/API/OnlyFans/UserData.vb b/SCrawler/API/OnlyFans/UserData.vb index 2354167..50f52c7 100644 --- a/SCrawler/API/OnlyFans/UserData.vb +++ b/SCrawler/API/OnlyFans/UserData.vb @@ -380,7 +380,7 @@ Namespace API.OnlyFans Try If ContentMissingExists Then Dim m As UserMedia - Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ii As Integer) As UserMedia + Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ByVal ii As Integer) As UserMedia input.State = UStates.Missing input.Attempts = m.Attempts Return input diff --git a/SCrawler/API/PathPlugin/SiteSettings.vb b/SCrawler/API/PathPlugin/SiteSettings.vb index 0387608..1302797 100644 --- a/SCrawler/API/PathPlugin/SiteSettings.vb +++ b/SCrawler/API/PathPlugin/SiteSettings.vb @@ -12,19 +12,8 @@ Imports SCrawler.Plugin.Attributes Namespace API.PathPlugin Friend Class SiteSettings : Inherits SiteSettingsBase - Private ReadOnly _Icon As Icon = Nothing - Friend Overrides ReadOnly Property Icon As Icon - Get - Return _Icon - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return PersonalUtilities.My.Resources.FolderOpenPic_Orange_16 - End Get - End Property Friend Sub New() - MyBase.New(PluginName) + MyBase.New(PluginName,, PersonalUtilities.My.Resources.FolderOpenPic_Orange_16) _Icon = PersonalUtilities.Tools.ImageRenderer.GetIcon(PersonalUtilities.My.Resources.FolderOpenPic_Orange_16, EDP.ReturnValue) End Sub Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider diff --git a/SCrawler/API/Pinterest/SiteSettings.vb b/SCrawler/API/Pinterest/SiteSettings.vb index 2b64b80..50345f0 100644 --- a/SCrawler/API/Pinterest/SiteSettings.vb +++ b/SCrawler/API/Pinterest/SiteSettings.vb @@ -9,33 +9,22 @@ Imports SCrawler.API.Base Imports SCrawler.Plugin Imports SCrawler.Plugin.Attributes -Imports PersonalUtilities.Forms Imports PersonalUtilities.Functions.RegularExpressions Namespace API.Pinterest Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.PinterestIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.PinterestPic_48 - End Get - End Property + ControlToolTip:=DeclaredNames.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter, PClonable> Friend ReadOnly Property ConcurrentDownloads As PropertyValue Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider - + Friend ReadOnly Property SavedPostsUserName As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("Pinterest", "pinterest.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("Pinterest", "pinterest.com", AccName, Temp, My.Resources.SiteResources.PinterestIcon_32, My.Resources.SiteResources.PinterestPic_48) SavedPostsUserName = New PropertyValue(String.Empty, GetType(String)) ConcurrentDownloads = New PropertyValue(1) MyConcurrentDownloadsProvider = New ConcurrentDownloadsProvider diff --git a/SCrawler/API/PornHub/SiteSettings.vb b/SCrawler/API/PornHub/SiteSettings.vb index 67eecbf..6882029 100644 --- a/SCrawler/API/PornHub/SiteSettings.vb +++ b/SCrawler/API/PornHub/SiteSettings.vb @@ -15,40 +15,30 @@ Namespace API.PornHub Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.PornHubIcon_16 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.PornHubPic_16 - End Get - End Property - + Friend Property DownloadUHD As PropertyValue - + Friend Property DownloadUploaded As PropertyValue - + Friend Property DownloadTagged As PropertyValue - + Friend Property DownloadPrivate As PropertyValue - + Friend Property DownloadFavorite As PropertyValue - + Friend ReadOnly Property DownloadGifs As PropertyValue - + Friend ReadOnly Property DownloadGifsAsMp4 As PropertyValue + "Attention! Downloading photos hosted on PornHub is a very heavy job."), PXML, PClonable> Friend ReadOnly Property DownloadPhotoOnlyFromModelHub As PropertyValue - + Friend ReadOnly Property SavedPostsUserName As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("PornHub", "pornhub.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("PornHub", "pornhub.com", AccName, Temp, My.Resources.SiteResources.PornHubIcon_16, My.Resources.SiteResources.PornHubPic_16) With Responser : .CurlSslNoRevoke = True : .CurlInsecure = True : End With DownloadUHD = New PropertyValue(False) diff --git a/SCrawler/API/Reddit/Channel.vb b/SCrawler/API/Reddit/Channel.vb index 3d40fe3..f1fa0b4 100644 --- a/SCrawler/API/Reddit/Channel.vb +++ b/SCrawler/API/Reddit/Channel.vb @@ -18,7 +18,7 @@ Imports Period = SCrawler.API.Reddit.IRedditView.Period Namespace API.Reddit Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel), IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IRedditView, IDisposable -#Region "XML Nodes' Names" +#Region "XML Names" Private Const Name_Name As String = "Name" Private Const Name_ID As String = "ID" Private Const Name_Date As String = "Date" @@ -88,10 +88,14 @@ Namespace API.Reddit End Property Friend Property ViewMode As View = View.New Implements IRedditView.ViewMode Friend Property ViewPeriod As Period = Period.All Implements IRedditView.ViewPeriod + Friend Property RedGifsAccount As String = String.Empty Implements IRedditView.RedGifsAccount + Friend Property RedditAccount As String = String.Empty Implements IRedditView.RedditAccount Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView If Not Options Is Nothing Then ViewMode = Options.ViewMode ViewPeriod = Options.ViewPeriod + RedditAccount = Options.RedditAccount + RedGifsAccount = Options.RedGifsAccount End If End Sub #Region "Statistics support" @@ -215,7 +219,17 @@ Namespace API.Reddit End Sub Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits #End Region + Private _HOST As SettingsHost Friend ReadOnly Property HOST As SettingsHost + Get + _HOST = Settings(RedditSiteKey, RedditAccount) + If _HOST Is Nothing Then + MyMainLOG = $"Reddit account '{RedditAccount}' for channel '{Name}' not found in the accounts. The default account will be used." + _HOST = Settings(RedditSiteKey).Default + End If + Return _HOST + End Get + End Property Friend Sub New() Posts = New List(Of UserPost) PostsLatest = New List(Of UserPost) @@ -223,7 +237,6 @@ Namespace API.Reddit CountOfAddedUsers = New List(Of Integer) CountOfLoadedPostsPerSession = New List(Of Integer) ChannelExistentUserNames = New List(Of String) - HOST = Settings(RedditSiteKey) End Sub Friend Sub New(ByVal f As SFile) Me.New @@ -350,6 +363,8 @@ Namespace API.Reddit ID = x.Value(Name_ID) ViewMode = x.Value(Name_ViewMode).FromXML(Of Integer)(CInt(View.[New])) ViewPeriod = x.Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(Period.All)) + RedGifsAccount = x.Value(Name_RedGifsAccount) + RedditAccount = x.Value(Name_RedditAccount) If FilePosts.Exists Then PostsNames.ListAddList(FilePosts.GetText.StringToList(Of String)("|"), LNC) LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), DateTimeDefaultProvider, Nothing) CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc) @@ -388,6 +403,8 @@ Namespace API.Reddit x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString("|")) x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString("|")) x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString("|")) + x.Add(Name_RedGifsAccount, RedGifsAccount) + x.Add(Name_RedditAccount, RedditAccount) If Posts.Count > 0 Or PostsLatest.Count > 0 Then Dim tmpPostList As List(Of UserPost) = Nothing tmpPostList.ListAddList(Posts).ListAddList(PostsLatest) diff --git a/SCrawler/API/Reddit/IRedditView.vb b/SCrawler/API/Reddit/IRedditView.vb index 0f36803..7f0bbfe 100644 --- a/SCrawler/API/Reddit/IRedditView.vb +++ b/SCrawler/API/Reddit/IRedditView.vb @@ -23,17 +23,25 @@ Namespace API.Reddit End Enum Property ViewMode As View Property ViewPeriod As Period + Property RedGifsAccount As String + Property RedditAccount As String Sub SetView(ByVal Options As IRedditView) End Interface Friend Class RedditViewExchange : Implements IRedditView Friend Const Name_ViewMode As String = "ViewMode" Friend Const Name_ViewPeriod As String = "ViewPeriod" + Friend Const Name_RedGifsAccount As String = "RedGifsAccount" + Friend Const Name_RedditAccount As String = "RedditAccount" Friend Property ViewMode As IRedditView.View Implements IRedditView.ViewMode Friend Property ViewPeriod As IRedditView.Period Implements IRedditView.ViewPeriod + Friend Property RedGifsAccount As String Implements IRedditView.RedGifsAccount + Friend Property RedditAccount As String Implements IRedditView.RedditAccount Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView If Not Options Is Nothing Then ViewMode = Options.ViewMode ViewPeriod = Options.ViewPeriod + RedGifsAccount = Options.RedGifsAccount + RedditAccount = Options.RedditAccount End If End Sub End Class diff --git a/SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb b/SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb index 3d0816e..d4659b8 100644 --- a/SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb +++ b/SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb @@ -23,10 +23,13 @@ Namespace API.Reddit Private Sub InitializeComponent() Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer - Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel Dim TP_VIEW_MODE As System.Windows.Forms.TableLayoutPanel Dim LBL_VIEW_MODE As System.Windows.Forms.Label Dim LBL_PERIOD As System.Windows.Forms.Label + Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(RedditViewSettingsForm)) + Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel() Me.OPT_VIEW_MODE_NEW = New System.Windows.Forms.RadioButton() Me.OPT_VIEW_MODE_HOT = New System.Windows.Forms.RadioButton() Me.OPT_VIEW_MODE_TOP = New System.Windows.Forms.RadioButton() @@ -37,16 +40,19 @@ Namespace API.Reddit Me.OPT_PERIOD_WEEK = New System.Windows.Forms.RadioButton() Me.OPT_PERIOD_MONTH = New System.Windows.Forms.RadioButton() Me.OPT_PERIOD_YEAR = New System.Windows.Forms.RadioButton() + Me.CMB_REDGIFS_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended() + Me.CMB_REDDIT_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended() CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() - TP_MAIN = New System.Windows.Forms.TableLayoutPanel() TP_VIEW_MODE = New System.Windows.Forms.TableLayoutPanel() LBL_VIEW_MODE = New System.Windows.Forms.Label() LBL_PERIOD = New System.Windows.Forms.Label() CONTAINER_MAIN.ContentPanel.SuspendLayout() CONTAINER_MAIN.SuspendLayout() - TP_MAIN.SuspendLayout() + Me.TP_MAIN.SuspendLayout() TP_VIEW_MODE.SuspendLayout() Me.TP_PERIOD.SuspendLayout() + CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'CONTAINER_MAIN @@ -54,34 +60,37 @@ Namespace API.Reddit ' 'CONTAINER_MAIN.ContentPanel ' - CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 87) + CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 169) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) CONTAINER_MAIN.Name = "CONTAINER_MAIN" CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(477, 112) + CONTAINER_MAIN.Size = New System.Drawing.Size(477, 169) CONTAINER_MAIN.TabIndex = 0 CONTAINER_MAIN.TopToolStripPanelVisible = False ' 'TP_MAIN ' - TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] - TP_MAIN.ColumnCount = 1 - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.Controls.Add(TP_VIEW_MODE, 0, 0) - TP_MAIN.Controls.Add(Me.TP_PERIOD, 0, 1) - TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill - TP_MAIN.Location = New System.Drawing.Point(0, 0) - TP_MAIN.Name = "TP_MAIN" - TP_MAIN.RowCount = 3 - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!)) - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_MAIN.Size = New System.Drawing.Size(477, 87) - TP_MAIN.TabIndex = 0 + Me.TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] + Me.TP_MAIN.ColumnCount = 1 + Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) + Me.TP_MAIN.Controls.Add(TP_VIEW_MODE, 0, 0) + Me.TP_MAIN.Controls.Add(Me.TP_PERIOD, 0, 1) + Me.TP_MAIN.Controls.Add(Me.CMB_REDGIFS_ACC, 0, 3) + Me.TP_MAIN.Controls.Add(Me.CMB_REDDIT_ACC, 0, 2) + Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill + Me.TP_MAIN.Location = New System.Drawing.Point(0, 0) + Me.TP_MAIN.Name = "TP_MAIN" + Me.TP_MAIN.RowCount = 5 + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) + Me.TP_MAIN.Size = New System.Drawing.Size(477, 169) + Me.TP_MAIN.TabIndex = 0 ' 'TP_VIEW_MODE ' @@ -258,19 +267,55 @@ Namespace API.Reddit Me.OPT_PERIOD_YEAR.Text = "Year" Me.OPT_PERIOD_YEAR.UseVisualStyleBackColor = True ' + 'CMB_REDGIFS_ACC + ' + ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image) + ActionButton1.Name = "ArrowDown" + ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_REDGIFS_ACC.Buttons.Add(ActionButton1) + Me.CMB_REDGIFS_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label + Me.CMB_REDGIFS_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent + Me.CMB_REDGIFS_ACC.CaptionText = "RedGifs account" + Me.CMB_REDGIFS_ACC.CaptionVisible = True + Me.CMB_REDGIFS_ACC.CaptionWidth = 26.0R + Me.CMB_REDGIFS_ACC.Dock = System.Windows.Forms.DockStyle.Fill + Me.CMB_REDGIFS_ACC.Location = New System.Drawing.Point(4, 119) + Me.CMB_REDGIFS_ACC.Name = "CMB_REDGIFS_ACC" + Me.CMB_REDGIFS_ACC.Size = New System.Drawing.Size(469, 22) + Me.CMB_REDGIFS_ACC.TabIndex = 4 + Me.CMB_REDGIFS_ACC.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + ' + 'CMB_REDDIT_ACC + ' + ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image) + ActionButton2.Name = "ArrowDown" + ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_REDDIT_ACC.Buttons.Add(ActionButton2) + Me.CMB_REDDIT_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label + Me.CMB_REDDIT_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent + Me.CMB_REDDIT_ACC.CaptionText = "Reddit account" + Me.CMB_REDDIT_ACC.CaptionVisible = True + Me.CMB_REDDIT_ACC.CaptionWidth = 26.0R + Me.CMB_REDDIT_ACC.Dock = System.Windows.Forms.DockStyle.Fill + Me.CMB_REDDIT_ACC.Location = New System.Drawing.Point(4, 90) + Me.CMB_REDDIT_ACC.Name = "CMB_REDDIT_ACC" + Me.CMB_REDDIT_ACC.Size = New System.Drawing.Size(469, 22) + Me.CMB_REDDIT_ACC.TabIndex = 3 + Me.CMB_REDDIT_ACC.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + ' 'RedditViewSettingsForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(477, 112) + Me.ClientSize = New System.Drawing.Size(477, 169) Me.Controls.Add(CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.Icon = Global.SCrawler.My.Resources.SiteResources.RedditIcon_128 Me.KeyPreview = True Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(493, 151) + Me.MaximumSize = New System.Drawing.Size(493, 208) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(493, 151) + Me.MinimumSize = New System.Drawing.Size(493, 208) Me.Name = "RedditViewSettingsForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -278,11 +323,13 @@ Namespace API.Reddit CONTAINER_MAIN.ContentPanel.ResumeLayout(False) CONTAINER_MAIN.ResumeLayout(False) CONTAINER_MAIN.PerformLayout() - TP_MAIN.ResumeLayout(False) + Me.TP_MAIN.ResumeLayout(False) TP_VIEW_MODE.ResumeLayout(False) TP_VIEW_MODE.PerformLayout() Me.TP_PERIOD.ResumeLayout(False) Me.TP_PERIOD.PerformLayout() + CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub @@ -296,5 +343,8 @@ Namespace API.Reddit Private WithEvents OPT_PERIOD_MONTH As RadioButton Private WithEvents OPT_PERIOD_YEAR As RadioButton Private WithEvents TP_PERIOD As TableLayoutPanel + Private WithEvents CMB_REDGIFS_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended + Private WithEvents CMB_REDDIT_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended + Private WithEvents TP_MAIN As TableLayoutPanel End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Reddit/RedditViewSettingsForm.resx b/SCrawler/API/Reddit/RedditViewSettingsForm.resx index d19222f..1050e12 100644 --- a/SCrawler/API/Reddit/RedditViewSettingsForm.resx +++ b/SCrawler/API/Reddit/RedditViewSettingsForm.resx @@ -120,9 +120,6 @@ False - - False - False @@ -132,4 +129,185 @@ False + + + + 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 + AAAASUVORK5CYII= + + + + + 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 + AAAASUVORK5CYII= + + \ No newline at end of file diff --git a/SCrawler/API/Reddit/RedditViewSettingsForm.vb b/SCrawler/API/Reddit/RedditViewSettingsForm.vb index 7ed1653..0f7a1a3 100644 --- a/SCrawler/API/Reddit/RedditViewSettingsForm.vb +++ b/SCrawler/API/Reddit/RedditViewSettingsForm.vb @@ -6,16 +6,21 @@ ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY +Imports SCrawler.Plugin.Hosts Imports PersonalUtilities.Forms +Imports PersonalUtilities.Forms.Controls +Imports PersonalUtilities.Forms.Controls.Base Imports CView = SCrawler.API.Reddit.IRedditView.View Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period Namespace API.Reddit Friend Class RedditViewSettingsForm Private WithEvents MyDefs As DefaultFormOptions Private ReadOnly Property MyOptions As IRedditView - Friend Sub New(ByRef opt As IRedditView) + Private ReadOnly Property IsUserSettings As Boolean + Friend Sub New(ByRef opt As IRedditView, ByVal _IsUserSettings As Boolean) InitializeComponent() MyOptions = opt + IsUserSettings = _IsUserSettings MyDefs = New DefaultFormOptions(Me, Settings.Design) End Sub Private Sub RedditViewSettingsForm_Load(sender As Object, e As EventArgs) Handles Me.Load @@ -44,12 +49,52 @@ Namespace API.Reddit Case Else : OPT_PERIOD_ALL.Checked = True End Select ChangePeriodEnabled() + + PopulateCMB(Settings(RedditSiteKey), CMB_REDDIT_ACC, MyOptions.RedditAccount) + PopulateCMB(Settings(RedGifs.RedGifsSiteKey), CMB_REDGIFS_ACC, MyOptions.RedGifsAccount) + If IsUserSettings Then + TP_MAIN.Controls.Remove(CMB_REDDIT_ACC) + TP_MAIN.RowStyles(2).Height = 0 + TP_MAIN.Refresh() + Dim s As Size = Size + s.Height -= 28 + MaximumSize = Nothing + MinimumSize = Nothing + Size = s + MinimumSize = s + MaximumSize = s + Refresh() + End If + .EndLoaderOperations() End With Catch ex As Exception MyDefs.InvokeLoaderError(ex) End Try End Sub + Private Sub PopulateCMB(ByVal Plugin As SettingsHostCollection, ByRef CMB As ComboBoxExtended, ByVal Acc As String) + With CMB + Dim indx% = 0 + .BeginUpdate() + If Plugin.Count = 1 Then + .Text = SettingsHost.NameAccountNameDefault + .LeaveDefaultButtons = False + .Buttons.Clear() + .Buttons.UpdateButtonsPositions(True) + .CaptionWidth -= 1 + Else + Dim data As List(Of String) = Plugin.Select(Function(h) h.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).ToList + If Not Acc.IsEmptyString Then + indx = data.IndexOf(Acc) + If indx = -1 Then indx = 0 + End If + .Items.AddRange(data.Select(Function(d) New ListItem(d))) + End If + .EndUpdate(True) + If .Count > 0 Then .SelectedIndex = indx + .Enabled = .Count > 1 + End With + End Sub Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick With MyOptions Select Case True @@ -65,6 +110,8 @@ Namespace API.Reddit Case OPT_PERIOD_YEAR.Checked : .ViewPeriod = CPeriod.Year Case Else : .ViewPeriod = CPeriod.All End Select + .RedGifsAccount = CMB_REDGIFS_ACC.Text + If Not IsUserSettings Then .RedditAccount = CMB_REDDIT_ACC.Text End With MyDefs.CloseForm() End Sub diff --git a/SCrawler/API/Reddit/SiteSettings.vb b/SCrawler/API/Reddit/SiteSettings.vb index 20c6491..83e8f9f 100644 --- a/SCrawler/API/Reddit/SiteSettings.vb +++ b/SCrawler/API/Reddit/SiteSettings.vb @@ -18,27 +18,15 @@ Imports Download = SCrawler.Plugin.ISiteSettings.Download Namespace API.Reddit Friend Class SiteSettings : Inherits SiteSettingsBase -#Region "Icons" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.RedditIcon_128 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.RedditPic_512 - End Get - End Property -#End Region #Region "Declarations" #Region "Authorization" - + Friend ReadOnly Property AuthUserName As PropertyValue - + Friend ReadOnly Property AuthPassword As PropertyValue - + Friend ReadOnly Property ApiClientID As PropertyValue - + Friend ReadOnly Property ApiClientSecret As PropertyValue + AllowNull:=False, LeftOffset:=120, IsAuth:=True), PXML, PClonable> Friend ReadOnly Property TokenUpdateInterval As PropertyValue Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider #End Region - Private ReadOnly Property BearerTokenDateUpdate As PropertyValue - + Private ReadOnly Property BearerTokenDateUpdate As PropertyValue + Friend ReadOnly Property UseTokenForTimelines As PropertyValue - + Friend ReadOnly Property UseTokenForSavedPosts As PropertyValue - + Friend ReadOnly Property UseCookiesForTimelines As PropertyValue - + Friend ReadOnly Property SavedPostsUserName As PropertyValue #End Region #Region "Other" - + Friend ReadOnly Property UseM3U8 As PropertyValue #End Region #End Region #Region "Initializer" - Friend Sub New() - MyBase.New(RedditSite, "reddit.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New(RedditSite, "reddit.com", AccName, Temp, My.Resources.SiteResources.RedditIcon_128, My.Resources.SiteResources.RedditPic_512) Dim token$ With Responser @@ -144,6 +132,7 @@ Namespace API.Reddit End Function Private Function AvailableImpl(ByVal What As Download, ByVal Silent As Boolean) As Boolean Try + AvailableText = String.Empty Dim trueValue As Boolean = Not What = Download.SavedPosts OrElse (Responser.CookiesExists And ACheck(SavedPostsUserName.Value)) If Not trueValue Then Return False Dim dl As List(Of DownDetector.Data) = DownDetector.GetData("reddit") @@ -151,13 +140,13 @@ Namespace API.Reddit dl = dl.Take(4).ToList Dim avg% = dl.Average(Function(d) d.Value) If avg > 100 Then + AvailableText = "Over the past hour, Reddit has received an average of " & + avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr & + dl.ListToString(vbCr) If Silent Then Return False Else - If MsgBoxE({"Over the past hour, Reddit has received an average of " & - avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr & - dl.ListToString(vbCr) & vbCr & vbCr & - "Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes Then + If MsgBoxE({$"{AvailableText}{vbCr}{vbCr}Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes Then If trueValue Then UpdateRedGifsToken() Return trueValue AndAlso UpdateTokenIfRequired() Else @@ -182,7 +171,7 @@ Namespace API.Reddit MyBase.DownloadDone(What) End Sub Private Sub UpdateRedGifsToken() - DirectCast(Settings(RedGifs.RedGifsSiteKey).Source, RedGifs.SiteSettings).UpdateTokenIfRequired() + Settings(RedGifs.RedGifsSiteKey).ListForEach(Sub(h, i) DirectCast(h.Source, RedGifs.SiteSettings).UpdateTokenIfRequired()) End Sub #End Region #Region "IsMyUser, GetUserUrl, GetUserPostUrl" @@ -212,7 +201,7 @@ Namespace API.Reddit Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) If Options Is Nothing OrElse Not TypeOf Options Is RedditViewExchange Then Options = New RedditViewExchange If OpenForm Then - Using f As New RedditViewSettingsForm(Options) : f.ShowDialog() : End Using + Using f As New RedditViewSettingsForm(Options, True) : f.ShowDialog() : End Using End If End Sub #End Region diff --git a/SCrawler/API/Reddit/UserData.vb b/SCrawler/API/Reddit/UserData.vb index d1f66bc..2ca625a 100644 --- a/SCrawler/API/Reddit/UserData.vb +++ b/SCrawler/API/Reddit/UserData.vb @@ -51,6 +51,42 @@ Namespace API.Reddit Return {CannelsLabelName, CannelsLabelName_ChannelsForm, UserLabelName} End Get End Property + Private _RedGifsAccount As String = String.Empty + Friend Property RedGifsAccount As String Implements IRedditView.RedGifsAccount + Get + If Not _RedGifsAccount.IsEmptyString Then + Return _RedGifsAccount + ElseIf Not ChannelInfo Is Nothing Then + Return ChannelInfo.RedGifsAccount + Else + Return String.Empty + End If + End Get + Set(ByVal acc As String) + _RedGifsAccount = acc + End Set + End Property + Private _RedditAccount As String = String.Empty + Friend Property RedditAccount As String Implements IRedditView.RedditAccount + Get + If IsChannelForm Then + Return _RedditAccount + Else + Return MyBase.AccountName + End If + End Get + Set(ByVal acc As String) + _RedditAccount = acc + End Set + End Property + Friend Overrides Property AccountName As String + Get + Return RedditAccount + End Get + Set(ByVal acc As String) + MyBase.AccountName = acc + End Set + End Property #End Region #Region "Channels Support" #Region "IChannelLimits Support" @@ -72,6 +108,11 @@ Namespace API.Reddit End With End Sub Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits + Private ReadOnly Property IsChannelForm As Boolean + Get + Return Not IsSavedPosts AndAlso IsChannel AndAlso Not ChannelInfo Is Nothing + End Get + End Property #End Region Friend Property ChannelInfo As Channel Private ReadOnly ChannelPostsNames As List(Of String) @@ -91,6 +132,8 @@ Namespace API.Reddit If Not Options Is Nothing Then ViewMode = Options.ViewMode ViewPeriod = Options.ViewPeriod + RedGifsAccount = Options.RedGifsAccount + RedditAccount = Options.RedditAccount End If End Sub Private ReadOnly Property View As String @@ -162,6 +205,8 @@ Namespace API.Reddit ViewPeriod = .Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(CPeriod.All)) IsChannel = .Value(Name_IsChannel).FromXML(Of Boolean)(False) TrueName = .Value(Name_TrueName) + RedGifsAccount = .Value(Name_RedGifsAccount) + RedditAccount = .Value(Name_RedditAccount) UpdateNames() Else If UpdateNames() Then .Value(Name_LabelsName) = LabelsString @@ -169,11 +214,13 @@ Namespace API.Reddit .Add(Name_ViewPeriod, CInt(ViewPeriod)) .Add(Name_IsChannel, IsChannel.BoolToInteger) .Add(Name_TrueName, TrueName) + .Add(Name_RedGifsAccount, RedGifsAccount) + .Add(Name_RedditAccount, RedditAccount) End If End With End Sub Friend Overrides Function ExchangeOptionsGet() As Object - Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod} + Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod, .RedGifsAccount = RedGifsAccount, .RedditAccount = RedditAccount} End Function Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object) If Not Obj Is Nothing AndAlso TypeOf Obj Is IRedditView Then SetView(DirectCast(Obj, IRedditView)) @@ -187,7 +234,7 @@ Namespace API.Reddit If IsChannel Or IsSavedPosts Then UseMD5Comparison = False If IsSavedPosts Then TrueName = MySiteSettings.SavedPostsUserName.Value UpdateNames() - If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo Is Nothing) Then + If IsChannelForm Then UseMD5Comparison = False EnvirDownloadSet() If Not Responser Is Nothing Then Responser.Dispose() @@ -790,8 +837,9 @@ Namespace API.Reddit Dim r$, v$ Dim e As New ErrorsDescriber(EDP.ReturnValue) Dim m As UserMedia, m2 As UserMedia - Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey) + Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey, RedGifsAccount) Dim _repeatForRedgifs As Boolean + If RedGifsHost Is Nothing Then RedGifsHost = Settings(RedGifs.RedGifsSiteKey).Default RedGifsResponser = RedGifsHost.Responser.Copy ProgressPre.ChangeMax(_TempMediaList.Count) For i% = _TempMediaList.Count - 1 To 0 Step -1 @@ -806,7 +854,7 @@ Namespace API.Reddit r = Gfycat.Envir.GetVideo(m.URL) If Not r.IsEmptyString AndAlso r.Contains("redgifs.com") Then m.URL = r : _repeatForRedgifs = True ElseIf m.URL.Contains(SiteRedGifsKey) Then - m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost) + m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost, RedGifsAccount) If m2.State = UStates.Missing Then m.State = UStates.Missing _ContentList.Add(m) @@ -853,7 +901,8 @@ Namespace API.Reddit Try If Not ChannelInfo Is Nothing Or SaveToCache Then Exit Sub If ContentMissingExists Then - Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey) + Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey, RedGifsAccount) + If RedGifsHost Is Nothing Then RedGifsHost = Settings(RedGifs.RedGifsSiteKey).Default RedGifsResponser = RedGifsHost.Responser.Copy Dim m As UserMedia, m2 As UserMedia Dim r$ @@ -945,7 +994,7 @@ Namespace API.Reddit If _ContentNew.Count > 0 Then Try If Not _RedGifsResponser Is Nothing Then _RedGifsResponser.Dispose() - _RedGifsResponser = Settings(RedGifs.RedGifsSiteKey).Responser.Copy + _RedGifsResponser = If(Settings(RedGifs.RedGifsSiteKey, RedGifsAccount), Settings(RedGifs.RedGifsSiteKey).Default).Responser.Copy DownloadContentDefault(Token) Finally If Not _RedGifsResponser Is Nothing Then _RedGifsResponser.Dispose() : _RedGifsResponser = Nothing diff --git a/SCrawler/API/Redgifs/SiteSettings.vb b/SCrawler/API/Redgifs/SiteSettings.vb index 8319762..624bd88 100644 --- a/SCrawler/API/Redgifs/SiteSettings.vb +++ b/SCrawler/API/Redgifs/SiteSettings.vb @@ -18,33 +18,23 @@ Namespace API.RedGifs Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.RedGifsIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.RedGifsPic_32 - End Get - End Property - + Friend ReadOnly Property Token As PropertyValue - + Private ReadOnly Property UserAgent As PropertyValue Friend ReadOnly Property TokenLastDateUpdated As PropertyValue Private Const TokenName As String = "authorization" #Region "TokenUpdateInterval" + PXML, ControlNumber(0), PClonable> Friend ReadOnly Property TokenUpdateInterval As PropertyValue Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider #End Region #End Region #Region "Initializer" - Friend Sub New() - MyBase.New(RedGifsSite, "redgifs.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New(RedGifsSite, "redgifs.com", AccName, Temp, My.Resources.SiteResources.RedGifsIcon_32, My.Resources.SiteResources.RedGifsPic_32) Dim t$ = String.Empty With Responser .Mode = Responser.Modes.WebClient diff --git a/SCrawler/API/Redgifs/UserData.vb b/SCrawler/API/Redgifs/UserData.vb index ed4d44e..333af81 100644 --- a/SCrawler/API/Redgifs/UserData.vb +++ b/SCrawler/API/Redgifs/UserData.vb @@ -166,16 +166,19 @@ Namespace API.RedGifs End If End Function Friend Shared Function GetDataFromUrlId(ByVal Obj As String, ByVal ObjIsID As Boolean, ByVal Responser As Responser, - ByVal Host As Plugin.Hosts.SettingsHost) As UserMedia + ByVal Host As Plugin.Hosts.SettingsHost, ByVal AccountName As String) As UserMedia Dim URL$ = String.Empty Try If Obj.IsEmptyString Then Return Nothing If Not ObjIsID Then Obj = GetVideoIdFromUrl(Obj) - If Not Obj.IsEmptyString Then Return GetDataFromUrlId(Obj, True, Responser, Host) + If Not Obj.IsEmptyString Then Return GetDataFromUrlId(Obj, True, Responser, Host, AccountName) Else - If Host Is Nothing Then Host = Settings(RedGifsSiteKey) - If Host.Source.Available(Plugin.ISiteSettings.Download.Main, True) Then + If Host Is Nothing Then + Host = Settings(RedGifsSiteKey, AccountName) + If Host Is Nothing Then Host = Settings(RedGifsSiteKey).Default + End If + If Not Host Is Nothing AndAlso Host.Source.Available(Plugin.ISiteSettings.Download.Main, True) Then If Responser Is Nothing Then Responser = Host.Responser.Copy URL = String.Format(PostDataUrl, Obj.ToLower) Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException) @@ -220,7 +223,7 @@ Namespace API.RedGifs #End Region #Region "Single data downloader" Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken) - Dim m As UserMedia = GetDataFromUrlId(Data.URL, False, Responser, HOST) + Dim m As UserMedia = GetDataFromUrlId(Data.URL, False, Responser, HOST, AccountName) If Not m.State = UStates.Missing And Not m.State = DataGone And (m.Type = UTypes.Picture Or m.Type = UTypes.Video) Then m.URL_BASE = MySettings.GetUserPostUrl(Me, m) _TempMediaList.Add(m) diff --git a/SCrawler/API/ThisVid/SiteSettings.vb b/SCrawler/API/ThisVid/SiteSettings.vb index 382e2dd..90f20f9 100644 --- a/SCrawler/API/ThisVid/SiteSettings.vb +++ b/SCrawler/API/ThisVid/SiteSettings.vb @@ -16,31 +16,21 @@ Namespace API.ThisVid Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.ThisVidIcon_16 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.ThisVidPic_16 - End Get - End Property - + Friend ReadOnly Property DownloadPublic As PropertyValue - + Friend ReadOnly Property DownloadPrivate As PropertyValue - + Friend ReadOnly Property DownloadFavourite As PropertyValue + "If false, all videos will be stored in the 'Video' folder."), PClonable> Friend ReadOnly Property DifferentFolders As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("ThisVid", "thisvid.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("ThisVid", "thisvid.com", AccName, Temp, My.Resources.SiteResources.ThisVidIcon_16, My.Resources.SiteResources.ThisVidPic_16) With Responser .CookiesExtractMode = Responser.CookiesExtractModes.Any .CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll diff --git a/SCrawler/API/ThreadsNet/SiteSettings.vb b/SCrawler/API/ThreadsNet/SiteSettings.vb index a197fb3..dc641ac 100644 --- a/SCrawler/API/ThreadsNet/SiteSettings.vb +++ b/SCrawler/API/ThreadsNet/SiteSettings.vb @@ -17,31 +17,20 @@ Namespace API.ThreadsNet Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.ThreadsIcon_192 - End Get - End Property - Private ReadOnly _Image As Image - Friend Overrides ReadOnly Property Image As Image - Get - Return _Image - End Get - End Property #Region "Authorization" - + Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue - + Friend Property HH_IG_APP_ID As PropertyValue - + Friend Property HH_ASBD_ID As PropertyValue - + Private Property HH_BROWSER As PropertyValue - + Private Property HH_BROWSER_EXT As PropertyValue - + Private Property HH_PLATFORM As PropertyValue - + Private ReadOnly Property HH_USER_AGENT As PropertyValue Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) If Not PropName.IsEmptyString Then @@ -67,10 +56,9 @@ Namespace API.ThreadsNet #End Region #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("Threads", "threads.net") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("Threads", "threads.net", AccName, Temp, My.Resources.SiteResources.ThreadsIcon_192, My.Resources.SiteResources.ThreadsIcon_192.ToBitmap) _AllowUserAgentUpdate = False - _Image = My.Resources.SiteResources.ThreadsIcon_192.ToBitmap Dim app_id$ = String.Empty Dim token$ = String.Empty diff --git a/SCrawler/API/TikTok/SiteSettings.vb b/SCrawler/API/TikTok/SiteSettings.vb index 3105533..e892507 100644 --- a/SCrawler/API/TikTok/SiteSettings.vb +++ b/SCrawler/API/TikTok/SiteSettings.vb @@ -13,27 +13,17 @@ Imports PersonalUtilities.Functions.RegularExpressions Namespace API.TikTok Friend Class SiteSettings : Inherits SiteSettingsBase - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.TikTokIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.TikTokPic_192 - End Get - End Property - + Friend Property RemoveTagsFromTitle As PropertyValue - + Friend Property TitleUseNative As PropertyValue + ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML, PClonable> Friend Property TitleUseNativeSTD As PropertyValue - + Friend Property TitleAddVideoID As PropertyValue - Friend Sub New() - MyBase.New("TikTok", "www.tiktok.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("TikTok", "www.tiktok.com", AccName, Temp, My.Resources.SiteResources.TikTokIcon_32, My.Resources.SiteResources.TikTokPic_192) RemoveTagsFromTitle = New PropertyValue(False) TitleUseNative = New PropertyValue(True) TitleUseNativeSTD = New PropertyValue(False) diff --git a/SCrawler/API/Twitter/SiteSettings.vb b/SCrawler/API/Twitter/SiteSettings.vb index 512990f..aca626e 100644 --- a/SCrawler/API/Twitter/SiteSettings.vb +++ b/SCrawler/API/Twitter/SiteSettings.vb @@ -16,43 +16,32 @@ Namespace API.Twitter Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteResources.TwitterIcon_32 - End Get - End Property - Private ReadOnly _Image As Image - Friend Overrides ReadOnly Property Image As Image - Get - Return _Image - End Get - End Property #Region "Other properties" + "Otherwise the appropriate download model will be selected right from the start."), PXML, PClonable> Friend ReadOnly Property UseAppropriateModel As PropertyValue #Region "End points" - + Friend Property UseNewEndPointSearch As PropertyValue - + Friend Property UseNewEndPointProfiles As PropertyValue #End Region #Region "Limits" - + Friend Property AbortOnLimit As PropertyValue - + Friend Property DownloadAlreadyParsed As PropertyValue #End Region - + Friend ReadOnly Property MediaModelAllowNonUserTweets As PropertyValue - + Friend ReadOnly Property GifsDownload As PropertyValue - + Friend ReadOnly Property GifsSpecialFolder As PropertyValue - + Friend ReadOnly Property GifsPrefix As PropertyValue Private ReadOnly Property GifStringChecker As IFormatProvider @@ -74,19 +63,18 @@ Namespace API.Twitter Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]") End Function End Class - + Friend ReadOnly Property UseMD5Comparison As PropertyValue + ControlToolTip:=DN.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter, PClonable> Friend ReadOnly Property ConcurrentDownloads As PropertyValue Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider #End Region #End Region - Friend Sub New() - MyBase.New(TwitterSite, "twitter.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New(TwitterSite, "twitter.com", AccName, Temp, My.Resources.SiteResources.TwitterIcon_32, My.Resources.SiteResources.TwitterIcon_32.ToBitmap) - _Image = My.Resources.SiteResources.TwitterIcon_32.ToBitmap LimitSkippedUsers = New List(Of UserDataBase) With Responser diff --git a/SCrawler/API/XVIDEOS/SiteSettings.vb b/SCrawler/API/XVIDEOS/SiteSettings.vb index 247944b..fa47c26 100644 --- a/SCrawler/API/XVIDEOS/SiteSettings.vb +++ b/SCrawler/API/XVIDEOS/SiteSettings.vb @@ -15,31 +15,31 @@ Namespace API.XVIDEOS Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon + Private ReadOnly Property SiteDomains As PropertyValue + Private Shadows ReadOnly Property DefaultInstance As SiteSettings Get - Return My.Resources.SiteResources.XvideosIcon_48 + Return MyBase.DefaultInstance End Get End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.XvideosPic_32 - End Get - End Property - Private ReadOnly Property SiteDomains As PropertyValue + Private ReadOnly _Domains As DomainsContainer Friend ReadOnly Property Domains As DomainsContainer - + Get + Return If(DefaultInstance?.Domains, _Domains) + End Get + End Property + Friend Property DownloadUHD As PropertyValue + LeftOffset:=130), PXML, PClonable(Clone:=False)> Friend ReadOnly Property SavedVideosPlaylist As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("XVIDEOS", "www.xvideos.com") - Domains = New DomainsContainer(Me, "xvideos.com|xnxx.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("XVIDEOS", "www.xvideos.com", AccName, Temp, My.Resources.SiteResources.XvideosIcon_48, My.Resources.SiteResources.XvideosPic_32) + _Domains = New DomainsContainer(Me, "xvideos.com|xnxx.com") SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String)) Domains.DestinationProp = SiteDomains DownloadUHD = New PropertyValue(False) @@ -156,6 +156,12 @@ Namespace API.XVIDEOS Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using End If End Sub +#End Region +#Region "IDisposable Support" + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue And disposing Then _Domains.Dispose() + MyBase.Dispose(disposing) + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/Xhamster/SiteSettings.vb b/SCrawler/API/Xhamster/SiteSettings.vb index df33387..b9c53c8 100644 --- a/SCrawler/API/Xhamster/SiteSettings.vb +++ b/SCrawler/API/Xhamster/SiteSettings.vb @@ -15,26 +15,26 @@ Namespace API.Xhamster Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon + Private ReadOnly Property SiteDomains As PropertyValue + Private Shadows ReadOnly Property DefaultInstance As SiteSettings Get - Return My.Resources.SiteResources.XhamsterIcon_32 + Return MyBase.DefaultInstance End Get End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteResources.XhamsterPic_32 - End Get - End Property - Private ReadOnly Property SiteDomains As PropertyValue + Private ReadOnly _Domains As DomainsContainer Friend ReadOnly Property Domains As DomainsContainer - + Get + Return If(DefaultInstance?.Domains, _Domains) + End Get + End Property + Friend Property DownloadUHD As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New("XHamster", "xhamster.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New("XHamster", "xhamster.com", AccName, Temp, My.Resources.SiteResources.XhamsterIcon_32, My.Resources.SiteResources.XhamsterPic_32) - Domains = New DomainsContainer(Me, "xhamster.com") + _Domains = New DomainsContainer(Me, "xhamster.com") SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String)) Domains.DestinationProp = SiteDomains DownloadUHD = New PropertyValue(False) @@ -149,6 +149,12 @@ Namespace API.Xhamster Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using End If End Sub +#End Region +#Region "IDisposable Support" + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue And disposing Then _Domains.Dispose() + MyBase.Dispose(disposing) + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/API/YouTube/SiteSettings.vb b/SCrawler/API/YouTube/SiteSettings.vb index 243bad9..286e22a 100644 --- a/SCrawler/API/YouTube/SiteSettings.vb +++ b/SCrawler/API/YouTube/SiteSettings.vb @@ -14,28 +14,18 @@ Namespace API.YouTube Friend Class SiteSettings : Inherits SiteSettingsBase #Region "Declarations" - Friend Overrides ReadOnly Property Icon As Icon - Get - Return My.Resources.SiteYouTube.YouTubeIcon_32 - End Get - End Property - Friend Overrides ReadOnly Property Image As Image - Get - Return My.Resources.SiteYouTube.YouTubePic_96 - End Get - End Property - + Friend ReadOnly Property DownloadVideos As PropertyValue - + Friend ReadOnly Property DownloadShorts As PropertyValue - + Friend ReadOnly Property DownloadPlaylists As PropertyValue - + Friend ReadOnly Property UseCookies As PropertyValue #End Region #Region "Initializer" - Friend Sub New() - MyBase.New(YouTubeSite, "youtube.com") + Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean) + MyBase.New(YouTubeSite, "youtube.com", AccName, Temp, My.Resources.SiteYouTube.YouTubeIcon_32, My.Resources.SiteYouTube.YouTubePic_96) Responser.Cookies.ChangedAllowInternalDrop = False DownloadVideos = New PropertyValue(True) DownloadShorts = New PropertyValue(False) diff --git a/SCrawler/Channels/ChannelViewForm.vb b/SCrawler/Channels/ChannelViewForm.vb index 6c03476..7e776ee 100644 --- a/SCrawler/Channels/ChannelViewForm.vb +++ b/SCrawler/Channels/ChannelViewForm.vb @@ -124,7 +124,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits Private Sub SetLimit(ByVal Source As IChannelLimits) Implements IChannelLimits.SetLimit End Sub #End Region - Private ReadOnly HOST As SettingsHost + Private ReadOnly HOST_COLLECTION As SettingsHostCollection Private ReadOnly PendingUsers As List(Of PendingUser) Private ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly) Private WithEvents MyRange As RangeSwitcherToolbar(Of UserPost) @@ -148,7 +148,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits CProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral} LimitProvider = New ADateTime("dd.MM.yyyy HH:mm") PendingUsers = New List(Of PendingUser) - HOST = Settings(RedditSiteKey) + HOST_COLLECTION = Settings(RedditSiteKey) CMB_CHANNELS = New ComboBoxExtended With { .CaptionMode = ICaptionControl.Modes.CheckBox, @@ -312,7 +312,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits Dim Added% = 0, Skipped% = 0 Dim StartIndex% = Settings.Users.Count Dim f As SFile - Dim umo As Boolean = HOST.GetUserMediaOnly + Dim umo As Boolean Settings.Labels.Add(UserData.CannelsLabelName_ChannelsForm) Settings.Labels.Add(LabelsKeeper.NoParsedUser) Dim rUsers$() = UserBanned(PendingUsers.Select(Function(u) u.ID).ToArray) @@ -321,13 +321,23 @@ Friend Class ChannelViewForm : Implements IChannelLimits Dim c As New ListAddParams(LAP.NotContainsOnly) Dim cn$ Dim tmpUser As IUserData - With PendingUsers.Select(Function(u) New UserInfo(u, HOST)) + Dim h As SettingsHost + With PendingUsers.Select(Function(u) New UserInfo(u, If(u.Channel?.HOST, HOST_COLLECTION.Default))) For i = 0 To .Count - 1 If Not Settings.UsersList.Contains(.ElementAt(i)) Then f = PendingUsers(i).File - cn = If(PendingUsers(i).Channel?.Name, String.Empty) + If Not PendingUsers(i).Channel Is Nothing Then + cn = PendingUsers(i).Channel.Name + umo = PendingUsers(i).Channel.HOST.GetUserMediaOnly + h = PendingUsers(i).Channel.HOST + Else + cn = String.Empty + umo = True + h = Nothing + End If + If h Is Nothing Then h = HOST_COLLECTION.Default Settings.UpdateUsersList(.ElementAt(i)) - tmpUser = HOST.GetInstance(Plugin.ISiteSettings.Download.Main, .ElementAt(i), False) + tmpUser = h.GetInstance(Plugin.ISiteSettings.Download.Main, .ElementAt(i), False) With DirectCast(tmpUser, UserData) .Temporary = Settings.ChannelsDefaultTemporary .CreatedByChannel = True @@ -417,7 +427,18 @@ Friend Class ChannelViewForm : Implements IChannelLimits Private Async Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click Try AppendPendingUsers() - If Not TokenSource Is Nothing OrElse Not HOST.Source.Available(Plugin.ISiteSettings.Download.Main, False) Then Exit Sub + Dim c As Channel + If CMB_CHANNELS.Count > 0 Then + Dim hList As IEnumerable(Of String) = Nothing + If CMB_CHANNELS.Checked Then + hList = Settings.Channels.Select(Function(cc) cc.RedditAccount.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).Distinct + Else + c = GetCurrentChannel() + If Not c Is Nothing Then hList = {c.RedditAccount} + End If + If Not TokenSource Is Nothing OrElse Not HOST_COLLECTION.Available(Plugin.ISiteSettings.Download.Main, False, False, + hList, Not hList Is Nothing) Then Exit Sub + End If Dim InvokeToken As Action = Sub() If TokenSource Is Nothing Then CProgress.Maximum = 0 @@ -437,7 +458,6 @@ Friend Class ChannelViewForm : Implements IChannelLimits MyRange.Enabled = False End If End Sub - Dim c As Channel If CMB_CHANNELS.Count > 0 Then BTT_DOWNLOAD.Enabled = False BTT_STOP.Enabled = True @@ -607,7 +627,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits Try c = GetCurrentChannel() If Not c Is Nothing Then - Using f As New RedditViewSettingsForm(c) + Using f As New RedditViewSettingsForm(c, False) f.ShowDialog() If f.DialogResult = DialogResult.OK Then c.Save() End Using diff --git a/SCrawler/Download/DownloadProgress.vb b/SCrawler/Download/DownloadProgress.vb index 04f53f8..67c0fcc 100644 --- a/SCrawler/Download/DownloadProgress.vb +++ b/SCrawler/Download/DownloadProgress.vb @@ -49,8 +49,8 @@ Namespace DownloadObjects } CreateButton(BTT_STOP, My.Resources.DeletePic_24) Dim img As Image = Nothing - If Not _Job.Host Is Nothing Then - With Job.Host.Source + If Not _Job.Host(String.Empty) Is Nothing Then + With Job.Host(String.Empty).Source If Not .Icon Is Nothing Then img = .Icon.ToBitmap If img Is Nothing AndAlso Not .Image Is Nothing Then img = .Image End With @@ -131,8 +131,8 @@ Namespace DownloadObjects End With End With - If Job.Type = Download.SavedPosts And Not Job.Progress Is Nothing Then Job.Progress.InformationTemporary = Job.Host.Name - Instance = New API.Base.ProfileSaved(Job.Host, Job.Progress) + If Job.Type = Download.SavedPosts And Not Job.Progress Is Nothing Then Job.Progress.InformationTemporary = Job.HostCollection.Name + Instance = New API.Base.ProfileSaved(Job.HostCollection, Job.Progress) End Sub Private Sub CreateButton(ByRef BTT As Button, ByVal Img As Image) BTT = New Button With { @@ -154,7 +154,7 @@ Namespace DownloadObjects [Stop]() End Sub Private Sub BTT_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_OPEN.Click - GlobalOpenPath(Job.Host.SavedPostsPath) + GlobalOpenPath(If(Job.HostCollection.FirstOrDefault(Function(h) h.DownloadSavedPosts), Job.HostCollection.Default).SavedPostsPath) End Sub #End Region #Region "Start, Stop" @@ -173,13 +173,13 @@ Namespace DownloadObjects Try btte.Invoke(BTT_START, False) btte.Invoke(BTT_STOP, True) - Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading started" + Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading started" Job.Start() Instance.Download(Job.Token, _IsMultiple) - RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.Host.Name} posts is completed") + RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.HostCollection.Name} posts is completed") Catch ex As Exception - Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading error" - ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Job.Host.Name} saved posts downloading error", "Saved posts"}) + Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading error" + ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Job.HostCollection.Name} saved posts downloading error", "Saved posts"}) Finally _IsMultiple = False btte.Invoke(BTT_START, True) diff --git a/SCrawler/Download/DownloadSavedPostsForm.vb b/SCrawler/Download/DownloadSavedPostsForm.vb index 0bf0118..3257351 100644 --- a/SCrawler/Download/DownloadSavedPostsForm.vb +++ b/SCrawler/Download/DownloadSavedPostsForm.vb @@ -25,7 +25,7 @@ Friend Class DownloadSavedPostsForm If Settings.Plugins.Count > 0 Then Dim j As TDownloader.Job For Each p As PluginHost In Settings.Plugins - If p.Settings.IsSavedPostsCompatible Then + If p.Settings.Default.IsSavedPostsCompatible Then j = New TDownloader.Job(Plugin.ISiteSettings.Download.SavedPosts) j.AddHost(p.Settings) JobsList.Add(New DownloadProgress(j)) diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb b/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb index 8047e66..595c431 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb +++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb @@ -32,8 +32,10 @@ Namespace DownloadObjects.STDownloader Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() + Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Me.TXT_URL = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_PATH = New PersonalUtilities.Forms.Controls.ComboBoxExtended() + Me.CMB_ACCOUNT = New PersonalUtilities.Forms.Controls.ComboBoxExtended() CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() TP_MAIN = New System.Windows.Forms.TableLayoutPanel() CONTAINER_MAIN.ContentPanel.SuspendLayout() @@ -41,6 +43,7 @@ Namespace DownloadObjects.STDownloader TP_MAIN.SuspendLayout() CType(Me.TXT_URL, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'CONTAINER_MAIN @@ -49,13 +52,13 @@ Namespace DownloadObjects.STDownloader 'CONTAINER_MAIN.ContentPanel ' CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(484, 84) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(484, 88) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) CONTAINER_MAIN.Name = "CONTAINER_MAIN" CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(484, 84) + CONTAINER_MAIN.Size = New System.Drawing.Size(484, 113) CONTAINER_MAIN.TabIndex = 0 CONTAINER_MAIN.TopToolStripPanelVisible = False ' @@ -64,17 +67,18 @@ Namespace DownloadObjects.STDownloader TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] TP_MAIN.ColumnCount = 1 TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_MAIN.Controls.Add(Me.TXT_URL, 0, 0) TP_MAIN.Controls.Add(Me.TXT_PATH, 0, 1) + TP_MAIN.Controls.Add(Me.CMB_ACCOUNT, 0, 2) TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill TP_MAIN.Location = New System.Drawing.Point(0, 0) TP_MAIN.Name = "TP_MAIN" - TP_MAIN.RowCount = 3 + TP_MAIN.RowCount = 4 + TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.Size = New System.Drawing.Size(484, 84) + TP_MAIN.Size = New System.Drawing.Size(484, 88) TP_MAIN.TabIndex = 0 ' 'TXT_URL @@ -84,7 +88,7 @@ Namespace DownloadObjects.STDownloader ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear Me.TXT_URL.Buttons.Add(ActionButton1) Me.TXT_URL.CaptionText = "URL" - Me.TXT_URL.CaptionWidth = 40.0R + Me.TXT_URL.CaptionWidth = 50.0R Me.TXT_URL.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_URL.Location = New System.Drawing.Point(4, 4) Me.TXT_URL.Name = "TXT_URL" @@ -116,7 +120,7 @@ Namespace DownloadObjects.STDownloader Me.TXT_PATH.CaptionToolTipEnabled = True Me.TXT_PATH.CaptionToolTipText = "Output path" Me.TXT_PATH.CaptionVisible = True - Me.TXT_PATH.CaptionWidth = 40.0R + Me.TXT_PATH.CaptionWidth = 50.0R ListColumn1.Name = "COL_NAME" ListColumn1.Text = "Name" ListColumn1.Width = -1 @@ -135,19 +139,38 @@ Namespace DownloadObjects.STDownloader Me.TXT_PATH.TabIndex = 1 Me.TXT_PATH.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle ' + 'CMB_ACCOUNT + ' + ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image) + ActionButton6.Name = "ArrowDown" + ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_ACCOUNT.Buttons.Add(ActionButton6) + Me.CMB_ACCOUNT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label + Me.CMB_ACCOUNT.CaptionText = "Account" + Me.CMB_ACCOUNT.CaptionToolTipEnabled = True + Me.CMB_ACCOUNT.CaptionToolTipText = "Select an account to download this media" + Me.CMB_ACCOUNT.CaptionVisible = True + Me.CMB_ACCOUNT.CaptionWidth = 50.0R + Me.CMB_ACCOUNT.Dock = System.Windows.Forms.DockStyle.Fill + Me.CMB_ACCOUNT.Location = New System.Drawing.Point(4, 62) + Me.CMB_ACCOUNT.Name = "CMB_ACCOUNT" + Me.CMB_ACCOUNT.Size = New System.Drawing.Size(476, 22) + Me.CMB_ACCOUNT.TabIndex = 2 + Me.CMB_ACCOUNT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + ' 'DownloaderUrlForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(484, 84) + Me.ClientSize = New System.Drawing.Size(484, 113) Me.Controls.Add(CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.Icon = Global.SCrawler.My.Resources.Resources.ArrowDownIcon_Blue_24 Me.KeyPreview = True Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(500, 123) + Me.MaximumSize = New System.Drawing.Size(500, 152) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(500, 123) + Me.MinimumSize = New System.Drawing.Size(500, 152) Me.Name = "DownloaderUrlForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -158,10 +181,12 @@ Namespace DownloadObjects.STDownloader TP_MAIN.ResumeLayout(False) CType(Me.TXT_URL, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub Private WithEvents TXT_URL As PersonalUtilities.Forms.Controls.TextBoxExtended Private WithEvents TXT_PATH As PersonalUtilities.Forms.Controls.ComboBoxExtended + Private WithEvents CMB_ACCOUNT As PersonalUtilities.Forms.Controls.ComboBoxExtended End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.resx b/SCrawler/Download/STDownloader/DownloaderUrlForm.resx index 299ec6d..9a19560 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlForm.resx +++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.resx @@ -261,6 +261,96 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A AAAASUVORK5CYII= + + + + + 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 + AAAASUVORK5CYII= \ No newline at end of file diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.vb b/SCrawler/Download/STDownloader/DownloaderUrlForm.vb index dcd4b49..db7bd03 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlForm.vb +++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.vb @@ -14,6 +14,11 @@ Namespace DownloadObjects.STDownloader Private WithEvents MyDefs As DefaultFormOptions Friend Property URL As String Friend Property OutputPath As SFile + Friend ReadOnly Property AccountName As String + Get + Return CMB_ACCOUNT.Text + End Get + End Property Friend Sub New() InitializeComponent() MyDefs = New DefaultFormOptions(Me, Settings.Design) @@ -26,6 +31,7 @@ Namespace DownloadObjects.STDownloader Settings.DownloadLocations.PopulateComboBox(TXT_PATH) TXT_PATH.Text = Settings.LatestSavingPath.Value If TXT_PATH.Text.IsEmptyString Then TXT_PATH.Text = Application.StartupPath.CSFileP.PathWithSeparator + TXT_URL_ActionOnTextChanged() .MyFieldsChecker = New FieldsChecker With .MyFieldsCheckerE .AddControl(Of String)(TXT_URL, TXT_URL.CaptionText) @@ -54,6 +60,36 @@ Namespace DownloadObjects.STDownloader MyDefs.CloseForm() End If End Sub + Friend Shared Function GetMediaPluginKey(ByVal URL As String) As String + If Not URL.IsEmptyString Then + Return Settings.Plugins.Select(Function(p) p.Settings.IsMyImageVideo(URL).HostKey).FirstOrDefault(Function(p) Not p.IsEmptyString) + Else + Return String.Empty + End If + End Function + Private Sub TXT_URL_ActionOnTextChanged() Handles TXT_URL.ActionOnTextChanged + Try + With CMB_ACCOUNT + .BeginUpdate() + .Items.Clear() + .Text = String.Empty + If Not TXT_URL.Text.IsEmptyString Then + Dim plugin$ = Settings.Plugins.Select(Function(p) p.Settings.IsMyImageVideo(TXT_URL.Text).HostKey).FirstOrDefault(Function(p) Not p.IsEmptyString) + If Not plugin.IsEmptyString Then _ + CMB_ACCOUNT.Items.AddRange(Settings(plugin).Select(Function(p) New ListItem(p.AccountName.IfNullOrEmpty( + SCrawler.Plugin.Hosts.SettingsHost.NameAccountNameDefault)))) + End If + .LeaveDefaultButtons = .Items.Count > 1 + .Buttons.UpdateButtonsPositions() + .EndUpdate() + If .Items.Count > 0 Then .SelectedIndex = 0 + .Enabled = .Items.Count > 1 + End With + Catch ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, ex, "[STDownloader.DownloaderUrlForm.TXT_URL_ActionOnTextChanged]") + MainFrameObj.UpdateLogButton() + End Try + End Sub Private Sub TXT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH.ActionOnButtonClick If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _ Settings.DownloadLocations.ChooseNewLocation(TXT_PATH, Sender.DefaultButton = ADB.Add, Settings.STDownloader_OutputPathAskForName) diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb index babbd6f..fe162be 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb +++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb @@ -32,8 +32,10 @@ Namespace DownloadObjects.STDownloader Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() Dim FRM_URLS As System.Windows.Forms.GroupBox + Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Me.TXT_OUTPUT = New PersonalUtilities.Forms.Controls.ComboBoxExtended() Me.TXT_URLS = New System.Windows.Forms.RichTextBox() + Me.CMB_ACCOUNT = New PersonalUtilities.Forms.Controls.ComboBoxExtended() CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() TP_MAIN = New System.Windows.Forms.TableLayoutPanel() FRM_URLS = New System.Windows.Forms.GroupBox() @@ -42,6 +44,7 @@ Namespace DownloadObjects.STDownloader TP_MAIN.SuspendLayout() CType(Me.TXT_OUTPUT, System.ComponentModel.ISupportInitialize).BeginInit() FRM_URLS.SuspendLayout() + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'CONTAINER_MAIN @@ -50,7 +53,7 @@ Namespace DownloadObjects.STDownloader 'CONTAINER_MAIN.ContentPanel ' CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 261) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 236) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) @@ -64,16 +67,17 @@ Namespace DownloadObjects.STDownloader ' TP_MAIN.ColumnCount = 1 TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_MAIN.Controls.Add(Me.TXT_OUTPUT, 0, 0) - TP_MAIN.Controls.Add(FRM_URLS, 0, 1) + TP_MAIN.Controls.Add(FRM_URLS, 0, 2) + TP_MAIN.Controls.Add(Me.CMB_ACCOUNT, 0, 1) TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill TP_MAIN.Location = New System.Drawing.Point(0, 0) TP_MAIN.Name = "TP_MAIN" - TP_MAIN.RowCount = 2 + TP_MAIN.RowCount = 3 + TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_MAIN.Size = New System.Drawing.Size(384, 261) + TP_MAIN.Size = New System.Drawing.Size(384, 236) TP_MAIN.TabIndex = 0 ' 'TXT_OUTPUT @@ -120,10 +124,10 @@ Namespace DownloadObjects.STDownloader ' FRM_URLS.Controls.Add(Me.TXT_URLS) FRM_URLS.Dock = System.Windows.Forms.DockStyle.Fill - FRM_URLS.Location = New System.Drawing.Point(3, 31) + FRM_URLS.Location = New System.Drawing.Point(3, 59) FRM_URLS.Name = "FRM_URLS" - FRM_URLS.Size = New System.Drawing.Size(378, 227) - FRM_URLS.TabIndex = 1 + FRM_URLS.Size = New System.Drawing.Size(378, 174) + FRM_URLS.TabIndex = 2 FRM_URLS.TabStop = False FRM_URLS.Text = "URLs (new line as delimiter)" ' @@ -133,10 +137,29 @@ Namespace DownloadObjects.STDownloader Me.TXT_URLS.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_URLS.Location = New System.Drawing.Point(3, 16) Me.TXT_URLS.Name = "TXT_URLS" - Me.TXT_URLS.Size = New System.Drawing.Size(372, 208) + Me.TXT_URLS.Size = New System.Drawing.Size(372, 155) Me.TXT_URLS.TabIndex = 0 Me.TXT_URLS.Text = "" ' + 'CMB_ACCOUNT + ' + ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image) + ActionButton5.Name = "ArrowDown" + ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_ACCOUNT.Buttons.Add(ActionButton5) + Me.CMB_ACCOUNT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label + Me.CMB_ACCOUNT.CaptionText = "Account" + Me.CMB_ACCOUNT.CaptionToolTipEnabled = True + Me.CMB_ACCOUNT.CaptionToolTipText = "Select an account to download media array" + Me.CMB_ACCOUNT.CaptionVisible = True + Me.CMB_ACCOUNT.CaptionWidth = 50.0R + Me.CMB_ACCOUNT.Dock = System.Windows.Forms.DockStyle.Fill + Me.CMB_ACCOUNT.Location = New System.Drawing.Point(3, 31) + Me.CMB_ACCOUNT.Name = "CMB_ACCOUNT" + Me.CMB_ACCOUNT.Size = New System.Drawing.Size(378, 22) + Me.CMB_ACCOUNT.TabIndex = 1 + Me.CMB_ACCOUNT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle + ' 'DownloaderUrlsArrForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) @@ -155,10 +178,12 @@ Namespace DownloadObjects.STDownloader TP_MAIN.ResumeLayout(False) CType(Me.TXT_OUTPUT, System.ComponentModel.ISupportInitialize).EndInit() FRM_URLS.ResumeLayout(False) + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub Private WithEvents TXT_OUTPUT As PersonalUtilities.Forms.Controls.ComboBoxExtended Private WithEvents TXT_URLS As RichTextBox + Private WithEvents CMB_ACCOUNT As PersonalUtilities.Forms.Controls.ComboBoxExtended End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx index 04fd3f1..cf94e9a 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx +++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx @@ -258,4 +258,94 @@ False + + + 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 + AAAASUVORK5CYII= + + \ No newline at end of file diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb index b3e5597..2d062f6 100644 --- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb +++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb @@ -26,6 +26,17 @@ Namespace DownloadObjects.STDownloader End If End Get End Property + Friend ReadOnly Property AccountName As String + Get + Return CMB_ACCOUNT.Text + End Get + End Property + Private _UseAccountName As Boolean = False + Friend ReadOnly Property UseAccountName As Boolean + Get + Return _UseAccountName + End Get + End Property Friend Sub New(ByVal InitialList As IEnumerable(Of String)) InitializeComponent() MyDefs = New DefaultFormOptions(Me, Settings.Design) @@ -38,6 +49,7 @@ Namespace DownloadObjects.STDownloader Settings.DownloadLocations.PopulateComboBox(TXT_OUTPUT) TXT_OUTPUT.Text = Settings.LatestSavingPath.Value.PathWithSeparator If TXT_OUTPUT.Text.IsEmptyString Then TXT_OUTPUT.Text = Application.StartupPath.CSFileP.PathWithSeparator + TXT_URLS_TextChanged() .MyFieldsChecker = New FieldsChecker With .MyFieldsCheckerE .AddControl(Of String)(TXT_OUTPUT, TXT_OUTPUT.CaptionText) @@ -65,5 +77,33 @@ Namespace DownloadObjects.STDownloader If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _ Settings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT, Sender.DefaultButton = ADB.Add, Settings.STDownloader_OutputPathAskForName) End Sub + Private Sub TXT_URLS_TextChanged() Handles TXT_URLS.TextChanged + Try + With CMB_ACCOUNT + .BeginUpdate() + .Items.Clear() + .Text = String.Empty + _UseAccountName = False + If Not TXT_URLS.Text.IsEmptyString Then + Dim plugins As IEnumerable(Of String) = TXT_URLS.Lines.Select(Function(u) DownloaderUrlForm.GetMediaPluginKey(u)).Distinct + Dim fpl As Func(Of String, Boolean) = Function(p) Not p.IsEmptyString + If plugins.ListExists AndAlso plugins.LongCount(fpl) = 1 Then + CMB_ACCOUNT.Items.AddRange(Settings(plugins.First(fpl)).Select(Function(p) New ListItem(p.AccountName.IfNullOrEmpty( + Plugin.Hosts.SettingsHost.NameAccountNameDefault)))) + _UseAccountName = True + End If + End If + .LeaveDefaultButtons = .Items.Count > 1 + .Buttons.UpdateButtonsPositions() + .EndUpdate() + If .Items.Count > 0 Then .SelectedIndex = 0 + .Enabled = .Items.Count > 1 + End With + Catch ex As Exception + _UseAccountName = True + ErrorsDescriber.Execute(EDP.SendToLog, ex, "[STDownloader.DownloaderUrlsArrForm.TXT_URLS_TextChanged]") + MainFrameObj.UpdateLogButton() + End Try + End Sub End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb index 9a51217..077913f 100644 --- a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb +++ b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb @@ -68,6 +68,7 @@ Namespace DownloadObjects.STDownloader If Not isExternal Then url = BufferText Dim disableDown As Boolean = e.Shift Dim output As SFile = Settings.LatestSavingPath + Dim acc$ = String.Empty Dim isArr As Boolean = (__tag = UrlsArrTag Or (isExternal And ExternalUrlsTemp.Count > 1)) Dim formOpened As Boolean = False Dim media As IYouTubeMediaContainer @@ -79,6 +80,7 @@ Namespace DownloadObjects.STDownloader If f.DialogResult = DialogResult.OK Then url = f.URL output = f.OutputPath + acc = f.AccountName Settings.LatestSavingPath.Value = output If Settings.STDownloader_UpdateYouTubeOutputPath Then _ API.YouTube.MyYouTubeSettings.OutputPath.Value = output @@ -127,6 +129,7 @@ Namespace DownloadObjects.STDownloader If fa.DialogResult = DialogResult.OK Then urls = fa.URLs.ToList output = fa.OutputPath + If fa.UseAccountName Then acc = fa.AccountName If Settings.STDownloader_UpdateYouTubeOutputPath Then API.YouTube.MyYouTubeSettings.OutputPath.Value = output If Settings.STDownloader_OutputPathAutoAddPaths Then Settings.DownloadLocations.Add(output, False) Else @@ -142,7 +145,7 @@ Namespace DownloadObjects.STDownloader For Each url In urls If Not TryYouTube.Invoke Then media = FindSource(url, output) - If Not media Is Nothing Then ControlCreateAndAdd(media, disableDown) + If Not media Is Nothing Then media.AccountName = acc : ControlCreateAndAdd(media, disableDown) End If Next urls.Clear() @@ -173,6 +176,7 @@ Namespace DownloadObjects.STDownloader If media Is Nothing Then MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical) Else + media.AccountName = acc output.Exists(SFO.Path, True) ControlCreateAndAdd(media, disableDown) End If diff --git a/SCrawler/Download/TDownloader.vb b/SCrawler/Download/TDownloader.vb index e7ba2fc..b7cb26c 100644 --- a/SCrawler/Download/TDownloader.vb +++ b/SCrawler/Download/TDownloader.vb @@ -154,7 +154,7 @@ Namespace DownloadObjects #Region "Working, Count" Friend ReadOnly Property Working As Boolean Get - Return Pool.Count > 0 AndAlso Pool.Exists(Function(j) j.Working) + Return _PoolReconfiguration Or (Pool.Count > 0 AndAlso Pool.Exists(Function(j) j.Working)) Or If(CheckerThread?.IsAlive, False) End Get End Property Friend ReadOnly Property Count As Integer @@ -180,13 +180,13 @@ Namespace DownloadObjects #End Region #Region "Jobs" Friend Class Job : Inherits JobThread(Of IUserData) - Private ReadOnly Hosts As List(Of SettingsHost) + Private ReadOnly Hosts As List(Of SettingsHostCollection) Private ReadOnly Keys As List(Of String) Private ReadOnly RemovingKeys As List(Of String) Friend ReadOnly Property [Type] As Download Friend ReadOnly Property IsSeparated As Boolean Get - Return Hosts.Count = 1 AndAlso Hosts(0).IsSeparatedTasks + Return Hosts.Count = 1 AndAlso Hosts(0).Default.IsSeparatedTasks End Get End Property Friend ReadOnly Property Name As String @@ -195,23 +195,28 @@ Namespace DownloadObjects End Get End Property Friend ReadOnly Property GroupName As String - Friend ReadOnly Property TaskCount As Integer + Friend ReadOnly Property TaskCount(ByVal AccountName As String) As Integer Get - Return Hosts(0).TaskCount + Return Hosts(0)(AccountName).TaskCount End Get End Property - Friend ReadOnly Property Host As SettingsHost + Friend ReadOnly Property HostCollection As SettingsHostCollection + Get + Return Hosts(0) + End Get + End Property + Friend ReadOnly Property Host(ByVal AccountName As String) As SettingsHost Get If Hosts.Count > 0 Then Dim k$ = Hosts(0).Key Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = k) - If i >= 0 Then Return Settings.Plugins(i).Settings + If i >= 0 Then Return Settings.Plugins(i).Settings(AccountName) End If Return Nothing End Get End Property Friend Sub New(ByVal JobType As Download) - Hosts = New List(Of SettingsHost) + Hosts = New List(Of SettingsHostCollection) RemovingKeys = New List(Of String) Keys = New List(Of String) [Type] = JobType @@ -236,28 +241,41 @@ Namespace DownloadObjects End With Return False End Function - Friend Sub AddHost(ByRef h As SettingsHost) + Friend Sub AddHost(ByRef h As SettingsHostCollection) Hosts.Add(h) Keys.Add(h.Key) End Sub Friend Function UserHost(ByVal User As IUserData) As SettingsHost Dim i% = Keys.IndexOf(DirectCast(User, UserDataBase).User.Plugin) - If i >= 0 Then Return Hosts(i) Else Throw New KeyNotFoundException($"Plugin key [{DirectCast(User, UserDataBase).User.Plugin}] not found") + If i >= 0 Then Return Hosts(i)(User.AccountName) Else Throw New KeyNotFoundException($"Plugin key [{DirectCast(User, UserDataBase).User.Plugin}] not found") End Function Friend Function Available(ByVal Silent As Boolean) As Boolean If Hosts.Count > 0 Then Dim k$ + Dim h As SettingsHostCollection + Dim hList As IEnumerable(Of String) For i% = Hosts.Count - 1 To 0 Step -1 - If Not Hosts(i).Available(Type, Silent) Then - k = Hosts(i).Key - If Not RemovingKeys.Contains(k) Then RemovingKeys.Add(k) - Hosts(i).DownloadDone(Type) - Hosts.RemoveAt(i) - Keys.RemoveAt(i) - If Items.Count > 0 Then Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k) + h = Hosts(i) + k = h.Key + hList = Nothing + If Items.Count > 0 Then + hList = (From u As UserDataBase In Items + Where u.HOST.Key = k + Select u.HOST.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).Distinct + If Not h.Available(Type, Silent,, hList, True) Then + If Not RemovingKeys.Contains(k) Then RemovingKeys.Add(k) + h.DownloadDone(Type) + Hosts.RemoveAt(i) + Keys.RemoveAt(i) + If Items.Count > 0 Then Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k) + ElseIf h.CountUnavailable > 0 AndAlso Items.Count > 0 Then + Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k And Not h.AvailablePartial(u.AccountName)) + End If + Else + Hosts.Clear() End If Next - Return Hosts.Count > 0 + Return Hosts.Count > 0 And Items.Count > 0 Else Return False End If @@ -303,7 +321,12 @@ Namespace DownloadObjects End Sub #End Region #Region "Pool" - Friend Sub ReconfPool(Optional ByVal Round As Integer = 0) + Private _PoolReconfiguration As Boolean = False + Friend Overloads Sub ReconfPool() + _PoolReconfiguration = True + Try : ReconfPool(0) : Finally : _PoolReconfiguration = False : End Try + End Sub + Friend Overloads Sub ReconfPool(ByVal Round As Integer) Try If Pool.Count = 0 OrElse Not Pool.Exists(Function(j) j.Working Or j.Count > 0) Then Dim i% @@ -311,16 +334,16 @@ Namespace DownloadObjects If Settings.Plugins.Count > 0 Then Pool.Add(New Job(Download.Main)) For Each p As PluginHost In Settings.Plugins - If p.Settings.IsSeparatedTasks Then + If p.Settings.Default.IsSeparatedTasks Then Pool.Add(New Job(Download.Main)) Pool.Last.AddHost(p.Settings) - ElseIf Not p.Settings.TaskGroupName.IsEmptyString Then + ElseIf Not p.Settings.Default.TaskGroupName.IsEmptyString Then i = -1 - If Pool.Count > 0 Then i = Pool.FindIndex(Function(pt) pt.GroupName = p.Settings.TaskGroupName) + If Pool.Count > 0 Then i = Pool.FindIndex(Function(pt) pt.GroupName = p.Settings.Default.TaskGroupName) If i >= 0 Then Pool(i).AddHost(p.Settings) Else - Pool.Add(New Job(Download.Main, p.Settings.TaskGroupName)) + Pool.Add(New Job(Download.Main, p.Settings.Default.TaskGroupName)) Pool.Last.AddHost(p.Settings) End If Else @@ -331,11 +354,7 @@ Namespace DownloadObjects RaiseEvent Reconfigured() End If Catch ex As Exception - If Round = 0 Then - ReconfPool(Round + 1) - Else - Throw ex - End If + If Round = 0 Then ReconfPool(Round + 1) Else Throw ex End Try End Sub #End Region @@ -429,28 +448,58 @@ Namespace DownloadObjects Private Sub UpdateJobsLabel() RaiseEvent JobsChange(Count) End Sub + Friend Structure HostLimit + Friend Key As String + Friend Limit As Integer + Friend Value As Integer + Public Shared Widening Operator CType(ByVal Host As SettingsHost) As HostLimit + Return New HostLimit With {.Key = Host.KeyDownloader, .Limit = Host.TaskCount, .Value = 0} + End Operator + Friend Function [Next]() As HostLimit + Value += 1 + Return Me + End Function + Public Overrides Function Equals(ByVal Obj As Object) As Boolean + Return Key = CType(Obj, HostLimit).Key + End Function + End Structure Private Sub DownloadData(ByRef _Job As Job, ByVal Token As CancellationToken) Try If _Job.Count > 0 Then Const nf As ANumbers.Formats = ANumbers.Formats.Number Dim t As New List(Of Task) Dim i% = 0 - Dim limit% = _Job.TaskCount + Dim limit As HostLimit + Dim limitIndex% + Dim limits As New List(Of HostLimit) Dim Keys As New List(Of String) Dim h As Boolean = False Dim host As SettingsHost = Nothing + Dim hostAvailable As Boolean For Each _Item As IUserData In _Job.Items If Not _Item.Disposed Then - Keys.Add(_Item.Key) host = _Job.UserHost(_Item) - If host.Source.ReadyToDownload(Download.Main) Then - host.BeforeStartDownload(_Item, Download.Main) - _Job.ThrowIfCancellationRequested() - DirectCast(_Item, UserDataBase).Progress = _Job.Progress - t.Add(Task.Run(Sub() _Item.DownloadData(Token))) - RaiseEvent UserDownloadStateChanged(_Item, True) - i += 1 - If i >= limit Then Exit For + hostAvailable = DirectCast(_Item, UserDataBase).HostCollection.AvailablePartial(_Item.AccountName) + Keys.Add(_Item.Key) + If hostAvailable Then + limit = host + If Not limits.Contains(limit) Then + limits.Add(limit) + limitIndex = limits.Count - 1 + Else + limitIndex = limits.IndexOf(limit) + limit = limits(limitIndex) + End If + If host.Source.ReadyToDownload(Download.Main) Then + host.BeforeStartDownload(_Item, Download.Main) + _Job.ThrowIfCancellationRequested() + DirectCast(_Item, UserDataBase).Progress = _Job.Progress + t.Add(Task.Run(Sub() _Item.DownloadData(Token))) + RaiseEvent UserDownloadStateChanged(_Item, True) + limit = limit.Next + limits(limitIndex) = limit + If limit.Value >= limit.Limit Then Exit For + End If End If End If Next @@ -470,6 +519,7 @@ Namespace DownloadObjects With _Job.Items(i) If DirectCast(.Self, UserDataBase).ContentMissingExists Then MissingPostsDetected = True RaiseEvent UserDownloadStateChanged(.Self, False) + host = _Job.UserHost(.Self) host.AfterDownload(.Self, Download.Main) If Not .Disposed AndAlso Not .IsCollection AndAlso .DownloadedTotal(False) > 0 Then If Not Downloaded.Contains(.Self) Then Downloaded.Add(Settings.GetUser(.Self)) diff --git a/SCrawler/Editors/GlobalSettingsForm.Designer.vb b/SCrawler/Editors/GlobalSettingsForm.Designer.vb index c392fbc..aaff696 100644 --- a/SCrawler/Editors/GlobalSettingsForm.Designer.vb +++ b/SCrawler/Editors/GlobalSettingsForm.Designer.vb @@ -24,16 +24,16 @@ Namespace Editors Private Sub InitializeComponent() Me.components = New System.ComponentModel.Container() Dim TP_BASIS As System.Windows.Forms.TableLayoutPanel - Dim ActionButton55 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(GlobalSettingsForm)) - Dim ActionButton56 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_IMAGES As System.Windows.Forms.TableLayoutPanel - Dim ActionButton57 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton58 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton59 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton60 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton61 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton62 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel Dim LBL_DATE_POS As System.Windows.Forms.Label @@ -46,14 +46,14 @@ Namespace Editors Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel Dim TAB_BEHAVIOR As System.Windows.Forms.TabPage Dim TP_BEHAVIOR As System.Windows.Forms.TableLayoutPanel - Dim ActionButton63 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton64 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_OPEN_INFO As System.Windows.Forms.TableLayoutPanel Dim TP_OPEN_PROGRESS As System.Windows.Forms.TableLayoutPanel Dim TAB_DOWN As System.Windows.Forms.TabPage Dim TP_DOWNLOADING As System.Windows.Forms.TableLayoutPanel - Dim ActionButton65 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton66 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton11 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton12 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TP_MISSING_DATA As System.Windows.Forms.TableLayoutPanel Dim TAB_FEED As System.Windows.Forms.TabPage Dim TP_FEED As System.Windows.Forms.TableLayoutPanel @@ -61,27 +61,27 @@ Namespace Editors Dim TAB_NOTIFY As System.Windows.Forms.TabPage Dim TP_NOTIFY_MAIN As System.Windows.Forms.TableLayoutPanel Dim TP_ENVIR As System.Windows.Forms.TableLayoutPanel - Dim ActionButton67 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton68 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton69 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton70 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton71 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton72 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton73 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton74 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton75 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton76 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton15 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton16 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton17 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton18 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton19 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton20 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton21 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton22 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim TAB_STD As System.Windows.Forms.TabPage Dim TP_STD As System.Windows.Forms.TableLayoutPanel - Dim ActionButton77 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ListColumn5 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() - Dim ListColumn6 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() + Dim ActionButton23 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() + Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn() Dim TAB_DESIGN As System.Windows.Forms.TabPage Dim TP_DESIGN As System.Windows.Forms.TableLayoutPanel - Dim ActionButton78 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton79 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton80 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() - Dim ActionButton81 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton24 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton25 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton26 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton27 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended() @@ -131,6 +131,7 @@ Namespace Editors Me.BTT_RESET_DOWNLOAD_LOCATIONS = New System.Windows.Forms.Button() Me.CH_STD_SNAP_KEEP_WITH_FILES = New System.Windows.Forms.CheckBox() Me.CH_STD_SNAP_CACHE_PERMANENT = New System.Windows.Forms.CheckBox() + Me.CH_STD_YT_CREATE_URL = New System.Windows.Forms.CheckBox() Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox() @@ -175,7 +176,7 @@ Namespace Editors Me.TAB_MAIN = New System.Windows.Forms.TabControl() Me.TAB_ENVIR = New System.Windows.Forms.TabPage() Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() - Me.CH_STD_YT_CREATE_URL = New System.Windows.Forms.CheckBox() + Me.CH_USE_DEF_ACC = New System.Windows.Forms.CheckBox() TP_BASIS = New System.Windows.Forms.TableLayoutPanel() TP_IMAGES = New System.Windows.Forms.TableLayoutPanel() TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel() @@ -302,17 +303,17 @@ Namespace Editors TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_BASIS.Size = New System.Drawing.Size(570, 368) + TP_BASIS.Size = New System.Drawing.Size(570, 393) TP_BASIS.TabIndex = 0 ' 'TXT_GLOBAL_PATH ' - ActionButton55.BackgroundImage = CType(resources.GetObject("ActionButton55.BackgroundImage"), System.Drawing.Image) - ActionButton55.Name = "Open" - ActionButton56.BackgroundImage = CType(resources.GetObject("ActionButton56.BackgroundImage"), System.Drawing.Image) - ActionButton56.Name = "Clear" - Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton55) - Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton56) + ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image) + ActionButton1.Name = "Open" + ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image) + ActionButton2.Name = "Clear" + Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton1) + Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton2) Me.TXT_GLOBAL_PATH.CaptionText = "Data Path" Me.TXT_GLOBAL_PATH.CaptionToolTipEnabled = True Me.TXT_GLOBAL_PATH.CaptionToolTipText = "Root path for storing users' data" @@ -373,9 +374,9 @@ Namespace Editors ' 'TXT_COLLECTIONS_PATH ' - ActionButton57.BackgroundImage = CType(resources.GetObject("ActionButton57.BackgroundImage"), System.Drawing.Image) - ActionButton57.Name = "Clear" - Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton57) + ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image) + ActionButton3.Name = "Clear" + Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton3) Me.TXT_COLLECTIONS_PATH.CaptionText = "Collections folder" Me.TXT_COLLECTIONS_PATH.CaptionToolTipEnabled = True Me.TXT_COLLECTIONS_PATH.CaptionToolTipText = "Set collections folder name (name only)" @@ -387,10 +388,10 @@ Namespace Editors ' 'TXT_MAX_JOBS_USERS ' - ActionButton58.BackgroundImage = CType(resources.GetObject("ActionButton58.BackgroundImage"), System.Drawing.Image) - ActionButton58.Name = "Refresh" - ActionButton58.ToolTipText = "Set to default" - Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton58) + ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image) + ActionButton4.Name = "Refresh" + ActionButton4.ToolTipText = "Set to default" + Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton4) Me.TXT_MAX_JOBS_USERS.CaptionSizeType = System.Windows.Forms.SizeType.Percent Me.TXT_MAX_JOBS_USERS.CaptionText = "Maximum downloading tasks of users" Me.TXT_MAX_JOBS_USERS.CaptionWidth = 50.0R @@ -406,10 +407,10 @@ Namespace Editors ' 'TXT_MAX_JOBS_CHANNELS ' - ActionButton59.BackgroundImage = CType(resources.GetObject("ActionButton59.BackgroundImage"), System.Drawing.Image) - ActionButton59.Name = "Refresh" - ActionButton59.ToolTipText = "Set to default" - Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton59) + ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image) + ActionButton5.Name = "Refresh" + ActionButton5.ToolTipText = "Set to default" + Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton5) Me.TXT_MAX_JOBS_CHANNELS.CaptionSizeType = System.Windows.Forms.SizeType.Percent Me.TXT_MAX_JOBS_CHANNELS.CaptionText = "Maximum downloading tasks of channels" Me.TXT_MAX_JOBS_CHANNELS.CaptionWidth = 50.0R @@ -436,9 +437,9 @@ Namespace Editors ' 'TXT_IMGUR_CLIENT_ID ' - ActionButton60.BackgroundImage = CType(resources.GetObject("ActionButton60.BackgroundImage"), System.Drawing.Image) - ActionButton60.Name = "Clear" - Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton60) + ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image) + ActionButton6.Name = "Clear" + Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton6) Me.TXT_IMGUR_CLIENT_ID.CaptionText = "Imgur Client ID" Me.TXT_IMGUR_CLIENT_ID.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 204) @@ -472,14 +473,14 @@ Namespace Editors ' 'TXT_USER_AGENT ' - ActionButton61.BackgroundImage = CType(resources.GetObject("ActionButton61.BackgroundImage"), System.Drawing.Image) - ActionButton61.Name = "Refresh" - ActionButton61.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh - ActionButton62.BackgroundImage = CType(resources.GetObject("ActionButton62.BackgroundImage"), System.Drawing.Image) - ActionButton62.Name = "Clear" - ActionButton62.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_USER_AGENT.Buttons.Add(ActionButton61) - Me.TXT_USER_AGENT.Buttons.Add(ActionButton62) + ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image) + ActionButton7.Name = "Refresh" + ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh + ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image) + ActionButton8.Name = "Clear" + ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_USER_AGENT.Buttons.Add(ActionButton7) + Me.TXT_USER_AGENT.Buttons.Add(ActionButton8) Me.TXT_USER_AGENT.CaptionText = "UserAgent" Me.TXT_USER_AGENT.CaptionToolTipEnabled = True Me.TXT_USER_AGENT.CaptionToolTipText = "Default user agent to use in requests" @@ -1009,6 +1010,19 @@ Namespace Editors "with 'Create video thumbnail' and 'Keep video thumbnail with files'.") Me.CH_STD_SNAP_CACHE_PERMANENT.UseVisualStyleBackColor = True ' + 'CH_STD_YT_CREATE_URL + ' + Me.CH_STD_YT_CREATE_URL.AutoSize = True + Me.CH_STD_YT_CREATE_URL.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_STD_YT_CREATE_URL.Location = New System.Drawing.Point(4, 322) + Me.CH_STD_YT_CREATE_URL.Name = "CH_STD_YT_CREATE_URL" + Me.CH_STD_YT_CREATE_URL.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_STD_YT_CREATE_URL.Size = New System.Drawing.Size(568, 19) + Me.CH_STD_YT_CREATE_URL.TabIndex = 12 + Me.CH_STD_YT_CREATE_URL.Text = "Create URL files" + TT_MAIN.SetToolTip(Me.CH_STD_YT_CREATE_URL, "Create local URL files to link to the original page") + Me.CH_STD_YT_CREATE_URL.UseVisualStyleBackColor = True + ' 'TP_CHANNELS_IMGS ' TP_CHANNELS_IMGS.ColumnCount = 2 @@ -1060,7 +1074,7 @@ Namespace Editors TAB_BASIS.Location = New System.Drawing.Point(4, 22) TAB_BASIS.Name = "TAB_BASIS" TAB_BASIS.Padding = New System.Windows.Forms.Padding(3) - TAB_BASIS.Size = New System.Drawing.Size(576, 374) + TAB_BASIS.Size = New System.Drawing.Size(576, 399) TAB_BASIS.TabIndex = 0 TAB_BASIS.Text = "Basis" ' @@ -1070,7 +1084,7 @@ Namespace Editors TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22) TAB_DEFAULTS.Name = "TAB_DEFAULTS" TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3) - TAB_DEFAULTS.Size = New System.Drawing.Size(576, 374) + TAB_DEFAULTS.Size = New System.Drawing.Size(576, 399) TAB_DEFAULTS.TabIndex = 1 TAB_DEFAULTS.Text = "Defaults" ' @@ -1096,7 +1110,7 @@ Namespace Editors TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DEFS.Size = New System.Drawing.Size(570, 368) + TP_DEFS.Size = New System.Drawing.Size(570, 393) TP_DEFS.TabIndex = 0 ' 'CH_DOWN_IMAGES_NATIVE @@ -1116,7 +1130,7 @@ Namespace Editors TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22) TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS" TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3) - TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 374) + TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 399) TAB_DEFS_CHANNELS.TabIndex = 4 TAB_DEFS_CHANNELS.Text = "Channels" ' @@ -1140,7 +1154,7 @@ Namespace Editors TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_CHANNELS.Size = New System.Drawing.Size(570, 368) + TP_CHANNELS.Size = New System.Drawing.Size(570, 393) TP_CHANNELS.TabIndex = 0 ' 'TXT_CHANNEL_USER_POST_LIMIT @@ -1168,7 +1182,7 @@ Namespace Editors TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR) TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22) TAB_BEHAVIOR.Name = "TAB_BEHAVIOR" - TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 374) + TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 399) TAB_BEHAVIOR.TabIndex = 5 TAB_BEHAVIOR.Text = "Behavior" ' @@ -1199,17 +1213,17 @@ Namespace Editors TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!)) - TP_BEHAVIOR.Size = New System.Drawing.Size(576, 374) + TP_BEHAVIOR.Size = New System.Drawing.Size(576, 399) TP_BEHAVIOR.TabIndex = 0 ' 'TXT_FOLDER_CMD ' Me.TXT_FOLDER_CMD.AutoShowClearButton = True - ActionButton63.BackgroundImage = CType(resources.GetObject("ActionButton63.BackgroundImage"), System.Drawing.Image) - ActionButton63.Enabled = False - ActionButton63.Name = "Clear" - ActionButton63.Visible = False - Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton63) + ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image) + ActionButton9.Enabled = False + ActionButton9.Name = "Clear" + ActionButton9.Visible = False + Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton9) Me.TXT_FOLDER_CMD.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_FOLDER_CMD.CaptionText = "Folder cmd" Me.TXT_FOLDER_CMD.CaptionToolTipEnabled = True @@ -1248,11 +1262,11 @@ Namespace Editors 'TXT_CLOSE_SCRIPT ' Me.TXT_CLOSE_SCRIPT.AutoShowClearButton = True - ActionButton64.BackgroundImage = CType(resources.GetObject("ActionButton64.BackgroundImage"), System.Drawing.Image) - ActionButton64.Enabled = False - ActionButton64.Name = "Clear" - ActionButton64.Visible = False - Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton64) + ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image) + ActionButton10.Enabled = False + ActionButton10.Name = "Clear" + ActionButton10.Visible = False + Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton10) Me.TXT_CLOSE_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_CLOSE_SCRIPT.CaptionText = "Close cmd" Me.TXT_CLOSE_SCRIPT.CaptionToolTipEnabled = True @@ -1340,7 +1354,7 @@ Namespace Editors TAB_DOWN.Controls.Add(TP_DOWNLOADING) TAB_DOWN.Location = New System.Drawing.Point(4, 22) TAB_DOWN.Name = "TAB_DOWN" - TAB_DOWN.Size = New System.Drawing.Size(576, 374) + TAB_DOWN.Size = New System.Drawing.Size(576, 399) TAB_DOWN.TabIndex = 6 TAB_DOWN.Text = "Downloading" ' @@ -1358,10 +1372,11 @@ Namespace Editors TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 8) TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1) TP_DOWNLOADING.Controls.Add(Me.CH_UICON_UP, 0, 2) + TP_DOWNLOADING.Controls.Add(Me.CH_USE_DEF_ACC, 0, 9) TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0) TP_DOWNLOADING.Name = "TP_DOWNLOADING" - TP_DOWNLOADING.RowCount = 10 + TP_DOWNLOADING.RowCount = 11 TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) @@ -1371,18 +1386,19 @@ Namespace Editors TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) + TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DOWNLOADING.Size = New System.Drawing.Size(576, 374) + TP_DOWNLOADING.Size = New System.Drawing.Size(576, 399) TP_DOWNLOADING.TabIndex = 1 ' 'TXT_SCRIPT ' - ActionButton65.BackgroundImage = CType(resources.GetObject("ActionButton65.BackgroundImage"), System.Drawing.Image) - ActionButton65.Name = "Open" - ActionButton66.BackgroundImage = CType(resources.GetObject("ActionButton66.BackgroundImage"), System.Drawing.Image) - ActionButton66.Name = "Clear" - Me.TXT_SCRIPT.Buttons.Add(ActionButton65) - Me.TXT_SCRIPT.Buttons.Add(ActionButton66) + ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image) + ActionButton11.Name = "Open" + ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image) + ActionButton12.Name = "Clear" + Me.TXT_SCRIPT.Buttons.Add(ActionButton11) + Me.TXT_SCRIPT.Buttons.Add(ActionButton12) Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox Me.TXT_SCRIPT.CaptionText = "Script" Me.TXT_SCRIPT.CaptionToolTipEnabled = True @@ -1458,7 +1474,7 @@ Namespace Editors TAB_FEED.Controls.Add(TP_FEED) TAB_FEED.Location = New System.Drawing.Point(4, 22) TAB_FEED.Name = "TAB_FEED" - TAB_FEED.Size = New System.Drawing.Size(576, 374) + TAB_FEED.Size = New System.Drawing.Size(576, 399) TAB_FEED.TabIndex = 7 TAB_FEED.Text = "Feed" ' @@ -1490,7 +1506,7 @@ Namespace Editors TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_FEED.Size = New System.Drawing.Size(576, 374) + TP_FEED.Size = New System.Drawing.Size(576, 399) TP_FEED.TabIndex = 0 ' 'TP_FEED_IMG_COUNT @@ -1644,7 +1660,7 @@ Namespace Editors TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN) TAB_NOTIFY.Location = New System.Drawing.Point(4, 22) TAB_NOTIFY.Name = "TAB_NOTIFY" - TAB_NOTIFY.Size = New System.Drawing.Size(576, 374) + TAB_NOTIFY.Size = New System.Drawing.Size(576, 399) TAB_NOTIFY.TabIndex = 8 TAB_NOTIFY.Text = "Notifications" ' @@ -1674,7 +1690,7 @@ Namespace Editors TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 374) + TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 399) TP_NOTIFY_MAIN.TabIndex = 0 ' 'TP_ENVIR @@ -1697,19 +1713,19 @@ Namespace Editors TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_ENVIR.Size = New System.Drawing.Size(576, 374) + TP_ENVIR.Size = New System.Drawing.Size(576, 399) TP_ENVIR.TabIndex = 0 ' 'TXT_YTDLP ' - ActionButton67.BackgroundImage = CType(resources.GetObject("ActionButton67.BackgroundImage"), System.Drawing.Image) - ActionButton67.Name = "Open" - ActionButton67.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open - ActionButton68.BackgroundImage = CType(resources.GetObject("ActionButton68.BackgroundImage"), System.Drawing.Image) - ActionButton68.Name = "Clear" - ActionButton68.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_YTDLP.Buttons.Add(ActionButton67) - Me.TXT_YTDLP.Buttons.Add(ActionButton68) + ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image) + ActionButton13.Name = "Open" + ActionButton13.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image) + ActionButton14.Name = "Clear" + ActionButton14.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_YTDLP.Buttons.Add(ActionButton13) + Me.TXT_YTDLP.Buttons.Add(ActionButton14) Me.TXT_YTDLP.CaptionText = "yt-dlp" Me.TXT_YTDLP.CaptionToolTipEnabled = True Me.TXT_YTDLP.CaptionToolTipText = "Path to yt-dlp.exe file" @@ -1723,14 +1739,14 @@ Namespace Editors ' 'TXT_FFMPEG ' - ActionButton69.BackgroundImage = CType(resources.GetObject("ActionButton69.BackgroundImage"), System.Drawing.Image) - ActionButton69.Name = "Open" - ActionButton69.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open - ActionButton70.BackgroundImage = CType(resources.GetObject("ActionButton70.BackgroundImage"), System.Drawing.Image) - ActionButton70.Name = "Clear" - ActionButton70.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_FFMPEG.Buttons.Add(ActionButton69) - Me.TXT_FFMPEG.Buttons.Add(ActionButton70) + ActionButton15.BackgroundImage = CType(resources.GetObject("ActionButton15.BackgroundImage"), System.Drawing.Image) + ActionButton15.Name = "Open" + ActionButton15.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton16.BackgroundImage = CType(resources.GetObject("ActionButton16.BackgroundImage"), System.Drawing.Image) + ActionButton16.Name = "Clear" + ActionButton16.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_FFMPEG.Buttons.Add(ActionButton15) + Me.TXT_FFMPEG.Buttons.Add(ActionButton16) Me.TXT_FFMPEG.CaptionText = "ffmpeg" Me.TXT_FFMPEG.CaptionToolTipEnabled = True Me.TXT_FFMPEG.CaptionToolTipText = "Path to ffmpeg.exe file" @@ -1744,14 +1760,14 @@ Namespace Editors ' 'TXT_CURL ' - ActionButton71.BackgroundImage = CType(resources.GetObject("ActionButton71.BackgroundImage"), System.Drawing.Image) - ActionButton71.Name = "Open" - ActionButton71.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open - ActionButton72.BackgroundImage = CType(resources.GetObject("ActionButton72.BackgroundImage"), System.Drawing.Image) - ActionButton72.Name = "Clear" - ActionButton72.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_CURL.Buttons.Add(ActionButton71) - Me.TXT_CURL.Buttons.Add(ActionButton72) + ActionButton17.BackgroundImage = CType(resources.GetObject("ActionButton17.BackgroundImage"), System.Drawing.Image) + ActionButton17.Name = "Open" + ActionButton17.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton18.BackgroundImage = CType(resources.GetObject("ActionButton18.BackgroundImage"), System.Drawing.Image) + ActionButton18.Name = "Clear" + ActionButton18.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_CURL.Buttons.Add(ActionButton17) + Me.TXT_CURL.Buttons.Add(ActionButton18) Me.TXT_CURL.CaptionText = "cURL" Me.TXT_CURL.CaptionToolTipEnabled = True Me.TXT_CURL.CaptionToolTipText = "Path to curl.exe file" @@ -1765,14 +1781,14 @@ Namespace Editors ' 'TXT_GALLERYDL ' - ActionButton73.BackgroundImage = CType(resources.GetObject("ActionButton73.BackgroundImage"), System.Drawing.Image) - ActionButton73.Name = "Open" - ActionButton73.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open - ActionButton74.BackgroundImage = CType(resources.GetObject("ActionButton74.BackgroundImage"), System.Drawing.Image) - ActionButton74.Name = "Clear" - ActionButton74.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_GALLERYDL.Buttons.Add(ActionButton73) - Me.TXT_GALLERYDL.Buttons.Add(ActionButton74) + ActionButton19.BackgroundImage = CType(resources.GetObject("ActionButton19.BackgroundImage"), System.Drawing.Image) + ActionButton19.Name = "Open" + ActionButton19.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton20.BackgroundImage = CType(resources.GetObject("ActionButton20.BackgroundImage"), System.Drawing.Image) + ActionButton20.Name = "Clear" + ActionButton20.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_GALLERYDL.Buttons.Add(ActionButton19) + Me.TXT_GALLERYDL.Buttons.Add(ActionButton20) Me.TXT_GALLERYDL.CaptionText = "gallery-dl" Me.TXT_GALLERYDL.CaptionToolTipText = "Path to gallery-dl.exe file" Me.TXT_GALLERYDL.CaptionWidth = 80.0R @@ -1785,14 +1801,14 @@ Namespace Editors ' 'TXT_CMD_ENCODING ' - ActionButton75.BackgroundImage = CType(resources.GetObject("ActionButton75.BackgroundImage"), System.Drawing.Image) - ActionButton75.Name = "Refresh" - ActionButton75.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh - ActionButton76.BackgroundImage = CType(resources.GetObject("ActionButton76.BackgroundImage"), System.Drawing.Image) - ActionButton76.Name = "Clear" - ActionButton76.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton75) - Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton76) + ActionButton21.BackgroundImage = CType(resources.GetObject("ActionButton21.BackgroundImage"), System.Drawing.Image) + ActionButton21.Name = "Refresh" + ActionButton21.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh + ActionButton22.BackgroundImage = CType(resources.GetObject("ActionButton22.BackgroundImage"), System.Drawing.Image) + ActionButton22.Name = "Clear" + ActionButton22.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton21) + Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton22) Me.TXT_CMD_ENCODING.CaptionText = "CMD Encoding" Me.TXT_CMD_ENCODING.CaptionToolTipEnabled = True Me.TXT_CMD_ENCODING.CaptionToolTipText = "Command line encoding" @@ -1808,7 +1824,7 @@ Namespace Editors TAB_STD.Controls.Add(TP_STD) TAB_STD.Location = New System.Drawing.Point(4, 22) TAB_STD.Name = "TAB_STD" - TAB_STD.Size = New System.Drawing.Size(576, 374) + TAB_STD.Size = New System.Drawing.Size(576, 399) TAB_STD.TabIndex = 10 TAB_STD.Text = "Downloader" ' @@ -1850,7 +1866,7 @@ Namespace Editors TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_STD.Size = New System.Drawing.Size(576, 374) + TP_STD.Size = New System.Drawing.Size(576, 399) TP_STD.TabIndex = 0 ' 'TXT_STD_MAX_JOBS_COUNT @@ -1895,24 +1911,24 @@ Namespace Editors ' 'CMB_STD_OPEN_DBL ' - ActionButton77.BackgroundImage = CType(resources.GetObject("ActionButton77.BackgroundImage"), System.Drawing.Image) - ActionButton77.Name = "ArrowDown" - ActionButton77.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown - Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton77) + ActionButton23.BackgroundImage = CType(resources.GetObject("ActionButton23.BackgroundImage"), System.Drawing.Image) + ActionButton23.Name = "ArrowDown" + ActionButton23.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton23) Me.CMB_STD_OPEN_DBL.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label Me.CMB_STD_OPEN_DBL.CaptionText = "DoubleClick opens" Me.CMB_STD_OPEN_DBL.CaptionToolTipEnabled = True Me.CMB_STD_OPEN_DBL.CaptionToolTipText = "What do you want to open when you double click on an item" Me.CMB_STD_OPEN_DBL.CaptionVisible = True - ListColumn5.DisplayMember = True - ListColumn5.Name = "STD_CMB_COL_TEXT" - ListColumn5.Text = "Text" - ListColumn6.Name = "STD_CMB_COL_VALUE" - ListColumn6.Text = "Value" - ListColumn6.ValueMember = True - ListColumn6.Visible = False - Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn5) - Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn6) + ListColumn1.DisplayMember = True + ListColumn1.Name = "STD_CMB_COL_TEXT" + ListColumn1.Text = "Text" + ListColumn2.Name = "STD_CMB_COL_VALUE" + ListColumn2.Text = "Value" + ListColumn2.ValueMember = True + ListColumn2.Visible = False + Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn1) + Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn2) Me.CMB_STD_OPEN_DBL.Dock = System.Windows.Forms.DockStyle.Fill Me.CMB_STD_OPEN_DBL.Location = New System.Drawing.Point(4, 85) Me.CMB_STD_OPEN_DBL.Name = "CMB_STD_OPEN_DBL" @@ -1949,7 +1965,7 @@ Namespace Editors TAB_DESIGN.Controls.Add(TP_DESIGN) TAB_DESIGN.Location = New System.Drawing.Point(4, 22) TAB_DESIGN.Name = "TAB_DESIGN" - TAB_DESIGN.Size = New System.Drawing.Size(576, 374) + TAB_DESIGN.Size = New System.Drawing.Size(576, 399) TAB_DESIGN.TabIndex = 11 TAB_DESIGN.Text = "Design" ' @@ -1975,15 +1991,15 @@ Namespace Editors TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - TP_DESIGN.Size = New System.Drawing.Size(576, 374) + TP_DESIGN.Size = New System.Drawing.Size(576, 399) TP_DESIGN.TabIndex = 0 ' 'TXT_PRG_TITLE ' - ActionButton78.BackgroundImage = CType(resources.GetObject("ActionButton78.BackgroundImage"), System.Drawing.Image) - ActionButton78.Name = "Clear" - ActionButton78.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_PRG_TITLE.Buttons.Add(ActionButton78) + ActionButton24.BackgroundImage = CType(resources.GetObject("ActionButton24.BackgroundImage"), System.Drawing.Image) + ActionButton24.Name = "Clear" + ActionButton24.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_PRG_TITLE.Buttons.Add(ActionButton24) Me.TXT_PRG_TITLE.CaptionText = "Program title" Me.TXT_PRG_TITLE.CaptionToolTipEnabled = True Me.TXT_PRG_TITLE.CaptionToolTipText = "Change the title of the main window if you need to" @@ -1995,10 +2011,10 @@ Namespace Editors ' 'TXT_PRG_DESCR ' - ActionButton79.BackgroundImage = CType(resources.GetObject("ActionButton79.BackgroundImage"), System.Drawing.Image) - ActionButton79.Name = "Clear" - ActionButton79.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_PRG_DESCR.Buttons.Add(ActionButton79) + ActionButton25.BackgroundImage = CType(resources.GetObject("ActionButton25.BackgroundImage"), System.Drawing.Image) + ActionButton25.Name = "Clear" + ActionButton25.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_PRG_DESCR.Buttons.Add(ActionButton25) Me.TXT_PRG_DESCR.CaptionText = "Program description" Me.TXT_PRG_DESCR.CaptionToolTipEnabled = True Me.TXT_PRG_DESCR.CaptionToolTipText = "Add some additional info to the program info if you need" @@ -2010,14 +2026,14 @@ Namespace Editors ' 'TXT_USER_LIST_IMAGE ' - ActionButton80.BackgroundImage = CType(resources.GetObject("ActionButton80.BackgroundImage"), System.Drawing.Image) - ActionButton80.Name = "Open" - ActionButton80.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open - ActionButton81.BackgroundImage = CType(resources.GetObject("ActionButton81.BackgroundImage"), System.Drawing.Image) - ActionButton81.Name = "Clear" - ActionButton81.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear - Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton80) - Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton81) + ActionButton26.BackgroundImage = CType(resources.GetObject("ActionButton26.BackgroundImage"), System.Drawing.Image) + ActionButton26.Name = "Open" + ActionButton26.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open + ActionButton27.BackgroundImage = CType(resources.GetObject("ActionButton27.BackgroundImage"), System.Drawing.Image) + ActionButton27.Name = "Clear" + ActionButton27.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton26) + Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton27) Me.TXT_USER_LIST_IMAGE.CaptionText = "Userlist image" Me.TXT_USER_LIST_IMAGE.CaptionToolTipEnabled = True Me.TXT_USER_LIST_IMAGE.CaptionToolTipText = "Background image for user list" @@ -2081,7 +2097,7 @@ Namespace Editors Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0) Me.TAB_MAIN.Name = "TAB_MAIN" Me.TAB_MAIN.SelectedIndex = 0 - Me.TAB_MAIN.Size = New System.Drawing.Size(584, 400) + Me.TAB_MAIN.Size = New System.Drawing.Size(584, 425) Me.TAB_MAIN.TabIndex = 1 ' 'TAB_ENVIR @@ -2089,7 +2105,7 @@ Namespace Editors Me.TAB_ENVIR.Controls.Add(TP_ENVIR) Me.TAB_ENVIR.Location = New System.Drawing.Point(4, 22) Me.TAB_ENVIR.Name = "TAB_ENVIR" - Me.TAB_ENVIR.Size = New System.Drawing.Size(576, 374) + Me.TAB_ENVIR.Size = New System.Drawing.Size(576, 399) Me.TAB_ENVIR.TabIndex = 9 Me.TAB_ENVIR.Text = "Environment" ' @@ -2099,7 +2115,7 @@ Namespace Editors 'CONTAINER_MAIN.ContentPanel ' Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN) - Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 400) + Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 425) Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) @@ -2109,18 +2125,17 @@ Namespace Editors Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TopToolStripPanelVisible = False ' - 'CH_STD_YT_CREATE_URL + 'CH_USE_DEF_ACC ' - Me.CH_STD_YT_CREATE_URL.AutoSize = True - Me.CH_STD_YT_CREATE_URL.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_STD_YT_CREATE_URL.Location = New System.Drawing.Point(4, 322) - Me.CH_STD_YT_CREATE_URL.Name = "CH_STD_YT_CREATE_URL" - Me.CH_STD_YT_CREATE_URL.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) - Me.CH_STD_YT_CREATE_URL.Size = New System.Drawing.Size(568, 19) - Me.CH_STD_YT_CREATE_URL.TabIndex = 12 - Me.CH_STD_YT_CREATE_URL.Text = "Create URL files" - TT_MAIN.SetToolTip(Me.CH_STD_YT_CREATE_URL, "Create local URL files to link to the original page") - Me.CH_STD_YT_CREATE_URL.UseVisualStyleBackColor = True + Me.CH_USE_DEF_ACC.AutoSize = True + Me.CH_USE_DEF_ACC.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_USE_DEF_ACC.Location = New System.Drawing.Point(4, 254) + Me.CH_USE_DEF_ACC.Name = "CH_USE_DEF_ACC" + Me.CH_USE_DEF_ACC.Size = New System.Drawing.Size(568, 19) + Me.CH_USE_DEF_ACC.TabIndex = 9 + Me.CH_USE_DEF_ACC.Text = "Use the default account if the selected account does not exist" + TT_MAIN.SetToolTip(Me.CH_USE_DEF_ACC, "Use the default account if you deleted an account that you used for some users") + Me.CH_USE_DEF_ACC.UseVisualStyleBackColor = True ' 'GlobalSettingsForm ' @@ -2310,5 +2325,6 @@ Namespace Editors Private WithEvents CH_FEED_SHOW_FRIENDLY As CheckBox Private WithEvents COLORS_SUBSCRIPTIONS_USERS As ColorPicker Private WithEvents CH_STD_YT_CREATE_URL As CheckBox + Private WithEvents CH_USE_DEF_ACC As CheckBox End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/GlobalSettingsForm.resx b/SCrawler/Editors/GlobalSettingsForm.resx index ce7a527..d2a52f5 100644 --- a/SCrawler/Editors/GlobalSettingsForm.resx +++ b/SCrawler/Editors/GlobalSettingsForm.resx @@ -121,7 +121,7 @@ False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -132,7 +132,7 @@ cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -143,7 +143,7 @@ False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -151,7 +151,7 @@ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -167,7 +167,7 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -183,7 +183,7 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -197,7 +197,7 @@ 17, 17 - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -213,7 +213,7 @@ VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -230,15 +230,6 @@ False - - False - - - False - - - 17, 17 - This is a global setting for newly added users only. This parameter specifies how the video will be stored in the users' download path. @@ -278,7 +269,7 @@ You can find more detailed information about the missing posts in the form that False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -286,7 +277,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -306,7 +297,7 @@ You can find more detailed information about the missing posts in the form that False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -317,7 +308,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -346,7 +337,7 @@ You can find more detailed information about the missing posts in the form that False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -357,7 +348,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -365,7 +356,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -376,7 +367,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -384,7 +375,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -395,7 +386,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -403,7 +394,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -414,7 +405,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -422,7 +413,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE @@ -438,7 +429,7 @@ You can find more detailed information about the missing posts in the form that VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -452,7 +443,7 @@ You can find more detailed information about the missing posts in the form that False - + iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t 3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL @@ -548,7 +539,7 @@ You can find more detailed information about the missing posts in the form that False - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -556,7 +547,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -564,7 +555,7 @@ You can find more detailed information about the missing posts in the form that AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP @@ -575,7 +566,7 @@ You can find more detailed information about the missing posts in the form that cMaRN0UdBBkAAAAASUVORK5CYII= - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go diff --git a/SCrawler/Editors/GlobalSettingsForm.vb b/SCrawler/Editors/GlobalSettingsForm.vb index e1eb304..daa0a4d 100644 --- a/SCrawler/Editors/GlobalSettingsForm.vb +++ b/SCrawler/Editors/GlobalSettingsForm.vb @@ -109,6 +109,7 @@ Namespace Editors CH_ADD_MISSING_TO_LOG.Checked = .AddMissingToLog CH_ADD_MISSING_ERROS_TO_LOG.Checked = .AddMissingErrorsToLog CH_DOWN_REPARSE_MISSING.Checked = .ReparseMissingInTheRoutine + CH_USE_DEF_ACC.Checked = .UseDefaultAccountIfMissing 'Downloading: file names CH_FILE_NAME_CHANGE.Checked = Not .FileReplaceNameByDate.Value = FileNameReplaceMode.None OPT_FILE_NAME_REPLACE.Checked = .FileReplaceNameByDate.Value = FileNameReplaceMode.Replace @@ -278,6 +279,7 @@ Namespace Editors .AddMissingToLog.Value = CH_ADD_MISSING_TO_LOG.Checked .AddMissingErrorsToLog.Value = CH_ADD_MISSING_ERROS_TO_LOG.Checked .ReparseMissingInTheRoutine.Value = CH_DOWN_REPARSE_MISSING.Checked + .UseDefaultAccountIfMissing.Value = CH_USE_DEF_ACC.Checked 'Downloading: file names If CH_FILE_NAME_CHANGE.Checked Then .FileReplaceNameByDate.Value = If(OPT_FILE_NAME_REPLACE.Checked, FileNameReplaceMode.Replace, FileNameReplaceMode.Add) diff --git a/SCrawler/Editors/SiteEditorForm.Designer.vb b/SCrawler/Editors/SiteEditorForm.Designer.vb index e9fed7d..4cf052d 100644 --- a/SCrawler/Editors/SiteEditorForm.Designer.vb +++ b/SCrawler/Editors/SiteEditorForm.Designer.vb @@ -31,6 +31,8 @@ Namespace Editors Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel() Me.TXT_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_COOKIES = New PersonalUtilities.Forms.Controls.TextBoxExtended() @@ -38,7 +40,9 @@ Namespace Editors Me.TXT_PATH_SAVED_POSTS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.CH_GET_USER_MEDIA_ONLY = New System.Windows.Forms.CheckBox() Me.CH_DOWNLOAD_SITE_DATA = New System.Windows.Forms.CheckBox() + Me.TXT_ACCOUNT_NAME = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TT_MAIN = New System.Windows.Forms.ToolTip(Me.components) + Me.CH_USE_SAVED_POSTS = New System.Windows.Forms.CheckBox() CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() CONTAINER_MAIN.ContentPanel.SuspendLayout() CONTAINER_MAIN.SuspendLayout() @@ -46,6 +50,7 @@ Namespace Editors CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_COOKIES, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_PATH_SAVED_POSTS, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.TXT_ACCOUNT_NAME, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'CONTAINER_MAIN @@ -54,13 +59,13 @@ Namespace Editors 'CONTAINER_MAIN.ContentPanel ' CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(544, 243) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(544, 271) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) CONTAINER_MAIN.Name = "CONTAINER_MAIN" CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(544, 243) + CONTAINER_MAIN.Size = New System.Drawing.Size(544, 296) CONTAINER_MAIN.TabIndex = 0 CONTAINER_MAIN.TopToolStripPanelVisible = False ' @@ -70,21 +75,25 @@ Namespace Editors Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_MAIN.Controls.Add(Me.TXT_PATH, 0, 0) Me.TP_MAIN.Controls.Add(Me.TXT_COOKIES, 0, 2) - Me.TP_MAIN.Controls.Add(Me.TP_SITE_PROPS, 0, 5) + Me.TP_MAIN.Controls.Add(Me.TP_SITE_PROPS, 0, 7) Me.TP_MAIN.Controls.Add(Me.TXT_PATH_SAVED_POSTS, 0, 1) - Me.TP_MAIN.Controls.Add(Me.CH_GET_USER_MEDIA_ONLY, 0, 4) - Me.TP_MAIN.Controls.Add(Me.CH_DOWNLOAD_SITE_DATA, 0, 3) + Me.TP_MAIN.Controls.Add(Me.CH_GET_USER_MEDIA_ONLY, 0, 6) + Me.TP_MAIN.Controls.Add(Me.CH_DOWNLOAD_SITE_DATA, 0, 4) + Me.TP_MAIN.Controls.Add(Me.TXT_ACCOUNT_NAME, 0, 3) + Me.TP_MAIN.Controls.Add(Me.CH_USE_SAVED_POSTS, 0, 5) Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.TP_MAIN.Location = New System.Drawing.Point(0, 0) Me.TP_MAIN.Name = "TP_MAIN" - Me.TP_MAIN.RowCount = 6 + Me.TP_MAIN.RowCount = 8 Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - Me.TP_MAIN.Size = New System.Drawing.Size(544, 243) + Me.TP_MAIN.Size = New System.Drawing.Size(544, 271) Me.TP_MAIN.TabIndex = 0 ' 'TXT_PATH @@ -128,24 +137,28 @@ Namespace Editors Me.TP_SITE_PROPS.ColumnCount = 1 Me.TP_SITE_PROPS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_SITE_PROPS.Dock = System.Windows.Forms.DockStyle.Fill - Me.TP_SITE_PROPS.Location = New System.Drawing.Point(3, 137) + Me.TP_SITE_PROPS.Location = New System.Drawing.Point(3, 190) Me.TP_SITE_PROPS.Name = "TP_SITE_PROPS" Me.TP_SITE_PROPS.RowCount = 4 Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - Me.TP_SITE_PROPS.Size = New System.Drawing.Size(538, 103) - Me.TP_SITE_PROPS.TabIndex = 5 + Me.TP_SITE_PROPS.Size = New System.Drawing.Size(538, 78) + Me.TP_SITE_PROPS.TabIndex = 7 ' 'TXT_PATH_SAVED_POSTS ' ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image) ActionButton5.Name = "Open" ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image) - ActionButton6.Name = "Clear" + ActionButton6.Name = "Refresh" + ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh + ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image) + ActionButton7.Name = "Clear" Me.TXT_PATH_SAVED_POSTS.Buttons.Add(ActionButton5) Me.TXT_PATH_SAVED_POSTS.Buttons.Add(ActionButton6) + Me.TXT_PATH_SAVED_POSTS.Buttons.Add(ActionButton7) Me.TXT_PATH_SAVED_POSTS.CaptionText = "Saved posts path" Me.TXT_PATH_SAVED_POSTS.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_PATH_SAVED_POSTS.Location = New System.Drawing.Point(3, 31) @@ -157,11 +170,11 @@ Namespace Editors ' Me.CH_GET_USER_MEDIA_ONLY.AutoSize = True Me.CH_GET_USER_MEDIA_ONLY.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_GET_USER_MEDIA_ONLY.Location = New System.Drawing.Point(3, 112) + Me.CH_GET_USER_MEDIA_ONLY.Location = New System.Drawing.Point(3, 165) Me.CH_GET_USER_MEDIA_ONLY.Name = "CH_GET_USER_MEDIA_ONLY" Me.CH_GET_USER_MEDIA_ONLY.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) Me.CH_GET_USER_MEDIA_ONLY.Size = New System.Drawing.Size(538, 19) - Me.CH_GET_USER_MEDIA_ONLY.TabIndex = 4 + Me.CH_GET_USER_MEDIA_ONLY.TabIndex = 6 Me.CH_GET_USER_MEDIA_ONLY.Text = "Get user media only" Me.CH_GET_USER_MEDIA_ONLY.UseVisualStyleBackColor = True ' @@ -169,28 +182,54 @@ Namespace Editors ' Me.CH_DOWNLOAD_SITE_DATA.AutoSize = True Me.CH_DOWNLOAD_SITE_DATA.Dock = System.Windows.Forms.DockStyle.Fill - Me.CH_DOWNLOAD_SITE_DATA.Location = New System.Drawing.Point(3, 87) + Me.CH_DOWNLOAD_SITE_DATA.Location = New System.Drawing.Point(3, 115) Me.CH_DOWNLOAD_SITE_DATA.Name = "CH_DOWNLOAD_SITE_DATA" Me.CH_DOWNLOAD_SITE_DATA.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) Me.CH_DOWNLOAD_SITE_DATA.Size = New System.Drawing.Size(538, 19) - Me.CH_DOWNLOAD_SITE_DATA.TabIndex = 3 + Me.CH_DOWNLOAD_SITE_DATA.TabIndex = 4 Me.CH_DOWNLOAD_SITE_DATA.Text = "Download site data" Me.TT_MAIN.SetToolTip(Me.CH_DOWNLOAD_SITE_DATA, "If disabled, this site's data will not be downloaded." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "You can disable downloadin" & "g data from the site if you need it.") Me.CH_DOWNLOAD_SITE_DATA.UseVisualStyleBackColor = True ' + 'TXT_ACCOUNT_NAME + ' + ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image) + ActionButton8.Name = "Clear" + ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear + Me.TXT_ACCOUNT_NAME.Buttons.Add(ActionButton8) + Me.TXT_ACCOUNT_NAME.CaptionText = "Account name" + Me.TXT_ACCOUNT_NAME.Dock = System.Windows.Forms.DockStyle.Fill + Me.TXT_ACCOUNT_NAME.Location = New System.Drawing.Point(3, 87) + Me.TXT_ACCOUNT_NAME.Name = "TXT_ACCOUNT_NAME" + Me.TXT_ACCOUNT_NAME.Size = New System.Drawing.Size(538, 22) + Me.TXT_ACCOUNT_NAME.TabIndex = 3 + ' + 'CH_USE_SAVED_POSTS + ' + Me.CH_USE_SAVED_POSTS.AutoSize = True + Me.CH_USE_SAVED_POSTS.Dock = System.Windows.Forms.DockStyle.Fill + Me.CH_USE_SAVED_POSTS.Location = New System.Drawing.Point(3, 140) + Me.CH_USE_SAVED_POSTS.Name = "CH_USE_SAVED_POSTS" + Me.CH_USE_SAVED_POSTS.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0) + Me.CH_USE_SAVED_POSTS.Size = New System.Drawing.Size(538, 19) + Me.CH_USE_SAVED_POSTS.TabIndex = 5 + Me.CH_USE_SAVED_POSTS.Text = "Download saved posts" + Me.TT_MAIN.SetToolTip(Me.CH_USE_SAVED_POSTS, "Use this account to download saved posts.") + Me.CH_USE_SAVED_POSTS.UseVisualStyleBackColor = True + ' 'SiteEditorForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(544, 243) + Me.ClientSize = New System.Drawing.Size(544, 296) Me.Controls.Add(CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.KeyPreview = True Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(560, 282) + Me.MaximumSize = New System.Drawing.Size(560, 335) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(560, 282) + Me.MinimumSize = New System.Drawing.Size(560, 335) Me.Name = "SiteEditorForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -203,6 +242,7 @@ Namespace Editors CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_COOKIES, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_PATH_SAVED_POSTS, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.TXT_ACCOUNT_NAME, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub @@ -214,5 +254,7 @@ Namespace Editors Private WithEvents CH_GET_USER_MEDIA_ONLY As CheckBox Private WithEvents TT_MAIN As ToolTip Private WithEvents CH_DOWNLOAD_SITE_DATA As CheckBox + Private WithEvents TXT_ACCOUNT_NAME As PersonalUtilities.Forms.Controls.TextBoxExtended + Private WithEvents CH_USE_SAVED_POSTS As CheckBox End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/SiteEditorForm.resx b/SCrawler/Editors/SiteEditorForm.resx index e2d09b7..dd68433 100644 --- a/SCrawler/Editors/SiteEditorForm.resx +++ b/SCrawler/Editors/SiteEditorForm.resx @@ -218,6 +218,22 @@ + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE + QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb + ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb + +eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv + qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN + v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA + prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ + qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY + HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74 + qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG + VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg== + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go @@ -228,4 +244,12 @@ 17, 17 + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go + tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX + AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC + + \ No newline at end of file diff --git a/SCrawler/Editors/SiteEditorForm.vb b/SCrawler/Editors/SiteEditorForm.vb index b06d49d..5bbbaba 100644 --- a/SCrawler/Editors/SiteEditorForm.vb +++ b/SCrawler/Editors/SiteEditorForm.vb @@ -22,20 +22,124 @@ Namespace Editors Private Property Cookies As CookieKeeper Private CookiesChanged As Boolean = False #Region "Providers" - Private Class SavedPostsChecker : Inherits FieldsCheckerProviderBase + Private Class SavedPostsChecker : Inherits AccountsNameChecker + Friend ReadOnly PathControl As TextBoxExtended + Friend ReadOnly HostPaths As List(Of String) + Friend Shared Function GetNewSavedPostsName(ByVal PathText As String, ByVal HostIndex As Integer, ByVal MaxCount As Integer) As String + Return If(Not PathText.IsEmptyString, $"{PathText.CSFilePS}{SettingsHost.SavedPostsFolderName}{If(HostIndex = 0, String.Empty, $"_{IIf(HostIndex = -1, MaxCount + 1, HostIndex)}")}\", String.Empty) + End Function + Friend Sub New(ByVal h As SettingsHostCollection, ByVal i As Integer) + MyBase.New(h, i) + HostPaths = New List(Of String)(h.Select(Function(hh) hh.Path.PathNoSeparator)) + End Sub + Friend Sub New(ByVal h As SettingsHostCollection, ByVal i As Integer, ByRef _PathControl As TextBoxExtended) + Me.New(h, i) + PathControl = _PathControl + End Sub Public Overrides Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider, Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object - If ACheck(Value) AndAlso CStr(Value).Contains("/") Then + Dim v$ = AConvert(Of String)(Value, String.Empty) + If Not v.IsEmptyString AndAlso v.Contains("/") Then ErrorMessage = $"Path [{Name}] contains forbidden character ""/""" HasError = True - Return Nothing + ElseIf HostCollection.Count = 1 And HostIndex = 0 Then + Return Value + ElseIf v.IsEmptyString Then + If Not PathControl.IsEmptyString AndAlso Not HostPaths.Contains(PathControl.Text.CSFilePSN) Then + Return GetNewSavedPostsName(PathControl.Text, HostIndex, HostCollection.Count) + Else + HasError = True + ErrorMessage = "The path to saved posts is not unique!" + End If Else Return Value End If + Return Nothing + End Function + End Class + Private Class SavedPostsControlParams : Inherits FieldsChecker.ControlParams + Private ReadOnly Property ProviderE As SavedPostsChecker + Get + Return Provider + End Get + End Property + Public Overrides Property CanBeNull As Boolean + Get + With ProviderE + If .HostCollection.Count = 1 And .HostIndex = 0 Then + Return True + ElseIf Not .PathControl.IsEmptyString Then + Dim v$ = .PathControl.Text.CSFilePSN + Return Not .HostPaths.Contains(v) + Else + Return False + End If + End With + End Get + Set : End Set + End Property + Friend Sub New(ByVal Name As String, ByRef RelatedControl As TextBoxExtended, ByRef _PathControl As TextBoxExtended, + ByVal h As SettingsHostCollection, ByVal i As Integer) + MyBase.New(Name, GetType(String), RelatedControl, True, New SavedPostsChecker(h, i, _PathControl)) + End Sub + Public Overrides Function Validate() As Boolean + If MyBase.Validate() Then + Return True + Else + DirectCast(WorkingControl, TextBoxExtended).Text = ProviderE.Convert(Validate_GetValue, GetType(String), Nothing, String.Empty, EDP.ReturnValue) + Return MyBase.Validate() + End If + End Function + End Class + Private Class AccountsNameChecker : Inherits FieldsCheckerProviderBase + Friend ReadOnly HostCollection As SettingsHostCollection + Friend ReadOnly HostIndex As Integer + Public Overrides Property ErrorMessage As String + Get + Return MyBase.ErrorMessage + End Get + Set(ByVal m As String) + MyBase.ErrorMessage = m + HasError = True + End Set + End Property + Public Overrides Sub Reset() + MyBase.Reset() + MyBase.ErrorMessage = String.Empty + End Sub + Friend Sub New(ByVal h As SettingsHostCollection, ByVal i As Integer) + HostCollection = h + HostIndex = i + End Sub + Public Overrides Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider, + Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object + If HostCollection.Count = 1 And HostIndex = 0 Then + Return Value + Else + Dim v$ = AConvert(Of String)(Value, String.Empty) + If v.IsEmptyString Then + If HostIndex = 0 Then + Return v + Else + ErrorMessage = "Settings name cannot be null" + End If + ElseIf v = SettingsHost.NameAccountNameDefault Then + If HostIndex = 0 Then + Return v + Else + ErrorMessage = "The default name can only be set for the first settings!" + End If + Else + Dim i% = HostCollection.IndexOf(v) + If i >= 0 And i <> HostIndex Then ErrorMessage = $"There are already settings named '{v}'" Else Return v + End If + End If + Return Nothing End Function End Class #End Region Private ReadOnly Property Host As SettingsHost + Private Property HostCollection As SettingsHostCollection Friend Sub New(ByVal h As SettingsHost) InitializeComponent() MyDefs = New DefaultFormOptions(Me, Settings.Design) @@ -53,23 +157,33 @@ Namespace Editors .MyFieldsChecker = New FieldsChecker With Host + HostCollection = Settings(Host.Key) With .Source Text = .Site If Not .Icon Is Nothing Then Icon = .Icon Else ShowIcon = False End With + If Not .AccountName.IsEmptyString Then Text &= $" [{ .AccountName}]" + If hostCollection.Count = 1 Then TXT_PATH_SAVED_POSTS.Button(ADB.Refresh).Visible = False SetCookieText() - TXT_PATH.Text = .Path(False) TXT_PATH_SAVED_POSTS.Text = .SavedPostsPath(False) + _PathBefore = .Path(False) + TXT_PATH.Text = _PathBefore + TXT_ACCOUNT_NAME.Text = .AccountName + If Host.Index = 0 Then TXT_PATH_SAVED_POSTS.Button(ADB.Refresh).Visible = False : TXT_PATH_SAVED_POSTS.Buttons.UpdateButtonsPositions() + If Host.Index >= 0 Then TXT_ACCOUNT_NAME.Enabled = False : TXT_ACCOUNT_NAME.Buttons.Clear() : TXT_ACCOUNT_NAME.Buttons.UpdateButtonsPositions() CH_DOWNLOAD_SITE_DATA.Checked = .DownloadSiteData + CH_USE_SAVED_POSTS.Checked = .DownloadSavedPosts CH_GET_USER_MEDIA_ONLY.Checked = .GetUserMediaOnly SiteDefaultsFunctions.SetChecker(TP_SITE_PROPS, Host) With MyDefs.MyFieldsCheckerE - .AddControl(Of String)(TXT_PATH, TXT_PATH.CaptionText, True, New SavedPostsChecker) - .AddControl(Of String)(TXT_PATH_SAVED_POSTS, TXT_PATH_SAVED_POSTS.CaptionText, True, New SavedPostsChecker) + .AddControl(Of String)(TXT_PATH, TXT_PATH.CaptionText, True, New SavedPostsChecker(HostCollection, Host.Index)) + .AddControl(New SavedPostsControlParams(TXT_PATH_SAVED_POSTS.CaptionText, TXT_PATH_SAVED_POSTS, TXT_PATH, HostCollection, Host.Index)) + .AddControl(Of String)(TXT_ACCOUNT_NAME, TXT_ACCOUNT_NAME.CaptionText, + hostCollection.Count = 1 And Host.Index = 0, New AccountsNameChecker(hostCollection, Host.Index)) End With Dim offset% = PropertyValueHost.LeftOffsetDefault @@ -135,7 +249,9 @@ Namespace Editors TXT_PATH.CaptionWidth = offset TXT_PATH_SAVED_POSTS.CaptionWidth = offset TXT_COOKIES.CaptionWidth = offset + TXT_ACCOUNT_NAME.CaptionWidth = offset CH_DOWNLOAD_SITE_DATA.Padding = New PaddingE(CH_DOWNLOAD_SITE_DATA.Padding) With {.Left = offset} + CH_USE_SAVED_POSTS.Padding = New PaddingE(CH_USE_SAVED_POSTS.Padding) With {.Left = offset} CH_GET_USER_MEDIA_ONLY.Padding = New PaddingE(CH_GET_USER_MEDIA_ONLY.Padding) With {.Left = offset} If c > 0 Or h <> 0 Then Dim ss As New Size(Size.Width, Size.Height + h + c) @@ -200,7 +316,9 @@ Namespace Editors SiteDefaultsFunctions.SetPropByChecker(TP_SITE_PROPS, Host) If TXT_PATH.IsEmptyString Then .Path = Nothing Else .Path = TXT_PATH.Text .SavedPostsPath = TXT_PATH_SAVED_POSTS.Text + .AccountName = TXT_ACCOUNT_NAME.Text .DownloadSiteData.Value = CH_DOWNLOAD_SITE_DATA.Checked + .DownloadSavedPosts.Value = CH_USE_SAVED_POSTS.Checked .GetUserMediaOnly.Value = CH_GET_USER_MEDIA_ONLY.Checked If CookiesChanged And Not Cookies Is Nothing And Not .Responser Is Nothing Then With .Responser.Cookies @@ -219,11 +337,32 @@ Namespace Editors MyDefs.CloseForm() End If End Sub - Private Sub TXT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles TXT_PATH.ActionOnButtonClick - ChangePath(Sender, Host.Path(False), TXT_PATH) + Private _PathBefore As SFile = Nothing + Private Sub TXT_PATH_ActionOnBeforeTextChanged(sender As Object, e As EventArgs) Handles TXT_PATH.ActionOnBeforeTextChanged + If Not MyDefs.Initializing Then _PathBefore = TXT_PATH.Text.CSFileP End Sub - Private Sub TXT_PATH_SAVED_POSTS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles TXT_PATH_SAVED_POSTS.ActionOnButtonClick - ChangePath(Sender, Host.SavedPostsPath(False), TXT_PATH_SAVED_POSTS) + Private _PathButtonClicked As Boolean = False + Private Sub TXT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH.ActionOnButtonClick + _PathButtonClicked = True + ChangePath(Sender, Host.Path(False), TXT_PATH) + _PathButtonClicked = False + End Sub + Private Sub TXT_PATH_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_PATH.ActionOnTextChanged + If (_PathButtonClicked Or MyDefs.Initializing) And (HostCollection.Count > 1 Or Host.Index = -1) And TXT_PATH_SAVED_POSTS.IsEmptyString Then + If Not TXT_PATH.Text.IsEmptyString Then + Dim f As SFile = TXT_PATH_SAVED_POSTS.Text.CSFileP + If f.IsEmptyString OrElse (Not _PathBefore.IsEmptyString AndAlso _PathBefore.PathNoSeparator.Contains(f.PathNoSeparator)) Then _ + TXT_PATH_SAVED_POSTS.Text = SavedPostsChecker.GetNewSavedPostsName(TXT_PATH.Text, Host.Index, HostCollection.Count) + End If + End If + End Sub + Private Sub TXT_PATH_SAVED_POSTS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH_SAVED_POSTS.ActionOnButtonClick + If e.DefaultButton = ADB.Refresh Then + If Not TXT_PATH.IsEmptyString Then TXT_PATH_SAVED_POSTS.Text = + SavedPostsChecker.GetNewSavedPostsName(TXT_PATH.Text, Host.Index, HostCollection.Count) + Else + ChangePath(Sender, Host.SavedPostsPath(False), TXT_PATH_SAVED_POSTS) + End If End Sub Private Sub ChangePath(ByVal Sender As ActionButton, ByVal PathValue As SFile, ByRef CNT As TextBoxExtended) If Sender.DefaultButton = ADB.Open Then diff --git a/SCrawler/Editors/UserCreatorForm.Designer.vb b/SCrawler/Editors/UserCreatorForm.Designer.vb index 148b9b0..a264ea9 100644 --- a/SCrawler/Editors/UserCreatorForm.Designer.vb +++ b/SCrawler/Editors/UserCreatorForm.Designer.vb @@ -37,6 +37,7 @@ Namespace Editors Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() + Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton() Me.CH_PARSE_USER_MEDIA = New System.Windows.Forms.CheckBox() Me.CH_READY_FOR_DOWN = New System.Windows.Forms.CheckBox() Me.BTT_OTHER_SETTINGS = New System.Windows.Forms.Button() @@ -60,6 +61,7 @@ Namespace Editors Me.TXT_SPEC_FOLDER = New PersonalUtilities.Forms.Controls.ComboBoxExtended() Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.COLOR_USER = New SCrawler.Editors.ColorPicker() + Me.CMB_ACCOUNT = New PersonalUtilities.Forms.Controls.ComboBoxExtended() TT_MAIN = New System.Windows.Forms.ToolTip(Me.components) CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() CONTAINER_MAIN.ContentPanel.SuspendLayout() @@ -77,6 +79,7 @@ Namespace Editors Me.TP_DOWN_IMG_VID.SuspendLayout() CType(Me.TXT_SPEC_FOLDER, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'CH_PARSE_USER_MEDIA @@ -122,13 +125,13 @@ Namespace Editors 'CONTAINER_MAIN.ContentPanel ' CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN) - CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(454, 461) + CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(454, 489) CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill CONTAINER_MAIN.LeftToolStripPanelVisible = False CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) CONTAINER_MAIN.Name = "CONTAINER_MAIN" CONTAINER_MAIN.RightToolStripPanelVisible = False - CONTAINER_MAIN.Size = New System.Drawing.Size(454, 461) + CONTAINER_MAIN.Size = New System.Drawing.Size(454, 489) CONTAINER_MAIN.TabIndex = 0 CONTAINER_MAIN.TopToolStripPanelVisible = False ' @@ -139,20 +142,22 @@ Namespace Editors Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_MAIN.Controls.Add(Me.TXT_USER, 0, 0) Me.TP_MAIN.Controls.Add(Me.TP_SITE, 0, 3) - Me.TP_MAIN.Controls.Add(Me.TP_TEMP_FAV, 0, 4) - Me.TP_MAIN.Controls.Add(Me.TP_READY_USERMEDIA, 0, 6) - Me.TP_MAIN.Controls.Add(Me.TXT_DESCR, 0, 11) + Me.TP_MAIN.Controls.Add(Me.TP_TEMP_FAV, 0, 5) + Me.TP_MAIN.Controls.Add(Me.TP_READY_USERMEDIA, 0, 7) + Me.TP_MAIN.Controls.Add(Me.TXT_DESCR, 0, 12) Me.TP_MAIN.Controls.Add(Me.TXT_USER_FRIENDLY, 0, 1) - Me.TP_MAIN.Controls.Add(Me.TP_ADD_BY_LIST, 0, 7) - Me.TP_MAIN.Controls.Add(Me.TXT_LABELS, 0, 8) - Me.TP_MAIN.Controls.Add(Me.TP_DOWN_IMG_VID, 0, 5) + Me.TP_MAIN.Controls.Add(Me.TP_ADD_BY_LIST, 0, 8) + Me.TP_MAIN.Controls.Add(Me.TXT_LABELS, 0, 9) + Me.TP_MAIN.Controls.Add(Me.TP_DOWN_IMG_VID, 0, 6) Me.TP_MAIN.Controls.Add(Me.TXT_SPEC_FOLDER, 0, 2) - Me.TP_MAIN.Controls.Add(Me.TXT_SCRIPT, 0, 10) - Me.TP_MAIN.Controls.Add(Me.COLOR_USER, 0, 9) + Me.TP_MAIN.Controls.Add(Me.TXT_SCRIPT, 0, 11) + Me.TP_MAIN.Controls.Add(Me.COLOR_USER, 0, 10) + Me.TP_MAIN.Controls.Add(Me.CMB_ACCOUNT, 0, 4) Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.TP_MAIN.Location = New System.Drawing.Point(0, 0) Me.TP_MAIN.Name = "TP_MAIN" - Me.TP_MAIN.RowCount = 12 + Me.TP_MAIN.RowCount = 13 + Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) @@ -165,7 +170,7 @@ Namespace Editors Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26.0!)) Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) - Me.TP_MAIN.Size = New System.Drawing.Size(454, 461) + Me.TP_MAIN.Size = New System.Drawing.Size(454, 489) Me.TP_MAIN.TabIndex = 0 ' 'TXT_USER @@ -240,14 +245,14 @@ Namespace Editors Me.TP_TEMP_FAV.Controls.Add(Me.CH_TEMP, 0, 0) Me.TP_TEMP_FAV.Controls.Add(Me.CH_FAV, 1, 0) Me.TP_TEMP_FAV.Dock = System.Windows.Forms.DockStyle.Fill - Me.TP_TEMP_FAV.Location = New System.Drawing.Point(1, 117) + Me.TP_TEMP_FAV.Location = New System.Drawing.Point(1, 146) Me.TP_TEMP_FAV.Margin = New System.Windows.Forms.Padding(0) Me.TP_TEMP_FAV.Name = "TP_TEMP_FAV" Me.TP_TEMP_FAV.RowCount = 1 Me.TP_TEMP_FAV.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_TEMP_FAV.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27.0!)) Me.TP_TEMP_FAV.Size = New System.Drawing.Size(452, 28) - Me.TP_TEMP_FAV.TabIndex = 4 + Me.TP_TEMP_FAV.TabIndex = 5 ' 'CH_TEMP ' @@ -280,14 +285,14 @@ Namespace Editors Me.TP_READY_USERMEDIA.Controls.Add(Me.CH_PARSE_USER_MEDIA, 1, 0) Me.TP_READY_USERMEDIA.Controls.Add(Me.CH_READY_FOR_DOWN, 0, 0) Me.TP_READY_USERMEDIA.Dock = System.Windows.Forms.DockStyle.Fill - Me.TP_READY_USERMEDIA.Location = New System.Drawing.Point(1, 175) + Me.TP_READY_USERMEDIA.Location = New System.Drawing.Point(1, 204) Me.TP_READY_USERMEDIA.Margin = New System.Windows.Forms.Padding(0) Me.TP_READY_USERMEDIA.Name = "TP_READY_USERMEDIA" Me.TP_READY_USERMEDIA.RowCount = 1 Me.TP_READY_USERMEDIA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_READY_USERMEDIA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27.0!)) Me.TP_READY_USERMEDIA.Size = New System.Drawing.Size(452, 28) - Me.TP_READY_USERMEDIA.TabIndex = 6 + Me.TP_READY_USERMEDIA.TabIndex = 7 ' 'TXT_DESCR ' @@ -301,11 +306,11 @@ Namespace Editors Me.TXT_DESCR.Dock = System.Windows.Forms.DockStyle.Fill Me.TXT_DESCR.GroupBoxed = True Me.TXT_DESCR.GroupBoxText = "Description" - Me.TXT_DESCR.Location = New System.Drawing.Point(4, 317) + Me.TXT_DESCR.Location = New System.Drawing.Point(4, 346) Me.TXT_DESCR.Multiline = True Me.TXT_DESCR.Name = "TXT_DESCR" - Me.TXT_DESCR.Size = New System.Drawing.Size(446, 140) - Me.TXT_DESCR.TabIndex = 11 + Me.TXT_DESCR.Size = New System.Drawing.Size(446, 139) + Me.TXT_DESCR.TabIndex = 12 ' 'TXT_USER_FRIENDLY ' @@ -326,13 +331,13 @@ Namespace Editors Me.TP_ADD_BY_LIST.Controls.Add(Me.CH_ADD_BY_LIST, 0, 0) Me.TP_ADD_BY_LIST.Controls.Add(Me.CH_AUTO_DETECT_SITE, 1, 0) Me.TP_ADD_BY_LIST.Dock = System.Windows.Forms.DockStyle.Fill - Me.TP_ADD_BY_LIST.Location = New System.Drawing.Point(1, 204) + Me.TP_ADD_BY_LIST.Location = New System.Drawing.Point(1, 233) Me.TP_ADD_BY_LIST.Margin = New System.Windows.Forms.Padding(0) Me.TP_ADD_BY_LIST.Name = "TP_ADD_BY_LIST" Me.TP_ADD_BY_LIST.RowCount = 1 Me.TP_ADD_BY_LIST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_ADD_BY_LIST.Size = New System.Drawing.Size(452, 28) - Me.TP_ADD_BY_LIST.TabIndex = 7 + Me.TP_ADD_BY_LIST.TabIndex = 8 ' 'CH_ADD_BY_LIST ' @@ -367,11 +372,11 @@ Namespace Editors Me.TXT_LABELS.CaptionText = "Labels" Me.TXT_LABELS.CaptionWidth = 50.0R Me.TXT_LABELS.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_LABELS.Location = New System.Drawing.Point(4, 235) + Me.TXT_LABELS.Location = New System.Drawing.Point(4, 264) Me.TXT_LABELS.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3) Me.TXT_LABELS.Name = "TXT_LABELS" Me.TXT_LABELS.Size = New System.Drawing.Size(446, 22) - Me.TXT_LABELS.TabIndex = 8 + Me.TXT_LABELS.TabIndex = 9 Me.TXT_LABELS.TextBoxReadOnly = True ' 'TP_DOWN_IMG_VID @@ -383,14 +388,14 @@ Namespace Editors Me.TP_DOWN_IMG_VID.Controls.Add(Me.CH_DOWN_IMAGES, 0, 0) Me.TP_DOWN_IMG_VID.Controls.Add(Me.CH_DOWN_VIDEOS, 1, 0) Me.TP_DOWN_IMG_VID.Dock = System.Windows.Forms.DockStyle.Fill - Me.TP_DOWN_IMG_VID.Location = New System.Drawing.Point(1, 146) + Me.TP_DOWN_IMG_VID.Location = New System.Drawing.Point(1, 175) Me.TP_DOWN_IMG_VID.Margin = New System.Windows.Forms.Padding(0) Me.TP_DOWN_IMG_VID.Name = "TP_DOWN_IMG_VID" Me.TP_DOWN_IMG_VID.RowCount = 1 Me.TP_DOWN_IMG_VID.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) Me.TP_DOWN_IMG_VID.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27.0!)) Me.TP_DOWN_IMG_VID.Size = New System.Drawing.Size(452, 28) - Me.TP_DOWN_IMG_VID.TabIndex = 5 + Me.TP_DOWN_IMG_VID.TabIndex = 6 ' 'CH_DOWN_IMAGES ' @@ -454,13 +459,13 @@ Namespace Editors Me.TXT_SCRIPT.CaptionToolTipText = "Execute script after downloading this user" Me.TXT_SCRIPT.CaptionWidth = 65.0R Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill - Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 289) + Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 318) Me.TXT_SCRIPT.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3) Me.TXT_SCRIPT.Name = "TXT_SCRIPT" Me.TXT_SCRIPT.PlaceholderEnabled = True Me.TXT_SCRIPT.PlaceholderText = "Leave blank to use the default script..." Me.TXT_SCRIPT.Size = New System.Drawing.Size(446, 22) - Me.TXT_SCRIPT.TabIndex = 10 + Me.TXT_SCRIPT.TabIndex = 11 ' 'COLOR_USER ' @@ -468,25 +473,41 @@ Namespace Editors Me.COLOR_USER.CaptionText = "Color" Me.COLOR_USER.CaptionWidth = 55 Me.COLOR_USER.Dock = System.Windows.Forms.DockStyle.Fill - Me.COLOR_USER.Location = New System.Drawing.Point(2, 261) + Me.COLOR_USER.Location = New System.Drawing.Point(2, 290) Me.COLOR_USER.Margin = New System.Windows.Forms.Padding(1, 1, 2, 1) Me.COLOR_USER.Name = "COLOR_USER" Me.COLOR_USER.Size = New System.Drawing.Size(449, 24) - Me.COLOR_USER.TabIndex = 9 + Me.COLOR_USER.TabIndex = 10 + ' + 'CMB_ACCOUNT + ' + ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image) + ActionButton10.Name = "ArrowDown" + ActionButton10.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown + Me.CMB_ACCOUNT.Buttons.Add(ActionButton10) + Me.CMB_ACCOUNT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label + Me.CMB_ACCOUNT.CaptionText = "Account" + Me.CMB_ACCOUNT.CaptionVisible = True + Me.CMB_ACCOUNT.Dock = System.Windows.Forms.DockStyle.Fill + Me.CMB_ACCOUNT.Location = New System.Drawing.Point(4, 120) + Me.CMB_ACCOUNT.Name = "CMB_ACCOUNT" + Me.CMB_ACCOUNT.Size = New System.Drawing.Size(446, 22) + Me.CMB_ACCOUNT.TabIndex = 4 + Me.CMB_ACCOUNT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle ' 'UserCreatorForm ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font - Me.ClientSize = New System.Drawing.Size(454, 461) + Me.ClientSize = New System.Drawing.Size(454, 489) Me.Controls.Add(CONTAINER_MAIN) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.Icon = Global.SCrawler.My.Resources.Resources.UsersIcon_32 Me.KeyPreview = True Me.MaximizeBox = False - Me.MaximumSize = New System.Drawing.Size(470, 500) + Me.MaximumSize = New System.Drawing.Size(470, 528) Me.MinimizeBox = False - Me.MinimumSize = New System.Drawing.Size(470, 500) + Me.MinimumSize = New System.Drawing.Size(470, 528) Me.Name = "UserCreatorForm" Me.ShowInTaskbar = False Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide @@ -511,6 +532,7 @@ Namespace Editors Me.TP_DOWN_IMG_VID.PerformLayout() CType(Me.TXT_SPEC_FOLDER, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub @@ -537,5 +559,6 @@ Namespace Editors Private WithEvents TP_READY_USERMEDIA As TableLayoutPanel Private WithEvents TP_DOWN_IMG_VID As TableLayoutPanel Private WithEvents COLOR_USER As ColorPicker + Private WithEvents CMB_ACCOUNT As PersonalUtilities.Forms.Controls.ComboBoxExtended End Class End Namespace \ No newline at end of file diff --git a/SCrawler/Editors/UserCreatorForm.resx b/SCrawler/Editors/UserCreatorForm.resx index 6c89bed..4d81392 100644 --- a/SCrawler/Editors/UserCreatorForm.resx +++ b/SCrawler/Editors/UserCreatorForm.resx @@ -376,6 +376,96 @@ You can see downloaded subscriptions in the feed. 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 + AAAASUVORK5CYII= \ No newline at end of file diff --git a/SCrawler/Editors/UserCreatorForm.vb b/SCrawler/Editors/UserCreatorForm.vb index b776711..b3b515b 100644 --- a/SCrawler/Editors/UserCreatorForm.vb +++ b/SCrawler/Editors/UserCreatorForm.vb @@ -254,12 +254,13 @@ Namespace Editors Else If User.Name.IsEmptyString Then checkBuffer = True + TXT_USER.CaptionText = "User URL" CH_READY_FOR_DOWN.Checked = True CH_TEMP.Checked = Settings.DefaultTemporary CH_DOWN_IMAGES.Checked = Settings.DefaultDownloadImages CH_DOWN_VIDEOS.Checked = Settings.DefaultDownloadVideos TXT_SCRIPT.Checked = Settings.ScriptData.Attribute - SetParamsBySite() + SetParamsBySite(True) Else TP_ADD_BY_LIST.Enabled = False TXT_USER.Text = User.Name @@ -267,7 +268,13 @@ Namespace Editors Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = User.Plugin) If i >= 0 Then CMB_SITE.SelectedIndex = i CMB_SITE.Checked = User.IsSubscription - SetParamsBySite() + SetParamsBySite(True) + If i >= 0 Then + With Settings.Plugins(i).Settings + i = .IndexOf(User.AccountName) + If i >= 0 And CMB_ACCOUNT.Items.Count > 0 Then CMB_ACCOUNT.SelectedIndex = i + End With + End If If Not UserInstance Is Nothing Then CMB_SITE.Enabled = False Text = $"User: {UserInstance.Name}" @@ -383,7 +390,10 @@ Namespace Editors Else If Not CH_ADD_BY_LIST.Checked Then If MyDef.MyFieldsChecker.AllParamsOK Then - Dim s As SettingsHost = GetSiteByCheckers() + Dim s As SettingsHost = Nothing + With GetSiteByCheckers() + If Not .Self Is Nothing Then s = .Self()(CMB_ACCOUNT.Text, True) + End With If Not s Is Nothing Then If IsSubscription And Not s.Source.SubscriptionsAllowed Then MsgBoxE({$"Subscription mode for site [{s.Name}] is not allowed", msgTitle}, vbCritical) @@ -395,6 +405,7 @@ Namespace Editors .Name = TXT_USER.Text .Site = s.Name .Plugin = s.Key + .AccountName = CMB_ACCOUNT.Text .IsSubscription = IsSubscription Dim sp As SFile = SpecialPath(s) If Not sp.IsEmptyString AndAlso Not SpecialPathHandler Is Nothing And UserInstance Is Nothing Then _ @@ -530,13 +541,16 @@ CloseForm: End Sub Private Sub CMB_SITE_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_SITE.ActionSelectedItemChanged MyExchangeOptions = Nothing - SetParamsBySite() + SetParamsBySite(True) End Sub Private Sub CMB_SITE_ActionOnTextChanged(sender As Object, e As EventArgs) Handles CMB_SITE.ActionOnTextChanged If CMB_SITE.Text.IsEmptyString And Not UserIsCollection Then CMB_SITE.SelectedIndex = -1 : Icon = My.Resources.UsersIcon_32 End Sub Private Sub BTT_OTHER_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_OTHER_SETTINGS.Click - Dim s As SettingsHost = GetSiteByCheckers() + Dim s As SettingsHost = Nothing + With GetSiteByCheckers() + If Not .Self Is Nothing Then s = .Self()(CMB_ACCOUNT.Text, True) + End With If Not s Is Nothing Then s.Source.UserOptions(MyExchangeOptions, True) MyDef.ChangesDetected = True @@ -568,6 +582,10 @@ CloseForm: SpecialPathHandler = Nothing End If End Sub + Private _AccountsRefilling As Boolean = False + Private Sub CMB_ACCOUNT_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_ACCOUNT.ActionSelectedItemChanged + If Not _AccountsRefilling Then SetParamsBySite(False) + End Sub Private Sub CH_TEMP_CheckedChanged(sender As Object, e As EventArgs) Handles CH_TEMP.CheckedChanged If CH_TEMP.Checked Then CH_FAV.Checked = False : CH_READY_FOR_DOWN.Checked = False End Sub @@ -582,7 +600,7 @@ CloseForm: TXT_DESCR.GroupBoxText = "Description" CH_AUTO_DETECT_SITE.Checked = False CH_AUTO_DETECT_SITE.Enabled = False - SetParamsBySite() + SetParamsBySite(False) End If TXT_USER.Enabled = Not CH_ADD_BY_LIST.Checked TXT_USER_FRIENDLY.Enabled = Not CH_ADD_BY_LIST.Checked @@ -620,7 +638,7 @@ CloseForm: End Sub #End Region #Region "Functions" - Private Function GetSiteByCheckers() As SettingsHost + Private Function GetSiteByCheckers() As SettingsHostCollection Return If(CMB_SITE.SelectedIndex >= 0, Settings(CStr(CMB_SITE.Items(CMB_SITE.SelectedIndex).Value(0))), Nothing) End Function Private Function CreateUsersByList() As Boolean @@ -636,7 +654,7 @@ CloseForm: Dim uu$ Dim ulabels As List(Of String) = ListAddList(Nothing, UserLabels).ListAddValue(LabelsKeeper.NoParsedUser, LAP.NotContainsOnly) Dim tmpUser As UserInfo - Dim s As SettingsHost = GetSiteByCheckers() + Dim s As SettingsHost = GetSiteByCheckers().Default Dim sObj As ExchangeOptions = Nothing Dim Added% = 0 Dim Skipped% = 0 @@ -660,7 +678,7 @@ CloseForm: If CH_AUTO_DETECT_SITE.Checked Then sObj = GetSiteByText(uu) If Not sObj.UserName.IsEmptyString Then - s = Settings(sObj.HostKey) + s = Settings(sObj.HostKey).Default uu = sObj.UserName Else s = Nothing @@ -746,13 +764,18 @@ CloseForm: Private Function GetSiteByText(ByRef TXT As String) As ExchangeOptions Dim s As ExchangeOptions For Each p As PluginHost In Settings.Plugins - s = p.Settings.IsMyUser(TXT) + s = p.Settings.Default.IsMyUser(TXT) If Not s.UserName.IsEmptyString Then Return s Next Return Nothing End Function - Private Sub SetParamsBySite() - Dim s As SettingsHost = GetSiteByCheckers() + Private Sub SetParamsBySite(ByVal RefillAccs As Boolean) + Dim sc As SettingsHostCollection = GetSiteByCheckers() + Dim s As SettingsHost = Nothing + If Not sc Is Nothing Then + If RefillAccs Then RefillAccounts(sc) + s = sc(CMB_ACCOUNT.Text) + End If If Not s Is Nothing Then With s CH_TEMP.Checked = .Temporary @@ -783,6 +806,40 @@ CloseForm: If Not UserIsCollection Then Icon = My.Resources.UsersIcon_32 End If End Sub + Private Sub RefillAccounts(ByVal sc As SettingsHostCollection) + Try + If Not sc Is Nothing And Not UserIsCollection Then + _AccountsRefilling = True + CMB_ACCOUNT.BeginUpdate() + + With CMB_ACCOUNT + .BeginUpdate() + .Text = String.Empty + .Items.Clear() + If sc.Count = 1 Then + .Text = SettingsHost.NameAccountNameDefault + .LeaveDefaultButtons = False + .Buttons.Clear() + Else + .LeaveDefaultButtons = True + .Items.AddRange(sc.Select(Function(s) New ListItem(s.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)))) + End If + .Buttons.UpdateButtonsPositions(True) + .EndUpdate(True) + If .Items.Count > 0 Then + .Enabled = True + .SelectedIndex = 0 + Else + .Enabled = False + End If + End With + End If + Catch ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, ex, "[UserCreatorForm.RefillAccounts]") + Finally + _AccountsRefilling = False + End Try + End Sub Private Sub ChangeLabels() Using fl As New LabelsForm(UserLabels) fl.ShowDialog() diff --git a/SCrawler/MainFrame.vb b/SCrawler/MainFrame.vb index cd7fa76..7383a32 100644 --- a/SCrawler/MainFrame.vb +++ b/SCrawler/MainFrame.vb @@ -22,6 +22,7 @@ Public Class MainFrame Private MyView As FormView Private WithEvents MyActivator As FormActivator Private WithEvents BTT_IMPORT_USERS As ToolStripMenuItem + Private WithEvents BTT_NEW_PROFILE As ToolStripMenuItem Friend MyChannels As ChannelViewForm Friend MySavedPosts As DownloadSavedPostsForm Private MyMissingPosts As MissingPostsForm @@ -43,7 +44,10 @@ Public Class MainFrame Next End If End With - BTT_IMPORT_USERS = New ToolStripMenuItem With {.Text = "Import", .Image = My.Resources.UsersIcon_32.ToBitmap} + BTT_IMPORT_USERS = New ToolStripMenuItem("Import", My.Resources.UsersIcon_32.ToBitmap) + BTT_NEW_PROFILE = New ToolStripMenuItem("Add new profile", My.Resources.PlusPic_24) + MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, New ToolStripSeparator) + MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, BTT_NEW_PROFILE) MENU_SETTINGS.DropDownItems.AddRange({New ToolStripSeparator, BTT_IMPORT_USERS}) BTT_BUG_REPORT.Image = My.Resources.MailPic_16 End Sub @@ -87,7 +91,7 @@ Public Class MainFrame With LIST_PROFILES.Groups .AddRange(GetLviGroupName(Nothing, True)) 'collections If Settings.Plugins.Count > 0 Then - For Each h As SettingsHost In Settings.Plugins.Select(Function(hh) hh.Settings) : .AddRange(GetLviGroupName(h, False)) : Next + For Each h As SettingsHost In Settings.Plugins.Select(Function(hh) hh.Settings.Default) : .AddRange(GetLviGroupName(h, False)) : Next End If If Settings.Labels.Count > 0 Then Settings.Labels.ToList.ForEach(Sub(l) .Add(New ListViewGroup(l, l))) .Add(Settings.Labels.NoLabel) @@ -312,6 +316,21 @@ CloseResume: If .OutputPath.IsEmptyString And Not Settings.LatestSavingPath.IsEmptyString Then .OutputPath.Value = Settings.LatestSavingPath.Value End With End Sub + Private Sub BTT_NEW_PROFILE_Click(sender As Object, e As EventArgs) Handles BTT_NEW_PROFILE.Click + Try + Using f As New SimpleListForm(Of PluginHost)(Settings.Plugins, Settings.Design) With { + .DesignXMLNodeName = "PluginsChooserForm", + .Mode = SimpleListFormModes.SelectedItems, + .MultiSelect = False, + .FormText = "Available plugins", + .Icon = My.Resources.SettingsIcon_48 + } + If f.ShowDialog = DialogResult.OK AndAlso f.DataResult.Count > 0 Then f.DataResult.First.Settings.CreateAbstract() + End Using + Catch ex As Exception + ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "MainFrame.CreateNewProfile]") + End Try + End Sub Private Sub BTT_IMPORT_USERS_Click(sender As Object, e As EventArgs) Handles BTT_IMPORT_USERS.Click Const MsgTitle$ = "Import users" Try @@ -1662,8 +1681,8 @@ ResumeDownloadingOperation: If user.IsCollection And Not user.CollectionName = f.CollectionName Then If Not user.IsVirtual AndAlso Downloader.Working Then MsgBoxE({"Some users are currently downloading." & vbCr & - "You cannot change collection name while downloading." & vbCr & - "Wait until the download is complete.", MsgTitle}, vbCritical) + "You cannot change collection name while downloading." & vbCr & + "Wait until the download is complete.", MsgTitle}, vbCritical) Exit Sub Else If Not user.IsVirtual Then diff --git a/SCrawler/PluginsEnvironment/Attributes/Attributes.vb b/SCrawler/PluginsEnvironment/Attributes/Attributes.vb index a046402..ae63fb6 100644 --- a/SCrawler/PluginsEnvironment/Attributes/Attributes.vb +++ b/SCrawler/PluginsEnvironment/Attributes/Attributes.vb @@ -41,4 +41,8 @@ Namespace Plugin.Attributes Name = _Name End Sub End Class + Public Class PClonableAttribute : Inherits Attribute + Public Clone As Boolean = True + Public Update As Boolean = True + End Class End Namespace \ No newline at end of file diff --git a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb index 4c1bc68..6039928 100644 --- a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb @@ -53,7 +53,7 @@ Namespace Plugin.Hosts Friend Sub New(ByVal f As SFile) Load(f) If _Exists Then - Dim plugin As SettingsHost + Dim plugin As SettingsHostCollection SiteIcon = Nothing If Not MediaState = UserMediaStates.Downloaded Then If Not SiteKey.IsEmptyString Then @@ -66,7 +66,8 @@ Namespace Plugin.Hosts If plugin Is Nothing Then _Exists = False Else - Instance = plugin.GetInstance(ISiteSettings.Download.SingleObject, Nothing, False, False) + Instance = plugin(AccountName, True).GetInstance(ISiteSettings.Download.SingleObject, Nothing, False, False) + Instance.AccountName = AccountName End If End If If _Exists And Not Instance Is Nothing AndAlso Not Instance.HOST Is Nothing Then SiteIcon = Instance.HOST.Source.Image @@ -76,8 +77,9 @@ Namespace Plugin.Hosts Else plugin = Settings(SiteKey) If Not plugin Is Nothing Then - Dim i As UserDataBase = plugin.GetInstance(ISiteSettings.Download.SingleObject, Nothing, False, False) + Dim i As UserDataBase = plugin(AccountName, True).GetInstance(ISiteSettings.Download.SingleObject, Nothing, False, False) If Not i Is Nothing Then + i.AccountName = AccountName If Not i.HOST.Source.Image Is Nothing Then SiteIcon = i.HOST.Source.Image ElseIf Not i.HOST.Source.Icon Is Nothing Then @@ -97,6 +99,7 @@ Namespace Plugin.Hosts SiteIcon = .SiteIcon Site = .Site SiteKey = .SiteKey + AccountName = .AccountName _HasError = .HasError _Exists = .Exists End With @@ -140,6 +143,7 @@ Namespace Plugin.Hosts d.Size = s.Size d.Duration = s.Duration d.Checked = s.Checked + d.AccountName = s.AccountName End If End Sub Public Overrides Sub Load(ByVal f As SFile) diff --git a/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb b/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb index 0328d30..25d65d9 100644 --- a/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/PluginHost.vb @@ -14,7 +14,7 @@ Imports PersonalUtilities.Tools.WEB.GitHub Namespace Plugin.Hosts Friend Class PluginHost Friend Const PluginsPath As String = "Plugins\" - Friend ReadOnly Property Settings As SettingsHost + Friend ReadOnly Property Settings As SettingsHostCollection Friend ReadOnly Property Name As String Get Return Settings.Name @@ -42,9 +42,9 @@ Namespace Plugin.Hosts End Get End Property Friend ReadOnly Property HasError As Boolean - Private Sub New(ByVal s As ISiteSettings, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, + Private Sub New(ByVal PluginType As Type, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) - Settings = New SettingsHost(s, _XML, GlobalPath, _Temp, _Imgs, _Vids) + Settings = New SettingsHostCollection(PluginType, _XML, GlobalPath, _Temp, _Imgs, _Vids) End Sub Private Sub New(ByVal AssemblyFile As SFile, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) @@ -59,10 +59,8 @@ Namespace Plugin.Hosts For Each tt As Type In t If tt.IsInterface Or tt.IsAbstract Then Continue For - Else - If Not tt.GetInterface(tSettings) Is Nothing Then - Settings = New SettingsHost(Activator.CreateInstance(tt), _XML, GlobalPath, _Temp, _Imgs, _Vids) - End If + ElseIf Not tt.GetInterface(tSettings) Is Nothing Then + Settings = New SettingsHostCollection(tt, _XML, GlobalPath, _Temp, _Imgs, _Vids) End If Next End If @@ -72,26 +70,29 @@ Namespace Plugin.Hosts _HasError = True End Try End Sub + Public Overrides Function ToString() As String + Return Name + End Function Friend Shared Function GetMyHosts(ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) As IEnumerable(Of PluginHost) - Return {New PluginHost(New API.Reddit.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.Twitter.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.Mastodon.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.Instagram.SiteSettings(_XML, GlobalPath), _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.ThreadsNet.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.RedGifs.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.YouTube.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.Pinterest.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.TikTok.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.LPSG.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.PornHub.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.Xhamster.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.XVIDEOS.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.ThisVid.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.PathPlugin.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.OnlyFans.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids), - New PluginHost(New API.JustForFans.SiteSettings, _XML, GlobalPath, _Temp, _Imgs, _Vids)} + Return {New PluginHost(GetType(API.Reddit.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.Twitter.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.Mastodon.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.Instagram.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.ThreadsNet.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.RedGifs.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.YouTube.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.Pinterest.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.TikTok.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.LPSG.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.PornHub.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.Xhamster.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.XVIDEOS.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.ThisVid.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.PathPlugin.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.OnlyFans.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids), + New PluginHost(GetType(API.JustForFans.SiteSettings), _XML, GlobalPath, _Temp, _Imgs, _Vids)} End Function Friend Shared Function GetPluginsHosts(ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), diff --git a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb index 286e2ba..9d2bfef 100644 --- a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb @@ -15,7 +15,7 @@ Imports PersonalUtilities.Forms.Controls Imports PersonalUtilities.Forms.Controls.Base Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons Namespace Plugin.Hosts - Friend Class PropertyValueHost : Implements IPropertyValue, IComparable(Of PropertyValueHost) + Friend Class PropertyValueHost : Implements IPropertyValue, IComparable(Of PropertyValueHost), IDisposable #Region "Events" Private Event ValueChanged As IPropertyValue.ValueChangedEventHandler Implements IPropertyValue.ValueChanged #End Region @@ -309,6 +309,36 @@ Namespace Plugin.Hosts Private Function CompareTo(ByVal Other As PropertyValueHost) As Integer Implements IComparable(Of PropertyValueHost).CompareTo Return ControlNumber.CompareTo(Other.ControlNumber) End Function +#End Region +#Region "IDisposable Support" + Protected disposedValue As Boolean = False + Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue Then + If disposing Then + Source = Nothing + Member = Nothing + ProviderFieldsChecker = Nothing + ProviderValue = Nothing + PropertiesChecking = Nothing + PropertiesCheckingMethod = Nothing + UpdateMethod = Nothing + UpdateMethodArguments = Nothing + XValue.DisposeIfReady + DisposeControl() + DependentNames.Clear() + Dependents.Clear() + End If + disposedValue = True + End If + End Sub + Protected Overrides Sub Finalize() + Dispose(False) + MyBase.Finalize() + End Sub + Friend Overloads Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + GC.SuppressFinalize(Me) + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb index 5f2de75..c3de022 100644 --- a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb @@ -16,16 +16,43 @@ Imports PersonalUtilities.Functions.XML.Objects Imports PersonalUtilities.Tools.Web.Clients Imports Download = SCrawler.Plugin.ISiteSettings.Download Namespace Plugin.Hosts - Friend Class SettingsHost + Friend Class SettingsHost : Implements IIndexable, IEquatable(Of SettingsHost), IDisposableSuspend +#Region "Events" + Friend Delegate Sub SettingsHostActionEventHandler(ByVal Obj As SettingsHost) + Friend Event Deleted As SettingsHostActionEventHandler + Friend Event OkClick As SettingsHostActionEventHandler + Friend Event CloneClick As SettingsHostActionEventHandler +#End Region #Region "Controls" Private WithEvents BTT_SETTINGS As ToolStripMenuItem + Private WithEvents BTT_SETTINGS_ACTIONS_EDIT As ToolStripMenuItem + Private WithEvents BTT_SETTINGS_ACTIONS_DELETE As ToolStripMenuItem + Private WithEvents BTT_SETTINGS_ACTIONS_CLONE As ToolStripMenuItem Private WithEvents BTT_SETTINGS_INTERNAL As Button Private ReadOnly SpecialFormAttribute As SpecialForm = Nothing +#Region "Menu buttons" Friend Function GetSettingsButton() As ToolStripItem - BTT_SETTINGS = New ToolStripMenuItem With {.Text = Source.Site} - If Not Source.Image Is Nothing Then BTT_SETTINGS.Image = Source.Image + UpdateSettingsButton() Return BTT_SETTINGS End Function + Private Sub UpdateSettingsButton() + If BTT_SETTINGS Is Nothing Then + BTT_SETTINGS = New ToolStripMenuItem + If [Default] Then + BTT_SETTINGS.Text = NameAccountNameDefault + If Not _AccountName.IsEmptyString Then BTT_SETTINGS.Text &= $" [{_AccountName}]" + Else + BTT_SETTINGS.Text = AccountName + End If + If Not Source.Image Is Nothing Then BTT_SETTINGS.Image = Source.Image + End If + If BTT_SETTINGS_ACTIONS_EDIT Is Nothing Then BTT_SETTINGS_ACTIONS_EDIT = New ToolStripMenuItem("Edit", My.Resources.PencilPic_16) With {.BackColor = MyColor.EditBack, .ForeColor = MyColor.EditFore} + If BTT_SETTINGS_ACTIONS_DELETE Is Nothing Then BTT_SETTINGS_ACTIONS_DELETE = New ToolStripMenuItem("Delete", My.Resources.DeletePic_24) With {.BackColor = MyColor.DeleteBack, .ForeColor = MyColor.DeleteFore} + If BTT_SETTINGS_ACTIONS_CLONE Is Nothing Then BTT_SETTINGS_ACTIONS_CLONE = New ToolStripMenuItem("Clone", My.Resources.PlusPic_24) With {.BackColor = MyColor.OkBack, .ForeColor = MyColor.OkFore} + If BTT_SETTINGS.DropDownItems.Count = 0 Then BTT_SETTINGS.DropDownItems.AddRange({BTT_SETTINGS_ACTIONS_EDIT, BTT_SETTINGS_ACTIONS_DELETE, BTT_SETTINGS_ACTIONS_CLONE}) + End Sub +#End Region +#Region "Editor form button" Friend Function GetSettingsButtonInternal() As Button If Not SpecialFormAttribute Is Nothing AndAlso SpecialFormAttribute.SettingsForm Then BTT_SETTINGS_INTERNAL = New Button With {.Text = "Other settings", .Dock = DockStyle.Right, .Width = 150} @@ -34,13 +61,33 @@ Namespace Plugin.Hosts Return Nothing End If End Function - Private Sub BTT_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS.Click +#End Region +#Region "Menu buttons handlers" + Friend Sub SettingsPerformClick() Handles BTT_SETTINGS.Click, BTT_SETTINGS_ACTIONS_EDIT.Click Try - Using f As New Editors.SiteEditorForm(Me) : f.ShowDialog() : End Using + Using f As New Editors.SiteEditorForm(Me) + f.ShowDialog() + If f.DialogResult = DialogResult.OK And IsAbstract Then RaiseEvent OkClick(Me) + End Using Catch ex As Exception ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "[Plugin.Hosts.SettingsHost.OpenSettingsForm]") End Try End Sub + Private Sub BTT_SETTINGS_ACTIONS_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS_ACTIONS_DELETE.Click + Const msgTitle$ = "Deleting a profile" + If Downloader.Working Then + MsgBoxE({"You cannot delete a profile until the download is complete", msgTitle}, vbCritical) + ElseIf [Default] Then + MsgBoxE({"The default profile cannot be deleted", msgTitle}, vbCritical) + ElseIf MsgBoxE({$"Are you sure you want to delete this profile ({AccountName})?", msgTitle}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then + RaiseEvent Deleted(Me) + End If + End Sub + Private Sub BTT_SETTINGS_ACTIONS_CLONE_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS_ACTIONS_CLONE.Click + RaiseEvent CloneClick(Me) + End Sub +#End Region +#Region "Editor form buttons handlers" Private Sub BTT_SETTINGS_INTERNAL_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS_INTERNAL.Click Try If Not SpecialFormAttribute Is Nothing AndAlso SpecialFormAttribute.SettingsForm Then Source.OpenSettingsForm() @@ -49,6 +96,14 @@ Namespace Plugin.Hosts End Try End Sub #End Region +#End Region +#Region "IIndexable Support" + Friend Property Index As Integer = -1 Implements IIndexable.Index + Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex + DirectCast(Obj, SettingsHost).Index = Index + Return Obj + End Function +#End Region #Region "Host declarations" Friend ReadOnly Property Source As ISiteSettings Friend ReadOnly Property PropList As List(Of PropertyValueHost) @@ -60,9 +115,33 @@ Namespace Plugin.Hosts Private ReadOnly _Key As String Friend ReadOnly Property Key As String Get - Return IIf(_Key.IsEmptyString, Name, _Key) + Return _Key.IfNullOrEmpty(Name) End Get End Property + Friend ReadOnly Property KeyDownloader As String + Get + Return $"{Key}_{AccountName}" + End Get + End Property + Friend Const NameAccountNameDefault As String = "Default" + Friend Const NameXML_AccountName As String = "AccountName" + Private ReadOnly _AccountName As XMLValue(Of String) + Friend Property AccountName As String + Get + If Not _AccountName.IsEmptyString Then + Return _AccountName + ElseIf Index = 0 Then + Return NameAccountNameDefault + Else + Return String.Empty + End If + End Get + Set(ByVal _AccountName As String) + Me._AccountName.Value = _AccountName + Me.Source.AccountName = _AccountName + End Set + End Property + Friend ReadOnly Property [Default] As Boolean Friend ReadOnly Property IsSeparatedTasks As Boolean = False Friend ReadOnly Property IsSavedPostsCompatible As Boolean = False Private ReadOnly _TaskCountDefined As Integer? = Nothing @@ -130,12 +209,19 @@ Namespace Plugin.Hosts _SavedPostsPath.Value = NewPath End Set End Property + Friend Property DownloadSavedPosts As XMLValue(Of Boolean) Friend ReadOnly Property GetUserMediaOnly As XMLValue(Of Boolean) #End Region - Friend Sub New(ByVal Plugin As ISiteSettings, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, + Friend ReadOnly Property IsAbstract As Boolean = False + Friend Sub New(ByVal Plugin As ISiteSettings, ByVal GlobalPath As SFile, ByVal _Temp As Boolean, _Imgs As Boolean, _Vids As Boolean) + Me.New(Plugin, False, Nothing, GlobalPath, _Temp, _Imgs, _Vids) + End Sub + Friend Sub New(ByVal Plugin As ISiteSettings, ByVal IsDef As Boolean, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) Source = Plugin Source.Logger = LogConnector + [Default] = IsDef + If _XML Is Nothing Then IsAbstract = True PropList = New List(Of PropertyValueHost) @@ -166,11 +252,13 @@ Namespace Plugin.Hosts End If Dim i% + Dim n() As String = {SettingsCLS.Name_Node_Sites, Name} + + _AccountName = New XMLValue(Of String)(NameXML_AccountName,, _XML, n) + Source.AccountName = _AccountName Source.BeginInit() - Dim n() As String = {SettingsCLS.Name_Node_Sites, Name} - If If(_XML(n)?.Count, 0) > 0 Then Source.Load(ToKeyValuePair(Of String, EContainer)(_XML(n))) Dim Members As IEnumerable(Of MemberInfo) = Plugin.GetType.GetTypeInfo.DeclaredMembers _ResponserIsContainer = TypeOf Plugin Is IResponserContainer If Members.ListExists Then @@ -247,6 +335,7 @@ Namespace Plugin.Hosts _Path = New XMLValue(Of SFile)("Path",, _XML, n, New XMLToFilePathProvider) _SavedPostsPath = New XMLValue(Of SFile)("SavedPostsPath",, _XML, n, New XMLToFilePathProvider) + DownloadSavedPosts = New XMLValue(Of Boolean)("DownloadSavedPosts", True, _XML, n) Temporary = New XMLValue(Of Boolean) Temporary.SetExtended("Temporary", False, _XML, n) @@ -266,13 +355,45 @@ Namespace Plugin.Hosts If PropList.Count > 0 Then Dim MaxOffset% = Math.Max(PropList.Max(Function(pp) pp.LeftOffset), PropertyValueHost.LeftOffsetDefault) For Each p As PropertyValueHost In PropList - p.SetXmlEnvironment(_XML, n) + If Not IsAbstract Then p.SetXmlEnvironment(_XML, n) p.LeftOffset = MaxOffset Next End If Source.EndInit() End Sub + Friend Function Apply(ByVal _XML As XmlFile, ByVal GlobalPath As SFile, + ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) As SettingsHost + Dim newHost As New SettingsHost(Source.Clone(True), False, _XML, GlobalPath, _Temp, _Imgs, _Vids) + + _XML.BeginUpdate() + + With newHost + ._AccountName.Value = _AccountName.Value + .DownloadSiteData.Value = DownloadSiteData.Value + .Temporary.ValueF = Temporary.ValueF + .DownloadImages.ValueF = DownloadImages.ValueF + .DownloadVideos.ValueF = DownloadVideos.ValueF + ._Path.Value = _Path.Value + ._SavedPostsPath.Value = _SavedPostsPath.Value + .DownloadSavedPosts.Value = .DownloadSavedPosts.Value + .GetUserMediaOnly.Value = .GetUserMediaOnly.Value + With .Source + .BeginInit() + .AccountName = _AccountName + .Update(Source) + .AccountName = _AccountName + .EndInit() + End With + End With + + _XML.EndUpdate() + + Return newHost + End Function + Friend Function Clone() As SettingsHost + Return New SettingsHost(Source.Clone(False), Path, Temporary, DownloadImages, DownloadVideos) With {.SavedPostsPath = SavedPostsPath} + End Function #Region "Forks" Friend Function IsMyUser(ByVal UserURL As String) As ExchangeOptions Dim s As ExchangeOptions = Source.IsMyUser(UserURL) @@ -323,15 +444,18 @@ Namespace Plugin.Hosts Private _AvailableValue As Boolean = True Private _AvailableAsked As Boolean = False Private _ActiveTaskCount As Integer = 0 + Friend Property AvailableText As String = String.Empty Friend Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean If DownloadSiteData Then If Not _AvailableAsked Then _AvailableValue = Source.Available(What, Silent) + AvailableText = Source.AvailableText _AvailableAsked = True End If Return _AvailableValue Else - If Not Silent Then MsgBoxE({$"Downloading data for the site {Name} has been disabled by you.", $"{Name} downloading disabled"}, vbExclamation) + AvailableText = $"Downloading data for the site {Name} - {AccountName.IfNullOrEmpty(NameAccountNameDefault)} has been disabled by you." + If Not Silent Then MsgBoxE({AvailableText, $"{Name} downloading disabled"}, vbExclamation) Return False End If End Function @@ -347,12 +471,60 @@ Namespace Plugin.Hosts End Sub Friend Sub DownloadDone(ByVal What As Download) _ActiveTaskCount -= 1 - If _ActiveTaskCount = 0 Then _AvailableAsked = False + If _ActiveTaskCount = 0 Then _AvailableAsked = False : AvailableText = String.Empty Source.DownloadDone(What) End Sub Private Function ConvertUser(ByVal User As IUserData) As Object Return If(DirectCast(User, UserDataBase).ExternalPlugin, User) End Function +#End Region +#Region "IEquatable Support" + Friend Overloads Function Equals(ByVal Other As SettingsHost) As Boolean Implements IEquatable(Of SettingsHost).Equals + Return [Default] = Other.Default OrElse AccountName = Other.AccountName + End Function + Public Overrides Function Equals(ByVal Obj As Object) As Boolean + Return Equals(DirectCast(Obj, SettingsHost)) + End Function +#End Region +#Region "IDisposable Support" + Private disposedValue As Boolean = False + Friend Property DisposeSuspended As Boolean Implements IDisposableSuspend.DisposeSuspended + Get + Return [Default] + End Get + Private Set : End Set + End Property + Friend ReadOnly Property Disposed As Boolean Implements IDisposableSuspend.Disposed + Get + Return disposedValue + End Get + End Property + Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) + If Not disposedValue And Not DisposeSuspended Then + If disposing Then + Source.DisposeIfReady + If Not BTT_SETTINGS Is Nothing Then BTT_SETTINGS.DropDownItems.Clear() + BTT_SETTINGS.DisposeIfReady + BTT_SETTINGS_ACTIONS_EDIT.DisposeIfReady + BTT_SETTINGS_ACTIONS_DELETE.DisposeIfReady + BTT_SETTINGS_ACTIONS_CLONE.DisposeIfReady + BTT_SETTINGS_INTERNAL.DisposeIfReady + PropList.ListClearDispose + XMLValuesDispose(Me, False) + End If + BTT_SETTINGS = Nothing + BTT_SETTINGS_INTERNAL = Nothing + disposedValue = True + End If + End Sub + Protected Overrides Sub Finalize() + Dispose(False) + MyBase.Finalize() + End Sub + Friend Overloads Sub Dispose() Implements IDisposable.Dispose + Dispose(True) + GC.SuppressFinalize(Me) + End Sub #End Region End Class End Namespace \ No newline at end of file diff --git a/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb b/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb new file mode 100644 index 0000000..d8d78be --- /dev/null +++ b/SCrawler/PluginsEnvironment/Hosts/SettingsHostCollection.vb @@ -0,0 +1,434 @@ +' Copyright (C) 2023 Andy https://github.com/AAndyProgram +' This program is free software: you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation, either version 3 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY +Imports System.Reflection +Imports SCrawler.API.Base +Imports SCrawler.API.YouTube.Objects +Imports PersonalUtilities.Tools +Imports PersonalUtilities.Forms +Imports PersonalUtilities.Functions.XML +Imports PersonalUtilities.Functions.XML.Objects +Imports Download = SCrawler.Plugin.ISiteSettings.Download +Imports PauseModes = SCrawler.DownloadObjects.AutoDownloader.PauseModes +Imports MsgBoxButton = PersonalUtilities.Functions.Messaging.MsgBoxButton +Namespace Plugin.Hosts + Friend Class SettingsHostCollection : Implements IEnumerable(Of SettingsHost), IMyEnumerator(Of SettingsHost) +#Region "Declarations" + Private Const FileNamePrefix As String = "Host_" + Private Const FileNamePattern As String = FileNamePrefix & "{0}_{1}_" + Private Const FileNamePatternFull As String = FileNamePattern & "{2}" + Private ReadOnly Hosts As List(Of SettingsHost) + Private ReadOnly HostsUnavailableIndexes As List(Of Integer) + Private ReadOnly HostsXml As List(Of XmlFile) +#Region "Controls" + Private WithEvents BTT_SETTINGS As ToolStripMenuItem + Private BTT_SETTINGS_SEP_1 As ToolStripSeparator + Private WithEvents BTT_SETTINGS_ACTIONS_ADD As ToolStripMenuItem + Friend Function GetSettingsButton() As ToolStripItem + UpdateSettingsButton() + Return BTT_SETTINGS + End Function + Private Sub UpdateSettingsButton() + If BTT_SETTINGS Is Nothing Then + BTT_SETTINGS = New ToolStripMenuItem With {.Text = [Default].Source.Site} + If Not [Default].Source.Image Is Nothing Then BTT_SETTINGS.Image = [Default].Source.Image + End If + BTT_SETTINGS.DropDownItems.Clear() + If Count > 1 Then + If BTT_SETTINGS_SEP_1 Is Nothing Then BTT_SETTINGS_SEP_1 = New ToolStripSeparator + If BTT_SETTINGS_ACTIONS_ADD Is Nothing Then BTT_SETTINGS_ACTIONS_ADD = New ToolStripMenuItem("Add new profile", My.Resources.PlusPic_24) + Hosts.ForEach(Sub(h) BTT_SETTINGS.DropDownItems.Add(h.GetSettingsButton)) + BTT_SETTINGS.DropDownItems.AddRange({BTT_SETTINGS_SEP_1, BTT_SETTINGS_ACTIONS_ADD}) + End If + End Sub + Private Sub BTT_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS.Click + If Count = 1 Then [Default].SettingsPerformClick() + End Sub +#End Region + Friend ReadOnly Property Key As String + Get + Return [Default].Key + End Get + End Property + Friend ReadOnly Property Name As String + Get + Return [Default].Name + End Get + End Property + Private ReadOnly Property PluginType As Type + Private ReadOnly PluginConstructorArguments As Integer = 0 + Private ReadOnly PluginConstructor As ConstructorInfo = Nothing + Friend ReadOnly Property [Default] As SettingsHost + Get + Return Hosts(0) + End Get + End Property +#End Region +#Region "Initializer" + Friend Sub New(ByVal Plugin As Type, ByRef _XML As XmlFile, ByVal GlobalPath As SFile, + ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean)) + PluginType = Plugin + With Plugin.GetTypeInfo.DeclaredConstructors + If .ListExists Then + With .Where(Function(m) If(m.GetParameters?.Count, 0).ValueBetween(0, 2)) + If .ListExists Then + PluginConstructorArguments = .Max(Of Integer)(Function(m) If(m.GetParameters?.Count, 0)) + PluginConstructor = .First(Function(m) If(m.GetParameters?.Count, 0) = PluginConstructorArguments) + Else + PluginConstructorArguments = -1 + End If + End With + Else + PluginConstructorArguments = -1 + End If + End With + HostsUnavailableIndexes = New List(Of Integer) + Hosts = New List(Of SettingsHost) From {New SettingsHost(CreateInstance(), True, _XML, GlobalPath, _Temp, _Imgs, _Vids)} + HostsXml = New List(Of XmlFile) + Dim hostFiles As List(Of SFile) = SFile.GetFiles(SettingsFolderName.CSFileP, $"{String.Format(FileNamePattern, Key, Name)}*.xml",, EDP.ReturnValue) + If hostFiles.ListExists Then + For Each f As SFile In hostFiles + HostsXml.Add(New XmlFile(f) With {.AutoUpdateFile = True}) + Hosts.Add(New SettingsHost(CreateInstance(HostsXml.Last.Value({SettingsCLS.Name_Node_Sites, [Default].Name}, SettingsHost.NameXML_AccountName)), False, HostsXml.Last, + GlobalPath, _Temp, _Imgs, _Vids)) + Next + End If + Hosts.ListReindex + Hosts.ForEach(Sub(h) SetHostHandlers(h)) + End Sub +#End Region +#Region "CreateInstance" + Private Function CreateInstance(Optional ByVal Name As String = Nothing, Optional ByVal Abstract As Boolean = False) As ISiteSettings + Select Case PluginConstructorArguments + Case 2 : Return PluginConstructor.Invoke({Name, Abstract}) + Case 1 : Return PluginConstructor.Invoke({Name}) + Case 0 : Return PluginConstructor.Invoke(Nothing) + Case Else : Return Activator.CreateInstance(PluginType) + End Select + End Function +#End Region +#Region "ToString" + Public Overrides Function ToString() As String + Return Name + End Function +#End Region +#Region "Host handlers" + Private Sub SetHostHandlers(ByVal Host As SettingsHost) + AddHandler Host.OkClick, AddressOf Hosts_OkClick + AddHandler Host.Deleted, AddressOf Hosts_Deleted + AddHandler Host.CloneClick, AddressOf Hosts_CloneClick + If Host.Index > 0 Then Host.Source.DefaultInstance = [Default].Source + End Sub + Private Sub Hosts_OkClick(ByVal Obj As SettingsHost) + If Obj.Index = -1 Then + HostsXml.Add(New XmlFile($"{SettingsFolderName}\{String.Format(FileNamePatternFull, Key, Name, Obj.AccountName)}.xml") With {.AutoUpdateFile = True}) + With Settings : Hosts.Add(Obj.Apply(HostsXml.Last, .GlobalPath, + .DefaultTemporary, .DefaultDownloadImages, .DefaultDownloadVideos)) : End With + HostsXml.Last.UpdateData() + Obj.Dispose() + Hosts.ListReindex + SetHostHandlers(Hosts.Last) + UpdateSettingsButton() + End If + End Sub + Private Sub Hosts_CloneClick(ByVal Obj As SettingsHost) + Try + Using host As SettingsHost = Obj.Clone : SetHostHandlers(host) : host.SettingsPerformClick() : End Using + Catch ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, ex, "[SettingsHostCollection.HostClone]") + End Try + End Sub + Private Const ChngUACC_MsgTitle As String = "Changing user accounts" + Private Sub Hosts_Deleted(ByVal Obj As SettingsHost) + Try + If Obj.Index > 0 Then + Select Case Hosts_Deleted_MoveAcc(Obj) + Case -1 : ShowOperationCanceledMsg(ChngUACC_MsgTitle) : Exit Sub + Case 1 + MainFrameObj.UpdateLogButton() + MsgBoxE({$"An error occurred while changing user accounts (see log for details).{vbCr}Operation canceled.", ChngUACC_MsgTitle}, vbCritical) + Exit Sub + End Select + With HostsXml(Obj.Index - 1) + .File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None) + .Dispose() + End With + HostsXml.RemoveAt(Obj.Index - 1) + Hosts.RemoveAt(Obj.Index) + Hosts.ListReindex + Obj.Source.Delete() + Obj.Dispose() + UpdateSettingsButton() + End If + Catch ex As Exception + ErrorsDescriber.Execute(EDP.SendToLog, ex, $"Deleting an account '{Obj.AccountName}'") + End Try + End Sub + ''' + ''' -1 - cancel; + ''' 0 - process; + ''' 1 - error + ''' + Private Function Hosts_Deleted_MoveAcc(ByVal Obj As SettingsHost) As Integer + Const np% = -100 + Dim p As PauseModes = np + Dim changedUsers As New List(Of String) + Try + With Settings + p = .Automation.Pause + If .UsersList.Count > 0 Then + Dim users As New List(Of UserInfo) + users.ListAddList(.UsersList.Where(Function(u) u.Plugin = Key And u.AccountName = Obj.AccountName)) + If users.ListExists Then + .Automation.Pause = PauseModes.Unlimited + Dim m As New MMessage($"There are {users.Count} user profiles using this ({Obj.AccountName}) account.", ChngUACC_MsgTitle,, vbExclamation) With {.Editable = True} + Dim b As New List(Of MsgBoxButton) + If Count - 1 = 1 Then + m.Text.StringAppendLine("Change their account to the default account?") + b.Add(New MsgBoxButton("Change") With {.CallBackObject = 1}) + Else + m.Text.StringAppendLine("Change their account?") + b.Add(New MsgBoxButton("Default", "Change their account to the default account.") With {.CallBackObject = 1}) + b.Add(New MsgBoxButton("Select", "Select an account for these users. A selection form will open.") With {.CallBackObject = 2}) + End If + m.Text &= vbCr & vbCr + m.Text &= users.ListToStringE(vbCr, New CustomProvider(Function(u As UserInfo) u.Name)) + b.Add(New MsgBoxButton("Leave", "Leave the existing account as is") With {.CallBackObject = 3}) + b.Add(New MsgBoxButton("Cancel", "Cancel operation") With {.CallBackObject = 4}) + If b.Count = 4 Then m.ButtonsPerRow = 2 + m.Buttons = b + Dim selectedAcc% = -1 + Select Case CInt(m.Show.Button.CallBackObject) + Case 1 : selectedAcc = 0 + Case 2 + Using f As New SimpleListForm(Of String)(Hosts.Select(Function(h) h.AccountName. + IfNullOrEmpty(SettingsHost.NameAccountNameDefault)), + .Design) With { + .DesignXMLNodeName = "AccountsChooserForm", + .Mode = SimpleListFormModes.SelectedItems, + .MultiSelect = False, + .Icon = [Default].Source.Icon, + .FormText = "Select profile" + } + f.DataSelectedIndexes.Add(0) + If f.ShowDialog = DialogResult.OK Then selectedAcc = f.DataResultIndexes.FirstOrDefault + End Using + If selectedAcc = -1 OrElse selectedAcc = Obj.Index OrElse + MsgBoxE({$"Are you sure you want to change user accounts to {Hosts(selectedAcc).AccountName. + IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}?", ChngUACC_MsgTitle}, + vbQuestion,,, {"Confirm", "Cancel"}) = 1 Then Return -1 + Case 3 : Return 0 + Case 4 : Return -1 + End Select + + If selectedAcc >= 0 Then + Dim tUser As UserInfo + Dim tUserIndx% + Dim tUserBase As UserDataBase + Dim samePath As Boolean = Obj.Path(False) = Hosts(selectedAcc).Path(False) + Dim processUserPath As Boolean + For Each tUser In users + tUserIndx = .UsersList.IndexOf(tUser) + If tUserIndx = -1 Then + Throw New KeyNotFoundException("User not found in the collection") + Else + tUserBase = .GetUser(tUser) + With tUser + If Not samePath AndAlso .SpecialPath.IsEmptyString AndAlso .SpecialCollectionPath.IsEmptyString Then + processUserPath = False + If .IncludedInCollection Then + If Not .IsVirtual Then + .SpecialCollectionPath = .GetCollectionRootPath + Else + processUserPath = True + End If + End If + If Not .IncludedInCollection Or processUserPath Then .SpecialPath = .File.CutPath.PathWithSeparator + End If + End With + tUser.AccountName = Hosts(selectedAcc).AccountName + tUser.UpdateUserFile() + .UsersList(tUserIndx) = tUser + tUserBase.AccountName = String.Empty + tUserBase.User = tUser + tUserBase.UpdateUserInformation() + changedUsers.Add(tUserBase.ToStringForLog) + End If + Next + .UpdateUsersList() + End If + Else + p = np + End If + Else + p = np + End If + End With + Return 0 + Catch ex As Exception + Dim msg$ = $"Changing user accounts when deleting a profile ({Obj.AccountName})." + If changedUsers.Count > 0 Then + msg.StringAppendLine($"The following users' accounts have been changed{vbCr}{changedUsers.ListToString(vbCr)}") + Settings.UpdateUsersList() + End If + Return ErrorsDescriber.Execute(EDP.SendToLog, ex, msg, 1) + Finally + If p <> np Then Settings.Automation.Pause = p + End Try + End Function +#End Region +#Region "Count, Item" + Friend ReadOnly Property Count As Integer Implements IMyEnumerator(Of SettingsHost).MyEnumeratorCount + Get + Return Hosts.Count + End Get + End Property + Friend ReadOnly Property CountUnavailable As Integer + Get + Return HostsUnavailableIndexes.Count + End Get + End Property + Default Friend Overloads ReadOnly Property Item(ByVal Index As Integer) As SettingsHost Implements IMyEnumerator(Of SettingsHost).MyEnumeratorObject + Get + Return Hosts(Index) + End Get + End Property + Default Friend Overloads ReadOnly Property Item(ByVal Name As String, Optional ByVal ReturnDef As Boolean = False) As SettingsHost + Get + Dim i% = IndexOf(Name) + If i >= 0 Then + Return Hosts(i) + ElseIf Settings.UseDefaultAccountIfMissing Or ReturnDef Then + Return [Default] + Else + Return Nothing + End If + End Get + End Property +#End Region +#Region "Forks" + Friend Function Available(ByVal What As Download, ByVal Silent As Boolean, Optional ByVal FillIndexes As Boolean = True, + Optional ByVal HostNames As IEnumerable(Of String) = Nothing, + Optional ByVal HostNamesPassed As Boolean = False) As Boolean + If FillIndexes Then HostsUnavailableIndexes.Clear() + If Count = 1 Then + If [Default].Available(What, Silent) Then + Return True + Else + If FillIndexes Then HostsUnavailableIndexes.Add(0) + Return False + End If + Else + Dim a As Boolean = False, n As Boolean = False + Dim t$ = String.Empty + Dim tExists As Boolean = False + Dim hnExists As Boolean = HostNames.ListExists + Dim singleHost As Boolean = hnExists AndAlso HostNames.Count = 1 + Dim m As New MMessage("", "Some of the hosts are unavailable",, vbExclamation) + For i% = 0 To Count - 1 + If Not hnExists OrElse HostNames.Contains(Hosts(i).AccountName) Then + If Hosts(i).Available(What, True) Then + a = True + Else + n = True + If Not Hosts(i).AvailableText.IsEmptyString Then + t &= vbCr + t.StringAppendLine($"{Name} - {Hosts(i).AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}:") + t.StringAppendLine(Hosts(i).AvailableText) + tExists = True + Else + t.StringAppendLine($"{Name} - {Hosts(i).AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}") + End If + If FillIndexes Then HostsUnavailableIndexes.Add(i) + End If + End If + Next + t = t.StringTrim + If singleHost Then + m.Text = "The host is unavailable." + Else + m.Text = "Some of the hosts are unavailable." + End If + If HostNamesPassed And Not hnExists Then Silent = True + If a And Not n Then + Return True + ElseIf Not a And n Then + If Not Silent And tExists Then m.Text &= $"{vbCr}{vbCr}{t}" : m.Show() + Return False + ElseIf Not t.IsEmptyString And tExists And Not Silent Then + m.Style(True) = m.Style + vbYesNo + m.Text &= $" Do you want to continue?{vbCr}{vbCr}{t}" + Return m.Show = vbYes + Else + Return True + End If + End If + End Function + Friend Function AvailablePartial(ByVal AccountName As String) As Boolean + Dim i% = IndexOf(AccountName) + Return i >= 0 AndAlso Not HostsUnavailableIndexes.Contains(i) + End Function + Friend Sub DownloadStarted(ByVal What As Download) + Hosts.ForEach(Sub(h) h.DownloadStarted(What)) + End Sub + Friend Sub DownloadDone(ByVal What As Download) + Hosts.ForEach(Sub(h) h.DownloadDone(What)) + HostsUnavailableIndexes.Clear() + End Sub + Friend Function IsMyUser(ByVal UserURL As String) As ExchangeOptions + Return [Default].IsMyUser(UserURL) + End Function + Friend Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions + Return [Default].IsMyImageVideo(URL) + End Function + Friend Function GetSingleMediaInstance(ByVal URL As String, ByVal OutputFile As SFile) As IYouTubeMediaContainer + Return [Default].GetSingleMediaInstance(URL, OutputFile) + End Function +#End Region +#Region "BeginUpdate, EndUpdate" + Friend Sub BeginUpdate() + Hosts.ForEach(Sub(h) h.Source.BeginUpdate()) + End Sub + Friend Sub EndUpdate() + Hosts.ForEach(Sub(h) h.Source.EndUpdate()) + End Sub +#End Region +#Region "CreateAbstract" + Friend Sub CreateAbstract() Handles BTT_SETTINGS_ACTIONS_ADD.Click + If Count = 1 AndAlso MsgBoxE({"Do you want to clone an existing one or create empty settings?", "New profile settings"}, + vbQuestion,,, {"Empty", "Clone"}) = 1 Then + Hosts_CloneClick([Default]) + Else + With Settings + Using host As New SettingsHost(CreateInstance(, True), .GlobalPath, .DefaultTemporary, .DefaultDownloadImages, .DefaultDownloadVideos) + SetHostHandlers(host) + host.SettingsPerformClick() + End Using + End With + End If + End Sub +#End Region +#Region "IndexOf" + Friend Function IndexOf(ByVal Name As String) As Integer + If Name.IsEmptyString OrElse Name = SettingsHost.NameAccountNameDefault Then + Return 0 + Else + Return Hosts.FindIndex(Function(h) h.AccountName = Name) + End If + End Function +#End Region +#Region "IEnumerable Support" + Private Function GetEnumerator() As IEnumerator(Of SettingsHost) Implements IEnumerable(Of SettingsHost).GetEnumerator + Return New MyEnumerator(Of SettingsHost)(Me) + End Function + Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator + Return GetEnumerator() + End Function +#End Region + End Class +End Namespace \ No newline at end of file diff --git a/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb b/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb index f051bdc..2400ffd 100644 --- a/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb +++ b/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb @@ -44,6 +44,7 @@ Namespace Plugin.Hosts Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken) With ExternalPlugin .Settings = HOST.Source + .AccountName = AccountName .Thrower = Me .LogProvider = LogConnector .Name = Name diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj index 9b7abb6..74b0486 100644 --- a/SCrawler/SCrawler.vbproj +++ b/SCrawler/SCrawler.vbproj @@ -187,13 +187,6 @@ - - - SettingsForm.vb - - - Form - @@ -357,6 +350,7 @@ + @@ -490,9 +484,6 @@ InternalSettingsForm.vb - - SettingsForm.vb - RedditViewSettingsForm.vb diff --git a/SCrawler/SettingsCLS.vb b/SCrawler/SettingsCLS.vb index 390862b..9bad20d 100644 --- a/SCrawler/SettingsCLS.vb +++ b/SCrawler/SettingsCLS.vb @@ -197,6 +197,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable UserSiteNameAsFriendly = New XMLValue(Of Boolean)("UserSiteNameAsFriendly", False, MyXML, n) UserSiteNameUpdateEveryTime = New XMLValue(Of Boolean)("UserSiteNameUpdateEveryTime", False, MyXML, n) CMDEncoding = New XMLValue(Of Integer)("CMDEncoding", DefaultCmdEncoding, MyXML, n) + UseDefaultAccountIfMissing = New XMLValue(Of Boolean)("UseDefaultAccountIfMissing", True, MyXML, n) Plugins.AddRange(PluginHost.GetMyHosts(MyXML, GlobalPath.Value, DefaultTemporary, DefaultDownloadImages, DefaultDownloadVideos)) Dim tmpPluginList As IEnumerable(Of PluginHost) = PluginHost.GetPluginsHosts(MyXML, GlobalPath.Value, DefaultTemporary, @@ -686,21 +687,27 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable Friend Sub BeginUpdate() MyXML.BeginUpdate() _UpdatesSuspended = True - If Plugins.Count > 0 Then Plugins.ForEach(Sub(p) p.Settings.Source.BeginUpdate()) + If Plugins.Count > 0 Then Plugins.ForEach(Sub(p) p.Settings.BeginUpdate()) End Sub Friend Sub EndUpdate() - If Plugins.Count > 0 Then Plugins.ForEach(Sub(p) p.Settings.Source.EndUpdate()) + If Plugins.Count > 0 Then Plugins.ForEach(Sub(p) p.Settings.EndUpdate()) MyXML.EndUpdate() If MyXML.ChangesDetected Then MyXML.UpdateData() _UpdatesSuspended = False ChangeDateProvider(Nothing, Nothing) End Sub - Default Friend ReadOnly Property Site(ByVal PluginKey As String) As SettingsHost + Default Friend Overloads ReadOnly Property Site(ByVal PluginKey As String) As SettingsHostCollection Get Dim i% = Plugins.FindIndex(Function(p) p.Key = PluginKey) If i >= 0 Then Return Plugins(i).Settings Else Return Nothing End Get End Property + Default Friend Overloads ReadOnly Property Site(ByVal PluginKey As String, ByVal AccountName As String) As SettingsHost + Get + Dim i% = Plugins.FindIndex(Function(p) p.Key = PluginKey) + If i >= 0 Then Return Plugins(i).Settings(AccountName) Else Return Nothing + End Get + End Property Friend ReadOnly Property GlobalPath As XMLValue(Of SFile) Friend ReadOnly Property LastCopyPath As XMLValue(Of SFile) Friend ReadOnly Property SeparateVideoFolder As XMLValue(Of Boolean) @@ -734,6 +741,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable Friend ReadOnly Property UserSiteNameAsFriendly As XMLValue(Of Boolean) Friend ReadOnly Property UserSiteNameUpdateEveryTime As XMLValue(Of Boolean) Friend ReadOnly Property CMDEncoding As XMLValue(Of Integer) + Friend ReadOnly Property UseDefaultAccountIfMissing As XMLValue(Of Boolean) #End Region #Region "STDownloader" Friend ReadOnly Property STDownloader_UpdateYouTubeOutputPath As XMLValue(Of Boolean) diff --git a/SCrawler/UserFinder.vb b/SCrawler/UserFinder.vb index 8eac2f2..2e2dc5d 100644 --- a/SCrawler/UserFinder.vb +++ b/SCrawler/UserFinder.vb @@ -58,7 +58,7 @@ Friend Class UserFinder : Implements IDisposable If OriginalLocations Then Paths.Clear() PathStr = String.Empty - Paths.ListAddList(Settings.Plugins.Select(Function(p) p.Settings.Path), LAP.NotContainsOnly) + Paths.ListAddList(Settings.Plugins.SelectMany(Function(p) p.Settings.Select(Function(pp) pp.Path)), LAP.NotContainsOnly) Paths.ListAddValue(Settings.CollectionsPathF, LAP.NotContainsOnly) PathStr = vbCr & Paths.ListToString(vbCr) End If @@ -78,6 +78,7 @@ Friend Class UserFinder : Implements IDisposable .Name = x.Value(UserDataBase.Name_UserName), .Site = x.Value(UserInfo.Name_Site), .Plugin = x.Value(UserInfo.Name_Plugin), + .AccountName = x.Value(UserInfo.Name_AccountName), .File = f, .SpecialPath = x.Value(UserInfo.Name_SpecialPath), .SpecialCollectionPath = x.Value(UserInfo.Name_SpecialCollectionPath), @@ -115,9 +116,9 @@ Friend Class UserFinder : Implements IDisposable s = Nothing If u.Plugin.IsEmptyString Then pIndx = Settings.Plugins.FindIndex(Function(pp) pp.Name.ToLower = u.Site.ToLower) - If pIndx >= 0 Then s = Settings.Plugins(pIndx).Settings + If pIndx >= 0 Then s = Settings.Plugins(pIndx).Settings.Default Else - s = Settings(u.Plugin) + s = Settings(u.Plugin).Default End If If Not s Is Nothing Then u.Plugin = s.Key diff --git a/SCrawler/UserInfo.vb b/SCrawler/UserInfo.vb index 223daaa..71e34b6 100644 --- a/SCrawler/UserInfo.vb +++ b/SCrawler/UserInfo.vb @@ -17,6 +17,7 @@ Partial Friend Module MainMod Friend Const Name_UserNode As String = "User" Friend Const Name_Site As String = "Site" Friend Const Name_Plugin As String = "Plugin" + Friend Const Name_AccountName As String = "AccountName" Friend Const Name_IsSubscription As String = "IsSubscription" Friend Const Name_Collection As String = "Collection" Friend Const Name_Model_User As String = "ModelUser" @@ -30,6 +31,7 @@ Partial Friend Module MainMod Friend Name As String Friend Site As String Friend Plugin As String + Friend AccountName As String Friend File As SFile Friend IsSubscription As Boolean Friend SpecialPath As SFile @@ -67,6 +69,7 @@ Partial Friend Module MainMod Name = x.Value Site = x.Attribute(Name_Site).Value Plugin = x.Attribute(Name_Plugin).Value + AccountName = x.Attribute(Name_AccountName).Value IsSubscription = x.Attribute(Name_IsSubscription).Value.FromXML(Of Boolean)(False) CollectionName = x.Attribute(Name_Collection).Value CollectionModel = x.Attribute(Name_Model_Collection).Value.FromXML(Of Integer)(UsageModel.Default) @@ -81,6 +84,7 @@ Partial Friend Module MainMod Name = c.Name Site = Reddit.RedditSite Plugin = Reddit.RedditSiteKey + AccountName = c.RedditAccount File = c.File End Sub Public Shared Widening Operator CType(ByVal x As EContainer) As UserInfo @@ -125,13 +129,11 @@ Partial Friend Module MainMod Private Function GetFilePathByParams() As String If [Protected] Then Return String.Empty If IsSubscription Then - If Not Settings(Plugin) Is Nothing Then - Return $"{Application.StartupPath.CSFilePSN}\{SettingsFolderName}\Subscriptions\{Settings(Plugin).Key}\{Name}\{SettingsFolderName}" - Else - Return String.Empty - End If + If Not Settings(Plugin) Is Nothing Then _ + Return $"{Application.StartupPath.CSFilePSN}\{SettingsFolderName}\Subscriptions\{Settings(Plugin).Key}\{Name}\{SettingsFolderName}" Else Dim ColPath$ = GetCollectionRootPath().PathNoSeparator + Dim pluginSettings As SettingsHost If Not SpecialPath.IsEmptyString Then Return $"{SpecialPath.PathWithSeparator}{SettingsFolderName}" ElseIf Merged And IncludedInCollection Then @@ -140,20 +142,26 @@ Partial Friend Module MainMod If IncludedInCollection And Not IsVirtual Then Return $"{String.Format(CollectionUserPathPattern, ColPath, Site, Name)}{SettingsFolderName}" ElseIf Not Settings(Plugin) Is Nothing Then - Return $"{Settings(Plugin).Path.PathNoSeparator}\{Name}\{SettingsFolderName}" + pluginSettings = Settings(Plugin)(AccountName) + If Not pluginSettings Is Nothing Then Return $"{pluginSettings.Path.PathNoSeparator}\{Name}\{SettingsFolderName}" Else Dim s$ = Site.ToLower Dim i% = Settings.Plugins.FindIndex(Function(p) p.Name.ToLower = s) - If i >= 0 Then Return $"{Settings.Plugins(i).Settings.Path.PathNoSeparator}\{Name}\{SettingsFolderName}" Else Return String.Empty + If i >= 0 Then + pluginSettings = Settings.Plugins(i).Settings(AccountName) + If Not pluginSettings Is Nothing Then Return $"{pluginSettings.Path.PathNoSeparator}\{Name}\{SettingsFolderName}" + End If End If End If End If + Return String.Empty End Function #End Region #Region "ToEContainer Support" Friend Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer Return New EContainer(Name_UserNode, Name, {New EAttribute(Name_Site, Site), New EAttribute(Name_Plugin, Plugin), + New EAttribute(Name_AccountName, AccountName), New EAttribute(Name_IsSubscription, IsSubscription.BoolToInteger), New EAttribute(Name_Collection, CollectionName), New EAttribute(Name_Model_User, CInt(UserModel)),