2023.8.6.0

Plugins.Attributes: add 'DependentFields' attribute
Plugins.IPluginContentProvider: add 'Options' and 'IsSubscription' properties
Plugins.ISiteSettings: add 'SubscriptionsAllowed' property
Plugins.ExchangeOptions: add 'Options' field
Plugins.Attributes.PropertyUpdater: replace 'Dependencies' with 'Arguments'

YT: add 'OutputPathAskForName' and 'OutputPathAutoAddPaths' properties; add the ability to store download locations; add 'DownloadLocation' and 'DownloadLocationsCollection' objects
YT.IDownloaderSettings: add 'OutputPathAskForName' and 'OutputPathAutoAddPaths' properties
YT.Downloader: fixed bug with re-saving elements when loading a video list; fixed bug when files were not deleted when clicking on the delete button; fixed a bug that caused the video to redownload; download job removes elements at wrong indexes; added skipping of downloaded elements in the job; fixed a bug, pending option did not change after download complete
YT.YouTubeMediaContainerBase: add '_MediaStateOnLoad' field and 'NeedToSave' function; update the 'Save' function to prevent saving a file when a download is complete and the file has already been saved; update code for new yt-dlp version

Fixed cache deletion errors
Add user queue
Add global locations
API.Base.SiteSettingsBase: implement 'SubscriptionsAllowed' property; remove request headers with null values on save; add '_AllowUserAgentUpdate' parameter
API.Base.Structures: add 'SiteModes' enum
API.Base.UserDataBase: add 'Erase' button; implement 'Options' and 'IsSubscription' properties; add 'SpecialLabels' property; update 'LVIKey'; update 'FitToAddParams' function; add 'EraseData' function; user colors; Not UserExists notification, UserQueue support
API.Base: add 'DeclaredNames'
API.Instagram: remove default values for headers; disable updating UserAgent from global; check for a new username for non-existent users
API.Mastodon: bypass new inherited twitter options; update names and headers
API.OnlyFans: make 'HH_BROWSER' property nullable; remove 'HH_BROWSER' from required; fix username bug (dots); handling of 504 and 429 errors; add 'DownloadHighlights' and 'DownloadChatMedia' options; add 'UserExchangeOptions'; fixed incorrect error handler
API.PathPlugin: fixed incorrect detection of path existence
API.Pinterest: add 'SpecialLabels'
API.PornHub: add new video regex; remove old regex; added 'DownloadUploaded', 'DownloadTagged', 'DownloadPrivate' and 'DownloadFavorite' properties to 'SiteSettings', 'UserData' and 'UserExchangeOptions'; update regex to define user; added downloading search queries; update 'GetUserUrl' function; hide unnecessary 'RegexFieldsTextBecameNullException' errors; add subscriptions
API.Reddit: add 'SpecialLabels'; add bearer token and its refresh interval; add OAuth; add additional options
API.RedGifs: add 'DependentFields' for 'Token'
API.ThisVid: add 'DownloadFavourite' option; add downloading search queries, tags, categories; add 'SpecialLabels'; add subscriptions; updating cookies issue
API.TikTok: rewrite algorithms
API.Twitter: add 'UseAppropriateModel', 'UseNewEndPointSearch', 'UseNewEndPointProfiles', 'AbortOnLimit', 'DownloadAlreadyParsed', 'MediaModelAllowNonUserTweets' properties; remove old commented code; remove 'TwitterPic_400' and replace with 'TwitterIcon_32.ToBitmap'; add 'DownloadModelForceApply' user option; update environment to GDL 1.25.8; fixed gifs downloading; fix typo in 'ReparseMissing'; update names
API.UserDataBind: prevent adding site-specific labels when adding to a collection
API.Xhamster: add downloading search queries, tags, categories; add 'SpecialLabels'; add additional nodes for channels; add subscriptions
API.XVIDEOS: add downloading search queries, tags, categories; add 'SpecialLabels'; add subscriptions; changed users creation method; add subscriptions
API.YouTube: add subscriptions
AutoDownloader: add new group subscription options; update predicates; fixed excluded labels and sites in default mode; update notifications; add an additional skip options, add 'Force start' option
DownloadedInfoForm: add subscriptions; fixed size/location bug; hide unnecessary error (refill)
Feed: add subscriptions; update filters; add 'Ctrl+G' shortcut
FeedMedia: add subscriptions; fixed 'webm' bug; add title for subscription media; add site icon to post; user colors; always using 'FriendlyName' instead of 'UserName' if it exists
DownloadGroup, GroupDefaults, GroupParameters: add subscription and 'UsersCount' options
MissingPostsForm: add 'BTT_DELETE_ALL'
VideoDownloaderForm, DownloaderUrlForm, DownloaderUrlsArrForm: add download locations support
VideoDownloaderForm: add subscriptions support
GlobalSettingsForm: add new properties
UserCreatorForm: add subscriptions; add 'Options' support (of 'ExchangeOptions'); user colors
ListImagesLoader: add subscription colors; user colors
MainFrame: add subscriptions; add filters by subscription and user; update predicates
NuGet: update 'LibVLCSharp', 'LibVLCSharp.WinForms', 'VideoLAN.LibVLC.Windows'
DownloadableMediaHost: update 'Save' function
PropertyValueHost: fix 'CaptionWidth' bug; add 'Dependents'
SettingsHost: add 'Dependents'
UserDataHost: add 'Options' and 'IsSubscription' properties
SettingsCLS: implement new 'IDownloaderSettings' properties; add 'CacheSnapshots'; add 'DownloadLocations'; add new properties
UserInfo, UserFinder: add subscriptions
UserSearchForm: fixed search by name bug
This commit is contained in:
Andy
2023-08-06 18:16:07 +03:00
parent bade8666d5
commit df06a86651
179 changed files with 9145 additions and 2041 deletions

View File

@@ -6,9 +6,12 @@
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Base
Friend Module Declarations
Friend Const UserLabelName As String = "User"
Friend Const SearchRequestLabelName As String = "Search request"
Friend ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly)
Friend ReadOnly UnixDate32Provider As New ADateTime(ADateTime.Formats.Unix32)
Friend ReadOnly UnixDate64Provider As New ADateTime(ADateTime.Formats.Unix64)
@@ -16,5 +19,58 @@ Namespace API.Base
Friend ReadOnly TitleHtmlConverter As Func(Of String, String) =
Function(Input) SymbolsConverter.HTML.Decode(SymbolsConverter.Convert(Input, EDP.ReturnValue), EDP.ReturnValue).
StringRemoveWinForbiddenSymbols().StringTrim()
Friend ReadOnly Regex_VideosThumb_OG_IMAGE As RParams = RParams.DMS("meta.property=.og.image..content=""([^""]+)""", 1, EDP.ReturnValue)
Friend Class ConcurrentDownloadsProvider : Inherits FieldsCheckerProviderBase
Public Overrides Sub Reset()
ErrorMessage = String.Empty
MyBase.Reset()
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
Dim v% = AConvert(Of Integer)(Value, -1)
Dim defV% = Settings.MaxUsersJobsCount
If v.ValueBetween(1, defV) Then
Return Value
Else
HasError = True
If ACheck(Of Integer)(Value) Then
ErrorMessage = $"The number of concurrent downloads must be greater than 0 and equal to or less than {defV} (global limit)."
Else
TypeError = True
End If
Return Nothing
End If
End Function
End Class
Friend Class TokenRefreshIntervalProvider : Inherits FieldsCheckerProviderBase
Public Overrides Sub Reset()
ErrorMessage = String.Empty
MyBase.Reset()
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
Dim v% = AConvert(Of Integer)(Value, -1)
If v > 0 Then
Return Value
ElseIf Not ACheck(Of Integer)(Value) Then
TypeError = True
Else
ErrorMessage = $"The value of [{Name}] field must be greater than or equal to 1"
End If
HasError = True
Return Nothing
End Function
End Class
Friend ReadOnly Property CacheDeletionError(ByVal RootPath As SFile) As ErrorsDescriber
Get
Return New ErrorsDescriber(EDP.None) With {.Action = Sub(ee, eex, msg, obj) Settings.Cache.AddPath(RootPath)}
End Get
End Property
Friend Function ValidateChangeSearchOptions(ByVal User As String, ByVal NewQuery As String, ByVal CurrentQuery As String) As Boolean
Return MsgBoxE({$"Are you sure you want to change the query for user '{User}'?{vbCr}" &
"It is highly recommended to add a new user with this query instead of changing current one." & vbCr &
$"Current query: [{CurrentQuery}]{vbCr}New query: [{NewQuery}]",
"Changing a query"}, vbExclamation,,, {"Process", "Cancel"}) = 0
End Function
End Module
End Namespace

View File

@@ -0,0 +1,31 @@
' 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.Base
Friend NotInheritable Class DeclaredNames
Friend Const Header_Authorization As String = "authorization"
Friend Const Header_CSRFToken As String = "x-csrf-token"
Friend Const ConcurrentDownloadsCaption As String = "Concurrent downloads"
Friend Const ConcurrentDownloadsToolTip As String = "The number of concurrent downloads."
Friend Const SavedPostsUserNameCaption As String = "Saved posts user"
Friend Const SavedPostsUserNameToolTip As String = "Personal profile username"
Friend Const GifsSpecialFolderCaption As String = "GIFs special folder"
Friend Const GifsSpecialFolderToolTip As String = "Put the GIFs in a special folder" & vbCr &
"This is a folder name, not an absolute path." & vbCr &
"This folder(s) will be created relative to the user's root folder." & vbCr &
"Examples:" & vbCr & "SomeFolderName" & vbCr & "SomeFolderName\SomeFolderName2"
Friend Const GifsPrefixCaption As String = "GIF prefix"
Friend Const GifsPrefixToolTip As String = "This prefix will be added to the beginning of the filename"
Friend Const GifsDownloadCaption As String = "Download GIFs"
Friend Const UseMD5ComparisonCaption As String = "Use MD5 comparison"
Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5"
Private Sub New()
End Sub
End Class
End Namespace

View File

@@ -66,12 +66,12 @@ Namespace API.Base.GDL
Return urls
End Function
End Module
Friend Class GDLBatch : Inherits BatchExecutor
Friend Class GDLBatch : Inherits TokenBatch
Friend Property TempPostsList As List(Of String)
Friend Const UrlLibStart As String = "[urllib3.connectionpool][debug]"
Friend Const UrlTextStart As String = UrlLibStart & " https"
Friend Sub New()
MyBase.New(True)
Friend Sub New(ByVal _Token As Threading.CancellationToken)
MyBase.New(_Token)
MainProcessName = "gallery-dl"
ChangeDirectory(Settings.GalleryDLFile.File)
End Sub
@@ -86,8 +86,9 @@ Namespace API.Base.GDL
End If
End Sub
Protected Overridable Async Function Validate(ByVal Value As String) As Task
If Not ProcessKilled AndAlso Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill()
If Not ProcessKilled AndAlso Await Task.Run(Of Boolean)(Function() Token.IsCancellationRequested OrElse
(Not Value.IsEmptyString AndAlso
TempPostsList.Exists(Function(v) Value.Contains(v)))) Then Kill()
End Function
End Class
End Namespace

View File

@@ -0,0 +1,88 @@
' 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.Threading
Imports SCrawler.Plugin.Hosts
Namespace API.Base
Friend Interface IUserData : Inherits IComparable(Of UserDataBase), IComparable, IEquatable(Of UserDataBase), IIndexable, IDisposable
Event UserUpdated(ByVal User As IUserData)
Enum EraseMode As Integer
None = 0
Data = 1
History = 2
End Enum
ReadOnly Property Site As String
ReadOnly Property Name As String
Property ID As String
Property Options As String
Property FriendlyName As String
Property Description As String
Property Favorite As Boolean
Property Temporary As Boolean
Property BackColor As Color?
Property ForeColor As Color?
Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing)
Sub DownloadData(ByVal Token As CancellationToken)
Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken)
Property ParseUserMediaOnly As Boolean
ReadOnly Property IsSubscription As Boolean
#Region "Images"
Function GetPicture() As Image
Sub SetPicture(ByVal f As SFile)
#End Region
#Region "Collection support"
ReadOnly Property IsCollection As Boolean
ReadOnly Property CollectionName As String
ReadOnly Property CollectionPath As SFile
ReadOnly Property IncludedInCollection As Boolean
ReadOnly Property UserModel As UsageModel
ReadOnly Property CollectionModel As UsageModel
ReadOnly Property IsVirtual As Boolean
ReadOnly Property Labels As List(Of String)
#End Region
Property Exists As Boolean
Property Suspended As Boolean
Property ReadyForDownload As Boolean
Property HOST As SettingsHost
Property [File] As SFile
Property FileExists As Boolean
Property DownloadedPictures(ByVal Total As Boolean) As Integer
Property DownloadedVideos(ByVal Total As Boolean) As Integer
ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
ReadOnly Property DownloadedInformation As String
Property HasError As Boolean
ReadOnly Property FitToAddParams As Boolean
ReadOnly Property Key As String
Property DownloadImages As Boolean
Property DownloadVideos As Boolean
Property DownloadMissingOnly As Boolean
Property ScriptUse As Boolean
Property ScriptData As String
Function GetLVI(ByVal Destination As ListView) As ListViewItem
Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup
Sub LoadUserInformation()
Sub UpdateUserInformation()
''' <summary>
''' 0 - Nothing removed<br/>
''' 1 - User removed<br/>
''' 2 - Collection removed<br/>
''' 3 - Collection split
''' </summary>
Function Delete(Optional ByVal Multiple As Boolean = False, Optional ByVal CollectionValue As Integer = -1) As Integer
Function EraseData(ByVal Mode As EraseMode) As Boolean
Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile) As Boolean
Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
Sub OpenFolder()
Property DownloadTopCount As Integer?
Property DownloadDateFrom As Date?
Property DownloadDateTo As Date?
Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
Optional ByVal AttachUserInfo As Boolean = True)
ReadOnly Property Disposed As Boolean
End Interface
End Namespace

View File

@@ -43,6 +43,7 @@ Namespace API.Base
If ConcatFile.Name.IsEmptyString Then ConcatFile.Name = "PlayListFile"
ConcatFile.Extension = "mp4"
Cache = New CacheKeeper($"{DestinationFile.PathWithSeparator}_{TempCacheFolderName}\")
Cache.CacheDeleteError = CacheDeletionError(Cache)
Dim cache2 As CacheKeeper = Cache.NewInstance
If cache2.RootDirectory.Exists(SFO.Path) Then
Dim progressExists As Boolean = Not Progress Is Nothing

View File

@@ -15,6 +15,13 @@ Namespace API.Base
Friend ReadOnly Property Site As String Implements ISiteSettings.Site
Friend Overridable ReadOnly Property Icon As Icon Implements ISiteSettings.Icon
Friend Overridable ReadOnly Property Image As Image Implements ISiteSettings.Image
Protected _AllowUserAgentUpdate As Boolean = True
Protected _SubscriptionsAllowed As Boolean = False
Friend ReadOnly Property SubscriptionsAllowed As Boolean Implements ISiteSettings.SubscriptionsAllowed
Get
Return _SubscriptionsAllowed
End Get
End Property
Private Property Logger As ILogProvider = LogConnector Implements ISiteSettings.Logger
Friend Overridable ReadOnly Property Responser As Responser
Friend ReadOnly Property CookiesNetscapeFile As SFile
@@ -62,7 +69,7 @@ Namespace API.Base
Friend Overridable Sub BeginInit() Implements ISiteSettings.BeginInit
End Sub
Friend Overridable Sub EndInit() Implements ISiteSettings.EndInit
If Not DefaultUserAgent.IsEmptyString And Not Responser Is Nothing Then Responser.UserAgent = DefaultUserAgent
If _AllowUserAgentUpdate And Not DefaultUserAgent.IsEmptyString And Not Responser Is Nothing Then Responser.UserAgent = DefaultUserAgent
If CheckNetscapeCookiesOnEndInit Then Update_SaveCookiesNetscape(, True)
End Sub
#End Region
@@ -82,6 +89,11 @@ Namespace API.Base
Friend Overridable Sub Update() Implements ISiteSettings.Update
If _SiteEditorFormOpened Then
If UseNetscapeCookies Then Update_SaveCookiesNetscape()
If Not Responser Is Nothing Then
With Responser.Headers
If .Count > 0 Then .ListDisposeRemove(Function(h) h.Value.IsEmptyString)
End With
End If
DomainsApply()
End If
If Not Responser Is Nothing Then Responser.SaveSettings()
@@ -105,12 +117,30 @@ Namespace API.Base
#End Region
#End Region
#Region "Before and After Download"
''' <summary>
''' PRE<br/>
''' DownloadStarted<br/>
''' <br/>
''' BEFORE<br/>
''' Available<br/>
''' <br/>
''' IN<br/>
''' ReadyToDownload<br/>
''' BeforeStartDownload<br/>
''' AfterDownload<br/>
''' <br/>
''' AFTER<br/>
''' DownloadDone
''' </summary>
Friend Overridable Sub DownloadStarted(ByVal What As Download) Implements ISiteSettings.DownloadStarted
End Sub
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download) Implements ISiteSettings.BeforeStartDownload
End Sub
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Sub AfterDownload(ByVal User As Object, ByVal What As Download) Implements ISiteSettings.AfterDownload
End Sub
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Sub DownloadDone(ByVal What As Download) Implements ISiteSettings.DownloadDone
End Sub
#End Region
@@ -158,13 +188,13 @@ Namespace API.Base
Friend Overridable Function BaseAuthExists() As Boolean
Return True
End Function
''' <summary>JOB: leave or remove</summary>
''' <returns>Return BaseAuthExists()</returns>
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean Implements ISiteSettings.Available
Return BaseAuthExists()
End Function
''' <summary>'DownloadData': before processing</summary>
''' <returns>True</returns>
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Function ReadyToDownload(ByVal What As Download) As Boolean Implements ISiteSettings.ReadyToDownload
Return True
End Function

View File

@@ -12,6 +12,13 @@ Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Base
Friend Module Structures
Friend Enum SiteModes As Integer
User = 0
Search = 1
Tags = 2
Categories = 3
Pornstars = 4
End Enum
Friend Structure UserMedia : Implements IUserMedia, IEquatable(Of UserMedia), IEContainerProvider
#Region "XML Names"
Friend Const Name_MediaNode As String = "MediaData"
@@ -182,6 +189,7 @@ Namespace API.Base
End With
End If
'TODO: UserMedia.SpecialFolder
SpecialFolder = e.Attribute(Name_SpecialFolder).Value
If Not SpecialFolder.IsEmptyString Then upath &= $"{SpecialFolder}\"
If vp.HasValue AndAlso vp.Value Then upath &= $"Video\"

View File

@@ -0,0 +1,27 @@
' 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.Threading
Imports PersonalUtilities.Tools
Namespace API.Base
Friend Class TokenBatch : Inherits BatchExecutor
Protected ReadOnly Token As CancellationToken
Friend Sub New(ByVal _Token As CancellationToken)
MyBase.New(True)
Token = _Token
End Sub
Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
MyBase.OutputDataReceiver(Sender, e)
Await Task.Run(Sub() If Token.IsCancellationRequested Then Kill())
End Sub
Protected Overrides Async Sub ErrorDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
MyBase.ErrorDataReceiver(Sender, e)
Await Task.Run(Sub() If Token.IsCancellationRequested Then Kill())
End Sub
End Class
End Namespace

View File

@@ -13,6 +13,7 @@ Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Hosts
Imports PersonalUtilities.Functions.Messaging
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Objects
Imports PersonalUtilities.Functions.RegularExpressions
@@ -51,6 +52,28 @@ Namespace API.Base
Friend Sub RemoveUpdateHandlers()
UserUpdatedEventHandlers.Clear()
End Sub
Private ReadOnly UserDownloadStateChangedEventHandlers As List(Of UserDownloadStateChangedEventHandler)
Friend Custom Event UserDownloadStateChanged As UserDownloadStateChangedEventHandler
AddHandler(ByVal h As UserDownloadStateChangedEventHandler)
If Not UserDownloadStateChangedEventHandlers.Contains(h) Then UserDownloadStateChangedEventHandlers.Add(h)
End AddHandler
RemoveHandler(ByVal h As UserDownloadStateChangedEventHandler)
UserDownloadStateChangedEventHandlers.Remove(h)
End RemoveHandler
RaiseEvent(ByVal User As IUserData, ByVal IsDownloading As Boolean)
Try
If UserDownloadStateChangedEventHandlers.Count > 0 Then
For i% = 0 To UserDownloadStateChangedEventHandlers.Count - 1
Try : UserDownloadStateChangedEventHandlers(i).Invoke(User, IsDownloading) : Catch : End Try
Next
End If
Catch
End Try
End RaiseEvent
End Event
Private Sub OnUserDownloadStateChanged(ByVal IsDownloading As Boolean)
RaiseEvent UserDownloadStateChanged(Me, IsDownloading)
End Sub
#End Region
#Region "Collection buttons"
Private _CollectionButtonsExists As Boolean = False
@@ -58,6 +81,7 @@ Namespace API.Base
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripKeyMenuItem
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_OPEN_PATH As ToolStripMenuItem
Friend WithEvents BTT_CONTEXT_OPEN_SITE As ToolStripMenuItem
Friend Sub CreateButtons()
@@ -75,6 +99,7 @@ Namespace API.Base
BTT_CONTEXT_DOWN = New ToolStripKeyMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = Me}
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = Me}
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = Me}
BTT_CONTEXT_ERASE = New ToolStripMenuItem(tn, i) With {.Name = tnn("ERASE"), .Tag = Me}
BTT_CONTEXT_OPEN_PATH = New ToolStripMenuItem(tn, i) With {.Name = tnn("PATH"), .Tag = Me}
BTT_CONTEXT_OPEN_SITE = New ToolStripMenuItem(tn, i) With {.Name = tnn("SITE"), .Tag = Me}
UpdateButtonsColor()
@@ -91,7 +116,8 @@ Namespace API.Base
cb = MyColor.EditBack
cf = MyColor.EditFore
End If
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_ERASE,
BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf
Next
If _UserInformationLoaded Then _CollectionButtonsColorsSet = True
@@ -111,12 +137,16 @@ Namespace API.Base
Private Const Name_UserExists As String = "UserExists"
Private Const Name_UserSuspended As String = "UserSuspended"
Protected Const Name_FriendlyName As String = "FriendlyName"
Private Const Name_UserSiteName As String = "UserSiteName"
Protected Const Name_UserSiteName As String = "UserSiteName"
Protected Const Name_UserID As String = "UserID"
Private Const Name_Description As String = "Description"
Protected Const Name_Options As String = "Options"
Protected Const Name_Description As String = "Description"
Private Const Name_ParseUserMediaOnly As String = "ParseUserMediaOnly"
Private Const Name_IsSubscription As String = UserInfo.Name_IsSubscription
Private Const Name_Temporary As String = "Temporary"
Private Const Name_Favorite As String = "Favorite"
Private Const Name_BackColor As String = "BackColor"
Private Const Name_ForeColor As String = "ForeColor"
Private Const Name_CreatedByChannel As String = "CreatedByChannel"
Private Const Name_SeparateVideoFolder As String = "SeparateVideoFolder"
@@ -142,7 +172,7 @@ Namespace API.Base
#Region "Declarations"
#Region "Host, Site, Progress"
Friend Property HOST As SettingsHost Implements IUserData.HOST
Friend ReadOnly Property Site As String Implements IContentProvider.Site
Friend ReadOnly Property Site As String Implements IUserData.Site
Get
Return HOST.Name
End Get
@@ -160,7 +190,7 @@ Namespace API.Base
End Property
Protected Property ProgressPre As PreProgress = Nothing
#End Region
#Region "User name, ID, exist, suspend"
#Region "User name, ID, exist, suspend, options"
Friend User As UserInfo
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
Private _UserExists As Boolean = True
@@ -190,14 +220,14 @@ Namespace API.Base
Set(ByVal NewName As String)
End Set
End Property
Friend Overridable ReadOnly Property Name As String Implements IContentProvider.Name
Friend Overridable ReadOnly Property Name As String Implements IUserData.Name
Get
Return User.Name
End Get
End Property
Friend Overridable Property ID As String = String.Empty Implements IContentProvider.ID, IPluginContentProvider.ID
Friend Overridable Property ID As String = String.Empty Implements IUserData.ID, IPluginContentProvider.ID
Protected _FriendlyName As String = String.Empty
Friend Overridable Property FriendlyName As String Implements IContentProvider.FriendlyName
Friend Overridable Property FriendlyName As String Implements IUserData.FriendlyName
Get
If Settings.UserSiteNameAsFriendly Then
Return _FriendlyName.IfNullOrEmpty(UserSiteName)
@@ -251,9 +281,15 @@ Namespace API.Base
Return UserModel = UsageModel.Virtual
End Get
End Property
Friend Property Options As String = String.Empty Implements IUserData.Options, IPluginContentProvider.Options
Friend Overridable ReadOnly Property FeedIsUser As Boolean
Get
Return True
End Get
End Property
#End Region
#Region "Description"
Friend Property UserDescription As String = String.Empty Implements IContentProvider.Description, IPluginContentProvider.UserDescription
Friend Property UserDescription As String = String.Empty Implements IUserData.Description, IPluginContentProvider.UserDescription
Protected _DescriptionEveryTime As Boolean = False
Protected _DescriptionChecked As Boolean = False
Protected Function UserDescriptionNeedToUpdate() As Boolean
@@ -270,9 +306,9 @@ Namespace API.Base
End If
End Sub
#End Region
#Region "Favorite, Temporary"
#Region "Favorite, Temporary, Colors"
Protected _Favorite As Boolean = False
Friend Overridable Property Favorite As Boolean Implements IContentProvider.Favorite
Friend Overridable Property Favorite As Boolean Implements IUserData.Favorite
Get
Return _Favorite
End Get
@@ -282,7 +318,7 @@ Namespace API.Base
End Set
End Property
Protected _Temporary As Boolean = False
Friend Overridable Property Temporary As Boolean Implements IContentProvider.Temporary
Friend Overridable Property Temporary As Boolean Implements IUserData.Temporary
Get
Return _Temporary
End Get
@@ -291,6 +327,24 @@ Namespace API.Base
If _Temporary Then _Favorite = False
End Set
End Property
Private _BackColor As Color? = Nothing
Friend Overridable Property BackColor As Color? Implements IUserData.BackColor
Get
Return _BackColor
End Get
Set(ByVal b As Color?)
_BackColor = b
End Set
End Property
Private _ForeColor As Color? = Nothing
Friend Overridable Property ForeColor As Color? Implements IUserData.ForeColor
Get
Return _ForeColor
End Get
Set(ByVal f As Color?)
_ForeColor = f
End Set
End Property
#End Region
#Region "Channel"
Friend Property CreatedByChannel As Boolean = False
@@ -405,32 +459,106 @@ BlockNullPicture:
Return _IsCollection
End Get
End Property
Friend Overridable Property CollectionName As String Implements IUserData.CollectionName
Friend Overridable ReadOnly Property CollectionName As String Implements IUserData.CollectionName
Get
Return User.CollectionName
End Get
Set(ByVal NewCollection As String)
ChangeCollectionName(NewCollection, True)
End Set
End Property
Friend Overridable ReadOnly Property CollectionPath As SFile Implements IUserData.CollectionPath
Get
Return User.GetCollectionRootPath
End Get
End Property
Friend ReadOnly Property IncludedInCollection As Boolean Implements IUserData.IncludedInCollection
Get
Return User.IncludedInCollection
End Get
End Property
Friend Overridable Sub ChangeCollectionName(ByVal NewName As String, ByVal UpdateSettings As Boolean)
Dim u As UserInfo = User
u.CollectionName = NewName
u.UpdateUserFile()
User = u
If UpdateSettings Then Settings.UpdateUsersList(User)
End Sub
Friend Overridable ReadOnly Property Labels As List(Of String) Implements IUserData.Labels
Protected ReadOnly Property LabelsString As String
Get
Return Labels.ListToString("|", EDP.ReturnValue)
End Get
End Property
Friend Overridable ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return New String() {}
End Get
End Property
''' <summary>
''' 0 add<br/>
''' 1 replace<br/>
''' 2 remove
''' </summary>
''' <returns>true = w/special</returns>
Friend Shared Function UpdateLabelsKeepSpecial(ByVal Mode As Byte) As Boolean
Dim m As New MMessage("", "Update labels",, vbQuestion + vbYesNo) With {.DefaultButton = 0, .CancelButton = 0}
Select Case Mode
Case 0 : m.Text = "Do you want to exclude site-specific labels from adding?"
Case 1, 2 : m.Text = "Do you want to keep site-specific labels?"
Case Else : Return False
End Select
Return m.Show = vbYes
End Function
''' <inheritdoc cref="UpdateLabelsKeepSpecial(Byte)"/>
Friend Shared Sub UpdateLabels(ByVal User As UserDataBase, ByVal NewLabels As IEnumerable(Of String), ByVal Mode As Byte, ByVal KeepSpecial As Boolean)
Try
If User.IsCollection Then
With DirectCast(User, UserDataBind)
If .Count > 0 Then .Collections.ForEach(Sub(u) UpdateLabels(u, NewLabels, Mode, KeepSpecial))
End With
Else
Dim nl As List(Of String)
If NewLabels.ListExists Then nl = NewLabels.ToList Else nl = New List(Of String)
Dim lex As List(Of String) = User.SpecialLabels.ToList
If lex.ListExists Then
If User.Labels.Count = 0 Or Not KeepSpecial Then
lex.Clear()
Else
lex.ListDisposeRemove(Function(l) Not User.Labels.Contains(l))
End If
End If
Select Case Mode
Case 0 'add
If KeepSpecial Then nl.ListAddList(lex, LNC)
User.Labels.ListAddList(nl, LNC)
Case 1 'replace
If KeepSpecial Then
nl.ListAddList(lex, LNC)
Else
nl.ListWithRemove(lex)
End If
User.Labels.Clear()
User.Labels.ListAddList(nl, LNC)
Case 2 'remove
If KeepSpecial Then nl.ListWithRemove(lex)
User.Labels.ListWithRemove(nl)
End Select
If User.Labels.Count > 0 Then User.Labels.Sort()
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[UserDataBase.UpdateLabels]")
End Try
End Sub
#End Region
#Region "Downloading"
Protected _DataLoaded As Boolean = False
Protected _DataParsed As Boolean = False
Friend Property ParseUserMediaOnly As Boolean = False Implements IUserData.ParseUserMediaOnly, IPluginContentProvider.ParseUserMediaOnly
Friend Overridable ReadOnly Property IsSubscription As Boolean Implements IUserData.IsSubscription
Get
Return User.IsSubscription
End Get
End Property
Private Property IPluginContentProvider_IsSubscription As Boolean Implements IPluginContentProvider.IsSubscription
Get
Return IsSubscription
End Get
Set : End Set
End Property
Friend Overridable Property ReadyForDownload As Boolean = True Implements IUserData.ReadyForDownload
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos
@@ -636,7 +764,7 @@ BlockNullPicture:
Friend ReadOnly Property LVIKey As String Implements IUserData.Key
Get
If Not _IsCollection Then
Return $"{Site.ToString.ToUpper}_{Name}"
Return $"{IIf(IsSubscription, "SSSS", String.Empty)}{Site.ToString.ToUpper}_{Name}"
Else
Return $"CCCC_{CollectionName}"
End If
@@ -652,6 +780,8 @@ BlockNullPicture:
Friend Overridable ReadOnly Property FitToAddParams As Boolean Implements IUserData.FitToAddParams
Get
With Settings
If IsSubscription And Not .MainFrameUsersShowSubscriptions Then Return False
If Not IsSubscription And Not .MainFrameUsersShowDefaults Then Return False
If LastUpdated.HasValue And Not .ViewDateMode.Value = ShowingDates.Off Then
Dim f As Date = If(.ViewDateFrom.HasValue, .ViewDateFrom.Value.Date, Date.MinValue.Date)
Dim t As Date = If(.ViewDateTo.HasValue, .ViewDateTo.Value.Date, Date.MaxValue.Date)
@@ -705,6 +835,7 @@ BlockNullPicture:
_TempPostsList = New List(Of String)
Labels = New List(Of String)
UserUpdatedEventHandlers = New List(Of IUserData.UserUpdatedEventHandler)
UserDownloadStateChangedEventHandlers = New List(Of UserDownloadStateChangedEventHandler)
If InvokeImageHandler Then MainFrameObj.ImageHandler(Me)
End Sub
Friend Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
@@ -753,12 +884,25 @@ BlockNullPicture:
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
ID = x.Value(Name_UserID)
Options = x.Value(Name_Options)
_FriendlyName = x.Value(Name_FriendlyName)
UserSiteName = x.Value(Name_UserSiteName)
UserDescription = x.Value(Name_Description)
ParseUserMediaOnly = x.Value(Name_ParseUserMediaOnly).FromXML(Of Boolean)(False)
Temporary = x.Value(Name_Temporary).FromXML(Of Boolean)(False)
Favorite = x.Value(Name_Favorite).FromXML(Of Boolean)(False)
If Not x.Value(Name_BackColor).IsEmptyString Then
BackColor = AConvert(Of Color)(x.Value(Name_BackColor), Nothing, EDP.ReturnValue)
Else
BackColor = Nothing
End If
If Not x.Value(Name_ForeColor).IsEmptyString Then
ForeColor = AConvert(Of Color)(x.Value(Name_ForeColor), Nothing, EDP.ReturnValue)
Else
ForeColor = Nothing
End If
CreatedByChannel = x.Value(Name_CreatedByChannel).FromXML(Of Boolean)(False)
SeparateVideoFolder = AConvert(Of Boolean)(x.Value(Name_SeparateVideoFolder), AModes.Var, Nothing)
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
@@ -771,7 +915,6 @@ BlockNullPicture:
ScriptUse = x.Value(Name_ScriptUse).FromXML(Of Boolean)(False)
ScriptData = x.Value(Name_ScriptData)
DataMerging = x.Value(Name_Merged).FromXML(Of Boolean)(False)
ChangeCollectionName(x.Value(Name_CollectionName), False)
Labels.ListAddList(x.Value(Name_LabelsName).StringToList(Of String, List(Of String))("|", EDP.ReturnValue), LAP.NotContainsOnly, LAP.ClearBeforeAdd)
LoadUserInformation_OptionalFields(x, True)
End Using
@@ -798,12 +941,18 @@ BlockNullPicture:
x.Add(Name_UserExists, UserExists.BoolToInteger)
x.Add(Name_UserSuspended, UserSuspended.BoolToInteger)
x.Add(Name_UserID, ID)
x.Add(Name_Options, Options)
x.Add(Name_FriendlyName, _FriendlyName)
x.Add(Name_UserSiteName, UserSiteName)
x.Add(Name_Description, UserDescription)
x.Add(Name_ParseUserMediaOnly, ParseUserMediaOnly.BoolToInteger)
x.Add(Name_IsSubscription, IsSubscription.BoolToInteger)
x.Add(Name_Temporary, Temporary.BoolToInteger)
x.Add(Name_Favorite, Favorite.BoolToInteger)
x.Add(Name_BackColor, CStr(AConvert(Of String)(BackColor, String.Empty, EDP.ReturnValue)))
x.Add(Name_ForeColor, CStr(AConvert(Of String)(ForeColor, String.Empty, EDP.ReturnValue)))
x.Add(Name_CreatedByChannel, CreatedByChannel.BoolToInteger)
If SeparateVideoFolder.HasValue Then
x.Add(Name_SeparateVideoFolder, SeparateVideoFolder.Value.BoolToInteger)
@@ -820,7 +969,7 @@ BlockNullPicture:
x.Add(Name_ScriptUse, ScriptUse.BoolToInteger)
x.Add(Name_ScriptData, ScriptData)
x.Add(Name_CollectionName, CollectionName)
x.Add(Name_LabelsName, Labels.ListToString("|", EDP.ReturnValue))
x.Add(Name_LabelsName, LabelsString)
x.Add(Name_Merged, DataMerging.BoolToInteger)
LoadUserInformation_OptionalFields(x, False)
@@ -867,7 +1016,7 @@ BlockNullPicture:
#End Region
#End Region
#Region "Open site, folder"
Friend Overridable Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing) Implements IContentProvider.OpenSite
Friend Overridable Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing) Implements IUserData.OpenSite
Try
Dim URL$ = HOST.Source.GetUserUrl(Me)
If Not URL.IsEmptyString Then Process.Start(URL)
@@ -927,6 +1076,13 @@ BlockNullPicture:
End Function
#End Region
#Region "Download functions and options"
Private __DOWNLOAD_IN_PROGRESS As Boolean = False
Friend ReadOnly Property DownloadInProgress As Boolean
Get
Return __DOWNLOAD_IN_PROGRESS
End Get
End Property
Friend PersonalToken As CancellationToken
Protected Responser As Responser
Protected UseResponserClient As Boolean = False
Protected UseClientTokens As Boolean = False
@@ -935,10 +1091,12 @@ BlockNullPicture:
Private _DownloadInProgress As Boolean = False
Private _EnvirUserExists As Boolean
Private _EnvirUserSuspended As Boolean
Private _EnvirCreatedByChannel As Boolean
Private _EnvirChanged As Boolean = False
Private _PictureExists As Boolean
Private _EnvirInvokeUserUpdated As Boolean = False
Protected Sub EnvirDownloadSet()
PersonalToken = Nothing
ProgressPre.Reset()
UpdateDataFiles()
_DownloadInProgress = True
@@ -948,6 +1106,7 @@ BlockNullPicture:
_ForceSaveUserInfo = False
_EnvirUserExists = UserExists
_EnvirUserSuspended = UserSuspended
_EnvirCreatedByChannel = CreatedByChannel
_EnvirChanged = False
_EnvirInvokeUserUpdated = False
UserExists = True
@@ -965,7 +1124,9 @@ BlockNullPicture:
End Select
End If
End Sub
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IUserData.DownloadData
__DOWNLOAD_IN_PROGRESS = True
OnUserDownloadStateChanged(True)
Dim Canceled As Boolean = False
_ExternalCompatibilityToken = Token
Try
@@ -981,14 +1142,14 @@ BlockNullPicture:
_TempMediaList.Clear()
_TempPostsList.Clear()
LatestData.Clear()
Dim __SaveData As Boolean = Not CreatedByChannel Or Not Settings.FromChannelDownloadTopUse
Dim __isChannelsSupport As Boolean = CreatedByChannel And Settings.FromChannelDownloadTopUse
LoadContentInformation()
If MyFilePosts.Exists Then _TempPostsList.ListAddList(File.ReadAllLines(MyFilePosts))
If _ContentList.Count > 0 Then _TempPostsList.ListAddList(_ContentList.Select(Function(u) u.Post.ID), LNC)
If Not DownloadMissingOnly Then
If Not DownloadMissingOnly Or IsSubscription Then
ThrowAny(Token)
DownloadDataF(Token)
ProgressPre.Done()
@@ -1010,22 +1171,37 @@ BlockNullPicture:
ProgressPre.Done()
ThrowAny(Token)
If UseMD5Comparison Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
If UseMD5Comparison And Not IsSubscription Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And Not __isChannelsSupport Then
If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd)
TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None)
End If
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
DownloadContent(Token)
ThrowIfDisposed()
If IncludeInTheFeed Then LatestData.ListAddList(_ContentNew.Where(_downContent), LNC)
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
If IsSubscription Then
_ContentNew.ListAddList(_ContentNew.ListForEachCopy(Function(ByVal tmpC As UserMedia, ByVal ii As Integer) As UserMedia
tmpC.State = UStates.Downloaded
If tmpC.Type = UTypes.Picture Or tmpC.Type = UTypes.GIF Then
DownloadedPictures(False) += 1
Else
DownloadedVideos(False) += 1
End If
Return tmpC
End Function))
Else
DownloadContent(Token)
ThrowIfDisposed()
End If
CreatedByChannel = False
If IncludeInTheFeed Or IsSubscription Then LatestData.ListAddList(_ContentNew.Where(_downContent), LNC)
Dim mcb& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0)
_ContentList.ListAddList(_ContentNew.Where(Function(c) _downContent(c) Or MissingFinder(c)), LNC)
Dim mca& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0)
If DownloadedTotal(False) > 0 Or _EnvirChanged Or Not mcb = mca Or _ForceSaveUserData Then
If __SaveData Then
If Not __isChannelsSupport Then
LastUpdated = Now
RunScript()
DownloadedPictures(True) = SFile.GetFiles(MyFile.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count
@@ -1040,20 +1216,30 @@ BlockNullPicture:
End If
UpdateUserInformation()
If _CollectionButtonsExists AndAlso _EnvirChanged Then UpdateButtonsColor()
ElseIf _ForceSaveUserInfo Then
ElseIf _ForceSaveUserInfo Or __isChannelsSupport Or Not _EnvirCreatedByChannel = CreatedByChannel Then
UpdateUserInformation()
End If
ThrowIfDisposed()
If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated()
Catch oex As OperationCanceledException When Token.IsCancellationRequested
Catch oex As OperationCanceledException When Token.IsCancellationRequested Or PersonalToken.IsCancellationRequested
MyMainLOG = $"{ToStringForLog()}: downloading canceled"
Canceled = True
Catch exit_ex As ExitException
If Not exit_ex.Silent Then
If exit_ex.SimpleLogLine Then
MyMainLOG = $"{ToStringForLog()}: downloading canceled (exit) ({exit_ex.Message})"
Else
ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{ToStringForLog()}: downloading canceled (exit)")
End If
End If
Canceled = True
Catch dex As ObjectDisposedException When Disposed
Canceled = True
Catch ex As Exception
LogError(ex, "downloading data error")
HasError = True
Finally
If Not UserExists Then MyMainLOG = $"User '{ToStringForLog()}' not found on the site"
If Not Responser Is Nothing Then Responser.Dispose() : Responser = Nothing
If Not Canceled Then _DataParsed = True
_ContentNew.Clear()
@@ -1065,6 +1251,8 @@ BlockNullPicture:
_ForceSaveUserData = False
_ForceSaveUserInfo = False
ProgressPre.Done()
__DOWNLOAD_IN_PROGRESS = False
OnUserDownloadStateChanged(False)
End Try
End Sub
Protected Sub UpdateDataFiles()
@@ -1087,6 +1275,13 @@ BlockNullPicture:
End If
End Sub
Protected MustOverride Sub DownloadDataF(ByVal Token As CancellationToken)
Protected Function CreateCache() As CacheKeeper
Dim Cache As New CacheKeeper($"{DownloadContentDefault_GetRootDir()}\_tCache\")
Cache.CacheDeleteError = CacheDeletionError(Cache)
If Cache.RootDirectory.Exists(SFO.Path, False) Then Cache.RootDirectory.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.ReturnValue)
Cache.Validate()
Return Cache
End Function
#Region "DownloadSingleObject"
Protected IsSingleObjectDownload As Boolean = False
Friend Overridable Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) Implements IUserData.DownloadSingleObject
@@ -1124,7 +1319,12 @@ BlockNullPicture:
DirectCast(Data, IDownloadableMedia).ThumbnailFile = _ContentNew(0).File
ElseIf Settings.STDownloader_TakeSnapshot And Settings.FfmpegFile.Exists And Not Settings.STDownloader_RemoveDownloadedAutomatically Then
Dim f As SFile = _ContentNew(0).File
Dim ff As SFile = f
Dim ff As SFile
If Settings.STDownloader_SnapshotsKeepWithFiles Then
ff = f
Else
ff = Settings.CacheSnapshots(Settings.STDownloader_SnapShotsCachePermamnent).NewFile
End If
ff.Name &= "_thumb"
ff.Extension = "jpg"
f = Web.FFMPEG.TakeSnapshot(f, ff, Settings.FfmpegFile, TimeSpan.FromSeconds(1),,, EDP.LogMessageValue)
@@ -1423,6 +1623,7 @@ BlockNullPicture:
If __isVideo Then fileNumProvider.FileName = f.Name : f = SFile.IndexReindex(f,,, fileNumProvider)
__interrupt = False
If IsSingleObjectDownload Then f.Exists(SFO.Path, True)
If v.Type = UTypes.m3u8 And UseInternalM3U8Function Then
f = DownloadM3U8(v.URL, v, f, Token)
If f.IsEmptyString Then Throw New Exception("M3U8 download failed")
@@ -1519,8 +1720,10 @@ BlockNullPicture:
Protected Function ProcessException(ByVal ex As Exception, ByVal Token As CancellationToken, ByVal Message As String,
Optional ByVal RDE As Boolean = True, Optional ByVal EObj As Object = Nothing,
Optional ByVal ThrowEx As Boolean = True) As Integer
If Not ((TypeOf ex Is OperationCanceledException And Token.IsCancellationRequested) Or
(TypeOf ex Is ObjectDisposedException And Disposed)) Then
If TypeOf ex Is ExitException Then
Throw ex
ElseIf Not ((TypeOf ex Is OperationCanceledException And (Token.IsCancellationRequested Or PersonalToken.IsCancellationRequested)) Or
(TypeOf ex Is ObjectDisposedException And Disposed)) Then
If RDE Then
Dim v% = DownloadingException(ex, Message, True, EObj)
If v = 0 Then LogError(ex, Message) : HasError = True
@@ -1579,7 +1782,67 @@ BlockNullPicture:
End Sub
#End Region
#End Region
#Region "Delete, Move, Merge, Copy"
#Region "Erase, Delete, Move, Merge, Copy"
Friend Shared Function GetEraseMode(ByVal Users As IEnumerable(Of IUserData)) As IUserData.EraseMode
Dim mode As IUserData.EraseMode = IUserData.EraseMode.None
If Users.ListExists Then
Dim m As New MMessage("The data of the following users will be erased:" & vbCr & vbCr, "Erase data",
{New MsgBoxButton("History and Data", "All files (images and videos) will be deleted; download history will be deleted."),
New MsgBoxButton("Data", "All files (images and videos) will be deleted; download history will not be affected."),
New MsgBoxButton("History", "All files (images and videos) will not be affected; download history will be deleted."),
New MsgBoxButton("Cancel")
}, MsgBoxStyle.Exclamation) With {.ButtonsPerRow = 4}
Dim collectionsCount% = Users.Count(Function(u) u.IsCollection)
m.Text &= Users.ListToStringE(vbNewLine, MainFrameObj.GetUserListProvider(collectionsCount > 0))
m.Text &= vbCr.StringDup(2)
If collectionsCount > 0 Then
If collectionsCount = 1 And Users.Count = 1 Then
m.Text &= $"THIS USER IS A COLLECTION OF {DirectCast(Users(0), UserDataBind).Count} USERS. THE DATA WILL BE ERASED FOR ALL OF THEM."
Else
m.Text &= "ONE OR MORE USERS IN THE LIST IS A COLLECTION. THE DATA WILL BE ERASED FOR EACH USER OF EACH COLLECTION."
End If
m.Text &= vbCr.StringDup(2)
End If
m.Text &= "Are you sure you want to erase the data?"
Select Case m.Show
Case 0 : mode = IUserData.EraseMode.Data + IUserData.EraseMode.History
Case 1 : mode = IUserData.EraseMode.Data
Case 2 : mode = IUserData.EraseMode.History
End Select
End If
Return mode
End Function
Friend Overridable Function EraseData(ByVal Mode As IUserData.EraseMode) As Boolean Implements IUserData.EraseData
Try
Dim result As Boolean = False
If Not Mode = IUserData.EraseMode.None And Not DataMerging Then
Dim m() As IUserData.EraseMode = Mode.EnumExtract(Of IUserData.EraseMode)
If m.ListExists Then
Dim e As New ErrorsDescriber(EDP.ReturnValue)
If m.Contains(IUserData.EraseMode.History) Then
If MyFilePosts.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
If MyFileData.Delete(SFO.File, SFODelete.DeleteToRecycleBin, e) Then result = True
If result Then
_TempPostsList.Clear()
_TempMediaList.Clear()
_ContentNew.Clear()
_ContentList.Clear()
End If
End If
If m.Contains(IUserData.EraseMode.Data) Then
Dim files As List(Of SFile) = SFile.GetFiles(DownloadContentDefault_GetRootDir.CSFileP,, SearchOption.AllDirectories, e)
If files.ListExists Then files.RemoveAll(Function(f) Not f.Extension.IsEmptyString AndAlso (f.Extension = "txt" Or f.Extension = "xml"))
If files.ListExists Then files.ForEach(Sub(f) f.Delete(SFO.File, Settings.DeleteMode, e))
LatestData.Clear()
result = True
End If
End If
End If
Return result
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"EraseData({CInt(Mode)}): {ToStringForLog()}", False)
End Try
End Function
Friend Overridable Function Delete(Optional ByVal Multiple As Boolean = False, Optional ByVal CollectionValue As Integer = -1) As Integer Implements IUserData.Delete
Dim f As SFile = SFile.GetPath(MyFile.CutPath.Path)
If f.Exists(SFO.Path, False) AndAlso (User.Merged OrElse f.Delete(SFO.Path, Settings.DeleteMode)) Then
@@ -1601,7 +1864,8 @@ BlockNullPicture:
Try
Dim f As SFile
Dim v As Boolean = IsVirtual
If IncludedInCollection Then
If IncludedInCollection And __CollectionName.IsEmptyString And __SpecialCollectionPath.IsEmptyString Then
Settings.Users.Add(Me)
Removed = False
User.CollectionName = String.Empty
@@ -1634,7 +1898,8 @@ BlockNullPicture:
f.Delete(SFO.Path, Settings.DeleteMode, EDP.ThrowException)
End If
f.CutPath.Exists(SFO.Path)
Directory.Move(UserBefore.File.CutPath(, EDP.ThrowException).Path, f.Path)
SFile.Move(UserBefore.File.CutPath(, EDP.ThrowException), f, SFO.Path,,
SFODelete.EmptyOnly + SFODelete.DeleteToRecycleBin + SFODelete.OnCancelThrowException, EDP.ThrowException)
If Not ScriptData.IsEmptyString AndAlso ScriptData.Contains(UserBefore.File.PathNoSeparator) Then _
ScriptData = ScriptData.Replace(UserBefore.File.PathNoSeparator, MyFile.PathNoSeparator)
End If
@@ -1772,10 +2037,11 @@ BlockNullPicture:
''' <exception cref="ObjectDisposedException"></exception>
Friend Overridable Overloads Sub ThrowAny(ByVal Token As CancellationToken)
Token.ThrowIfCancellationRequested()
PersonalToken.ThrowIfCancellationRequested()
ThrowIfDisposed()
End Sub
#End Region
Protected Function ToStringForLog() As String
Friend Function ToStringForLog() As String
Return $"{IIf(IncludedInCollection, $"[{CollectionName}] - ", String.Empty)}[{Site}] - {Name}"
End Function
Public Overrides Function ToString() As String
@@ -1807,6 +2073,21 @@ BlockNullPicture:
End Sub
Private Sub BTT_CONTEXT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DELETE.Click
End Sub
Private Sub BTT_CONTEXT_ERASE_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_ERASE.Click
Const msgTitle$ = "Erase data"
Try
Dim m As IUserData.EraseMode = GetEraseMode({Me})
If Not m = IUserData.EraseMode.None Then
If EraseData(m) Then
MsgBoxE({"User data has been erased.", msgTitle})
Else
MsgBoxE({"User data has not been erased.", msgTitle}, vbExclamation)
End If
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, msgTitle)
End Try
End Sub
Private Sub BTT_CONTEXT_OPEN_PATH_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_PATH.Click
OpenFolder()
End Sub
@@ -1858,6 +2139,7 @@ BlockNullPicture:
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
If Not BTT_CONTEXT_ERASE Is Nothing Then BTT_CONTEXT_ERASE.Dispose()
If Not BTT_CONTEXT_OPEN_PATH Is Nothing Then BTT_CONTEXT_OPEN_PATH.Dispose()
If Not BTT_CONTEXT_OPEN_SITE Is Nothing Then BTT_CONTEXT_OPEN_SITE.Dispose()
UserUpdatedEventHandlers.Clear()
@@ -1875,85 +2157,4 @@ BlockNullPicture:
End Sub
#End Region
End Class
#Region "Base interfaces"
Friend Interface IContentProvider
ReadOnly Property Site As String
ReadOnly Property Name As String
Property ID As String
Property FriendlyName As String
Property Description As String
Property Favorite As Boolean
Property Temporary As Boolean
Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing)
Sub DownloadData(ByVal Token As CancellationToken)
Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken)
End Interface
Friend Interface IUserData : Inherits IContentProvider, IComparable(Of UserDataBase), IComparable, IEquatable(Of UserDataBase), IIndexable, IDisposable
Event UserUpdated(ByVal User As IUserData)
Property ParseUserMediaOnly As Boolean
#Region "Images"
Function GetPicture() As Image
Sub SetPicture(ByVal f As SFile)
#End Region
#Region "Collection support"
ReadOnly Property IsCollection As Boolean
Property CollectionName As String
ReadOnly Property IncludedInCollection As Boolean
ReadOnly Property UserModel As UsageModel
ReadOnly Property CollectionModel As UsageModel
ReadOnly Property IsVirtual As Boolean
ReadOnly Property Labels As List(Of String)
#End Region
Property Exists As Boolean
Property Suspended As Boolean
Property ReadyForDownload As Boolean
Property HOST As SettingsHost
Property [File] As SFile
Property FileExists As Boolean
Property DownloadedPictures(ByVal Total As Boolean) As Integer
Property DownloadedVideos(ByVal Total As Boolean) As Integer
ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
ReadOnly Property DownloadedInformation As String
Property HasError As Boolean
ReadOnly Property FitToAddParams As Boolean
ReadOnly Property Key As String
Property DownloadImages As Boolean
Property DownloadVideos As Boolean
Property DownloadMissingOnly As Boolean
Property ScriptUse As Boolean
Property ScriptData As String
Function GetLVI(ByVal Destination As ListView) As ListViewItem
Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup
Sub LoadUserInformation()
Sub UpdateUserInformation()
''' <summary>
''' 0 - Nothing removed<br/>
''' 1 - User removed<br/>
''' 2 - Collection removed<br/>
''' 3 - Collection split
''' </summary>
Function Delete(Optional ByVal Multiple As Boolean = False, Optional ByVal CollectionValue As Integer = -1) As Integer
Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile) As Boolean
Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
Sub OpenFolder()
Property DownloadTopCount As Integer?
Property DownloadDateFrom As Date?
Property DownloadDateTo As Date?
Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
Optional ByVal AttachUserInfo As Boolean = True)
ReadOnly Property Disposed As Boolean
End Interface
Friend Interface IChannelLimits
Property AutoGetLimits As Boolean
Property DownloadLimitCount As Integer?
Property DownloadLimitPost As String
Property DownloadLimitDate As Date?
Overloads Sub SetLimit(Optional ByVal Post As String = "", Optional ByVal Count As Integer? = Nothing, Optional ByVal [Date] As Date? = Nothing)
Overloads Sub SetLimit(ByVal Source As IChannelLimits)
End Interface
Friend Interface IChannelData : Inherits IContentProvider, IChannelLimits
Property SkipExistsUsers As Boolean
Property SaveToCache As Boolean
End Interface
#End Region
End Namespace

View File

@@ -74,9 +74,9 @@ Namespace API.Instagram
Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
Friend Const Header_CSRF_TOKEN As String = "x-csrftoken"
Private Const Header_ASBD_ID As String = "X-Asbd-Id"
Private ReadOnly Header_Browser As New HttpHeader("Sec-Ch-Ua", """Google Chrome"";v=""113"", ""Chromium"";v=""113"", ""Not-A.Brand"";v=""24""")
Private ReadOnly Header_BrowserExt As New HttpHeader("Sec-Ch-Ua-Full-Version-List", """Google Chrome"";v=""113.0.5672.127"", ""Chromium"";v=""113.0.5672.127"", ""Not-A.Brand"";v=""24.0.0.0""")
Private ReadOnly Header_Platform As New HttpHeader("Sec-Ch-Ua-Platform-Version", """10.0.0""")
Private Const Header_Browser As String = "Sec-Ch-Ua"
Private Const Header_BrowserExt As String = "Sec-Ch-Ua-Full-Version-List"
Private Const Header_Platform As String = "Sec-Ch-Ua-Platform-Version"
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
Friend ReadOnly Property HashTagged As PropertyValue
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
@@ -108,9 +108,9 @@ Namespace API.Instagram
Case NameOf(HH_ASBD_ID) : f = Header_ASBD_ID
Case NameOf(HH_IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM
Case NameOf(HH_CSRF_TOKEN) : f = Header_CSRF_TOKEN
Case NameOf(HH_BROWSER) : f = Header_Browser.Name
Case NameOf(HH_BROWSER_EXT) : f = Header_BrowserExt.Name
Case NameOf(HH_PLATFORM) : f = Header_Platform.Name
Case NameOf(HH_BROWSER) : f = Header_Browser
Case NameOf(HH_BROWSER_EXT) : f = Header_BrowserExt
Case NameOf(HH_PLATFORM) : f = Header_Platform
Case NameOf(HH_USER_AGENT) : isUserAgent = True
End Select
If Not f.IsEmptyString Then
@@ -219,20 +219,6 @@ Namespace API.Instagram
Dim platform$ = String.Empty
Dim useragent$ = String.Empty
Dim __UpdateHeader As Action(Of HttpHeader, Boolean) = Sub(ByVal h As HttpHeader, ByVal UpdateValueIfEmpty As Boolean)
With Responser.Headers
Dim i% = .IndexOf(h)
Dim hh As HttpHeader
If i >= 0 Then
hh = .Item(i)
If hh.Value.IsEmptyString And UpdateValueIfEmpty Then hh.Value = h.Value
Else
hh = h
End If
.Add(hh)
End With
End Sub
With Responser
.Accept = "*/*"
useragent = .UserAgent
@@ -242,19 +228,13 @@ Namespace API.Instagram
app_id = .Value(Header_IG_APP_ID)
www_claim = .Value(Header_IG_WWW_CLAIM)
asbd = .Value(Header_ASBD_ID)
browser = .Value(Header_Browser.Name)
browserExt = .Value(Header_BrowserExt.Name)
platform = .Value(Header_Platform.Name)
browser = .Value(Header_Browser)
browserExt = .Value(Header_BrowserExt)
platform = .Value(Header_Platform)
End If
.Add("Dnt", 1)
__UpdateHeader(Header_Browser, browser.IsEmptyString)
browser = .Value(Header_Browser.Name)
__UpdateHeader(Header_BrowserExt, browserExt.IsEmptyString)
browserExt = .Value(Header_BrowserExt.Name)
.Add("Sec-Ch-Ua-Mobile", "?0")
.Add("Sec-Ch-Ua-Platform", """Windows""")
__UpdateHeader(Header_Platform, platform.IsEmptyString)
platform = .Value(Header_Platform.Name)
.Add("Sec-Fetch-Dest", "empty")
.Add("Sec-Fetch-Mode", "cors")
.Add("Sec-Fetch-Site", "same-origin")
@@ -301,6 +281,7 @@ Namespace API.Instagram
LastRequestsCountLabel = New PropertyValue(LastRequestsCountLabelStr.Invoke(LastRequestsCount.Value))
AddHandler LastRequestsCount.ValueChanged, Sub(sender, e) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(DirectCast(sender, XMLValue(Of Integer)).ValueF.Value)
_AllowUserAgentUpdate = False
UrlPatternUser = "https://www.instagram.com/{0}/"
UserRegex = RParams.DMS("[htps:/]{7,8}.*?instagram.com/([^/]+)", 1)
ImageVideoContains = "instagram.com"

View File

@@ -26,6 +26,7 @@ Namespace API.Instagram
Private Const Name_GetStories As String = "GetStories"
Private Const Name_GetTagged As String = "GetTaggedData"
Private Const Name_TaggedChecked As String = "TaggedChecked"
Private Const Name_NameTrue As String = "NameTrue"
#End Region
#Region "Declarations"
Private Structure PostKV : Implements IEContainerProvider
@@ -75,6 +76,13 @@ Namespace API.Instagram
Friend Property GetTimeline As Boolean = True
Friend Property GetStories As Boolean
Friend Property GetTaggedData As Boolean
Private _NameTrue As String = String.Empty
Private ReadOnly Property NameTrue As String
Get
Return _NameTrue.IfNullOrEmpty(Name)
End Get
End Property
Private UserNameRequested As Boolean = False
#End Region
#Region "Exchange options"
Friend Overrides Function ExchangeOptionsGet() As Object
@@ -96,21 +104,25 @@ Namespace API.Instagram
PostsToReparse = New List(Of PostKV)
End Sub
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
If Loading Then
LastCursor = Container.Value(Name_LastCursor)
FirstLoadingDone = Container.Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
GetTimeline = Container.Value(Name_GetTimeline).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline.Value))
GetStories = Container.Value(Name_GetStories).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories.Value))
GetTaggedData = Container.Value(Name_GetTagged).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged.Value))
TaggedChecked = Container.Value(Name_TaggedChecked).FromXML(Of Boolean)(False)
Else
Container.Add(Name_LastCursor, LastCursor)
Container.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
Container.Add(Name_GetTimeline, GetTimeline.BoolToInteger)
Container.Add(Name_GetStories, GetStories.BoolToInteger)
Container.Add(Name_GetTagged, GetTaggedData.BoolToInteger)
Container.Add(Name_TaggedChecked, TaggedChecked.BoolToInteger)
End If
With Container
If Loading Then
LastCursor = .Value(Name_LastCursor)
FirstLoadingDone = .Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
GetTimeline = .Value(Name_GetTimeline).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline.Value))
GetStories = .Value(Name_GetStories).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories.Value))
GetTaggedData = .Value(Name_GetTagged).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged.Value))
TaggedChecked = .Value(Name_TaggedChecked).FromXML(Of Boolean)(False)
_NameTrue = .Value(Name_NameTrue)
Else
.Add(Name_LastCursor, LastCursor)
.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
.Add(Name_GetTimeline, GetTimeline.BoolToInteger)
.Add(Name_GetStories, GetStories.BoolToInteger)
.Add(Name_GetTagged, GetTaggedData.BoolToInteger)
.Add(Name_TaggedChecked, TaggedChecked.BoolToInteger)
.Add(Name_NameTrue, _NameTrue)
End If
End With
End Sub
#End Region
#Region "Download data"
@@ -195,6 +207,7 @@ Namespace API.Instagram
End Function
Private _DownloadingInProgress As Boolean = False
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
UserNameRequested = False
Dim s As Sections = Sections.Timeline
Dim errorFound As Boolean = False
Try
@@ -413,13 +426,13 @@ Namespace API.Instagram
'Check environment
If Not IsSavedPosts Then
If ID.IsEmptyString Then GetUserId()
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
If ID.IsEmptyString Then Throw New Plugin.ExitException("can't get user ID")
End If
'Create query
Select Case Section
Case Sections.Timeline
URL = $"https://www.instagram.com/api/v1/feed/user/{Name}/username/?count=50" &
URL = $"https://www.instagram.com/api/v1/feed/user/{NameTrue}/username/?count=50" &
If(Cursor.IsEmptyString, String.Empty, $"&max_id={Cursor}")
ENode = Nothing
Case Sections.SavedPosts
@@ -766,16 +779,18 @@ Namespace API.Instagram
End Try
End Sub
#End Region
#Region "GetUserId"
#Region "GetUserId, GetUserName"
Private Sub GetUserId()
Dim __idFound As Boolean = False
Try
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/users/web_profile_info/?username={Name}",, EDP.ThrowException)
RequestsCount += 1
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/users/web_profile_info/?username={NameTrue}",, EDP.ThrowException)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If Not j Is Nothing AndAlso j.Contains({"data", "user"}) Then
With j({"data", "user"})
ID = .Value("id")
_ForceSaveUserData = True
__idFound = True
UserSiteNameUpdate(.Value("full_name"))
Dim descr$ = .Value("biography")
@@ -800,11 +815,43 @@ Namespace API.Instagram
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
Throw ex
Else
LogError(ex, "get Instagram user id")
LogError(ex, "get Instagram user ID")
End If
End If
End Try
End Sub
Private Function GetUserNameById() As Boolean
UserNameRequested = True
Try
If Not ID.IsEmptyString Then
RequestsCount += 1
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/users/{ID}/info/",, EDP.ReturnValue)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
If j.ListExists Then
Dim newName$ = j.Value({"user"}, "username")
If Not newName.IsEmptyString Then
Dim oldName$ = NameTrue
If Not newName = oldName Then
MyMainLOG = $"{ToStringForLog()}: username changed from '{oldName}' to '{newName}'"
_NameTrue = newName
Dim descr$ = $"Username changed from '{oldName}' to '{newName}' ({Now.ToStringDate(ADateTime.Formats.BaseDateTime)})!"
descr.StringAppendLine(UserDescription)
UserDescription = descr
_ForceSaveUserData = True
End If
Return True
End If
End If
End Using
End If
End If
Return False
Catch ex As Exception
LogError(ex, "get Instagram user name by ID")
Return False
End Try
End Function
#End Region
#Region "Pinned stories"
Private Sub GetStoriesData(ByRef StoriesList As List(Of String), ByVal Token As CancellationToken)
@@ -887,7 +934,7 @@ Namespace API.Instagram
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal s As Object = Nothing) As Integer
If Responser.StatusCode = HttpStatusCode.NotFound Then
UserExists = False
If Not UserNameRequested AndAlso GetUserNameById() Then Return 1 Else UserExists = False
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
HasError = True
MyMainLOG = $"Instagram credentials have expired [{CInt(Responser.StatusCode)}]: {ToStringForLog()} [{s}]"
@@ -906,7 +953,7 @@ Namespace API.Instagram
ElseIf Responser.StatusCode = 560 Then
MySiteSettings.SkipUntilNextSession = True
Else
MyMainLOG = $"Instagram hash requested [{CInt(Responser.StatusCode)}]: {ToString()} [{s}]"
MyMainLOG = $"Something is wrong. Your credentials may have expired [{CInt(Responser.StatusCode)}]: {ToString()} [{s}]"
DisableSection(s)
If Not FromPE Then LogError(ex, Message) : HasError = True
Return 0

View File

@@ -9,9 +9,11 @@
Imports SCrawler.Plugin.Attributes
Namespace API.Mastodon
Friend Class EditorExchangeOptions : Inherits Twitter.EditorExchangeOptions
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property MediaModelAllowNonUserTweets As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelMedia As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelProfile As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelSearch As Boolean
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadModelForceApply As Boolean
Friend Sub New(ByVal s As SiteSettings)
MyBase.New(s)
End Sub

View File

@@ -13,7 +13,7 @@ Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Documents.JSON
Imports TS = SCrawler.API.Twitter.SiteSettings
Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.Mastodon
<Manifest(MastodonSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
@@ -46,8 +46,8 @@ Namespace API.Mastodon
If Not PropName.IsEmptyString Then
Dim f$ = String.Empty
Select Case PropName
Case NameOf(Auth) : f = TS.Header_Authorization
Case NameOf(Token) : f = TS.Header_Token
Case NameOf(Auth) : f = DN.Header_Authorization
Case NameOf(Token) : f = DN.Header_CSRFToken
End Select
If Not f.IsEmptyString Then
Responser.Headers.Remove(f)
@@ -58,15 +58,15 @@ Namespace API.Mastodon
End Sub
#End Region
#Region "Other properties"
<PropertyOption(IsAuth:=False, ControlText:=TS.GifsDownload_Text), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsDownloadCaption), PXML>
Friend ReadOnly Property GifsDownload As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:=TS.GifsSpecialFolder_Text, ControlToolTip:=TS.GifsSpecialFolder_ToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML>
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:=TS.GifsPrefix_Text, ControlToolTip:=TS.GifsPrefix_ToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML>
Friend ReadOnly Property GifsPrefix As PropertyValue
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
Private ReadOnly Property GifStringChecker As IFormatProvider
<PropertyOption(IsAuth:=False, ControlText:=TS.UseMD5Comparison_Text, ControlToolTip:=TS.UseMD5Comparison_ToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML>
Friend ReadOnly Property UseMD5Comparison As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:="User related to my domain",
ControlToolTip:="Open user profiles and user posts through my domain."), PXML>
@@ -82,13 +82,13 @@ Namespace API.Mastodon
Domains.DestinationProp = SiteDomains
DomainsLastUpdateDate = New PropertyValue(Now.AddYears(-1))
Auth = New PropertyValue(Responser.Headers.Value(TS.Header_Authorization), GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
Token = New PropertyValue(Responser.Headers.Value(TS.Header_Token), GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
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))
GifsDownload = New PropertyValue(True)
GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
GifsPrefix = New PropertyValue("GIF_")
GifStringChecker = New TS.GifStringProvider
GifStringChecker = New API.Twitter.SiteSettings.GifStringProvider
UseMD5Comparison = New PropertyValue(False)
MyDomain = New PropertyValue(String.Empty, GetType(String))
UserRelatedToMyDomain = New PropertyValue(False)

View File

@@ -55,8 +55,8 @@ Namespace API.Mastodon
If setDef Then MyCredentials = New Credentials With {.Domain = UserDomain, .Bearer = MySettings.Auth.Value, .Csrf = MySettings.Token.Value}
End With
With MyCredentials
Responser.Headers.Add(Twitter.SiteSettings.Header_Authorization, .Bearer)
Responser.Headers.Add(Twitter.SiteSettings.Header_Token, .Csrf)
Responser.Headers.Add(DeclaredNames.Header_Authorization, .Bearer)
Responser.Headers.Add(DeclaredNames.Header_CSRFToken, .Csrf)
End With
End Sub
#End Region
@@ -274,7 +274,7 @@ Namespace API.Mastodon
ProcessException(ex, Token, $"ReparseMissing error [{URL}]")
Finally
If rList.Count > 0 Then
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
rList.Clear()
End If
End Try

View File

@@ -14,7 +14,7 @@ Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.OnlyFans
<Manifest("AndyProgram_OnlyFans"), SavedPosts, SeparatedTasks(1)>
<Manifest("AndyProgram_OnlyFans"), SavedPosts, SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Icon"
Friend Overrides ReadOnly Property Icon As Icon
@@ -29,6 +29,13 @@ Namespace API.OnlyFans
End Property
#End Region
#Region "Declarations"
#Region "Options"
<PropertyOption(ControlText:="Download highlights", ControlToolTip:="Download profile highlights if they exists"), PXML>
Friend Property DownloadHighlights As PropertyValue
<PropertyOption(ControlText:="Download chat", ControlToolTip:="Download unlocked chat media"), PXML>
Friend Property DownloadChatMedia As PropertyValue
#End Region
#Region "Headers"
Private Const HeaderBrowser As String = "sec-ch-ua"
Private Const HeaderUserID As String = "User-Id"
Private Const HeaderXBC As String = "X-Bc"
@@ -39,7 +46,7 @@ Namespace API.OnlyFans
Private ReadOnly Property HH_X_BC As PropertyValue
<PropertyOption(ControlText:=HeaderAppToken, AllowNull:=False)>
Private ReadOnly Property HH_APP_TOKEN As PropertyValue
<PropertyOption(ControlText:=HeaderBrowser, AllowNull:=False)>
<PropertyOption(ControlText:=HeaderBrowser, ControlToolTip:="Can be null", AllowNull:=True)>
Private ReadOnly Property HH_BROWSER As PropertyValue
<PropertyOption(AllowNull:=False)>
Private ReadOnly Property UserAgent As PropertyValue
@@ -59,6 +66,8 @@ Namespace API.OnlyFans
Responser.UserAgent = Value
End If
End Sub
#End Region
#Region "Rules"
<PXML("LastDateUpdated")> Private ReadOnly Property LastDateUpdated_XML As PropertyValue
Friend Property LastDateUpdated As Date
Get
@@ -81,6 +90,7 @@ Namespace API.OnlyFans
"Change this value only if you know what you are doing."), PXML>
Friend ReadOnly Property DynamicRules As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("OnlyFans", ".onlyfans.com")
@@ -110,13 +120,16 @@ Namespace API.OnlyFans
UserAgent = New PropertyValue(IIf(.UserAgentExists, .UserAgent, String.Empty), GetType(String), Sub(v) UpdateHeader(NameOf(UserAgent), v))
End With
DownloadHighlights = New PropertyValue(True)
DownloadChatMedia = New PropertyValue(True)
LastDateUpdated_XML = New PropertyValue(Now.AddYears(-1), GetType(Date))
UseOldAuthRules = New PropertyValue(False)
DynamicRulesUpdateInterval = New PropertyValue(60 * 24)
DynamicRulesUpdateIntervalProvider = New FieldsCheckerProviderSimple(Function(v) IIf(AConvert(Of Integer)(v, 0) > 0, v, Nothing),
"The value of [{0}] field must be greater than 0")
DynamicRules = New PropertyValue(String.Empty, GetType(String))
UserRegex = RParams.DMS("onlyfans.com/(\w+)", 1, EDP.ReturnValue)
UserRegex = RParams.DMS("onlyfans.com/([\w\._]+)", 1, EDP.ReturnValue)
UrlPatternUser = "https://onlyfans.com/{0}"
ImageVideoContains = "onlyfans.com"
End Sub
@@ -134,7 +147,7 @@ Namespace API.OnlyFans
#End Region
#Region "Download"
Friend Overrides Function BaseAuthExists() As Boolean
Return Responser.CookiesExists And {HH_USER_ID, HH_X_BC, HH_APP_TOKEN, HH_BROWSER, UserAgent}.All(Function(v) ACheck(v.Value))
Return Responser.CookiesExists And {HH_USER_ID, HH_X_BC, HH_APP_TOKEN, UserAgent}.All(Function(v) ACheck(v.Value))
End Function
Friend Overrides Function ReadyToDownload(ByVal What As ISiteSettings.Download) As Boolean
Return BaseAuthExists() And Not SessionAborted
@@ -149,17 +162,36 @@ Namespace API.OnlyFans
If Responser.Cookies.Changed Then Responser.SaveCookies() : Responser.Cookies.Changed = False
End Sub
#End Region
#Region "GetUserUrl, GetUserPostUrl"
#Region "GetUserUrl, GetUserPostUrl, UserOptions"
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
Return String.Format(UrlPatternUser, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}"))
End Function
Friend Overrides Function GetUserPostUrl(ByVal User As UserDataBase, ByVal Media As UserMedia) As String
If Not Media.Post.ID.IsEmptyString Then
Return String.Format("https://onlyfans.com/{0}/{1}", Media.Post.ID, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}"))
Dim post$() = Media.Post.ID.Split("_")
Dim p$ = String.Empty
If post.ListExists Then
If post(0) = UserData.A_MESSAGE Then
If Not User.ID.IsEmptyString Then Return $"https://onlyfans.com/my/chats/chat/{User.ID}/"
ElseIf Not post(0) = UserData.A_HIGHLIGHT Then
p = post(0)
End If
End If
If p.IsEmptyString Then
Return GetUserUrl(User)
Else
Return String.Format("https://onlyfans.com/{0}/{1}", p, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}"))
End If
Else
Return String.Empty
End If
End Function
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions(Me)
If OpenForm Then
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
#End Region
End Class
End Namespace

View File

@@ -19,26 +19,68 @@ Imports UTypes = SCrawler.API.Base.UserMedia.Types
Imports UStates = SCrawler.API.Base.UserMedia.States
Namespace API.OnlyFans
Friend Class UserData : Inherits UserDataBase
#Region "XML names"
Private Const Name_MediaDownloadHighlights As String = "DownloadHighlights"
Private Const Name_MediaDownloadChatMedia As String = "DownloadChatMedia"
#End Region
#Region "Declarations"
Friend Property CCookie As CookieKeeper = Nothing
Private Const HeaderSign As String = "Sign"
Private Const HeaderTime As String = "Time"
Private ReadOnly HighlightsList As List(Of String)
Friend Property MediaDownloadHighlights As Boolean = True
Friend Property MediaDownloadChatMedia As Boolean = True
Private ReadOnly Property MySettings As SiteSettings
Get
Return HOST.Source
End Get
End Property
#End Region
#Region "Load"
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
MediaDownloadHighlights = .Value(Name_MediaDownloadHighlights).FromXML(Of Boolean)(True)
MediaDownloadChatMedia = .Value(Name_MediaDownloadChatMedia).FromXML(Of Boolean)(True)
Else
.Add(Name_MediaDownloadHighlights, MediaDownloadHighlights.BoolToInteger)
.Add(Name_MediaDownloadChatMedia, MediaDownloadChatMedia.BoolToInteger)
End If
End With
End Sub
#End Region
#Region "Exchange"
Friend Overrides Function ExchangeOptionsGet() As Object
Return New UserExchangeOptions(Me)
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
With DirectCast(Obj, UserExchangeOptions)
MediaDownloadHighlights = .DownloadHighlights
MediaDownloadChatMedia = .DownloadChatMedia
End With
End If
End Sub
#End Region
#Region "Initializer"
Friend Sub New()
HighlightsList = New List(Of String)
End Sub
#End Region
#Region "Download functions"
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
If Not CCookie Is Nothing Then CCookie.Dispose()
CCookie = Responser.Cookies.Copy
Responser.Cookies.Clear()
AddHandler Responser.ResponseReceived, AddressOf OnResponseReceived
UpdateCookieHeader()
DownloadData(IIf(IsSavedPosts, 0, String.Empty), Token)
If Not MySettings.SessionAborted Then
If Not CCookie Is Nothing Then CCookie.Dispose()
CCookie = Responser.Cookies.Copy
Responser.Cookies.Clear()
AddHandler Responser.ResponseReceived, AddressOf OnResponseReceived
UpdateCookieHeader()
DownloadTimeline(IIf(IsSavedPosts, 0, String.Empty), Token)
If Not IsSavedPosts Then
If MediaDownloadHighlights Then DownloadHighlights(Token)
If MediaDownloadChatMedia Then DownloadChatMedia(0, Token)
End If
End If
End Sub
Private Sub OnResponseReceived(ByVal Sender As Object, ByVal e As WebDataResponse)
If e.CookiesExists Then
@@ -49,9 +91,11 @@ Namespace API.OnlyFans
Private Sub UpdateCookieHeader()
Responser.Headers.Add("Cookie", CCookie.ToString(False))
End Sub
Friend Const A_HIGHLIGHT As String = "HL"
Friend Const A_MESSAGE As String = "MSG"
Private Const BaseUrlPattern As String = "https://onlyfans.com{0}"
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
#Region "Download timeline"
Private Overloads Sub DownloadTimeline(ByVal Cursor As String, ByVal Token As CancellationToken)
Dim url$ = String.Empty
Dim _complete As Boolean = True
Do
@@ -122,15 +166,148 @@ Namespace API.OnlyFans
If hasMore Then
If IsSavedPosts Then tmpCursor = CInt(Cursor.IfNullOrEmpty(0)) + 10
DownloadData(tmpCursor, Token)
DownloadTimeline(tmpCursor, Token)
End If
Catch ex As Exception
If ProcessException(ex, Token, $"data downloading error [{url}]") = 2 Then _complete = False
_complete = Not ProcessException(ex, Token, $"data downloading error [{url}]") = 2
End Try
Loop While Not _complete
End Sub
#End Region
#Region "Download highlights"
Private Overloads Sub DownloadHighlights(ByVal Token As CancellationToken)
HighlightsList.Clear()
DownloadHighlights(0, Token)
If HighlightsList.Count > 0 Then HighlightsList.ForEach(Sub(hl) DownloadHighlightMedia(hl, Token))
End Sub
Private Overloads Sub DownloadHighlights(ByVal Cursor As Integer, ByVal Token As CancellationToken)
Dim url$ = String.Empty
Dim _complete As Boolean = True
Do
Try
Dim hasMore As Boolean = False
Dim path$ = $"/api2/v2/users/{ID}/stories/highlights?limit=5&offset={Cursor}"
If UpdateSignature(path) Then
url = String.Format(BaseUrlPattern, path)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(url)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
hasMore = j.Value("hasMore").FromXML(Of Boolean)(False)
With j("list")
If .ListExists Then
HighlightsList.AddRange(.Select(Function(e) e.Value("id")))
Else
hasMore = False
End If
End With
End If
End Using
End If
End If
If hasMore Then DownloadHighlights(Cursor + 5, Token)
Catch ex As Exception
_complete = Not ProcessException(ex, Token, $"highlights downloading error [{url}]") = 2
End Try
Loop While Not _complete
End Sub
Private Sub DownloadHighlightMedia(ByVal HLID As String, ByVal Token As CancellationToken)
Dim url$ = String.Empty
Dim _complete As Boolean = True
Do
Try
Dim specFolder$, postID$, postDate$
Dim media As List(Of UserMedia)
Dim result As Boolean
Dim path$ = $"/api2/v2/stories/highlights/{HLID}"
If UpdateSignature(path) Then
url = String.Format(BaseUrlPattern, path)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(url)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
specFolder = j.Value("title").StringRemoveWinForbiddenSymbols.IfNullOrEmpty(HLID)
specFolder &= "*"
With j("stories")
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each m As EContainer In .Self
ProgressPre.Perform()
postID = $"{A_HIGHLIGHT}_{HLID}_{m.Value("id")}"
postDate = m.Value("createdAt")
If Not _TempPostsList.Contains(postID) Then
_TempPostsList.Add(postID)
Else
Exit Sub
End If
result = False
media = TryCreateMedia(m, postID, postDate, result, True, specFolder)
If result Then _TempMediaList.ListAddList(media, LNC)
Next
End If
End With
End If
End Using
End If
End If
Catch ex As Exception
_complete = Not ProcessException(ex, Token, $"highlights downloading error [{url}]") = 2
End Try
Loop While Not _complete
End Sub
#End Region
#Region "Download chat media"
Private Sub DownloadChatMedia(ByVal Cursor As Integer, ByVal Token As CancellationToken)
Dim url$ = String.Empty
Dim _complete As Boolean = True
Do
Try
Dim hasMore As Boolean = False
Dim postID$, postDate$
Dim media As List(Of UserMedia)
Dim result As Boolean
Dim path$ = $"/api2/v2/chats/{ID}/media/?opened=1&limit=20&skip_users=all"
If Cursor > 0 Then path &= $"&offset={Cursor}"
If UpdateSignature(path) Then
url = String.Format(BaseUrlPattern, path)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(url)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
hasMore = j.Value("hasMore").FromXML(Of Boolean)(False)
With j("list")
If .ListExists Then
For Each m As EContainer In .Self
postID = $"{A_MESSAGE}_{m.Value("id")}"
postDate = m.Value("createdAt")
If Not _TempPostsList.Contains(postID) Then
_TempPostsList.Add(postID)
Else
Exit Sub
End If
result = False
media = TryCreateMedia(m, postID, postDate, result,, "Chats*")
If result Then _TempMediaList.ListAddList(media, LNC)
Next
End If
End With
End If
End Using
End If
End If
If hasMore Then DownloadChatMedia(Cursor + 20, Token)
Catch ex As Exception
_complete = Not ProcessException(ex, Token, $"chats downloading error [{url}]") = 2
End Try
Loop While Not _complete
End Sub
#End Region
Private Function TryCreateMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal PostDate As String = Nothing,
Optional ByRef Result As Boolean = False) As List(Of UserMedia)
Optional ByRef Result As Boolean = False, Optional ByVal IsHL As Boolean = False,
Optional ByVal SpecFolder As String = Nothing) As List(Of UserMedia)
Dim postUrl$, ext$
Dim t As UTypes
Dim mList As New List(Of UserMedia)
@@ -138,7 +315,11 @@ Namespace API.OnlyFans
With n("media")
If .ListExists Then
For Each m In .Self
postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full"))
If IsHL Then
postUrl = m.Value({"files", "source"}, "url")
Else
postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full"))
End If
Select Case m.Value("type")
Case "photo" : t = UTypes.Picture : ext = "jpg"
Case "video" : t = UTypes.Video : ext = "mp4"
@@ -146,7 +327,9 @@ Namespace API.OnlyFans
End Select
If Not t = UTypes.Undefined And Not postUrl.IsEmptyString Then
Dim media As New UserMedia(postUrl, t) With {
.Post = New UserPost(PostID, AConvert(Of Date)(PostDate, DateProvider, Nothing))}
.Post = New UserPost(PostID, AConvert(Of Date)(PostDate, DateProvider, Nothing)),
.SpecialFolder = SpecFolder
}
media.File.Extension = ext
Result = True
mList.Add(media)
@@ -157,6 +340,7 @@ Namespace API.OnlyFans
Return mList
End Function
Private Sub GetUserID()
Const brTag$ = "<br />"
Dim path$ = $"/api2/v2/users/{Name}"
Dim url$ = String.Format(BaseUrlPattern, path)
Try
@@ -168,7 +352,9 @@ Namespace API.OnlyFans
ID = j.Value("id")
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
UserSiteNameUpdate(j.Value("name"))
UserDescriptionUpdate(j.Value("about"))
Dim descr$ = j.Value("about")
If Not descr.IsEmptyString Then descr = descr.Replace(brTag, String.Empty)
UserDescriptionUpdate(descr)
Dim a As Action(Of String) = Sub(ByVal address As String)
If Not address.IsEmptyString Then
Dim f As SFile = address
@@ -232,7 +418,7 @@ Namespace API.OnlyFans
ProcessException(ex, Token, $"ReparseMissing error [{URL}]")
Finally
If rList.Count > 0 Then
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
rList.Clear()
End If
End Try
@@ -347,6 +533,10 @@ Namespace API.OnlyFans
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then
UserExists = False
Return 1
ElseIf Responser.StatusCode = Net.HttpStatusCode.GatewayTimeout Or Responser.StatusCode = 429 Then
If Responser.StatusCode = 429 Then MyMainLOG = $"[429] OnlyFans too many requests ({ToStringForLog()})"
MySettings.SessionAborted = True
Return 1
Else
Return 0
End If
@@ -354,7 +544,7 @@ Namespace API.OnlyFans
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then CCookie.DisposeIfReady(False) : CCookie = Nothing
If Not disposedValue And disposing Then CCookie.DisposeIfReady(False) : CCookie = Nothing : HighlightsList.Clear()
MyBase.Dispose(disposing)
End Sub
#End Region

View File

@@ -0,0 +1,28 @@
' 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.Attributes
Namespace API.OnlyFans
Friend Class UserExchangeOptions
<PSetting(NameOf(SiteSettings.DownloadHighlights), NameOf(MySettings))>
Friend Property DownloadHighlights As Boolean
<PSetting(NameOf(SiteSettings.DownloadChatMedia), NameOf(MySettings))>
Friend Property DownloadChatMedia As Boolean
Private ReadOnly MySettings As SiteSettings
Friend Sub New(ByVal u As UserData)
DownloadHighlights = u.MediaDownloadHighlights
DownloadChatMedia = u.MediaDownloadChatMedia
MySettings = u.HOST.Source
End Sub
Friend Sub New(ByVal s As SiteSettings)
DownloadHighlights = s.DownloadHighlights.Value
DownloadChatMedia = s.DownloadChatMedia.Value
MySettings = s
End Sub
End Class
End Namespace

View File

@@ -12,7 +12,7 @@ Namespace API.PathPlugin
Private Const DOWNLOAD_ERROR As String = "The path plugin only provides user paths."
Friend Overrides Property UserExists As Boolean
Get
Return FileExists
Return DownloadContentDefault_GetRootDir.CSFileP.Exists(SFO.Path, False)
End Get
Set(ByVal e As Boolean)
MyBase.UserExists = e

View File

@@ -25,25 +25,12 @@ Namespace API.Pinterest
Return My.Resources.SiteResources.PinterestPic_48
End Get
End Property
Private Class ConcurrentDownloadsValidator : Inherits FieldsCheckerProviderBase
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
Dim v% = AConvert(Of Integer)(Value, -1)
Dim defV% = Settings.MaxUsersJobsCount
If v.ValueBetween(1, defV) Then
Return Value
Else
ErrorMessage = $"The number of concurrent downloads must be greater than 0 and equal to or less than {defV} (global limit)."
HasError = True
Return Nothing
End If
End Function
End Class
<Provider(NameOf(ConcurrentDownloads), FieldsChecker:=True)>
Private ReadOnly Property ConcurrentDownloadsProvider As IFormatProvider
<PXML, PropertyOption(ControlText:="Concurrent downloads", ControlToolTip:="The number of concurrent downloads.", LeftOffset:=120), TaskCounter>
<PropertyOption(ControlText:=DeclaredNames.ConcurrentDownloadsCaption,
ControlToolTip:=DeclaredNames.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter>
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
<PXML, PropertyOption(ControlText:="Saved posts user", ControlToolTip:="Personal profile username")>
<Provider(NameOf(ConcurrentDownloads), FieldsChecker:=True)>
Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Initializer"
@@ -51,7 +38,7 @@ Namespace API.Pinterest
MyBase.New("Pinterest", "pinterest.com")
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
ConcurrentDownloads = New PropertyValue(1)
ConcurrentDownloadsProvider = New ConcurrentDownloadsValidator
MyConcurrentDownloadsProvider = New ConcurrentDownloadsProvider
CheckNetscapeCookiesOnEndInit = True
UseNetscapeCookies = True
UserRegex = RParams.DMS("https?://w{0,3}.?[^/]*?.?pinterest.com/([^/]+)/?(?(_)|([^/]*))", 0, RegexReturn.ListByMatch, EDP.ReturnValue)

View File

@@ -38,6 +38,12 @@ Namespace API.Pinterest
Friend Property TrueUserName As String
Friend Property TrueBoardName As String
Friend Property IsUser As Boolean
Private Const BoardLabelName As String = "Board"
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {UserLabelName, BoardLabelName}
End Get
End Property
#End Region
#Region "Load"
Private Function ReconfUserName() As Boolean
@@ -48,12 +54,12 @@ Namespace API.Pinterest
IsUser = True
If n.Length > 1 Then TrueBoardName = n(1) : IsUser = False
If Not IsSavedPosts And Not IsSingleObjectDownload Then
Dim l$ = IIf(IsUser, UserLabelName, "Board")
Dim l$ = IIf(IsUser, UserLabelName, BoardLabelName)
Settings.Labels.Add(l)
Labels.ListAddValue(l, LNC)
Labels.Sort()
Return True
End If
Return True
End If
End If
Return False
@@ -66,7 +72,7 @@ Namespace API.Pinterest
IsUser = .Value(Name_IsUser).FromXML(Of Boolean)(False)
ReconfUserName()
Else
If ReconfUserName() Then .Value(Name_LabelsName) = Labels.ListToString("|", EDP.ReturnValue)
If ReconfUserName() Then .Value(Name_LabelsName) = LabelsString
.Add(Name_TrueUserName, TrueUserName)
.Add(Name_TrueBoardName, TrueBoardName)
.Add(Name_IsUser, IsUser.BoolToInteger)
@@ -128,7 +134,7 @@ Namespace API.Pinterest
Dim j As EContainer, jj As EContainer
Dim rootNode$() = {"resource_response", "data"}
Dim jErr As New ErrorsDescriber(EDP.SendToLog + EDP.ReturnValue)
Dim urls As List(Of String) = GetDataFromGalleryDL(URL, True)
Dim urls As List(Of String) = GetDataFromGalleryDL(URL, True, Token)
If urls.ListExists Then urls.RemoveAll(Function(__url) Not __url.Contains("BoardsResource/get/"))
If urls.ListExists Then
ProgressPre.ChangeMax(urls.Count)
@@ -177,7 +183,7 @@ Namespace API.Pinterest
Dim images As List(Of Sizes)
Dim imgSelector As Func(Of EContainer, Sizes) = Function(img) New Sizes(img.Value("width"), img.Value("url"))
Dim fullData As Predicate(Of EContainer) = Function(e) e.Count > 5
Dim l As List(Of String) = GetDataFromGalleryDL(Board.URL, False)
Dim l As List(Of String) = GetDataFromGalleryDL(Board.URL, False, Token)
If l.ListExists Then l.RemoveAll(Function(ll) Not ll.Contains("BoardFeedResource/get/"))
If l.ListExists Then
ProgressPre.ChangeMax(l.Count)
@@ -253,8 +259,8 @@ Namespace API.Pinterest
Private Class GDLBatch : Inherits GDL.GDLBatch
Private ReadOnly Property Source As UserData
Private ReadOnly IsBoardsRequested As Boolean
Friend Sub New(ByRef s As UserData, ByVal IsBoardsRequested As Boolean)
MyBase.New
Friend Sub New(ByRef s As UserData, ByVal IsBoardsRequested As Boolean, ByVal _Token As CancellationToken)
MyBase.New(_Token)
Source = s
Me.IsBoardsRequested = IsBoardsRequested
End Sub
@@ -269,22 +275,24 @@ Namespace API.Pinterest
Protected Overrides Async Function Validate(ByVal Value As String) As Task
If IsBoardsRequested Then
If ErrorOutputData.Count > 0 Then
If Await Task.Run(Of Boolean)(Function() ErrorOutputData.Exists(Function(ee) Not ee.IsEmptyString AndAlso
If Await Task.Run(Of Boolean)(Function() Token.IsCancellationRequested OrElse
ErrorOutputData.Exists(Function(ee) Not ee.IsEmptyString AndAlso
ee.StartsWith(UrlTextStart))) Then Kill()
End If
Else
If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
Source._TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill()
If Await Task.Run(Of Boolean)(Function() Token.IsCancellationRequested OrElse
(Not Value.IsEmptyString AndAlso
Source._TempPostsList.Exists(Function(v) Value.Contains(v)))) Then Kill()
End If
End Function
End Class
Private Function GetDataFromGalleryDL(ByVal URL As String, ByVal IsBoardsRequested As Boolean) As List(Of String)
Private Function GetDataFromGalleryDL(ByVal URL As String, ByVal IsBoardsRequested As Boolean, ByVal Token As CancellationToken) As List(Of String)
Dim command$ = $"gallery-dl --verbose --simulate "
Try
If Not URL.IsEmptyString Then
If MySettings.CookiesNetscapeFile.Exists Then command &= $"--cookies ""{MySettings.CookiesNetscapeFile}"" "
command &= URL
Using batch As New GDLBatch(Me, IsBoardsRequested)
Using batch As New GDLBatch(Me, IsBoardsRequested, Token)
Return GetUrlsFromGalleryDl(batch, command)
End Using
End If

View File

@@ -6,6 +6,7 @@
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.Text.RegularExpressions
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.PornHub
Friend Module Declarations
@@ -15,17 +16,11 @@ Namespace API.PornHub
#Region "Declarations video"
Friend ReadOnly RegexVideo_FlashVarsBlocks As RParams = RParams.DM("(?<=(flashvars_\['[nN]ext[vV]ideo'\]|flashvars_\d+[^ ]+? = media_\d+?);[\r\n]*?)(.+?)(?=;flashvars_\d+?)",
0, RegexReturn.List, EDP.ReturnValue)
'TODELETE: PornHub old 'RegexVideo_FlashVarsBlock' declaration
'Friend ReadOnly RegexVideo_FlashVarsBlock As RParams = RParams.DM("(?<=flashvars_\['[nN]ext[vV]ideo'\];[\r\n]*?)(.+?)(?=;flashvars_\d+?)", 0, EDP.ReturnValue)
Friend ReadOnly RegexVideo_FlashVars_Vars As RParams = RParams.DM("var ([\w\d]{10,})=("".+?)(?=(;|\Z))", 0, RegexReturn.List)
Friend ReadOnly RegexVideo_FlashVars_Compiler As RParams = RParams.DM("(?<=\*/)([\w\d\S]{10,})", 0, RegexReturn.List)
Friend ReadOnly RegexVideo_FlashVars_UrlResolution As RParams = RParams.DMS("/(\d+)[^/]+\.mp4", 1, EDP.ReturnValue)
Friend ReadOnly RegexVideo_Video_All As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""",
0, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
Friend ReadOnly RegexVideo_Video_Wrong As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""[\w\W\s\r\n]+?(?=\<div class=""videoUploaderBlock)",
0, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
Private ReadOnly RegexVideo_Video_Wrong_Option As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""[\w\W\s\r\n]+?", 0, RegexReturn.ListByMatch)
Friend ReadOnly RegexVideo_Video_Wrong_Fields As RField() = {New RField(New RFieldOption(1, RegexVideo_Video_Wrong_Option)), New RField(New RFieldOption(2, RegexVideo_Video_Wrong_Option))}
Friend ReadOnly RegexUserVideos As RParams = RParams.DM("(\<li class=""pcVideoListItem)((?:(?!/li\>).)*?)(\<div.class=.private-vid-title((?:(?!/li\>).)*?)|)(\<a.href=.([^""]+?)"".title=.([^""]*?)"")(((?:(?!/li\>).)+?)(\<div class=.videoUploaderBlock)|)((?:(?!/li\>).)*?)(\</li\>)",
0, RegexOptions.Singleline, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
Friend ReadOnly RegexVideo_Video_VideoKey As RParams = RParams.DMS("viewkey=([\w\d]+)", 1, EDP.ReturnValue)
Friend ReadOnly RegexVideoPageTitle As RParams = RParams.DMS("meta (property|name)=""[^:]+?:title"" content=""([^""]+)""", 2, EDP.ReturnValue)
#End Region

View File

@@ -27,6 +27,14 @@ Namespace API.PornHub
End Property
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
Friend Property DownloadUHD As PropertyValue
<PropertyOption(ControlText:="Download uploaded", ControlToolTip:="Download uploaded videos"), PXML>
Friend Property DownloadUploaded As PropertyValue
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged videos"), PXML>
Friend Property DownloadTagged As PropertyValue
<PropertyOption(ControlText:="Download private", ControlToolTip:="Download private videos"), PXML>
Friend Property DownloadPrivate As PropertyValue
<PropertyOption(ControlText:="Download favorite", ControlToolTip:="Download favorite videos"), PXML>
Friend Property DownloadFavorite As PropertyValue
<PropertyOption(ControlText:="Download GIF", ControlToolTip:="Default for new users", ThreeStates:=True), PXML>
Friend ReadOnly Property DownloadGifs As PropertyValue
<PropertyOption(ControlText:="Download GIFs as mp4", ControlToolTip:="Download gifs in 'mp4' format instead of native 'webm'"), PXML>
@@ -35,7 +43,7 @@ Namespace API.PornHub
ControlToolTip:="Download photo only from ModelHub. Prornstar photos hosted on PornHub itself will not be downloaded." & vbCr &
"Attention! Downloading photos hosted on PornHub is a very heavy job."), PXML>
Friend ReadOnly Property DownloadPhotoOnlyFromModelHub As PropertyValue
<PropertyOption(ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Initializer"
@@ -44,14 +52,19 @@ Namespace API.PornHub
With Responser : .CurlSslNoRevoke = True : .CurlInsecure = True : End With
DownloadUHD = New PropertyValue(False)
DownloadUploaded = New PropertyValue(True)
DownloadTagged = New PropertyValue(False)
DownloadPrivate = New PropertyValue(False)
DownloadFavorite = New PropertyValue(False)
DownloadGifsAsMp4 = New PropertyValue(True)
DownloadGifs = New PropertyValue(CInt(CheckState.Indeterminate), GetType(Integer))
DownloadPhotoOnlyFromModelHub = New PropertyValue(True)
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
_SubscriptionsAllowed = True
UrlPatternUser = "https://www.pornhub.com/{0}/{1}"
UserRegex = RParams.DMS("pornhub.com/([^/]+)/([^/]+).*?", 0, RegexReturn.ListByMatch)
ImageVideoContains = "pornhub"
UserRegex = RParams.DMS("pornhub.com/(model|user[s]?|pornstar|channel[s]?)/([^/]+).*?", 0, RegexReturn.ListByMatch)
ImageVideoContains = "pornhub.com"
End Sub
#End Region
#Region "GetInstance"
@@ -67,11 +80,17 @@ Namespace API.PornHub
End Function
#End Region
#Region "IsMyUser"
Private ReadOnly NonUserRegex As RParams = RParams.DM("(?<=pornhub.com/)((.+?)(?=[\?&]{1}page=\d+)|(.+))", 0, EDP.ReturnValue)
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Try
If Not UserURL.IsEmptyString Then
If Not UserURL.IsEmptyString AndAlso UserURL.ToLower.Contains("pornhub.com") Then
Dim alist As List(Of String) = RegexReplace(UserURL.ToLower, UserRegex)
If alist.ListExists(3) Then Return New ExchangeOptions(Site, $"{alist(1)}_{alist(2)}")
If alist.ListExists(3) Then
Return New ExchangeOptions(Site, $"{alist(1)}_{alist(2)}")
Else
Dim opt$ = RegexReplace(UserURL, NonUserRegex)
If Not opt.IsEmptyString Then Return New ExchangeOptions(Site, opt.StringRemoveWinForbiddenSymbols) With {.Options = opt}
End If
End If
Return Nothing
Catch ex As Exception
@@ -81,7 +100,13 @@ Namespace API.PornHub
#End Region
#Region "GetUserUrl"
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
With DirectCast(User, UserData) : Return String.Format(UrlPatternUser, .PersonType, .NameTrue) : End With
With DirectCast(User, UserData)
If .IsUser Then
Return String.Format(UrlPatternUser, .PersonType, .NameTrue)
Else
Return .GetNonUserUrl(0)
End If
End With
End Function
#End Region
#Region "User options"

View File

@@ -21,11 +21,15 @@ Namespace API.PornHub
#Region "XML names"
Private Const Name_PersonType As String = "PersonType"
Private Const Name_NameTrue As String = "NameTrue"
Private Const Name_VideoPageModel As String = "VideoPageModel"
Private Const Name_PhotoPageModel As String = "PhotoPageModel"
Private Const Name_DownloadUHD As String = "DownloadUHD"
Private Const Name_DownloadUploaded As String = "DownloadUploaded"
Private Const Name_DownloadTagged As String = "DownloadTagged"
Private Const Name_DownloadPrivate As String = "DownloadPrivate"
Private Const Name_DownloadFavorite As String = "DownloadFavorite"
Private Const Name_DownloadGifs As String = "DownloadGifs"
Private Const Name_DownloadPhotoOnlyFromModelHub As String = "DownloadPhotoOnlyFromModelHub"
Private Const Name_IsUser As String = "IsUser"
#End Region
#Region "Structures"
Private Structure FlashVar : Implements IRegExCreator
@@ -50,18 +54,31 @@ Namespace API.PornHub
Friend URL As String
Friend ID As String
Friend Title As String
Friend Function ToUserMedia() As UserMedia
Friend Type As VideoTypes
Friend Function ToUserMedia(Optional ByVal SpecialFolder As String = Nothing) As UserMedia
Return New UserMedia(URL, UTypes.VideoPre) With {
.File = If(Title.IsEmptyString, .File, New SFile($"{Title}.mp4")),
.Post = ID
.Post = ID,
.SpecialFolder = SpecialFolder
}
End Function
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
If ParamsArray.ListExists Then
If ParamsArray.ListExists(4) Then
URL = ParamsArray(0)
ID = RegexReplace(URL, RegexVideo_Video_VideoKey)
URL = String.Format(UrlPattern, URL.TrimStart("/"))
Title = TitleHtmlConverter(ParamsArray(1))
If ID.IsEmptyString Then
URL = String.Empty
Else
URL = String.Format(UrlPattern, URL.TrimStart("/"))
Title = TitleHtmlConverter(ParamsArray(1))
If Not ParamsArray(2).IsEmptyString Then
Type = VideoTypes.Private
ElseIf Not ParamsArray(3).IsEmptyString Then
Type = VideoTypes.Tagged
Else
Type = VideoTypes.Uploaded
End If
End If
End If
Return Me
End Function
@@ -82,21 +99,24 @@ Namespace API.PornHub
End Structure
#End Region
#Region "Enums"
Friend Enum VideoPageModels As Integer
[Default] = 0
ConcatPage = 1
Favorite = 2
Undefined = -1
End Enum
Private Enum PhotoPageModels As Integer
Undefined = 0
PornHubPage = 1
ModelHubPage = 2
End Enum
Private Enum VideoTypes
Undefined
Uploaded
[Private]
Tagged
Favorite
End Enum
#End Region
#Region "Constants"
Private Const PersonTypeModel As String = "model"
Friend Const PersonTypeUser As String = "users"
Private Const PersonTypeUser As String = "users"
Private Const PersonTypePornstar As String = "pornstar"
Private Const PersonTypeCannel As String = "channels"
#End Region
#Region "Person"
Friend Property PersonType As String
@@ -111,11 +131,37 @@ Namespace API.PornHub
End Property
#End Region
#Region "Advanced fields"
Friend Property VideoPageModel As VideoPageModels = VideoPageModels.Undefined
Friend Overrides ReadOnly Property FeedIsUser As Boolean
Get
Return IsUser
End Get
End Property
Private Property PhotoPageModel As PhotoPageModels = PhotoPageModels.Undefined
Friend Property DownloadUHD As Boolean = False
Friend Property DownloadUploaded As Boolean = True
Friend Property DownloadTagged As Boolean = False
Friend Property DownloadPrivate As Boolean = False
Friend Property DownloadFavorite As Boolean = False
Friend Property DownloadGifs As Boolean
Friend Property DownloadPhotoOnlyFromModelHub As Boolean = True
Friend Property IsUser As Boolean = True
Friend Property QueryString As String
Get
If IsUser Then
Return String.Empty
Else
Return GetNonUserUrl(0)
End If
End Get
Set(ByVal q As String)
UpdateUserOptions(True, q)
End Set
End Property
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
End Get
End Property
#End Region
#Region "ExchangeOptions"
Friend Overrides Function ExchangeOptionsGet() As Object
@@ -125,8 +171,13 @@ Namespace API.PornHub
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
With DirectCast(Obj, UserExchangeOptions)
DownloadUHD = .DownloadUHD
DownloadUploaded = .DownloadUploaded
DownloadTagged = .DownloadTagged
DownloadPrivate = .DownloadPrivate
DownloadFavorite = .DownloadFavorite
DownloadGifs = .DownloadGifs
DownloadPhotoOnlyFromModelHub = .DownloadPhotoOnlyFromModelHub
QueryString = .QueryString
End With
End If
End Sub
@@ -136,96 +187,131 @@ Namespace API.PornHub
Return DirectCast(HOST.Source, SiteSettings)
End Get
End Property
Private ReadOnly LastPageIDs As List(Of String)
#End Region
#Region "Initializer, loader"
#Region "Initializer"
Friend Sub New()
LastPageIDs = New List(Of String)
UseInternalM3U8Function = True
UseClientTokens = True
End Sub
#End Region
#Region "Loader"
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
If Not Force OrElse (Not IsUser AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
Dim eObj As Plugin.ExchangeOptions = Nothing
If Force Then eObj = MySettings.IsMyUser(NewUrl)
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And Not Name.IsEmptyString And NameTrue.IsEmptyString) Then
If Not If(Force, eObj.Options, Options).IsEmptyString Then
If IsUser And Force Then
Return False
Else
IsUser = False
Options = If(Force, eObj.Options, Options)
NameTrue = Options
If Not Force Then
Settings.Labels.Add(SearchRequestLabelName)
Labels.ListAddValue(SearchRequestLabelName, LNC)
Labels.Sort()
Return True
End If
End If
Else
IsUser = True
Dim n$() = Name.Split("_")
If n.ListExists(2) Then
NameTrue = Name.Replace($"{n(0)}_", String.Empty)
PersonType = n(0)
End If
End If
End If
End If
Return False
End Function
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
Dim SetNames As Action = Sub()
If Not Name.IsEmptyString And NameTrue.IsEmptyString Then
Dim n$() = Name.Split("_")
If n.ListExists(2) Then
NameTrue = Name.Replace($"{n(0)}_", String.Empty)
PersonType = n(0)
If (PersonType = PersonTypeModel Or PersonType = PersonTypeUser) And
VideoPageModel = VideoPageModels.Undefined Then VideoPageModel = VideoPageModels.Default
End If
End If
End Sub
If Loading Then
PersonType = .Value(Name_PersonType)
NameTrue = .Value(Name_NameTrue)
VideoPageModel = .Value(Name_VideoPageModel).FromXML(Of Integer)(VideoPageModels.Undefined)
PhotoPageModel = .Value(Name_PhotoPageModel).FromXML(Of Integer)(PhotoPageModels.Undefined)
DownloadUHD = .Value(Name_DownloadUHD).FromXML(Of Boolean)(False)
DownloadUploaded = .Value(Name_DownloadUploaded).FromXML(Of Boolean)(True)
DownloadTagged = .Value(Name_DownloadTagged).FromXML(Of Boolean)(False)
DownloadPrivate = .Value(Name_DownloadPrivate).FromXML(Of Boolean)(False)
DownloadFavorite = .Value(Name_DownloadFavorite).FromXML(Of Boolean)(False)
DownloadGifs = .Value(Name_DownloadGifs).FromXML(Of Integer)(False)
DownloadPhotoOnlyFromModelHub = .Value(Name_DownloadPhotoOnlyFromModelHub).FromXML(Of Boolean)(True)
SetNames.Invoke()
IsUser = .Value(Name_IsUser).FromXML(Of Boolean)(True)
UpdateUserOptions()
Else
SetNames.Invoke()
If UpdateUserOptions() Then .Value(Name_LabelsName) = LabelsString
.Add(Name_PersonType, PersonType)
.Add(Name_NameTrue, NameTrue)
.Add(Name_VideoPageModel, CInt(VideoPageModel))
.Add(Name_PhotoPageModel, CInt(PhotoPageModel))
.Add(Name_DownloadUHD, DownloadUHD.BoolToInteger)
.Add(Name_DownloadUploaded, DownloadUploaded.BoolToInteger)
.Add(Name_DownloadTagged, DownloadTagged.BoolToInteger)
.Add(Name_DownloadPrivate, DownloadPrivate.BoolToInteger)
.Add(Name_DownloadFavorite, DownloadFavorite.BoolToInteger)
.Add(Name_DownloadGifs, DownloadGifs.BoolToInteger)
.Add(Name_DownloadPhotoOnlyFromModelHub, DownloadPhotoOnlyFromModelHub.BoolToInteger)
.Add(Name_IsUser, IsUser.BoolToInteger)
'Debug.WriteLine(GetNonUserUrl(0))
'Debug.WriteLine(GetNonUserUrl(2))
End If
End With
End Sub
#End Region
#Region "Downloading"
#Region "Download override"
Private Const DataDownloaded As Integer = -10
Private Const DataDownloaded_NotFound As Integer = -20
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Try
Responser.ResetStatus()
If PersonType = PersonTypeUser Then Responser.Mode = Responser.Modes.Curl
If IsSavedPosts Then
VideoPageModel = VideoPageModels.Favorite
PersonType = PersonTypeUser
NameTrue = MySettings.SavedPostsUserName.Value
End If
Dim page% = 1
Dim __continue As Boolean = True
Dim __videoDone As Boolean = False
Dim d%
Dim limit% = If(DownloadTopCount, -1)
If DownloadVideos Then
If PersonType = PersonTypeUser Then Responser.Mode = Responser.Modes.Curl : Responser.Method = "POST"
If VideoPageModel = VideoPageModels.Undefined Then
__continue = False
d = DownloadUserVideos(page, Token)
Select Case d
Case DataDownloaded : __continue = True : page += 1
Case 1 : VideoPageModel = VideoPageModels.ConcatPage
Case EXCEPTION_OPERATION_CANCELED : ThrowAny(Token)
Case DataDownloaded_NotFound : __videoDone = True
End Select
If Not __continue And Not __videoDone Then
d = DownloadUserVideos(page, Token)
Select Case d
Case DataDownloaded : __continue = True : page += 1
Case 1 : VideoPageModel = VideoPageModels.Undefined
Case EXCEPTION_OPERATION_CANCELED : ThrowAny(Token)
Case DataDownloaded_NotFound : __videoDone = True
End Select
If IsSavedPosts Or Not IsUser Or PersonType = PersonTypeUser Then
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
Else
If DownloadUploaded Then
LastPageIDs.Clear()
DownloadUserVideos(1, VideoTypes.Uploaded, False, Token)
End If
If DownloadTagged Then
LastPageIDs.Clear()
Dim lBefore% = _TempMediaList.Count
DownloadUserVideos(1, VideoTypes.Tagged, False, Token)
If PersonType = PersonTypePornstar And lBefore = _TempMediaList.Count Then
LastPageIDs.Clear()
DownloadUserVideos(1, VideoTypes.Tagged, True, Token)
End If
End If
If DownloadPrivate Then
LastPageIDs.Clear()
DownloadUserVideos(1, VideoTypes.Private, False, Token)
End If
If DownloadFavorite Then
LastPageIDs.Clear()
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
End If
End If
If __continue And Not __videoDone Then
Do While DownloadUserVideos(page, Token) = DataDownloaded And page < 100 : page += 1 : Loop
If _TempMediaList.Count > 0 Then
_TempMediaList.RemoveAll(Function(m) Not m.Type = UTypes.m3u8 And Not m.Type = UTypes.VideoPre)
If limit > 0 And _TempMediaList.Count > limit Then _TempMediaList.ListAddList(_TempMediaList.ListTake(-1, limit), LAP.ClearBeforeAdd)
End If
If _TempMediaList.Count > 0 Then _TempMediaList.RemoveAll(Function(m) Not m.Type = UTypes.m3u8 And Not m.Type = UTypes.VideoPre)
End If
Responser.Method = "GET"
If DownloadGifs And Not IsSavedPosts Then DownloadUserGifs(Token)
If DownloadImages Then DownloadUserPhotos(Token)
If DownloadGifs And Not IsSavedPosts And Not IsSubscription And IsUser Then DownloadUserGifs(Token)
If DownloadImages And Not IsSubscription And IsUser Then DownloadUserPhotos(Token)
Finally
Responser.Mode = Responser.Modes.Default
Responser.Method = "GET"
@@ -234,72 +320,100 @@ Namespace API.PornHub
End Sub
#End Region
#Region "Download video"
Private ReadOnly Property VideoPageType As String
Get
Select Case VideoPageModel
Case VideoPageModels.Default : Return "/videos/upload"
Case VideoPageModels.Favorite : Return "/videos/favorites/"
Case Else : Return String.Empty
End Select
End Get
End Property
Private ReadOnly Property VideoPageAppender As String
Get
Return If(PersonType = PersonTypeUser, "ajax?o=newest&page=", String.Empty)
End Get
End Property
Private Overloads Function DownloadUserVideos(ByVal Page As Integer, ByVal Token As CancellationToken) As Integer
Const VideoUrlPattern$ = "https://www.pornhub.com/{0}/{1}{2}{3}"
Const HtmlPageNotFoundVideo$ = "<span>Error Page Not Found</span>"
Friend Function GetNonUserUrl(ByVal Page As Integer) As String
If IsUser Then
Return String.Empty
Else
Dim url$ = $"https://www.pornhub.com/{Options}"
If Page > 1 Then
If url.Contains("?") Then
url &= $"&page={Page}"
Else
url = url.TrimEnd("/")
url &= $"?page={Page}"
End If
End If
Return url
End If
End Function
Private Sub DownloadUserVideos(ByVal Page As Integer, ByVal Type As VideoTypes, ByVal SecondMode As Boolean, ByVal Token As CancellationToken)
Dim URL$ = String.Empty
ProgressPre.ChangeMax(1)
Try
Dim p$
If PersonType = PersonTypeUser Then
p = Page
Dim specFolder$ = String.Empty
Dim tryNextPage As Boolean = False
Dim limit% = If(DownloadTopCount, -1)
If IsUser Then
URL = $"https://www.pornhub.com/{PersonType}/{NameTrue}"
If Type = VideoTypes.Uploaded Then
URL &= "/videos/upload"
ElseIf Type = VideoTypes.Tagged Then
If Not SecondMode Then URL &= "/videos"
specFolder = "Tagged"
ElseIf Type = VideoTypes.Private Then
URL &= "/videos/private"
specFolder = "Private"
ElseIf Type = VideoTypes.Favorite Then
URL &= "/videos/favorites"
If Not PersonType = PersonTypeUser Then specFolder = "Favorite"
Else
Throw New ArgumentException($"Type '{Type}' is not implemented in the video download function", "Type")
End If
If Page > 1 Then URL &= $"?page={Page}"
Else
p = IIf(Page = 1, String.Empty, $"?page={Page}")
URL = GetNonUserUrl(Page)
End If
URL = $"{String.Format(VideoUrlPattern, PersonType, NameTrue, VideoPageType, VideoPageAppender)}{p}"
ThrowAny(Token)
'Debug.WriteLine(URL)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
If PersonType = PersonTypeUser And r.Contains(HtmlPageNotFoundVideo) Then Return DataDownloaded_NotFound
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexVideo_Video_All}, {1, 2})
Dim lw As List(Of UserVideo) = Nothing
If Not PersonType = PersonTypeUser Then lw = RegexFields(Of UserVideo)(r, {RegexVideo_Video_Wrong}, RegexVideo_Video_Wrong_Fields)
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexUserVideos}, {6, 7, 3, 10})
If l.ListExists Then l = l.ListTake(3, l.Count).ToList
If l.ListExists Then
If lw.ListExists Then l.ListWithRemove(lw)
If IsUser Then
If Type = VideoTypes.Favorite Then
l.RemoveAll(Function(uv) uv.Type = VideoTypes.Private)
ElseIf Not PersonType = PersonTypeCannel Then
l.RemoveAll(Function(uv) Not uv.Type = Type)
End If
End If
If l.Count > 0 Then l.RemoveAll(Function(uv) uv.ID.IsEmptyString Or uv.URL.IsEmptyString)
If l.Count > 0 Then
Dim lBefore% = l.Count
Dim nonLastPageDetected As Boolean = False
Dim newLastPageIDs As New List(Of String)
l.RemoveAll(Function(ByVal uv As UserVideo) As Boolean
If Not _TempPostsList.Contains(uv.ID) Then
_TempPostsList.Add(uv.ID)
newLastPageIDs.Add(uv.ID)
Return False
Else
If Not LastPageIDs.Contains(uv.ID) Then nonLastPageDetected = True
'Debug.WriteLine($"[REMOVED]: {uv.Title}")
Return True
End If
End Function)
If l.Count > 0 Then _TempMediaList.ListAddList(l.Select(Function(uv) uv.ToUserMedia))
If l.Count = lBefore And l.Count > 0 Then Return DataDownloaded
'Debug.WriteLineIf(l.Count > 0, l.Select(Function(ll) ll.Title).ListToString(vbNewLine))
If l.Count > 0 Then _TempMediaList.ListAddList(l.Select(Function(uv) uv.ToUserMedia(specFolder)))
LastPageIDs.Clear()
If newLastPageIDs.Count > 0 Then LastPageIDs.AddRange(newLastPageIDs) : newLastPageIDs.Clear()
If l.Count > 0 AndAlso (l.Count = lBefore Or Not nonLastPageDetected) AndAlso
Not (limit > 0 And _TempMediaList.Count >= limit) Then tryNextPage = True
End If
End If
End If
Return DataDownloaded_NotFound
If tryNextPage Then DownloadUserVideos(Page + 1, Type, SecondMode, Token)
Catch regex_ex As RegexFieldsTextBecameNullException
If PersonType = PersonTypeUser Or IsSavedPosts Then
Return DataDownloaded_NotFound
Else
Return ProcessException(regex_ex, Token, $"videos downloading error [{URL}]")
End If
If Not IsSavedPosts Then MyMainLOG = $"{ToStringForLog()}: videos not found. You may need to update your credentials."
Catch ex As Exception
Return ProcessException(ex, Token, $"videos downloading error [{URL}]")
ProcessException(ex, Token, $"videos downloading error [{URL}]")
Finally
ProgressPre.Perform()
End Try
End Function
End Sub
#End Region
#Region "Download GIF"
Private Sub DownloadUserGifs(ByVal Token As CancellationToken)
@@ -393,7 +507,7 @@ Namespace API.PornHub
URL = String.Format(PhotoUrlPattern_ModelHub, NameTrue)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_ModelHub_PhotoBlocks}, {1, 2})
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_ModelHub_PhotoBlocks}, {1, 2}, EDP.ReturnValue)
If l.ListExists Then l.RemoveAll(Function(ll) ll.Data.IsEmptyString)
If l.ListExists Then
ProgressPre.ChangeMax(l.Count)
@@ -431,7 +545,7 @@ Namespace API.PornHub
Dim page%
Dim r$ = Responser.GetResponse(String.Format(PhotoUrlPattern_PornHub, PersonType, NameTrue))
If Not r.IsEmptyString Then
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_PornHub_PhotoBlocks}, {2, 1})
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_PornHub_PhotoBlocks}, {2, 1}, EDP.ReturnValue)
If l.ListExists Then l.RemoveAll(Function(ll) ll.AlbumID.IsEmptyString)
If l.ListExists Then
ProgressPre.ChangeMax(l.Count)
@@ -539,17 +653,21 @@ Namespace API.PornHub
End If
Return False
Catch ex As Exception
Return ProcessException(ex, Token, $"photos downloading error [{URL}]")
Return ProcessException(ex, Token, $"photos downloading error [{URL}]") = 1
End Try
End Function
#End Region
#End Region
#Region "ReparseVideo"
Protected Overloads Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
ReparseVideo(Token, False)
If IsSubscription Then
ReparseVideoSubscriptions(Token)
Else
ReparseVideo(Token, False)
End If
End Sub
Protected Overloads Sub ReparseVideo(ByVal Token As CancellationToken, ByVal CreateFileName As Boolean,
Optional ByRef Data As IYouTubeMediaContainer = Nothing)
Private Overloads Sub ReparseVideo(ByVal Token As CancellationToken, ByVal CreateFileName As Boolean,
Optional ByRef Data As IYouTubeMediaContainer = Nothing)
Const ERR_NEW_URL$ = "ERR_NEW_URL"
Dim URL$ = String.Empty
Try
@@ -600,6 +718,54 @@ Namespace API.PornHub
ProcessException(ex, Token, "video reparsing error", False)
End Try
End Sub
Private Sub ReparseVideoSubscriptions(ByVal Token As CancellationToken)
Try
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
Dim m As UserMedia
Dim r$, URL$, tmpName$, thumb$
Dim c% = 0
Dim rErr As New ErrorsDescriber(EDP.ReturnValue)
Progress.Maximum += _TempMediaList.Count
For i% = _TempMediaList.Count - 1 To 0 Step -1
Progress.Perform()
If _TempMediaList(i).Type = UTypes.VideoPre Then
If Not DownloadTopCount.HasValue OrElse c <= DownloadTopCount.Value Then
m = _TempMediaList(i)
ThrowAny(Token)
Try
URL = m.URL_BASE
r = Responser.GetResponse(URL,, rErr)
If Not r.IsEmptyString Then
m.Type = UTypes.m3u8
thumb = RegexReplace(r, Regex_VideosThumb_OG_IMAGE)
If Not thumb.IsEmptyString Then m.URL = thumb
tmpName = RegexReplace(r, RegexVideoPageTitle)
If Not tmpName.IsEmptyString Then
m.File.Name = TitleHtmlConverter(tmpName)
m.File.Extension = "mp4"
m.PictureOption = tmpName
End If
_TempMediaList(i) = m
c += 1
Else
_TempMediaList.RemoveAt(i)
End If
Catch mid_ex As Exception
_TempMediaList.RemoveAt(i)
End Try
Else
_TempMediaList.RemoveAt(i)
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "subscriptions video reparsing error", False)
End Try
End Sub
#End Region
#Region "ReparseMissing"
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
@@ -646,33 +812,6 @@ Namespace API.PornHub
End Function
#End Region
#Region "CreateVideoURL"
'TODELETE: PornHub old 'CreateVideoURL' function
'Private Function CreateVideoURL(ByVal r As String) As String
' Try
' Dim OutStr$ = String.Empty
' If Not r.IsEmptyString Then
' Dim _VarBlock$ = RegexReplace(r, RegexVideo_FlashVarsBlock)
' If Not _VarBlock.IsEmptyString Then
' Dim vars As List(Of FlashVar) = RegexFields(Of FlashVar)(_VarBlock, {RegexVideo_FlashVars_Vars}, {1, 2})
' Dim compiler As List(Of String) = RegexReplace(_VarBlock, RegexVideo_FlashVars_Compiler)
' If vars.ListExists And compiler.ListExists Then
' Dim v$
' Dim i%
' For Each var$ In compiler
' i = vars.IndexOf(var)
' If i >= 0 Then
' v = vars(i).Value
' If Not v.IsEmptyString Then OutStr &= v
' End If
' Next
' End If
' End If
' End If
' Return OutStr
' Catch ex As Exception
' Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL]", String.Empty)
' End Try
'End Function
Private Function CreateVideoURL(ByVal r As String) As String
Try
Dim OutStr$ = String.Empty
@@ -705,8 +844,8 @@ Namespace API.PornHub
End If
End If
If outList.Count > 0 Then outList.RemoveAll(Function(u) u.IsEmptyString)
If outList.Count > 0 Then
If OutList.Count > 0 Then OutList.RemoveAll(Function(u) u.IsEmptyString)
If OutList.Count > 0 Then
i = OutList.FindIndex(Function(u) u.Contains("urlset"))
If i >= 0 Then
OutStr = OutList(i)
@@ -728,6 +867,9 @@ Namespace API.PornHub
End If
OutList.Clear()
Return OutStr
Catch regex_ex As RegexFieldsTextBecameNullException
MyMainLOG = $"{ToStringForLog()}: something is wrong when parsing flashvars.{vbCr}{regex_ex.Message}"
Return String.Empty
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL]", String.Empty)
End Try
@@ -753,6 +895,12 @@ Namespace API.PornHub
Return 0
End If
End Function
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then LastPageIDs.Clear()
MyBase.Dispose(disposing)
End Sub
#End Region
End Class
End Namespace

View File

@@ -8,9 +8,17 @@
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes
Namespace API.PornHub
Friend Class UserExchangeOptions
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
<PSetting(NameOf(SiteSettings.DownloadUHD), NameOf(MySettings))>
Friend Property DownloadUHD As Boolean
<PSetting(NameOf(SiteSettings.DownloadUploaded), NameOf(MySettings))>
Friend Property DownloadUploaded As Boolean
<PSetting(NameOf(SiteSettings.DownloadTagged), NameOf(MySettings))>
Friend Property DownloadTagged As Boolean
<PSetting(NameOf(SiteSettings.DownloadPrivate), NameOf(MySettings))>
Friend Property DownloadPrivate As Boolean
<PSetting(NameOf(SiteSettings.DownloadFavorite), NameOf(MySettings))>
Friend Property DownloadFavorite As Boolean
<PSetting(Caption:="Download gifs")>
Friend Property DownloadGifs As Boolean
<PSetting(NameOf(SiteSettings.DownloadPhotoOnlyFromModelHub), NameOf(MySettings), Caption:="Download photo only from ModelHub")>
@@ -18,13 +26,22 @@ Namespace API.PornHub
Private ReadOnly Property MySettings As SiteSettings
Friend Sub New(ByVal u As UserData)
DownloadUHD = u.DownloadUHD
DownloadUploaded = u.DownloadUploaded
DownloadTagged = u.DownloadTagged
DownloadPrivate = u.DownloadPrivate
DownloadFavorite = u.DownloadFavorite
DownloadGifs = u.DownloadGifs
DownloadPhotoOnlyFromModelHub = u.DownloadPhotoOnlyFromModelHub
QueryString = u.QueryString
MySettings = u.HOST.Source
End Sub
Friend Sub New(ByVal s As SiteSettings)
Dim v As CheckState = CInt(s.DownloadGifs.Value)
DownloadUHD = s.DownloadUHD.Value
DownloadUploaded = s.DownloadUploaded.Value
DownloadTagged = s.DownloadTagged.Value
DownloadPrivate = s.DownloadPrivate.Value
DownloadFavorite = s.DownloadFavorite.Value
DownloadGifs = Not v = CheckState.Unchecked
DownloadPhotoOnlyFromModelHub = s.DownloadPhotoOnlyFromModelHub.Value
MySettings = s

View File

@@ -0,0 +1,18 @@
' 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.Reddit
Friend Interface IChannelLimits
Property AutoGetLimits As Boolean
Property DownloadLimitCount As Integer?
Property DownloadLimitPost As String
Property DownloadLimitDate As Date?
Overloads Sub SetLimit(Optional ByVal Post As String = "", Optional ByVal Count As Integer? = Nothing, Optional ByVal [Date] As Date? = Nothing)
Overloads Sub SetLimit(ByVal Source As IChannelLimits)
End Interface
End Namespace

View File

@@ -75,6 +75,7 @@ Namespace API.Reddit
ProgressPre = New PreProgress(Progress)
Me.UsePreProgress = UsePreProgress
Cache = New CacheKeeper($"{OutFile.PathWithSeparator}_{Base.M3U8Base.TempCacheFolderName}\")
Cache.CacheDeleteError = Base.CacheDeletionError(Cache)
CacheFiles = Cache.NewInstance
End Sub
#Region "Internal functions"

View File

@@ -9,12 +9,16 @@
Imports SCrawler.API.Base
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Documents.JSON
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports DownDetector = SCrawler.API.Base.DownDetector
Imports Download = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Reddit
<Manifest(RedditSiteKey), SavedPosts, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Icons"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.RedditIcon_128
@@ -25,36 +29,85 @@ Namespace API.Reddit
Return My.Resources.SiteResources.RedditPic_512
End Get
End Property
<PropertyOption(ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
#End Region
#Region "Declarations"
#Region "Authorization"
<PropertyOption(ControlText:="Login", ControlToolTip:="Your authorization username", IsAuth:=True), PXML>
Friend ReadOnly Property AuthUserName As PropertyValue
<PropertyOption(ControlText:="Password", ControlToolTip:="Your authorization password", IsAuth:=True), PXML>
Friend ReadOnly Property AuthPassword As PropertyValue
<PropertyOption(ControlText:="Client ID", ControlToolTip:="Your registered app client ID", IsAuth:=True), PXML>
Friend ReadOnly Property ApiClientID As PropertyValue
<PropertyOption(ControlText:="Client Secret", ControlToolTip:="Your registered app client secret", IsAuth:=True), PXML>
Friend ReadOnly Property ApiClientSecret As PropertyValue
<PropertyOption(ControlText:="Bearer token",
ControlToolTip:="Bearer token (can be null)." & vbCr &
"If you are using cookies to download the timeline, it is highly recommended that you add a token." & vbCr &
"You can find different tokens in the responses. Make sure that bearer token belongs to Reddit and not RedGifs." & vbCr &
"There is not need to add a token if you are not using cookies to download the timeline.", IsAuth:=True)>
Friend ReadOnly Property BearerToken As PropertyValue
#Region "TokenUpdateInterval"
<PropertyOption(ControlText:="Token refresh interval", ControlToolTip:="Interval (in minutes) to refresh the token",
AllowNull:=False, LeftOffset:=120, IsAuth:=True), PXML>
Friend ReadOnly Property TokenUpdateInterval As PropertyValue
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
#End Region
<PXML> Private ReadOnly Property BearerTokenDateUpdate As PropertyValue
<PropertyOption(ControlText:="Use the token to download the timeline", IsAuth:=True), PXML>
Friend ReadOnly Property UseTokenForTimelines As PropertyValue
<PropertyOption(ControlText:="Use the token to download saved posts", IsAuth:=True), PXML>
Friend ReadOnly Property UseTokenForSavedPosts As PropertyValue
<PropertyOption(ControlText:="Use cookies to download the timeline", IsAuth:=True), PXML>
Friend ReadOnly Property UseCookiesForTimelines As PropertyValue
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip, IsAuth:=True), PXML>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos"), PXML>
#End Region
#Region "Other"
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos", IsAuth:=False), PXML>
Friend ReadOnly Property UseM3U8 As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New(RedditSite, "reddit.com")
Dim token$
With Responser
Dim d% = .Decoders.Count
.Decoders.ListAddList({SymbolsConverter.Converters.Unicode, SymbolsConverter.Converters.HTML}, LAP.NotContainsOnly)
If d <> .Decoders.Count Then .SaveSettings()
token = .Headers.Value(DeclaredNames.Header_Authorization)
End With
AuthUserName = New PropertyValue(String.Empty, GetType(String))
AuthPassword = New PropertyValue(String.Empty, GetType(String))
ApiClientID = New PropertyValue(String.Empty, GetType(String))
ApiClientSecret = New PropertyValue(String.Empty, GetType(String))
BearerToken = New PropertyValue(token, GetType(String), Sub(v) Responser.Headers.Add(DeclaredNames.Header_Authorization, v))
TokenUpdateInterval = New PropertyValue(60 * 12)
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
BearerTokenDateUpdate = New PropertyValue(Now.AddYears(-1))
UseTokenForTimelines = New PropertyValue(False)
UseTokenForSavedPosts = New PropertyValue(False)
UseCookiesForTimelines = New PropertyValue(False)
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
UseM3U8 = New PropertyValue(True)
UrlPatternUser = "https://www.reddit.com/{0}/{1}/"
ImageVideoContains = "reddit.com"
UserRegex = RParams.DM("[htps:/]{7,8}.*?reddit.com/([user]{1,4})/([^/]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
End Sub
#End Region
#Region "GetInstance"
Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider
Return New UserData
End Function
Friend Const ChannelOption As String = "r"
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Dim l As List(Of String) = RegexReplace(UserURL, UserRegex)
If l.ListExists(3) Then
Dim n$ = l(2)
If Not l(1).IsEmptyString AndAlso l(1) = ChannelOption Then n &= $"@{ChannelOption}"
Return New ExchangeOptions(Site, n)
Else
Return Nothing
End If
#End Region
#Region "Available, UpdateRedGifsToken"
Friend Property SessionInterrupted As Boolean = False
Friend Overrides Function ReadyToDownload(ByVal What As Download) As Boolean
If What = Download.Main Then Return Not SessionInterrupted Else Return True
End Function
Friend Overrides Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean
Try
@@ -72,29 +125,40 @@ Namespace API.Reddit
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
UpdateRedGifsToken()
Return trueValue
If trueValue Then UpdateRedGifsToken()
Return trueValue AndAlso UpdateTokenIfRequired()
Else
Return False
End If
End If
End If
End If
UpdateRedGifsToken()
Return trueValue
If trueValue Then UpdateRedGifsToken()
Return trueValue AndAlso UpdateTokenIfRequired()
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[API.Reddit.SiteSettings.Available]", True)
End Try
End Function
Friend Overrides Sub DownloadDone(ByVal What As Download)
SessionInterrupted = False
MyBase.DownloadDone(What)
End Sub
Private Sub UpdateRedGifsToken()
DirectCast(Settings(RedGifs.RedGifsSiteKey).Source, RedGifs.SiteSettings).UpdateTokenIfRequired()
End Sub
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
#End Region
#Region "IsMyUser, GetUserUrl, GetUserPostUrl"
Friend Const ChannelOption As String = "r"
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Dim l As List(Of String) = RegexReplace(UserURL, UserRegex)
If l.ListExists(3) Then
Dim n$ = l(2)
If Not l(1).IsEmptyString AndAlso l(1) = ChannelOption Then n &= $"@{ChannelOption}"
Return New ExchangeOptions(Site, n)
Else
Return Nothing
End If
End Sub
End Function
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
With DirectCast(User, UserData) : Return String.Format(UrlPatternUser, IIf(.IsChannel, ChannelOption, "user"), .TrueName) : End With
End Function
@@ -105,5 +169,90 @@ Namespace API.Reddit
Return String.Empty
End If
End Function
#End Region
#Region "UserOptions"
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
End If
End Sub
#End Region
#Region "BeginEdit, Update"
Private _OldTokenValue As String = String.Empty
Friend Overrides Sub BeginEdit()
_OldTokenValue = BearerToken.Value
MyBase.BeginEdit()
End Sub
Friend Overrides Sub Update()
If _SiteEditorFormOpened Then
Dim newTokenValue$ = BearerToken.Value
If Not newTokenValue.IsEmptyString AndAlso Not newTokenValue = _OldTokenValue Then BearerTokenDateUpdate.Value = Now
End If
MyBase.Update()
End Sub
#End Region
#Region "Token"
<PropertiesDataChecker({NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret)})>
Private Function TokenPropertiesChecker(ByVal p As IEnumerable(Of PropertyData)) As Boolean
If p.ListExists Then
Dim wrong As New List(Of String)
For i% = 0 To p.Count - 1
If CStr(p(i).Value).IsEmptyString Then wrong.Add(p(i).Name)
Next
If wrong.Count > 0 Then
MsgBoxE({$"You have not completed the following fields: {wrong.ListToString}." & vbCr &
"To use OAuth authorization, all authorization fields must be filled in.", "Validate token fields"}, vbCritical)
Return False
Else
Return True
End If
End If
Return False
End Function
Private Function UpdateTokenIfRequired() As Boolean
If (CBool(UseTokenForTimelines.Value) Or CBool(UseTokenForSavedPosts.Value)) AndAlso
{AuthUserName.Value, AuthPassword.Value, ApiClientID.Value, ApiClientSecret.Value}.All(Function(v$) Not v.IsEmptyString) Then
If CDate(BearerTokenDateUpdate.Value).AddMinutes(TokenUpdateInterval.Value) <= Now Then Return UpdateToken()
End If
Return True
End Function
Private Overloads Function UpdateToken() As Boolean
Return UpdateToken(AuthUserName.Value, AuthPassword.Value, ApiClientID.Value, ApiClientSecret.Value)
End Function
<PropertyUpdater(NameOf(BearerToken), {NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret)})>
Private Overloads Function UpdateToken(ByVal UserName As String, ByVal Password As String, ByVal ClientID As String, ByVal ClientSecret As String) As Boolean
Try
Dim result As Boolean = True
If {UserName, Password, ClientID, ClientSecret}.All(Function(v) Not v.IsEmptyString) Then
result = False
Dim r$ = String.Empty
Using resp As New Responser With {
.Mode = Responser.Modes.Curl,
.Method = "POST",
.CurlArgumentsLeft = $"-d ""grant_type=password&username={UserName}&password={Password}"" --user ""{ClientID}:{ClientSecret}"""
}
r = resp.GetResponse("https://www.reddit.com/api/v1/access_token")
End Using
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
Dim newToken$ = j.Value("access_token")
If Not newToken.IsEmptyString Then
BearerToken.Value = $"Bearer {newToken}"
BearerTokenDateUpdate.Value = Now
Responser.SaveSettings()
result = True
End If
End If
End Using
End If
End If
Return result
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[Reddit.SiteSettings.UpdateToken]", False)
End Try
End Function
#End Region
End Class
End Namespace

View File

@@ -22,7 +22,7 @@ Imports UTypes = SCrawler.API.Base.UserMedia.Types
Imports CView = SCrawler.API.Reddit.IRedditView.View
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit
Friend Class UserData : Inherits UserDataBase : Implements IChannelData, IRedditView
Friend Class UserData : Inherits UserDataBase : Implements IChannelLimits, IRedditView
#Region "XML names"
Private Const Name_TrueName As String = "TrueName"
#End Region
@@ -46,6 +46,11 @@ Namespace API.Reddit
End Property
Friend Property IsChannel As Boolean = False
Friend Property TrueName As String = String.Empty
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {CannelsLabelName, CannelsLabelName_ChannelsForm, UserLabelName}
End Get
End Property
#End Region
#Region "Channels Support"
#Region "IChannelLimits Support"
@@ -70,9 +75,9 @@ Namespace API.Reddit
#End Region
Friend Property ChannelInfo As Channel
Private ReadOnly ChannelPostsNames As List(Of String)
Friend Property SkipExistsUsers As Boolean = False Implements IChannelData.SkipExistsUsers
Friend Property SkipExistsUsers As Boolean = False
Private ReadOnly _ExistsUsersNames As List(Of String)
Friend Property SaveToCache As Boolean = False Implements IChannelData.SaveToCache
Friend Property SaveToCache As Boolean = False
Friend Function GetNewChannelPosts() As IEnumerable(Of UserPost)
If _ContentNew.Count > 0 Then Return (From c As UserMedia In _ContentNew
Where Not c.Post.CachedFile.IsEmptyString And c.State = UStates.Downloaded
@@ -127,7 +132,7 @@ Namespace API.Reddit
End Sub
#End Region
#Region "Load and Update user info"
Private Sub UpdateNames()
Private Function UpdateNames() As Boolean
If TrueName.IsEmptyString Then
Dim n$() = Name.Split("@")
If n.ListExists Then
@@ -145,9 +150,11 @@ Namespace API.Reddit
Settings.Labels.Add(l)
Labels.ListAddValue(l, LNC)
Labels.Sort()
Return True
End If
End If
End Sub
Return False
End Function
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
@@ -157,7 +164,7 @@ Namespace API.Reddit
TrueName = .Value(Name_TrueName)
UpdateNames()
Else
UpdateNames()
If UpdateNames() Then .Value(Name_LabelsName) = LabelsString
.Add(Name_ViewMode, CInt(ViewMode))
.Add(Name_ViewPeriod, CInt(ViewPeriod))
.Add(Name_IsChannel, IsChannel.BoolToInteger)
@@ -198,6 +205,15 @@ Namespace API.Reddit
End If
End Sub
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
With MySiteSettings
If IsSavedPosts Then
If Not CBool(.UseTokenForSavedPosts.Value) Then Responser.Headers.Remove(DeclaredNames.Header_Authorization)
Else
If Not CBool(.UseCookiesForTimelines.Value) Then Responser.Cookies.Clear()
If Not CBool(.UseTokenForTimelines.Value) Then Responser.Headers.Remove(DeclaredNames.Header_Authorization)
End If
End With
_TotalPostsDownloaded = 0
If IsSavedPosts Then
Responser.DecodersError = EDP.ReturnValue
@@ -302,7 +318,7 @@ Namespace API.Reddit
End If
End Using
If POST.IsEmptyString And ExistsDetected Then Exit Sub
If Not PostID.IsEmptyString And NewPostDetected Then DownloadDataUser(PostID, Token)
If Not _PostID().IsEmptyString And NewPostDetected Then DownloadDataUser(_PostID(), Token)
End If
_completed = True
Catch ex As Exception
@@ -979,8 +995,13 @@ Namespace API.Reddit
UserSuspended = True
ElseIf .StatusCode = HttpStatusCode.BadGateway Or .StatusCode = HttpStatusCode.ServiceUnavailable Then
MyMainLOG = $"[{CInt(Responser.StatusCode)}] Reddit is currently unavailable ({ToString()})"
Throw New Plugin.ExitException With {.Silent = True}
ElseIf .StatusCode = HttpStatusCode.GatewayTimeout Then
Return 1
ElseIf .StatusCode = HttpStatusCode.Unauthorized Then
MyMainLOG = $"[{CInt(Responser.StatusCode)}] Reddit credentials expired ({ToString()})"
MySiteSettings.SessionInterrupted = True
Throw New Plugin.ExitException With {.Silent = True}
ElseIf .StatusCode = HttpStatusCode.InternalServerError Then
If Not IsNothing(EObj) AndAlso IsNumeric(EObj) AndAlso CInt(EObj) = HttpStatusCode.InternalServerError Then Return 1
Return HttpStatusCode.InternalServerError

View File

@@ -28,7 +28,7 @@ Namespace API.RedGifs
Return My.Resources.SiteResources.RedGifsPic_32
End Get
End Property
<PropertyOption(ControlToolTip:="Bearer token", AllowNull:=False), ControlNumber(1)>
<PropertyOption(ControlToolTip:="Bearer token", AllowNull:=False), DependentFields(NameOf(UserAgent)), ControlNumber(1)>
Friend ReadOnly Property Token As PropertyValue
<PropertyOption, ControlNumber(2)>
Private ReadOnly Property UserAgent As PropertyValue
@@ -38,22 +38,6 @@ Namespace API.RedGifs
<PropertyOption(ControlText:="Token refresh interval", ControlToolTip:="Interval (in minutes) to refresh the token", AllowNull:=False, LeftOffset:=120),
PXML, ControlNumber(0)>
Friend ReadOnly Property TokenUpdateInterval As PropertyValue
Private Class TokenIntervalProvider : Inherits FieldsCheckerProviderBase
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
TypeError = False
ErrorMessage = String.Empty
If Not ACheck(Of Integer)(Value) Then
TypeError = True
ElseIf CInt(Value) > 0 Then
Return Value
Else
ErrorMessage = $"The value of [{Name}] field must be greater than or equal to 1"
HasError = True
End If
Return Nothing
End Function
End Class
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
#End Region
@@ -64,7 +48,6 @@ Namespace API.RedGifs
Dim t$ = String.Empty
With Responser
.Mode = Responser.Modes.WebClient
If Not .UserAgentExists Then .UserAgent = ParserUserAgent
.ClientWebUseCookies = False
.ClientWebUseHeaders = True
t = .Headers.Value(TokenName)
@@ -73,7 +56,8 @@ Namespace API.RedGifs
UserAgent = New PropertyValue(Responser.UserAgent, GetType(String), Sub(v) UpdateResponse(NameOf(UserAgent), v))
TokenLastDateUpdated = New PropertyValue(Now.AddYears(-1), GetType(Date))
TokenUpdateInterval = New PropertyValue(60 * 12, GetType(Integer))
TokenUpdateIntervalProvider = New TokenIntervalProvider
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
_AllowUserAgentUpdate = False
UrlPatternUser = "https://www.redgifs.com/users/{0}/"
UserRegex = RParams.DMS("[htps:/]{7,8}.*?redgifs.com/users/([^/]+)", 1)
ImageVideoContains = "redgifs"

View File

@@ -18,5 +18,9 @@ Namespace API.ThisVid
Friend ReadOnly RegExAlbumID As RParams = RParams.DMS("albumId:.'(\d+)'", 1)
Friend ReadOnly RegExAlbumImagesList As RParams = RParams.DMS("""([^""]+?image\d+/?)""", 1, RegexReturn.List, EDP.ReturnValue)
Friend ReadOnly RegExAlbumImageUrl As RParams = RParams.DMS("\<img src=""(https?://media.thisvid.com/contents/albums/[^""]+?)""", 1, EDP.ReturnValue)
Friend ReadOnly RegExVideosThumb1 As RParams = RParams.DMS("preview_url:\s*'([^""']+)'", 1, EDP.ReturnValue)
Friend ReadOnly RegExVideosThumb2 As RParams = RParams.DMS("preview_url1:\s*'([^""']+)'", 1, EDP.ReturnValue)
Friend ReadOnly RegExVideoTitle As RParams = RParams.DMS("meta property=.og:title..content=""([^""]*)""", 1, EDP.ReturnValue)
End Module
End Namespace

View File

@@ -9,6 +9,8 @@
Imports SCrawler.API.Base
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.ThisVid
<Manifest(ThisVidSiteKey), SeparatedTasks(1), SpecialForm(False), SavedPosts>
@@ -28,6 +30,8 @@ Namespace API.ThisVid
Friend ReadOnly Property DownloadPublic As PropertyValue
<PXML, PropertyOption(ControlText:="Private videos", ControlToolTip:="Download private videos")>
Friend ReadOnly Property DownloadPrivate As PropertyValue
<PXML, PropertyOption(ControlText:="Favourite videos", ControlToolTip:="Download favourite videos")>
Friend ReadOnly Property DownloadFavourite As PropertyValue
<PXML, PropertyOption(ControlText:="Different folders",
ControlToolTip:="Use different folders to store video files." & vbCr &
"If true, then public videos will be stored in the 'Public' folder, private - in the 'Private' folder." & vbCr &
@@ -37,9 +41,16 @@ Namespace API.ThisVid
#Region "Initializer"
Friend Sub New()
MyBase.New("ThisVid", "thisvid.com")
With Responser
.CookiesExtractMode = Responser.CookiesExtractModes.Any
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll
.CookiesExtractedAutoSave = False
End With
DownloadPublic = New PropertyValue(True)
DownloadPrivate = New PropertyValue(True)
DownloadFavourite = New PropertyValue(False)
DifferentFolders = New PropertyValue(True)
_SubscriptionsAllowed = True
CheckNetscapeCookiesOnEndInit = True
UseNetscapeCookies = True
UserRegex = RParams.DMS("thisvid.com/members/(\d+)", 1)
@@ -47,17 +58,100 @@ Namespace API.ThisVid
ImageVideoContains = "https://thisvid.com/videos/"
End Sub
#End Region
#Region "GetInstance, GetSpecialData"
#Region "GetInstance"
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
Return New UserData
End Function
#End Region
#Region "UpdateCookies"
Friend Sub UpdateCookies(ByVal Source As Responser)
Responser.Cookies.Clear()
Responser.Cookies.AddRange(Source.Cookies)
Update_SaveCookiesNetscape(True)
End Sub
#End Region
#Region "Downloading"
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
Return Settings.YtdlpFile.Exists And (What = ISiteSettings.Download.SingleObject Or Responser.CookiesExists)
End Function
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As ISiteSettings.Download)
If CookiesNetscapeFile.Exists Then
With Responser.Cookies
.Clear()
.AddRange(CookieKeeper.ParseNetscapeText(CookiesNetscapeFile.GetText, EDP.ReturnValue),, EDP.ReturnValue)
End With
End If
MyBase.BeforeStartDownload(User, What)
End Sub
#End Region
#Region "UserOptions"
#Region "GetUserUrl, IsMyUser, UserOptions"
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
With DirectCast(User, UserData)
If .IsUser Then
Return MyBase.GetUserUrl(User)
Else
Return .GetNonUserUrl(0)
End If
End With
End Function
Private ReadOnly AbstractExtractor As RParams = RParams.DM("[^/]+", 0, RegexReturn.List, EDP.ReturnValue)
Private Const P_Albums As String = "albums"
Friend Const P_Tags As String = "tags"
Friend Const P_Categories As String = "categories"
Friend Const P_Search As String = "search"
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
If Not UserURL.IsEmptyString AndAlso UserURL.ToLower.Contains("thisvid.com") Then
Dim user$ = RegexReplace(UserURL, UserRegex)
If Not user.IsEmptyString Then
Return New ExchangeOptions(Site, user)
Else
Dim data As List(Of String) = RegexReplace(UserURL.ToLower, AbstractExtractor)
If data.ListExists Then
If data.Count >= 3 AndAlso Not data(2).IsEmptyString Then
Dim mode As SiteModes
Dim n$ = String.Empty, opt$ = String.Empty
Dim __data As Func(Of Integer, String) = Function(i) If(data.Count - 1 >= i, data(i), String.Empty)
Select Case data(2)
Case P_Albums
Case P_Tags
mode = SiteModes.Tags
If Not __data(3).IsEmptyString Then
n = __data(3)
If Not __data(4).IsEmptyString AndAlso Not IsNumeric(__data(4)) Then opt = __data(4)
End If
Case P_Categories
mode = SiteModes.Categories
If Not __data(3).IsEmptyString Then
n = __data(3)
If Not __data(4).IsEmptyString AndAlso Not IsNumeric(__data(4)) Then opt = __data(4)
End If
Case Else
mode = SiteModes.Search
If Not __data(3).IsEmptyString AndAlso Not IsNumeric(__data(3)) Then n = __data(3)
If n.IsEmptyString AndAlso Not __data(4).IsEmptyString AndAlso Not IsNumeric(__data(4)) Then n = __data(4)
If Not n.IsEmptyString Then n = n.TrimStart("?", "q", "=")
If Not n.IsEmptyString Then
If __data(2).IsEmptyString Then
n = String.Empty
Else
opt = __data(2)
End If
End If
End Select
opt = $"{n}@{opt}"
n = n.StringRemoveWinForbiddenSymbols
If Not n.IsEmptyString Then
n = $"{CInt(mode)}@{n}"
Return New ExchangeOptions(Site, n) With {.Options = opt}
End If
End If
End If
End If
End If
Return Nothing
End Function
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions(Me)
If OpenForm Then

View File

@@ -18,7 +18,11 @@ Namespace API.ThisVid
#Region "XML names"
Private Const Name_DownloadPublic As String = "DownloadPublic"
Private Const Name_DownloadPrivate As String = "DownloadPrivate"
Private Const Name_DownloadFavourite As String = "DownloadFavourite"
Private Const Name_DifferentFolders As String = "DifferentFolders"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_Arguments As String = "Arguments"
#End Region
#Region "Structures"
Private Structure Album : Implements IRegExCreator
@@ -34,21 +38,127 @@ Namespace API.ThisVid
End Structure
#End Region
#Region "Declarations"
Friend Overrides ReadOnly Property FeedIsUser As Boolean
Get
Return IsUser
End Get
End Property
Friend Property DownloadPublic As Boolean = True
Friend Property DownloadPrivate As Boolean = True
Friend Property DownloadFavourite As Boolean = False
Friend Property DifferentFolders As Boolean = True
Friend Property TrueName As String = String.Empty
Friend Property SiteMode As SiteModes = SiteModes.User
Private Property Arguments As String = String.Empty
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
End Get
End Property
Friend Property QueryString As String
Get
If SiteMode = SiteModes.User Then
Return String.Empty
Else
Return GetNonUserUrl(0)
End If
End Get
Set(ByVal q As String)
UpdateUserOptions(True, q)
End Set
End Property
Friend ReadOnly Property IsUser As Boolean
Get
Return SiteMode = SiteModes.User
End Get
End Property
Private ReadOnly Property MySettings As SiteSettings
Get
Return DirectCast(HOST.Source, SiteSettings)
End Get
End Property
#End Region
#Region "Loaders"
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
If Not Force OrElse (Not SiteMode = SiteModes.User AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
Dim eObj As Plugin.ExchangeOptions = Nothing
If Force Then eObj = MySettings.IsMyUser(NewUrl)
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And TrueName.IsEmptyString) Then
Dim n$() = If(Force, eObj.UserName, Name).Split("@")
If n.ListExists(2) Then
If Force And SiteMode = SiteModes.User Then Return False
Dim __TrueName$, __Arguments$
Dim __Mode As SiteModes
Dim __ForceApply As Boolean = False
Dim opt$() = If(Force, eObj.Options, Options).Split("@")
__Mode = CInt(n(0))
If opt.Length > 1 Then
__Arguments = opt.ListTake(0, 100, EDP.ReturnValue).ListToString(String.Empty)
Else
__Arguments = String.Empty
End If
__TrueName = n(1)
If Force AndAlso (Not TrueName = __TrueName Or Not SiteMode = __Mode) Then
If ValidateChangeSearchOptions(ToStringForLog, $"{__Mode}: {__TrueName}", $"{SiteMode}: {TrueName}") Then
__ForceApply = True
Else
Return False
End If
End If
Arguments = __Arguments
Options = If(Force, eObj.Options, Options)
If Not Force Then
TrueName = __TrueName
SiteMode = __Mode
Settings.Labels.Add(SearchRequestLabelName)
Labels.ListAddValue(SearchRequestLabelName, LNC)
Labels.Sort()
UserSiteName = $"{SiteMode}: {TrueName}"
If FriendlyName.IsEmptyString Then FriendlyName = UserSiteName
ElseIf Force And __ForceApply Then
TrueName = __TrueName
SiteMode = __Mode
End If
Return True
Else
SiteMode = SiteModes.User
TrueName = Name
End If
End If
End If
Return False
End Function
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
DownloadPublic = .Value(Name_DownloadPublic).FromXML(Of Boolean)(True)
DownloadPrivate = .Value(Name_DownloadPrivate).FromXML(Of Boolean)(True)
DownloadFavourite = .Value(Name_DownloadFavourite).FromXML(Of Boolean)(False)
DifferentFolders = .Value(Name_DifferentFolders).FromXML(Of Boolean)(True)
TrueName = .Value(Name_TrueName)
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
Arguments = .Value(Name_Arguments)
UpdateUserOptions()
Else
If UpdateUserOptions() Then
.Value(Name_LabelsName) = LabelsString
.Value(Name_UserSiteName) = UserSiteName
.Value(Name_FriendlyName) = FriendlyName
End If
.Add(Name_DownloadPublic, DownloadPublic.BoolToInteger)
.Add(Name_DownloadPrivate, DownloadPrivate.BoolToInteger)
.Add(Name_DownloadFavourite, DownloadFavourite.BoolToInteger)
.Add(Name_DifferentFolders, DifferentFolders.BoolToInteger)
.Add(Name_TrueName, TrueName)
.Add(Name_SiteMode, CInt(SiteMode))
.Add(Name_Arguments, Arguments)
'Debug.WriteLine(GetNonUserUrl(0))
'Debug.WriteLine(GetNonUserUrl(2))
End If
End With
End Sub
@@ -60,7 +170,9 @@ Namespace API.ThisVid
With DirectCast(Obj, UserExchangeOptions)
DownloadPublic = .DownloadPublic
DownloadPrivate = .DownloadPrivate
DownloadFavourite = .DownloadFavourite
DifferentFolders = .DifferentFolders
QueryString = .QueryString
End With
End If
End Sub
@@ -111,37 +223,73 @@ Namespace API.ThisVid
End Function
#End Region
#Region "Download functions"
Private AddedCount As Integer = 0
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
AddedCount = 0
Responser.Cookies.ChangedAllowInternalDrop = False
Responser.Cookies.Changed = False
If ID.IsEmptyString Then ID = Name
If IsValid() Then
If Not IsUser OrElse IsValid() Then
If IsSavedPosts Then
DownloadData(1, True, Token)
DownloadData(1, 0, Token)
DownloadData_Images(Token)
Else
If DownloadVideos Then
If DownloadPublic Then DownloadData(1, True, Token)
If DownloadPrivate Then DownloadData(1, False, Token)
If IsUser Then
If DownloadVideos Then
If DownloadPublic Then DownloadData(1, 0, Token)
If DownloadPrivate Then DownloadData(1, 1, Token)
If DownloadFavourite Then DownloadData(1, 2, Token)
End If
If DownloadImages And Not IsSubscription Then DownloadData_Images(Token)
Else
DownloadData(1, 0, Token)
End If
If DownloadImages Then DownloadData_Images(Token)
End If
End If
If Responser.Cookies.Changed Then MySettings.UpdateCookies(Responser) : Responser.Cookies.Changed = False
End Sub
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal IsPublic As Boolean, ByVal Token As CancellationToken)
Friend Function GetNonUserUrl(ByVal Page As Integer) As String
Dim url$ = String.Empty
Select Case SiteMode
Case SiteModes.Tags
url = $"https://thisvid.com/{SiteSettings.P_Tags}/{TrueName}/"
If Not Arguments.IsEmptyString Then url &= $"{Arguments}/"
If Page > 1 Then url &= $"{Page}/"
Case SiteModes.Categories
url = $"https://thisvid.com/{SiteSettings.P_Categories}/{TrueName}/"
If Not Arguments.IsEmptyString Then url &= $"{Arguments}/"
If Page > 1 Then url &= $"{Page}/"
Case SiteModes.Search
If Not Arguments.IsEmptyString Then
url = $"https://thisvid.com/{Arguments}/"
If Page > 1 Then url &= $"{Page}/"
url &= $"?q={TrueName}/"
End If
End Select
Return url
End Function
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal Model As Byte, ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Try
ProgressPre.ChangeMax(1)
Dim limit% = If(DownloadTopCount, -1)
Dim p$ = IIf(Page = 1, String.Empty, $"{Page}/")
If IsSavedPosts Then
URL = $"https://thisvid.com/my_favourite_videos/{p}"
ElseIf IsUser Then
URL = $"https://thisvid.com/members/{ID}/{Interaction.Switch(Model = 0, "public", Model = 1, "private", Model = 2, "favourite")}_videos/{p}"
Else
URL = $"https://thisvid.com/members/{ID}/{IIf(IsPublic, "public", "private")}_videos/{p}"
URL = GetNonUserUrl(Page)
If URL.IsEmptyString Then Throw New ArgumentNullException With {.HelpLink = 1}
End If
ThrowAny(Token)
ProgressPre.Perform()
Dim r$ = Responser.GetResponse(URL)
Dim cBefore% = _TempMediaList.Count
If Not r.IsEmptyString Then
Dim __SpecialFolder$ = IIf(DifferentFolders, IIf(IsPublic, "Public", "Private"), String.Empty)
Dim __SpecialFolder$ = If(DifferentFolders And Not IsSavedPosts And IsUser,
Interaction.Switch(Model = 0, "Public", Model = 1, "Private", Model = 2, "Favourite"),
String.Empty)
Dim l As List(Of String) = RegexReplace(r, If(IsSavedPosts, RegExVideoListSavedPosts, RegExVideoList))
If l.ListExists Then
For Each u$ In l
@@ -149,6 +297,8 @@ Namespace API.ThisVid
If Not _TempPostsList.Contains(u) Then
_TempPostsList.Add(u)
_TempMediaList.Add(New UserMedia(u) With {.Type = UserMedia.Types.VideoPre, .SpecialFolder = __SpecialFolder})
AddedCount += 1
If limit > 0 And AddedCount >= limit Then Exit Sub
Else
Exit Sub
End If
@@ -156,7 +306,8 @@ Namespace API.ThisVid
Next
End If
End If
If Not cBefore = _TempMediaList.Count Then DownloadData(Page + 1, IsPublic, Token)
If Not cBefore = _TempMediaList.Count And (IsUser Or Page < 1000) Then DownloadData(Page + 1, Model, Token)
Catch aex As ArgumentNullException When aex.HelpLink = 1
Catch ex As Exception
ProcessException(ex, Token, $"videos downloading error [{URL}]")
End Try
@@ -239,53 +390,104 @@ Namespace API.ThisVid
#End Region
#Region "ReparseVideo"
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
If IsSubscription Then
ReparseVideoSubscriptions(Token)
Else
Try
If _TempMediaList.Count > 0 Then
Dim u As UserMedia
Dim dirCmd$ = String.Empty
Dim f As SFile = Settings.YtdlpFile.File
Dim n$
Dim cookieFile As SFile = MySettings.CookiesNetscapeFile
Dim command$
Dim e As EContainer
ProgressPre.ChangeMax(_TempMediaList.Count)
For i% = _TempMediaList.Count - 1 To 0 Step -1
ProgressPre.Perform()
u = _TempMediaList(i)
If u.Type = UserMedia.Types.VideoPre Then
ThrowAny(Token)
command = $"""{f}"" --verbose --dump-json "
If cookieFile.Exists Then command &= $"--no-cookies-from-browser --cookies ""{cookieFile}"" "
command &= u.URL
e = GetJson(command)
If Not e Is Nothing Then
u.URL = e.Value("url")
u.Post = New UserPost(e.Value("id"), ADateTime.ParseUnix32(e.Value("epoch")))
If u.Post.Date.HasValue Then
Select Case CheckDatesLimit(u.Post.Date.Value, Nothing)
Case DateResult.Skip : _TempPostsList.ListAddValue(u.Post.ID, LNC) : _TempMediaList.RemoveAt(i) : Continue For
Case DateResult.Exit : Exit Sub
End Select
End If
n = TitleHtmlConverter(e.Value("title"))
If Not n.IsEmptyString Then n = n.Replace("ThisVid.com", String.Empty).StringTrim.StringTrimEnd("-").StringTrim
If n.IsEmptyString Then n = u.Post.ID
If n.IsEmptyString Then n = "VideoFile"
u.File = $"{n}.mp4"
If u.URL.IsEmptyString OrElse (Not u.Post.ID.IsEmptyString AndAlso _TempPostsList.Contains(u.Post.ID)) Then
_TempMediaList.RemoveAt(i)
Else
u.Type = UserMedia.Types.Video
_TempPostsList.Add(u.Post.ID)
_TempMediaList(i) = u
End If
e.Dispose()
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "video reparsing error")
End Try
End If
End Sub
Private Sub ReparseVideoSubscriptions(ByVal Token As CancellationToken)
Try
If _TempMediaList.Count > 0 Then
Dim u As UserMedia
Dim dirCmd$ = String.Empty
Dim f As SFile = Settings.YtdlpFile.File
Dim n$
Dim cookieFile As SFile = DirectCast(HOST.Source, SiteSettings).CookiesNetscapeFile
Dim command$
Dim e As EContainer
ProgressPre.ChangeMax(_TempMediaList.Count)
Dim n$, r$
Dim c% = 0
Progress.Maximum += _TempMediaList.Count
For i% = _TempMediaList.Count - 1 To 0 Step -1
ProgressPre.Perform()
Progress.Perform()
u = _TempMediaList(i)
If u.Type = UserMedia.Types.VideoPre Then
ThrowAny(Token)
command = $"""{f}"" --verbose --dump-json "
If cookieFile.Exists Then command &= $"--no-cookies-from-browser --cookies ""{cookieFile}"" "
command &= u.URL
e = GetJson(command)
If Not e Is Nothing Then
u.URL = e.Value("url")
u.Post = New UserPost(e.Value("id"), ADateTime.ParseUnix32(e.Value("epoch")))
If u.Post.Date.HasValue Then
Select Case CheckDatesLimit(u.Post.Date.Value, Nothing)
Case DateResult.Skip : _TempPostsList.ListAddValue(u.Post.ID, LNC) : _TempMediaList.RemoveAt(i) : Continue For
Case DateResult.Exit : Exit Sub
End Select
If Not DownloadTopCount.HasValue OrElse c <= DownloadTopCount.Value Then
ThrowAny(Token)
r = Responser.GetResponse(u.URL,, EDP.ReturnValue)
If Not r.IsEmptyString Then
n = TitleHtmlConverter(RegexReplace(r, RegExVideoTitle))
u.Post.ID = u.URL
If Not n.IsEmptyString Then n = n.Replace("ThisVid.com", String.Empty).StringTrim.StringTrimEnd("-").StringTrim
If n.IsEmptyString Then n = TitleHtmlConverter(u.URL.Replace("https://thisvid.com/videos/", String.Empty).StringTrim.StringTrimEnd("-").StringTrim)
If n.IsEmptyString Then n = "VideoFile"
u.File = $"{n}.mp4"
u.PictureOption = n
u.URL = RegexReplace(r, Regex_VideosThumb_OG_IMAGE)
If u.URL.IsEmptyString Then u.URL = RegexReplace(r, RegExVideosThumb1)
If u.URL.IsEmptyString Then u.URL = RegexReplace(r, RegExVideosThumb2)
If Not u.URL.IsEmptyString Then
u.URL = LinkFormatterSecure(u.URL)
u.Type = UserMedia.Types.Video
_TempPostsList.Add(u.Post.ID)
_TempMediaList(i) = u
c += 1
Else
_TempMediaList.RemoveAt(i)
End If
End If
n = TitleHtmlConverter(e.Value("title"))
If Not n.IsEmptyString Then n = n.Replace("ThisVid.com", String.Empty).StringTrim.StringTrimEnd("-").StringTrim
If n.IsEmptyString Then n = u.Post.ID
If n.IsEmptyString Then n = "VideoFile"
u.File = $"{n}.mp4"
If u.URL.IsEmptyString OrElse (Not u.Post.ID.IsEmptyString AndAlso _TempPostsList.Contains(u.Post.ID)) Then
_TempMediaList.RemoveAt(i)
Else
u.Type = UserMedia.Types.Video
_TempPostsList.Add(u.Post.ID)
_TempMediaList(i) = u
End If
e.Dispose()
Else
_TempMediaList.RemoveAt(i)
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "video reparsing error")
ProcessException(ex, Token, "subscriptions video reparsing error")
Finally
If Responser.Cookies.Changed Then MySettings.UpdateCookies(Responser) : Responser.Cookies.Changed = False
End Try
End Sub
#End Region

View File

@@ -8,24 +8,29 @@
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes
Namespace API.ThisVid
Friend Class UserExchangeOptions
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
<PSetting(Caption:="Download public videos")>
Friend Property DownloadPublic As Boolean = True
<PSetting(Caption:="Download private videos")>
Friend Property DownloadPrivate As Boolean = True
<PSetting(Caption:="Download favourite videos")>
Friend Property DownloadFavourite As Boolean = False
<PSetting(NameOf(SiteSettings.DifferentFolders), NameOf(MySettings), Caption:="Different video folders")>
Friend Property DifferentFolders As Boolean = True
Private ReadOnly Property MySettings As SiteSettings
Friend Sub New(ByVal s As SiteSettings)
DownloadPublic = s.DownloadPublic.Value
DownloadPrivate = s.DownloadPrivate.Value
DownloadFavourite = s.DownloadFavourite.Value
DifferentFolders = s.DifferentFolders.Value
MySettings = s
End Sub
Friend Sub New(ByVal u As UserData)
DownloadPublic = u.DownloadPublic
DownloadPrivate = u.DownloadPrivate
DownloadFavourite = u.DownloadFavourite
DifferentFolders = u.DifferentFolders
QueryString = u.QueryString
MySettings = u.HOST.Source
End Sub
End Class

View File

@@ -9,53 +9,8 @@
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.TikTok
Friend Module Declarations
Friend ReadOnly RegexEnvir As New RegexParseEnvir
Friend ReadOnly CheckDateProvider As New CustomProvider(Function(v) IIf(CType(v, Date?).HasValue, CObj(CType(v, Date?).Value), Nothing))
Friend Class RegexParseEnvir
Private ReadOnly UrlIdRegex As RParams = RParams.DMS("http[s]?://[w\.]{0,4}tiktok.com/[^/]+?/video/(\d+)", 1, EDP.ReturnValue)
Private ReadOnly RegexItemsArrPre As RParams = RParams.DMS("ItemList"":\{""user-post"":\{""list"":\[([^\[]+)\]", 1)
Private ReadOnly RegexItemsArr As RParams = RParams.DM("\d+", 0, RegexReturn.List)
Private ReadOnly VideoPattern As New RParams(String.Empty, Nothing, 1, EDP.ReturnValue)
Private ReadOnly DatePattern As New RParams(String.Empty, Nothing, 1, EDP.ReturnValue)
Private ReadOnly UserIdFromVideo As RParams = RParams.DMS("/\?a=(\d+)", 1, EDP.ReturnValue)
Friend Function GetIDList(ByVal r As String) As List(Of String)
Try
If Not r.IsEmptyString Then
Dim l As List(Of String) = Nothing
Dim IdArr$ = RegexReplace(r, RegexItemsArrPre)
If Not IdArr.IsEmptyString Then l = RegexReplace(IdArr, RegexItemsArr)
If l.ListExists Then l.RemoveAll(Function(id) id.IsEmptyString)
Return l
End If
Return Nothing
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.TikTok.RegexParseEnvir.GetIDList]")
End Try
End Function
Friend Function GetVideoData(ByVal r As String, ByVal ID As String, ByRef URL As String, ByRef [Date] As Date?) As Boolean
Try
[Date] = Nothing
URL = String.Empty
If Not r.IsEmptyString Then
VideoPattern.Pattern = "video"":\{""id"":""" & ID & """[^\}]+?""downloadAddr"":""([^""]+)"""
DatePattern.Pattern = """:{""id"":""" & ID & """,""desc"":.+?""createTime"":""(\d+)"
Dim u$ = RegexReplace(r, VideoPattern)
If Not u.IsEmptyString Then URL = SymbolsConverter.Unicode.Decode(u, EDP.ReturnValue)
Dim d$ = RegexReplace(r, DatePattern)
If Not d.IsEmptyString Then [Date] = ADateTime.ParseUnix32(d)
Return Not URL.IsEmptyString
End If
Return False
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.TikTok.RegexParseEnvir.GetVideoData]", False)
End Try
End Function
Friend Function ExtractPostID(ByVal URL As String) As String
If Not URL.IsEmptyString Then Return RegexReplace(URL, UrlIdRegex) Else Return String.Empty
End Function
Friend Function ExtractUserID(ByVal VideoUrl As String) As String
If Not VideoUrl.IsEmptyString Then Return RegexReplace(VideoUrl, UserIdFromVideo) Else Return String.Empty
End Function
End Class
Friend ReadOnly SimpleDateConverter As New ADateTime("yyyyMMdd")
Friend ReadOnly RegexTagsReplacer As RParams = RParams.DM("#\w+\s?", -1, RegexReturn.Replace,
CType(Function(input$) String.Empty, Func(Of String, String)), EDP.ReturnValue)
End Module
End Namespace

View File

@@ -11,7 +11,7 @@ Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.TikTok
<Manifest("AndyProgram_TikTok")>
<Manifest("AndyProgram_TikTok"), SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Overrides ReadOnly Property Icon As Icon
Get
@@ -23,8 +23,22 @@ Namespace API.TikTok
Return My.Resources.SiteResources.TikTokPic_192
End Get
End Property
<PropertyOption(ControlText:="Remove tags from title"), PXML>
Friend Property RemoveTagsFromTitle As PropertyValue
<PropertyOption(ControlText:="Use native title", ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML>
Friend Property TitleUseNative As PropertyValue
<PropertyOption(ControlText:="Use native title in standalone downloader",
ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML>
Friend Property TitleUseNativeSTD As PropertyValue
<PropertyOption(ControlText:="Add video ID to video title"), PXML>
Friend Property TitleAddVideoID As PropertyValue
Friend Sub New()
MyBase.New("TikTok", "www.tiktok.com")
RemoveTagsFromTitle = New PropertyValue(False)
TitleUseNative = New PropertyValue(True)
TitleUseNativeSTD = New PropertyValue(False)
TitleAddVideoID = New PropertyValue(True)
UseNetscapeCookies = True
UrlPatternUser = "https://www.tiktok.com/@{0}/"
UserRegex = RParams.DMS("[htps:/]{7,8}.*?tiktok.com/@([^/]+)", 1)
ImageVideoContains = "tiktok.com"
@@ -32,12 +46,14 @@ Namespace API.TikTok
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
Return New UserData
End Function
Friend Overrides Function BaseAuthExists() As Boolean
Return Responser.CookiesExists
End Function
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
'TODO: TikTok disabled
Return False
Return Settings.YtdlpFile.Exists
End Function
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions(Me)
If OpenForm Then
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
End Class
End Namespace

View File

@@ -8,65 +8,261 @@
' but WITHOUT ANY WARRANTY
Imports System.Threading
Imports SCrawler.API.Base
Imports SCrawler.API.YouTube.Objects
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Web.Documents.JSON
Namespace API.TikTok
Friend Class UserData : Inherits UserDataBase
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
#Region "XML names"
Private Const Name_RemoveTagsFromTitle As String = "RemoveTagsFromTitle"
Private Const Name_TitleUseNative As String = "TitleUseNative"
Private Const Name_TitleAddVideoID As String = "TitleAddVideoID"
Private Const Name_LastDownloadDate As String = "LastDownloadDate"
#End Region
#Region "Declarations"
Private ReadOnly Property MySettings As SiteSettings
Get
Return HOST.Source
End Get
End Property
Private ReadOnly Property RootCacheTikTok As ICacheKeeper
Get
With Settings.Cache
Dim f As SFile = $"{Settings.Cache.RootDirectory.PathWithSeparator}TikTokCache\"
If .ContainsFolder(f) Then
Return .GetInstance(f)
Else
f.Exists(SFO.Path, True)
With .NewInstance(Of BatchFileExchanger)(f)
.DeleteCacheOnDispose = False
.DeleteRootOnDispose = False
Return .Self
End With
End If
End With
End Get
End Property
Friend Property RemoveTagsFromTitle As Boolean = False
Friend Property TitleUseNative As Boolean = True
Friend Property TitleAddVideoID As Boolean = True
Private Property LastDownloadDate As Date? = Nothing
#End Region
#Region "Exchange"
Friend Overrides Function ExchangeOptionsGet() As Object
Return New UserExchangeOptions(Me)
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
With DirectCast(Obj, UserExchangeOptions)
RemoveTagsFromTitle = .RemoveTagsFromTitle
TitleUseNative = .TitleUseNative
TitleAddVideoID = .TitleAddVideoID
End With
End If
End Sub
#End Region
#Region "Loader"
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
RemoveTagsFromTitle = .Value(Name_RemoveTagsFromTitle).FromXML(Of Boolean)(False)
TitleUseNative = .Value(Name_TitleUseNative).FromXML(Of Boolean)(True)
TitleAddVideoID = .Value(Name_TitleAddVideoID).FromXML(Of Boolean)(True)
LastDownloadDate = AConvert(Of Date)(.Value(Name_LastDownloadDate), ADateTime.Formats.BaseDateTime, Nothing)
Else
.Add(Name_RemoveTagsFromTitle, RemoveTagsFromTitle.BoolToInteger)
.Add(Name_TitleUseNative, TitleUseNative.BoolToInteger)
.Add(Name_TitleAddVideoID, TitleAddVideoID.BoolToInteger)
.Add(Name_LastDownloadDate, AConvert(Of String)(LastDownloadDate, AModes.XML, ADateTime.Formats.BaseDateTime, String.Empty))
End If
End With
End Sub
#End Region
#Region "Initializer"
Friend Sub New()
SeparateVideoFolder = False
UseInternalDownloadFileFunction = True
End Sub
#End Region
#Region "Download functions"
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Try
Dim PostIDs As List(Of String)
Dim PostDate As Date? = Nothing
Dim PostURL$ = String.Empty
Dim r$
URL = $"https://www.tiktok.com/@{Name}"
r = Responser.GetResponse(URL)
PostIDs = RegexEnvir.GetIDList(r)
If PostIDs.ListExists Then
For Each __id$ In PostIDs
If Not _TempPostsList.Contains(__id) Then
_TempPostsList.Add(__id)
If RegexEnvir.GetVideoData(r, __id, PostURL, PostDate) Then
Select Case CheckDatesLimit(PostDate, CheckDateProvider)
Case DateResult.Skip : Continue For
Case DateResult.Exit : Exit Sub
End Select
If ID.IsEmptyString And Not PostURL.IsEmptyString Then ID = RegexEnvir.ExtractUserID(PostURL)
_TempMediaList.ListAddValue(MediaFromData(PostURL, __id, PostDate))
End If
Else
Exit Sub
Dim URL$ = $"https://www.tiktok.com/@{Name}"
Using cache As CacheKeeper = CreateCache()
Try
Dim postID$, title$, postUrl$
Dim postDate As Date?
Dim dateAfterC As Date? = Nothing
Dim dateBefore As Date? = DownloadDateTo
Dim dateAfter As Date? = DownloadDateFrom
If _ContentList.Count > 0 Then
With (From d In _ContentList Where d.Post.Date.HasValue Select d.Post.Date.Value)
If .ListExists Then dateAfterC = .Min
End With
End If
With {CStr(AConvert(Of String)(dateAfter, SimpleDateConverter, String.Empty)).FromXML(Of Integer)(-1),
CStr(AConvert(Of String)(dateAfterC, SimpleDateConverter, String.Empty)).FromXML(Of Integer)(-1)}.ListWithRemove(Function(d) d = -1)
If .ListExists Then dateAfter = AConvert(Of Date)(CStr(.Min), SimpleDateConverter, Nothing)
End With
If LastDownloadDate.HasValue Then
If dateAfter.HasValue And Not DownloadDateFrom.HasValue Then
If (LastDownloadDate.Value - dateAfter.Value).TotalDays > 1 Then dateAfter = dateAfter.Value.AddDays(1)
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]")
End Try
End If
Using b As New TokenBatch(Token)
b.ChangeDirectory(cache)
b.Encoding = BatchExecutor.UnicodeEncoding
b.Execute(CreateYTCommand(cache.RootDirectory, URL, False, dateBefore, dateAfter))
End Using
ThrowAny(Token)
Dim files As List(Of SFile) = SFile.GetFiles(cache, "*.json",, EDP.ReturnValue)
If files.ListExists Then
Dim j As EContainer
For Each file As SFile In files
j = JsonDocument.Parse(file.GetText, EDP.ReturnValue)
If j.ListExists Then
If j.Value("_type").StringToLower = "video" Then
postID = j.Value("id")
If Not _TempPostsList.Contains(postID) Then
_TempPostsList.Add(postID)
Else
Exit Sub
End If
title = j.Value("title").StringRemoveWinForbiddenSymbols
If title.IsEmptyString Or Not TitleUseNative Then
title = postID
Else
If RemoveTagsFromTitle Then title = RegexReplace(title, RegexTagsReplacer)
title = title.StringTrim
If title.IsEmptyString Then
title = postID
ElseIf TitleAddVideoID Then
title &= $" ({postID})"
End If
End If
postDate = AConvert(Of Date)(j.Value("timestamp"), UnixDate32Provider, Nothing)
If Not postDate.HasValue Then postDate = AConvert(Of Date)(j.Value("upload_date"), SimpleDateConverter, Nothing)
Select Case CheckDatesLimit(postDate, SimpleDateConverter)
Case DateResult.Skip : Continue For
Case DateResult.Exit : Exit Sub
End Select
postUrl = j.Value("webpage_url")
If postUrl.IsEmptyString Then postUrl = $"https://www.tiktok.com/@{Name}/video/{postID}"
_TempMediaList.Add(New UserMedia(postUrl, UserMedia.Types.Video) With {
.File = $"{title}.mp4", .Post = New UserPost(postID, postDate)})
End If
j.Dispose()
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]")
End Try
End Using
End Sub
#End Region
#Region "ReparseMissing"
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
If ContentMissingExists Then
Dim m As UserMedia
Dim i%
Dim rList As New List(Of Integer)
For i = 0 To _ContentList.Count - 1
If _ContentList(i).State = UserMedia.States.Missing Then
m = _ContentList(i)
m.URL = m.URL_BASE
_TempMediaList.Add(m)
rList.Add(i)
End If
Next
If rList.Count > 0 Then
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
End If
End If
End Sub
#End Region
#Region "YT-DLP Support"
Private Function CreateYTCommand(ByVal Output As SFile, ByVal URL As String, ByVal IsDownload As Boolean,
Optional ByVal DateBefore As Date? = Nothing, Optional ByVal DateAfter As Date? = Nothing,
Optional ByVal PrintTitle As Boolean = False, Optional ByVal SupportOutput As Boolean = True) As String
Dim command$ = $"""{Settings.YtdlpFile}"" "
If Not IsDownload Then command &= "--write-info-json --skip-download "
If PrintTitle Then
If Not command.Contains("--skip-download") Then command &= "--skip-download "
command &= "--print title "
End If
If DateBefore.HasValue Then command &= $"--datebefore {DateBefore.Value.AddDays(1).ToStringDate(SimpleDateConverter)} "
If DateAfter.HasValue Then command &= $"--dateafter {DateAfter.Value.AddDays(-1).ToStringDate(SimpleDateConverter)} "
If MySettings.CookiesNetscapeFile.Exists Then command &= $"--no-cookies-from-browser --cookies ""{MySettings.CookiesNetscapeFile}"" "
command &= $"{URL} "
If SupportOutput Then
If IsDownload Then
command &= $"-o ""{Output}"""
Else
command &= "-o %(id)s"
End If
End If
Return command
End Function
#End Region
#Region "DownloadContent, DownloadFile"
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
DownloadContentDefault(Token)
End Sub
Private Function MediaFromData(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As Date?) As UserMedia
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
Dim m As New UserMedia(_URL, UserMedia.Types.Video) With {.Post = New UserPost With {.ID = PostID}}
If Not m.URL.IsEmptyString Then m.File = $"{PostID}.mp4"
If PostDate.HasValue Then m.Post.Date = PostDate
Return m
Protected Overrides Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
Using b As New TokenBatch(Token) With {.FileExchanger = RootCacheTikTok}
b.Encoding = BatchExecutor.UnicodeEncoding
b.Execute(CreateYTCommand(DestinationFile, URL, True))
End Using
Return DestinationFile
End Function
#End Region
#Region "DownloadSingleObject"
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
Dim f$ = String.Empty
If CBool(MySettings.TitleUseNativeSTD.Value) Then
Using b As New BatchExecutor(True) With {
.Encoding = BatchExecutor.UnicodeEncoding,
.CleanAutomaticallyViaRegEx = True,
.CleanAutomaticallyViaRegExRemoveAllCommands = True
}
b.Execute(CreateYTCommand(Nothing, Data.URL, True,,, True, False))
b.Clean()
With b.OutputData
If .Count > 0 Then
For Each vData$ In .Self
If Not vData.Contains($": {BatchExecutor.UnicodeEncoding}") Then f = vData : Exit For
Next
End If
End With
End Using
End If
Dim m As New UserMedia(Data.URL, UserMedia.Types.Video)
If Not f.IsEmptyString Then f = TitleHtmlConverter(f)
If Not f.IsEmptyString Then
If CBool(MySettings.RemoveTagsFromTitle.Value) Then f = RegexReplace(f, RegexTagsReplacer)
f = f.StringTrim
If Not f.IsEmptyString Then
If CBool(MySettings.TitleAddVideoID.Value) Then f &= $" ({m.File.Name})"
m.File.Name = f
End If
End If
_TempMediaList.Add(m)
End Sub
#End Region
#Region "Exception"
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal EObj As Object = Nothing) As Integer
If Responser.Status = Net.WebExceptionStatus.ConnectionClosed Then
UserExists = False
Return 1
Else
Return 0
End If
Return 0
End Function
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,32 @@
' 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.Attributes
Namespace API.TikTok
Friend Class UserExchangeOptions
<PSetting(NameOf(SiteSettings.RemoveTagsFromTitle), NameOf(MySettings))>
Friend Property RemoveTagsFromTitle As Boolean
<PSetting(NameOf(SiteSettings.TitleUseNative), NameOf(MySettings))>
Friend Property TitleUseNative As Boolean
<PSetting(NameOf(SiteSettings.TitleAddVideoID), NameOf(MySettings))>
Friend Property TitleAddVideoID As Boolean
Private ReadOnly MySettings As SiteSettings
Friend Sub New(ByVal u As UserData)
MySettings = u.HOST.Source
RemoveTagsFromTitle = u.RemoveTagsFromTitle
TitleUseNative = u.TitleUseNative
TitleAddVideoID = u.TitleAddVideoID
End Sub
Friend Sub New(ByVal s As SiteSettings)
MySettings = s
RemoveTagsFromTitle = s.RemoveTagsFromTitle.Value
TitleUseNative = s.TitleUseNative.Value
TitleAddVideoID = s.TitleAddVideoID.Value
End Sub
End Class
End Namespace

View File

@@ -24,6 +24,8 @@ Namespace API.Twitter
ToolTip:="Existing files will be checked for duplicates and duplicates removed." & vbCr &
"Works only on the first activation 'Use MD5 comparison'.", LeftOffset:=DefaultOffset)>
Friend Property RemoveExistingDuplicates As Boolean = False
<PSetting(NameOf(SiteSettings.MediaModelAllowNonUserTweets), NameOf(MySettings), LeftOffset:=DefaultOffset)>
Friend Overridable Property MediaModelAllowNonUserTweets As Boolean = False
<PSetting(Address:=SettingAddress.User,
Caption:="Download model 'Media'",
ToolTip:="Download the data using the 'https://twitter.com/UserName/media' command.", LeftOffset:=DefaultOffset)>
@@ -36,12 +38,18 @@ Namespace API.Twitter
Caption:="Download model 'Search'",
ToolTip:="Download the data using the 'https://twitter.com/search?q=from:UserName+include:nativeretweets' command.", LeftOffset:=DefaultOffset)>
Friend Overridable Property DownloadModelSearch As Boolean = False
<PSetting(Address:=SettingAddress.User,
Caption:="Force apply",
ToolTip:="Force overrides the default parameters for the first download." & vbCr & "Applies to first download only.", LeftOffset:=DefaultOffset)>
Friend Overridable Property DownloadModelForceApply As Boolean = False
Private ReadOnly Property MySettings As Object
Friend Sub New(ByVal s As SiteSettings)
GifsDownload = s.GifsDownload.Value
GifsSpecialFolder = s.GifsSpecialFolder.Value
GifsPrefix = s.GifsPrefix.Value
UseMD5Comparison = s.UseMD5Comparison.Value
DownloadModelForceApply = s.UseAppropriateModel.Value
MediaModelAllowNonUserTweets = s.MediaModelAllowNonUserTweets.Value
MySettings = s
End Sub
Friend Sub New(ByVal s As Mastodon.SiteSettings)
@@ -57,7 +65,9 @@ Namespace API.Twitter
GifsPrefix = u.GifsPrefix
UseMD5Comparison = u.UseMD5Comparison
RemoveExistingDuplicates = u.RemoveExistingDuplicates
MediaModelAllowNonUserTweets = u.MediaModelAllowNonUserTweets
If Not TypeOf u Is Mastodon.UserData Then
DownloadModelForceApply = u.DownloadModelForceApply
Dim dm As DModels() = EnumExtract(Of DModels)(u.DownloadModel)
If dm.ListExists Then
DownloadModelMedia = dm.Contains(DModels.Media)

View File

@@ -11,50 +11,48 @@ Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports DN = SCrawler.API.Base.DeclaredNames
Namespace API.Twitter
<Manifest(TwitterSiteKey), SavedPosts, SeparatedTasks, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Token names"
Friend Const Header_Authorization As String = "authorization"
Friend Const Header_Token As String = "x-csrf-token"
#End Region
#Region "Properties constants"
Friend Const GifsSpecialFolder_Text As String = "GIFs special folder"
Friend Const GifsSpecialFolder_ToolTip As String = "Put the GIFs in a special folder" & vbCr &
"This is a folder name, not an absolute path." & vbCr &
"This folder(s) will be created relative to the user's root folder." & vbCr &
"Examples:" & vbCr & "SomeFolderName" & vbCr & "SomeFolderName\SomeFolderName2"
Friend Const GifsPrefix_Text As String = "GIF prefix"
Friend Const GifsPrefix_ToolTip As String = "This prefix will be added to the beginning of the filename"
Friend Const GifsDownload_Text As String = "Download GIFs"
Friend Const UseMD5Comparison_Text As String = "Use MD5 comparison"
Friend Const UseMD5Comparison_ToolTip As String = "Each image will be checked for existence using MD5"
#End Region
#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 My.Resources.SiteResources.TwitterPic_400
Return _Image
End Get
End Property
'TODELETE: twitter headers
'#Region "Auth"
' <PropertyOption(AllowNull:=False, IsAuth:=False, ControlText:="Authorization",
' ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
' Private ReadOnly Property Auth As PropertyValue
' <PropertyOption(AllowNull:=False, IsAuth:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
' Private ReadOnly Property Token As PropertyValue
'#End Region
#Region "Other properties"
<PropertyOption(ControlText:=GifsDownload_Text), PXML>
<PropertyOption(ControlText:="Use the appropriate model",
ControlToolTip:="Use the appropriate model for new users." & vbCr &
"If disabled, all download models will be used for the first download. " &
"Next, the appropriate download model will be automatically selected." & vbCr &
"Otherwise the appropriate download model will be selected right from the start."), PXML>
Friend ReadOnly Property UseAppropriateModel As PropertyValue
#Region "End points"
<PropertyOption(ControlText:="New endpoint: search", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the search model."), PXML>
Friend Property UseNewEndPointSearch As PropertyValue
<PropertyOption(ControlText:="New endpoint: profiles", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the profile models."), PXML>
Friend Property UseNewEndPointProfiles As PropertyValue
#End Region
#Region "Limits"
<PropertyOption(ControlText:="Abort on limit", ControlToolTip:="Abort twitter downloading when limit is reached"), PXML>
Friend Property AbortOnLimit As PropertyValue
<PropertyOption(ControlText:="Download already parsed", ControlToolTip:="Download already parsed content on abort"), PXML>
Friend Property DownloadAlreadyParsed As PropertyValue
#End Region
<PropertyOption(ControlText:="Media Model: allow non-user tweets", ControlToolTip:="Allow downloading non-user tweets in the media-model."), PXML>
Friend ReadOnly Property MediaModelAllowNonUserTweets As PropertyValue
<PropertyOption(ControlText:=DN.GifsDownloadCaption), PXML>
Friend ReadOnly Property GifsDownload As PropertyValue
<PropertyOption(ControlText:=GifsSpecialFolder_Text, ControlToolTip:=GifsSpecialFolder_ToolTip), PXML>
<PropertyOption(ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML>
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
<PropertyOption(ControlText:=GifsPrefix_Text, ControlToolTip:=GifsPrefix_ToolTip), PXML>
<PropertyOption(ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML>
Friend ReadOnly Property GifsPrefix As PropertyValue
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
Private ReadOnly Property GifStringChecker As IFormatProvider
@@ -76,52 +74,38 @@ Namespace API.Twitter
Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]")
End Function
End Class
<PropertyOption(ControlText:=UseMD5Comparison_Text, ControlToolTip:=UseMD5Comparison_ToolTip), PXML>
<PropertyOption(ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML>
Friend ReadOnly Property UseMD5Comparison As PropertyValue
<PXML, PropertyOption(ControlText:="Concurrent downloads", ControlToolTip:="The number of concurrent downloads.", LeftOffset:=120), TaskCounter>
<PropertyOption(ControlText:=DN.ConcurrentDownloadsCaption,
ControlToolTip:=DN.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter>
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
<Provider(NameOf(ConcurrentDownloads), FieldsChecker:=True)>
Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider
#End Region
'TODELETE: twitter headers
'Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
' If Not PropName.IsEmptyString Then
' Dim f$ = String.Empty
' Select Case PropName
' Case NameOf(Auth) : f = Header_Authorization
' Case NameOf(Token) : f = Header_Token
' End Select
' If Not f.IsEmptyString Then
' Responser.Headers.Remove(f)
' If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
' Responser.SaveSettings()
' End If
' End If
'End Sub
#End Region
Friend Sub New()
MyBase.New(TwitterSite, "twitter.com")
'TODELETE: twitter headers
'Dim a$ = String.Empty
'Dim t$ = String.Empty
_Image = My.Resources.SiteResources.TwitterIcon_32.ToBitmap
With Responser
'TODELETE: twitter headers
'a = .Headers.Value(Header_Authorization)
't = .Headers.Value(Header_Token)
.Cookies.ChangedAllowInternalDrop = False
.Cookies.Changed = False
End With
'TODELETE: twitter headers
'Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
'Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
UseAppropriateModel = New PropertyValue(True)
UseNewEndPointSearch = New PropertyValue(True)
UseNewEndPointProfiles = New PropertyValue(True)
AbortOnLimit = New PropertyValue(True)
DownloadAlreadyParsed = New PropertyValue(True)
MediaModelAllowNonUserTweets = New PropertyValue(False)
GifsDownload = New PropertyValue(True)
GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
GifsPrefix = New PropertyValue("GIF_")
GifStringChecker = New GifStringProvider
UseMD5Comparison = New PropertyValue(False)
ConcurrentDownloads = New PropertyValue(1)
MyConcurrentDownloadsProvider = New ConcurrentDownloadsProvider
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
UrlPatternUser = "https://twitter.com/{0}"
@@ -141,6 +125,11 @@ Namespace API.Twitter
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
Return Settings.GalleryDLFile.Exists And BaseAuthExists()
End Function
Friend Property LIMIT_ABORT As Boolean = False
Friend Overrides Sub DownloadDone(ByVal What As ISiteSettings.Download)
LIMIT_ABORT = False
MyBase.DownloadDone(What)
End Sub
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse (Not TypeOf Options Is EditorExchangeOptions OrElse
Not DirectCast(Options, EditorExchangeOptions).SiteKey = TwitterSiteKey) Then _

View File

@@ -20,6 +20,8 @@ Namespace API.Twitter
#Region "XML names"
Private Const Name_FirstDownloadComplete As String = "FirstDownloadComplete"
Private Const Name_DownloadModel As String = "DownloadModel"
Private Const Name_DownloadModelForceApply As String = "DownloadModelForceApply"
Private Const Name_MediaModelAllowNonUserTweets As String = "MediaModelAllowNonUserTweets"
Private Const Name_GifsDownload As String = "GifsDownload"
Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
Private Const Name_GifsPrefix As String = "GifsPrefix"
@@ -32,7 +34,9 @@ Namespace API.Twitter
Search = 5
End Enum
Private FirstDownloadComplete As Boolean = False
Friend Property DownloadModelForceApply As Boolean = False
Friend Property DownloadModel As DownloadModels = DownloadModels.Undefined
Friend Property MediaModelAllowNonUserTweets As Boolean = False
Friend Property GifsDownload As Boolean = True
Friend Property GifsSpecialFolder As String = String.Empty
Friend Property GifsPrefix As String = String.Empty
@@ -64,6 +68,8 @@ Namespace API.Twitter
UseMD5Comparison = .UseMD5Comparison
RemoveExistingDuplicates = .RemoveExistingDuplicates
DownloadModel = DownloadModels.Undefined
DownloadModelForceApply = .DownloadModelForceApply
MediaModelAllowNonUserTweets = .MediaModelAllowNonUserTweets
If .DownloadModelMedia Then DownloadModel += DownloadModels.Media
If .DownloadModelProfile Then DownloadModel += DownloadModels.Profile
If .DownloadModelSearch Then DownloadModel += DownloadModels.Search
@@ -78,6 +84,7 @@ Namespace API.Twitter
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
DownloadModelForceApply = .Value(Name_DownloadModelForceApply).FromXML(Of Boolean)(False)
If .Contains(Name_FirstDownloadComplete) Then
FirstDownloadComplete = .Value(Name_FirstDownloadComplete).FromXML(Of Boolean)(False)
DownloadModel = .Value(Name_DownloadModel).FromXML(Of Integer)(DownloadModels.Undefined)
@@ -87,6 +94,7 @@ Namespace API.Twitter
DownloadModel = .Value(Name_DownloadModel).FromXML(Of Integer)(DownloadModels.Undefined)
Else
If FirstDownloadComplete Then
DownloadModelForceApply = False
If ParseUserMediaOnly Then
DownloadModel = DownloadModels.Media
Else
@@ -107,8 +115,10 @@ Namespace API.Twitter
UseMD5Comparison = .Value(Name_UseMD5Comparison).FromXML(Of Boolean)(False)
RemoveExistingDuplicates = .Value(Name_RemoveExistingDuplicates).FromXML(Of Boolean)(False)
StartMD5Checked = .Value(Name_StartMD5Checked).FromXML(Of Boolean)(False)
MediaModelAllowNonUserTweets = .Value(Name_MediaModelAllowNonUserTweets).FromXML(Of Boolean)(False)
Else
.Add(Name_FirstDownloadComplete, FirstDownloadComplete.BoolToInteger)
.Add(Name_DownloadModelForceApply, DownloadModelForceApply.BoolToInteger)
.Add(Name_DownloadModel, CInt(DownloadModel))
.Add(Name_GifsDownload, GifsDownload.BoolToInteger)
.Add(Name_GifsSpecialFolder, GifsSpecialFolder)
@@ -116,18 +126,29 @@ Namespace API.Twitter
.Add(Name_UseMD5Comparison, UseMD5Comparison.BoolToInteger)
.Add(Name_RemoveExistingDuplicates, RemoveExistingDuplicates.BoolToInteger)
.Add(Name_StartMD5Checked, StartMD5Checked.BoolToInteger)
.Add(Name_MediaModelAllowNonUserTweets, MediaModelAllowNonUserTweets.BoolToInteger)
End If
End With
End Sub
#End Region
#Region "Download functions"
Private Function GetContainerSubnodes() As List(Of String())
Return New List(Of String()) From {
{{"content", "itemContent", "tweet_results", "result", "legacy"}},
{{"content", "itemContent", "tweet_results", "result", "tweet", "legacy"}}
}
End Function
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
If IsSavedPosts Then
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.Post.ID), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData_SavedPosts(Token)
If MySettings.LIMIT_ABORT Then
TwitterLimitException.LogMessage(ToStringForLog, True)
Else
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData_Timeline(Token)
If IsSavedPosts Then
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.Post.ID), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData_SavedPosts(Token)
Else
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData_Timeline(Token)
End If
End If
End Sub
Private Sub DownloadData_Timeline(ByVal Token As CancellationToken)
@@ -139,6 +160,8 @@ Namespace API.Twitter
Dim PostDate$, tmpUserId$
Dim i%
Dim dirIndx% = -1
Dim nodes As List(Of String()) = GetContainerSubnodes()
Dim node$()
Dim timelineNode As Predicate(Of EContainer) = Function(ee) ee.Value("type").StringToLower = "timelineaddentries"
Dim pinNode As Predicate(Of EContainer) = Function(ee) ee.Value("type").StringToLower = "timelinepinentry"
Dim entriesNode As Predicate(Of EContainer) = Function(ee) ee.Name = "entries" Or ee.Name = entry
@@ -150,13 +173,15 @@ Namespace API.Twitter
Dim __parseContainer As Func(Of EContainer, Boolean) =
Function(ByVal ee As EContainer) As Boolean
If dirIndx <= 1 Then
nn = ee({"content", "itemContent", "tweet_results", "result", "legacy"})
Else
nn = ee
nn = Nothing
If dirIndx > 1 Then nn = ee
If Not nn.ListExists Then
For Each node In nodes
nn = ee(node)
If nn.ListExists Then Exit For
Next
End If
If Not nn.ListExists Then nn = ee({"content", "itemContent", "tweet_results", "result", "tweet", "legacy"})
If nn.ListExists Then
PostID = nn.Value("id_str").IfNullOrEmpty(nn.Value("id"))
@@ -181,15 +206,14 @@ Namespace API.Twitter
If tmpUserId.IsEmptyString Then tmpUserId = nn.ItemF({"extended_entities", "media", 0, sourceIdPredicate}).XmlIfNothingValue.
IfNullOrEmpty(nn.Value("user_id")).IfNullOrEmpty(nn.Value("user_id_str")).IfNullOrEmpty("/")
If Not ParseUserMediaOnly OrElse (Not ID.IsEmptyString AndAlso tmpUserId = ID) Then ObtainMedia(nn, PostID, PostDate)
If Not ParseUserMediaOnly OrElse
(dirIndx = 0 AndAlso MediaModelAllowNonUserTweets) OrElse
(Not ID.IsEmptyString AndAlso tmpUserId = ID) Then ObtainMedia(nn, PostID, PostDate)
End If
Return True
End Function
tCache = New CacheKeeper($"{DownloadContentDefault_GetRootDir()}\_tCache\") With {
.CacheDeleteError = New ErrorsDescriber(EDP.None) With {.Action = Sub(ee, eex, msg, obj) Settings.Cache.AddPath(tCache)}}
If tCache.RootDirectory.Exists(SFO.Path, False) Then tCache.RootDirectory.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.ReturnValue)
tCache.Validate()
tCache = CreateCache()
Dim dirs As List(Of SFile) = GetTimelineFromGalleryDL(tCache, Token)
If dirs.ListExists Then
@@ -313,7 +337,9 @@ Namespace API.Twitter
End If
End If
End If
DownloadModelForceApply = False
FirstDownloadComplete = True
Catch limit_ex As TwitterLimitException
Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]")
Finally
@@ -328,6 +354,8 @@ Namespace API.Twitter
If files.ListExists Then
ResetFileNameProvider(Math.Max(files.Count.ToString.Length, 3))
Dim id$
Dim nodes As List(Of String()) = GetContainerSubnodes()
Dim node$()
Dim j As EContainer, jj As EContainer
Dim jErr As New ErrorsDescriber(EDP.ReturnValue)
For i% = 0 To files.Count - 1
@@ -339,19 +367,24 @@ Namespace API.Twitter
ProgressPre.ChangeMax(.Count)
For Each jj In .Self
ProgressPre.Perform()
With jj({"content", "itemContent", "tweet_results", "result", "legacy"})
If .ListExists Then
id = .Value("id_str")
If _TempPostsList.Contains(id) Then j.Dispose() : Exit Sub Else ObtainMedia(.Self, id, .Value("created_at"))
End If
End With
For Each node In nodes
With jj(node)
If .ListExists Then
id = .Value("id_str")
If _TempPostsList.Contains(id) Then j.Dispose() : Exit Sub Else ObtainMedia(.Self, id, .Value("created_at"))
Exit For
End If
End With
Next
Next
End If
End With
j.Dispose()
End If
Next
nodes.Clear()
End If
Catch limit_ex As TwitterLimitException
Catch ex As Exception
ProcessException(ex, Token, "data downloading error (Saved Posts)")
End Try
@@ -408,30 +441,28 @@ Namespace API.Twitter
Dim f As SFile
Dim m As UserMedia
If w.ListExists Then
For Each n As EContainer In w
If n.Value("type") = "animated_gif" Then
With n({"video_info", "variants"})
If .ListExists Then
With .ItemF({gifUrl})
If .ListExists Then
url = .Value("url")
ff = UrlFile(url)
If Not ff.IsEmptyString Then
If GifsDownload And Not _DataNames.Contains(ff) Then
m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video)
f = m.File
If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f
If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*"
_TempMediaList.ListAddValue(m, LNC)
End If
Return True
If w.Value("type") = "animated_gif" Then
With w({"video_info", "variants"})
If .ListExists Then
With .ItemF({gifUrl})
If .ListExists Then
url = .Value("url")
ff = UrlFile(url)
If Not ff.IsEmptyString Then
If GifsDownload And Not _DataNames.Contains(ff) Then
m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video)
f = m.File
If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f
If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*"
_TempMediaList.ListAddValue(m, LNC)
End If
Return True
End If
End With
End If
End With
End If
Next
End If
End With
End If
End With
End If
End If
Return False
Catch ex As Exception
@@ -460,13 +491,22 @@ Namespace API.Twitter
End Function
#End Region
#Region "Gallery-DL Support"
Private Class TwitterLimitException : Inherits Exception
Friend Sub New(ByVal User As String, ByVal Skipped As Boolean)
LogMessage(User, Skipped)
End Sub
Friend Shared Sub LogMessage(ByVal User As String, ByVal Skipped As Boolean)
MyMainLOG = $"{User}: twitter limit reached.{IIf(Skipped, "Data has not been downloaded", String.Empty)}"
End Sub
End Class
Private Class TwitterGDL : Inherits GDL.GDLBatch
Private Property Token As CancellationToken
Friend Sub New(ByVal Dir As SFile, ByVal _Token As CancellationToken)
MyBase.New
Private ReadOnly KillOnLimit As Boolean
Friend LimitReached As Boolean = False
Friend Sub New(ByVal Dir As SFile, ByVal _Token As CancellationToken, ByVal _KillOnLimit As Boolean)
MyBase.New(_Token)
Commands.Clear()
If Not Dir.IsEmptyString Then ChangeDirectory(Dir)
Token = _Token
KillOnLimit = _KillOnLimit
End Sub
Protected Overrides Async Function Validate(ByVal Value As String) As Task
If Not ProcessKilled AndAlso Await Task.Run(Function() Token.IsCancellationRequested OrElse IdExists(Value)) Then Kill()
@@ -482,14 +522,27 @@ Namespace API.Twitter
End Try
Return False
End Function
Protected Overrides Async Sub ErrorDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
Await Task.Run(Sub() CheckForLimit(e.Data))
End Sub
Private Sub CheckForLimit(ByVal Value As String)
If Token.IsCancellationRequested Or (KillOnLimit AndAlso Not ProcessKilled AndAlso
Not Value.IsEmptyString AndAlso Value.ToLower.Contains("for rate limit reset")) Then
LimitReached = True
Kill()
End If
End Sub
End Class
Private Function GetDataFromGalleryDL(ByVal URL As String, ByVal Cache As CacheKeeper, ByVal UseTempPostList As Boolean,
Optional ByVal Token As CancellationToken = Nothing) As SFile
Dim command$ = $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --cookies ""{MySettings.CookiesNetscapeFile}"" --write-pages "
Dim command$ = String.Empty
Try
Dim conf As SFile = GdlCreateConf(Cache.NewPath)
command = $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --config ""{conf}"" --write-pages "
command &= GdlGetIdFilterString()
Dim dir As SFile = Cache.NewPath
If dir.Exists(SFO.Path,, EDP.ThrowException) Then
Using batch As New TwitterGDL(dir, Token)
Using batch As New TwitterGDL(dir, Token, MySettings.AbortOnLimit.Value)
If UseTempPostList Then
batch.TempPostsList = _TempPostsList
command &= GdlGetIdFilterString()
@@ -499,10 +552,22 @@ Namespace API.Twitter
'Debug.WriteLine(command)
'#End If
batch.Execute(command)
If batch.LimitReached Then
If CBool(MySettings.DownloadAlreadyParsed.Value) And
SFile.GetFiles(dir, "*.txt", IO.SearchOption.AllDirectories, EDP.ReturnValue).Count > 0 Then
MySettings.LIMIT_ABORT = True
Return dir
Else
Throw New TwitterLimitException(ToStringForLog, False)
End If
End If
End Using
Return dir
End If
Return Nothing
Catch limit_ex As TwitterLimitException
MySettings.LIMIT_ABORT = True
Throw limit_ex
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{ToStringForLog()}: GetDataFromGalleryDL({command})")
End Try
@@ -511,20 +576,23 @@ Namespace API.Twitter
Dim command$ = String.Empty
Try
Dim confCache As CacheKeeper = Cache.NewInstance(Of BatchFileExchanger)
Dim conf As SFile = $"{confCache.RootDirectory.PathWithSeparator}TwitterGdlConfig.conf"
Dim confText$ = "{""extractor"":{""cookies"": """ & MySettings.CookiesNetscapeFile.ToString.Replace("\", "/") &
""",""cookies-update"": false,""twitter"":{""cards"": false,""conversations"": true,""pinned"": false,""quoted"": false,""replies"": true,""retweets"": true,""strategy"": null,""text-tweets"": false,""twitpic"": false,""unique"": true,""users"": ""timeline"",""videos"": true}}}"
If conf.Exists(SFO.Path, True, EDP.ThrowException) Then TextSaver.SaveTextToFile(confText, conf)
If Not conf.Exists Then Throw New IO.FileNotFoundException("Can't find Twitter GDL config file", conf)
Dim conf As SFile = GdlCreateConf(confCache.RootDirectory)
If DownloadModel = DownloadModels.Undefined And Not FirstDownloadComplete And DownloadModelForceApply Then
If ParseUserMediaOnly Then
DownloadModel = DownloadModels.Media
Else
DownloadModel = DownloadModels.Media + DownloadModels.Profile + DownloadModels.Search
End If
End If
Dim outList As New List(Of SFile)
Dim rootDir As CacheKeeper = Cache.NewInstance
Dim dir As SFile
Dim dm As List(Of DownloadModels) = EnumExtract(Of DownloadModels)(DownloadModel).ListIfNothing
Dim process As Boolean
Dim bProcess As Boolean = DownloadModel = DownloadModels.Undefined Or Not FirstDownloadComplete
Using tgdl As New TwitterGDL(Nothing, Token) With {
Using tgdl As New TwitterGDL(Nothing, Token, MySettings.AbortOnLimit.Value) With {
.TempPostsList = _TempPostsList,
.AutoClear = True,
.AutoReset = True,
@@ -541,22 +609,36 @@ Namespace API.Twitter
command = $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --config ""{conf}"" --write-pages "
command &= GdlGetIdFilterString()
Select Case i
Case 0 : command &= $"https://twitter.com/{Name}/media" : process = bProcess Or dm.Contains(DownloadModels.Media)
Case 1 : command &= $"https://twitter.com/{Name}" : process = bProcess Or dm.Contains(DownloadModels.Profile)
Case 2 : command &= $"https://twitter.com/search?q=from:{Name}+include:nativeretweets" : process = bProcess Or dm.Contains(DownloadModels.Search)
Case 0 : command &= $"https://twitter.com/{Name}/media" : process = dm.Contains(DownloadModels.Media)
Case 1 : command &= $"https://twitter.com/{Name}" : process = dm.Contains(DownloadModels.Profile)
Case 2 : command &= $"-o search-endpoint=graphql https://twitter.com/search?q=from:{Name}+include:nativeretweets" : process = dm.Contains(DownloadModels.Search)
Case Else : process = False
End Select
'#If DEBUG Then
'Debug.WriteLine(command)
'#End If
ThrowAny(Token)
If process Then tgdl.Execute(command)
If process Then
tgdl.Execute(command)
If tgdl.LimitReached Then
If CBool(MySettings.DownloadAlreadyParsed.Value) And
SFile.GetFiles(rootDir, "*.txt", IO.SearchOption.AllDirectories, EDP.ReturnValue).Count > 0 Then
MySettings.LIMIT_ABORT = True
Exit For
Else
Throw New TwitterLimitException(ToStringForLog, False)
End If
End If
End If
ThrowAny(Token)
Next
End Using
dm.Clear()
Return outList
Catch limit_ex As TwitterLimitException
MySettings.LIMIT_ABORT = True
Throw limit_ex
Catch ex As Exception
ProcessException(ex, Token, $"{ToStringForLog()}: GetTimelineFromGalleryDL({command})")
Return Nothing
@@ -565,6 +647,20 @@ Namespace API.Twitter
Private Function GdlGetIdFilterString() As String
Return If(_TempPostsList.Count > 0, $"--filter ""int(tweet_id) > {_TempPostsList.Last} or abort()"" ", String.Empty)
End Function
Private Function GdlCreateConf(ByVal Path As SFile) As SFile
Try
Dim conf As SFile = $"{Path.PathWithSeparator}TwitterGdlConfig.conf"
Dim confText$ = "{""extractor"":{""cookies"": """ & MySettings.CookiesNetscapeFile.ToString.Replace("\", "/") &
""",""cookies-update"": false,""twitter"":{""tweet-endpoint"": ""detail"",""cards"": false,""conversations"": true,""pinned"": false,""quoted"": false,""replies"": true,""retweets"": true,""strategy"": null,""text-tweets"": false,""twitpic"": false,""unique"": true,""users"": ""timeline"",""videos"": true}}}"
If conf.Exists(SFO.Path, True, EDP.ThrowException) Then TextSaver.SaveTextToFile(confText, conf)
If Not conf.Exists Then Throw New IO.FileNotFoundException("Can't find Twitter GDL config file", conf)
Return conf
Catch file_ex As IO.FileNotFoundException
Throw file_ex
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "gallery-dl configuration file creating error", New SFile)
End Try
End Function
#End Region
#Region "ReparseMissing"
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
@@ -576,7 +672,9 @@ Namespace API.Twitter
If ContentMissingExists Then
Dim m As UserMedia
Dim PostDate$
Dim j As EContainer
Dim nodes As List(Of String()) = GetContainerSubnodes()
Dim node$()
Dim j As EContainer, n As EContainer
Dim f As SFile
Dim i%, ii%
Dim files As List(Of SFile)
@@ -585,6 +683,7 @@ Namespace API.Twitter
cache = Settings.Cache
Else
cache = New CacheKeeper(DownloadContentDefault_GetRootDir.CSFilePS)
cache.CacheDeleteError = CacheDeletionError(cache)
End If
ProgressPre.ChangeMax(_ContentList.Count)
For i = 0 To _ContentList.Count - 1
@@ -598,7 +697,7 @@ Namespace API.Twitter
Else
URL = String.Format(SinglePostPattern, Name, m.Post.ID)
End If
f = GetDataFromGalleryDL(URL, cache, Favorite, Token)
f = GetDataFromGalleryDL(URL, cache, False, Token)
If Not f.IsEmptyString Then
files = SFile.GetFiles(f, "*.txt")
If files.ListExists Then
@@ -606,13 +705,20 @@ Namespace API.Twitter
f = RenameGdlFile(files(ii), ii)
j = JsonDocument.Parse(f.GetText)
If Not j Is Nothing Then
With j.ItemF({"data", 0, "instructions", 0, "entries", 0,
"content", "itemContent", "tweet_results", "result", "legacy"})
With j.ItemF({"data", 0, "instructions", 0, "entries"})
If .ListExists Then
PostDate = String.Empty
If .Contains("created_at") Then PostDate = .Value("created_at") Else PostDate = String.Empty
ObtainMedia(.Self, m.Post.ID, PostDate, UStates.Missing)
rList.Add(i)
For Each n In .Self
For Each node In nodes
With n(node)
If .ListExists Then
PostDate = String.Empty
If .Contains("created_at") Then PostDate = .Value("created_at") Else PostDate = String.Empty
ObtainMedia(.Self, m.Post.ID, PostDate, UStates.Missing)
rList.ListAddValue(i, LNC)
End If
End With
Next
Next
End If
End With
j.Dispose()
@@ -630,7 +736,7 @@ Namespace API.Twitter
Finally
If Not cache Is Nothing And Not IsSingleObjectDownload Then cache.Dispose()
If rList.Count > 0 Then
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
rList.Clear()
End If
End Try

View File

@@ -33,7 +33,7 @@ Namespace API
End Property
Friend Property CurrentlyEdited As Boolean = False
Private _CollectionName As String = String.Empty
Friend Overrides Property CollectionName As String
Friend Overrides ReadOnly Property CollectionName As String
Get
If Count > 0 Then
Return Collections(0).CollectionName
@@ -41,14 +41,29 @@ Namespace API
Return _CollectionName
End If
End Get
Set(ByVal NewName As String)
ChangeCollectionName(NewName, True)
End Set
End Property
Friend Overrides Sub ChangeCollectionName(ByVal NewName As String, ByVal UpdateSettings As Boolean)
_CollectionName = NewName
If Count > 0 Then Collections.ForEach(Sub(c) c.CollectionName = NewName)
Friend Sub ChangeVirtualCollectionName(ByVal NewName As String)
If Count > 0 And Not NewName.IsEmptyString Then
Dim u As UserInfo
For Each user As UserDataBase In Collections
u = user.User
u.CollectionName = NewName
u.UpdateUserFile()
user.User = u
Settings.UpdateUsersList(u)
Next
End If
End Sub
Private _CollectionPath As SFile = Nothing
Friend Overrides ReadOnly Property CollectionPath As SFile
Get
If Count > 0 And Not IsVirtual Then
Dim _RealUser As UserDataBase = GetRealUser()
If Not _RealUser Is Nothing Then Return _RealUser.User.SpecialCollectionPath
End If
Return _CollectionPath
End Get
End Property
Friend Overrides ReadOnly Property Name As String
Get
Return CollectionName
@@ -185,6 +200,43 @@ Namespace API
UpdateUserInformation()
End Set
End Property
Friend Overrides Property BackColor As Color?
Get
If Count > 0 Then
With Collections.Select(Function(u) u.BackColor)
If .All(Function(c) c.HasValue) Then
Dim cc As Color = Collections(0).BackColor.Value
If .All(Function(c) c.Value = cc) Then Return cc
End If
End With
End If
Return Nothing
End Get
Set(ByVal b As Color?)
If Count > 0 Then Collections.ForEach(Sub(c) c.BackColor = b)
End Set
End Property
Friend Overrides Property ForeColor As Color?
Get
If Count > 0 Then
With Collections.Select(Function(u) u.ForeColor)
If .All(Function(c) c.HasValue) Then
Dim cc As Color = Collections(0).ForeColor.Value
If .All(Function(c) c.Value = cc) Then Return cc
End If
End With
End If
Return Nothing
End Get
Set(ByVal f As Color?)
If Count > 0 Then Collections.ForEach(Sub(c) c.ForeColor = f)
End Set
End Property
Friend Overrides ReadOnly Property IsSubscription As Boolean
Get
Return Count > 0 AndAlso Collections.All(Function(u) u.IsSubscription)
End Get
End Property
Friend Overrides Property ReadyForDownload As Boolean
Get
Return Count > 0 AndAlso Collections(0).ReadyForDownload
@@ -202,6 +254,16 @@ Namespace API
End If
End Get
End Property
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
If Count > 0 Then
With Collections.SelectMany(Function(u As UserDataBase) u.SpecialLabels)
If .ListExists Then Return .Distinct
End With
End If
Return New String() {}
End Get
End Property
Friend Overrides Function GetUserInformation() As String
Dim OutStr$ = String.Empty
If IsVirtual Then OutStr = "This is a virtual collection."
@@ -268,6 +330,15 @@ Namespace API
End If
End Get
End Property
Friend ReadOnly Property ContextErase As ToolStripMenuItem()
Get
If Count > 0 Then
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_ERASE).ToArray
Else
Return New ToolStripMenuItem() {}
End If
End Get
End Property
Friend ReadOnly Property ContextPath As ToolStripMenuItem()
Get
If Count > 0 Then
@@ -293,9 +364,10 @@ Namespace API
_IsCollection = True
Collections = New List(Of IUserData)
End Sub
Friend Sub New(ByVal _Name As String)
Friend Sub New(ByVal _Name As String, Optional ByVal _Path As SFile = Nothing)
Me.New
CollectionName = _Name
_CollectionName = _Name
_CollectionPath = _Path
End Sub
#End Region
#Region "Load, Update"
@@ -384,18 +456,13 @@ Namespace API
Catch
End Try
End Sub
Friend Function GetRealUserFile() As SFile
Friend Function GetRealUser() As IUserData
Dim i% = -1
If Count > 0 Then i = Collections.FindIndex(RealUser)
If i >= 0 Then Return Collections(i).File Else Return Nothing
Return If(i >= 0, Collections(i), Nothing)
End Function
Friend Function GetRealUserSpecialCollectionPath()
Dim _SpecialCollectionPath As SFile = Nothing
If Count > 0 And Not IsVirtual Then
Dim _RealUser As UserDataBase = Collections.Find(RealUser)
If Not _RealUser Is Nothing Then _SpecialCollectionPath = _RealUser.User.SpecialCollectionPath
End If
Return _SpecialCollectionPath
Friend Function GetRealUserFile() As SFile
Return If(GetRealUser()?.File, New SFile)
End Function
#End Region
#Region "ICollection Support"
@@ -431,7 +498,7 @@ Namespace API
''' <exception cref="InvalidOperationException"></exception>
Friend Overloads Sub Add(ByVal _Item As IUserData) Implements ICollection(Of IUserData).Add
With _Item
If .MoveFiles(CollectionName, GetRealUserSpecialCollectionPath()) Then
If .MoveFiles(CollectionName, CollectionPath) Then
If Not _Item.IsVirtual And DataMerging Then DirectCast(.Self, UserDataBase).MergeData()
Collections.Add(_Item)
With Collections.Last
@@ -480,12 +547,7 @@ Namespace API
End Try
End Sub
Private Sub ConsolidateLabels()
If Count > 1 Then
Dim l As New List(Of String)
Dim lp As New ListAddParams(LAP.ClearBeforeAdd)
l.ListAddList(Collections.SelectMany(Function(c) c.Labels), LNC)
Collections.ForEach(Sub(c) c.Labels.ListAddList(l, lp))
End If
UpdateLabels(Me, ListAddList(Nothing, Labels.ListWithRemove(SpecialLabels)), 1, True)
End Sub
Private Sub ConsolidateScripts()
If Count > 1 AndAlso ScriptUse Then Collections.ForEach(Sub(c) c.ScriptUse = True)
@@ -520,7 +582,14 @@ Namespace API
End If
End Sub
#End Region
#Region "Remove, Delete"
#Region "Erase, Remove, Delete"
Friend Overrides Function EraseData(ByVal Mode As IUserData.EraseMode) As Boolean
If Count > 0 Then
Return Collections.All(Function(u) u.EraseData(Mode))
Else
Return True
End If
End Function
Friend Function Remove(ByVal _Item As IUserData) As Boolean Implements ICollection(Of IUserData).Remove
If DataMerging Then
MsgBoxE($"Collection [{CollectionName}] data is already merged" & vbCr &

View File

@@ -18,5 +18,8 @@ Namespace API.XVIDEOS
Friend ReadOnly Regex_M3U8_Appender As RParams = RParams.DM("(.+)(?=/.+?\.m3u8.*?)", 0)
Friend ReadOnly Regex_SavedVideosPlaylist As RParams = RParams.DM("\<div id=""video.+?data-id=""(\d+).+?a href=""([^""]+)"".+?title=""([^""]*)""",
0, RegexReturn.List, EDP.ReturnValue)
Friend ReadOnly Regex_VideoThumbBig As RParams = RParams.DMS("html5player.setThumbUrl\d+\('([^']+)'\)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_VideoThumbSmall As RParams = RParams.DMS("html5player.setThumbUrl\('([^']+)'\)", 1, EDP.ReturnValue)
End Module
End Namespace

View File

@@ -12,7 +12,7 @@ Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.XVIDEOS
<Manifest(XvideosSiteKey), SavedPosts, SpecialForm(True), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
<Manifest(XvideosSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
@@ -44,6 +44,8 @@ Namespace API.XVIDEOS
Domains.DestinationProp = SiteDomains
DownloadUHD = New PropertyValue(False)
SavedVideosPlaylist = New PropertyValue(String.Empty, GetType(String))
_SubscriptionsAllowed = True
UrlPatternUser = "https://xvideos.com/{0}"
End Sub
Friend Overrides Sub EndInit()
@@ -81,21 +83,19 @@ Namespace API.XVIDEOS
End Function
#End Region
#Region "User: get, check"
Friend Function GetUserUrlPart(ByVal User As UserData) As String
Dim __user$ = User.Name.Split("_").FirstOrDefault
__user &= $"/{User.Name.Replace($"{__user}_", String.Empty)}"
Return __user
End Function
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
Return String.Format(UrlPatternUser, GetUserUrlPart(User))
Return DirectCast(User, UserData).GetUserUrl(0)
End Function
#End Region
#Region "IsMyUser, IsMyImageVideo"
Private Const UserRegexDefault As String = "/(profiles|[\w]*?[-]{0,1}channels)/([^/]+)(\Z|.*?)"
Private Const URD As String = ".*?{0}{1}"
Private ReadOnly AbstractRegex As RParams = RParams.DM("[^/]+", 0, RegexReturn.List, EDP.ReturnValue)
Private ReadOnly SearchRegex As RParams = RParams.DMS("\?k=([^&]+)&?((.*)(&p=\d+)|(.*))", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
If Not UserURL.IsEmptyString Then
If Domains.Count > 0 Then
UserURL = UserURL.ToLower
If Domains.Count > 0 AndAlso Domains.Domains.Exists(Function(d) UserURL.Contains(d)) Then
Dim uName$, uOpt$, fStr$
Dim uErr As New ErrorsDescriber(EDP.ReturnValue)
For i% = 0 To Domains.Count - 1
@@ -103,9 +103,41 @@ Namespace API.XVIDEOS
uName = RegexReplace(UserURL, RParams.DMS(fStr, 2, uErr))
If Not uName.IsEmptyString Then
uOpt = RegexReplace(UserURL, RParams.DMS(fStr, 1))
If Not uOpt.IsEmptyString Then Return New ExchangeOptions(Site, $"{uOpt}_{uName}")
If Not uOpt.IsEmptyString Then Return New ExchangeOptions(Site, $"{uOpt}@{uName}")
End If
Next
Dim absList As List(Of String) = RegexReplace(UserURL, AbstractRegex)
If absList.ListExists(3) AndAlso Not absList(2).IsEmptyString Then
If absList(2) = "c" Then
If absList.Count > 3 AndAlso Not absList.Last.IsEmptyString AndAlso IsNumeric(absList.Last) Then absList.RemoveAt(absList.Count - 1)
If absList.Count > 3 Then
uName = $"{CInt(SiteModes.Categories)}@{absList.Last}"
uOpt = $"{absList.Last}@"
absList.RemoveAt(absList.Count - 1)
If absList.Count > 3 Then uOpt &= absList.ListTake(2, absList.Count).ListToString("/")
Return New ExchangeOptions(Site, uName) With {.Options = uOpt}
End If
ElseIf absList(2) = "tags" And absList.Count >= 4 Then
If Not absList.Last.IsEmptyString AndAlso IsNumeric(absList.Last) Then absList.RemoveAt(absList.Count - 1)
If absList.Count > 3 Then
uOpt = String.Empty
uName = absList.Last
absList.RemoveAt(absList.Count - 1)
If absList.Count > 3 Then uOpt = absList.ListTake(2, 100, EDP.ReturnValue).ListToString("/").StringTrimStart("/").StringTrimEnd("/")
uOpt = $"{uName}@{uOpt}"
uName = $"{CInt(SiteModes.Tags)}@{uName.StringRemoveWinForbiddenSymbols}"
Return New ExchangeOptions(Site, uName) With {.Options = uOpt}
End If
ElseIf absList.Count = 3 And Not absList(2).IsEmptyString Then
absList = RegexReplace(absList(2), SearchRegex)
If absList.ListExists(6) AndAlso Not absList(1).IsEmptyString Then
uName = $"{CInt(SiteModes.Search)}@{absList(1).StringRemoveWinForbiddenSymbols}"
uOpt = $"{absList(1)}@{absList(3).IfNullOrEmpty(absList(5))}"
Return New ExchangeOptions(Site, uName) With {.Options = uOpt}
End If
End If
End If
End If
End If
Return Nothing
@@ -116,6 +148,14 @@ Namespace API.XVIDEOS
End If
Return Nothing
End Function
#End Region
#Region "UserOptions"
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions
If OpenForm Then
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
#End Region
End Class
End Namespace

View File

@@ -16,6 +16,13 @@ Imports PersonalUtilities.Tools.Web.Documents.JSON
Imports UTypes = SCrawler.API.Base.UserMedia.Types
Namespace API.XVIDEOS
Friend Class UserData : Inherits UserDataBase
#Region "XML names"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_Arguments As String = "Arguments"
Private Const Name_PersonType As String = "PersonType"
#End Region
#Region "Structures"
Private Structure PlayListVideo : Implements IRegExCreator
Friend ID As String
Friend URL As String
@@ -33,23 +40,171 @@ Namespace API.XVIDEOS
Return New UserMedia(URL, UTypes.VideoPre) With {.Object = Me, .PictureOption = Title, .Post = ID}
End Function
End Structure
#End Region
#Region "Declarations"
Friend Overrides ReadOnly Property FeedIsUser As Boolean
Get
Return SiteMode = SiteModes.User
End Get
End Property
Private Property SiteMode As SiteModes = SiteModes.User
Private Property TrueName As String = String.Empty
Private Property Arguments As String = String.Empty
Private Property PersonType As String = String.Empty
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
End Get
End Property
Friend Property QueryString As String
Get
If SiteMode = SiteModes.User Then
Return String.Empty
Else
Return GetUserUrl(0)
End If
End Get
Set(ByVal q As String)
UpdateUserOptions(True, q)
End Set
End Property
Private ReadOnly Property MySettings As SiteSettings
Get
Return DirectCast(HOST.Source, SiteSettings)
End Get
End Property
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
#End Region
#Region "Load"
Friend Overrides Function ExchangeOptionsGet() As Object
Return New UserExchangeOptions(Me)
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then QueryString = DirectCast(Obj, UserExchangeOptions).QueryString
End Sub
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
If Not Force OrElse (Not SiteMode = SiteModes.User AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
Dim eObj As Plugin.ExchangeOptions = Nothing
If Force Then eObj = MySettings.IsMyUser(NewUrl)
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And TrueName.IsEmptyString) Then
Dim n$() = If(Force, eObj.UserName, Name).Split("@")
If n.ListExists(2) Then
Dim opt$ = If(Force, eObj.Options, Options)
If opt.IsEmptyString AndAlso Not IsNumeric(n(0)) Then
If Not Force Then
PersonType = n(0)
TrueName = If(Force, eObj.UserName, Name).Replace($"{PersonType}@", String.Empty)
End If
ElseIf Not opt.IsEmptyString Then
Dim n2$() = opt.Split("@")
Dim __SiteMode As SiteModes = CInt(n(0))
Dim __TrueName$ = n2.FirstOrDefault
Dim __Arguments$ = opt.Replace($"{__TrueName}@", String.Empty)
Dim __ForceApply As Boolean = False
If Force AndAlso (Not TrueName = __TrueName Or Not SiteMode = __SiteMode) Then
If ValidateChangeSearchOptions(ToStringForLog, $"{__SiteMode}: {__TrueName}", $"{SiteMode}: {TrueName}") Then
__ForceApply = True
Else
Return False
End If
End If
Arguments = __Arguments
Options = opt
If Not Force Then
SiteMode = __SiteMode
TrueName = __TrueName
UserSiteName = $"{SiteMode}: {TrueName}"
If FriendlyName.IsEmptyString Then FriendlyName = UserSiteName
Settings.Labels.Add(SearchRequestLabelName)
Labels.ListAddValue(SearchRequestLabelName, LNC)
Labels.Sort()
ElseIf Force And __ForceApply Then
SiteMode = __SiteMode
TrueName = __TrueName
End If
Return True
End If
End If
End If
End If
Return False
End Function
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
TrueName = .Value(Name_TrueName)
Arguments = .Value(Name_Arguments)
PersonType = .Value(Name_PersonType)
If PersonType.IsEmptyString And TrueName.IsEmptyString And Not Name.IsEmptyString Then
If Not Name.Contains("@") Then
Dim n$() = Name.Split("_")
PersonType = n(0)
TrueName = Name.Replace($"{PersonType}_", String.Empty)
End If
End If
UpdateUserOptions()
Else
If UpdateUserOptions() Then
.Value(Name_LabelsName) = LabelsString
.Value(Name_UserSiteName) = UserSiteName
.Value(Name_FriendlyName) = FriendlyName
End If
.Add(Name_SiteMode, CInt(SiteMode))
.Add(Name_TrueName, TrueName)
.Add(Name_Arguments, Arguments)
.Add(Name_PersonType, PersonType)
'Debug.WriteLine(GetUserUrl(0))
'Debug.WriteLine(GetUserUrl(2))
End If
End With
End Sub
#End Region
#Region "Initializer"
Friend Sub New()
SeparateVideoFolder = False
UseInternalM3U8Function = True
UseClientTokens = True
End Sub
#End Region
Friend Function GetUserUrl(ByVal Page As Integer) As String
Dim url$ = String.Empty
If SiteMode = SiteModes.User Then
url = $"https://xvideos.com/{PersonType}/{TrueName}"
ElseIf SiteMode = SiteModes.Categories Then
url = "https://xvideos.com/c/"
If Not Arguments.IsEmptyString Then url &= $"{Arguments}/"
url &= TrueName
If Page > 1 Then url &= $"/{Page - 1}"
ElseIf SiteMode = SiteModes.Tags Then
url = "https://www.xvideos.com/tags/"
If Not Arguments.IsEmptyString Then url &= $"{Arguments}/"
url &= $"{TrueName}/"
If Page > 1 Then url &= Page - 1
ElseIf SiteMode = SiteModes.Search Then
url = $"https://www.xvideos.com/?k={TrueName}"
If Not Arguments.IsEmptyString Then url &= $"&{Arguments}"
If Page > 1 Then url &= $"&p={Page - 1}"
End If
Return url
End Function
Private Sub Wait429(ByVal Round As Integer)
If (Round Mod 5) = 0 Then
Thread.Sleep(5000 + (Round / 5).RoundDown)
Else
Thread.Sleep(1000)
End If
End Sub
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
If Not Settings.UseM3U8 Then MyMainLOG = $"{ToStringForLog()}: File [ffmpeg.exe] not found" : Exit Sub
If IsSavedPosts Then
If Not ACheck(MySettings.SavedVideosPlaylist.Value) Then Throw New ArgumentNullException("SavedVideosPlaylist", "Playlist of saved videos cannot be null")
DownloadSavedVideos(Token)
ElseIf Not SiteMode = SiteModes.User Then
DownloadSavedVideos(Token)
Else
DownloadUserVideo(Token)
End If
@@ -59,11 +214,11 @@ Namespace API.XVIDEOS
Dim isQuickies As Boolean = False
Try
Dim NextPage%, d%
Dim round% = 0
Dim limit% = If(DownloadTopCount, -1)
Dim r$, n$
Dim j As EContainer = Nothing
Dim jj As EContainer
Dim user$ = MySettings.GetUserUrlPart(Me)
Dim p As UserMedia
Dim EnvirSet As Boolean = False
@@ -74,9 +229,12 @@ Namespace API.XVIDEOS
d = 0
n = IIf(i = 0, "u", "url")
Do
round += 1
Wait429(round)
ThrowAny(Token)
If i = 0 Then
URL = $"https://www.xvideos.com/{user}/videos/new/{If(NextPage = 0, String.Empty, NextPage)}"
URL = GetUserUrl(0)
URL &= $"/videos/new/{If(NextPage = 0, String.Empty, NextPage)}"
Else 'Quickies
URL = $"https://www.xvideos.com/quickies-api/profilevideos/all/none/N/{ID}/{NextPage}"
isQuickies = True
@@ -95,10 +253,7 @@ Namespace API.XVIDEOS
NextPage += 1
For Each jj In .Self
ProgressPre.Perform()
p = New UserMedia With {
.Post = jj.Value("id"),
.URL = $"https://www.xvideos.com/{jj.Value(n).StringTrimStart("/")}"
}
p = New UserMedia($"https://www.xvideos.com/{jj.Value(n).StringTrimStart("/")}") With {.Post = jj.Value("id")}
If Not p.Post.ID.IsEmptyString And Not jj.Value(n).IsEmptyString Then
If Not _TempPostsList.Contains(p.Post.ID) Then
_TempPostsList.Add(p.Post.ID)
@@ -124,10 +279,19 @@ Namespace API.XVIDEOS
If Not j Is Nothing Then j.Dispose()
If limit > 0 And _TempMediaList.Count >= limit Then _TempMediaList.ListAddList(_TempMediaList.ListTake(-1, limit), LAP.ClearBeforeAdd)
If _TempMediaList.Count > 0 Then
ProgressPre.ChangeMax(_TempMediaList.Count)
If IsSubscription Then
Progress.Maximum += _TempMediaList.Count
Else
ProgressPre.ChangeMax(_TempMediaList.Count)
End If
For i% = 0 To _TempMediaList.Count - 1
ProgressPre.Perform()
If IsSubscription Then
Progress.Perform()
Else
ProgressPre.Perform()
End If
ThrowAny(Token)
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
Next
@@ -140,25 +304,40 @@ Namespace API.XVIDEOS
End Try
End Sub
Private Sub GetUserID()
Dim r$ = Responser.GetResponse($"https://www.xvideos.com/{MySettings.GetUserUrlPart(Me)}",, EDP.ReturnValue)
Dim r$ = Responser.GetResponse(GetUserUrl(0),, EDP.ReturnValue)
If Not r.IsEmptyString Then ID = RegexReplace(r, RParams.DMS("""id_user"":(\d+)", 1, EDP.ReturnValue))
End Sub
Private Sub DownloadSavedVideos(ByVal Token As CancellationToken)
Dim URL$ = MySettings.SavedVideosPlaylist.Value
Try
Dim NextPage% = 0
Dim NextPage% = IIf(SiteMode = SiteModes.User, -1, 0)
Dim startPage% = NextPage
Dim __continue As Boolean = True
Dim r$
Dim round% = 0
Dim data As List(Of PlayListVideo)
Dim i%
Dim cBefore%
Dim limit% = If(DownloadTopCount, -1)
Do
round += 1
Wait429(round)
ThrowAny(Token)
URL = $"{MySettings.SavedVideosPlaylist.Value}{If(NextPage = 0, String.Empty, $"/{NextPage}")}"
NextPage += 1
cBefore = _TempMediaList.Count
If SiteMode = SiteModes.User Then
URL = $"{MySettings.SavedVideosPlaylist.Value}{If(NextPage = 0, String.Empty, $"/{NextPage}")}"
Else
URL = GetUserUrl(NextPage)
End If
r = Responser.GetResponse(URL,, EDP.ReturnValue)
If Responser.HasError Then
If Responser.StatusCode = Net.HttpStatusCode.NotFound Then
If NextPage = 0 Then
MyMainLOG = $"XVIDEOS saved video playlist {URL} not found."
If NextPage = startPage Then
If SiteMode = SiteModes.User Then MyMainLOG = $"XVIDEOS saved video playlist {URL} not found."
Exit Sub
Else
Exit Do
@@ -167,26 +346,32 @@ Namespace API.XVIDEOS
Throw New Exception(Responser.ErrorText, Responser.ErrorException)
End If
End If
NextPage += 1
If Not r.IsEmptyString Then
data = RegexFields(Of PlayListVideo)(r, {Regex_SavedVideosPlaylist}, {1, 2, 3}, EDP.ReturnValue)
If data.ListExists Then
If data.RemoveAll(Function(d) _TempPostsList.Contains(d.ID)) > 0 Then __continue = False
If data.ListExists Then
_TempPostsList.ListAddList(data.Select(Function(d) d.ID), LNC)
i = _TempMediaList.Count
_TempMediaList.ListAddList(data.Select(Function(d) d.ToUserMedia()), LNC)
If _TempMediaList.Count = i Or Not __continue Then Exit Do Else Continue Do
End If
End If
End If
Exit Do
Loop While NextPage < 100 And __continue
Loop While NextPage < 100 And __continue And _TempMediaList.Count > cBefore And (limit < 0 Or _TempMediaList.Count < limit)
If limit > 0 And _TempMediaList.Count >= limit Then _TempMediaList.ListAddList(_TempMediaList.ListTake(-1, limit), LAP.ClearBeforeAdd)
If _TempMediaList.Count > 0 Then
ProgressPre.ChangeMax(_TempMediaList.Count)
If SiteMode = SiteModes.User Then
ProgressPre.ChangeMax(_TempMediaList.Count)
Else
Progress.Maximum += _TempMediaList.Count
End If
For i% = 0 To _TempMediaList.Count - 1
ProgressPre.Perform()
If SiteMode = SiteModes.User Then
ProgressPre.Perform()
Else
Progress.Perform()
End If
ThrowAny(Token)
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
Next
@@ -205,31 +390,50 @@ Namespace API.XVIDEOS
If Not NewUrl.IsEmptyString Then
Dim appender$ = RegexReplace(NewUrl, Regex_M3U8_Appender)
Dim t$ = If(Media.PictureOption.IsEmptyString, RegexReplace(r, Regex_VideoTitle), Media.PictureOption)
r = Responser.GetResponse(NewUrl)
If Not r.IsEmptyString Then
Dim ls As List(Of Sizes) = RegexFields(Of Sizes)(r, {Regex_M3U8_Reparse}, {1, 2})
If ls.ListExists And Not MySettings.DownloadUHD.Value Then ls.RemoveAll(Function(v) Not v.Value.ValueBetween(1, 1080))
If ls.ListExists Then
ls.Sort()
NewUrl = $"{appender}/{ls(0).Data.StringTrimStart("/")}"
ls.Clear()
Dim pID$ = Media.Post.ID
If pID.IsEmptyString Then pID = RegexReplace(r, Regex_VideoID)
If pID.IsEmptyString Then pID = "0"
t = t.StringRemoveWinForbiddenSymbols.StringTrim
If t.IsEmptyString Then
t = pID
If IsSubscription Then
Dim thumb$ = RegexReplace(r, Regex_VideoThumbBig)
If thumb.IsEmptyString Then thumb = RegexReplace(r, Regex_VideoThumbSmall)
If thumb.IsEmptyString Then thumb = RegexReplace(r, Regex_VideosThumb_OG_IMAGE)
If Not thumb.IsEmptyString Then
Media.URL = thumb
If Not t.IsEmptyString Then
Media.PictureOption = t
Media.File = $"{t}.mp4"
Else
If t.Length > 100 Then t = Left(t, 100)
Media.PictureOption = "Video"
Media.File = "Video.mp4"
End If
If Not NewUrl.IsEmptyString Then
Return New UserMedia(NewUrl, UTypes.m3u8) With {
.Post = pID,
.URL_BASE = Media.URL,
.File = $"{t}.mp4",
.PictureOption = appender
}
Return Media
Else
Return Nothing
End If
Else
r = Responser.GetResponse(NewUrl)
If Not r.IsEmptyString Then
Dim ls As List(Of Sizes) = RegexFields(Of Sizes)(r, {Regex_M3U8_Reparse}, {1, 2})
If ls.ListExists And Not MySettings.DownloadUHD.Value Then ls.RemoveAll(Function(v) Not v.Value.ValueBetween(1, 1080))
If ls.ListExists Then
ls.Sort()
NewUrl = $"{appender}/{ls(0).Data.StringTrimStart("/")}"
ls.Clear()
Dim pID$ = Media.Post.ID
If pID.IsEmptyString Then pID = RegexReplace(r, Regex_VideoID)
If pID.IsEmptyString Then pID = "0"
t = t.StringRemoveWinForbiddenSymbols.StringTrim
If t.IsEmptyString Then
t = pID
Else
If t.Length > 100 Then t = Left(t, 100)
End If
If Not NewUrl.IsEmptyString Then
Return New UserMedia(NewUrl, UTypes.m3u8) With {
.Post = pID,
.URL_BASE = Media.URL,
.File = $"{t}.mp4",
.PictureOption = appender
}
End If
End If
End If
End If

View File

@@ -0,0 +1,17 @@
' 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.XVIDEOS
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
Friend Sub New()
End Sub
Friend Sub New(ByVal u As UserData)
QueryString = u.QueryString
End Sub
End Class
End Namespace

View File

@@ -12,7 +12,7 @@ Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Xhamster
<Manifest(XhamsterSiteKey), SavedPosts, SpecialForm(True), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
<Manifest(XhamsterSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
@@ -39,7 +39,7 @@ Namespace API.Xhamster
Domains.DestinationProp = SiteDomains
DownloadUHD = New PropertyValue(False)
_SubscriptionsAllowed = True
UrlPatternUser = "https://xhamster.com/{0}/{1}"
UserRegex = RParams.DMS($"/({UserOption}|{ChannelOption})/([^/]+)(\Z|.*)", 0, RegexReturn.ListByMatch)
ImageVideoContains = "xhamster"
@@ -77,18 +77,60 @@ Namespace API.Xhamster
End If
End Function
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
With DirectCast(User, UserData) : Return String.Format(UrlPatternUser, IIf(.IsChannel, ChannelOption, UserOption), .TrueName) : End With
With DirectCast(User, UserData)
If Not .SiteMode = SiteModes.User Then
Return .GetNonUserUrl(0)
Else
Return String.Format(UrlPatternUser, IIf(.IsChannel, ChannelOption, UserOption), .TrueName)
End If
End With
End Function
#Region "IsMyUser, IsMyImageVideo"
Friend Const ChannelOption As String = "channels"
Private Const UserOption As String = "users"
Friend Const P_Search As String = "search"
Friend Const P_Tags As String = "tags"
Friend Const P_Categories As String = "categories"
Friend Const P_Pornstars = "pornstars"
Private ReadOnly NonUsersRegex As RParams = RParams.DM("https?://[^/]+/((gay)/|(shemale)/|)(pornstars|tags|categories|search)/([^/\?]+)[/\?]?(.*)", 0,
RegexReturn.ListByMatch, EDP.ReturnValue)
Private ReadOnly PageRemover_1 As RParams = RParams.DM("[\?&]?[Pp]age=\d+", 0, RegexReturn.Replace, EDP.ReturnValue,
CType(Function(input) String.Empty, Func(Of String, String)))
Private ReadOnly PageRemover_2 As RParams = RParams.DM("/\d+\?", 0, RegexReturn.Replace, EDP.ReturnValue,
CType(Function(input) "?", Func(Of String, String)))
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
If Not UserURL.IsEmptyString AndAlso Domains.Domains.Count > 0 AndAlso Domains.Domains.Exists(Function(d) UserURL.ToLower.Contains(d.ToLower)) Then
Dim n$, opt$
Dim data As List(Of String) = RegexReplace(UserURL, UserRegex)
If data.ListExists(3) AndAlso Not data(2).IsEmptyString Then
Dim n$ = data(2)
n = data(2)
If Not data(1).IsEmptyString AndAlso data(1) = ChannelOption Then n &= $"@{data(1)}"
Return New ExchangeOptions(Site, n)
Else
data = RegexReplace(UserURL, NonUsersRegex)
If data.ListExists(7) AndAlso Not data(5).IsEmptyString Then
n = data(5).StringRemoveWinForbiddenSymbols
If Not n.IsEmptyString And Not data(4).IsEmptyString Then
Dim mode As SiteModes
Select Case data(4)
Case P_Search : mode = SiteModes.Search
Case P_Tags : mode = SiteModes.Tags
Case P_Categories : mode = SiteModes.Categories
Case P_Pornstars : mode = SiteModes.Pornstars
Case Else : Return Nothing
End Select
n = $"{CInt(mode)}@{n}"
Dim tmpOpt$ = data(6)
If Not tmpOpt.IsEmptyString Then
tmpOpt = RegexReplace(tmpOpt, PageRemover_1)
tmpOpt = RegexReplace(tmpOpt, PageRemover_2)
End If
'mode@gay@tags@arguments@query
opt = $"{CInt(mode)}@{data(2)}@{data(4)}@{tmpOpt}@{data(5)}"
Return New ExchangeOptions(Site, n) With {.Options = opt}
End If
End If
End If
End If
Return Nothing
@@ -99,6 +141,14 @@ Namespace API.Xhamster
End If
Return Nothing
End Function
#End Region
#Region "UserOptions"
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions
If OpenForm Then
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
#End Region
End Class
End Namespace

View File

@@ -19,10 +19,38 @@ Namespace API.Xhamster
Friend Class UserData : Inherits UserDataBase
#Region "XML names"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_Gender As String = "Gender"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_Arguments As String = "Arguments"
#End Region
#Region "Declarations"
Friend Overrides ReadOnly Property FeedIsUser As Boolean
Get
Return SiteMode = SiteModes.User
End Get
End Property
Friend Property IsChannel As Boolean = False
Friend Property TrueName As String = String.Empty
Friend Property Gender As String = String.Empty
Friend Property SiteMode As SiteModes = SiteModes.User
Friend Property Arguments As String = String.Empty
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
End Get
End Property
Friend Property QueryString As String
Get
If SiteMode = SiteModes.User Then
Return String.Empty
Else
Return GetNonUserUrl(0)
End If
End Get
Set(ByVal q As String)
UpdateUserOptions(True, q)
End Set
End Property
Private ReadOnly Property MySettings As SiteSettings
Get
Return DirectCast(HOST.Source, SiteSettings)
@@ -32,35 +60,106 @@ Namespace API.Xhamster
Friend IsPhoto As Boolean
End Structure
Private ReadOnly _TempPhotoData As List(Of UserMedia)
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
If Not Force OrElse (Not SiteMode = SiteModes.User AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
Dim eObj As Plugin.ExchangeOptions = Nothing
If Force Then eObj = MySettings.IsMyUser(NewUrl)
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And TrueName.IsEmptyString) Then
Dim n$() = If(Force, eObj.UserName, Name).Split("@")
If n.ListExists Then
If n.Length = 2 And If(Force, eObj.Options, Options).IsEmptyString Then
If Force Then Return False
TrueName = n(0)
IsChannel = True
ElseIf IsChannel Then
If Force Then Return False
TrueName = Name
ElseIf Not If(Force, eObj.Options, Options).IsEmptyString Then
Dim __TrueName$, __Arguments$, __Gender$
Dim __Mode As SiteModes
Dim __ForceApply As Boolean = False
Dim n2 As List(Of String) = If(Force, eObj.Options, Options).Split("@").ListIfNothing
If n2.ListExists Then
IsChannel = False
__Mode = CInt(n2(0))
__Gender = n2(1)
__Arguments = n2(3)
__TrueName = n2.ListTake(3, 100, EDP.ReturnValue).ListToString(String.Empty)
If Force AndAlso (Not TrueName = __TrueName Or Not SiteMode = __Mode Or Not Gender = __Gender) Then
If ValidateChangeSearchOptions(ToStringForLog,
$"{__Mode}{IIf(__Gender.IsEmptyString, String.Empty, $" ({__Gender})")}: {__TrueName}",
$"{SiteMode}{IIf(Gender.IsEmptyString, String.Empty, $" ({Gender})")}: {TrueName}") Then
__ForceApply = True
Else
Return False
End If
End If
Arguments = __Arguments
Options = If(Force, eObj.Options, Options)
If Not Force Then
TrueName = __TrueName
SiteMode = __Mode
Gender = __Gender
UserSiteName = $"{SiteMode}: {TrueName}"
If FriendlyName.IsEmptyString Then FriendlyName = UserSiteName
Settings.Labels.Add(SearchRequestLabelName)
Labels.ListAddValue(SearchRequestLabelName, LNC)
Labels.Sort()
ElseIf Force And __ForceApply Then
TrueName = __TrueName
SiteMode = __Mode
Gender = __Gender
End If
Return True
Else
If Force Then Return False
UserExists = False
End If
Else
If Force Then Return False
TrueName = n(0)
End If
End If
End If
End If
Return False
End Function
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
Dim setNames As Action = Sub()
If TrueName.IsEmptyString Then
Dim n$() = Name.Split("@")
If n.ListExists Then
If n.Length = 2 Then
TrueName = n(0)
IsChannel = True
ElseIf IsChannel Then
TrueName = Name
Else
TrueName = n(0)
End If
End If
End If
End Sub
With Container
If Loading Then
IsChannel = .Value(Name_IsChannel).FromXML(Of Boolean)(False)
TrueName = .Value(Name_TrueName)
setNames.Invoke
Gender = .Value(Name_Gender)
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
Arguments = .Value(Name_Arguments)
UpdateUserOptions()
Else
setNames.Invoke
If UpdateUserOptions() Then
.Value(Name_LabelsName) = LabelsString
.Value(Name_UserSiteName) = UserSiteName
.Value(Name_FriendlyName) = FriendlyName
End If
.Add(Name_IsChannel, IsChannel.BoolToInteger)
.Add(Name_TrueName, TrueName)
setNames.Invoke
.Add(Name_Gender, Gender)
.Add(Name_SiteMode, CInt(SiteMode))
.Add(Name_Arguments, Arguments)
'Debug.WriteLine(GetNonUserUrl(0))
'Debug.WriteLine(GetNonUserUrl(2))
End If
End With
End Sub
Friend Overrides Function ExchangeOptionsGet() As Object
Return New UserExchangeOptions(Me)
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then QueryString = DirectCast(Obj, UserExchangeOptions).QueryString
End Sub
#End Region
#Region "Initializer"
Friend Sub New()
@@ -69,11 +168,56 @@ Namespace API.Xhamster
_TempPhotoData = New List(Of UserMedia)
End Sub
#End Region
#Region "Download base functions"
#Region "Download functions"
Friend Function GetNonUserUrl(ByVal Page As Integer) As String
If SiteMode = SiteModes.User Then
Return String.Empty
Else
Dim url$ = "https://xhamster.com/"
If Not Gender.IsEmptyString Then url &= $"{Gender}/"
Select Case SiteMode
Case SiteModes.Tags : url &= SiteSettings.P_Tags
Case SiteModes.Categories : url &= SiteSettings.P_Categories
Case SiteModes.Search : url &= SiteSettings.P_Search
Case SiteModes.Pornstars : url &= SiteSettings.P_Pornstars
Case Else : Return String.Empty
End Select
url &= $"/{TrueName}"
Dim args$ = Arguments
If Page > 1 Then
If args.IsEmptyString Then
If SiteMode = SiteModes.Search Then
args = $"?page={Page}"
Else
args = $"/{Page}"
End If
Else
If SiteMode = SiteModes.Search Then
args = $"?{args}&page={Page}"
Else
If args.Contains("?") Then
args = $"/{args.Replace("?", $"/{Page}?")}"
Else
args = $"/{args.StringTrimEnd("/")}/{Page}"
End If
End If
End If
Else
If Not args.IsEmptyString Then args = $"{IIf(SiteMode = SiteModes.Search, "?", "/")}{args}"
End If
url &= args
Return url
End If
End Function
Private SearchPostsCount As Integer = 0
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
_TempPhotoData.Clear()
SearchPostsCount = 0
If DownloadVideos Then DownloadData(1, True, Token)
If Not IsChannel And DownloadImages Then
If Not IsChannel And DownloadImages And Not IsSubscription Then
DownloadData(1, False, Token)
ReparsePhoto(Token)
End If
@@ -85,19 +229,35 @@ Namespace API.Xhamster
Dim Type As UTypes = IIf(IsVideo, UTypes.VideoPre, UTypes.Picture)
Dim mPages$ = IIf(IsVideo, "maxVideoPages", "maxPhotoPages")
Dim listNode$()
Dim containerNodes As New List(Of String())
Dim skipped As Boolean = False
Dim limit% = If(DownloadTopCount, -1)
Dim cBefore% = _TempMediaList.Count
Dim m As UserMedia
Dim checkLimit As Func(Of Boolean) = Function() limit > 0 And SearchPostsCount >= limit And IsVideo
If IsSavedPosts Then
URL = $"https://xhamster.com/my/favorites/{IIf(IsVideo, "videos", "photos-and-galleries")}{IIf(Page = 1, String.Empty, $"/{Page}")}"
listNode = If(IsVideo, {"favoriteVideoListComponent", "models"}, {"favoritesGalleriesAndPhotosCollection"})
containerNodes.Add(If(IsVideo, {"favoriteVideoListComponent", "models"}, {"favoritesGalleriesAndPhotosCollection"}))
ElseIf IsChannel Then
URL = $"https://xhamster.com/channels/{TrueName}/newest{IIf(Page = 1, String.Empty, $"/{Page}")}"
listNode = {"trendingVideoListComponent", "models"}
containerNodes.Add({"trendingVideoListComponent", "models"})
containerNodes.Add({"pagesCategoryComponent", "trendingVideoListProps", "models"})
ElseIf SiteMode = SiteModes.Search Then
URL = GetNonUserUrl(Page)
containerNodes.Add({"searchResult", "models"})
ElseIf SiteMode = SiteModes.Tags Or SiteMode = SiteModes.Categories Or SiteMode = SiteModes.Pornstars Then
URL = GetNonUserUrl(Page)
If SiteMode = SiteModes.Pornstars Then
containerNodes.Add({"trendingVideoListComponent", "models"})
containerNodes.Add({"pagesCategoryComponent", "trendingVideoListProps", "models"})
Else
containerNodes.Add({"pagesCategoryComponent", "trendingVideoListProps", "models"})
containerNodes.Add({"trendingVideoListComponent", "models"})
End If
Else
URL = $"https://xhamster.com/users/{TrueName}/{IIf(IsVideo, "videos", "photos")}{IIf(Page = 1, String.Empty, $"/{Page}")}"
listNode = {If(IsVideo, "userVideoCollection", "userGalleriesCollection")}
containerNodes.Add({If(IsVideo, "userVideoCollection", "userGalleriesCollection")})
End If
ThrowAny(Token)
@@ -111,47 +271,54 @@ Namespace API.Xhamster
MaxPage = j.Value(mPages).FromXML(Of Integer)(-1)
With j(listNode)
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each e As EContainer In .Self
ProgressPre.Perform()
m = ExtractMedia(e, Type)
If Not m.URL.IsEmptyString Then
If m.File.IsEmptyString Then Continue For
For Each listNode In containerNodes
With j(listNode)
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each e As EContainer In .Self
ProgressPre.Perform()
m = ExtractMedia(e, Type)
If Not m.URL.IsEmptyString Then
If m.File.IsEmptyString Then Continue For
If m.Post.Date.HasValue Then
Select Case CheckDatesLimit(m.Post.Date.Value, Nothing)
Case DateResult.Skip : skipped = True : Continue For
Case DateResult.Exit : Exit Sub
End Select
End If
If m.Post.Date.HasValue Then
Select Case CheckDatesLimit(m.Post.Date.Value, Nothing)
Case DateResult.Skip : skipped = True : Continue For
Case DateResult.Exit : Exit Sub
End Select
End If
If IsVideo AndAlso Not _TempPostsList.Contains(m.Post.ID) Then
_TempPostsList.Add(m.Post.ID)
_TempMediaList.ListAddValue(m, LNC)
ElseIf Not IsVideo Then
If DirectCast(m.Object, ExchObj).IsPhoto Then
If Not m.Post.ID.IsEmptyString AndAlso Not _TempPostsList.Contains(m.Post.ID) Then
_TempPostsList.Add(m.Post.ID)
_TempMediaList.ListAddValue(m, LNC)
If IsVideo AndAlso Not _TempPostsList.Contains(m.Post.ID) Then
_TempPostsList.Add(m.Post.ID)
_TempMediaList.ListAddValue(m, LNC)
SearchPostsCount += 1
If checkLimit.Invoke Then Exit Sub
ElseIf Not IsVideo Then
If DirectCast(m.Object, ExchObj).IsPhoto Then
If Not m.Post.ID.IsEmptyString AndAlso Not _TempPostsList.Contains(m.Post.ID) Then
_TempPostsList.Add(m.Post.ID)
_TempMediaList.ListAddValue(m, LNC)
End If
Else
_TempPhotoData.ListAddValue(m, LNC)
End If
Else
_TempPhotoData.ListAddValue(m, LNC)
Exit Sub
End If
Else
Exit Sub
End If
End If
Next
End If
End With
Next
Exit For
End If
End With
Next
End If
End Using
End If
containerNodes.Clear()
If (Not _TempMediaList.Count = cBefore Or skipped) And
(IsChannel Or (MaxPage > 0 And Page < MaxPage)) Then DownloadData(Page + 1, IsVideo, Token)
(IsChannel Or (MaxPage > 0 And Page < MaxPage) Or (Not SiteMode = SiteModes.User And Page < 1000)) Then DownloadData(Page + 1, IsVideo, Token)
Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]")
End Try
@@ -159,30 +326,64 @@ Namespace API.Xhamster
#End Region
#Region "Reparse video, photo"
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
Dim URL$ = String.Empty
If IsSubscription Then
ReparseVideoSubscriptions(Token)
Else
Try
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
Dim m As UserMedia, m2 As UserMedia
ProgressPre.ChangeMax(_TempMediaList.Count)
For i% = _TempMediaList.Count - 1 To 0 Step -1
ProgressPre.Perform()
If _TempMediaList(i).Type = UTypes.VideoPre Then
m = _TempMediaList(i)
If Not m.URL_BASE.IsEmptyString Then
m2 = Nothing
If GetM3U8(m2, m.URL_BASE) Then
m2.URL_BASE = m.URL_BASE
_TempMediaList(i) = m2
Else
m.State = UserMedia.States.Missing
_TempMediaList(i) = m
End If
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "video reparsing error", False)
End Try
End If
End Sub
Private Sub ReparseVideoSubscriptions(ByVal Token As CancellationToken)
Try
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
Dim m As UserMedia, m2 As UserMedia
ProgressPre.ChangeMax(_TempMediaList.Count)
Dim c% = 0
Progress.Maximum += _TempMediaList.Count
For i% = _TempMediaList.Count - 1 To 0 Step -1
ProgressPre.Perform()
Progress.Perform()
If _TempMediaList(i).Type = UTypes.VideoPre Then
m = _TempMediaList(i)
If Not m.URL_BASE.IsEmptyString Then
m2 = Nothing
If GetM3U8(m2, m.URL_BASE) Then
m2.URL_BASE = m.URL_BASE
_TempMediaList(i) = m2
Else
m.State = UserMedia.States.Missing
_TempMediaList(i) = m
If Not DownloadTopCount.HasValue OrElse c <= DownloadTopCount.Value Then
m = _TempMediaList(i)
If Not m.URL_BASE.IsEmptyString Then
m2 = Nothing
If GetM3U8(m2, m.URL_BASE) Then
m2.URL_BASE = m.URL_BASE
_TempMediaList(i) = m2
c += 1
Else
_TempMediaList.RemoveAt(i)
End If
End If
Else
_TempMediaList.RemoveAt(i)
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "video reparsing error", False)
ProcessException(ex, Token, "subscriptions video reparsing error", False)
End Try
End Sub
Private Overloads Sub ReparsePhoto(ByVal Token As CancellationToken)
@@ -277,7 +478,16 @@ Namespace API.Xhamster
If j.ListExists Then
m = ExtractMedia(j("videoModel"), UTypes.VideoPre)
m.URL_BASE = URL
Return GetM3U8(m, j)
If IsSubscription Then
With j("videoModel")
If .ListExists Then
m.URL = .Value("thumbURL").IfNullOrEmpty(.Value("previewThumbURL"))
Return Not m.URL.IsEmptyString
End If
End With
Else
Return GetM3U8(m, j)
End If
End If
End Using
End If

View File

@@ -0,0 +1,21 @@
' 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.Attributes
Namespace API.Xhamster
Friend Class UserExchangeOptions
<PSetting(Address:=SettingAddress.User, Caption:="Query",
ToolTip:="Query string. Don't change this field when creating a user! Change it only for the same request.")>
Friend Property QueryString As String
Friend Sub New()
End Sub
Friend Sub New(ByVal u As UserData)
QueryString = u.QueryString
End Sub
End Class
End Namespace

View File

@@ -41,6 +41,7 @@ Namespace API.YouTube
DownloadShorts = New PropertyValue(False)
DownloadPlaylists = New PropertyValue(False)
UseCookies = New PropertyValue(False)
_SubscriptionsAllowed = True
End Sub
#End Region
#Region "GetInstance"

View File

@@ -113,6 +113,7 @@ Namespace API.YouTube
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Dim pr As New YTPreProgress(ProgressPre)
Try
If IsSubscription And IsMusic Then Exit Sub
Dim container As IYouTubeMediaContainer = Nothing
Dim list As New List(Of IYouTubeMediaContainer)
Dim url$ = String.Empty
@@ -191,8 +192,9 @@ Namespace API.YouTube
If Settings.UserSiteNameUpdateEveryTime Or UserSiteName.IsEmptyString Then UserSiteName = .UserTitle
If FriendlyName.IsEmptyString Then FriendlyName = UserSiteName
End With
_TempMediaList.AddRange(list.Select(Function(c) New UserMedia(c)))
_TempMediaList.AddRange(list.Select(Function(c) New UserMedia(c) With {.URL = If(IsSubscription, c.ThumbnailUrlMedia, .URL)}))
_TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC)
If IsSubscription Then _TempMediaList.RemoveAll(Function(m) m.URL.IsEmptyString)
list.Clear()
End If
Catch ex As Exception

View File

@@ -336,7 +336,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
End With
Settings.Users.Add(tmpUser)
With Settings.Users.Last
.Labels.Add(UserData.CannelsLabelName_ChannelsForm)
.Labels.ListAddList({UserData.CannelsLabelName_ChannelsForm, LabelsKeeper.NoParsedUser})
.UpdateUserInformation()
If Settings.FromChannelCopyImageToUser And Not f.IsEmptyString And Not .File.IsEmptyString Then _
CopyFile(ListAddValue(Nothing, New ChannelsCollection.ChannelImage(cn, f)).ListAddList(Settings.Channels.GetUserFiles(.Name), c), .File)

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -80,7 +80,7 @@ Namespace DownloadObjects
If Not AutoDownloaderSource Is Nothing And Settings.ProcessNotification(SettingsCLS.NotificationObjects.AutoDownloader) Then
If AutoDownloaderSource.ShowNotifications Then
If Not User Is Nothing Then
Dim Text$ = $"{User.Site} - {User.Name}{vbNewLine}" &
Dim Text$ = $"{IIf(User.IsSubscription, "[Subscription] ", String.Empty)}{User.Site} - {User.Name}{vbNewLine}" &
$"Downloaded: {User.DownloadedPictures(False)} images, {User.DownloadedVideos(False)} videos"
Dim Title$
If Not User.CollectionName.IsEmptyString Then
@@ -96,7 +96,7 @@ Namespace DownloadObjects
Dim uifKey$ = String.Empty
If AutoDownloaderSource.ShowPictureUser Then uPic = DirectCast(User, UserDataBase).GetUserPictureToastAddress
If AutoDownloaderSource.ShowPictureUser AndAlso uPic.Exists Then Notify.Images = {New ToastImage(uPic)}
If AutoDownloaderSource.ShowPictureDownloaded And User.DownloadedPictures(False) > 0 Then
If AutoDownloaderSource.ShowPictureDownloaded And User.DownloadedPictures(False) > 0 And Not User.IsSubscription Then
uif = DirectCast(User, UserDataBase).GetLastImageAddress
uif_orig = uif
If uif.Exists Then
@@ -129,7 +129,7 @@ Namespace DownloadObjects
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[AutoDownloader.NotifiedUser.ShowNotification]")
If Not User Is Nothing Then
MainFrameObj.ShowNotification(SettingsCLS.NotificationObjects.AutoDownloader,
User.ToString & vbNewLine &
If(User.IsSubscription, "[Subscription] ", String.Empty) & User.ToString & vbNewLine &
$"Downloaded: {User.DownloadedPictures(False)} images, {User.DownloadedVideos(False)} videos" &
If(User.HasError, vbNewLine & "With errors", String.Empty))
End If
@@ -142,7 +142,11 @@ Namespace DownloadObjects
ElseIf Key = _Key Then
Return True
ElseIf KeyFolder = _Key Then
User.OpenFolder()
If User.IsSubscription Then
Return True
Else
User.OpenFolder()
End If
ElseIf KeySite = _Key Then
User.OpenSite()
ElseIf Images.ContainsKey(_Key) Then
@@ -216,6 +220,7 @@ Namespace DownloadObjects
Private ReadOnly LastDownloadDateXML As Date? = Nothing
Private _LastDownloadDate As Date = Now.AddYears(-1)
Private _LastDownloadDateChanged As Boolean = False
Private _LastDownloadDateSkip As Date? = Nothing
Friend Property LastDownloadDate As Date
Get
Return _LastDownloadDate
@@ -227,10 +232,11 @@ Namespace DownloadObjects
End Property
Private ReadOnly Property NextExecutionDate As Date
Get
Dim lds As Date = If(_LastDownloadDateSkip, Date.MinValue)
If _PauseValue.HasValue Then
Return {LastDownloadDate.AddMinutes(Timer), _StartTime.AddMinutes(StartupDelay), _PauseValue.Value}.Max
Return {LastDownloadDate.AddMinutes(Timer), _StartTime.AddMinutes(StartupDelay), _PauseValue.Value, lds}.Max
Else
Return {LastDownloadDate.AddMinutes(Timer), _StartTime.AddMinutes(StartupDelay)}.Max
Return {LastDownloadDate.AddMinutes(Timer), _StartTime.AddMinutes(StartupDelay), lds}.Max
End If
End Get
End Property
@@ -411,21 +417,33 @@ Namespace DownloadObjects
Friend Sub [Stop]()
If Working Then _StopRequested = True
End Sub
Friend Sub Skip()
Friend Overloads Sub Skip()
If LastDownloadDate.AddMinutes(Timer) <= Now Then
LastDownloadDate = Now.AddMinutes(Timer)
_LastDownloadDateSkip = Now.AddMinutes(Timer)
Else
LastDownloadDate = LastDownloadDate.AddMinutes(Timer)
_LastDownloadDateSkip = LastDownloadDate.AddMinutes(Timer)
End If
End Sub
Friend Overloads Sub Skip(ByVal Minutes As Integer)
_LastDownloadDateSkip = If(_LastDownloadDateSkip, Now).AddMinutes(Minutes)
End Sub
Friend Overloads Sub Skip(ByVal ToDate As Date)
_LastDownloadDateSkip = ToDate
End Sub
Friend Sub SkipReset()
_LastDownloadDateSkip = Nothing
End Sub
Friend Sub ForceStart()
_ForceStartRequested = True
End Sub
Private _ForceStartRequested As Boolean = False
Private _SpecialDelayUse As Boolean = False
Private _SpecialDelayTime As Date? = Nothing
Private Sub Checker()
Try
Dim _StartDownload As Boolean
While (Not _StopRequested Or Downloader.Working) And Not Mode = Modes.None
If LastDownloadDate.AddMinutes(Timer) < Now And _StartTime.AddMinutes(StartupDelay) < Now And
Not IsPaused And Not _StopRequested And Not Mode = Modes.None Then
If ((NextExecutionDate < Now And Not IsPaused) Or _ForceStartRequested) And Not _StopRequested And Not Mode = Modes.None Then
If Downloader.Working Then
_SpecialDelayUse = True
Else
@@ -434,9 +452,7 @@ Namespace DownloadObjects
_SpecialDelayUse = False
_SpecialDelayTime = Nothing
_StartDownload = False
If Settings.Automation.Count = 1 Then
_StartDownload = True
ElseIf Index = -1 Then
If Settings.Automation.Count = 1 Or _ForceStartRequested Or Index = -1 Then
_StartDownload = True
Else
_StartDownload = NextExecutionDate.AddMilliseconds(1000 * (Index + 1)).Ticks <= Now.Ticks
@@ -467,6 +483,7 @@ Namespace DownloadObjects
Dim GName$
Dim i%
Dim DownloadedUsersCount% = 0
Dim DownloadedSubscriptionsCount% = 0
Dim simple As Boolean = ShowSimpleNotification And ShowNotifications
Dim notify As Action = Sub()
Try
@@ -476,7 +493,11 @@ Namespace DownloadObjects
With .Item(indx)
If Keys.Contains(.Key) Then
If simple Then
DownloadedUsersCount += 1
If .IsSubscription Then
DownloadedSubscriptionsCount += 1
Else
DownloadedUsersCount += 1
End If
Else
ShowNotification(.Self)
End If
@@ -501,9 +522,27 @@ Namespace DownloadObjects
End If
End Function
Dim CheckSites As Predicate(Of IUserData) = Function(u) SitesExcluded.Count = 0 OrElse Not SitesExcluded.Contains(u.Site)
users.ListAddList(Settings.GetUsers(Function(u) UserExistsPredicate(u) And CheckLabels.Invoke(u) And CheckSites.Invoke(u)))
Dim ExistsPredicate As Predicate(Of IUserData)
If Subscriptions Then
If SubscriptionsOnly Then
ExistsPredicate = UserExistsSubscriptionsPredicate
Else
ExistsPredicate = UserExistsPredicate
End If
Else
ExistsPredicate = UserExistsNonSubscriptionsPredicate
End If
users.ListAddList(Settings.GetUsers(Function(u) ExistsPredicate(u) And CheckLabels.Invoke(u) And CheckSites.Invoke(u)))
If UsersCount <> 0 And users.Count > 0 Then
users = users.ListTake(If(UsersCount > 0, -1, -2), Math.Abs(UsersCount))
If UsersCount < 0 Then users = users.ListReverse
End If
Case Modes.Default
Using g As New GroupParameters : users.ListAddList(DownloadGroup.GetUsers(g, True)) : End Using
Using g As New GroupParameters
g.LabelsExcluded.ListAddList(LabelsExcluded)
g.SitesExcluded.ListAddList(SitesExcluded)
users.ListAddList(DownloadGroup.GetUsers(g, True))
End Using
Case Modes.Specified : users.ListAddList(DownloadGroup.GetUsers(Me, True))
Case Modes.Groups
If Groups.Count > 0 And Settings.Groups.Count > 0 Then
@@ -522,9 +561,13 @@ Namespace DownloadObjects
While .Working Or .Count > 0 : notify.Invoke() : Thread.Sleep(200) : End While
.AutoDownloaderWorking = False
notify.Invoke
If simple And DownloadedUsersCount > 0 Then _
MainFrameObj.ShowNotification(SettingsCLS.NotificationObjects.AutoDownloader,
$"{DownloadedUsersCount} user(s) downloaded with scheduler plan '{Name}'")
If simple And DownloadedUsersCount + DownloadedSubscriptionsCount > 0 Then
Dim msg$ = String.Empty
If DownloadedUsersCount > 0 Then msg = $"{DownloadedUsersCount} user(s) "
If DownloadedSubscriptionsCount > 0 Then msg &= $"{IIf(DownloadedUsersCount > 0, "and ", String.Empty)}{DownloadedSubscriptionsCount} subscription(s) "
msg &= $"downloaded with scheduler plan '{Name}'"
MainFrameObj.ShowNotification(SettingsCLS.NotificationObjects.AutoDownloader, msg)
End If
End With
End If
Catch ex As Exception
@@ -534,6 +577,8 @@ Namespace DownloadObjects
LastDownloadDate = Now
Update()
_Downloading = False
_ForceStartRequested = False
_LastDownloadDateSkip = Nothing
End Try
End Sub
Private Sub ShowNotification(ByVal u As IUserData)

View File

@@ -66,13 +66,13 @@ Namespace DownloadObjects
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.DEF_GROUP)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(476, 308)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(476, 363)
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(476, 333)
CONTAINER_MAIN.Size = New System.Drawing.Size(476, 388)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
@@ -81,20 +81,22 @@ Namespace DownloadObjects
Me.DEF_GROUP.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
Me.DEF_GROUP.ColumnCount = 1
Me.DEF_GROUP.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.DEF_GROUP.Controls.Add(Me.TXT_GROUPS, 0, 6)
Me.DEF_GROUP.Controls.Add(TP_MODE, 0, 0)
Me.DEF_GROUP.Controls.Add(Me.TXT_TIMER, 0, 8)
Me.DEF_GROUP.Controls.Add(Me.LBL_LAST_TIME_UP, 0, 10)
Me.DEF_GROUP.Controls.Add(Me.NUM_DELAY, 0, 9)
Me.DEF_GROUP.Controls.Add(TP_NOTIFY, 0, 7)
Me.DEF_GROUP.Controls.Add(Me.TXT_GROUPS, 0, 8)
Me.DEF_GROUP.Controls.Add(TP_NOTIFY, 0, 9)
Me.DEF_GROUP.Controls.Add(Me.TXT_TIMER, 0, 10)
Me.DEF_GROUP.Controls.Add(Me.NUM_DELAY, 0, 11)
Me.DEF_GROUP.Controls.Add(Me.LBL_LAST_TIME_UP, 0, 12)
Me.DEF_GROUP.Dock = System.Windows.Forms.DockStyle.Fill
Me.DEF_GROUP.Location = New System.Drawing.Point(0, 0)
Me.DEF_GROUP.Name = "DEF_GROUP"
Me.DEF_GROUP.RowCount = 12
Me.DEF_GROUP.RowCount = 14
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
@@ -104,7 +106,7 @@ Namespace DownloadObjects
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.DEF_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.DEF_GROUP.Size = New System.Drawing.Size(476, 308)
Me.DEF_GROUP.Size = New System.Drawing.Size(476, 363)
Me.DEF_GROUP.TabIndex = 0
'
'TXT_GROUPS
@@ -118,7 +120,7 @@ Namespace DownloadObjects
Me.TXT_GROUPS.CaptionText = "Groups"
Me.TXT_GROUPS.CaptionWidth = 50.0R
Me.TXT_GROUPS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_GROUPS.Location = New System.Drawing.Point(4, 169)
Me.TXT_GROUPS.Location = New System.Drawing.Point(4, 195)
Me.TXT_GROUPS.Name = "TXT_GROUPS"
Me.TXT_GROUPS.Size = New System.Drawing.Size(468, 22)
Me.TXT_GROUPS.TabIndex = 1
@@ -222,7 +224,7 @@ Namespace DownloadObjects
Me.TXT_TIMER.CaptionToolTipText = "Timer (in minutes)"
Me.TXT_TIMER.CaptionWidth = 50.0R
Me.TXT_TIMER.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_TIMER.Location = New System.Drawing.Point(4, 227)
Me.TXT_TIMER.Location = New System.Drawing.Point(4, 282)
Me.TXT_TIMER.Name = "TXT_TIMER"
Me.TXT_TIMER.Size = New System.Drawing.Size(468, 22)
Me.TXT_TIMER.TabIndex = 3
@@ -232,7 +234,7 @@ Namespace DownloadObjects
Me.LBL_LAST_TIME_UP.AutoSize = True
Me.LBL_LAST_TIME_UP.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_LAST_TIME_UP.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_LAST_TIME_UP.Location = New System.Drawing.Point(4, 282)
Me.LBL_LAST_TIME_UP.Location = New System.Drawing.Point(4, 337)
Me.LBL_LAST_TIME_UP.Name = "LBL_LAST_TIME_UP"
Me.LBL_LAST_TIME_UP.Size = New System.Drawing.Size(468, 25)
Me.LBL_LAST_TIME_UP.TabIndex = 5
@@ -251,7 +253,7 @@ Namespace DownloadObjects
Me.NUM_DELAY.ClearTextByButtonClear = False
Me.NUM_DELAY.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.NUM_DELAY.Dock = System.Windows.Forms.DockStyle.Fill
Me.NUM_DELAY.Location = New System.Drawing.Point(4, 256)
Me.NUM_DELAY.Location = New System.Drawing.Point(4, 311)
Me.NUM_DELAY.Name = "NUM_DELAY"
Me.NUM_DELAY.NumberMaximum = New Decimal(New Integer() {1440, 0, 0, 0})
Me.NUM_DELAY.NumberUpDownAlign = System.Windows.Forms.LeftRightAlignment.Left
@@ -271,7 +273,7 @@ Namespace DownloadObjects
TP_NOTIFY.Controls.Add(Me.CH_SHOW_PIC_USER, 3, 0)
TP_NOTIFY.Controls.Add(Me.CH_NOTIFY_SIMPLE, 1, 0)
TP_NOTIFY.Dock = System.Windows.Forms.DockStyle.Fill
TP_NOTIFY.Location = New System.Drawing.Point(1, 195)
TP_NOTIFY.Location = New System.Drawing.Point(1, 250)
TP_NOTIFY.Margin = New System.Windows.Forms.Padding(0)
TP_NOTIFY.Name = "TP_NOTIFY"
TP_NOTIFY.RowCount = 1
@@ -331,15 +333,15 @@ Namespace DownloadObjects
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(476, 333)
Me.ClientSize = New System.Drawing.Size(476, 388)
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(492, 372)
Me.MaximumSize = New System.Drawing.Size(492, 427)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(492, 372)
Me.MinimumSize = New System.Drawing.Size(492, 427)
Me.Name = "AutoDownloaderEditorForm"
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "AutoDownloader settings"

View File

@@ -114,7 +114,7 @@ Namespace DownloadObjects
Private Sub ChangeEnabled() Handles OPT_DISABLED.CheckedChanged, OPT_ALL.CheckedChanged, OPT_DEFAULT.CheckedChanged,
OPT_SPEC.CheckedChanged, OPT_GROUP.CheckedChanged,
CH_NOTIFY.CheckedChanged, CH_NOTIFY_SIMPLE.CheckedChanged
DEF_GROUP.Enabled(OPT_ALL.Checked Or OPT_DEFAULT.Checked Or OPT_SPEC.Checked) = OPT_SPEC.Checked
DEF_GROUP.Enabled(OPT_ALL.Checked Or OPT_DEFAULT.Checked Or OPT_SPEC.Checked, OPT_ALL.Checked) = OPT_SPEC.Checked
TXT_GROUPS.Enabled = OPT_GROUP.Checked
TXT_TIMER.Enabled = Not OPT_DISABLED.Checked
NUM_DELAY.Enabled = Not OPT_DISABLED.Checked

View File

@@ -12,8 +12,13 @@ Namespace DownloadObjects
Friend Class SchedulerEditorForm
#Region "Declarations"
Private WithEvents MyDefs As DefaultFormOptions
Private WithEvents BTT_SKIP As ToolStripButton
Private ReadOnly MENU_SKIP As ToolStripDropDownButton
Private WithEvents BTT_SKIP As ToolStripMenuItem
Private WithEvents BTT_SKIP_MIN As ToolStripMenuItem
Private WithEvents BTT_SKIP_DATE As ToolStripMenuItem
Private WithEvents BTT_SKIP_RESET As ToolStripMenuItem
Private WithEvents BTT_START As ToolStripButton
Private WithEvents BTT_START_FORCE As ToolStripButton
Private WithEvents BTT_PAUSE As ToolStripDropDownButton
Private WithEvents PauseArr As AutoDownloaderPauseButtons
#End Region
@@ -21,18 +26,52 @@ Namespace DownloadObjects
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
BTT_SKIP = New ToolStripButton With {
MENU_SKIP = New ToolStripDropDownButton With {
.Text = "Skip",
.ToolTipText = "Skip next run",
.ToolTipText = String.Empty,
.AutoToolTip = False,
.DisplayStyle = ToolStripItemDisplayStyle.Text
}
BTT_SKIP = New ToolStripMenuItem With {
.Text = "Skip",
.ToolTipText = "Delay for the number of minutes configured in the task",
.AutoToolTip = True,
.DisplayStyle = ToolStripItemDisplayStyle.Text
}
BTT_SKIP_MIN = New ToolStripMenuItem With {
.Text = "Delay for minutes",
.ToolTipText = "Delay for a specific number of minutes",
.AutoToolTip = True,
.DisplayStyle = ToolStripItemDisplayStyle.Text,
.Tag = "m"
}
BTT_SKIP_DATE = New ToolStripMenuItem With {
.Text = "Delay by date/time",
.ToolTipText = String.Empty,
.AutoToolTip = False,
.DisplayStyle = ToolStripItemDisplayStyle.Text,
.Tag = "d"
}
BTT_SKIP_RESET = New ToolStripMenuItem With {
.Text = "Delay reset",
.ToolTipText = "Reset the delay you set earlier",
.AutoToolTip = True,
.DisplayStyle = ToolStripItemDisplayStyle.Text,
.Tag = "r"
}
MENU_SKIP.DropDownItems.AddRange({BTT_SKIP, BTT_SKIP_MIN, BTT_SKIP_DATE, New ToolStripSeparator, BTT_SKIP_RESET})
BTT_START = New ToolStripButton With {
.Text = "Start",
.Image = My.Resources.StartPic_Green_16,
.ToolTipText = "Run selected plan",
.AutoToolTip = True
}
BTT_START_FORCE = New ToolStripButton With {
.Text = "Start (force)",
.ToolTipText = "Force start of the current task",
.AutoToolTip = True,
.Image = My.Resources.StartPic_Green_16
}
BTT_PAUSE = New ToolStripDropDownButton With {
.Text = "Pause",
.Image = My.Resources.Pause_Blue_16,
@@ -47,7 +86,7 @@ Namespace DownloadObjects
Private Sub SchedulerEditorForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddEditToolbarPlus({BTT_START, BTT_SKIP, BTT_PAUSE})
.AddEditToolbarPlus({New ToolStripSeparator, BTT_START, BTT_START_FORCE, MENU_SKIP, BTT_PAUSE})
PauseArr.AddButtons(BTT_PAUSE, .MyEditToolbar.ToolStrip)
Refill()
.EndLoaderOperations(False)
@@ -138,10 +177,38 @@ Namespace DownloadObjects
Refill()
End If
End Sub
Private Sub BTT_SKIP_Click(sender As Object, e As EventArgs) Handles BTT_SKIP.Click
Private Sub BTT_START_FORCE_Click(sender As Object, e As EventArgs) Handles BTT_START_FORCE.Click
If _LatestSelected.ValueBetween(0, LIST_PLANS.Items.Count - 1) Then
Settings.Automation(_LatestSelected).Skip()
Refill()
With Settings.Automation(_LatestSelected)
If .Working Then .ForceStart() : Refill()
End With
End If
End Sub
Private Sub BTT_SKIP_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles BTT_SKIP.Click, BTT_SKIP_MIN.Click, BTT_SKIP_DATE.Click, BTT_SKIP_RESET.Click
If _LatestSelected.ValueBetween(0, LIST_PLANS.Items.Count - 1) Then
Dim mode$ = AConvert(Of String)(Sender.Tag, String.Empty)
Select Case mode
Case String.Empty
Settings.Automation(_LatestSelected).Skip()
Refill()
Case "m"
Dim mins% = AConvert(Of Integer)(InputBoxE("Enter a number of minutes you want to delay:", Sender.Text, 60), -1)
If mins > 0 Then Settings.Automation(_LatestSelected).Skip(mins) : Refill()
Case "d"
Dim d As Date? = Nothing
Using f As New DateTimeSelectionForm(DateTimeSelectionForm.Modes.Date +
DateTimeSelectionForm.Modes.Time +
DateTimeSelectionForm.Modes.Start, Settings.Design) With {
.MyDateStart = Now.AddMinutes(60)
}
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then d = f.MyDateStart
End Using
If d.HasValue Then Settings.Automation(_LatestSelected).Skip(d.Value) : Refill()
Case "r"
Settings.Automation(_LatestSelected).SkipReset()
Refill()
End Select
End If
End Sub
Private Sub PauseArr_Updating() Handles PauseArr.Updating

View File

@@ -24,11 +24,14 @@ Namespace DownloadObjects
Private Sub InitializeComponent()
Dim SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadedInfoForm))
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
Me.MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
Me.MENU_VIEW_SESSION = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_VIEW_ALL = New System.Windows.Forms.ToolStripMenuItem()
Me.OPT_DEFAULT = New System.Windows.Forms.ToolStripMenuItem()
Me.OPT_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
Me.BTT_UP = New System.Windows.Forms.ToolStripButton()
Me.BTT_DOWN = New System.Windows.Forms.ToolStripButton()
@@ -38,6 +41,7 @@ Namespace DownloadObjects
Me.LIST_DOWN = New System.Windows.Forms.ListBox()
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
Me.ToolbarTOP.SuspendLayout()
Me.SuspendLayout()
'
@@ -51,6 +55,11 @@ Namespace DownloadObjects
SEP_2.Name = "SEP_2"
SEP_2.Size = New System.Drawing.Size(6, 25)
'
'MENU_VIEW_SEP_1
'
MENU_VIEW_SEP_1.Name = "MENU_VIEW_SEP_1"
MENU_VIEW_SEP_1.Size = New System.Drawing.Size(211, 6)
'
'ToolbarTOP
'
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
@@ -63,18 +72,18 @@ Namespace DownloadObjects
'MENU_VIEW
'
Me.MENU_VIEW.AutoToolTip = False
Me.MENU_VIEW.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW_SESSION, Me.MENU_VIEW_ALL})
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW_SESSION, Me.MENU_VIEW_ALL, MENU_VIEW_SEP_1, Me.OPT_DEFAULT, Me.OPT_SUBSCRIPTIONS})
Me.MENU_VIEW.Image = CType(resources.GetObject("MENU_VIEW.Image"), System.Drawing.Image)
Me.MENU_VIEW.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_VIEW.Name = "MENU_VIEW"
Me.MENU_VIEW.Size = New System.Drawing.Size(45, 22)
Me.MENU_VIEW.Size = New System.Drawing.Size(61, 22)
Me.MENU_VIEW.Text = "View"
'
'MENU_VIEW_SESSION
'
Me.MENU_VIEW_SESSION.AutoToolTip = True
Me.MENU_VIEW_SESSION.Name = "MENU_VIEW_SESSION"
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(180, 22)
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(214, 22)
Me.MENU_VIEW_SESSION.Text = "Session"
Me.MENU_VIEW_SESSION.ToolTipText = "Show downloaded users by this session"
'
@@ -82,10 +91,26 @@ Namespace DownloadObjects
'
Me.MENU_VIEW_ALL.AutoToolTip = True
Me.MENU_VIEW_ALL.Name = "MENU_VIEW_ALL"
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(180, 22)
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(214, 22)
Me.MENU_VIEW_ALL.Text = "All"
Me.MENU_VIEW_ALL.ToolTipText = "Show all users (sorted by latest download)"
'
'OPT_DEFAULT
'
Me.OPT_DEFAULT.AutoToolTip = True
Me.OPT_DEFAULT.Name = "OPT_DEFAULT"
Me.OPT_DEFAULT.Size = New System.Drawing.Size(214, 22)
Me.OPT_DEFAULT.Text = "Downloaded users"
Me.OPT_DEFAULT.ToolTipText = "Show downloaded users"
'
'OPT_SUBSCRIPTIONS
'
Me.OPT_SUBSCRIPTIONS.AutoToolTip = True
Me.OPT_SUBSCRIPTIONS.Name = "OPT_SUBSCRIPTIONS"
Me.OPT_SUBSCRIPTIONS.Size = New System.Drawing.Size(214, 22)
Me.OPT_SUBSCRIPTIONS.Text = "Downloaded subscriptions"
Me.OPT_SUBSCRIPTIONS.ToolTipText = "Show downloaded subscriptions"
'
'BTT_REFRESH
'
Me.BTT_REFRESH.Image = Global.SCrawler.My.Resources.Resources.RefreshPic_24
@@ -179,5 +204,7 @@ Namespace DownloadObjects
Private WithEvents BTT_FIND As ToolStripButton
Private WithEvents BTT_UP As ToolStripButton
Private WithEvents BTT_DOWN As ToolStripButton
Private WithEvents OPT_DEFAULT As ToolStripMenuItem
Private WithEvents OPT_SUBSCRIPTIONS As ToolStripMenuItem
End Class
End Namespace

View File

@@ -123,10 +123,21 @@
<metadata name="SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABkSURBVDhPY6AKyO86WFDQfeg/iIYKkQZAmkNbnvyXta76
DxViYGFi+Y8PQ5VBAMhmkGYgJs8FAw9GA5EKILFiWUFixfL/IBoqRBoAafYsOvpf0jiTvEAE2QzSLGmU
MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_UP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8

View File

@@ -16,7 +16,6 @@ Namespace DownloadObjects
#End Region
#Region "Declarations"
Private MyView As FormView
Private ReadOnly LParams As New ListAddParams(LAP.IgnoreICopier) With {.Error = EDP.None}
Private Opened As Boolean = False
Friend ReadOnly Property ReadyToOpen As Boolean
Get
@@ -35,12 +34,29 @@ Namespace DownloadObjects
Settings.InfoViewMode.Value = CInt(SMode)
End Set
End Property
Private ReadOnly _TempUsersList As List(Of IUserData)
Private ReadOnly _UsersListSession As List(Of IUserData)
Private ReadOnly _UsersListAll As List(Of IUserData)
Private ReadOnly Property Current As List(Of IUserData)
Get
Return If(ViewMode = ViewModes.All, _UsersListAll, _UsersListSession)
End Get
End Property
Private Overloads ReadOnly Property SelectedUser As IUserData
Get
If ViewMode = ViewModes.All Then
If _LatestSelected.ValueBetween(0, _UsersListAll.Count - 1) Then Return _UsersListAll(_LatestSelected)
Else
If _LatestSelected.ValueBetween(0, _UsersListSession.Count - 1) Then Return _UsersListSession(_LatestSelected)
End If
Return Nothing
End Get
End Property
#End Region
#Region "Initializer"
Public Sub New()
InitializeComponent()
_TempUsersList = New List(Of IUserData)
_UsersListSession = New List(Of IUserData)
_UsersListAll = New List(Of IUserData)
If Settings.InfoViewMode.Value = CInt(ViewModes.All) Then
MENU_VIEW_SESSION.Checked = False
MENU_VIEW_ALL.Checked = True
@@ -48,6 +64,8 @@ Namespace DownloadObjects
MENU_VIEW_SESSION.Checked = True
MENU_VIEW_ALL.Checked = False
End If
OPT_DEFAULT.Checked = Settings.InfoViewDefault
OPT_SUBSCRIPTIONS.Checked = Not Settings.InfoViewDefault
Settings.InfoViewMode.Value = ViewMode
RefillList()
End Sub
@@ -56,8 +74,8 @@ Namespace DownloadObjects
Private Sub DownloadedInfoForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
If MyView Is Nothing Then
MyView = New FormView(Me)
MyView.Import(Settings.Design)
MyView = New FormView(Me, Settings.Design)
MyView.Import()
MyView.SetFormSize()
End If
BTT_CLEAR.Visible = ViewMode = ViewModes.Session
@@ -72,8 +90,9 @@ Namespace DownloadObjects
Hide()
End Sub
Private Sub DownloadedInfoForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
If Not MyView Is Nothing Then MyView.Dispose(Settings.Design)
_TempUsersList.Clear()
MyView.DisposeIfReady()
_UsersListSession.Clear()
_UsersListAll.Clear()
End Sub
Private Sub DownloadedInfoForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
@@ -98,25 +117,36 @@ Namespace DownloadObjects
End Class
Private Sub RefillList() Handles BTT_REFRESH.Click
Try
_TempUsersList.Clear()
Dim lClear As Action = Sub() LIST_DOWN.Items.Clear()
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(lClear) Else lClear.Invoke
If ViewMode = ViewModes.Session Then
_TempUsersList.ListAddList(Downloader.Downloaded, LParams)
With Downloader.Downloaded
If .Count > 0 Then
With .Select(Function(u) Settings.GetUser(u, False)).Reverse
If _UsersListSession.Count > 0 Then _UsersListSession.ListWithRemove(.Self)
If _UsersListSession.Count > 0 Then
_UsersListSession.InsertRange(0, .Self)
Else
_UsersListSession.AddRange(.Self)
End If
End With
End If
End With
Else
_TempUsersList.ListAddList(Settings.Users.SelectMany(Of IUserData) _
(Function(u) If(u.IsCollection, DirectCast(u, API.UserDataBind).Collections, {u})), LParams)
_UsersListAll.ListAddList(Settings.GetUsers(Function(u) True), LAP.ClearBeforeAdd)
If _UsersListAll.Count > 0 Then _UsersListAll.Sort(New UsersDateOrder)
End If
If _TempUsersList.Count > 0 Then
_TempUsersList.Sort(New UsersDateOrder)
For Each user As IUserData In _TempUsersList
Dim isDefault As Boolean = OPT_DEFAULT.Checked
If Current.Count > 0 Then Current.RemoveAll(Function(u) u.IsSubscription = isDefault)
If Current.Count > 0 Then
For Each user As IUserData In Current
If LIST_DOWN.InvokeRequired Then
LIST_DOWN.Invoke(Sub() LIST_DOWN.Items.Add(user.DownloadedInformation))
Else
LIST_DOWN.Items.Add(user.DownloadedInformation)
End If
Next
If _LatestSelected >= 0 AndAlso _LatestSelected <= LIST_DOWN.Items.Count - 1 Then
If _LatestSelected.ValueBetween(0, LIST_DOWN.Items.Count - 1) Then
Dim aSel As Action = Sub() LIST_DOWN.SelectedIndex = _LatestSelected
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(aSel) Else aSel.Invoke
Else
@@ -125,6 +155,7 @@ Namespace DownloadObjects
Else
_LatestSelected = -1
End If
Catch ies As InvalidOperationException
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadedInfoForm.RefillList]")
Finally
@@ -133,34 +164,40 @@ Namespace DownloadObjects
End Sub
#End Region
#Region "Toolbar controls"
Private Sub MENU_VIEW_SESSION_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_SESSION.Click
MENU_VIEW_SESSION.Checked = True
MENU_VIEW_ALL.Checked = False
ViewMode = ViewModes.Session
BTT_CLEAR.Visible = True
RefillList()
Private Sub MENU_VIEW_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles MENU_VIEW_SESSION.Click, MENU_VIEW_ALL.Click
Dim __refill As Boolean = False
Dim clicked As ToolStripMenuItem = Sender
Dim other As ToolStripMenuItem = If(Sender Is MENU_VIEW_SESSION, MENU_VIEW_ALL, MENU_VIEW_SESSION)
If other.Checked Then
clicked.Checked = True
other.Checked = False
__refill = True
Else
clicked.Checked = False
End If
ViewMode = IIf(MENU_VIEW_SESSION.Checked, ViewModes.Session, ViewModes.All)
ControlInvokeFast(ToolbarTOP, BTT_CLEAR, Sub() BTT_CLEAR.Visible = ViewMode = ViewModes.Session)
If __refill Then RefillList()
End Sub
Private Sub MENU_VIEW_ALL_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_ALL.Click
MENU_VIEW_SESSION.Checked = False
MENU_VIEW_ALL.Checked = True
ViewMode = ViewModes.All
BTT_CLEAR.Visible = False
RefillList()
Private Sub OPT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DEFAULT.Click, OPT_SUBSCRIPTIONS.Click
Dim __refill As Boolean = False
Dim clicked As ToolStripMenuItem = Sender
Dim other As ToolStripMenuItem = If(Sender Is OPT_DEFAULT, OPT_SUBSCRIPTIONS, OPT_DEFAULT)
If other.Checked Then
clicked.Checked = True
other.Checked = False
__refill = True
Else
clicked.Checked = False
End If
Settings.InfoViewDefault.Value = OPT_DEFAULT.Checked
If __refill Then RefillList()
End Sub
Private Sub BTT_FIND_Click(sender As Object, e As EventArgs) Handles BTT_FIND.Click
Try
If _LatestSelected.ValueBetween(0, LIST_DOWN.Items.Count - 1) AndAlso _LatestSelected.ValueBetween(0, Downloader.Downloaded.Count - 1) Then
Dim u As IUserData = Settings.GetUser(_TempUsersList(_LatestSelected), True)
If Not u Is Nothing Then RaiseEvent UserFind(u.Key)
End If
Catch ex As Exception
End Try
Try : RaiseEvent UserFind(If(Settings.GetUser(SelectedUser, True)?.Key, String.Empty)) : Catch : End Try
End Sub
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
If LIST_DOWN.Items.Count > 0 Then
Downloader.Downloaded.Clear()
RefillList()
End If
If LIST_DOWN.Items.Count > 0 Then Downloader.Downloaded.Clear() : RefillList()
End Sub
#End Region
#Region "List handlers"
@@ -171,8 +208,8 @@ Namespace DownloadObjects
End Sub
Private Sub LIST_DOWN_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_DOWN.MouseDoubleClick
Try
If _LatestSelected.ValueBetween(0, _TempUsersList.Count - 1) AndAlso
Not DirectCast(_TempUsersList(_LatestSelected), UserDataBase).Disposed Then _TempUsersList(_LatestSelected).OpenFolder()
Dim u As IUserData = SelectedUser
If Not If(u?.Disposed, True) Then u.OpenFolder()
Catch
End Try
End Sub
@@ -191,17 +228,12 @@ Namespace DownloadObjects
u = _LatestSelected > 0
d = _LatestSelected < .Items.Count - 1
End If
Dim a As Action = Sub()
BTT_UP.Enabled = u
BTT_DOWN.Enabled = d
End Sub
If ToolbarTOP.InvokeRequired Then ToolbarTOP.Invoke(a) Else a.Invoke
a = Nothing
If Offset.HasValue AndAlso .Items.Count > 0 AndAlso
(_LatestSelected + Offset.Value).ValueBetween(0, .Items.Count - 1) Then a = Sub() .SelectedIndex = _LatestSelected + Offset.Value
If Not a Is Nothing Then
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(a) Else a.Invoke
End If
ControlInvokeFast(ToolbarTOP, BTT_UP, Sub()
BTT_UP.Enabled = u
BTT_DOWN.Enabled = d
End Sub, EDP.None)
If Offset.HasValue AndAlso .Items.Count > 0 AndAlso (_LatestSelected + Offset.Value).ValueBetween(0, .Items.Count - 1) Then _
ControlInvokeFast(LIST_DOWN, Sub() .SelectedIndex = _LatestSelected + Offset.Value, EDP.None)
End With
End Sub
#End Region

View File

@@ -23,15 +23,25 @@ Namespace DownloadObjects
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW As System.Windows.Forms.ToolStripDropDownButton
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadFeedForm))
Me.OPT_DEFAULT = New System.Windows.Forms.ToolStripMenuItem()
Me.OPT_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem()
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
Me.MENU_LOAD_SESSION = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_LOAD_SESSION_LAST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_SESSION_CHOOSE = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_0 = New System.Windows.Forms.ToolStripSeparator()
Me.MENU_DOWN = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_DOWN_ALL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_DOWN_SELECTED = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
Me.BTT_CLEAR = New System.Windows.Forms.ToolStripButton()
Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel()
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
Me.ToolbarTOP.SuspendLayout()
Me.SuspendLayout()
'
@@ -40,10 +50,37 @@ Namespace DownloadObjects
SEP_1.Name = "SEP_1"
SEP_1.Size = New System.Drawing.Size(6, 25)
'
'SEP_2
'
SEP_2.Name = "SEP_2"
SEP_2.Size = New System.Drawing.Size(6, 25)
'
'MENU_VIEW
'
MENU_VIEW.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.OPT_DEFAULT, Me.OPT_SUBSCRIPTIONS})
MENU_VIEW.Image = CType(resources.GetObject("MENU_VIEW.Image"), System.Drawing.Image)
MENU_VIEW.ImageTransparentColor = System.Drawing.Color.Magenta
MENU_VIEW.Name = "MENU_VIEW"
MENU_VIEW.Size = New System.Drawing.Size(29, 22)
MENU_VIEW.Text = "View"
'
'OPT_DEFAULT
'
Me.OPT_DEFAULT.Name = "OPT_DEFAULT"
Me.OPT_DEFAULT.Size = New System.Drawing.Size(145, 22)
Me.OPT_DEFAULT.Text = "Downloads"
'
'OPT_SUBSCRIPTIONS
'
Me.OPT_SUBSCRIPTIONS.Name = "OPT_SUBSCRIPTIONS"
Me.OPT_SUBSCRIPTIONS.Size = New System.Drawing.Size(145, 22)
Me.OPT_SUBSCRIPTIONS.Text = "Subscriptions"
'
'ToolbarTOP
'
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_LOAD_SESSION, Me.SEP_0, Me.BTT_REFRESH, Me.BTT_CLEAR, SEP_1})
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_LOAD_SESSION, Me.SEP_0, MENU_VIEW, SEP_1, Me.MENU_DOWN, Me.BTT_REFRESH, Me.BTT_CLEAR, SEP_2})
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
Me.ToolbarTOP.Name = "ToolbarTOP"
Me.ToolbarTOP.Size = New System.Drawing.Size(484, 25)
@@ -78,6 +115,33 @@ Namespace DownloadObjects
Me.SEP_0.Name = "SEP_0"
Me.SEP_0.Size = New System.Drawing.Size(6, 25)
'
'MENU_DOWN
'
Me.MENU_DOWN.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.MENU_DOWN.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN_ALL, Me.BTT_DOWN_SELECTED})
Me.MENU_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.MENU_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_DOWN.Name = "MENU_DOWN"
Me.MENU_DOWN.Size = New System.Drawing.Size(29, 22)
Me.MENU_DOWN.Text = "Download"
Me.MENU_DOWN.Visible = False
'
'BTT_DOWN_ALL
'
Me.BTT_DOWN_ALL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_ALL.Name = "BTT_DOWN_ALL"
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(180, 22)
Me.BTT_DOWN_ALL.Tag = "a"
Me.BTT_DOWN_ALL.Text = "Download ALL"
'
'BTT_DOWN_SELECTED
'
Me.BTT_DOWN_SELECTED.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SELECTED.Name = "BTT_DOWN_SELECTED"
Me.BTT_DOWN_SELECTED.Size = New System.Drawing.Size(180, 22)
Me.BTT_DOWN_SELECTED.Tag = "s"
Me.BTT_DOWN_SELECTED.Text = "Download selected"
'
'BTT_REFRESH
'
Me.BTT_REFRESH.Image = Global.SCrawler.My.Resources.Resources.RefreshPic_24
@@ -141,14 +205,18 @@ Namespace DownloadObjects
Me.PerformLayout()
End Sub
Private WithEvents ToolbarTOP As ToolStrip
Private WithEvents TP_DATA As TableLayoutPanel
Private WithEvents BTT_REFRESH As ToolStripButton
Private WithEvents BTT_CLEAR As ToolStripButton
Private WithEvents MENU_LOAD_SESSION As ToolStripDropDownButton
Private WithEvents BTT_LOAD_SESSION_LAST As ToolStripMenuItem
Private WithEvents BTT_LOAD_SESSION_CHOOSE As ToolStripMenuItem
Private WithEvents SEP_0 As ToolStripSeparator
Private WithEvents ToolbarTOP As ToolStrip
Private WithEvents TP_DATA As TableLayoutPanel
Private WithEvents OPT_DEFAULT As ToolStripMenuItem
Private WithEvents OPT_SUBSCRIPTIONS As ToolStripMenuItem
Private WithEvents MENU_DOWN As ToolStripDropDownButton
Private WithEvents BTT_DOWN_ALL As ToolStripMenuItem
Private WithEvents BTT_DOWN_SELECTED As ToolStripMenuItem
End Class
End Namespace

View File

@@ -120,6 +120,21 @@
<metadata name="SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABkSURBVDhPY6AKyO86WFDQfeg/iIYKkQZAmkNbnvyXta76
DxViYGFi+Y8PQ5VBAMhmkGYgJs8FAw9GA5EKILFiWUFixfL/IBoqRBoAafYsOvpf0jiTvEAE2QzSLGmU
MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>

View File

@@ -23,10 +23,17 @@ Namespace DownloadObjects
Private DataRows As Integer = 10
Private DataColumns As Integer = 1
Private FeedEndless As Boolean = False
Private ReadOnly FileNotExist As New FPredicate(Of UserMediaD)(Function(d) Not d.Data.File.Exists)
Private ReadOnly FilterSubscriptions As New FPredicate(Of UserMediaD)(Function(d) If(d.User?.IsSubscription, False))
Private ReadOnly FilterUsers As New FPredicate(Of UserMediaD)(Function(d) Not FilterSubscriptions.Invoke(d))
Private ReadOnly FileNotExist As New FPredicate(Of UserMediaD)(Function(d) Not d.Data.File.Exists And Not FilterSubscriptions.Invoke(d))
Private BttRefreshToolTipText As String = "Refresh data list"
Private CenterImage As Boolean = False
Private NumberOfVisibleImages As Integer = 1
Private ReadOnly Property IsSubscription As Boolean
Get
Return OPT_SUBSCRIPTIONS.Checked
End Get
End Property
#End Region
#Region "Initializer"
Friend Sub New()
@@ -56,6 +63,15 @@ Namespace DownloadObjects
.AddThisToolbar()
End With
ToolbarTOP.Items.AddRange({New ToolStripSeparator, BTT_DELETE_SELECTED})
With Settings
If .FeedOpenLastMode Then
If .FeedLastModeSubscriptions Then OPT_SUBSCRIPTIONS.Checked = True Else OPT_DEFAULT.Checked = True
Else
OPT_DEFAULT.Checked = True
Settings.FeedLastModeSubscriptions.Value = False
End If
End With
MENU_DOWN.Visible = OPT_SUBSCRIPTIONS.Checked
UpdateSettings()
RefillList()
.EndLoaderOperations(False)
@@ -72,7 +88,15 @@ Namespace DownloadObjects
DataList.Clear()
End Sub
Private Sub DownloadFeedForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.F5 Then RefillList() : e.Handled = True
Dim b As Boolean = True
If e.KeyCode = Keys.F5 Then
RefillList()
ElseIf e.Control And e.KeyCode = Keys.G Then
MyRange.GoToF()
Else
b = False
End If
If b Then e.Handled = True
End Sub
#End Region
#Region "Settings"
@@ -143,8 +167,11 @@ Namespace DownloadObjects
Private Sub RefillList(Optional ByVal RefillDataList As Boolean = True)
DataPopulated = False
If RefillDataList Then
Try : Downloader.Files.RemoveAll(FileNotExist) : Catch : End Try
DataList.ListAddList(Downloader.Files, LAP.ClearBeforeAdd, LAP.NotContainsOnly)
If Not IsSubscription Then
Try : Downloader.Files.RemoveAll(FileNotExist) : Catch : End Try
End If
DataList.Clear()
DataList.ListAddList(Downloader.Files.Where(If(IsSubscription, FilterSubscriptions, FilterUsers)), LAP.NotContainsOnly)
End If
MyRange.Source = DataList
ControlInvokeFast(ToolbarTOP, BTT_REFRESH, Sub() BTT_REFRESH.ToolTipText = BttRefreshToolTipText)
@@ -173,6 +200,14 @@ Namespace DownloadObjects
Dim m As New MMessage("Saved sessions not selected", "Sessions",, vbExclamation)
Dim x As XmlFile
Dim lcr As New ListAddParams(LAP.NotContainsOnly + LAP.IgnoreICopier)
Dim __clearList As Action = Sub()
If IsSubscription Then
DataList.RemoveAll(FilterUsers)
Else
DataList.RemoveAll(FilterSubscriptions)
DataList.RemoveAll(FileNotExist)
End If
End Sub
If Not GetLast AndAlso f.Exists(SFO.Path, False) Then fList = SFile.GetFiles(f, "*.xml",, EDP.ReturnValue)
If Not GetLast AndAlso fList.ListExists Then
Using chooser As New SimpleListForm(Of SFile)(fList, Settings.Design) With {
@@ -192,7 +227,7 @@ Namespace DownloadObjects
If x.Count > 0 Then DataList.ListAddList(x, lcr)
x.Dispose()
Next
DataList.RemoveAll(FileNotExist)
__clearList.Invoke
RefillList(False)
Else
MsgBoxE(m)
@@ -206,6 +241,7 @@ Namespace DownloadObjects
x.LoadData()
If x.Count > 0 Then DataList.Clear() : DataList.ListAddList(x, lcr)
x.Dispose()
__clearList.Invoke
RefillList(False)
Else
m.Text = "Saved sessions not found"
@@ -216,6 +252,49 @@ Namespace DownloadObjects
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[DownloadObjects.DownloadFeedForm.SessionChooser({GetLast})]")
End Try
End Sub
Private Sub OPT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DEFAULT.Click, OPT_SUBSCRIPTIONS.Click
Dim __refill As Boolean = False
ControlInvokeFast(ToolbarTOP, Sender,
Sub()
Dim clicked As ToolStripMenuItem = Sender
Dim other As ToolStripMenuItem = If(Sender Is OPT_DEFAULT, OPT_SUBSCRIPTIONS, OPT_DEFAULT)
If other.Checked Then
__refill = True
clicked.Checked = True
other.Checked = False
Else
clicked.Checked = False
End If
Settings.FeedLastModeSubscriptions.Value = OPT_SUBSCRIPTIONS.Checked
MENU_DOWN.Visible = OPT_SUBSCRIPTIONS.Checked
End Sub, EDP.None)
If __refill Then RefillList()
End Sub
#End Region
#Region "Download"
Private Sub FeedMedia_Download(ByVal Sender As Object, ByVal e As EventArgs) Handles BTT_DOWN_ALL.Click, BTT_DOWN_SELECTED.Click
Try
Dim urls As New List(Of String)
If TypeOf Sender Is FeedMedia Then
urls.Add(DirectCast(Sender, FeedMedia).Post.URL_BASE)
ElseIf TypeOf Sender Is ToolStripMenuItem Then
Dim all As Boolean = CStr(AConvert(Of String)(DirectCast(Sender, ToolStripMenuItem).Tag, String.Empty)).StringToLower = "a"
ControlInvokeFast(TP_DATA, Sub()
urls.ListAddList((From m As FeedMedia In TP_DATA.Controls
Where m.Checked Or all
Select m.Post.URL_BASE).ListIfNothing)
TP_DATA.Controls.Cast(Of FeedMedia).ToList.ForEach(Sub(cnt) cnt.Checked = False)
End Sub)
End If
If urls.Count > 0 Then
VideoDownloader.FormShow
VideoDownloader.ADD_URLS_EXTERNAL(urls)
urls.Clear()
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Download subscription media")
End Try
End Sub
#End Region
#Region "Delete"
Private Sub BTT_DELETE_SELECTED_Click(sender As Object, e As EventArgs) Handles BTT_DELETE_SELECTED.Click
@@ -370,10 +449,11 @@ Namespace DownloadObjects
RefillInProgress = True
AllowTopScroll = False
ScrollSuspended = True
Dim __isSubscriptions As Boolean = IsSubscription
Dim d As List(Of UserMediaD) = MyRange.Current
Dim d2 As List(Of UserMediaD)
Dim i%
If d.ListExists And d.All(FileNotExist) Then
If d.ListExists AndAlso Not IsSubscription AndAlso d.All(FileNotExist) Then
i = Sender.CurrentIndex
Sender.HandlersSuspended = True
RefillList()
@@ -390,14 +470,20 @@ Namespace DownloadObjects
ClearTable()
If Sender.CurrentIndex > 0 And FeedEndless Then
d2 = DirectCast(MyRange.Switcher, RangeSwitcher(Of UserMediaD)).Item(Sender.CurrentIndex - 1).
Where(Function(md) Not FileNotExist.Predicate(md)).ListTake(-2, DataColumns, EDP.ReturnValue).ListIfNothing
Where(Function(md) __isSubscriptions OrElse Not FileNotExist.Predicate(md)).ListTake(-2, DataColumns, EDP.ReturnValue).ListIfNothing
If d2.Count > 0 Then d.InsertRange(0, d2) : d2.Clear()
End If
Dim w% = GetWidth()
Dim h% = GetHeight()
Dim p As New TPCELL(DataRows, DataColumns)
Dim fmList As New List(Of FeedMedia)
d.ForEach(Sub(de) fmList.Add(New FeedMedia(de, w, h, AddressOf FeedMedia_MediaDeleted)))
d.ForEach(Sub(ByVal de As UserMediaD)
fmList.Add(New FeedMedia(de, w, h))
With fmList.Last
AddHandler .MediaDeleted, AddressOf FeedMedia_MediaDeleted
AddHandler .MediaDownload, AddressOf FeedMedia_Download
End With
End Sub)
If fmList.Count > 0 Then fmList.ListDisposeRemoveAll(Function(fm) fm Is Nothing OrElse fm.HasError)
If fmList.Count > 0 Then
For i = 0 To fmList.Count - 1
@@ -448,6 +534,7 @@ Namespace DownloadObjects
End Function
Private Sub DownloadFeedForm_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
ResizeGrid()
UpdateButton()
End Sub
Private Sub DownloadFeedForm_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
If Not LastWinState = WindowState And Not If(MyDefs?.Initializing, True) Then LastWinState = WindowState : ResizeGrid()
@@ -480,6 +567,11 @@ Namespace DownloadObjects
End With
End Sub)
End Sub
Private Sub UpdateButton()
ControlInvokeFast(ToolbarTOP, MENU_DOWN, Sub() MENU_DOWN.DisplayStyle = IIf(Width >= 540,
ToolStripItemDisplayStyle.ImageAndText,
ToolStripItemDisplayStyle.Image), EDP.None)
End Sub
#End Region
#Region "Scroll"
Private AllowTopScroll As Boolean = False

View File

@@ -25,25 +25,29 @@ Namespace DownloadObjects
Me.components = New System.ComponentModel.Container()
Dim CONTEXT_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim CONTEXT_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim CONTEXT_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim TP_LBL As System.Windows.Forms.TableLayoutPanel
Me.CH_CHECKED = New System.Windows.Forms.CheckBox()
Me.LBL_INFO = New System.Windows.Forms.Label()
Me.CONTEXT_DATA = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.BTT_CONTEXT_DOWN = New System.Windows.Forms.ToolStripMenuItem()
Me.CONTEXT_SEP_0 = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_CONTEXT_OPEN_MEDIA = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_OPEN_USER = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_OPEN_USER_URL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_OPEN_USER_POST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_FIND_USER = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_INFO = New System.Windows.Forms.ToolStripMenuItem()
Me.CONTEXT_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_CONTEXT_DELETE = New System.Windows.Forms.ToolStripMenuItem()
Me.ICON_SITE = New System.Windows.Forms.PictureBox()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.LBL_TITLE = New System.Windows.Forms.Label()
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
CONTEXT_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
CONTEXT_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
TP_LBL = New System.Windows.Forms.TableLayoutPanel()
TP_LBL.SuspendLayout()
Me.CONTEXT_DATA.SuspendLayout()
CType(Me.ICON_SITE, System.ComponentModel.ISupportInitialize).BeginInit()
Me.TP_MAIN.SuspendLayout()
Me.SuspendLayout()
'
@@ -57,25 +61,21 @@ Namespace DownloadObjects
CONTEXT_SEP_2.Name = "CONTEXT_SEP_2"
CONTEXT_SEP_2.Size = New System.Drawing.Size(134, 6)
'
'CONTEXT_SEP_3
'
CONTEXT_SEP_3.Name = "CONTEXT_SEP_3"
CONTEXT_SEP_3.Size = New System.Drawing.Size(134, 6)
'
'TP_LBL
'
TP_LBL.ColumnCount = 2
TP_LBL.ColumnCount = 3
TP_LBL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_LBL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_LBL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_LBL.Controls.Add(Me.CH_CHECKED, 0, 0)
TP_LBL.Controls.Add(Me.LBL_INFO, 1, 0)
TP_LBL.Controls.Add(Me.LBL_INFO, 2, 0)
TP_LBL.Controls.Add(Me.ICON_SITE, 1, 0)
TP_LBL.Dock = System.Windows.Forms.DockStyle.Fill
TP_LBL.Location = New System.Drawing.Point(0, 0)
TP_LBL.Margin = New System.Windows.Forms.Padding(0)
TP_LBL.Name = "TP_LBL"
TP_LBL.RowCount = 1
TP_LBL.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_LBL.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_LBL.Size = New System.Drawing.Size(146, 25)
TP_LBL.TabIndex = 0
'
@@ -95,17 +95,31 @@ Namespace DownloadObjects
Me.LBL_INFO.AutoSize = True
Me.LBL_INFO.ContextMenuStrip = Me.CONTEXT_DATA
Me.LBL_INFO.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_INFO.Location = New System.Drawing.Point(28, 0)
Me.LBL_INFO.Location = New System.Drawing.Point(53, 0)
Me.LBL_INFO.Name = "LBL_INFO"
Me.LBL_INFO.Size = New System.Drawing.Size(115, 25)
Me.LBL_INFO.Size = New System.Drawing.Size(90, 25)
Me.LBL_INFO.TabIndex = 1
Me.LBL_INFO.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'CONTEXT_DATA
'
Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, CONTEXT_SEP_2, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, CONTEXT_SEP_3, Me.BTT_CONTEXT_DELETE})
Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.CONTEXT_SEP_0, Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, CONTEXT_SEP_2, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, Me.CONTEXT_SEP_3, Me.BTT_CONTEXT_DELETE})
Me.CONTEXT_DATA.Name = "CONTEXT_PIC"
Me.CONTEXT_DATA.Size = New System.Drawing.Size(138, 176)
Me.CONTEXT_DATA.Size = New System.Drawing.Size(138, 204)
'
'BTT_CONTEXT_DOWN
'
Me.BTT_CONTEXT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_CONTEXT_DOWN.Name = "BTT_CONTEXT_DOWN"
Me.BTT_CONTEXT_DOWN.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_DOWN.Text = "Download"
Me.BTT_CONTEXT_DOWN.Visible = False
'
'CONTEXT_SEP_0
'
Me.CONTEXT_SEP_0.Name = "CONTEXT_SEP_0"
Me.CONTEXT_SEP_0.Size = New System.Drawing.Size(134, 6)
Me.CONTEXT_SEP_0.Visible = False
'
'BTT_CONTEXT_OPEN_MEDIA
'
@@ -149,6 +163,11 @@ Namespace DownloadObjects
Me.BTT_CONTEXT_INFO.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_INFO.Text = "Information"
'
'CONTEXT_SEP_3
'
Me.CONTEXT_SEP_3.Name = "CONTEXT_SEP_3"
Me.CONTEXT_SEP_3.Size = New System.Drawing.Size(134, 6)
'
'BTT_CONTEXT_DELETE
'
Me.BTT_CONTEXT_DELETE.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
@@ -156,22 +175,43 @@ Namespace DownloadObjects
Me.BTT_CONTEXT_DELETE.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_DELETE.Text = "Delete"
'
'ICON_SITE
'
Me.ICON_SITE.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
Me.ICON_SITE.Dock = System.Windows.Forms.DockStyle.Fill
Me.ICON_SITE.Location = New System.Drawing.Point(28, 3)
Me.ICON_SITE.Name = "ICON_SITE"
Me.ICON_SITE.Size = New System.Drawing.Size(19, 19)
Me.ICON_SITE.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom
Me.ICON_SITE.TabIndex = 2
Me.ICON_SITE.TabStop = False
'
'TP_MAIN
'
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.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.TP_MAIN.Controls.Add(TP_LBL, 0, 0)
Me.TP_MAIN.Controls.Add(Me.LBL_TITLE, 0, 1)
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
Me.TP_MAIN.Name = "TP_MAIN"
Me.TP_MAIN.RowCount = 2
Me.TP_MAIN.RowCount = 3
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(146, 146)
Me.TP_MAIN.TabIndex = 0
'
'LBL_TITLE
'
Me.LBL_TITLE.AutoSize = True
Me.LBL_TITLE.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_TITLE.Location = New System.Drawing.Point(3, 25)
Me.LBL_TITLE.Name = "LBL_TITLE"
Me.LBL_TITLE.Size = New System.Drawing.Size(140, 25)
Me.LBL_TITLE.TabIndex = 1
'
'FeedMedia
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
@@ -186,7 +226,9 @@ Namespace DownloadObjects
TP_LBL.ResumeLayout(False)
TP_LBL.PerformLayout()
Me.CONTEXT_DATA.ResumeLayout(False)
CType(Me.ICON_SITE, System.ComponentModel.ISupportInitialize).EndInit()
Me.TP_MAIN.ResumeLayout(False)
Me.TP_MAIN.PerformLayout()
Me.ResumeLayout(False)
End Sub
@@ -202,5 +244,10 @@ Namespace DownloadObjects
Private WithEvents CH_CHECKED As CheckBox
Private WithEvents LBL_INFO As Label
Private WithEvents BTT_CONTEXT_INFO As ToolStripMenuItem
Private WithEvents ICON_SITE As PictureBox
Private WithEvents CONTEXT_SEP_3 As ToolStripSeparator
Private WithEvents BTT_CONTEXT_DOWN As ToolStripMenuItem
Private WithEvents CONTEXT_SEP_0 As ToolStripSeparator
Private WithEvents LBL_TITLE As Label
End Class
End Namespace

View File

@@ -123,9 +123,6 @@
<metadata name="CONTEXT_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="CONTEXT_SEP_3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_LBL.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>

View File

@@ -16,6 +16,7 @@ Namespace DownloadObjects
Public Class FeedMedia
#Region "Events"
Friend Event MediaDeleted(ByVal Sender As Object)
Friend Event MediaDownload As EventHandler
#End Region
#Region "Declarations"
Private Const VideoHeight As Integer = 450
@@ -55,17 +56,22 @@ Namespace DownloadObjects
End Property
Private ReadOnly Property ObjectsPaddingHeight As Integer
Get
Return TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2)
Return TP_MAIN.RowStyles(0).Height + TP_MAIN.RowStyles(1).Height + PaddingE.GetOf({TP_MAIN}).Vertical(3)
End Get
End Property
Private ReadOnly UserKey As String
Private ReadOnly Post As UserMedia
Friend ReadOnly Property Checked As Boolean
Friend ReadOnly Post As UserMedia
Private ReadOnly Media As UserMediaD
Friend Property Checked As Boolean
Get
Return CH_CHECKED.Checked
End Get
Set(ByVal c As Boolean)
If Not CH_CHECKED.Checked = c Then ControlInvokeFast(CH_CHECKED, Sub() CH_CHECKED.Checked = c)
End Set
End Property
Friend ReadOnly Property Information As String
Private ReadOnly Property IsSubscription As Boolean = False
Private Function GetImageResize(ByVal Width As Integer, ByVal Height As Integer) As Size
If Height > 0 Then
Dim h% = Height = ObjectsPaddingHeight
@@ -101,46 +107,123 @@ Namespace DownloadObjects
End If
End Sub
Private Sub ApplyColors()
If Settings.FeedBackColor.Exists Then
BackColor = Settings.FeedBackColor
LBL_INFO.BackColor = Settings.FeedBackColor
Dim b As Color? = Nothing, f As Color? = Nothing
If Not Media.User Is Nothing Then
If Media.User.BackColor.HasValue Then b = Media.User.BackColor
If Media.User.ForeColor.HasValue Then f = Media.User.ForeColor
End If
If Settings.FeedForeColor.Exists Then
ForeColor = Settings.FeedForeColor
LBL_INFO.ForeColor = Settings.FeedForeColor
If Not b.HasValue And Settings.FeedBackColor.Exists Then b = Settings.FeedBackColor.Value
If Not f.HasValue And Settings.FeedForeColor.Exists Then f = Settings.FeedForeColor.Value
If b.HasValue Then
BackColor = b.Value
LBL_INFO.BackColor = b.Value
If Not LBL_TITLE.IsDisposed Then LBL_TITLE.BackColor = b.Value
End If
If f.HasValue Then
ForeColor = f.Value
LBL_INFO.ForeColor = f.Value
If Not LBL_TITLE.IsDisposed Then LBL_TITLE.ForeColor = f.Value
End If
End Sub
#End Region
#Region "Converter"
Private Const ExtWebp As String = "webp"
Private Const ExtJpg As String = "jpg"
Private Function ConvertWebp(ByVal file As SFile, Optional ByVal NewCacheDir As Boolean = False) As SFile
If file.Extension = ExtWebp Then
If Settings.FfmpegFile.Exists Then
Dim dir As SFile
If NewCacheDir Then dir = Settings.Cache.NewPath Else dir = Settings.Cache
Dim f As SFile = file
f.Path = dir.Path
f.Extension = ExtJpg
Using imgBatch As New BatchExecutor
With imgBatch
.ChangeDirectory(dir)
.Execute($"""{Settings.FfmpegFile}"" -i ""{file}"" ""{f}""")
End With
End Using
If f.Exists Then Return f
End If
Else
Return file
End If
Return Nothing
End Function
#End Region
#Region "Initializers"
Public Sub New()
InitializeComponent()
End Sub
Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Height As Integer, ByVal Handler As MediaDeletedEventHandler)
Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Height As Integer)
Try
InitializeComponent()
File = Media.Data.File
If Not File.Exists And Media.Data.Type = UserMedia.Types.Video Then File.Path = $"{File.Path.CSFilePS}Video"
If Not File.Exists Then
Me.Media = Media
IsSubscription = If(Media.User?.IsSubscription, False)
If IsSubscription Then
LBL_TITLE.Text = Media.Data.PictureOption.IfNullOrEmpty(Media.Data.File.Name)
If LBL_TITLE.Text.IsEmptyString Then
TP_MAIN.Controls.Remove(LBL_TITLE)
LBL_TITLE.Dispose()
TP_MAIN.RowStyles(1).Height = 0
End If
BTT_CONTEXT_DOWN.Visible = True
CONTEXT_SEP_0.Visible = True
BTT_CONTEXT_OPEN_USER.Visible = False
CONTEXT_SEP_3.Visible = False
BTT_CONTEXT_DELETE.Visible = False
If Not Media.Data.URL.IsEmptyString Then
Dim ext$ = Media.Data.URL.CSFile.Extension
Dim imgFile As New SFile With {.Path = Settings.Cache.RootDirectory.Path}
With Media.User
imgFile.Name = $"{IIf(.IncludedInCollection, "{.CollectionName}", String.Empty)}{ .Site}{ .Name}_"
imgFile.Name &= (CLng(Media.Data.URL.GetHashCode) + CLng(Media.Data.File.GetHashCode)).ToString
imgFile.Extension = ExtJpg
If Not imgFile.Exists AndAlso Not ext.IsEmptyString AndAlso ext.ToLower = ExtWebp Then imgFile.Extension = ExtWebp
End With
If Not imgFile.Exists Then
Settings.Cache.Validate()
GetWebFile(Media.Data.URL, imgFile, EDP.None)
If imgFile.Exists Then File = ConvertWebp(imgFile)
Else
File = imgFile
End If
End If
Else
TP_MAIN.Controls.Remove(LBL_TITLE)
LBL_TITLE.Dispose()
TP_MAIN.RowStyles(1).Height = 0
File = Media.Data.File
If Not File.Exists And Media.Data.Type = UserMedia.Types.Video Then File.Path = $"{File.Path.CSFilePS}Video"
End If
If Not File.Exists And Not IsSubscription Then
If Not Media.Data.SpecialFolder.IsEmptyString Then
File.Path = $"{File.Path.CSFilePS}{Media.Data.SpecialFolder}".CSFileP
If Not File.Exists And Media.Data.Type = UserMedia.Types.Video Then File.Path = $"{File.Path.CSFilePS}Video"
End If
End If
If File.Exists Then
Information = $"Type: {Media.Data.Type}"
Information.StringAppendLine($"File: {File.File}")
Information.StringAppendLine($"Address: {File}")
Information.StringAppendLine($"Downloaded: {Media.Date.ToStringDate(ADateTime.Formats.BaseDateTime)}")
If Media.Data.Post.Date.HasValue Then Information.StringAppendLine($"Posted: {Media.Data.Post.Date.Value.ToStringDate(ADateTime.Formats.BaseDateTime)}")
Dim infoType As UserMedia.Types = Media.Data.Type
Dim infoType As UserMedia.Types = If(IsSubscription, UserMedia.Types.Picture, Media.Data.Type)
Dim h%
Dim s As Size
Post = Media.Data
Select Case Media.Data.Type
Select Case infoType
Case UserMedia.Types.Picture, UserMedia.Types.GIF
MyImage = New ImageRenderer(File)
Dim tmpMediaFile As SFile = ConvertWebp(File, True)
If tmpMediaFile.IsEmptyString Then Throw New ArgumentNullException With {.HelpLink = 1}
MyImage = New ImageRenderer(tmpMediaFile)
Dim a As AnchorStyles = AnchorStyles.Top + If(Height > 0, 0, AnchorStyles.Left)
s = GetImageResize(Width, Height)
h = s.Height
@@ -158,14 +241,14 @@ Namespace DownloadObjects
.Padding = New Padding(0),
.ContextMenuStrip = CONTEXT_DATA
}
TP_MAIN.Controls.Add(MyPicture, 0, 1)
TP_MAIN.Controls.Add(MyPicture, 0, 2)
BTT_CONTEXT_OPEN_MEDIA.Text &= " picture"
BTT_CONTEXT_DELETE.Text &= " picture"
Case UserMedia.Types.Video, UserMedia.Types.m3u8
infoType = UserMedia.Types.Video
MyVideo = New FeedVideo(File) With {.Tag = File, .Dock = DockStyle.Fill, .ContextMenuStrip = CONTEXT_DATA}
If MyVideo.HasError Then HasError = True
TP_MAIN.Controls.Add(MyVideo, 0, 1)
TP_MAIN.Controls.Add(MyVideo, 0, 2)
BTT_CONTEXT_OPEN_MEDIA.Text &= " video"
BTT_CONTEXT_DELETE.Text &= " video"
h = VideoHeight
@@ -181,22 +264,33 @@ Namespace DownloadObjects
If .IncludedInCollection Then Information.StringAppendLine($"User collection: { .CollectionName}")
Information.StringAppendLine($"User site: { .Site}")
Information.StringAppendLine($"User name: {IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)}")
If .Site = API.Instagram.InstagramSite Then BTT_CONTEXT_OPEN_USER_POST.Visible = False
If .IncludedInCollection Then info &= $"[{ .CollectionName}]: "
info &= $"{ .Site} - {IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)}"
If Settings.FeedShowFriendlyNames Or Not DirectCast(.Self, UserDataBase).FeedIsUser Then
info &= $"{ .Site} - { .FriendlyName.IfNullOrEmpty(.Name)}"
Else
info &= $"{ .Site} - {IIf(Not .FriendlyName.IsEmptyString And Not .IncludedInCollection, .FriendlyName, .Name)}"
End If
End With
End If
If Settings.FeedAddSessionToCaption Then info = $"[{Media.Session}] {info}"
If Settings.FeedAddDateToCaption Then info &= $" ({Media.Date.ToStringDate(ADateTime.Formats.BaseDateTime)})"
LBL_INFO.Text = info
If Not Media.User Is Nothing AndAlso Not Media.User.HOST Is Nothing Then
With Media.User.HOST.Source
If Not .Image Is Nothing Then
ICON_SITE.Image = .Image
ElseIf Not .Icon Is Nothing Then
ICON_SITE.Image = .Icon.ToBitmap
End If
End With
End If
s = New Size(Width, h + ObjectsPaddingHeight)
Size = s
MinimumSize = s
MaximumSize = s
ApplyColors()
If Not Handler Is Nothing Then AddHandler Me.MediaDeleted, Handler
Else
Throw New ArgumentNullException With {.HelpLink = 1}
End If
@@ -222,11 +316,16 @@ Namespace DownloadObjects
If e.Button = MouseButtons.Left Then ControlInvoke(CH_CHECKED, Sub() CH_CHECKED.Checked = Not CH_CHECKED.Checked)
End Sub
Private Sub LBL_INFO_DoubleClick(sender As Object, e As EventArgs) Handles LBL_INFO.DoubleClick
If Not UserKey.IsEmptyString Then
If Not UserKey.IsEmptyString And Not IsSubscription Then
Dim u As IUserData = Settings.GetUser(UserKey)
If Not u Is Nothing Then u.OpenFolder()
End If
End Sub
Private Sub LBL_TITLE_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LBL_TITLE.MouseDoubleClick
If Not Post.URL_BASE.IsEmptyString Then
Try : Process.Start(Post.URL_BASE) : Catch : End Try
End If
End Sub
#End Region
#Region "Picture / Video objects"
Private Sub MyPicture_DoubleClick(sender As Object, e As EventArgs) Handles MyPicture.DoubleClick
@@ -234,6 +333,9 @@ Namespace DownloadObjects
End Sub
#End Region
#Region "Context"
Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click
RaiseEvent MediaDownload(Me, EventArgs.Empty)
End Sub
Private Sub BTT_CONTEXT_OPEN_MEDIA_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_MEDIA.Click
File.Open()
End Sub
@@ -251,15 +353,18 @@ Namespace DownloadObjects
End Sub
Private Sub BTT_CONTEXT_OPEN_USER_POST_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER_POST.Click
Try
If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then
Dim u As IUserData = Settings.GetUser(UserKey)
If Not u Is Nothing Then
Dim url$ = UserDataBase.GetPostUrl(u, Post)
If Not url.IsEmptyString Then
Try : Process.Start(url) : Catch : End Try
End If
Dim url$ = String.Empty
If IsSubscription Then
url = Post.URL_BASE
Else
If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then
Dim u As IUserData = Settings.GetUser(UserKey)
If Not u Is Nothing Then url = UserDataBase.GetPostUrl(u, Post)
End If
End If
If Not url.IsEmptyString Then
Try : Process.Start(url) : Catch : End Try
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, $"[FeedMedia.OpenPost({UserKey}, {Post.Post.ID})]")
End Try

View File

@@ -144,6 +144,17 @@ Namespace DownloadObjects.Groups
(.Temporary = CheckState.Indeterminate Or user.Temporary = CBool(.Temporary)) And
(.Favorite = CheckState.Indeterminate Or (user.Favorite = CBool(.Favorite))) And
(Not UseReadyOption Or .ReadyForDownloadIgnore Or user.ReadyForDownload = .ReadyForDownload) And user.Exists
Dim CheckSubscription As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If .Subscriptions Then
If .SubscriptionsOnly Then
Return user.IsSubscription = True
Else
Return True
End If
Else
Return user.IsSubscription = False
End If
End Function
Dim CheckLabelsExcluded As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If .LabelsExcluded.Count = 0 Then
Return True
@@ -165,7 +176,16 @@ Namespace DownloadObjects.Groups
Dim CheckSites As Predicate(Of IUserData) = Function(user) _
(.Sites.Count = 0 OrElse .Sites.Contains(user.Site)) AndAlso
(.SitesExcluded.Count = 0 OrElse Not .SitesExcluded.Contains(user.Site))
Return Settings.GetUsers(Function(user) CheckLabels.Invoke(user) AndAlso CheckSites.Invoke(user) AndAlso CheckParams.Invoke(user))
Dim users As IEnumerable(Of IUserData) =
Settings.GetUsers(Function(user) CheckLabels.Invoke(user) AndAlso CheckSites.Invoke(user) AndAlso
CheckParams.Invoke(user) AndAlso CheckSubscription.Invoke(user))
If .UsersCount = 0 Or Not users.ListExists Then
Return users
Else
users = users.ListTake(If(.UsersCount > 0, -1, -2), Math.Abs(.UsersCount))
If .UsersCount < 0 Then users = users.ListReverse
Return users
End If
End With
Else
Return Nothing

View File

@@ -13,10 +13,14 @@ Namespace DownloadObjects.Groups
Public Class GroupDefaults : Inherits TableLayoutPanel
Private ReadOnly TP_1 As TableLayoutPanel
Private ReadOnly TP_2 As TableLayoutPanel
Private ReadOnly TP_3 As TableLayoutPanel
Private ReadOnly CH_TEMPORARY As CheckBox
Private ReadOnly CH_FAV As CheckBox
Private ReadOnly CH_READY_FOR_DOWN As CheckBox
Private ReadOnly CH_READY_FOR_DOWN_IGNORE As CheckBox
Private ReadOnly CH_SUBSCRIPTIONS As CheckBox
Private ReadOnly CH_SUBSCRIPTIONS_ONLY As CheckBox
Private WithEvents NUM_USERS_COUNT As TextBoxExtended
Private WithEvents TXT_LABELS As TextBoxExtended
Private WithEvents TXT_SITES As TextBoxExtended
Friend WithEvents TXT_NAME As TextBoxExtended
@@ -48,6 +52,32 @@ Namespace DownloadObjects.Groups
FillTP(TP_1, CH_TEMPORARY, CH_FAV)
TP_2 = New TableLayoutPanel With {.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single, .Margin = New Padding(0), .Dock = DockStyle.Fill}
FillTP(TP_2, CH_READY_FOR_DOWN, CH_READY_FOR_DOWN_IGNORE)
CH_SUBSCRIPTIONS = New CheckBox With {.Text = "Subscriptions", .Name = "CH_SUBSCRIPTIONS", .Checked = False, .Dock = DockStyle.Fill}
CH_SUBSCRIPTIONS_ONLY = New CheckBox With {.Text = "Subscriptions only", .Name = "CH_SUBSCRIPTIONS_ONLY", .Checked = False, .Dock = DockStyle.Fill}
TP_3 = New TableLayoutPanel With {.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single, .Margin = New Padding(0), .Dock = DockStyle.Fill}
FillTP(TP_3, CH_SUBSCRIPTIONS, CH_SUBSCRIPTIONS_ONLY)
NUM_USERS_COUNT = New TextBoxExtended
With NUM_USERS_COUNT
.BeginInit()
.CaptionText = "Users"
.CaptionToolTipText = "The number of users that to be downloaded." & vbCr &
"The number is 0 = all users." & vbCr &
"Number greater than 0 = number of users from the beginning to the end of the list." & vbCr &
"Number less than 0 = number of users from end to the beginning of the list."
.CaptionToolTipEnabled = True
.CaptionWidth = 50
.ControlMode = TextBoxExtended.ControlModes.NumericUpDown
.NumberMinimum = Integer.MinValue
.NumberMaximum = Integer.MaxValue
.NumberUpDownAlign = LeftRightAlignment.Left
.Dock = DockStyle.Fill
.Buttons.Add(New ActionButton(ADB.Clear) With {.ToolTipText = "Reset value"})
.ClearTextByButtonClear = False
.Value = 0
.EndInit()
End With
End Sub
Private Sub InitTextBox(ByRef TXT As TextBoxExtended, ByVal Caption As String, ByVal Buttons As ActionButton())
TXT = New TextBoxExtended
@@ -76,6 +106,9 @@ Namespace DownloadObjects.Groups
CH_FAV.Dispose()
CH_READY_FOR_DOWN.Dispose()
CH_READY_FOR_DOWN_IGNORE.Dispose()
CH_SUBSCRIPTIONS.Dispose()
CH_SUBSCRIPTIONS_ONLY.Dispose()
NUM_USERS_COUNT.Dispose()
TXT_LABELS.Dispose()
With TP_1
.Controls.Clear()
@@ -89,6 +122,12 @@ Namespace DownloadObjects.Groups
.ColumnStyles.Clear()
.Dispose()
End With
With TP_3
.Controls.Clear()
.RowStyles.Clear()
.ColumnStyles.Clear()
.Dispose()
End With
End Sub
Protected Overrides Sub InitLayout()
MyBase.InitLayout()
@@ -98,11 +137,13 @@ Namespace DownloadObjects.Groups
CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
ColumnCount = 1
ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
RowCount = 7
RowCount = 9
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
RowStyles.Add(New RowStyle(SizeType.Absolute, 28))
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
RowStyles.Add(New RowStyle(SizeType.Absolute, 28))
RowStyles.Add(New RowStyle(SizeType.Absolute, 28))
RowStyles.Add(New RowStyle(SizeType.Absolute, 28))
RowStyles.Add(New RowStyle(SizeType.Percent, 100))
@@ -110,8 +151,13 @@ Namespace DownloadObjects.Groups
Controls.Add(TXT_NAME, 0, 1)
Controls.Add(TP_1, 0, 2)
Controls.Add(TP_2, 0, 3)
Controls.Add(TXT_LABELS, 0, 4)
Controls.Add(TXT_SITES, 0, 5)
Controls.Add(TP_3, 0, 4)
Controls.Add(NUM_USERS_COUNT, 0, 5)
Controls.Add(TXT_LABELS, 0, 6)
Controls.Add(TXT_SITES, 0, 7)
End Sub
Private Sub NUM_USERS_COUNT_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles NUM_USERS_COUNT.ActionOnButtonClick
If Sender.DefaultButton = ADB.Clear Then NUM_USERS_COUNT.Value = 0
End Sub
Private Sub TXT_LABELS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_LABELS.ActionOnButtonClick
Select Case Sender.DefaultButton
@@ -163,6 +209,9 @@ Namespace DownloadObjects.Groups
.Favorite = CH_FAV.CheckState
.ReadyForDownload = CH_READY_FOR_DOWN.Checked
.ReadyForDownloadIgnore = CH_READY_FOR_DOWN_IGNORE.Checked
.Subscriptions = CH_SUBSCRIPTIONS.Checked
.SubscriptionsOnly = CH_SUBSCRIPTIONS_ONLY.Checked
.UsersCount = NUM_USERS_COUNT.Value
.Labels.Clear()
.Labels.ListAddList(Labels)
.LabelsExcluded.Clear()
@@ -182,6 +231,9 @@ Namespace DownloadObjects.Groups
CH_FAV.CheckState = .Favorite
CH_READY_FOR_DOWN.Checked = .ReadyForDownload
CH_READY_FOR_DOWN_IGNORE.Checked = .ReadyForDownloadIgnore
CH_SUBSCRIPTIONS.Checked = .Subscriptions
CH_SUBSCRIPTIONS_ONLY.Checked = .SubscriptionsOnly
NUM_USERS_COUNT.Value = .UsersCount
Labels.ListAddList(.Labels)
LabelsExcluded.ListAddList(.LabelsExcluded)
@@ -195,7 +247,8 @@ Namespace DownloadObjects.Groups
End Sub
Private _Enabled As Boolean = True
Private _JustExcludeOptions As Boolean = False
Friend Overloads Property Enabled(Optional ByVal LeaveExcludeOptions As Boolean = False) As Boolean
Friend Overloads Property Enabled(Optional ByVal LeaveExcludeOptions As Boolean = False,
Optional ByVal LeaveSubscriptionsAndUsersCount As Boolean = False) As Boolean
Get
Return _Enabled
End Get
@@ -204,6 +257,8 @@ Namespace DownloadObjects.Groups
_JustExcludeOptions = False
TP_1.Enabled = e
TP_2.Enabled = e
TP_3.Enabled = e Or LeaveSubscriptionsAndUsersCount
NUM_USERS_COUNT.Enabled = e Or LeaveSubscriptionsAndUsersCount
If e Then
TXT_LABELS.Enabled = True
TXT_SITES.Enabled = True

View File

@@ -35,13 +35,13 @@ Namespace DownloadObjects.Groups
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.DEFS_GROUP)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(476, 141)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(476, 196)
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(476, 166)
CONTAINER_MAIN.Size = New System.Drawing.Size(476, 221)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
@@ -53,30 +53,32 @@ Namespace DownloadObjects.Groups
Me.DEFS_GROUP.Dock = System.Windows.Forms.DockStyle.Fill
Me.DEFS_GROUP.Location = New System.Drawing.Point(0, 0)
Me.DEFS_GROUP.Name = "DEFS_GROUP"
Me.DEFS_GROUP.RowCount = 7
Me.DEFS_GROUP.RowCount = 9
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.DEFS_GROUP.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.DEFS_GROUP.Size = New System.Drawing.Size(476, 141)
Me.DEFS_GROUP.Size = New System.Drawing.Size(476, 196)
Me.DEFS_GROUP.TabIndex = 0
'
'GroupEditorForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(476, 166)
Me.ClientSize = New System.Drawing.Size(476, 221)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.Resources.GroupByIcon_16
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(492, 205)
Me.MaximumSize = New System.Drawing.Size(492, 260)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(492, 205)
Me.MinimumSize = New System.Drawing.Size(492, 260)
Me.Name = "GroupEditorForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide

View File

@@ -18,6 +18,9 @@ Namespace DownloadObjects.Groups
Property Favorite As CheckState
Property ReadyForDownload As Boolean
Property ReadyForDownloadIgnore As Boolean
Property Subscriptions As Boolean
Property SubscriptionsOnly As Boolean
Property UsersCount As Integer
End Interface
Friend Class GroupParameters : Implements IGroup, IDisposable
Protected Const Name_Name As String = "Name"
@@ -25,6 +28,9 @@ Namespace DownloadObjects.Groups
Protected Const Name_Favorite As String = "Favorite"
Protected Const Name_ReadyForDownload As String = "RFD"
Protected Const Name_ReadyForDownloadIgnore As String = "RFDI"
Protected Const Name_Subscriptions As String = "Subscriptions"
Protected Const Name_SubscriptionsOnly As String = "SubscriptionsOnly"
Protected Const Name_UsersCount As String = "UsersCount"
Protected Const Name_Labels As String = "Labels"
Protected Const Name_Labels_Excluded As String = "LabelsExcluded"
Protected Const Name_Sites As String = "Sites"
@@ -38,6 +44,9 @@ Namespace DownloadObjects.Groups
Friend Property Favorite As CheckState = CheckState.Indeterminate Implements IGroup.Favorite
Friend Property ReadyForDownload As Boolean = True Implements IGroup.ReadyForDownload
Friend Property ReadyForDownloadIgnore As Boolean = False Implements IGroup.ReadyForDownloadIgnore
Friend Property Subscriptions As Boolean = False Implements IGroup.Subscriptions
Friend Property SubscriptionsOnly As Boolean = False Implements IGroup.SubscriptionsOnly
Friend Property UsersCount As Integer = 0 Implements IGroup.UsersCount
Friend Sub New()
Labels = New List(Of String)
LabelsExcluded = New List(Of String)
@@ -50,6 +59,9 @@ Namespace DownloadObjects.Groups
Favorite = e.Value(Name_Favorite).FromXML(Of Integer)(CInt(CheckState.Indeterminate))
ReadyForDownload = e.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
ReadyForDownloadIgnore = e.Value(Name_ReadyForDownloadIgnore).FromXML(Of Boolean)(False)
Subscriptions = e.Value(Name_Subscriptions).FromXML(Of Boolean)(False)
SubscriptionsOnly = e.Value(Name_SubscriptionsOnly).FromXML(Of Boolean)(False)
UsersCount = e.Value(Name_UsersCount).FromXML(Of Integer)(0)
Dim l As New ListAddParams(LAP.NotContainsOnly)
If Not e.Value(Name_Labels).IsEmptyString Then Labels.ListAddList(e.Value(Name_Labels).Split("|"), l)
@@ -63,6 +75,9 @@ Namespace DownloadObjects.Groups
New EContainer(Name_Favorite, CInt(Favorite)),
New EContainer(Name_ReadyForDownload, ReadyForDownload.BoolToInteger),
New EContainer(Name_ReadyForDownloadIgnore, ReadyForDownloadIgnore.BoolToInteger),
New EContainer(Name_Subscriptions, Subscriptions.BoolToInteger),
New EContainer(Name_SubscriptionsOnly, SubscriptionsOnly.BoolToInteger),
New EContainer(Name_UsersCount, UsersCount),
New EContainer(Name_Labels, Labels.ListToString("|")),
New EContainer(Name_Labels_Excluded, LabelsExcluded.ListToString("|")),
New EContainer(Name_Sites, Sites.ListToString("|")),

View File

@@ -11,11 +11,13 @@ Imports SCrawler.API.Base
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Functions.Messaging
Imports ECI = PersonalUtilities.Forms.Toolbars.EditToolbar.ControlItem
Namespace DownloadObjects
Friend Class MissingPostsForm
#Region "Declarations"
Private WithEvents MyDefs As DefaultFormOptions
Private ReadOnly MUsers As List(Of IUserData)
Private WithEvents BTT_DELETE_ALL As ToolStripButton
Private WithEvents BTT_DOWN_ALL As ToolStripButton
Private WithEvents BTT_INFO As ToolStripButton
#End Region
@@ -24,6 +26,13 @@ Namespace DownloadObjects
InitializeComponent()
MUsers = New List(Of IUserData)
MyDefs = New DefaultFormOptions(Me, Settings.Design)
BTT_DELETE_ALL = New ToolStripButton With {
.Text = "Delete ALL",
.ToolTipText = String.Empty,
.AutoToolTip = False,
.Image = PersonalUtilities.My.Resources.DeletePic_Red_24,
.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText
}
BTT_DOWN_ALL = New ToolStripButton With {
.Text = "Download ALL",
.ToolTipText = String.Empty,
@@ -44,7 +53,7 @@ Namespace DownloadObjects
Private Sub MissingPostsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddEditToolbarPlus({EditToolbar.ControlItem.Separator, BTT_DOWN_ALL, BTT_INFO})
.AddEditToolbar({ECI.Update, ECI.Separator, ECI.Delete, BTT_DELETE_ALL, ECI.Separator, BTT_DOWN_ALL, BTT_INFO})
.EndLoaderOperations(False)
End With
RefillList()
@@ -258,11 +267,17 @@ Namespace DownloadObjects
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[DownloadObjects.MissingPostsForm.FindUser]")
End Try
End Sub
Private Sub DeletePost() Handles MyDefs.ButtonDeleteClickE, BTT_DELETE.Click
Private Sub DeletePost(ByVal Sender As Object, ByVal e As EventArgs) Handles MyDefs.ButtonDeleteClickE, BTT_DELETE.Click, BTT_DELETE_ALL.Click
Const MsgTitle$ = "Remove missing posts"
Dim UsersToUpdate As New List(Of UserDataBase)
Try
Dim data As List(Of ListViewItem) = LIST_DATA.SelectedItems.ToObjectsList.ListCast(Of ListViewItem)
Dim data As List(Of ListViewItem)
Dim isAll As Boolean = Sender Is BTT_DELETE_ALL
If isAll Then
data = LIST_DATA.Items.ToObjectsList.ListCast(Of ListViewItem)
Else
data = LIST_DATA.SelectedItems.ToObjectsList.ListCast(Of ListViewItem)
End If
If data.ListExists Then
Dim lp As New ListAddParams(LAP.NotContainsOnly)
Dim usersCount% = ListAddList(Nothing, data.Select(Function(d) d.Group.Header), LAP.NotContainsOnly).ListIfNothing.Count
@@ -288,7 +303,7 @@ Namespace DownloadObjects
MsgBoxE({"Operation canceled", MsgTitle})
End If
Else
MsgBoxE({"No selected posts", MsgTitle})
MsgBoxE({IIf(isAll, "No posts found to delete", "No selected posts"), MsgTitle})
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[DownloadObjects.MissingPostsForm.DeletePost]")

View File

@@ -28,8 +28,12 @@ Namespace DownloadObjects.STDownloader
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloaderUrlForm))
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 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()
Me.TXT_URL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_PATH = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
@@ -92,20 +96,44 @@ Namespace DownloadObjects.STDownloader
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Open"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton2.ToolTipText = "Choose a new location (Ctrl+O)"
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "Clear"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton3.Name = "Add"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Add
ActionButton3.ToolTipText = "Choose a new location and add it to the list (Alt+O)"
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Name = "Clear"
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Name = "ArrowDown"
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.TXT_PATH.Buttons.Add(ActionButton2)
Me.TXT_PATH.Buttons.Add(ActionButton3)
Me.TXT_PATH.Buttons.Add(ActionButton4)
Me.TXT_PATH.Buttons.Add(ActionButton5)
Me.TXT_PATH.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.TXT_PATH.CaptionText = "Output"
Me.TXT_PATH.CaptionToolTipEnabled = True
Me.TXT_PATH.CaptionToolTipText = "Output path"
Me.TXT_PATH.CaptionVisible = True
Me.TXT_PATH.CaptionWidth = 40.0R
ListColumn1.Name = "COL_NAME"
ListColumn1.Text = "Name"
ListColumn1.Width = -1
ListColumn2.DisplayMember = True
ListColumn2.Name = "COL_VALUE"
ListColumn2.Text = "Value"
ListColumn2.ValueMember = True
ListColumn2.Visible = False
Me.TXT_PATH.Columns.Add(ListColumn1)
Me.TXT_PATH.Columns.Add(ListColumn2)
Me.TXT_PATH.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_PATH.ListAutoCompleteMode = PersonalUtilities.Forms.Controls.ComboBoxExtended.AutoCompleteModes.Disabled
Me.TXT_PATH.Location = New System.Drawing.Point(4, 33)
Me.TXT_PATH.Name = "TXT_PATH"
Me.TXT_PATH.Size = New System.Drawing.Size(476, 22)
Me.TXT_PATH.TabIndex = 1
Me.TXT_PATH.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'DownloaderUrlForm
'
@@ -134,6 +162,6 @@ Namespace DownloadObjects.STDownloader
End Sub
Private WithEvents TXT_URL As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_PATH As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_PATH As PersonalUtilities.Forms.Controls.ComboBoxExtended
End Class
End Namespace

View File

@@ -144,11 +144,123 @@
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
QVRIS62WWWxMURjHL220JW1HausmlFrDFKUhnUGH6bRFzJ2idImlC0Vp2mlji1A8iNhCPIjIRES8EU+W
h2oEtbSDTk3HNNM7S01VKsXjkb/vXBo3k1Ee7sMvmZzzzf//ne/+z50RAAxL1MUIG4G/YAv3HSVhF5Vw
IYNdz3LadVj9RgdTB+HQYYPHIJuE1ocSdlEJFzG+1bPRLQLinglIeCkg+XUkKvz56hnkOfQs/rmA8S9H
YEp7FDI64tAQtKhnsMapZ7zzNHsUFnbGY4VzIk70l6hnIH4wsDR7NBZ3apDrSqL5T8eFgUr1DLZ78lim
Q4N8VzK29MxEpZSBa4M16hnU+c3M9CEFpdJsVHsXos63DDcHrf9nQEXD5VymwW/5USLNwl5vJhp7dTgW
NML2pR7jbsUMS+KdMTa5Q8NQxinfBU4dRFcOyjy52OtbhwOBDTgZLKPPmTgY0ON4MBdNfSbYBupxY8Aq
G10dqMG5/nIc7ytGQ6CQRliAamkTN/g1Ai4e95Qy3iogpX0UtBRDnhRzdxq2SXOxz5eFQ70rScCEU335
ssGxj0YS06HSm4GN3ekwdE2C1hGH1LZR0JDOJof5jwHvnIvzTa0jlooTYfktvt+fhcOBHDQFTWRgxJGP
ObAGsulZLMLWnjlY756K5c4JmNcRi6T2SGheCIihS2l5ozAo6NRhMolnUAcGV6IcwwqvFrX+JTjYuwKH
SfRAYDms/mzs9y1GFe2VSnOw1j0FejqpLN4WCX4ZufiIBwLMLxQGm12rsLQzgWKYgmLPLNTQw6ynpDSS
IBet8y+TqaVRVdFIeJrWuCcj+/0EzH43BomvIhBLI45uFiDcJ+6QwROFwa6+Amb9bGFNg6Xs9Ncd7Oy3
Knb2eyU7/20nu9y/m136tIvEl6BC0qKoZwby3alo9JVhj7T5R7m/kJVIIityi8zyXmTiW+I10SqyIQNb
uIgNwYuuf25kFd75KPKkI49OmUWnrfYWyXv/wBb2cijhhVf6a9lGei65XclYRDd6mj0GWz2iLBJaH0rY
RSVc5Eywmhm7kuQXHX+bJlBStrh+zTi0PpSwi0q4yNFAOVvgiEcKJWUsxZn/NhT+znlofShhF5VwkRpv
MUtti4KGYjj6sYCIh5QSu4oG27stjItHU+cjeQzvkcFzFQ2KnSKLoc4FukDCXeI2GbSoaFD4ziyPxNxK
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
</root>

View File

@@ -8,6 +8,7 @@
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace DownloadObjects.STDownloader
Friend Class DownloaderUrlForm
Private WithEvents MyDefs As DefaultFormOptions
@@ -22,6 +23,7 @@ Namespace DownloadObjects.STDownloader
.MyViewInitialize(True)
.AddOkCancelToolbar()
TXT_URL.Text = URL
Settings.DownloadLocations.PopulateComboBox(TXT_PATH)
TXT_PATH.Text = Settings.LatestSavingPath.Value
If TXT_PATH.Text.IsEmptyString Then TXT_PATH.Text = Application.StartupPath.CSFileP.PathWithSeparator
.MyFieldsChecker = New FieldsChecker
@@ -31,8 +33,20 @@ Namespace DownloadObjects.STDownloader
.EndLoaderOperations()
End With
.EndLoaderOperations()
.MyOkCancel.EnableOK = True
End With
End Sub
Private Sub DownloaderUrlForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
If e.KeyCode = Keys.O And e.Control Then
Settings.DownloadLocations.ChooseNewLocation(TXT_PATH, False, Settings.STDownloader_OutputPathAskForName)
ElseIf e.KeyCode = Keys.O And e.Alt Then
Settings.DownloadLocations.ChooseNewLocation(TXT_PATH, True, Settings.STDownloader_OutputPathAskForName)
Else
b = False
End If
If b Then e.Handled = True
End Sub
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
If MyDefs.MyFieldsChecker.AllParamsOK Then
URL = TXT_URL.Text
@@ -41,10 +55,8 @@ Namespace DownloadObjects.STDownloader
End If
End Sub
Private Sub TXT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH.ActionOnButtonClick
If Sender.DefaultButton = ActionButton.DefaultButtons.Open Then
Dim f As SFile = SFile.SelectPath(TXT_PATH.Text.CSFileP, "Select output directory", EDP.ReturnValue)
If Not f.IsEmptyString Then TXT_PATH.Text = f.PathWithSeparator
End If
If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _
Settings.DownloadLocations.ChooseNewLocation(TXT_PATH, Sender.DefaultButton = ADB.Add, Settings.STDownloader_OutputPathAskForName)
End Sub
End Class
End Namespace

View File

@@ -27,8 +27,12 @@ Namespace DownloadObjects.STDownloader
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(DownloaderUrlsArrForm))
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 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
Me.TXT_OUTPUT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_OUTPUT = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.TXT_URLS = New System.Windows.Forms.RichTextBox()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
@@ -77,18 +81,40 @@ Namespace DownloadObjects.STDownloader
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Open"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton1.ToolTipText = "Choose a new location (Ctrl+O)"
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Clear"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton2.Name = "Add"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Add
ActionButton2.ToolTipText = "Choose a new location and add it to the list (Alt+O)"
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
Me.TXT_OUTPUT.Buttons.Add(ActionButton1)
Me.TXT_OUTPUT.Buttons.Add(ActionButton2)
Me.TXT_OUTPUT.Buttons.Add(ActionButton3)
Me.TXT_OUTPUT.Buttons.Add(ActionButton4)
Me.TXT_OUTPUT.CaptionText = "Output path"
Me.TXT_OUTPUT.CaptionWidth = 70.0R
ListColumn1.Name = "COL_NAME"
ListColumn1.Text = "Name"
ListColumn1.Width = -1
ListColumn2.DisplayMember = True
ListColumn2.Name = "COL_VALUE"
ListColumn2.Text = "Value"
ListColumn2.ValueMember = True
ListColumn2.Visible = False
Me.TXT_OUTPUT.Columns.Add(ListColumn1)
Me.TXT_OUTPUT.Columns.Add(ListColumn2)
Me.TXT_OUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_OUTPUT.ListAutoCompleteMode = PersonalUtilities.Forms.Controls.ComboBoxExtended.AutoCompleteModes.Disabled
Me.TXT_OUTPUT.Location = New System.Drawing.Point(3, 3)
Me.TXT_OUTPUT.Name = "TXT_OUTPUT"
Me.TXT_OUTPUT.Size = New System.Drawing.Size(378, 22)
Me.TXT_OUTPUT.TabIndex = 0
Me.TXT_OUTPUT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'FRM_URLS
'
@@ -117,9 +143,10 @@ Namespace DownloadObjects.STDownloader
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(384, 261)
Me.Controls.Add(CONTAINER_MAIN)
Me.Icon = Global.SCrawler.My.Resources.Resources.ArrowDownIcon_Blue_24
Me.KeyPreview = True
Me.MinimumSize = New System.Drawing.Size(400, 300)
Me.Name = "DownloaderUrlsArrForm"
Me.Icon = Global.SCrawler.My.Resources.ArrowDownIcon_Blue_24
Me.ShowInTaskbar = False
Me.Text = "Urls array"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
@@ -129,8 +156,9 @@ Namespace DownloadObjects.STDownloader
CType(Me.TXT_OUTPUT, System.ComponentModel.ISupportInitialize).EndInit()
FRM_URLS.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_OUTPUT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_OUTPUT As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents TXT_URLS As RichTextBox
End Class
End Namespace

View File

@@ -136,11 +136,123 @@
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
QVRIS62WWWxMURjHL220JW1HausmlFrDFKUhnUGH6bRFzJ2idImlC0Vp2mlji1A8iNhCPIjIRES8EU+W
h2oEtbSDTk3HNNM7S01VKsXjkb/vXBo3k1Ee7sMvmZzzzf//ne/+z50RAAxL1MUIG4G/YAv3HSVhF5Vw
IYNdz3LadVj9RgdTB+HQYYPHIJuE1ocSdlEJFzG+1bPRLQLinglIeCkg+XUkKvz56hnkOfQs/rmA8S9H
YEp7FDI64tAQtKhnsMapZ7zzNHsUFnbGY4VzIk70l6hnIH4wsDR7NBZ3apDrSqL5T8eFgUr1DLZ78lim
Q4N8VzK29MxEpZSBa4M16hnU+c3M9CEFpdJsVHsXos63DDcHrf9nQEXD5VymwW/5USLNwl5vJhp7dTgW
NML2pR7jbsUMS+KdMTa5Q8NQxinfBU4dRFcOyjy52OtbhwOBDTgZLKPPmTgY0ON4MBdNfSbYBupxY8Aq
G10dqMG5/nIc7ytGQ6CQRliAamkTN/g1Ai4e95Qy3iogpX0UtBRDnhRzdxq2SXOxz5eFQ70rScCEU335
ssGxj0YS06HSm4GN3ekwdE2C1hGH1LZR0JDOJof5jwHvnIvzTa0jlooTYfktvt+fhcOBHDQFTWRgxJGP
ObAGsulZLMLWnjlY756K5c4JmNcRi6T2SGheCIihS2l5ozAo6NRhMolnUAcGV6IcwwqvFrX+JTjYuwKH
SfRAYDms/mzs9y1GFe2VSnOw1j0FejqpLN4WCX4ZufiIBwLMLxQGm12rsLQzgWKYgmLPLNTQw6ynpDSS
IBet8y+TqaVRVdFIeJrWuCcj+/0EzH43BomvIhBLI45uFiDcJ+6QwROFwa6+Amb9bGFNg6Xs9Ncd7Oy3
Knb2eyU7/20nu9y/m136tIvEl6BC0qKoZwby3alo9JVhj7T5R7m/kJVIIityi8zyXmTiW+I10SqyIQNb
uIgNwYuuf25kFd75KPKkI49OmUWnrfYWyXv/wBb2cijhhVf6a9lGei65XclYRDd6mj0GWz2iLBJaH0rY
RSVc5Eywmhm7kuQXHX+bJlBStrh+zTi0PpSwi0q4yNFAOVvgiEcKJWUsxZn/NhT+znlofShhF5VwkRpv
MUtti4KGYjj6sYCIh5QSu4oG27stjItHU+cjeQzvkcFzFQ2KnSKLoc4FukDCXeI2GbSoaFD4ziyPxNxK
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<metadata name="FRM_URLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

View File

@@ -8,6 +8,7 @@
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace DownloadObjects.STDownloader
Friend Class DownloaderUrlsArrForm
Private WithEvents MyDefs As DefaultFormOptions
@@ -25,14 +26,16 @@ Namespace DownloadObjects.STDownloader
End If
End Get
End Property
Friend Sub New()
Friend Sub New(ByVal InitialList As IEnumerable(Of String))
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
If InitialList.ListExists Then TXT_URLS.Text = InitialList.ListToString(vbNewLine)
End Sub
Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddOkCancelToolbar()
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
.MyFieldsChecker = New FieldsChecker
@@ -41,17 +44,26 @@ Namespace DownloadObjects.STDownloader
.EndLoaderOperations()
End With
.EndLoaderOperations()
.MyOkCancel.EnableOK = True
End With
End Sub
Private Sub DownloaderUrlsArrForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
If e.KeyCode = Keys.O And e.Control Then
Settings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT, False, Settings.STDownloader_OutputPathAskForName)
ElseIf e.KeyCode = Keys.O And e.Alt Then
Settings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT, True, Settings.STDownloader_OutputPathAskForName)
Else
b = False
End If
If b Then e.Handled = True
End Sub
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
If MyDefs.MyFieldsChecker.AllParamsOK Then MyDefs.CloseForm()
End Sub
Private Sub TXT_OUTPUT_ActionOnButtonClick(ByVal Sender As Object, ByVal e As ActionButtonEventArgs) Handles TXT_OUTPUT.ActionOnButtonClick
If e.DefaultButton = ActionButton.DefaultButtons.Open Then
Dim f As SFile = TXT_OUTPUT.Text.CSFileP
f = SFile.SelectPath(f, "Select a folder for files", EDP.ReturnValue)
If Not f.IsEmptyString Then TXT_OUTPUT.Text = f.PathWithSeparator
End If
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
End Class
End Namespace

View File

@@ -13,20 +13,33 @@ Imports PersonalUtilities.Forms.Controls.KeyClick
Namespace DownloadObjects.STDownloader
Friend Class VideoDownloaderForm
Private WithEvents BTT_ADD_URLS_ARR As ToolStripMenuItemKeyClick
Private WithEvents BTT_ADD_URLS_EXTERNAL As ToolStripMenuItemKeyClick
Private Const UrlsArrTag As String = "URLS_ARR"
Private Const TAG_EXTERNAL As String = "EXTERNAL"
Private ReadOnly ControlNonYT As New FPredicate(Of MediaItem)(Function(i) Not i.MyContainer.SiteKey = API.YouTube.YouTubeSiteKey)
Private ReadOnly ControlsDownloadedNonYT As New FPredicate(Of MediaItem)(Function(i) i.MyContainer.MediaState = Plugin.UserMediaStates.Downloaded And ControlNonYT.Invoke(i))
Private ReadOnly Property ExternalUrlsTemp As List(Of String)
Public Sub New()
InitializeComponent()
ExternalUrlsTemp = New List(Of String)
AppMode = False
Icon = My.Resources.ArrowDownIcon_Blue_24
BTT_ADD_PLS_ARR.Text = $"YouTube: {BTT_ADD_PLS_ARR.Text}"
BTT_ADD_NO_SHORTS.Text = $"YouTube: {BTT_ADD_NO_SHORTS.Text}"
BTT_ADD_SHORTS_ONLY.Text = $"YouTube: {BTT_ADD_SHORTS_ONLY.Text}"
BTT_ADD_URLS_ARR = New ToolStripMenuItemKeyClick("Add an array of URLs", PersonalUtilities.My.Resources.PlusPic_Green_24) With {.Tag = UrlsArrTag}
BTT_ADD_URLS_EXTERNAL = New ToolStripMenuItemKeyClick With {.Tag = TAG_EXTERNAL}
MENU_ADD.DropDownItems.Insert(1, BTT_ADD_URLS_ARR)
Text = "Video downloader"
End Sub
Protected Overrides Sub VideoListForm_Disposed(sender As Object, e As EventArgs)
ExternalUrlsTemp.Clear()
MyBase.VideoListForm_Disposed(sender, e)
End Sub
Friend Sub ADD_URLS_EXTERNAL(ByVal UrlsList As IEnumerable(Of String))
ExternalUrlsTemp.ListAddList(UrlsList, LAP.ClearBeforeAdd, LAP.NotContainsOnly)
If ExternalUrlsTemp.Count > 0 Then BTT_ADD_URLS_EXTERNAL.PerformClick()
End Sub
Protected Overrides Function LoadData_GetFiles() As List(Of IYouTubeMediaContainer)
Try
Dim l As List(Of IYouTubeMediaContainer) = Nothing
@@ -43,17 +56,19 @@ Namespace DownloadObjects.STDownloader
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "VideoListForm.LoadData_GetFiles", New List(Of IYouTubeMediaContainer))
End Try
End Function
Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) Handles BTT_ADD_URLS_ARR.KeyClick
Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) Handles BTT_ADD_URLS_ARR.KeyClick,
BTT_ADD_URLS_EXTERNAL.KeyClick
Dim __tag$ = UniversalFunctions.IfNullOrEmpty(Of Object)(Sender.Tag, String.Empty)
If Not __tag = "a" And Not __tag = UrlsArrTag Then
If Not __tag = "a" And Not __tag = UrlsArrTag And Not __tag = TAG_EXTERNAL Then
MyBase.BTT_ADD_KeyClick(Sender, e)
Else
Dim url$ = String.Empty
Try
url = BufferText
Dim isExternal As Boolean = __tag = TAG_EXTERNAL
If Not isExternal Then url = BufferText
Dim disableDown As Boolean = e.Shift
Dim output As SFile = Settings.LatestSavingPath
Dim isArr As Boolean = __tag = UrlsArrTag
Dim isArr As Boolean = (__tag = UrlsArrTag Or (isExternal And ExternalUrlsTemp.Count > 1))
Dim formOpened As Boolean = False
Dim media As IYouTubeMediaContainer
Dim formValues As Func(Of DialogResult) = Function() As DialogResult
@@ -67,6 +82,8 @@ Namespace DownloadObjects.STDownloader
Settings.LatestSavingPath.Value = output
If Settings.STDownloader_UpdateYouTubeOutputPath Then _
API.YouTube.MyYouTubeSettings.OutputPath.Value = output
If Settings.STDownloader_OutputPathAutoAddPaths Then _
Settings.DownloadLocations.Add(output, False)
Return DialogResult.OK
Else
Return DialogResult.Cancel
@@ -103,22 +120,26 @@ Namespace DownloadObjects.STDownloader
If output.IsEmptyString Then output = API.YouTube.MyYouTubeSettings.OutputPath
If isArr Then
Dim urls As List(Of String)
Dim urls As List(Of String) = Nothing
Dim cntAdded As Boolean = False
Using fa As New DownloaderUrlsArrForm
If isExternal Then urls = New List(Of String)(ExternalUrlsTemp)
Using fa As New DownloaderUrlsArrForm(urls)
fa.ShowDialog()
If fa.DialogResult = DialogResult.OK Then
urls = fa.URLs.ToList
output = fa.OutputPath
If Settings.STDownloader_UpdateYouTubeOutputPath Then API.YouTube.MyYouTubeSettings.OutputPath.Value = output
If Settings.STDownloader_OutputPathAutoAddPaths Then Settings.DownloadLocations.Add(output, False)
Else
Exit Sub
End If
End Using
If urls.ListExists Then
urls.ListForEach(Function(uu, ii) uu.StringTrim,, False)
urls.RemoveAll(Function(uu) url.IsEmptyString OrElse Not url.StartsWith("http") OrElse Not canProcessUrl(uu, False))
urls.RemoveAll(Function(uu) uu.IsEmptyString OrElse Not uu.StartsWith("http") OrElse Not canProcessUrl(uu, False))
End If
If urls.ListExists Then
output.Exists(SFO.Path, True)
For Each url In urls
If Not TryYouTube.Invoke Then
media = FindSource(url, output)
@@ -131,6 +152,7 @@ Namespace DownloadObjects.STDownloader
MsgBoxE({"There are no valid URLs in the list", "Add URLs array"}, vbCritical)
End If
Else
If isExternal Then url = ExternalUrlsTemp.FirstOrDefault
If formValues.Invoke = DialogResult.Cancel Then Exit Sub
If canProcessUrl(url, True) Then
If TryYouTube.Invoke Then Exit Sub
@@ -153,11 +175,14 @@ 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
output.Exists(SFO.Path, True)
ControlCreateAndAdd(media, disableDown)
End If
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, $"Error when trying to download video from URL: [{url}]")
Finally
ExternalUrlsTemp.Clear()
End Try
End If
End Sub
@@ -181,14 +206,14 @@ Namespace DownloadObjects.STDownloader
If Settings.STDownloader_RemoveYTVideosOnClear Then
MyBase.BTT_CLEAR_DONE_Click(sender, e)
Else
RemoveControls(ControlsDownloadedNonYT)
RemoveControls(ControlsDownloadedNonYT, False)
End If
End Sub
Protected Overrides Sub BTT_CLEAR_ALL_Click(sender As Object, e As EventArgs)
If Settings.STDownloader_RemoveYTVideosOnClear Then
MyBase.BTT_CLEAR_ALL_Click(sender, e)
Else
RemoveControls(ControlNonYT)
RemoveControls(ControlNonYT, False)
End If
End Sub
Protected Overrides Sub MyJob_Finished(ByVal Sender As Object, ByVal e As EventArgs)

View File

@@ -22,6 +22,7 @@ Namespace DownloadObjects
Friend Event SendNotification As NotificationEventHandler
Friend Event Reconfigured()
Friend Event FeedFilesChanged(ByVal Added As Boolean)
Friend Event UserDownloadStateChanged As UserDownloadStateChangedEventHandler
#End Region
#Region "Declarations"
#Region "Files"
@@ -124,6 +125,8 @@ Namespace DownloadObjects
End Try
End Sub
#End Region
Friend ReadOnly Property ActiveDownloading As List(Of IUserData)
Friend Property QueueFormOpening As Boolean = False
Friend ReadOnly Property Downloaded As List(Of IUserData)
Private ReadOnly NProv As IFormatProvider
#End Region
@@ -272,6 +275,7 @@ Namespace DownloadObjects
#Region "Initializer"
Friend Sub New()
Files = New List(Of UserMediaD)
ActiveDownloading = New List(Of IUserData)
Downloaded = New List(Of IUserData)
NProv = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
Pool = New List(Of Job)
@@ -406,6 +410,9 @@ Namespace DownloadObjects
Dim Keys As New List(Of String)
Dim h As Boolean = False
Dim host As SettingsHost = Nothing
Dim waitQueueForm As Action = Sub()
While QueueFormOpening : Thread.Sleep(100) : End While
End Sub
For Each _Item As IUserData In _Job.Items
If Not _Item.Disposed Then
Keys.Add(_Item.Key)
@@ -413,8 +420,11 @@ Namespace DownloadObjects
If host.Source.ReadyToDownload(Download.Main) Then
host.BeforeStartDownload(_Item, Download.Main)
_Job.ThrowIfCancellationRequested()
waitQueueForm.Invoke
DirectCast(_Item, UserDataBase).Progress = _Job.Progress
t.Add(Task.Run(Sub() _Item.DownloadData(Token)))
ActiveDownloading.Add(_Item)
RaiseEvent UserDownloadStateChanged(_Item, True)
i += 1
If i >= limit Then Exit For
End If
@@ -431,11 +441,14 @@ Namespace DownloadObjects
Dim dcc As Boolean = False
If Keys.Count > 0 Then
For Each k$ In Keys
waitQueueForm.Invoke
i = _Job.Items.FindIndex(Function(ii) ii.Key = k)
If i >= 0 Then
With _Job.Items(i)
If DirectCast(.Self, UserDataBase).ContentMissingExists Then MissingPostsDetected = True
host.AfterDownload(_Job.Items(i), Download.Main)
If ActiveDownloading.Count > 0 AndAlso ActiveDownloading.Contains(.Self) Then ActiveDownloading.Remove(.Self)
RaiseEvent UserDownloadStateChanged(.Self, False)
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))
With DirectCast(.Self, UserDataBase)
@@ -518,6 +531,7 @@ Namespace DownloadObjects
[Stop]()
Pool.ListClearDispose
Files.Clear()
ActiveDownloading.Clear()
Downloaded.Clear()
End If
disposedValue = True

View File

@@ -0,0 +1,66 @@
' 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 DownloadObjects
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class UserDownloadQueueForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
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
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim TOOLBAR_BOTTOM As System.Windows.Forms.StatusStrip
Me.LIST_QUEUE = New System.Windows.Forms.ListBox()
TOOLBAR_BOTTOM = New System.Windows.Forms.StatusStrip()
Me.SuspendLayout()
'
'TOOLBAR_BOTTOM
'
TOOLBAR_BOTTOM.Location = New System.Drawing.Point(0, 189)
TOOLBAR_BOTTOM.Name = "TOOLBAR_BOTTOM"
TOOLBAR_BOTTOM.Size = New System.Drawing.Size(284, 22)
TOOLBAR_BOTTOM.TabIndex = 1
TOOLBAR_BOTTOM.Text = "StatusStrip1"
'
'LIST_QUEUE
'
Me.LIST_QUEUE.Dock = System.Windows.Forms.DockStyle.Fill
Me.LIST_QUEUE.FormattingEnabled = True
Me.LIST_QUEUE.Location = New System.Drawing.Point(0, 0)
Me.LIST_QUEUE.Name = "LIST_QUEUE"
Me.LIST_QUEUE.Size = New System.Drawing.Size(284, 189)
Me.LIST_QUEUE.TabIndex = 0
'
'UserDownloadQueueForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(284, 211)
Me.Controls.Add(Me.LIST_QUEUE)
Me.Controls.Add(TOOLBAR_BOTTOM)
Me.Icon = Global.SCrawler.My.Resources.Resources.ArrowDownIcon_Blue_24
Me.KeyPreview = True
Me.MinimumSize = New System.Drawing.Size(300, 250)
Me.Name = "UserDownloadQueueForm"
Me.Text = "User download queue"
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Private WithEvents LIST_QUEUE As ListBox
End Class
End Namespace

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TOOLBAR_BOTTOM.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TOOLBAR_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -0,0 +1,180 @@
' 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.Threading
Imports System.ComponentModel
Imports SCrawler.API.Base
Imports PersonalUtilities.Forms
Namespace DownloadObjects
Friend Class UserDownloadQueueForm
Private ReadOnly MyVew As FormView
Private ReadOnly Tokens As List(Of CancellationTokenSource)
Private Structure ListUser
Friend ReadOnly User As UserDataBase
Friend IsDownloading As Boolean
Private ReadOnly _UserString As String
Private ReadOnly Property UserString As String
Get
Return $"[{IIf(IsDownloading, "-", "+")}] {_UserString}"
End Get
End Property
Friend ReadOnly Key As String
Friend Sub New(ByVal _User As IUserData)
User = _User
Key = _User.Key
IsDownloading = True
_UserString = DirectCast(User, UserDataBase).ToStringForLog()
If Not User.FriendlyName.IsEmptyString Then _UserString &= $" ({User.FriendlyName})"
End Sub
Public Shared Widening Operator CType(ByVal _User As UserDataBase) As ListUser
Return New ListUser(_User)
End Operator
Public Shared Widening Operator CType(ByVal _User As ListUser) As String
Return _User.ToString
End Operator
Public Overrides Function ToString() As String
Return UserString
End Function
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
Try : Return Not IsNothing(Obj) AndAlso TypeOf Obj Is ListUser AndAlso Key.Equals(CType(Obj, ListUser).Key) : Catch : End Try
Return False
End Function
End Structure
Public Sub New()
InitializeComponent()
MyVew = New FormView(Me, Settings.Design)
Tokens = New List(Of CancellationTokenSource)
End Sub
Private Sub UserDownloadQueueForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
MyVew.Import()
MyVew.SetFormSize()
With Downloader
.QueueFormOpening = True
If .ActiveDownloading.Count > 0 Then
For Each user As UserDataBase In .ActiveDownloading
ApplyHandlers(user, user.DownloadInProgress)
LIST_QUEUE.Items.Add(New ListUser(user))
Next
End If
AddHandler .UserDownloadStateChanged, AddressOf Downloader_UserDownloadStateChanged
AddHandler .Downloading, AddressOf Downloader_Downloading
.QueueFormOpening = False
End With
Catch aoutex As ArgumentOutOfRangeException
Catch iex As IndexOutOfRangeException
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog + EDP.ShowMainMsg, ex, "Error when opening user download queue form")
Finally
Downloader.QueueFormOpening = False
End Try
End Sub
Private Sub UserDownloadQueueForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
e.Cancel = True
Hide()
End Sub
Private Sub UserDownloadQueueForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyVew.Dispose()
Tokens.ListClearDispose
End Sub
Private Sub UserDownloadQueueForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
If e.KeyCode = Keys.Delete Then
CancelUserDownload()
ElseIf e.KeyCode = Keys.F And e.Control Then
FindUser()
Else
b = False
End If
If b Then e.Handled = True
End Sub
Private Sub Downloader_Downloading(ByVal Value As Boolean)
ControlInvokeFast(LIST_QUEUE, Sub() If Not Value Then LIST_QUEUE.Items.Clear() : Tokens.ListClearDispose, EDP.None)
End Sub
Private Async Sub Downloader_UserDownloadStateChanged(ByVal User As IUserData, ByVal IsDownloading As Boolean)
Await Task.Run(Sub()
Try
ControlInvokeFast(LIST_QUEUE, Sub()
Dim u As New ListUser(User)
ApplyHandlers(User, IsDownloading)
If IsDownloading Then
LIST_QUEUE.Items.Add(u)
Else
LIST_QUEUE.Items.Remove(u)
End If
LIST_QUEUE.Refresh()
End Sub)
Catch ex As Exception
End Try
End Sub)
End Sub
Private Async Sub User_UserDownloadStateChanged(ByVal User As IUserData, ByVal IsDownloading As Boolean)
Await Task.Run(Sub()
Try
ControlInvokeFast(LIST_QUEUE,
Sub()
Dim lu As New ListUser(User)
Dim i% = LIST_QUEUE.Items.IndexOf(lu)
If i >= 0 Then
lu = LIST_QUEUE.Items(i)
If Not lu.User Is Nothing And Not lu.IsDownloading = IsDownloading Then
lu.IsDownloading = IsDownloading
LIST_QUEUE.Items(i) = lu
LIST_QUEUE.Refresh()
End If
End If
End Sub)
Catch
End Try
End Sub)
End Sub
Private Sub ApplyHandlers(ByVal User As IUserData, ByVal IsDownloading As Boolean)
Try
If Not User Is Nothing Then
With DirectCast(User, UserDataBase)
If IsDownloading Then
AddHandler .UserDownloadStateChanged, AddressOf User_UserDownloadStateChanged
Else
RemoveHandler .UserDownloadStateChanged, AddressOf User_UserDownloadStateChanged
End If
End With
End If
Catch
End Try
End Sub
Private Sub CancelUserDownload()
Const msgTitle$ = "Stop user download"
Try
Dim lu As ListUser = GetUserSelectedUser()
If Not lu.User Is Nothing AndAlso
MsgBoxE({$"Are you sure you want to stop downloading the following user?{vbCr}{lu}", msgTitle}, vbExclamation + vbYesNo) = vbYes Then
Dim token As New CancellationTokenSource
lu.User.PersonalToken = token.Token
token.Cancel()
Tokens.Add(token)
MsgBoxE({"Cancel user download processed.", msgTitle})
End If
Catch ex As Exception
End Try
End Sub
Private Sub FindUser()
Try
MainFrameObj.FocusUser(GetUserSelectedUser().Key, True)
Catch ex As Exception
End Try
End Sub
Private Function GetUserSelectedUser() As ListUser
Dim lu As ListUser = Nothing
ControlInvokeFast(LIST_QUEUE, Sub()
Dim sIndx% = LIST_QUEUE.SelectedIndex
If sIndx >= 0 Then lu = LIST_QUEUE.Items(sIndx)
End Sub)
Return lu
End Function
End Class
End Namespace

View File

@@ -26,6 +26,7 @@ Namespace Editors
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(CollectionEditorForm))
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()
Me.CMB_COLLECTIONS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
@@ -56,11 +57,17 @@ Namespace Editors
ActionButton1.Name = "Add"
ActionButton1.ToolTipText = "Add new collection"
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "ArrowDown"
ActionButton2.Visible = False
ActionButton2.Name = "Open"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton2.ToolTipText = "Choose a different destination for the new collection (Ctrl+O)"
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "ArrowDown"
ActionButton3.Visible = False
Me.CMB_COLLECTIONS.Buttons.Add(ActionButton1)
Me.CMB_COLLECTIONS.Buttons.Add(ActionButton2)
Me.CMB_COLLECTIONS.Buttons.Add(ActionButton3)
Me.CMB_COLLECTIONS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_COLLECTIONS.Lines = New String(-1) {}
Me.CMB_COLLECTIONS.ListDropDownStyle = PersonalUtilities.Forms.Controls.ComboBoxExtended.ListMode.Simple
Me.CMB_COLLECTIONS.Location = New System.Drawing.Point(2, 0)
Me.CMB_COLLECTIONS.Name = "CMB_COLLECTIONS"

View File

@@ -144,6 +144,17 @@
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL

View File

@@ -8,15 +8,24 @@
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace Editors
Friend Class CollectionEditorForm
Private WithEvents MyDefs As DefaultFormOptions
Private ReadOnly Collections As List(Of String)
Friend Property [Collection] As String = String.Empty
Friend Property MyCollection As String = String.Empty
Private _MyCollectionSpecialPath As SFile = Nothing
Friend ReadOnly Property MyCollectionSpecialPath As SFile
Get
Return _MyCollectionSpecialPath
End Get
End Property
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
Collections = New List(Of String)
Icon = PersonalUtilities.Tools.ImageRenderer.GetIcon(My.Resources.DBPic_32, EDP.ReturnValue)
If Not Icon Is Nothing Then ShowIcon = True
End Sub
Private Sub CollectionEditorForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
@@ -27,7 +36,7 @@ Namespace Editors
Dim ecol As List(Of String) = ListAddList(Nothing, (From c In Settings.Users Where c.IsCollection Select c.CollectionName), LAP.NotContainsOnly)
If ecol.ListExists Then ecol.Sort() : Collections.ListAddList(ecol, LAP.NotContainsOnly) : ecol.Clear()
If Collections.Count > 0 Then CMB_COLLECTIONS.Items.AddRange(Collections.Select(Function(c) New ListItem(c)))
If Not Collection.IsEmptyString And Collections.Contains(Collection) Then CMB_COLLECTIONS.SelectedIndex = Collections.IndexOf(Collection)
If Not MyCollection.IsEmptyString And Collections.Contains(MyCollection) Then CMB_COLLECTIONS.SelectedIndex = Collections.IndexOf(MyCollection)
.DelegateClosingChecker = False
.EndLoaderOperations()
End With
@@ -39,29 +48,41 @@ Namespace Editors
Collections.Clear()
End Sub
Private Sub CollectionEditorForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Insert Then AddNewCollection() : e.Handled = True Else e.Handled = False
If e.KeyCode = Keys.Insert Or (e.KeyCode = Keys.O And e.Control) Then AddNewCollection(Not e.KeyCode = Keys.Insert) : e.Handled = True
End Sub
Private Sub MyDefs_ButtonOkClick() Handles MyDefs.ButtonOkClick
If CMB_COLLECTIONS.SelectedIndex >= 0 Then
Collection = CMB_COLLECTIONS.Value.ToString
MyCollection = CMB_COLLECTIONS.Value.ToString
With Settings.LastCollections
If .Contains(Collection) Then .Remove(Collection)
If .Count = 0 Then .Add(Collection) Else .Insert(0, Collection)
If .Contains(MyCollection) Then .Remove(MyCollection)
If .Count = 0 Then .Add(MyCollection) Else .Insert(0, MyCollection)
End With
MyDefs.CloseForm()
Else
MsgBoxE("Collection not selected", MsgBoxStyle.Exclamation)
End If
End Sub
Private Sub CMB_COLLECTIONS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles CMB_COLLECTIONS.ActionOnButtonClick
If Sender.DefaultButton = ActionButton.DefaultButtons.Add Then AddNewCollection()
Private Sub CMB_COLLECTIONS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles CMB_COLLECTIONS.ActionOnButtonClick
If e.DefaultButton = ADB.Add Or e.DefaultButton = ADB.Open Then AddNewCollection(e.DefaultButton = ADB.Open)
End Sub
Private Sub CMB_COLLECTIONS_ActionOnListDoubleClick(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_COLLECTIONS.ActionOnListDoubleClick
Item.Selected = True
MyDefs_ButtonOkClick()
End Sub
Private Sub AddNewCollection()
Dim c$ = InputBoxE("Enter new collection name:", "Collection name")
Private Sub AddNewCollection(ByVal OpenMode As Boolean)
Dim c$ = String.Empty
If OpenMode Then
Using f As New GlobalLocationsChooserForm With {.MyIsCollectionSelector = True}
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
c = f.MyCollectionName
_MyCollectionSpecialPath = $"{f.MyDestination.Path.CSFilePS}{c}\"
End If
End Using
Else
_MyCollectionSpecialPath = Nothing
c = InputBoxE("Enter new collection name:", "Collection name")
End If
If Not c.IsEmptyString Then
If Not Collections.Contains(c) Then
Collections.Add(c)
@@ -69,7 +90,11 @@ Namespace Editors
CMB_COLLECTIONS.SelectedIndex = CMB_COLLECTIONS.Count - 1
Else
Dim i% = Collections.IndexOf(c)
If i >= 0 Then CMB_COLLECTIONS.SelectedIndex = i
If i >= 0 Then
CMB_COLLECTIONS.SelectedIndex = i
_MyCollectionSpecialPath = Settings.UsersList.FirstOrDefault(Function(u) u.CollectionName = c).SpecialCollectionPath
MsgBoxE({$"The '{c}' collection already exists", "Add a new collection"}, vbExclamation)
End If
End If
End If
End Sub

View File

@@ -92,10 +92,18 @@ Namespace Editors
ForeColorImpl = Nothing
End If
End Sub
Friend Sub ColorsSetUser(ByVal b As Color?, ByVal f As Color?)
BackColorImpl = b
ForeColorImpl = f
End Sub
Friend Sub ColorsGet(ByRef b As XMLValue(Of Color), ByRef f As XMLValue(Of Color))
If BackColorImpl.HasValue Then b.Value = BackColorImpl.Value Else b.ValueF = Nothing
If ForeColorImpl.HasValue Then f.Value = ForeColorImpl.Value Else f.ValueF = Nothing
End Sub
Friend Sub ColorsGetUser(ByRef b As Color?, ByRef f As Color?)
b = BackColorImpl
f = ForeColorImpl
End Sub
#End Region
#Region "Buttons handlers"
Private Sub COLOR_BUTTONS_Click(ByVal Sender As Button, ByVal e As EventArgs) Handles BTT_COLORS_BACK.Click,

View File

@@ -0,0 +1,227 @@
' 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 Editors
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class GlobalLocationsChooserForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
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
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
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(GlobalLocationsChooserForm))
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 TP_LOCATIONS_USER As System.Windows.Forms.TableLayoutPanel
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.CMB_LOCATIONS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.FRM_LOCATIONS = New System.Windows.Forms.GroupBox()
Me.OPT_LOCATION_1 = New System.Windows.Forms.RadioButton()
Me.OPT_LOCATION_2 = New System.Windows.Forms.RadioButton()
Me.OPT_LOCATION_3 = New System.Windows.Forms.RadioButton()
Me.TXT_COL_NAME = New PersonalUtilities.Forms.Controls.TextBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_LOCATIONS_USER = New System.Windows.Forms.TableLayoutPanel()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
Me.TP_MAIN.SuspendLayout()
CType(Me.CMB_LOCATIONS, System.ComponentModel.ISupportInitialize).BeginInit()
Me.FRM_LOCATIONS.SuspendLayout()
TP_LOCATIONS_USER.SuspendLayout()
CType(Me.TXT_COL_NAME, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 251)
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(584, 251)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'TP_MAIN
'
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(Me.CMB_LOCATIONS, 0, 0)
Me.TP_MAIN.Controls.Add(Me.FRM_LOCATIONS, 0, 2)
Me.TP_MAIN.Controls.Add(Me.TXT_COL_NAME, 0, 1)
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 = 3
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(584, 251)
Me.TP_MAIN.TabIndex = 0
'
'CMB_LOCATIONS
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Open"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton1.ToolTipText = "Choose a new location (Ctrl+O)"
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Clear"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "ArrowDown"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_LOCATIONS.Buttons.Add(ActionButton1)
Me.CMB_LOCATIONS.Buttons.Add(ActionButton2)
Me.CMB_LOCATIONS.Buttons.Add(ActionButton3)
Me.CMB_LOCATIONS.CaptionChecked = True
Me.CMB_LOCATIONS.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.CMB_LOCATIONS.CaptionText = "Global path"
Me.CMB_LOCATIONS.CaptionToolTipEnabled = True
Me.CMB_LOCATIONS.CaptionToolTipText = "If checked, the path will be added to the global paths"
Me.CMB_LOCATIONS.CaptionVisible = True
Me.CMB_LOCATIONS.ChangeControlsEnableOnCheckedChange = False
Me.CMB_LOCATIONS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_LOCATIONS.Lines = New String(-1) {}
Me.CMB_LOCATIONS.Location = New System.Drawing.Point(3, 3)
Me.CMB_LOCATIONS.Name = "CMB_LOCATIONS"
Me.CMB_LOCATIONS.Size = New System.Drawing.Size(578, 22)
Me.CMB_LOCATIONS.TabIndex = 0
Me.CMB_LOCATIONS.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'FRM_LOCATIONS
'
Me.FRM_LOCATIONS.Controls.Add(TP_LOCATIONS_USER)
Me.FRM_LOCATIONS.Dock = System.Windows.Forms.DockStyle.Fill
Me.FRM_LOCATIONS.Location = New System.Drawing.Point(3, 59)
Me.FRM_LOCATIONS.Name = "FRM_LOCATIONS"
Me.FRM_LOCATIONS.Size = New System.Drawing.Size(578, 189)
Me.FRM_LOCATIONS.TabIndex = 2
Me.FRM_LOCATIONS.TabStop = False
Me.FRM_LOCATIONS.Text = "Locations"
'
'TP_LOCATIONS_USER
'
TP_LOCATIONS_USER.ColumnCount = 1
TP_LOCATIONS_USER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_LOCATIONS_USER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_LOCATIONS_USER.Controls.Add(Me.OPT_LOCATION_1, 0, 0)
TP_LOCATIONS_USER.Controls.Add(Me.OPT_LOCATION_2, 0, 1)
TP_LOCATIONS_USER.Controls.Add(Me.OPT_LOCATION_3, 0, 2)
TP_LOCATIONS_USER.Dock = System.Windows.Forms.DockStyle.Fill
TP_LOCATIONS_USER.Location = New System.Drawing.Point(3, 16)
TP_LOCATIONS_USER.Margin = New System.Windows.Forms.Padding(0)
TP_LOCATIONS_USER.Name = "TP_LOCATIONS_USER"
TP_LOCATIONS_USER.RowCount = 3
TP_LOCATIONS_USER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_LOCATIONS_USER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_LOCATIONS_USER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_LOCATIONS_USER.Size = New System.Drawing.Size(572, 170)
TP_LOCATIONS_USER.TabIndex = 0
'
'OPT_LOCATION_1
'
Me.OPT_LOCATION_1.AutoSize = True
Me.OPT_LOCATION_1.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_LOCATION_1.Location = New System.Drawing.Point(3, 3)
Me.OPT_LOCATION_1.Name = "OPT_LOCATION_1"
Me.OPT_LOCATION_1.Size = New System.Drawing.Size(566, 50)
Me.OPT_LOCATION_1.TabIndex = 0
Me.OPT_LOCATION_1.TabStop = True
Me.OPT_LOCATION_1.Text = "Location user 1" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Location collection 1"
Me.OPT_LOCATION_1.UseVisualStyleBackColor = True
'
'OPT_LOCATION_2
'
Me.OPT_LOCATION_2.AutoSize = True
Me.OPT_LOCATION_2.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_LOCATION_2.Location = New System.Drawing.Point(3, 59)
Me.OPT_LOCATION_2.Name = "OPT_LOCATION_2"
Me.OPT_LOCATION_2.Size = New System.Drawing.Size(566, 50)
Me.OPT_LOCATION_2.TabIndex = 1
Me.OPT_LOCATION_2.TabStop = True
Me.OPT_LOCATION_2.Text = "Location user 2" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Location collection 2"
Me.OPT_LOCATION_2.UseVisualStyleBackColor = True
'
'OPT_LOCATION_3
'
Me.OPT_LOCATION_3.AutoSize = True
Me.OPT_LOCATION_3.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_LOCATION_3.Location = New System.Drawing.Point(3, 115)
Me.OPT_LOCATION_3.Name = "OPT_LOCATION_3"
Me.OPT_LOCATION_3.Size = New System.Drawing.Size(566, 52)
Me.OPT_LOCATION_3.TabIndex = 2
Me.OPT_LOCATION_3.TabStop = True
Me.OPT_LOCATION_3.Text = "Location user 3" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Location collection 3"
Me.OPT_LOCATION_3.UseVisualStyleBackColor = True
'
'TXT_COL_NAME
'
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Name = "Clear"
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_COL_NAME.Buttons.Add(ActionButton4)
Me.TXT_COL_NAME.CaptionText = "Collection name"
Me.TXT_COL_NAME.CaptionToolTipEnabled = True
Me.TXT_COL_NAME.CaptionToolTipText = "Collection folder to be created in the destination"
Me.TXT_COL_NAME.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_COL_NAME.Lines = New String(-1) {}
Me.TXT_COL_NAME.Location = New System.Drawing.Point(3, 31)
Me.TXT_COL_NAME.Name = "TXT_COL_NAME"
Me.TXT_COL_NAME.PlaceholderEnabled = True
Me.TXT_COL_NAME.PlaceholderText = "Enter collection name here..."
Me.TXT_COL_NAME.Size = New System.Drawing.Size(578, 22)
Me.TXT_COL_NAME.TabIndex = 1
'
'GlobalLocationsChooserForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(584, 251)
Me.Controls.Add(CONTAINER_MAIN)
Me.KeyPreview = True
Me.MinimumSize = New System.Drawing.Size(600, 290)
Me.Name = "GlobalLocationsChooserForm"
Me.Text = "Choose a new location"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
Me.TP_MAIN.ResumeLayout(False)
CType(Me.CMB_LOCATIONS, System.ComponentModel.ISupportInitialize).EndInit()
Me.FRM_LOCATIONS.ResumeLayout(False)
TP_LOCATIONS_USER.ResumeLayout(False)
TP_LOCATIONS_USER.PerformLayout()
CType(Me.TXT_COL_NAME, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents CMB_LOCATIONS As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents OPT_LOCATION_1 As RadioButton
Private WithEvents OPT_LOCATION_2 As RadioButton
Private WithEvents OPT_LOCATION_3 As RadioButton
Private WithEvents FRM_LOCATIONS As GroupBox
Private WithEvents TP_MAIN As TableLayoutPanel
Private WithEvents TXT_COL_NAME As PersonalUtilities.Forms.Controls.TextBoxExtended
End Class
End Namespace

View File

@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<metadata name="TP_LOCATIONS_USER.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,217 @@
' 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.API.Base
Imports SCrawler.DownloadObjects.STDownloader
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms.Controls.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace Editors
Friend Class GlobalLocationsChooserForm
#Region "Statics"
Friend Shared ReadOnly Property ModelHandler(ByVal Model As PathCreationModel) As PathMoverHandler
Get
Dim pattern$
Select Case Model
Case PathCreationModel.Path : pattern = "{0}\"
Case PathCreationModel.Path_UserName : pattern = "{0}\{2}\"
Case PathCreationModel.Path_UserSite_UserName : pattern = "{0}\{1}\{2}\"
Case PathCreationModel.Collection : pattern = UserInfo.CollectionUserPathPattern
Case Else : Return Nothing
End Select
Return New PathMoverHandler(Function(u, d) String.Format(pattern, d.PathNoSeparator, u.Site, u.Name).CSFileP)
End Get
End Property
Friend Shared Function GetModelByLocation(ByVal Locations As SFile) As Integer
If Settings.GlobalLocations.Count > 0 Then
Dim i% = Settings.GlobalLocations.IndexOf(Locations, True)
If i >= 0 Then Return Settings.GlobalLocations(i).Model
End If
Return -1
End Function
#End Region
#Region "Declarations"
Private WithEvents MyDefs As DefaultFormOptions
Friend ReadOnly Property MyModelHandler As PathMoverHandler
Get
Select Case True
Case OPT_LOCATION_1.Checked : Return ModelHandler(If(MyIsCollectionSelector, PathCreationModel.Collection, PathCreationModel.Path))
Case OPT_LOCATION_2.Checked : Return ModelHandler(PathCreationModel.Path_UserName)
Case OPT_LOCATION_3.Checked : Return ModelHandler(PathCreationModel.Path_UserSite_UserName)
Case Else : Return Nothing
End Select
End Get
End Property
Friend ReadOnly Property MyModel As PathCreationModel
Get
Select Case True
Case OPT_LOCATION_1.Checked : Return If(MyIsCollectionSelector, PathCreationModel.Collection, PathCreationModel.Path)
Case OPT_LOCATION_2.Checked : Return PathCreationModel.Path_UserName
Case OPT_LOCATION_3.Checked : Return PathCreationModel.Path_UserSite_UserName
Case Else : Return PathCreationModel.Path_UserSite_UserName
End Select
End Get
End Property
Friend ReadOnly Property MyDestination As DownloadLocation
Get
Return New DownloadLocation With {.Path = CMB_LOCATIONS.Text.CSFileP, .Model = MyModel}
End Get
End Property
Friend Property MyIsMultipleUsers As Boolean = False
Friend Property MyInitialLocation As SFile
Private _MyNonMyltipleUser As IUserData
Private _UserSite As String = String.Empty
Private _UserName As String = String.Empty
Friend Property MyNonMyltipleUser As IUserData
Get
Return _MyNonMyltipleUser
End Get
Set(ByVal u As IUserData)
_MyNonMyltipleUser = u
If Not u Is Nothing And Not u.IsCollection Then
_UserSite = u.Site
_UserName = u.Name
End If
End Set
End Property
Friend Property MyIsCollectionSelector As Boolean = False
Friend Property MyCollectionName As String
Get
Return TXT_COL_NAME.Text
End Get
Set(ByVal NewName As String)
TXT_COL_NAME.Text = NewName
End Set
End Property
#End Region
#Region "Initializer"
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
Icon = ImageRenderer.GetIcon(My.Resources.FolderPic_32, EDP.ReturnValue)
If Icon Is Nothing Then ShowIcon = False
End Sub
#End Region
#Region "Form handlers"
Private Sub GlobalLocationsChooserForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddOkCancelToolbar()
If Not MyIsCollectionSelector Then
TP_MAIN.Controls.Remove(TXT_COL_NAME)
TP_MAIN.RowStyles(1).Height = 0
End If
Settings.GlobalLocations.PopulateComboBox(CMB_LOCATIONS)
If MyIsCollectionSelector Then
FRM_LOCATIONS.Enabled = False
OPT_LOCATION_1.Checked = True
Else
OPT_LOCATION_3.Checked = True
End If
.MyFieldsChecker = New FieldsChecker
With .MyFieldsCheckerE
.AddControl(Of String)(CMB_LOCATIONS, "Location")
If MyIsCollectionSelector Then .AddControl(Of String)(TXT_COL_NAME, TXT_COL_NAME.CaptionText)
.EndLoaderOperations()
End With
.EndLoaderOperations()
UpdateOptions(False)
End With
End Sub
Private Sub GlobalLocationsChooserForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.O And e.Control Then
CMB_LOCATIONS.Button(ADB.Open).PerformClick()
e.Handled = True
End If
End Sub
#End Region
#Region "Ok, Cancel"
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
If MyDefs.MyFieldsChecker.AllParamsOK Then
If CMB_LOCATIONS.Checked Then _
Settings.GlobalLocations.Add(New DownloadLocation With {.Path = CMB_LOCATIONS.Text.CSFileP, .Model = MyModel},
Settings.STDownloader_OutputPathAskForName)
MyDefs.CloseForm()
End If
End Sub
#End Region
#Region "Controls"
Private Sub TXT_COL_NAME_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_COL_NAME.ActionOnTextChanged
UpdateOptions(True, False, False)
End Sub
Private Sub CMB_LOCATIONS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles CMB_LOCATIONS.ActionOnButtonClick
If e.DefaultButton = ADB.Open Or e.DefaultButton = ADB.Add Then
Dim t$ = "Select a new destination for "
If MyIsMultipleUsers Then
t &= "multiple users"
Else
t &= $"{IIf(If(MyNonMyltipleUser?.IsCollection, False), "collection", "user")}"
If Not MyNonMyltipleUser Is Nothing Then t &= $" [{MyNonMyltipleUser}]"
End If
Dim f As SFile = SFile.SelectPath(MyInitialLocation, t)
If Not f.IsEmptyString Then
_SuspendUpdate = True
CMB_LOCATIONS.Text = f.PathWithSeparator
_SuspendUpdate = False
UpdateOptions(True)
End If
End If
End Sub
Private Sub CMB_LOCATIONS_ActionSelectedItemBeforeChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_LOCATIONS.ActionSelectedItemBeforeChanged
_SuspendUpdate = True
End Sub
Private Sub CMB_LOCATIONS_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_LOCATIONS.ActionSelectedItemChanged
Dim i% = CMB_LOCATIONS.SelectedIndex
If i.ValueBetween(0, Settings.DownloadLocations.Count - 1) Then
Select Case Settings.DownloadLocations(i).Model
Case PathCreationModel.Path, PathCreationModel.Collection : OPT_LOCATION_1.Checked = True
Case PathCreationModel.Path_UserName : OPT_LOCATION_2.Checked = True
Case PathCreationModel.Path_UserSite_UserName : OPT_LOCATION_3.Checked = True
End Select
End If
_SuspendUpdate = False
UpdateOptions(False, False, False)
End Sub
Private Sub CMB_LOCATIONS_ActionOnCheckedChange(ByVal Sender As Object, ByVal e As EventArgs, ByVal Checked As Boolean) Handles CMB_LOCATIONS.ActionOnCheckedChange
If Not MyDefs.Initializing Then CMB_LOCATIONS.CaptionText = IIf(Checked, "Global path", "Path")
End Sub
Private Sub CMB_LOCATIONS_ActionOnTextChanged(ByVal Sender As Object, ByVal e As EventArgs) Handles CMB_LOCATIONS.ActionOnTextChanged
UpdateOptions(False)
End Sub
Private _SuspendUpdate As Boolean = False
Private Sub UpdateOptions(ByVal ResetColName As Boolean, Optional ByVal UpdateLocation As Boolean = True, Optional ByVal UpdateColName As Boolean = True)
Const uSiteDef$ = "[UserSite]"
Const uNameDef$ = "[UserName]"
If Not _SuspendUpdate Then
_SuspendUpdate = True
Dim loc As SFile = SFile.GetPath(CMB_LOCATIONS.Text)
If Not loc.IsEmptyString Then
If MyIsCollectionSelector And ResetColName Then
If UpdateColName Then TXT_COL_NAME.Text = loc.Segments.LastOrDefault
If UpdateLocation Then loc = loc.CutPath
CMB_LOCATIONS.Text = loc.PathWithSeparator
End If
Dim cName$ = TXT_COL_NAME.Text
If Not cName.IsEmptyString Then cName &= "\"
Dim p$ = loc.PathWithSeparator
Dim uSite$ = If(MyIsMultipleUsers, uSiteDef, _UserSite.IfNullOrEmpty(uSiteDef))
Dim uName$ = If(MyIsMultipleUsers, uNameDef, _UserName.IfNullOrEmpty(uNameDef))
OPT_LOCATION_1.Text = p & vbCr & $"{p}{cName}{uSite}_{uName}\"
OPT_LOCATION_2.Text = $"{p}{uName}\"
OPT_LOCATION_3.Text = $"{p}{uSite}\{uName}\"
Else
With {OPT_LOCATION_1, OPT_LOCATION_2, OPT_LOCATION_3}.ToList : .ForEach(Sub(opt) opt.Text = String.Empty) : End With
End If
_SuspendUpdate = False
End If
End Sub
#End Region
End Class
End Namespace

View File

@@ -36,6 +36,8 @@ Namespace Editors
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()
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_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
@@ -48,14 +50,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 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 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 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 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 TP_MISSING_DATA As System.Windows.Forms.TableLayoutPanel
Dim TAB_FEED As System.Windows.Forms.TabPage
Dim TP_FEED As System.Windows.Forms.TableLayoutPanel
@@ -63,8 +65,6 @@ 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 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()
@@ -73,9 +73,11 @@ Namespace Editors
Dim ActionButton22 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton23 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 TAB_STD As System.Windows.Forms.TabPage
Dim TP_STD As System.Windows.Forms.TableLayoutPanel
Dim ActionButton25 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()
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()
Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
@@ -91,6 +93,9 @@ Namespace Editors
Me.TXT_USER_AGENT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_USER_LIST_IMAGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.COLORS_USERLIST = New SCrawler.Editors.ColorPicker()
Me.COLORS_SUBSCRIPTIONS = New SCrawler.Editors.ColorPicker()
Me.TXT_PRG_TITLE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_PRG_DESCR = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.OPT_FILE_NAME_REPLACE = New System.Windows.Forms.RadioButton()
Me.OPT_FILE_NAME_ADD_DATE = New System.Windows.Forms.RadioButton()
Me.CH_FILE_NAME_CHANGE = New System.Windows.Forms.CheckBox()
@@ -124,6 +129,12 @@ Namespace Editors
Me.CH_STD_EVERY = New System.Windows.Forms.CheckBox()
Me.CH_STD_YT_LOAD = New System.Windows.Forms.CheckBox()
Me.CH_STD_YT_REMOVE = New System.Windows.Forms.CheckBox()
Me.CH_FEED_OPEN_LAST_MODE = New System.Windows.Forms.CheckBox()
Me.CH_STD_YT_OUTPUT_ASK_NAME = New System.Windows.Forms.CheckBox()
Me.CH_STD_YT_OUTPUT_AUTO_ADD = New System.Windows.Forms.CheckBox()
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.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()
@@ -138,6 +149,7 @@ Namespace Editors
Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_UNAME_UP = New System.Windows.Forms.CheckBox()
Me.CH_UICON_UP = New System.Windows.Forms.CheckBox()
Me.TXT_FEED_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_FEED_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_FEED_ENDLESS = New System.Windows.Forms.CheckBox()
@@ -159,7 +171,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_UICON_UP = New System.Windows.Forms.CheckBox()
Me.CH_FEED_SHOW_FRIENDLY = 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()
@@ -198,6 +210,8 @@ Namespace Editors
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_PRG_TITLE, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_PRG_DESCR, System.ComponentModel.ISupportInitialize).BeginInit()
TP_FILE_NAME.SuspendLayout()
TP_FILE_PATTERNS.SuspendLayout()
TP_CHANNELS_IMGS.SuspendLayout()
@@ -255,16 +269,19 @@ Namespace Editors
TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_USERS, 0, 3)
TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_CHANNELS, 0, 4)
TP_BASIS.Controls.Add(Me.CH_CHECK_VER_START, 0, 5)
TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 7)
TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 10)
TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 11)
TP_BASIS.Controls.Add(Me.TXT_USER_AGENT, 0, 6)
TP_BASIS.Controls.Add(Me.TXT_USER_LIST_IMAGE, 0, 8)
TP_BASIS.Controls.Add(Me.COLORS_USERLIST, 0, 9)
TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 9)
TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 13)
TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 14)
TP_BASIS.Controls.Add(Me.TXT_USER_AGENT, 0, 8)
TP_BASIS.Controls.Add(Me.TXT_USER_LIST_IMAGE, 0, 10)
TP_BASIS.Controls.Add(Me.COLORS_USERLIST, 0, 11)
TP_BASIS.Controls.Add(Me.COLORS_SUBSCRIPTIONS, 0, 12)
TP_BASIS.Controls.Add(Me.TXT_PRG_TITLE, 0, 6)
TP_BASIS.Controls.Add(Me.TXT_PRG_DESCR, 0, 7)
TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill
TP_BASIS.Location = New System.Drawing.Point(3, 3)
TP_BASIS.Name = "TP_BASIS"
TP_BASIS.RowCount = 13
TP_BASIS.RowCount = 16
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
@@ -274,12 +291,14 @@ Namespace Editors
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.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, 362)
TP_BASIS.Size = New System.Drawing.Size(570, 445)
TP_BASIS.TabIndex = 0
'
'TXT_GLOBAL_PATH
@@ -294,6 +313,7 @@ Namespace Editors
Me.TXT_GLOBAL_PATH.CaptionToolTipEnabled = True
Me.TXT_GLOBAL_PATH.CaptionToolTipText = "Root path for storing users' data"
Me.TXT_GLOBAL_PATH.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_GLOBAL_PATH.Lines = New String(-1) {}
Me.TXT_GLOBAL_PATH.Location = New System.Drawing.Point(4, 4)
Me.TXT_GLOBAL_PATH.Name = "TXT_GLOBAL_PATH"
Me.TXT_GLOBAL_PATH.Size = New System.Drawing.Size(562, 22)
@@ -323,6 +343,7 @@ Namespace Editors
Me.TXT_IMAGE_LARGE.CaptionToolTipText = "Maximum large image size by height"
Me.TXT_IMAGE_LARGE.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_IMAGE_LARGE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_IMAGE_LARGE.Lines = New String(-1) {}
Me.TXT_IMAGE_LARGE.Location = New System.Drawing.Point(3, 3)
Me.TXT_IMAGE_LARGE.Name = "TXT_IMAGE_LARGE"
Me.TXT_IMAGE_LARGE.NumberMaximum = New Decimal(New Integer() {256, 0, 0, 0})
@@ -339,6 +360,7 @@ Namespace Editors
Me.TXT_IMAGE_SMALL.CaptionToolTipText = "Maximum small image size by height"
Me.TXT_IMAGE_SMALL.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_IMAGE_SMALL.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_IMAGE_SMALL.Lines = New String(-1) {}
Me.TXT_IMAGE_SMALL.Location = New System.Drawing.Point(287, 3)
Me.TXT_IMAGE_SMALL.Name = "TXT_IMAGE_SMALL"
Me.TXT_IMAGE_SMALL.NumberMaximum = New Decimal(New Integer() {256, 0, 0, 0})
@@ -357,6 +379,7 @@ Namespace Editors
Me.TXT_COLLECTIONS_PATH.CaptionToolTipEnabled = True
Me.TXT_COLLECTIONS_PATH.CaptionToolTipText = "Set collections folder name (name only)"
Me.TXT_COLLECTIONS_PATH.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_COLLECTIONS_PATH.Lines = New String(-1) {}
Me.TXT_COLLECTIONS_PATH.Location = New System.Drawing.Point(4, 62)
Me.TXT_COLLECTIONS_PATH.Name = "TXT_COLLECTIONS_PATH"
Me.TXT_COLLECTIONS_PATH.Size = New System.Drawing.Size(562, 22)
@@ -373,6 +396,7 @@ Namespace Editors
Me.TXT_MAX_JOBS_USERS.CaptionWidth = 50.0R
Me.TXT_MAX_JOBS_USERS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_MAX_JOBS_USERS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_MAX_JOBS_USERS.Lines = New String(-1) {}
Me.TXT_MAX_JOBS_USERS.Location = New System.Drawing.Point(4, 91)
Me.TXT_MAX_JOBS_USERS.Name = "TXT_MAX_JOBS_USERS"
Me.TXT_MAX_JOBS_USERS.NumberMinimum = New Decimal(New Integer() {1, 0, 0, 0})
@@ -392,6 +416,7 @@ Namespace Editors
Me.TXT_MAX_JOBS_CHANNELS.CaptionWidth = 50.0R
Me.TXT_MAX_JOBS_CHANNELS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_MAX_JOBS_CHANNELS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_MAX_JOBS_CHANNELS.Lines = New String(-1) {}
Me.TXT_MAX_JOBS_CHANNELS.Location = New System.Drawing.Point(4, 120)
Me.TXT_MAX_JOBS_CHANNELS.Name = "TXT_MAX_JOBS_CHANNELS"
Me.TXT_MAX_JOBS_CHANNELS.NumberMinimum = New Decimal(New Integer() {1, 0, 0, 0})
@@ -418,19 +443,20 @@ Namespace Editors
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)
Me.TXT_IMGUR_CLIENT_ID.Lines = New String(-1) {}
Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 262)
Me.TXT_IMGUR_CLIENT_ID.Name = "TXT_IMGUR_CLIENT_ID"
Me.TXT_IMGUR_CLIENT_ID.Size = New System.Drawing.Size(562, 22)
Me.TXT_IMGUR_CLIENT_ID.TabIndex = 7
Me.TXT_IMGUR_CLIENT_ID.TabIndex = 9
'
'CH_SHOW_GROUPS
'
Me.CH_SHOW_GROUPS.AutoSize = True
Me.CH_SHOW_GROUPS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_SHOW_GROUPS.Location = New System.Drawing.Point(4, 288)
Me.CH_SHOW_GROUPS.Location = New System.Drawing.Point(4, 372)
Me.CH_SHOW_GROUPS.Name = "CH_SHOW_GROUPS"
Me.CH_SHOW_GROUPS.Size = New System.Drawing.Size(562, 19)
Me.CH_SHOW_GROUPS.TabIndex = 10
Me.CH_SHOW_GROUPS.TabIndex = 13
Me.CH_SHOW_GROUPS.Text = "Show groups"
TT_MAIN.SetToolTip(Me.CH_SHOW_GROUPS, "Grouping users by site")
Me.CH_SHOW_GROUPS.UseVisualStyleBackColor = True
@@ -439,10 +465,10 @@ Namespace Editors
'
Me.CH_USERS_GROUPING.AutoSize = True
Me.CH_USERS_GROUPING.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_USERS_GROUPING.Location = New System.Drawing.Point(4, 314)
Me.CH_USERS_GROUPING.Location = New System.Drawing.Point(4, 398)
Me.CH_USERS_GROUPING.Name = "CH_USERS_GROUPING"
Me.CH_USERS_GROUPING.Size = New System.Drawing.Size(562, 19)
Me.CH_USERS_GROUPING.TabIndex = 11
Me.CH_USERS_GROUPING.TabIndex = 14
Me.CH_USERS_GROUPING.Text = "Use user grouping"
TT_MAIN.SetToolTip(Me.CH_USERS_GROUPING, "Group users by groups and/or labels")
Me.CH_USERS_GROUPING.UseVisualStyleBackColor = True
@@ -461,10 +487,11 @@ Namespace Editors
Me.TXT_USER_AGENT.CaptionToolTipEnabled = True
Me.TXT_USER_AGENT.CaptionToolTipText = "Default user agent to use in requests"
Me.TXT_USER_AGENT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_USER_AGENT.Location = New System.Drawing.Point(4, 175)
Me.TXT_USER_AGENT.Lines = New String(-1) {}
Me.TXT_USER_AGENT.Location = New System.Drawing.Point(4, 233)
Me.TXT_USER_AGENT.Name = "TXT_USER_AGENT"
Me.TXT_USER_AGENT.Size = New System.Drawing.Size(562, 22)
Me.TXT_USER_AGENT.TabIndex = 6
Me.TXT_USER_AGENT.TabIndex = 8
'
'TXT_USER_LIST_IMAGE
'
@@ -480,10 +507,11 @@ Namespace Editors
Me.TXT_USER_LIST_IMAGE.CaptionToolTipEnabled = True
Me.TXT_USER_LIST_IMAGE.CaptionToolTipText = "Background image for user list"
Me.TXT_USER_LIST_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_USER_LIST_IMAGE.Location = New System.Drawing.Point(4, 233)
Me.TXT_USER_LIST_IMAGE.Lines = New String(-1) {}
Me.TXT_USER_LIST_IMAGE.Location = New System.Drawing.Point(4, 291)
Me.TXT_USER_LIST_IMAGE.Name = "TXT_USER_LIST_IMAGE"
Me.TXT_USER_LIST_IMAGE.Size = New System.Drawing.Size(562, 22)
Me.TXT_USER_LIST_IMAGE.TabIndex = 8
Me.TXT_USER_LIST_IMAGE.TabIndex = 10
'
'COLORS_USERLIST
'
@@ -491,12 +519,57 @@ Namespace Editors
Me.COLORS_USERLIST.CaptionText = "Userlist colors"
Me.COLORS_USERLIST.CaptionWidth = 103
Me.COLORS_USERLIST.Dock = System.Windows.Forms.DockStyle.Fill
Me.COLORS_USERLIST.Location = New System.Drawing.Point(1, 259)
Me.COLORS_USERLIST.Location = New System.Drawing.Point(1, 317)
Me.COLORS_USERLIST.Margin = New System.Windows.Forms.Padding(0)
Me.COLORS_USERLIST.Name = "COLORS_USERLIST"
Me.COLORS_USERLIST.Padding = New System.Windows.Forms.Padding(0, 0, 2, 0)
Me.COLORS_USERLIST.Size = New System.Drawing.Size(568, 25)
Me.COLORS_USERLIST.TabIndex = 9
Me.COLORS_USERLIST.TabIndex = 11
'
'COLORS_SUBSCRIPTIONS
'
Me.COLORS_SUBSCRIPTIONS.ButtonsMargin = New System.Windows.Forms.Padding(1, 2, 1, 2)
Me.COLORS_SUBSCRIPTIONS.CaptionText = "Subscriptions color"
Me.COLORS_SUBSCRIPTIONS.CaptionWidth = 103
Me.COLORS_SUBSCRIPTIONS.Dock = System.Windows.Forms.DockStyle.Fill
Me.COLORS_SUBSCRIPTIONS.Location = New System.Drawing.Point(1, 343)
Me.COLORS_SUBSCRIPTIONS.Margin = New System.Windows.Forms.Padding(0)
Me.COLORS_SUBSCRIPTIONS.Name = "COLORS_SUBSCRIPTIONS"
Me.COLORS_SUBSCRIPTIONS.Padding = New System.Windows.Forms.Padding(0, 0, 2, 0)
Me.COLORS_SUBSCRIPTIONS.Size = New System.Drawing.Size(568, 25)
Me.COLORS_SUBSCRIPTIONS.TabIndex = 12
'
'TXT_PRG_TITLE
'
ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image)
ActionButton11.Name = "Clear"
ActionButton11.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_TITLE.Buttons.Add(ActionButton11)
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"
Me.TXT_PRG_TITLE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_PRG_TITLE.Lines = New String(-1) {}
Me.TXT_PRG_TITLE.Location = New System.Drawing.Point(4, 175)
Me.TXT_PRG_TITLE.Name = "TXT_PRG_TITLE"
Me.TXT_PRG_TITLE.Size = New System.Drawing.Size(562, 22)
Me.TXT_PRG_TITLE.TabIndex = 6
'
'TXT_PRG_DESCR
'
ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image)
ActionButton12.Name = "Clear"
ActionButton12.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_DESCR.Buttons.Add(ActionButton12)
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"
Me.TXT_PRG_DESCR.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_PRG_DESCR.Lines = New String(-1) {}
Me.TXT_PRG_DESCR.Location = New System.Drawing.Point(4, 204)
Me.TXT_PRG_DESCR.Name = "TXT_PRG_DESCR"
Me.TXT_PRG_DESCR.Size = New System.Drawing.Size(562, 22)
Me.TXT_PRG_DESCR.TabIndex = 7
'
'TP_FILE_NAME
'
@@ -930,11 +1003,11 @@ Namespace Editors
'
Me.CH_STD_YT_LOAD.AutoSize = True
Me.CH_STD_YT_LOAD.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_LOAD.Location = New System.Drawing.Point(4, 166)
Me.CH_STD_YT_LOAD.Location = New System.Drawing.Point(4, 218)
Me.CH_STD_YT_LOAD.Name = "CH_STD_YT_LOAD"
Me.CH_STD_YT_LOAD.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_LOAD.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_LOAD.TabIndex = 6
Me.CH_STD_YT_LOAD.TabIndex = 8
Me.CH_STD_YT_LOAD.Text = "Load downloaded YouTube videos to the form"
TT_MAIN.SetToolTip(Me.CH_STD_YT_LOAD, "If checked, downloaded YouTube videos will be loaded to the form. Otherwise, all " &
"downloaded data will be loaded to the form except YouTube data.")
@@ -944,16 +1017,92 @@ Namespace Editors
'
Me.CH_STD_YT_REMOVE.AutoSize = True
Me.CH_STD_YT_REMOVE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_REMOVE.Location = New System.Drawing.Point(4, 192)
Me.CH_STD_YT_REMOVE.Location = New System.Drawing.Point(4, 244)
Me.CH_STD_YT_REMOVE.Name = "CH_STD_YT_REMOVE"
Me.CH_STD_YT_REMOVE.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_REMOVE.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_REMOVE.TabIndex = 7
Me.CH_STD_YT_REMOVE.TabIndex = 9
Me.CH_STD_YT_REMOVE.Text = "Clear YouTube videos when clearing the list"
TT_MAIN.SetToolTip(Me.CH_STD_YT_REMOVE, "If checked, YouTube videos will also be removed from the list. This action will a" &
"lso affect the standalone 'YouTubeDownloader' app.")
Me.CH_STD_YT_REMOVE.UseVisualStyleBackColor = True
'
'CH_FEED_OPEN_LAST_MODE
'
Me.CH_FEED_OPEN_LAST_MODE.AutoSize = True
Me.CH_FEED_OPEN_LAST_MODE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_OPEN_LAST_MODE.Location = New System.Drawing.Point(4, 192)
Me.CH_FEED_OPEN_LAST_MODE.Name = "CH_FEED_OPEN_LAST_MODE"
Me.CH_FEED_OPEN_LAST_MODE.Size = New System.Drawing.Size(568, 19)
Me.CH_FEED_OPEN_LAST_MODE.TabIndex = 7
Me.CH_FEED_OPEN_LAST_MODE.Text = "Open last mode (users or subscriptions)"
TT_MAIN.SetToolTip(Me.CH_FEED_OPEN_LAST_MODE, "If disabled, the user mode will be used when initializing the feed.")
Me.CH_FEED_OPEN_LAST_MODE.UseVisualStyleBackColor = True
'
'CH_STD_YT_OUTPUT_ASK_NAME
'
Me.CH_STD_YT_OUTPUT_ASK_NAME.AutoSize = True
Me.CH_STD_YT_OUTPUT_ASK_NAME.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_OUTPUT_ASK_NAME.Location = New System.Drawing.Point(4, 270)
Me.CH_STD_YT_OUTPUT_ASK_NAME.Name = "CH_STD_YT_OUTPUT_ASK_NAME"
Me.CH_STD_YT_OUTPUT_ASK_NAME.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_OUTPUT_ASK_NAME.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_OUTPUT_ASK_NAME.TabIndex = 10
Me.CH_STD_YT_OUTPUT_ASK_NAME.Text = "Output path: ask for a name"
TT_MAIN.SetToolTip(Me.CH_STD_YT_OUTPUT_ASK_NAME, "Ask for a name when adding a new output path to the list.")
Me.CH_STD_YT_OUTPUT_ASK_NAME.UseVisualStyleBackColor = True
'
'CH_STD_YT_OUTPUT_AUTO_ADD
'
Me.CH_STD_YT_OUTPUT_AUTO_ADD.AutoSize = True
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Location = New System.Drawing.Point(4, 296)
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Name = "CH_STD_YT_OUTPUT_AUTO_ADD"
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_OUTPUT_AUTO_ADD.TabIndex = 11
Me.CH_STD_YT_OUTPUT_AUTO_ADD.Text = "Output path: auto add"
TT_MAIN.SetToolTip(Me.CH_STD_YT_OUTPUT_AUTO_ADD, "Add new paths to the list automatically.")
Me.CH_STD_YT_OUTPUT_AUTO_ADD.UseVisualStyleBackColor = True
'
'BTT_RESET_DOWNLOAD_LOCATIONS
'
Me.BTT_RESET_DOWNLOAD_LOCATIONS.Dock = System.Windows.Forms.DockStyle.Right
Me.BTT_RESET_DOWNLOAD_LOCATIONS.Location = New System.Drawing.Point(382, 322)
Me.BTT_RESET_DOWNLOAD_LOCATIONS.Name = "BTT_RESET_DOWNLOAD_LOCATIONS"
Me.BTT_RESET_DOWNLOAD_LOCATIONS.Size = New System.Drawing.Size(190, 22)
Me.BTT_RESET_DOWNLOAD_LOCATIONS.TabIndex = 12
Me.BTT_RESET_DOWNLOAD_LOCATIONS.Text = "Reset download locations"
TT_MAIN.SetToolTip(Me.BTT_RESET_DOWNLOAD_LOCATIONS, "All saved download locations will be deleted")
Me.BTT_RESET_DOWNLOAD_LOCATIONS.UseVisualStyleBackColor = True
'
'CH_STD_SNAP_KEEP_WITH_FILES
'
Me.CH_STD_SNAP_KEEP_WITH_FILES.AutoSize = True
Me.CH_STD_SNAP_KEEP_WITH_FILES.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_SNAP_KEEP_WITH_FILES.Location = New System.Drawing.Point(4, 140)
Me.CH_STD_SNAP_KEEP_WITH_FILES.Name = "CH_STD_SNAP_KEEP_WITH_FILES"
Me.CH_STD_SNAP_KEEP_WITH_FILES.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_SNAP_KEEP_WITH_FILES.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_SNAP_KEEP_WITH_FILES.TabIndex = 5
Me.CH_STD_SNAP_KEEP_WITH_FILES.Text = "Keep video thumbnail with files"
TT_MAIN.SetToolTip(Me.CH_STD_SNAP_KEEP_WITH_FILES, "Only works with 'Create video thumbnail'.")
Me.CH_STD_SNAP_KEEP_WITH_FILES.UseVisualStyleBackColor = True
'
'CH_STD_SNAP_CACHE_PERMANENT
'
Me.CH_STD_SNAP_CACHE_PERMANENT.AutoSize = True
Me.CH_STD_SNAP_CACHE_PERMANENT.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_SNAP_CACHE_PERMANENT.Location = New System.Drawing.Point(4, 166)
Me.CH_STD_SNAP_CACHE_PERMANENT.Name = "CH_STD_SNAP_CACHE_PERMANENT"
Me.CH_STD_SNAP_CACHE_PERMANENT.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_SNAP_CACHE_PERMANENT.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_SNAP_CACHE_PERMANENT.TabIndex = 6
Me.CH_STD_SNAP_CACHE_PERMANENT.Text = "Leave the thumbnails cache"
TT_MAIN.SetToolTip(Me.CH_STD_SNAP_CACHE_PERMANENT, "If disabled, video thumbnails will be deleted after SCrawler closes." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Only works " &
"with 'Create video thumbnail' and 'Keep video thumbnail with files'.")
Me.CH_STD_SNAP_CACHE_PERMANENT.UseVisualStyleBackColor = True
'
'TP_CHANNELS_IMGS
'
TP_CHANNELS_IMGS.ColumnCount = 2
@@ -978,6 +1127,7 @@ Namespace Editors
Me.TXT_CHANNELS_ROWS.CaptionToolTipText = "How many lines of images should be shown in the channels form"
Me.TXT_CHANNELS_ROWS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_CHANNELS_ROWS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CHANNELS_ROWS.Lines = New String(-1) {}
Me.TXT_CHANNELS_ROWS.Location = New System.Drawing.Point(3, 3)
Me.TXT_CHANNELS_ROWS.Name = "TXT_CHANNELS_ROWS"
Me.TXT_CHANNELS_ROWS.Size = New System.Drawing.Size(278, 22)
@@ -992,6 +1142,7 @@ Namespace Editors
Me.TXT_CHANNELS_COLUMNS.CaptionToolTipText = "How many columns of images should be shown in the channels form"
Me.TXT_CHANNELS_COLUMNS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_CHANNELS_COLUMNS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CHANNELS_COLUMNS.Lines = New String(-1) {}
Me.TXT_CHANNELS_COLUMNS.Location = New System.Drawing.Point(287, 3)
Me.TXT_CHANNELS_COLUMNS.Name = "TXT_CHANNELS_COLUMNS"
Me.TXT_CHANNELS_COLUMNS.Size = New System.Drawing.Size(278, 22)
@@ -1005,7 +1156,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, 368)
TAB_BASIS.Size = New System.Drawing.Size(576, 451)
TAB_BASIS.TabIndex = 0
TAB_BASIS.Text = "Basis"
'
@@ -1015,7 +1166,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, 368)
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 451)
TAB_DEFAULTS.TabIndex = 1
TAB_DEFAULTS.Text = "Defaults"
'
@@ -1041,7 +1192,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, 362)
TP_DEFS.Size = New System.Drawing.Size(570, 445)
TP_DEFS.TabIndex = 0
'
'CH_DOWN_IMAGES_NATIVE
@@ -1061,7 +1212,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, 368)
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 451)
TAB_DEFS_CHANNELS.TabIndex = 4
TAB_DEFS_CHANNELS.Text = "Channels"
'
@@ -1085,7 +1236,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, 362)
TP_CHANNELS.Size = New System.Drawing.Size(570, 445)
TP_CHANNELS.TabIndex = 0
'
'TXT_CHANNEL_USER_POST_LIMIT
@@ -1099,6 +1250,7 @@ Namespace Editors
Me.TXT_CHANNEL_USER_POST_LIMIT.CaptionWidth = 50.0R
Me.TXT_CHANNEL_USER_POST_LIMIT.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_CHANNEL_USER_POST_LIMIT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CHANNEL_USER_POST_LIMIT.Lines = New String(-1) {}
Me.TXT_CHANNEL_USER_POST_LIMIT.Location = New System.Drawing.Point(4, 33)
Me.TXT_CHANNEL_USER_POST_LIMIT.Name = "TXT_CHANNEL_USER_POST_LIMIT"
Me.TXT_CHANNEL_USER_POST_LIMIT.NumberMaximum = New Decimal(New Integer() {1000, 0, 0, 0})
@@ -1113,7 +1265,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, 368)
TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 451)
TAB_BEHAVIOR.TabIndex = 5
TAB_BEHAVIOR.Text = "Behavior"
'
@@ -1144,23 +1296,24 @@ 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, 368)
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 451)
TP_BEHAVIOR.TabIndex = 0
'
'TXT_FOLDER_CMD
'
Me.TXT_FOLDER_CMD.AutoShowClearButton = True
ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image)
ActionButton11.Enabled = False
ActionButton11.Name = "Clear"
ActionButton11.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton11)
ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image)
ActionButton13.Enabled = False
ActionButton13.Name = "Clear"
ActionButton13.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton13)
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
Me.TXT_FOLDER_CMD.CaptionToolTipText = "The command to open a folder."
Me.TXT_FOLDER_CMD.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FOLDER_CMD.LeaveDefaultButtons = True
Me.TXT_FOLDER_CMD.Lines = New String(-1) {}
Me.TXT_FOLDER_CMD.Location = New System.Drawing.Point(4, 160)
Me.TXT_FOLDER_CMD.Name = "TXT_FOLDER_CMD"
Me.TXT_FOLDER_CMD.PlaceholderEnabled = True
@@ -1193,17 +1346,18 @@ Namespace Editors
'TXT_CLOSE_SCRIPT
'
Me.TXT_CLOSE_SCRIPT.AutoShowClearButton = True
ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image)
ActionButton12.Enabled = False
ActionButton12.Name = "Clear"
ActionButton12.Visible = False
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton12)
ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image)
ActionButton14.Enabled = False
ActionButton14.Name = "Clear"
ActionButton14.Visible = False
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton14)
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
Me.TXT_CLOSE_SCRIPT.CaptionToolTipText = "This command will be executed when SCrawler is closed"
Me.TXT_CLOSE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CLOSE_SCRIPT.LeaveDefaultButtons = True
Me.TXT_CLOSE_SCRIPT.Lines = New String(-1) {}
Me.TXT_CLOSE_SCRIPT.Location = New System.Drawing.Point(4, 189)
Me.TXT_CLOSE_SCRIPT.Name = "TXT_CLOSE_SCRIPT"
Me.TXT_CLOSE_SCRIPT.PlaceholderEnabled = True
@@ -1285,7 +1439,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, 368)
TAB_DOWN.Size = New System.Drawing.Size(576, 451)
TAB_DOWN.TabIndex = 6
TAB_DOWN.Text = "Downloading"
'
@@ -1317,17 +1471,17 @@ Namespace Editors
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, 368)
TP_DOWNLOADING.Size = New System.Drawing.Size(576, 451)
TP_DOWNLOADING.TabIndex = 1
'
'TXT_SCRIPT
'
ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image)
ActionButton13.Name = "Open"
ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image)
ActionButton14.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton13)
Me.TXT_SCRIPT.Buttons.Add(ActionButton14)
ActionButton15.BackgroundImage = CType(resources.GetObject("ActionButton15.BackgroundImage"), System.Drawing.Image)
ActionButton15.Name = "Open"
ActionButton16.BackgroundImage = CType(resources.GetObject("ActionButton16.BackgroundImage"), System.Drawing.Image)
ActionButton16.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton15)
Me.TXT_SCRIPT.Buttons.Add(ActionButton16)
Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SCRIPT.CaptionText = "Script"
Me.TXT_SCRIPT.CaptionToolTipEnabled = True
@@ -1336,6 +1490,7 @@ Namespace Editors
Me.TXT_SCRIPT.CaptionWidth = 120.0R
Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False
Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SCRIPT.Lines = New String(-1) {}
Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 144)
Me.TXT_SCRIPT.Name = "TXT_SCRIPT"
Me.TXT_SCRIPT.PlaceholderEnabled = True
@@ -1351,6 +1506,7 @@ Namespace Editors
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipText = "This command will be executed after all downloads are completed"
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionWidth = 120.0R
Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_DOWN_COMPLETE_SCRIPT.Lines = New String(-1) {}
Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 173)
Me.TXT_DOWN_COMPLETE_SCRIPT.Name = "TXT_DOWN_COMPLETE_SCRIPT"
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True
@@ -1387,12 +1543,23 @@ Namespace Editors
Me.CH_UNAME_UP.Text = "Update user site name every time"
Me.CH_UNAME_UP.UseVisualStyleBackColor = True
'
'CH_UICON_UP
'
Me.CH_UICON_UP.AutoSize = True
Me.CH_UICON_UP.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_UICON_UP.Location = New System.Drawing.Point(4, 56)
Me.CH_UICON_UP.Name = "CH_UICON_UP"
Me.CH_UICON_UP.Size = New System.Drawing.Size(568, 19)
Me.CH_UICON_UP.TabIndex = 2
Me.CH_UICON_UP.Text = "Update user icon and banner every time (where supported)"
Me.CH_UICON_UP.UseVisualStyleBackColor = True
'
'TAB_FEED
'
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, 368)
TAB_FEED.Size = New System.Drawing.Size(576, 451)
TAB_FEED.TabIndex = 7
TAB_FEED.Text = "Feed"
'
@@ -1408,10 +1575,12 @@ Namespace Editors
TP_FEED.Controls.Add(Me.CH_FEED_STORE_SESSION_DATA, 0, 6)
TP_FEED.Controls.Add(Me.TXT_FEED_CENTER_IMAGE, 0, 1)
TP_FEED.Controls.Add(Me.COLORS_FEED, 0, 2)
TP_FEED.Controls.Add(Me.CH_FEED_OPEN_LAST_MODE, 0, 7)
TP_FEED.Controls.Add(Me.CH_FEED_SHOW_FRIENDLY, 0, 8)
TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill
TP_FEED.Location = New System.Drawing.Point(0, 0)
TP_FEED.Name = "TP_FEED"
TP_FEED.RowCount = 8
TP_FEED.RowCount = 10
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
@@ -1419,9 +1588,10 @@ 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.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.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_FEED.Size = New System.Drawing.Size(576, 368)
TP_FEED.Size = New System.Drawing.Size(576, 451)
TP_FEED.TabIndex = 0
'
'TP_FEED_IMG_COUNT
@@ -1448,6 +1618,7 @@ Namespace Editors
Me.TXT_FEED_ROWS.CaptionToolTipText = "How many lines of images should be shown in the feed form"
Me.TXT_FEED_ROWS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_FEED_ROWS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FEED_ROWS.Lines = New String(-1) {}
Me.TXT_FEED_ROWS.Location = New System.Drawing.Point(3, 3)
Me.TXT_FEED_ROWS.Name = "TXT_FEED_ROWS"
Me.TXT_FEED_ROWS.NumberMaximum = New Decimal(New Integer() {50, 0, 0, 0})
@@ -1464,6 +1635,7 @@ Namespace Editors
Me.TXT_FEED_COLUMNS.CaptionToolTipText = "How many columns of images should be shown in the feed form"
Me.TXT_FEED_COLUMNS.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_FEED_COLUMNS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FEED_COLUMNS.Lines = New String(-1) {}
Me.TXT_FEED_COLUMNS.Location = New System.Drawing.Point(290, 3)
Me.TXT_FEED_COLUMNS.Name = "TXT_FEED_COLUMNS"
Me.TXT_FEED_COLUMNS.NumberMaximum = New Decimal(New Integer() {20, 0, 0, 0})
@@ -1517,6 +1689,7 @@ Namespace Editors
Me.TXT_FEED_CENTER_IMAGE.CaptionWidth = 50.0R
Me.TXT_FEED_CENTER_IMAGE.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_FEED_CENTER_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FEED_CENTER_IMAGE.Lines = New String(-1) {}
Me.TXT_FEED_CENTER_IMAGE.Location = New System.Drawing.Point(4, 33)
Me.TXT_FEED_CENTER_IMAGE.Margin = New System.Windows.Forms.Padding(3, 3, 2, 3)
Me.TXT_FEED_CENTER_IMAGE.Name = "TXT_FEED_CENTER_IMAGE"
@@ -1543,7 +1716,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, 368)
TAB_NOTIFY.Size = New System.Drawing.Size(576, 451)
TAB_NOTIFY.TabIndex = 8
TAB_NOTIFY.Text = "Notifications"
'
@@ -1573,7 +1746,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, 368)
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 451)
TP_NOTIFY_MAIN.TabIndex = 0
'
'TP_ENVIR
@@ -1596,24 +1769,25 @@ 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, 368)
TP_ENVIR.Size = New System.Drawing.Size(576, 451)
TP_ENVIR.TabIndex = 0
'
'TXT_YTDLP
'
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_YTDLP.Buttons.Add(ActionButton15)
Me.TXT_YTDLP.Buttons.Add(ActionButton16)
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_YTDLP.Buttons.Add(ActionButton17)
Me.TXT_YTDLP.Buttons.Add(ActionButton18)
Me.TXT_YTDLP.CaptionText = "yt-dlp"
Me.TXT_YTDLP.CaptionToolTipEnabled = True
Me.TXT_YTDLP.CaptionToolTipText = "Path to yt-dlp.exe file"
Me.TXT_YTDLP.CaptionWidth = 80.0R
Me.TXT_YTDLP.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_YTDLP.Lines = New String(-1) {}
Me.TXT_YTDLP.Location = New System.Drawing.Point(4, 62)
Me.TXT_YTDLP.Name = "TXT_YTDLP"
Me.TXT_YTDLP.Size = New System.Drawing.Size(568, 22)
@@ -1622,19 +1796,20 @@ Namespace Editors
'
'TXT_FFMPEG
'
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_FFMPEG.Buttons.Add(ActionButton17)
Me.TXT_FFMPEG.Buttons.Add(ActionButton18)
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_FFMPEG.Buttons.Add(ActionButton19)
Me.TXT_FFMPEG.Buttons.Add(ActionButton20)
Me.TXT_FFMPEG.CaptionText = "ffmpeg"
Me.TXT_FFMPEG.CaptionToolTipEnabled = True
Me.TXT_FFMPEG.CaptionToolTipText = "Path to ffmpeg.exe file"
Me.TXT_FFMPEG.CaptionWidth = 80.0R
Me.TXT_FFMPEG.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FFMPEG.Lines = New String(-1) {}
Me.TXT_FFMPEG.Location = New System.Drawing.Point(4, 4)
Me.TXT_FFMPEG.Name = "TXT_FFMPEG"
Me.TXT_FFMPEG.Size = New System.Drawing.Size(568, 22)
@@ -1643,19 +1818,20 @@ Namespace Editors
'
'TXT_CURL
'
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_CURL.Buttons.Add(ActionButton19)
Me.TXT_CURL.Buttons.Add(ActionButton20)
ActionButton21.BackgroundImage = CType(resources.GetObject("ActionButton21.BackgroundImage"), System.Drawing.Image)
ActionButton21.Name = "Open"
ActionButton21.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton22.BackgroundImage = CType(resources.GetObject("ActionButton22.BackgroundImage"), System.Drawing.Image)
ActionButton22.Name = "Clear"
ActionButton22.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CURL.Buttons.Add(ActionButton21)
Me.TXT_CURL.Buttons.Add(ActionButton22)
Me.TXT_CURL.CaptionText = "cURL"
Me.TXT_CURL.CaptionToolTipEnabled = True
Me.TXT_CURL.CaptionToolTipText = "Path to curl.exe file"
Me.TXT_CURL.CaptionWidth = 80.0R
Me.TXT_CURL.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CURL.Lines = New String(-1) {}
Me.TXT_CURL.Location = New System.Drawing.Point(4, 33)
Me.TXT_CURL.Name = "TXT_CURL"
Me.TXT_CURL.Size = New System.Drawing.Size(568, 22)
@@ -1664,18 +1840,19 @@ Namespace Editors
'
'TXT_GALLERYDL
'
ActionButton21.BackgroundImage = CType(resources.GetObject("ActionButton21.BackgroundImage"), System.Drawing.Image)
ActionButton21.Name = "Open"
ActionButton21.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton22.BackgroundImage = CType(resources.GetObject("ActionButton22.BackgroundImage"), System.Drawing.Image)
ActionButton22.Name = "Clear"
ActionButton22.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_GALLERYDL.Buttons.Add(ActionButton21)
Me.TXT_GALLERYDL.Buttons.Add(ActionButton22)
ActionButton23.BackgroundImage = CType(resources.GetObject("ActionButton23.BackgroundImage"), System.Drawing.Image)
ActionButton23.Name = "Open"
ActionButton23.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton24.BackgroundImage = CType(resources.GetObject("ActionButton24.BackgroundImage"), System.Drawing.Image)
ActionButton24.Name = "Clear"
ActionButton24.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_GALLERYDL.Buttons.Add(ActionButton23)
Me.TXT_GALLERYDL.Buttons.Add(ActionButton24)
Me.TXT_GALLERYDL.CaptionText = "gallery-dl"
Me.TXT_GALLERYDL.CaptionToolTipText = "Path to gallery-dl.exe file"
Me.TXT_GALLERYDL.CaptionWidth = 80.0R
Me.TXT_GALLERYDL.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_GALLERYDL.Lines = New String(-1) {}
Me.TXT_GALLERYDL.Location = New System.Drawing.Point(4, 91)
Me.TXT_GALLERYDL.Name = "TXT_GALLERYDL"
Me.TXT_GALLERYDL.Size = New System.Drawing.Size(568, 22)
@@ -1684,19 +1861,20 @@ Namespace Editors
'
'TXT_CMD_ENCODING
'
ActionButton23.BackgroundImage = CType(resources.GetObject("ActionButton23.BackgroundImage"), System.Drawing.Image)
ActionButton23.Name = "Refresh"
ActionButton23.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton24.BackgroundImage = CType(resources.GetObject("ActionButton24.BackgroundImage"), System.Drawing.Image)
ActionButton24.Name = "Clear"
ActionButton24.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton23)
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton24)
ActionButton25.BackgroundImage = CType(resources.GetObject("ActionButton25.BackgroundImage"), System.Drawing.Image)
ActionButton25.Name = "Refresh"
ActionButton25.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton26.BackgroundImage = CType(resources.GetObject("ActionButton26.BackgroundImage"), System.Drawing.Image)
ActionButton26.Name = "Clear"
ActionButton26.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton25)
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton26)
Me.TXT_CMD_ENCODING.CaptionText = "CMD Encoding"
Me.TXT_CMD_ENCODING.CaptionToolTipEnabled = True
Me.TXT_CMD_ENCODING.CaptionToolTipText = "Command line encoding"
Me.TXT_CMD_ENCODING.CaptionWidth = 80.0R
Me.TXT_CMD_ENCODING.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CMD_ENCODING.Lines = New String(-1) {}
Me.TXT_CMD_ENCODING.Location = New System.Drawing.Point(4, 120)
Me.TXT_CMD_ENCODING.Name = "TXT_CMD_ENCODING"
Me.TXT_CMD_ENCODING.Size = New System.Drawing.Size(568, 22)
@@ -1707,7 +1885,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, 368)
TAB_STD.Size = New System.Drawing.Size(576, 451)
TAB_STD.TabIndex = 10
TAB_STD.Text = "Downloader"
'
@@ -1721,13 +1899,18 @@ Namespace Editors
TP_STD.Controls.Add(Me.CH_STD_AUTO_REMOVE, 0, 2)
TP_STD.Controls.Add(Me.CMB_STD_OPEN_DBL, 0, 3)
TP_STD.Controls.Add(Me.CH_STD_TAKESNAP, 0, 4)
TP_STD.Controls.Add(Me.CH_STD_UPDATE_YT_PATH, 0, 5)
TP_STD.Controls.Add(Me.CH_STD_YT_LOAD, 0, 6)
TP_STD.Controls.Add(Me.CH_STD_YT_REMOVE, 0, 7)
TP_STD.Controls.Add(Me.CH_STD_UPDATE_YT_PATH, 0, 7)
TP_STD.Controls.Add(Me.CH_STD_YT_LOAD, 0, 8)
TP_STD.Controls.Add(Me.CH_STD_YT_REMOVE, 0, 9)
TP_STD.Controls.Add(Me.CH_STD_YT_OUTPUT_ASK_NAME, 0, 10)
TP_STD.Controls.Add(Me.CH_STD_YT_OUTPUT_AUTO_ADD, 0, 11)
TP_STD.Controls.Add(Me.BTT_RESET_DOWNLOAD_LOCATIONS, 0, 12)
TP_STD.Controls.Add(Me.CH_STD_SNAP_KEEP_WITH_FILES, 0, 5)
TP_STD.Controls.Add(Me.CH_STD_SNAP_CACHE_PERMANENT, 0, 6)
TP_STD.Dock = System.Windows.Forms.DockStyle.Fill
TP_STD.Location = New System.Drawing.Point(0, 0)
TP_STD.Name = "TP_STD"
TP_STD.RowCount = 9
TP_STD.RowCount = 14
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.Absolute, 25.0!))
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
@@ -1736,8 +1919,13 @@ 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, 25.0!))
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, 25.0!))
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, 25.0!))
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, 368)
TP_STD.Size = New System.Drawing.Size(576, 451)
TP_STD.TabIndex = 0
'
'TXT_STD_MAX_JOBS_COUNT
@@ -1747,6 +1935,7 @@ Namespace Editors
Me.TXT_STD_MAX_JOBS_COUNT.CaptionToolTipText = "Maximum number of jobs"
Me.TXT_STD_MAX_JOBS_COUNT.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
Me.TXT_STD_MAX_JOBS_COUNT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_STD_MAX_JOBS_COUNT.Lines = New String(-1) {}
Me.TXT_STD_MAX_JOBS_COUNT.Location = New System.Drawing.Point(4, 4)
Me.TXT_STD_MAX_JOBS_COUNT.Name = "TXT_STD_MAX_JOBS_COUNT"
Me.TXT_STD_MAX_JOBS_COUNT.NumberMaximum = New Decimal(New Integer() {10, 0, 0, 0})
@@ -1782,10 +1971,10 @@ Namespace Editors
'
'CMB_STD_OPEN_DBL
'
ActionButton25.BackgroundImage = CType(resources.GetObject("ActionButton25.BackgroundImage"), System.Drawing.Image)
ActionButton25.Name = "ArrowDown"
ActionButton25.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton25)
ActionButton27.BackgroundImage = CType(resources.GetObject("ActionButton27.BackgroundImage"), System.Drawing.Image)
ActionButton27.Name = "ArrowDown"
ActionButton27.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton27)
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
@@ -1801,6 +1990,7 @@ Namespace Editors
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.Lines = New String(-1) {}
Me.CMB_STD_OPEN_DBL.Location = New System.Drawing.Point(4, 85)
Me.CMB_STD_OPEN_DBL.Name = "CMB_STD_OPEN_DBL"
Me.CMB_STD_OPEN_DBL.Size = New System.Drawing.Size(568, 22)
@@ -1823,11 +2013,11 @@ Namespace Editors
'
Me.CH_STD_UPDATE_YT_PATH.AutoSize = True
Me.CH_STD_UPDATE_YT_PATH.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_UPDATE_YT_PATH.Location = New System.Drawing.Point(4, 140)
Me.CH_STD_UPDATE_YT_PATH.Location = New System.Drawing.Point(4, 192)
Me.CH_STD_UPDATE_YT_PATH.Name = "CH_STD_UPDATE_YT_PATH"
Me.CH_STD_UPDATE_YT_PATH.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_UPDATE_YT_PATH.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_UPDATE_YT_PATH.TabIndex = 5
Me.CH_STD_UPDATE_YT_PATH.TabIndex = 7
Me.CH_STD_UPDATE_YT_PATH.Text = "Update the YouTube output path when you change the output path."
Me.CH_STD_UPDATE_YT_PATH.UseVisualStyleBackColor = True
'
@@ -1846,7 +2036,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, 394)
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 477)
Me.TAB_MAIN.TabIndex = 1
'
'TAB_ENVIR
@@ -1854,7 +2044,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, 368)
Me.TAB_ENVIR.Size = New System.Drawing.Size(576, 451)
Me.TAB_ENVIR.TabIndex = 9
Me.TAB_ENVIR.Text = "Environment"
'
@@ -1864,40 +2054,40 @@ Namespace Editors
'CONTAINER_MAIN.ContentPanel
'
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 394)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 477)
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 394)
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 477)
Me.CONTAINER_MAIN.TabIndex = 0
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'CH_UICON_UP
'CH_FEED_SHOW_FRIENDLY
'
Me.CH_UICON_UP.AutoSize = True
Me.CH_UICON_UP.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_UICON_UP.Location = New System.Drawing.Point(4, 56)
Me.CH_UICON_UP.Name = "CH_UICON_UP"
Me.CH_UICON_UP.Size = New System.Drawing.Size(568, 19)
Me.CH_UICON_UP.TabIndex = 2
Me.CH_UICON_UP.Text = "Update user icon and banner every time (where supported)"
Me.CH_UICON_UP.UseVisualStyleBackColor = True
Me.CH_FEED_SHOW_FRIENDLY.AutoSize = True
Me.CH_FEED_SHOW_FRIENDLY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_SHOW_FRIENDLY.Location = New System.Drawing.Point(4, 218)
Me.CH_FEED_SHOW_FRIENDLY.Name = "CH_FEED_SHOW_FRIENDLY"
Me.CH_FEED_SHOW_FRIENDLY.Size = New System.Drawing.Size(568, 19)
Me.CH_FEED_SHOW_FRIENDLY.TabIndex = 8
Me.CH_FEED_SHOW_FRIENDLY.Text = "Show friendly names instead of usernames"
Me.CH_FEED_SHOW_FRIENDLY.UseVisualStyleBackColor = True
'
'GlobalSettingsForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(584, 394)
Me.ClientSize = New System.Drawing.Size(584, 477)
Me.Controls.Add(Me.CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.Resources.SettingsIcon_48
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(600, 433)
Me.MaximumSize = New System.Drawing.Size(600, 516)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(600, 433)
Me.MinimumSize = New System.Drawing.Size(600, 516)
Me.Name = "GlobalSettingsForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
@@ -1914,6 +2104,8 @@ Namespace Editors
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_PRG_TITLE, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_PRG_DESCR, System.ComponentModel.ISupportInitialize).EndInit()
TP_FILE_NAME.ResumeLayout(False)
TP_FILE_NAME.PerformLayout()
TP_FILE_PATTERNS.ResumeLayout(False)
@@ -2056,5 +2248,15 @@ Namespace Editors
Private WithEvents CH_STD_YT_LOAD As CheckBox
Private WithEvents CH_STD_YT_REMOVE As CheckBox
Private WithEvents CH_UICON_UP As CheckBox
Private WithEvents COLORS_SUBSCRIPTIONS As ColorPicker
Private WithEvents CH_FEED_OPEN_LAST_MODE As CheckBox
Private WithEvents CH_STD_YT_OUTPUT_ASK_NAME As CheckBox
Private WithEvents CH_STD_YT_OUTPUT_AUTO_ADD As CheckBox
Private WithEvents BTT_RESET_DOWNLOAD_LOCATIONS As Button
Private WithEvents CH_STD_SNAP_KEEP_WITH_FILES As CheckBox
Private WithEvents CH_STD_SNAP_CACHE_PERMANENT As CheckBox
Private WithEvents TXT_PRG_TITLE As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_PRG_DESCR As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_FEED_SHOW_FRIENDLY As CheckBox
End Class
End Namespace

View File

@@ -238,6 +238,22 @@
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton12.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="TP_FILE_NAME.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
@@ -288,7 +304,7 @@ You can find more detailed information about the missing posts in the form that
<metadata name="TP_BEHAVIOR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
@@ -296,7 +312,7 @@ You can find more detailed information about the missing posts in the form that
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton12.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
@@ -316,7 +332,7 @@ You can find more detailed information about the missing posts in the form that
<metadata name="TP_DOWNLOADING.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton15.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
@@ -327,7 +343,7 @@ You can find more detailed information about the missing posts in the form that
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton16.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
@@ -356,25 +372,6 @@ You can find more detailed information about the missing posts in the form that
<metadata name="TP_ENVIR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton15.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton16.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton17.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
@@ -433,6 +430,25 @@ You can find more detailed information about the missing posts in the form that
</value>
</data>
<data name="ActionButton23.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton24.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton25.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
@@ -448,7 +464,7 @@ You can find more detailed information about the missing posts in the form that
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton24.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton26.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
@@ -462,7 +478,7 @@ You can find more detailed information about the missing posts in the form that
<metadata name="TP_STD.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton25.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton27.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL

View File

@@ -33,10 +33,14 @@ Namespace Editors
TXT_MAX_JOBS_USERS.Value = .MaxUsersJobsCount.Value
TXT_MAX_JOBS_CHANNELS.Value = .ChannelsMaxJobsCount.Value
CH_CHECK_VER_START.Checked = .CheckUpdatesAtStart
TXT_PRG_TITLE.Text = .ProgramText
TXT_PRG_DESCR.Text = .ProgramDescription
TXT_USER_AGENT.Text = .UserAgent
TXT_IMGUR_CLIENT_ID.Text = .ImgurClientID
TXT_USER_LIST_IMAGE.Text = .UserListImage.Value
COLORS_USERLIST.ColorsSet(.UserListBackColor, .UserListForeColor, SystemColors.Window, SystemColors.WindowText)
COLORS_SUBSCRIPTIONS.ColorsSet(.MainFrameUsersSubscriptionsColorBack, .MainFrameUsersSubscriptionsColorFore,
SystemColors.Window, SystemColors.WindowText)
CH_SHOW_GROUPS.Checked = .ShowGroups
CH_USERS_GROUPING.Checked = .UseGrouping
'Environment
@@ -83,9 +87,13 @@ Namespace Editors
CMB_STD_OPEN_DBL.EndUpdate(True)
CMB_STD_OPEN_DBL.SelectedIndex = [Enum].GetValues(GetType(StdDblClck)).ToObjectsList(Of StdDblClck).ToList.IndexOf(.STDownloader_OnItemDoubleClick.Value)
CH_STD_TAKESNAP.Checked = .STDownloader_TakeSnapshot
CH_STD_SNAP_KEEP_WITH_FILES.Checked = .STDownloader_SnapshotsKeepWithFiles
CH_STD_SNAP_CACHE_PERMANENT.Checked = .STDownloader_SnapShotsCachePermamnent
CH_STD_UPDATE_YT_PATH.Checked = .STDownloader_UpdateYouTubeOutputPath
CH_STD_YT_LOAD.Checked = .STDownloader_LoadYTVideos
CH_STD_YT_REMOVE.Checked = .STDownloader_RemoveYTVideosOnClear
CH_STD_YT_OUTPUT_ASK_NAME.Checked = .STDownloader_OutputPathAskForName
CH_STD_YT_OUTPUT_AUTO_ADD.Checked = .STDownloader_OutputPathAutoAddPaths
'Downloading
CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime
CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime
@@ -125,6 +133,8 @@ Namespace Editors
CH_FEED_ADD_SESSION.Checked = .FeedAddSessionToCaption
CH_FEED_ADD_DATE.Checked = .FeedAddDateToCaption
CH_FEED_STORE_SESSION_DATA.Checked = .FeedStoreSessionsData
CH_FEED_OPEN_LAST_MODE.Checked = .FeedOpenLastMode
CH_FEED_SHOW_FRIENDLY.Checked = .FeedShowFriendlyNames
End With
.MyFieldsChecker = New FieldsChecker
With .MyFieldsCheckerE
@@ -191,11 +201,14 @@ Namespace Editors
.MaxUsersJobsCount.Value = CInt(TXT_MAX_JOBS_USERS.Value)
.ChannelsMaxJobsCount.Value = TXT_MAX_JOBS_CHANNELS.Value
.CheckUpdatesAtStart.Value = CH_CHECK_VER_START.Checked
.ProgramText.Value = TXT_PRG_TITLE.Text
.ProgramDescription.Value = TXT_PRG_DESCR.Text
.UserAgent.Value = TXT_USER_AGENT.Text
DefaultUserAgent = TXT_USER_AGENT.Text
.ImgurClientID.Value = TXT_IMGUR_CLIENT_ID.Text
.UserListImage.Value = TXT_USER_LIST_IMAGE.Text
COLORS_USERLIST.ColorsGet(.UserListBackColor, .UserListForeColor)
COLORS_SUBSCRIPTIONS.ColorsGet(.MainFrameUsersSubscriptionsColorBack, .MainFrameUsersSubscriptionsColorFore)
.ShowGroups.Value = CH_SHOW_GROUPS.Checked
.UseGrouping.Value = CH_USERS_GROUPING.Checked
'Environment
@@ -239,9 +252,13 @@ Namespace Editors
.STDownloader_RemoveDownloadedAutomatically.Value = CH_STD_AUTO_REMOVE.Checked
.STDownloader_OnItemDoubleClick.Value = CInt(CMB_STD_OPEN_DBL.Value)
.STDownloader_TakeSnapshot.Value = CH_STD_TAKESNAP.Checked
.STDownloader_SnapshotsKeepWithFiles.Value = CH_STD_SNAP_KEEP_WITH_FILES.Checked
.STDownloader_SnapShotsCachePermamnent.Value = CH_STD_SNAP_CACHE_PERMANENT.Checked
.STDownloader_UpdateYouTubeOutputPath.Value = CH_STD_UPDATE_YT_PATH.Checked
.STDownloader_LoadYTVideos.Value = CH_STD_YT_LOAD.Checked
.STDownloader_RemoveYTVideosOnClear.Value = CH_STD_YT_REMOVE.Checked
.STDownloader_OutputPathAskForName.Value = CH_STD_YT_OUTPUT_ASK_NAME.Checked
.STDownloader_OutputPathAutoAddPaths.Value = CH_STD_YT_OUTPUT_AUTO_ADD.Checked
'Downloading
.UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked
.UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked
@@ -282,6 +299,8 @@ Namespace Editors
.FeedAddSessionToCaption.Value = CH_FEED_ADD_SESSION.Checked
.FeedAddDateToCaption.Value = CH_FEED_ADD_DATE.Checked
.FeedStoreSessionsData.Value = CH_FEED_STORE_SESSION_DATA.Checked
.FeedOpenLastMode.Value = CH_FEED_OPEN_LAST_MODE.Checked
.FeedShowFriendlyNames.Value = CH_FEED_SHOW_FRIENDLY.Checked
FeedParametersChanged = .FeedDataRows.ChangesDetected Or .FeedDataColumns.ChangesDetected Or
.FeedEndless.ChangesDetected Or .FeedStoreSessionsData.ChangesDetected Or
.FeedBackColor.ChangesDetected Or .FeedForeColor.ChangesDetected Or
@@ -364,5 +383,18 @@ Namespace Editors
Private Sub TXT_CMD_ENCODING_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_CMD_ENCODING.ActionOnButtonClick
If Sender.DefaultButton = ADB.Refresh Then TXT_CMD_ENCODING.Text = SettingsCLS.DefaultCmdEncoding
End Sub
Private Sub BTT_RESET_DOWNLOAD_LOCATIONS_Click(sender As Object, e As EventArgs) Handles BTT_RESET_DOWNLOAD_LOCATIONS.Click
Try
Const msgTitle$ = "Reset download locations"
If Settings.DownloadLocations.Count = 0 Then
MsgBoxE({"There are no saved download locations.", msgTitle})
ElseIf MsgBoxE({$"Are you sure you want to delete all ({Settings.DownloadLocations.Count}) download locations?", msgTitle},
vbExclamation + vbYesNo) = vbYes Then
Settings.DownloadLocations.Clear()
MsgBoxE({"All download locations deleted.", msgTitle})
End If
Catch
End Try
End Sub
End Class
End Namespace

View File

@@ -36,6 +36,7 @@ Namespace Editors
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 ActionButton9 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()
@@ -56,8 +57,9 @@ Namespace Editors
Me.TP_DOWN_IMG_VID = New System.Windows.Forms.TableLayoutPanel()
Me.CH_DOWN_IMAGES = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_VIDEOS = New System.Windows.Forms.CheckBox()
Me.TXT_SPEC_FOLDER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_SPEC_FOLDER = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.COLOR_USER = New SCrawler.Editors.ColorPicker()
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
@@ -105,10 +107,10 @@ Namespace Editors
'BTT_OTHER_SETTINGS
'
Me.BTT_OTHER_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(1, 1)
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(353, 1)
Me.BTT_OTHER_SETTINGS.Margin = New System.Windows.Forms.Padding(1)
Me.BTT_OTHER_SETTINGS.Name = "BTT_OTHER_SETTINGS"
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(101, 26)
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(98, 26)
Me.BTT_OTHER_SETTINGS.TabIndex = 1
Me.BTT_OTHER_SETTINGS.Text = "Options (F2)"
TT_MAIN.SetToolTip(Me.BTT_OTHER_SETTINGS, "Other settings")
@@ -139,17 +141,18 @@ Namespace Editors
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, 10)
Me.TP_MAIN.Controls.Add(Me.TXT_DESCR, 0, 11)
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.TXT_SPEC_FOLDER, 0, 2)
Me.TP_MAIN.Controls.Add(Me.TXT_SCRIPT, 0, 9)
Me.TP_MAIN.Controls.Add(Me.TXT_SCRIPT, 0, 10)
Me.TP_MAIN.Controls.Add(Me.COLOR_USER, 0, 9)
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 = 11
Me.TP_MAIN.RowCount = 12
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!))
@@ -160,6 +163,7 @@ Namespace Editors
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, 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.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.TabIndex = 0
@@ -167,7 +171,10 @@ Namespace Editors
'TXT_USER
'
Me.TXT_USER.CaptionText = "User name"
Me.TXT_USER.CaptionToolTipEnabled = True
Me.TXT_USER.CaptionToolTipText = "You must enter the user's URL in this field."
Me.TXT_USER.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_USER.Lines = New String(-1) {}
Me.TXT_USER.Location = New System.Drawing.Point(4, 4)
Me.TXT_USER.Name = "TXT_USER"
Me.TXT_USER.PlaceholderEnabled = True
@@ -178,11 +185,11 @@ Namespace Editors
'TP_SITE
'
Me.TP_SITE.ColumnCount = 2
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 103.0!))
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100.0!))
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.TP_SITE.Controls.Add(Me.CMB_SITE, 1, 0)
Me.TP_SITE.Controls.Add(Me.BTT_OTHER_SETTINGS, 0, 0)
Me.TP_SITE.Controls.Add(Me.CMB_SITE, 0, 0)
Me.TP_SITE.Controls.Add(Me.BTT_OTHER_SETTINGS, 1, 0)
Me.TP_SITE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_SITE.Location = New System.Drawing.Point(1, 88)
Me.TP_SITE.Margin = New System.Windows.Forms.Padding(0)
@@ -197,6 +204,16 @@ Namespace Editors
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "ArrowDown"
Me.CMB_SITE.Buttons.Add(ActionButton1)
Me.CMB_SITE.CaptionCheckAlign = System.Drawing.ContentAlignment.MiddleLeft
Me.CMB_SITE.CaptionMargin = New System.Windows.Forms.Padding(4, 3, 3, 3)
Me.CMB_SITE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.CMB_SITE.CaptionText = "Subscription"
Me.CMB_SITE.CaptionTextAlign = System.Drawing.ContentAlignment.MiddleLeft
Me.CMB_SITE.CaptionToolTipEnabled = True
Me.CMB_SITE.CaptionToolTipText = resources.GetString("CMB_SITE.CaptionToolTipText")
Me.CMB_SITE.CaptionVisible = True
Me.CMB_SITE.CaptionWidth = 103.0R
Me.CMB_SITE.ChangeControlsEnableOnCheckedChange = False
ListColumn1.Name = "_COL_KEY"
ListColumn1.Text = "Key"
ListColumn1.ValueMember = True
@@ -208,10 +225,11 @@ Namespace Editors
Me.CMB_SITE.Columns.Add(ListColumn1)
Me.CMB_SITE.Columns.Add(ListColumn2)
Me.CMB_SITE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_SITE.Location = New System.Drawing.Point(103, 3)
Me.CMB_SITE.Lines = New String(-1) {}
Me.CMB_SITE.Location = New System.Drawing.Point(0, 3)
Me.CMB_SITE.Margin = New System.Windows.Forms.Padding(0, 3, 3, 3)
Me.CMB_SITE.Name = "CMB_SITE"
Me.CMB_SITE.Size = New System.Drawing.Size(346, 22)
Me.CMB_SITE.Size = New System.Drawing.Size(349, 22)
Me.CMB_SITE.TabIndex = 0
Me.CMB_SITE.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
@@ -285,16 +303,18 @@ 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, 290)
Me.TXT_DESCR.Lines = New String(-1) {}
Me.TXT_DESCR.Location = New System.Drawing.Point(4, 317)
Me.TXT_DESCR.Multiline = True
Me.TXT_DESCR.Name = "TXT_DESCR"
Me.TXT_DESCR.Size = New System.Drawing.Size(446, 167)
Me.TXT_DESCR.TabIndex = 10
Me.TXT_DESCR.Size = New System.Drawing.Size(446, 140)
Me.TXT_DESCR.TabIndex = 11
'
'TXT_USER_FRIENDLY
'
Me.TXT_USER_FRIENDLY.CaptionText = "Friendly name"
Me.TXT_USER_FRIENDLY.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_USER_FRIENDLY.Lines = New String(-1) {}
Me.TXT_USER_FRIENDLY.Location = New System.Drawing.Point(4, 33)
Me.TXT_USER_FRIENDLY.Name = "TXT_USER_FRIENDLY"
Me.TXT_USER_FRIENDLY.Size = New System.Drawing.Size(446, 22)
@@ -351,6 +371,7 @@ 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.Lines = New String(-1) {}
Me.TXT_LABELS.Location = New System.Drawing.Point(4, 235)
Me.TXT_LABELS.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
Me.TXT_LABELS.Name = "TXT_LABELS"
@@ -406,38 +427,59 @@ Namespace Editors
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Name = "Clear"
ActionButton6.ToolTipText = "Clear"
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Name = "ArrowDown"
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.TXT_SPEC_FOLDER.Buttons.Add(ActionButton5)
Me.TXT_SPEC_FOLDER.Buttons.Add(ActionButton6)
Me.TXT_SPEC_FOLDER.Buttons.Add(ActionButton7)
Me.TXT_SPEC_FOLDER.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.TXT_SPEC_FOLDER.CaptionText = "Special path"
Me.TXT_SPEC_FOLDER.CaptionVisible = True
Me.TXT_SPEC_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SPEC_FOLDER.Lines = New String(-1) {}
Me.TXT_SPEC_FOLDER.Location = New System.Drawing.Point(4, 62)
Me.TXT_SPEC_FOLDER.Name = "TXT_SPEC_FOLDER"
Me.TXT_SPEC_FOLDER.Size = New System.Drawing.Size(446, 22)
Me.TXT_SPEC_FOLDER.TabIndex = 2
Me.TXT_SPEC_FOLDER.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'TXT_SCRIPT
'
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Enabled = False
ActionButton7.Name = "Open"
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Enabled = False
ActionButton8.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton7)
ActionButton8.Name = "Open"
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Enabled = False
ActionButton9.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton8)
Me.TXT_SCRIPT.Buttons.Add(ActionButton9)
Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SCRIPT.CaptionText = "Script"
Me.TXT_SCRIPT.CaptionToolTipEnabled = True
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, 262)
Me.TXT_SCRIPT.Lines = New String(-1) {}
Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 289)
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 = 9
Me.TXT_SCRIPT.TabIndex = 10
'
'COLOR_USER
'
Me.COLOR_USER.ButtonsMargin = New System.Windows.Forms.Padding(1)
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.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
'
'UserCreatorForm
'
@@ -492,7 +534,7 @@ Namespace Editors
Private WithEvents TXT_LABELS As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_DOWN_IMAGES As CheckBox
Private WithEvents CH_DOWN_VIDEOS As CheckBox
Private WithEvents TXT_SPEC_FOLDER As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_SPEC_FOLDER As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents CMB_SITE As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents BTT_OTHER_SETTINGS As Button
Private WithEvents TXT_SCRIPT As PersonalUtilities.Forms.Controls.TextBoxExtended
@@ -501,5 +543,6 @@ Namespace Editors
Private WithEvents TP_TEMP_FAV As TableLayoutPanel
Private WithEvents TP_READY_USERMEDIA As TableLayoutPanel
Private WithEvents TP_DOWN_IMG_VID As TableLayoutPanel
Private WithEvents COLOR_USER As ColorPicker
End Class
End Namespace

View File

@@ -216,6 +216,12 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
AAAASUVORK5CYII=
</value>
</data>
<data name="CMB_SITE.CaptionToolTipText" xml:space="preserve">
<value>Create a subscription instead of a user.
This mode means that files will not be downloaded. Instead, a video preview (screenshot) will be loaded. You can choose what to download, open a post, etc.
The download goes through a standalone downloader.
You can see downloaded subscriptions in the feed.</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
@@ -264,6 +270,96 @@
</value>
</data>
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
@@ -274,7 +370,7 @@
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go

View File

@@ -80,8 +80,26 @@ Namespace Editors
Return TXT_SCRIPT.Text
End Get
End Property
Friend ReadOnly Property IsSubscription As Boolean
Get
Return CMB_SITE.Checked
End Get
End Property
Private _UserBackColor As Color? = Nothing
Friend ReadOnly Property UserBackColor As Color?
Get
Return _UserBackColor
End Get
End Property
Private _UserForeColor As Color? = Nothing
Friend ReadOnly Property UserForeColor As Color?
Get
Return _UserForeColor
End Get
End Property
Private FriendlyNameIsSiteName As Boolean = False
Private FriendlyNameChanged As Boolean = False
Friend Property Options As String = String.Empty
#End Region
#Region "Exchange, Path, Labels"
Friend Property MyExchangeOptions As Object = Nothing
@@ -99,7 +117,9 @@ Namespace Editors
End If
End Get
End Property
Private SpecialPathHandler As PathMoverHandler = Nothing
Friend ReadOnly Property UserLabels As List(Of String)
Private LabelsIncludeSpecial As Boolean = False
#End Region
#Region "Initializers"
''' <summary>Create new user</summary>
@@ -146,6 +166,7 @@ Namespace Editors
.MyViewInitialize(True)
.AddOkCancelToolbar()
CH_AUTO_DETECT_SITE.Enabled = False
Settings.GlobalLocations.PopulateComboBox(TXT_SPEC_FOLDER)
With CMB_SITE
.BeginUpdate()
.Items.AddRange(Settings.Plugins.Select(Function(p) New ListItem({p.Key, p.Name})))
@@ -155,6 +176,9 @@ Namespace Editors
Dim NameFieldProvider As IFormatProvider = Nothing
If UserIsCollection Then
CMB_SITE.CaptionEnabled = False
CMB_SITE.Checked = False
Icon = If(ImageRenderer.GetIcon(My.Resources.DBPic_32, EDP.ReturnValue), Icon)
Text = $"Collection: {UserInstance.CollectionName}"
@@ -163,6 +187,7 @@ Namespace Editors
TXT_USER.Buttons.AddRange({ADB.Refresh, ADB.Clear})
TXT_USER.Buttons.UpdateButtonsPositions()
TXT_SPEC_FOLDER.Buttons.Clear()
TXT_SPEC_FOLDER.Buttons.LeaveDefaultButtons = False
TXT_SPEC_FOLDER.TextBoxReadOnly = True
TXT_SPEC_FOLDER.Buttons.UpdateButtonsPositions()
@@ -177,6 +202,7 @@ Namespace Editors
.Add(New RowStyle(SizeType.Absolute, 28))
.Add(New RowStyle(SizeType.Absolute, 28))
.Add(New RowStyle(SizeType.Absolute, 26))
.Add(New RowStyle(SizeType.Absolute, 26))
.Add(New RowStyle(SizeType.Percent, 100))
End With
.RowCount = .RowStyles.Count
@@ -187,7 +213,8 @@ Namespace Editors
.Add(TP_DOWN_IMG_VID, 0, 3)
.Add(TP_READY_USERMEDIA, 0, 4)
.Add(TXT_LABELS, 0, 5)
.Add(TXT_DESCR, 0, 6)
.Add(COLOR_USER, 0, 6)
.Add(TXT_DESCR, 0, 7)
End With
.Refresh()
.Update()
@@ -214,9 +241,12 @@ Namespace Editors
CH_DOWN_VIDEOS.CheckState = state(.Item(0).DownloadVideos, Function(p, v) p.DownloadVideos = v)
CH_READY_FOR_DOWN.CheckState = state(.Item(0).ReadyForDownload, Function(p, v) p.ReadyForDownload = v)
CH_PARSE_USER_MEDIA.CheckState = state(.Item(0).ParseUserMediaOnly, Function(p, v) p.ParseUserMediaOnly = v)
_UserBackColor = .BackColor
_UserForeColor = .ForeColor
COLOR_USER.ColorsSetUser(.BackColor, .ForeColor)
TXT_DESCR.Text = .GetUserInformation.StringFormatLines
UserLabels.ListAddList(.Labels)
If UserLabels.ListExists Then TXT_LABELS.Text = UserLabels.ListToString
UpdateSpecificLabels(True)
TXT_LABELS.Buttons.Insert(0, New ActionButton(ADB.Refresh) With {.ToolTipText = "Show/hide site-specific labels"})
End With
NameFieldProvider = New CollectionNameFieldProvider
@@ -235,14 +265,16 @@ Namespace Editors
TXT_SPEC_FOLDER.Text = User.SpecialPath
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()
CMB_SITE.Enabled = False
If Not UserInstance Is Nothing Then
CMB_SITE.Enabled = False
Text = $"User: {UserInstance.Name}"
If Not UserInstance.FriendlyName.IsEmptyString Then Text &= $" ({UserInstance.FriendlyName})"
TXT_USER.Enabled = False
TXT_SPEC_FOLDER.TextBoxReadOnly = True
TXT_SPEC_FOLDER.Buttons.Clear()
TXT_SPEC_FOLDER.Buttons.LeaveDefaultButtons = False
TXT_SPEC_FOLDER.Buttons.UpdateButtonsPositions()
With UserInstance
If .HOST.Key = PathPlugin.PluginKey Then TXT_SPEC_FOLDER.Enabled = False
@@ -263,6 +295,7 @@ Namespace Editors
CH_READY_FOR_DOWN.Checked = .ReadyForDownload
CH_DOWN_IMAGES.Checked = .DownloadImages
CH_DOWN_VIDEOS.Checked = .DownloadVideos
COLOR_USER.ColorsSetUser(.BackColor, .ForeColor)
TXT_SCRIPT.Checked = .ScriptUse
TXT_SCRIPT.Text = .ScriptData
TXT_DESCR.Text = .Description.StringFormatLines
@@ -312,6 +345,7 @@ Namespace Editors
#End Region
#Region "Ok, Cancel"
Private Sub MyDef_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDef.ButtonOkClick
Const msgTitle$ = "Create user"
If UserIsCollection Then
If MyDef.MyFieldsChecker.AllParamsOK Then
With UserInstance
@@ -321,7 +355,23 @@ Namespace Editors
If Not CH_DOWN_VIDEOS.CheckState = CheckState.Indeterminate Then .DownloadVideos = CH_DOWN_VIDEOS.Checked
If Not CH_READY_FOR_DOWN.CheckState = CheckState.Indeterminate Then .ReadyForDownload = CH_READY_FOR_DOWN.Checked
If Not CH_PARSE_USER_MEDIA.CheckState = CheckState.Indeterminate Then .ParseUserMediaOnly = CH_PARSE_USER_MEDIA.Checked
DirectCast(UserInstance, UserDataBind).Collections.ForEach(Sub(u) u.Labels.ListAddList(UserLabels, LAP.ClearBeforeAdd, LAP.NotContainsOnly))
Dim __ubc As Color? = Nothing, __ufc As Color? = Nothing
COLOR_USER.ColorsGetUser(__ubc, __ufc)
Dim __cConv As Func(Of Color?, String) =
Function(__inputColor) If(__inputColor.HasValue, CStr(AConvert(Of String)(__inputColor.Value, String.Empty)), String.Empty)
If Not __cConv(UserBackColor) = __cConv(__ubc) Or Not __cConv(UserForeColor) = __cConv(__ufc) Then
If MsgBoxE({"Are you sure you want to apply the new colors to all users in the collection?", msgTitle}, vbYesNo + vbExclamation) = vbYes Then
.BackColor = __ubc
.ForeColor = __ufc
End If
End If
If Not .Labels.ListEquals(UserLabels) Then _
UserDataBase.UpdateLabels(.Self, UserLabels, 1,
Not DirectCast(.Self, UserDataBase).SpecialLabels.ListExists OrElse
UserDataBase.UpdateLabelsKeepSpecial(1))
CollectionName = TXT_USER.Text
.UpdateUserInformation()
End With
@@ -332,63 +382,74 @@ Namespace Editors
If MyDef.MyFieldsChecker.AllParamsOK Then
Dim s As SettingsHost = GetSiteByCheckers()
If Not s Is Nothing Then
Dim tmpUser As UserInfo = User.Clone
With tmpUser
.Name = TXT_USER.Text
.SpecialPath = SpecialPath(s)
.Site = s.Name
.Plugin = s.Key
.UpdateUserFile()
End With
User = tmpUser
Dim ScriptText$ = TXT_SCRIPT.Text
If Not ScriptText.IsEmptyString Then
Dim f As SFile = ScriptText
If Not SFile.IsDirectory(ScriptText) And Not UserInstance Is Nothing Then
With DirectCast(UserInstance, UserDataBase) : f.Path = .MyFile.Path : End With
End If
TXT_SCRIPT.Text = f
End If
If Not UserInstance Is Nothing Then
With DirectCast(UserInstance, UserDataBase)
.User = User
Dim setFriendly As Boolean = True
If FriendlyNameIsSiteName Then
If Not FriendlyNameChanged Then
setFriendly = False
Else
setFriendly = MsgBoxE({"Are you sure you want to set the site name as the friendly name?" & vbCr &
$"Friendly name: { .FriendlyNameOrig}" & vbCr &
$"Site name: { .UserSiteName}" & vbCr &
$"Your choice: {TXT_USER_FRIENDLY.Text}", "Friendly name change"}, vbExclamation,,,
{"Confirm", New Messaging.MsgBoxButton("Decline", "Friendly name will not be changed")}) = 0
End If
End If
If setFriendly Then .FriendlyName = TXT_USER_FRIENDLY.Text
.Favorite = CH_FAV.Checked
.Temporary = CH_TEMP.Checked
.ReadyForDownload = CH_READY_FOR_DOWN.Checked
.DownloadImages = CH_DOWN_IMAGES.Checked
.DownloadVideos = CH_DOWN_VIDEOS.Checked
.UserDescription = TXT_DESCR.Text
If Not MyExchangeOptions Is Nothing Then .ExchangeOptionsSet(MyExchangeOptions)
Dim l As New ListAddParams(LAP.NotContainsOnly + LAP.ClearBeforeAdd)
If .IsCollection Then
With DirectCast(UserInstance, UserDataBind)
If .Count > 0 Then .Collections.ForEach(Sub(c) c.Labels.ListAddList(UserLabels, l))
End With
Else
.Labels.ListAddList(UserLabels, LAP.NotContainsOnly, LAP.ClearBeforeAdd)
End If
.ParseUserMediaOnly = CH_PARSE_USER_MEDIA.Checked
.ScriptUse = TXT_SCRIPT.Checked
.ScriptData = TXT_SCRIPT.Text
.UpdateUserInformation()
If IsSubscription And Not s.Source.SubscriptionsAllowed Then
MsgBoxE({$"Subscription mode for site [{s.Name}] is not allowed", msgTitle}, vbCritical)
Exit Sub
Else
COLOR_USER.ColorsGetUser(_UserBackColor, _UserForeColor)
Dim tmpUser As UserInfo = User
With tmpUser
.Name = TXT_USER.Text
.Site = s.Name
.Plugin = s.Key
.IsSubscription = IsSubscription
Dim sp As SFile = SpecialPath(s)
If Not sp.IsEmptyString AndAlso Not SpecialPathHandler Is Nothing And UserInstance Is Nothing Then _
sp = SpecialPathHandler.Invoke(.Self, sp)
.SpecialPath = sp
.UpdateUserFile()
End With
User = tmpUser
Dim ScriptText$ = TXT_SCRIPT.Text
If Not ScriptText.IsEmptyString Then
Dim f As SFile = ScriptText
If Not SFile.IsDirectory(ScriptText) And Not UserInstance Is Nothing Then
With DirectCast(UserInstance, UserDataBase) : f.Path = .MyFile.Path : End With
End If
TXT_SCRIPT.Text = f
End If
If Not UserInstance Is Nothing Then
With DirectCast(UserInstance, UserDataBase)
.User = User
Dim setFriendly As Boolean = True
If FriendlyNameIsSiteName Then
If Not FriendlyNameChanged Then
setFriendly = False
Else
setFriendly = MsgBoxE({"Are you sure you want to set the site name as the friendly name?" & vbCr &
$"Friendly name: { .FriendlyNameOrig}" & vbCr &
$"Site name: { .UserSiteName}" & vbCr &
$"Your choice: {TXT_USER_FRIENDLY.Text}", "Friendly name change"}, vbExclamation,,,
{"Confirm", New Messaging.MsgBoxButton("Decline", "Friendly name will not be changed")}) = 0
End If
End If
If setFriendly Then .FriendlyName = TXT_USER_FRIENDLY.Text
.Favorite = CH_FAV.Checked
.Temporary = CH_TEMP.Checked
.ReadyForDownload = CH_READY_FOR_DOWN.Checked
.DownloadImages = CH_DOWN_IMAGES.Checked
.DownloadVideos = CH_DOWN_VIDEOS.Checked
COLOR_USER.ColorsGetUser(.BackColor, .ForeColor)
.UserDescription = TXT_DESCR.Text
If Not MyExchangeOptions Is Nothing Then .ExchangeOptionsSet(MyExchangeOptions)
Dim l As New ListAddParams(LAP.NotContainsOnly + LAP.ClearBeforeAdd)
If .IsCollection Then
With DirectCast(UserInstance, UserDataBind)
If .Count > 0 Then .Collections.ForEach(Sub(c) c.Labels.ListAddList(UserLabels, l))
End With
Else
.Labels.ListAddList(UserLabels, LAP.NotContainsOnly, LAP.ClearBeforeAdd)
End If
.ParseUserMediaOnly = CH_PARSE_USER_MEDIA.Checked
.ScriptUse = TXT_SCRIPT.Checked
.ScriptData = TXT_SCRIPT.Text
.UpdateUserInformation()
End With
End If
GoTo CloseForm
End If
GoTo CloseForm
Else
MsgBoxE("User site not selected", MsgBoxStyle.Exclamation)
MsgBoxE({"User site not selected", msgTitle}, MsgBoxStyle.Exclamation)
End If
End If
Else
@@ -409,6 +470,7 @@ CloseForm:
Try
If Not _TextChangeInvoked And Not UserIsCollection Then
_TextChangeInvoked = True
Options = String.Empty
If Not CH_ADD_BY_LIST.Checked Then
Dim s As ExchangeOptions = GetSiteByText(TXT_USER.Text)
Dim found As Boolean = False
@@ -421,6 +483,7 @@ CloseForm:
End If
CMB_SITE.SelectedIndex = i
TXT_USER.Text = s.UserName
Options = s.Options
found = True
End If
End If
@@ -479,10 +542,27 @@ CloseForm:
End Sub
Private Sub TXT_SPEC_FOLDER_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles TXT_SPEC_FOLDER.ActionOnButtonClick
If Sender.DefaultButton = ADB.Open Then
Dim f As SFile = Nothing
If Not TXT_SPEC_FOLDER.Text.IsEmptyString Then f = $"{TXT_SPEC_FOLDER.Text}\"
f = SFile.SelectPath(f)
If Not f.IsEmptyString Then TXT_SPEC_FOLDER.Text = f.PathWithSeparator
Using ff As New GlobalLocationsChooserForm With {.MyInitialLocation = TXT_SPEC_FOLDER.Text}
ff.ShowDialog()
If ff.DialogResult = DialogResult.OK And Not ff.MyDestination.Path.IsEmptyString Then
Settings.GlobalLocations.PopulateComboBox(TXT_SPEC_FOLDER)
Dim i% = Settings.GlobalLocations.IndexOf(ff.MyDestination)
If i.ValueBetween(0, TXT_SPEC_FOLDER.Count - 1) Then TXT_SPEC_FOLDER.SelectedIndex = i
TXT_SPEC_FOLDER.Text = ff.MyDestination.Path
SpecialPathHandler = ff.MyModelHandler
End If
End Using
End If
End Sub
Private Sub TXT_SPEC_FOLDER_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_SPEC_FOLDER.ActionOnTextChanged
SpecialPathHandler = Nothing
End Sub
Private Sub TXT_SPEC_FOLDER_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles TXT_SPEC_FOLDER.ActionSelectedItemChanged
Dim i% = TXT_SPEC_FOLDER.SelectedIndex
If i.ValueBetween(0, Settings.GlobalLocations.Count - 1) Then
SpecialPathHandler = GlobalLocationsChooserForm.ModelHandler(Settings.GlobalLocations(i).Model)
Else
SpecialPathHandler = Nothing
End If
End Sub
Private Sub CH_TEMP_CheckedChanged(sender As Object, e As EventArgs) Handles CH_TEMP.CheckedChanged
@@ -517,8 +597,21 @@ CloseForm:
Select Case Sender.DefaultButton
Case ADB.Open : ChangeLabels()
Case ADB.Clear : UserLabels.Clear()
Case ADB.Refresh : UpdateSpecificLabels(False)
End Select
End Sub
Private Sub UpdateSpecificLabels(ByVal IsInit As Boolean)
If DirectCast(UserInstance, UserDataBase).SpecialLabels.ListExists Then
If Not IsInit Then LabelsIncludeSpecial = Not LabelsIncludeSpecial
UserLabelName.Clone()
UserLabels.ListAddList(UserInstance.Labels, LAP.NotContainsOnly)
If Not LabelsIncludeSpecial Then UserLabels.ListWithRemove(DirectCast(UserInstance, UserDataBase).SpecialLabels)
If UserLabels.Count > 0 Then UserLabels.Sort()
TXT_LABELS.Text = UserLabels.ListToString
Else
If Not IsInit Then MsgBoxE({"Users in this collection do not have site-specific labels", "Change labels view"}, vbExclamation)
End If
End Sub
Private Sub TXT_SCRIPT_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles TXT_SCRIPT.ActionOnButtonClick
SettingsCLS.ScriptTextBoxButtonClick(TXT_SCRIPT, Sender)
End Sub
@@ -535,17 +628,27 @@ CloseForm:
If u.ListExists Then
Dim NonIdentified As New List(Of String)
Dim UsersForCreate As New List(Of UserInfo)
Dim UsersForCreate_Options As New List(Of String)
Dim BannedUsers() As String = Nothing
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 sObj As ExchangeOptions
Dim sObj As ExchangeOptions = Nothing
Dim Added% = 0
Dim Skipped% = 0
Dim uid%
Dim sf As Func(Of SettingsHost, String) = Function(__s) SpecialPath(__s).PathWithSeparator
Dim __sf As Func(Of String, SettingsHost, SFile) = Function(Input, __s) IIf(sf(__s).IsEmptyString, Nothing, New SFile($"{sf(__s)}{Input}\"))
Dim __getUserSpecialPath As Func(Of UserInfo, SettingsHost, SFile) =
Function(ByVal __user As UserInfo, ByVal __s As SettingsHost) As SFile
Dim sp As SFile = SpecialPath(__s).PathWithSeparator
If sp.IsEmptyString Then
Return Nothing
ElseIf Not SpecialPathHandler Is Nothing Then
Return SpecialPathHandler.Invoke(__user, sp)
Else
Return $"{sp}{__user.Name}\"
End If
End Function
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
@@ -559,15 +662,19 @@ CloseForm:
Else
s = Nothing
End If
ElseIf i = 0 Then
sObj = GetSiteByText(uu)
End If
If Not s Is Nothing Then
tmpUser = New UserInfo(uu, s) With {.SpecialPath = __sf(uu, s)}
If Not s Is Nothing AndAlso (Not IsSubscription OrElse s.Source.SubscriptionsAllowed) Then
tmpUser = New UserInfo(uu, s)
tmpUser.SpecialPath = __getUserSpecialPath(tmpUser, s)
tmpUser.UpdateUserFile()
uid = -1
If Settings.UsersList.Count > 0 Then uid = Settings.UsersList.IndexOf(tmpUser)
If uid < 0 And Not UsersForCreate.Contains(tmpUser) Then
UsersForCreate.Add(tmpUser)
UsersForCreate_Options.Add(sObj.Options)
Else
Skipped += 1
End If
@@ -585,6 +692,7 @@ CloseForm:
If StartIndex = -1 Then StartIndex = Settings.Users.Count
Settings.Users.Add(UserDataBase.GetInstance(tmpUser, False))
With Settings.Users.Last
.Options = sObj.Options
.FriendlyName = TXT_USER_FRIENDLY.Text
.Favorite = CH_FAV.Checked
.Temporary = CH_TEMP.Checked

View File

@@ -5,4 +5,5 @@
Imports System.Diagnostics.CodeAnalysis
<Assembly: SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification:="<Pending>", Scope:="member", Target:="~F:SCrawler.MainFrame.MySearch")>
<Assembly: SuppressMessage("Style", "IDE0059:Unnecessary assignment of a value", Justification:="<Pending>", Scope:="member", Target:="~M:SCrawler.DownloadObjects.DownloadFeedForm.TPRemoveControl(SCrawler.DownloadObjects.FeedMedia,System.Boolean)")>
<Assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification:="<Pending>", Scope:="member", Target:="~M:SCrawler.API.UserDataBind.DownloadData(System.Threading.CancellationToken,System.Boolean)")>
<Assembly: SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification:="<Pending>", Scope:="member", Target:="~M:SCrawler.API.UserDataBind.DownloadData(System.Threading.CancellationToken,System.Boolean)")>
<Assembly: SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification:="<Pending>", Scope:="member", Target:="~F:SCrawler.MainFrame.DownloadQueue")>

View File

@@ -199,9 +199,12 @@ Friend Class ListImagesLoader
ElseIf CheckUserCollection(User) Then
.BackColor = Color.LightSkyBlue
.ForeColor = Color.MidnightBlue
ElseIf User.IsSubscription Then
.BackColor = If(User.BackColor, Settings.MainFrameUsersSubscriptionsColorBack.Value)
.ForeColor = If(User.ForeColor, Settings.MainFrameUsersSubscriptionsColorFore.Value)
Else
.BackColor = Settings.UserListBackColorF
.ForeColor = Settings.UserListForeColorF
.BackColor = If(User.BackColor, Settings.UserListBackColorF)
.ForeColor = If(User.ForeColor, Settings.UserListForeColorF)
End If
End With
Return LVI

View File

@@ -32,18 +32,22 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Dim CONTEXT_SEP_4 As System.Windows.Forms.ToolStripSeparator
Dim CONTEXT_SEP_5 As System.Windows.Forms.ToolStripSeparator
Dim SEP_4 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_4 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim TRAY_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim TRAY_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim TRAY_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_4 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_5 As System.Windows.Forms.ToolStripSeparator
Dim MENU_DOWN_ALL_SEP_6 As System.Windows.Forms.ToolStripSeparator
Dim MENU_INFO As System.Windows.Forms.ToolStripDropDownButton
Dim MENU_VIEW_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MainFrame))
Me.MENU_INFO_SHOW_INFO = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_QUEUE = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_MISSING = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_INFO_SHOW_USER_METRICS = New System.Windows.Forms.ToolStripMenuItem()
Me.MENU_SETTINGS = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripMenuItem()
Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip()
@@ -51,16 +55,21 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_EDIT_USER = New System.Windows.Forms.ToolStripButton()
Me.BTT_DELETE_USER = New System.Windows.Forms.ToolStripButton()
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
Me.BTT_SHOW_INFO = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripButtonKeyClick()
Me.BTT_FEED = New System.Windows.Forms.ToolStripButton()
Me.BTT_CHANNELS = New System.Windows.Forms.ToolStripButton()
Me.BTT_DOWN_SAVED = New System.Windows.Forms.ToolStripButton()
Me.MENU_DOWN_ALL = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_DOWN_SELECTED = New SCrawler.ToolStripKeyMenuItem()
Me.MENU_D_DOWN_ALL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_DOWN_ALL = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_ALL_SUBSCR = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_SITE = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_SITE_SUBSCR = New SCrawler.ToolStripKeyMenuItem()
Me.MENU_D_DOWN_ALL_SITE = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_DOWN_ALL_FULL = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_ALL_FULL_SUBSCR = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_SITE_FULL = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_SITE_FULL_SUBSCR = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_DOWN_VIDEO = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_ADD_NEW_GROUP = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_SILENT_MODE = New System.Windows.Forms.ToolStripMenuItem()
@@ -72,6 +81,8 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_VIEW_SMALL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_VIEW_LIST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_VIEW_DETAILS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MODE_SHOW_USERS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_MODE_SHOW_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_SITE_ALL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_SITE_SPECIFIC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_SHOW_ALL = New System.Windows.Forms.ToolStripMenuItem()
@@ -90,6 +101,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_LOG = New System.Windows.Forms.ToolStripButton()
Me.BTT_VERSION_INFO = New System.Windows.Forms.ToolStripButton()
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
Me.BTT_BUG_REPORT = New System.Windows.Forms.ToolStripButton()
Me.Toolbar_BOTTOM = New System.Windows.Forms.StatusStrip()
Me.BTT_PR_INFO = New System.Windows.Forms.ToolStripStatusLabel()
Me.PR_PRE = New System.Windows.Forms.ToolStripProgressBar()
@@ -104,11 +116,12 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_CONTEXT_DOWN_DATE_LIMIT = New SCrawler.ToolStripKeyMenuItem()
Me.BTT_CONTEXT_EDIT = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_DELETE = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_ERASE = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_COPY_TO_FOLDER = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_TEMP = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_READY = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_GROUPS = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_GROUPS = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
Me.BTT_CONTEXT_SCRIPT = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_ADD_TO_COL = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_CONTEXT_COL_MERGE = New System.Windows.Forms.ToolStripMenuItem()
@@ -137,17 +150,17 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
CONTEXT_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
CONTEXT_SEP_5 = New System.Windows.Forms.ToolStripSeparator()
SEP_4 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
TRAY_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
TRAY_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
TRAY_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_5 = New System.Windows.Forms.ToolStripSeparator()
MENU_DOWN_ALL_SEP_6 = New System.Windows.Forms.ToolStripSeparator()
MENU_INFO = New System.Windows.Forms.ToolStripDropDownButton()
MENU_VIEW_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
Me.Toolbar_TOP.SuspendLayout()
Me.Toolbar_BOTTOM.SuspendLayout()
Me.USER_CONTEXT.SuspendLayout()
@@ -204,21 +217,21 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
SEP_4.Name = "SEP_4"
SEP_4.Size = New System.Drawing.Size(6, 25)
'
'MENU_VIEW_SEP_1
'MENU_VIEW_SEP_2
'
MENU_VIEW_SEP_1.Name = "MENU_VIEW_SEP_1"
MENU_VIEW_SEP_1.Size = New System.Drawing.Size(228, 6)
MENU_VIEW_SEP_2.Name = "MENU_VIEW_SEP_2"
MENU_VIEW_SEP_2.Size = New System.Drawing.Size(228, 6)
'
'MENU_VIEW_SEP_4
'
MENU_VIEW_SEP_4.Name = "MENU_VIEW_SEP_4"
MENU_VIEW_SEP_4.Size = New System.Drawing.Size(228, 6)
'
'MENU_VIEW_SEP_3
'
MENU_VIEW_SEP_3.Name = "MENU_VIEW_SEP_3"
MENU_VIEW_SEP_3.Size = New System.Drawing.Size(228, 6)
'
'MENU_VIEW_SEP_2
'
MENU_VIEW_SEP_2.Name = "MENU_VIEW_SEP_2"
MENU_VIEW_SEP_2.Size = New System.Drawing.Size(228, 6)
'
'TRAY_SEP_1
'
TRAY_SEP_1.Name = "TRAY_SEP_1"
@@ -227,37 +240,78 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'MENU_DOWN_ALL_SEP_1
'
MENU_DOWN_ALL_SEP_1.Name = "MENU_DOWN_ALL_SEP_1"
MENU_DOWN_ALL_SEP_1.Size = New System.Drawing.Size(228, 6)
'
'MENU_DOWN_ALL_SEP_2
'
MENU_DOWN_ALL_SEP_2.Name = "MENU_DOWN_ALL_SEP_2"
MENU_DOWN_ALL_SEP_2.Size = New System.Drawing.Size(228, 6)
'
'MENU_DOWN_ALL_SEP_3
'
MENU_DOWN_ALL_SEP_3.Name = "MENU_DOWN_ALL_SEP_3"
MENU_DOWN_ALL_SEP_3.Size = New System.Drawing.Size(228, 6)
MENU_DOWN_ALL_SEP_1.Size = New System.Drawing.Size(218, 6)
'
'TRAY_SEP_2
'
TRAY_SEP_2.Name = "TRAY_SEP_2"
TRAY_SEP_2.Size = New System.Drawing.Size(167, 6)
'
'MENU_DOWN_ALL_SEP_2
'
MENU_DOWN_ALL_SEP_2.Name = "MENU_DOWN_ALL_SEP_2"
MENU_DOWN_ALL_SEP_2.Size = New System.Drawing.Size(218, 6)
'
'MENU_DOWN_ALL_SEP_3
'
MENU_DOWN_ALL_SEP_3.Name = "MENU_DOWN_ALL_SEP_3"
MENU_DOWN_ALL_SEP_3.Size = New System.Drawing.Size(218, 6)
'
'MENU_DOWN_ALL_SEP_4
'
MENU_DOWN_ALL_SEP_4.Name = "MENU_DOWN_ALL_SEP_4"
MENU_DOWN_ALL_SEP_4.Size = New System.Drawing.Size(228, 6)
MENU_DOWN_ALL_SEP_4.Size = New System.Drawing.Size(218, 6)
'
'MENU_DOWN_ALL_SEP_5
'MENU_INFO
'
MENU_DOWN_ALL_SEP_5.Name = "MENU_DOWN_ALL_SEP_5"
MENU_DOWN_ALL_SEP_5.Size = New System.Drawing.Size(228, 6)
MENU_INFO.AutoToolTip = False
MENU_INFO.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_INFO_SHOW_INFO, Me.MENU_INFO_SHOW_QUEUE, Me.MENU_INFO_SHOW_MISSING, Me.MENU_INFO_SHOW_USER_METRICS})
MENU_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
MENU_INFO.ImageTransparentColor = System.Drawing.Color.Magenta
MENU_INFO.Name = "MENU_INFO"
MENU_INFO.Size = New System.Drawing.Size(57, 22)
MENU_INFO.Text = "Info"
'
'MENU_DOWN_ALL_SEP_6
'MENU_INFO_SHOW_INFO
'
MENU_DOWN_ALL_SEP_6.Name = "MENU_DOWN_ALL_SEP_6"
MENU_DOWN_ALL_SEP_6.Size = New System.Drawing.Size(228, 6)
Me.MENU_INFO_SHOW_INFO.AutoToolTip = True
Me.MENU_INFO_SHOW_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.MENU_INFO_SHOW_INFO.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_INFO_SHOW_INFO.Name = "MENU_INFO_SHOW_INFO"
Me.MENU_INFO_SHOW_INFO.Size = New System.Drawing.Size(212, 22)
Me.MENU_INFO_SHOW_INFO.Text = "Info (download summary)"
Me.MENU_INFO_SHOW_INFO.ToolTipText = "Open the 'Info' form (show download summary)."
'
'MENU_INFO_SHOW_QUEUE
'
Me.MENU_INFO_SHOW_QUEUE.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.MENU_INFO_SHOW_QUEUE.Name = "MENU_INFO_SHOW_QUEUE"
Me.MENU_INFO_SHOW_QUEUE.Size = New System.Drawing.Size(212, 22)
Me.MENU_INFO_SHOW_QUEUE.Text = "Users download queue"
'
'MENU_INFO_SHOW_MISSING
'
Me.MENU_INFO_SHOW_MISSING.AutoToolTip = True
Me.MENU_INFO_SHOW_MISSING.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.MENU_INFO_SHOW_MISSING.Name = "MENU_INFO_SHOW_MISSING"
Me.MENU_INFO_SHOW_MISSING.Size = New System.Drawing.Size(212, 22)
Me.MENU_INFO_SHOW_MISSING.Text = "Missing posts"
Me.MENU_INFO_SHOW_MISSING.ToolTipText = "Open the 'Missing' form (show information about missing posts)."
'
'MENU_INFO_SHOW_USER_METRICS
'
Me.MENU_INFO_SHOW_USER_METRICS.AutoToolTip = True
Me.MENU_INFO_SHOW_USER_METRICS.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.MENU_INFO_SHOW_USER_METRICS.Name = "MENU_INFO_SHOW_USER_METRICS"
Me.MENU_INFO_SHOW_USER_METRICS.Size = New System.Drawing.Size(212, 22)
Me.MENU_INFO_SHOW_USER_METRICS.Text = "User metrics"
Me.MENU_INFO_SHOW_USER_METRICS.ToolTipText = "Open the ""User metrics' form (show information about the user's metrics (such as " &
"size, number of files, etc.))."
'
'MENU_VIEW_SEP_1
'
MENU_VIEW_SEP_1.Name = "MENU_VIEW_SEP_1"
MENU_VIEW_SEP_1.Size = New System.Drawing.Size(228, 6)
'
'MENU_SETTINGS
'
@@ -279,7 +333,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'Toolbar_TOP
'
Me.Toolbar_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
Me.Toolbar_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_SETTINGS, SEP_1, Me.BTT_ADD_USER, Me.BTT_EDIT_USER, Me.BTT_DELETE_USER, Me.BTT_REFRESH, Me.BTT_SHOW_INFO, Me.BTT_FEED, Me.BTT_CHANNELS, Me.BTT_DOWN_SAVED, SEP_2, Me.MENU_DOWN_ALL, Me.BTT_DOWN_STOP, SEP_3, Me.MENU_VIEW, SEP_4, Me.BTT_LOG, Me.BTT_VERSION_INFO, Me.BTT_DONATE})
Me.Toolbar_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_SETTINGS, SEP_1, Me.BTT_ADD_USER, Me.BTT_EDIT_USER, Me.BTT_DELETE_USER, Me.BTT_REFRESH, MENU_INFO, Me.BTT_FEED, Me.BTT_CHANNELS, Me.BTT_DOWN_SAVED, SEP_2, Me.MENU_DOWN_ALL, Me.BTT_DOWN_STOP, SEP_3, Me.MENU_VIEW, SEP_4, Me.BTT_LOG, Me.BTT_VERSION_INFO, Me.BTT_DONATE, Me.BTT_BUG_REPORT})
Me.Toolbar_TOP.Location = New System.Drawing.Point(0, 0)
Me.Toolbar_TOP.Name = "Toolbar_TOP"
Me.Toolbar_TOP.Size = New System.Drawing.Size(934, 25)
@@ -322,15 +376,6 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_REFRESH.Text = "Refresh"
Me.BTT_REFRESH.ToolTipText = "Refresh user list"
'
'BTT_SHOW_INFO
'
Me.BTT_SHOW_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.BTT_SHOW_INFO.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_SHOW_INFO.Name = "BTT_SHOW_INFO"
Me.BTT_SHOW_INFO.Size = New System.Drawing.Size(48, 22)
Me.BTT_SHOW_INFO.Text = "Info"
Me.BTT_SHOW_INFO.ToolTipText = resources.GetString("BTT_SHOW_INFO.ToolTipText")
'
'BTT_FEED
'
Me.BTT_FEED.Image = Global.SCrawler.My.Resources.Resources.RSSPic_512
@@ -361,7 +406,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'MENU_DOWN_ALL
'
Me.MENU_DOWN_ALL.AutoToolTip = False
Me.MENU_DOWN_ALL.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN_SELECTED, MENU_DOWN_ALL_SEP_1, Me.BTT_DOWN_ALL, Me.BTT_DOWN_SITE, MENU_DOWN_ALL_SEP_2, Me.BTT_DOWN_ALL_FULL, Me.BTT_DOWN_SITE_FULL, MENU_DOWN_ALL_SEP_3, Me.BTT_DOWN_VIDEO, MENU_DOWN_ALL_SEP_4, Me.BTT_ADD_NEW_GROUP, MENU_DOWN_ALL_SEP_5, Me.BTT_SILENT_MODE, MENU_DOWN_ALL_SEP_6, Me.BTT_DOWN_AUTOMATION, Me.BTT_DOWN_AUTOMATION_PAUSE})
Me.MENU_DOWN_ALL.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN_SELECTED, Me.MENU_D_DOWN_ALL, Me.MENU_D_DOWN_ALL_SITE, MENU_DOWN_ALL_SEP_1, Me.BTT_DOWN_VIDEO, MENU_DOWN_ALL_SEP_2, Me.BTT_ADD_NEW_GROUP, MENU_DOWN_ALL_SEP_3, Me.BTT_SILENT_MODE, MENU_DOWN_ALL_SEP_4, Me.BTT_DOWN_AUTOMATION, Me.BTT_DOWN_AUTOMATION_PAUSE})
Me.MENU_DOWN_ALL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.MENU_DOWN_ALL.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_DOWN_ALL.Name = "MENU_DOWN_ALL"
@@ -374,49 +419,100 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_DOWN_SELECTED.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SELECTED.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DOWN_SELECTED.Name = "BTT_DOWN_SELECTED"
Me.BTT_DOWN_SELECTED.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_SELECTED.Size = New System.Drawing.Size(221, 22)
Me.BTT_DOWN_SELECTED.Text = "Download selected (F5)"
Me.BTT_DOWN_SELECTED.ToolTipText = "Download selected user." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "F5: download, include in the feed." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+F5: download, e" &
"xclude from feed."
Me.BTT_DOWN_SELECTED.ToolTipText = "Download selected user." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "F5: download, include in the feed."
'
'MENU_D_DOWN_ALL
'
Me.MENU_D_DOWN_ALL.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN_ALL, Me.BTT_DOWN_ALL_SUBSCR, Me.BTT_DOWN_SITE, Me.BTT_DOWN_SITE_SUBSCR})
Me.MENU_D_DOWN_ALL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.MENU_D_DOWN_ALL.Name = "MENU_D_DOWN_ALL"
Me.MENU_D_DOWN_ALL.Size = New System.Drawing.Size(221, 22)
Me.MENU_D_DOWN_ALL.Text = "Download all (F6)"
'
'BTT_DOWN_ALL
'
Me.BTT_DOWN_ALL.AutoToolTip = True
Me.BTT_DOWN_ALL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_ALL.Name = "BTT_DOWN_ALL"
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(237, 22)
Me.BTT_DOWN_ALL.Text = "Download all (F6)"
Me.BTT_DOWN_ALL.ToolTipText = "Download all users marked 'Ready for download' from all sites." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "F5: download, inc" &
"lude in the feed." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+F5: download, exclude from feed."
Me.BTT_DOWN_ALL.ToolTipText = "Download all users marked 'Ready for download' from all sites." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "F6: download, inc" &
"lude in the feed."
'
'BTT_DOWN_ALL_SUBSCR
'
Me.BTT_DOWN_ALL_SUBSCR.AutoToolTip = True
Me.BTT_DOWN_ALL_SUBSCR.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_ALL_SUBSCR.Name = "BTT_DOWN_ALL_SUBSCR"
Me.BTT_DOWN_ALL_SUBSCR.Size = New System.Drawing.Size(237, 22)
Me.BTT_DOWN_ALL_SUBSCR.Text = "Download all subscriptions"
Me.BTT_DOWN_ALL_SUBSCR.ToolTipText = "Download all subscriptions marked 'Ready for download' from all sites."
'
'BTT_DOWN_SITE
'
Me.BTT_DOWN_SITE.AutoToolTip = True
Me.BTT_DOWN_SITE.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SITE.Name = "BTT_DOWN_SITE"
Me.BTT_DOWN_SITE.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_SITE.Size = New System.Drawing.Size(237, 22)
Me.BTT_DOWN_SITE.Text = "Download all site users"
Me.BTT_DOWN_SITE.ToolTipText = "Download all users marked 'Ready for download' from specific sites."
'
'BTT_DOWN_SITE_SUBSCR
'
Me.BTT_DOWN_SITE_SUBSCR.AutoToolTip = True
Me.BTT_DOWN_SITE_SUBSCR.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SITE_SUBSCR.Name = "BTT_DOWN_SITE_SUBSCR"
Me.BTT_DOWN_SITE_SUBSCR.Size = New System.Drawing.Size(237, 22)
Me.BTT_DOWN_SITE_SUBSCR.Text = "Download all site subscriptions"
Me.BTT_DOWN_SITE_SUBSCR.ToolTipText = "Download all subscriptions marked 'Ready for download' from specific sites."
'
'MENU_D_DOWN_ALL_SITE
'
Me.MENU_D_DOWN_ALL_SITE.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN_ALL_FULL, Me.BTT_DOWN_ALL_FULL_SUBSCR, Me.BTT_DOWN_SITE_FULL, Me.BTT_DOWN_SITE_FULL_SUBSCR})
Me.MENU_D_DOWN_ALL_SITE.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.MENU_D_DOWN_ALL_SITE.Name = "MENU_D_DOWN_ALL_SITE"
Me.MENU_D_DOWN_ALL_SITE.Size = New System.Drawing.Size(221, 22)
Me.MENU_D_DOWN_ALL_SITE.Text = "Download all [FULL]"
'
'BTT_DOWN_ALL_FULL
'
Me.BTT_DOWN_ALL_FULL.AutoToolTip = True
Me.BTT_DOWN_ALL_FULL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_ALL_FULL.Name = "BTT_DOWN_ALL_FULL"
Me.BTT_DOWN_ALL_FULL.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_ALL_FULL.Size = New System.Drawing.Size(274, 22)
Me.BTT_DOWN_ALL_FULL.Text = "Download all [FULL]"
Me.BTT_DOWN_ALL_FULL.ToolTipText = "Download all users from all sites. The 'Ready for download' option will be ignore" &
"d."
'
'BTT_DOWN_ALL_FULL_SUBSCR
'
Me.BTT_DOWN_ALL_FULL_SUBSCR.AutoToolTip = True
Me.BTT_DOWN_ALL_FULL_SUBSCR.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_ALL_FULL_SUBSCR.Name = "BTT_DOWN_ALL_FULL_SUBSCR"
Me.BTT_DOWN_ALL_FULL_SUBSCR.Size = New System.Drawing.Size(274, 22)
Me.BTT_DOWN_ALL_FULL_SUBSCR.Text = "Download all subscriptions [FULL]"
Me.BTT_DOWN_ALL_FULL_SUBSCR.ToolTipText = "Download all subscriptions from all sites. The 'Ready for download' option will b" &
"e ignored."
'
'BTT_DOWN_SITE_FULL
'
Me.BTT_DOWN_SITE_FULL.AutoToolTip = True
Me.BTT_DOWN_SITE_FULL.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SITE_FULL.Name = "BTT_DOWN_SITE_FULL"
Me.BTT_DOWN_SITE_FULL.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_SITE_FULL.Size = New System.Drawing.Size(274, 22)
Me.BTT_DOWN_SITE_FULL.Text = "Download all site users [FULL]"
Me.BTT_DOWN_SITE_FULL.ToolTipText = "Download all users from specific sites. The 'Ready for download' option will be i" &
"gnored."
Me.BTT_DOWN_SITE_FULL.ToolTipText = resources.GetString("BTT_DOWN_SITE_FULL.ToolTipText")
'
'BTT_DOWN_SITE_FULL_SUBSCR
'
Me.BTT_DOWN_SITE_FULL_SUBSCR.AutoToolTip = True
Me.BTT_DOWN_SITE_FULL_SUBSCR.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN_SITE_FULL_SUBSCR.Name = "BTT_DOWN_SITE_FULL_SUBSCR"
Me.BTT_DOWN_SITE_FULL_SUBSCR.Size = New System.Drawing.Size(274, 22)
Me.BTT_DOWN_SITE_FULL_SUBSCR.Text = "Download all site subscriptions [FULL]"
Me.BTT_DOWN_SITE_FULL_SUBSCR.ToolTipText = resources.GetString("BTT_DOWN_SITE_FULL_SUBSCR.ToolTipText")
'
'BTT_DOWN_VIDEO
'
@@ -424,7 +520,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_DOWN_VIDEO.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_DOWN_VIDEO.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DOWN_VIDEO.Name = "BTT_DOWN_VIDEO"
Me.BTT_DOWN_VIDEO.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_VIDEO.Size = New System.Drawing.Size(221, 22)
Me.BTT_DOWN_VIDEO.Text = "Standalone downloader"
Me.BTT_DOWN_VIDEO.ToolTipText = "Download video by URL"
'
@@ -432,7 +528,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'
Me.BTT_ADD_NEW_GROUP.Image = Global.SCrawler.My.Resources.Resources.PlusPic_24
Me.BTT_ADD_NEW_GROUP.Name = "BTT_ADD_NEW_GROUP"
Me.BTT_ADD_NEW_GROUP.Size = New System.Drawing.Size(231, 22)
Me.BTT_ADD_NEW_GROUP.Size = New System.Drawing.Size(221, 22)
Me.BTT_ADD_NEW_GROUP.Text = "Add a new download group"
'
'BTT_SILENT_MODE
@@ -440,7 +536,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_SILENT_MODE.AutoToolTip = True
Me.BTT_SILENT_MODE.Image = Global.SCrawler.My.Resources.Resources.MessagePic_16
Me.BTT_SILENT_MODE.Name = "BTT_SILENT_MODE"
Me.BTT_SILENT_MODE.Size = New System.Drawing.Size(231, 22)
Me.BTT_SILENT_MODE.Size = New System.Drawing.Size(221, 22)
Me.BTT_SILENT_MODE.Text = "Silent mode"
Me.BTT_SILENT_MODE.ToolTipText = "Turn off notifications temporarily." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "This setting is not stored in the settings f" &
"ile. It is valid until you turn it off or close the program." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10)
@@ -449,14 +545,14 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'
Me.BTT_DOWN_AUTOMATION.Image = Global.SCrawler.My.Resources.Resources.ScriptPic_32
Me.BTT_DOWN_AUTOMATION.Name = "BTT_DOWN_AUTOMATION"
Me.BTT_DOWN_AUTOMATION.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_AUTOMATION.Size = New System.Drawing.Size(221, 22)
Me.BTT_DOWN_AUTOMATION.Text = "Automation"
'
'BTT_DOWN_AUTOMATION_PAUSE
'
Me.BTT_DOWN_AUTOMATION_PAUSE.Image = Global.SCrawler.My.Resources.Resources.Pause_Blue_16
Me.BTT_DOWN_AUTOMATION_PAUSE.Name = "BTT_DOWN_AUTOMATION_PAUSE"
Me.BTT_DOWN_AUTOMATION_PAUSE.Size = New System.Drawing.Size(231, 22)
Me.BTT_DOWN_AUTOMATION_PAUSE.Size = New System.Drawing.Size(221, 22)
Me.BTT_DOWN_AUTOMATION_PAUSE.Text = "Pause automation"
'
'BTT_DOWN_STOP
@@ -472,7 +568,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'MENU_VIEW
'
Me.MENU_VIEW.AutoToolTip = False
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_VIEW_LARGE, Me.BTT_VIEW_SMALL, Me.BTT_VIEW_LIST, Me.BTT_VIEW_DETAILS, MENU_VIEW_SEP_1, Me.BTT_SITE_ALL, Me.BTT_SITE_SPECIFIC, MENU_VIEW_SEP_2, Me.BTT_SHOW_ALL, Me.BTT_SHOW_REGULAR, Me.BTT_SHOW_TEMP, Me.BTT_SHOW_FAV, Me.BTT_SHOW_DELETED, Me.BTT_SHOW_SUSPENDED, Me.BTT_SHOW_LABELS, Me.BTT_SHOW_NO_LABELS, Me.BTT_SHOW_EXCLUDED_LABELS, Me.BTT_SHOW_EXCLUDED_LABELS_IGNORE, Me.BTT_SHOW_SHOW_GROUPS, MENU_VIEW_SEP_3, Me.BTT_SHOW_LIMIT_DATES_NOT, Me.BTT_SHOW_LIMIT_DATES_IN})
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_VIEW_LARGE, Me.BTT_VIEW_SMALL, Me.BTT_VIEW_LIST, Me.BTT_VIEW_DETAILS, MENU_VIEW_SEP_1, Me.BTT_MODE_SHOW_USERS, Me.BTT_MODE_SHOW_SUBSCRIPTIONS, MENU_VIEW_SEP_2, Me.BTT_SITE_ALL, Me.BTT_SITE_SPECIFIC, MENU_VIEW_SEP_3, Me.BTT_SHOW_ALL, Me.BTT_SHOW_REGULAR, Me.BTT_SHOW_TEMP, Me.BTT_SHOW_FAV, Me.BTT_SHOW_DELETED, Me.BTT_SHOW_SUSPENDED, Me.BTT_SHOW_LABELS, Me.BTT_SHOW_NO_LABELS, Me.BTT_SHOW_EXCLUDED_LABELS, Me.BTT_SHOW_EXCLUDED_LABELS_IGNORE, Me.BTT_SHOW_SHOW_GROUPS, MENU_VIEW_SEP_4, Me.BTT_SHOW_LIMIT_DATES_NOT, Me.BTT_SHOW_LIMIT_DATES_IN})
Me.MENU_VIEW.Image = CType(resources.GetObject("MENU_VIEW.Image"), System.Drawing.Image)
Me.MENU_VIEW.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_VIEW.Name = "MENU_VIEW"
@@ -503,6 +599,20 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_VIEW_DETAILS.Size = New System.Drawing.Size(231, 22)
Me.BTT_VIEW_DETAILS.Text = "Details"
'
'BTT_MODE_SHOW_USERS
'
Me.BTT_MODE_SHOW_USERS.CheckOnClick = True
Me.BTT_MODE_SHOW_USERS.Name = "BTT_MODE_SHOW_USERS"
Me.BTT_MODE_SHOW_USERS.Size = New System.Drawing.Size(231, 22)
Me.BTT_MODE_SHOW_USERS.Text = "Show users"
'
'BTT_MODE_SHOW_SUBSCRIPTIONS
'
Me.BTT_MODE_SHOW_SUBSCRIPTIONS.CheckOnClick = True
Me.BTT_MODE_SHOW_SUBSCRIPTIONS.Name = "BTT_MODE_SHOW_SUBSCRIPTIONS"
Me.BTT_MODE_SHOW_SUBSCRIPTIONS.Size = New System.Drawing.Size(231, 22)
Me.BTT_MODE_SHOW_SUBSCRIPTIONS.Text = "Show subscriptions"
'
'BTT_SITE_ALL
'
Me.BTT_SITE_ALL.Name = "BTT_SITE_ALL"
@@ -632,6 +742,16 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_DONATE.Text = "Donate"
Me.BTT_DONATE.ToolTipText = "Support"
'
'BTT_BUG_REPORT
'
Me.BTT_BUG_REPORT.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.BTT_BUG_REPORT.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.BTT_BUG_REPORT.Image = CType(resources.GetObject("BTT_BUG_REPORT.Image"), System.Drawing.Image)
Me.BTT_BUG_REPORT.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_BUG_REPORT.Name = "BTT_BUG_REPORT"
Me.BTT_BUG_REPORT.Size = New System.Drawing.Size(23, 22)
Me.BTT_BUG_REPORT.Text = "Bug report"
'
'Toolbar_BOTTOM
'
Me.Toolbar_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_PR_INFO, Me.PR_PRE, Me.PR_MAIN, Me.LBL_JOBS_COUNT, Me.LBL_STATUS})
@@ -691,9 +811,9 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'
'USER_CONTEXT
'
Me.USER_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.BTT_CONTEXT_DOWN_LIMITED, Me.BTT_CONTEXT_DOWN_DATE_LIMIT, Me.BTT_CONTEXT_EDIT, Me.BTT_CONTEXT_DELETE, Me.BTT_CONTEXT_COPY_TO_FOLDER, CONTEXT_SEP_1, Me.BTT_CONTEXT_FAV, Me.BTT_CONTEXT_TEMP, Me.BTT_CONTEXT_READY, Me.BTT_CONTEXT_GROUPS, Me.BTT_CONTEXT_SCRIPT, Me.BTT_CONTEXT_ADD_TO_COL, Me.BTT_CONTEXT_COL_MERGE, Me.BTT_CONTEXT_CHANGE_FOLDER, CONTEXT_SEP_2, Me.BTT_CHANGE_IMAGE, CONTEXT_SEP_3, Me.BTT_CONTEXT_OPEN_PATH, CONTEXT_SEP_4, Me.BTT_CONTEXT_OPEN_SITE, CONTEXT_SEP_5, Me.BTT_CONTEXT_INFO})
Me.USER_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.BTT_CONTEXT_DOWN_LIMITED, Me.BTT_CONTEXT_DOWN_DATE_LIMIT, Me.BTT_CONTEXT_EDIT, Me.BTT_CONTEXT_DELETE, Me.BTT_CONTEXT_ERASE, Me.BTT_CONTEXT_COPY_TO_FOLDER, CONTEXT_SEP_1, Me.BTT_CONTEXT_FAV, Me.BTT_CONTEXT_TEMP, Me.BTT_CONTEXT_READY, Me.BTT_CONTEXT_GROUPS, Me.BTT_CONTEXT_SCRIPT, Me.BTT_CONTEXT_ADD_TO_COL, Me.BTT_CONTEXT_COL_MERGE, Me.BTT_CONTEXT_CHANGE_FOLDER, CONTEXT_SEP_2, Me.BTT_CHANGE_IMAGE, CONTEXT_SEP_3, Me.BTT_CONTEXT_OPEN_PATH, CONTEXT_SEP_4, Me.BTT_CONTEXT_OPEN_SITE, CONTEXT_SEP_5, Me.BTT_CONTEXT_INFO})
Me.USER_CONTEXT.Name = "USER_CONTEXT"
Me.USER_CONTEXT.Size = New System.Drawing.Size(222, 430)
Me.USER_CONTEXT.Size = New System.Drawing.Size(222, 452)
'
'BTT_CONTEXT_DOWN
'
@@ -734,6 +854,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Me.BTT_CONTEXT_DELETE.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_DELETE.Text = "Delete user / collection"
'
'BTT_CONTEXT_ERASE
'
Me.BTT_CONTEXT_ERASE.Image = Global.SCrawler.My.Resources.Resources.BrushToolPic_16
Me.BTT_CONTEXT_ERASE.Name = "BTT_CONTEXT_ERASE"
Me.BTT_CONTEXT_ERASE.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_ERASE.Text = "Erase data"
'
'BTT_CONTEXT_COPY_TO_FOLDER
'
Me.BTT_CONTEXT_COPY_TO_FOLDER.Image = Global.SCrawler.My.Resources.Resources.PastePic_32
@@ -757,16 +884,19 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'
'BTT_CONTEXT_READY
'
Me.BTT_CONTEXT_READY.Image = Global.SCrawler.My.Resources.Resources.OkPic_32
Me.BTT_CONTEXT_READY.Name = "BTT_CONTEXT_READY"
Me.BTT_CONTEXT_READY.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_READY.Text = "Change ready for download"
'
'BTT_CONTEXT_GROUPS
'
Me.BTT_CONTEXT_GROUPS.AutoToolTip = True
Me.BTT_CONTEXT_GROUPS.Image = Global.SCrawler.My.Resources.Resources.TagPic_24
Me.BTT_CONTEXT_GROUPS.Name = "BTT_CONTEXT_GROUPS"
Me.BTT_CONTEXT_GROUPS.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_GROUPS.Text = "Change labels"
Me.BTT_CONTEXT_GROUPS.ToolTipText = "Change user labels." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to include site-specific labels."
'
'BTT_CONTEXT_SCRIPT
'
@@ -784,6 +914,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'
'BTT_CONTEXT_COL_MERGE
'
Me.BTT_CONTEXT_COL_MERGE.Image = Global.SCrawler.My.Resources.Resources.DBPic_32
Me.BTT_CONTEXT_COL_MERGE.Name = "BTT_CONTEXT_COL_MERGE"
Me.BTT_CONTEXT_COL_MERGE.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_COL_MERGE.Text = "Merge collection files"
@@ -791,6 +922,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
'BTT_CONTEXT_CHANGE_FOLDER
'
Me.BTT_CONTEXT_CHANGE_FOLDER.AutoToolTip = True
Me.BTT_CONTEXT_CHANGE_FOLDER.Image = Global.SCrawler.My.Resources.Resources.FolderPic_32
Me.BTT_CONTEXT_CHANGE_FOLDER.Name = "BTT_CONTEXT_CHANGE_FOLDER"
Me.BTT_CONTEXT_CHANGE_FOLDER.Size = New System.Drawing.Size(221, 22)
Me.BTT_CONTEXT_CHANGE_FOLDER.Text = "Change folder"
@@ -954,7 +1086,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Private WithEvents BTT_CONTEXT_COL_MERGE As ToolStripMenuItem
Private WithEvents LBL_JOBS_COUNT As ToolStripStatusLabel
Private WithEvents BTT_DOWN_VIDEO As ToolStripMenuItem
Private WithEvents BTT_SHOW_INFO As PersonalUtilities.Forms.Controls.KeyClick.ToolStripButtonKeyClick
Private WithEvents MENU_INFO_SHOW_INFO As ToolStripMenuItem
Private WithEvents BTT_CHANNELS As ToolStripButton
Private WithEvents LIST_PROFILES As ListView
Private WithEvents MENU_VIEW As ToolStripDropDownButton
@@ -967,7 +1099,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Private WithEvents BTT_SHOW_LABELS As ToolStripMenuItem
Private WithEvents BTT_SHOW_NO_LABELS As ToolStripMenuItem
Private WithEvents BTT_EDIT_USER As ToolStripButton
Private WithEvents BTT_CONTEXT_GROUPS As ToolStripMenuItem
Private WithEvents BTT_CONTEXT_GROUPS As PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick
Private WithEvents BTT_VERSION_INFO As ToolStripButton
Private WithEvents BTT_CONTEXT_DOWN_LIMITED As ToolStripKeyMenuItem
Private WithEvents BTT_CONTEXT_READY As ToolStripMenuItem
@@ -1013,4 +1145,17 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
Private WithEvents BTT_TRAY_CHANNELS As ToolStripMenuItem
Private WithEvents BTT_TRAY_DOWNLOADER As ToolStripMenuItem
Private WithEvents PR_PRE As ToolStripProgressBar
Private WithEvents BTT_CONTEXT_ERASE As ToolStripMenuItem
Private WithEvents MENU_INFO_SHOW_MISSING As ToolStripMenuItem
Private WithEvents MENU_INFO_SHOW_USER_METRICS As ToolStripMenuItem
Private WithEvents BTT_MODE_SHOW_USERS As ToolStripMenuItem
Private WithEvents BTT_MODE_SHOW_SUBSCRIPTIONS As ToolStripMenuItem
Private WithEvents MENU_D_DOWN_ALL As ToolStripMenuItem
Private WithEvents MENU_D_DOWN_ALL_SITE As ToolStripMenuItem
Private WithEvents BTT_DOWN_ALL_SUBSCR As ToolStripKeyMenuItem
Private WithEvents BTT_DOWN_SITE_SUBSCR As ToolStripKeyMenuItem
Private WithEvents BTT_DOWN_ALL_FULL_SUBSCR As ToolStripKeyMenuItem
Private WithEvents BTT_DOWN_SITE_FULL_SUBSCR As ToolStripKeyMenuItem
Private WithEvents BTT_BUG_REPORT As ToolStripButton
Private WithEvents MENU_INFO_SHOW_QUEUE As ToolStripMenuItem
End Class

View File

@@ -147,46 +147,51 @@
<metadata name="SEP_4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="MENU_VIEW_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_VIEW_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TRAY_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TRAY_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TRAY_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_5.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="MENU_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_DOWN_ALL_SEP_6.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="MENU_VIEW_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="Toolbar_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>132, 17</value>
</metadata>
<data name="BTT_SHOW_INFO.ToolTipText" xml:space="preserve">
<value>Left-click: open the 'Info' form (show download summary).
Right click: open the 'Missing' form (show information about missing posts).
Ctrl+Shift+Click: open the "User metrics' form (show information about the user's metrics (such as size, number of files, etc.)).</value>
<data name="BTT_DOWN_SITE_FULL.ToolTipText" xml:space="preserve">
<value>Download all users from specific sites. The 'Ready for download' option will be ignored.
Shift+Click to download, including non-existent users.
Ctrl+Shift+Click to download, excluding from the feed, including non-existent users.</value>
</data>
<data name="BTT_DOWN_SITE_FULL_SUBSCR.ToolTipText" xml:space="preserve">
<value>Download all subscriptions from specific sites. The 'Ready for download' option will be ignored.
Shift+Click to download, including non-existent users.
Ctrl+Shift+Click to download, excluding from the feed, including non-existent users.</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -207,6 +212,21 @@ Ctrl+Shift+Click: open the "User metrics' form (show information about the user'
9k7wdgtW4wRqSHlCP7y2AjWmbMB7Y7DzqgZdz2iF9zrxCDXq2oU9uLz31+tgAcHahhp1DSFY9pGhRl29
CFYXxrMoQ7BmsZfFPkoRpHWow+56hX26BWkRatR1gRIEaQLvUMMpOyhCkBpxBzWcMoOgLUMNm0vUIWj2
ebaJF7jj5+hGTiqE/f+bxDRGUIt8LIp+AC/GHt3tQnwvAAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_BUG_REPORT.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="Toolbar_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View File

@@ -25,6 +25,7 @@ Public Class MainFrame
Friend MyChannels As ChannelViewForm
Friend MySavedPosts As DownloadSavedPostsForm
Private MyMissingPosts As MissingPostsForm
Private DownloadQueue As UserDownloadQueueForm
Private MyFeed As DownloadFeedForm
Private MySearch As UserSearchForm
Private MyUserMetrics As UsersInfoForm = Nothing
@@ -44,11 +45,16 @@ Public Class MainFrame
End With
BTT_IMPORT_USERS = New ToolStripMenuItem With {.Text = "Import", .Image = My.Resources.UsersIcon_32.ToBitmap}
MENU_SETTINGS.DropDownItems.AddRange({New ToolStripSeparator, BTT_IMPORT_USERS})
BTT_BUG_REPORT.Image = My.Resources.MailPic_16
End Sub
#End Region
#Region "Form handlers"
Private Async Sub MainFrame_Load(sender As Object, e As EventArgs) Handles Me.Load
If Now.Month.ValueBetween(6, 8) Then Text = "SCrawler: Happy LGBT Pride Month! :-)"
If Now.Month.ValueBetween(6, 8) Then
Text = "SCrawler: Happy LGBT Pride Month! :-)"
ElseIf Not Settings.ProgramText.IsEmptyString Then
Text = Settings.ProgramText
End If
Settings.DeleteCachePath()
MainFrameObj = New MainFrameObjects(Me)
MainFrameObj.ChangeCloseVisible()
@@ -94,6 +100,8 @@ Public Class MainFrame
UpdateLabelsGroups()
SetShowButtonsCheckers(.ShowingMode.Value)
CheckVersion(False)
BTT_MODE_SHOW_USERS.Checked = .MainFrameUsersShowDefaults
BTT_MODE_SHOW_SUBSCRIPTIONS.Checked = .MainFrameUsersShowSubscriptions
BTT_SITE_ALL.Checked = .SelectedSites.Count = 0
BTT_SITE_SPECIFIC.Checked = .SelectedSites.Count > 0
BTT_SHOW_LIMIT_DATES_NOT.Tag = ShowingDates.Not
@@ -151,6 +159,7 @@ Public Class MainFrame
Downloader.Dispose()
MyProgressForm.Dispose()
InfoForm.Dispose()
DownloadQueue.DisposeIfReady()
MyMissingPosts.DisposeIfReady()
MyFeed.DisposeIfReady()
MainFrameObj.ClearNotifications()
@@ -360,6 +369,7 @@ CloseResume:
Settings.Users.Add(UserDataBase.GetInstance(f.User))
With Settings.Users.Last
If Not .FileExists Then
.Options = f.Options
.Favorite = f.UserFavorite
.Temporary = f.UserTemporary
.ParseUserMediaOnly = f.UserMediaOnly
@@ -367,6 +377,8 @@ CloseResume:
.DownloadImages = f.DownloadImages
.DownloadVideos = f.DownloadVideos
.FriendlyName = f.UserFriendly
.BackColor = f.UserBackColor
.ForeColor = f.UserForeColor
.Description = f.UserDescr
.ScriptUse = f.ScriptUse
.ScriptData = f.ScriptData
@@ -403,18 +415,19 @@ CloseResume:
End Sub
#End Region
#Region "Info, Feed, Channels, Saved posts"
Private Sub BTT_SHOW_INFO_KeyClick(ByVal Sender As Object, ByVal e As Controls.KeyClick.KeyClickEventArgs) Handles BTT_SHOW_INFO.KeyClick
If e.MouseButton = MouseButtons.Right Then
If MyMissingPosts Is Nothing Then MyMissingPosts = New MissingPostsForm
If MyMissingPosts.Visible Then MyMissingPosts.BringToFront() Else MyMissingPosts.Show()
ElseIf e.MouseButton = MouseButtons.Left Then
If e.Control And e.Shift Then
If MyUserMetrics Is Nothing Then MyUserMetrics = New UsersInfoForm
MyUserMetrics.FormShowS
Else
InfoForm.FormShow()
End If
End If
Private Sub MENU_INFO_SHOW_INFO_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_INFO.Click
InfoForm.FormShow()
End Sub
Private Sub MENU_INFO_SHOW_QUEUE_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_QUEUE.Click
DownloadQueue.FormShow(EDP.LogMessageValue)
End Sub
Private Sub MENU_INFO_SHOW_MISSING_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_MISSING.Click
If MyMissingPosts Is Nothing Then MyMissingPosts = New MissingPostsForm
If MyMissingPosts.Visible Then MyMissingPosts.BringToFront() Else MyMissingPosts.Show()
End Sub
Private Sub MENU_INFO_SHOW_USER_METRICS_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_USER_METRICS.Click
If MyUserMetrics Is Nothing Then MyUserMetrics = New UsersInfoForm
MyUserMetrics.FormShowS
End Sub
Private Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click
If MyFeed Is Nothing Then MyFeed = New DownloadFeedForm : AddHandler Downloader.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
@@ -439,22 +452,39 @@ CloseResume:
End Sub
#End Region
#Region "Download"
Private Sub BTT_DOWN_SELECTED_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SELECTED.KeyClick
Private Sub BTT_DOWN_SELECTED_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_SELECTED.KeyClick
DownloadSelectedUser(DownUserLimits.None, e.IncludeInTheFeed)
End Sub
Private Sub BTT_DOWN_ALL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_ALL.KeyClick
Downloader.AddRange(Settings.GetUsers(Function(u) u.ReadyForDownload And u.Exists), e.IncludeInTheFeed)
#Region "Down all"
Private Sub BTT_DOWN_ALL_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_ALL.KeyClick
Downloader.AddRange(Settings.GetUsers(Function(u) u.ReadyForDownload And UserExistsNonSubscriptionsPredicate.Invoke(u)), e.IncludeInTheFeed)
End Sub
Private Sub BTT_DOWN_SITE_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SITE.KeyClick
DownloadSiteFull(True, e.IncludeInTheFeed)
Private Sub BTT_DOWN_ALL_SUBSCR_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_ALL_SUBSCR.KeyClick
Downloader.AddRange(Settings.GetUsers(Function(u) u.ReadyForDownload And UserExistsSubscriptionsPredicate.Invoke(u)), e.IncludeInTheFeed)
End Sub
Private Sub BTT_DOWN_ALL_FULL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_ALL_FULL.KeyClick
Downloader.AddRange(Settings.GetUsers(UserExistsPredicate), e.IncludeInTheFeed)
Private Sub BTT_DOWN_SITE_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_SITE.KeyClick
DownloadSiteFull(True, e.IncludeInTheFeed, False)
End Sub
Private Sub BTT_DOWN_SITE_FULL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL.KeyClick
DownloadSiteFull(False, e.IncludeInTheFeed, e.Shift)
Private Sub BTT_DOWN_SITE_SUBSCR_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_SITE_SUBSCR.KeyClick
DownloadSiteFull(True, e.IncludeInTheFeed, True)
End Sub
Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean, Optional ByVal IgnoreExists As Boolean = False)
#End Region
#Region "Down full"
Private Sub BTT_DOWN_ALL_FULL_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_ALL_FULL.KeyClick
Downloader.AddRange(Settings.GetUsers(UserExistsNonSubscriptionsPredicate), e.IncludeInTheFeed)
End Sub
Private Sub BTT_DOWN_ALL_FULL_SUBSCR_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_ALL_FULL_SUBSCR.KeyClick
Downloader.AddRange(Settings.GetUsers(UserExistsSubscriptionsPredicate), e.IncludeInTheFeed)
End Sub
Private Sub BTT_DOWN_SITE_FULL_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL.KeyClick
DownloadSiteFull(False, e.IncludeInTheFeed, False, e.Shift)
End Sub
Private Sub BTT_DOWN_SITE_FULL_SUBSCR_KeyClick(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL_SUBSCR.KeyClick
DownloadSiteFull(False, e.IncludeInTheFeed, True, e.Shift)
End Sub
#End Region
Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean,
ByVal Subscription As Boolean, Optional ByVal IgnoreExists As Boolean = False)
Using f As New SiteSelectionForm(Settings.LatestDownloadedSites.ValuesList)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
@@ -463,6 +493,7 @@ CloseResume:
Settings.LatestDownloadedSites.Update()
If f.SelectedSites.Count > 0 Then
Downloader.AddRange(Settings.GetUsers(Function(u) f.SelectedSites.Contains(u.Site) And (u.Exists Or IgnoreExists) And
u.IsSubscription = Subscription And
(Not ReadyForDownloadOnly Or u.ReadyForDownload)), IncludeInTheFeed)
End If
End If
@@ -521,7 +552,7 @@ CloseResume:
End Sub
#End Region
#Region "View"
#Region "1 - view mode"
#Region "1 - view mode list"
Private Sub BTT_VIEW_LARGE_Click(sender As Object, e As EventArgs) Handles BTT_VIEW_LARGE.Click
ApplyViewPattern(ViewModes.IconLarge)
End Sub
@@ -558,7 +589,17 @@ CloseResume:
End If
End Sub
#End Region
#Region "2 - view site"
#Region "2 - view mode users"
Private Sub BTT_MODE_SHOW_USERS_Click(sender As Object, e As EventArgs) Handles BTT_MODE_SHOW_USERS.Click
Settings.MainFrameUsersShowDefaults.Value = BTT_MODE_SHOW_USERS.Checked
RefillList()
End Sub
Private Sub BTT_MODE_SHOW_SUBSCRIPTIONS_Click(sender As Object, e As EventArgs) Handles BTT_MODE_SHOW_SUBSCRIPTIONS.Click
Settings.MainFrameUsersShowSubscriptions.Value = BTT_MODE_SHOW_SUBSCRIPTIONS.Checked
RefillList()
End Sub
#End Region
#Region "3 - view site"
Private Sub BTT_SITE_ALL_Click(sender As Object, e As EventArgs) Handles BTT_SITE_ALL.Click
Settings.SelectedSites.Clear()
Settings.SelectedSites.Update()
@@ -580,7 +621,7 @@ CloseResume:
End Using
End Sub
#End Region
#Region "3 - view filters"
#Region "4 - view filters"
Private Sub BTT_SHOW_ALL_Click(sender As Object, e As EventArgs) Handles BTT_SHOW_ALL.Click
SetShowButtonsCheckers(ShowingModes.All)
End Sub
@@ -665,7 +706,7 @@ CloseResume:
End Using
End Function
#End Region
#Region "4 - view dates"
#Region "5 - view dates"
Private Sub BTT_SHOW_LIMIT_DATES_NOT_IN_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles BTT_SHOW_LIMIT_DATES_NOT.Click,
BTT_SHOW_LIMIT_DATES_IN.Click
Dim r As Boolean = False
@@ -717,6 +758,15 @@ CloseResume:
Private Sub BTT_DONATE_Click(sender As Object, e As EventArgs) Handles BTT_DONATE.Click
Try : Process.Start("https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md") : Catch : End Try
End Sub
Private Sub BTT_BUG_REPORT_Click(sender As Object, e As EventArgs) Handles BTT_BUG_REPORT.Click
Try
With Settings
Using f As New BugReporterForm(.Cache, .Design, .ProgramText, My.Application.Info.Version,
False, .Self, .ProgramDescription) : f.ShowDialog() : End Using
End With
Catch
End Try
End Sub
#End Region
#Region "List handlers"
Private _LatestSelected As Integer = -1
@@ -753,6 +803,32 @@ CloseResume:
Private Sub BTT_CONTEXT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DELETE.Click
DeleteSelectedUser()
End Sub
Private Sub BTT_CONTEXT_ERASE_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_ERASE.Click
Const msgTitle$ = "Erase data"
Try
Dim users As List(Of IUserData) = GetSelectedUserArray()
If users.ListExists Then
Dim m As IUserData.EraseMode = UserDataBase.GetEraseMode(users)
If Not m = IUserData.EraseMode.None Then
Dim nd As New List(Of IUserData)
For Each user As IUserData In users
If Not user.EraseData(m) Then nd.Add(user)
Next
If nd.Count = 0 Then
MsgBoxE({"All user data has been erased.", msgTitle})
Else
MsgBoxE(New MMessage("The data of the following users has not been erased:" &
vbCr.StringDup(2) & nd.ListToStringE(vbCr, GetUserListProvider(True)), msgTitle,,
MsgBoxStyle.Exclamation) With {.Editable = True})
End If
End If
Else
MsgBoxE({"No user selected", msgTitle}, vbExclamation)
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, msgTitle)
End Try
End Sub
Private Sub BTT_CONTEXT_COPY_TO_FOLDER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_COPY_TO_FOLDER.Click
CopyUserData()
End Sub
@@ -784,19 +860,24 @@ CloseResume:
End Sub)
End If
End Sub
Private Sub BTT_CONTEXT_GROUPS_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_GROUPS.Click
Private Sub BTT_CONTEXT_GROUPS_Click(ByVal Sender As Object, ByVal e As Controls.KeyClick.KeyClickEventArgs) Handles BTT_CONTEXT_GROUPS.KeyClick
Const MsgTitle$ = "Label change"
Try
Dim users As List(Of IUserData) = GetSelectedUserArray()
If users.ListExists Then
Dim l As List(Of String) = ListAddList(Nothing, users.SelectMany(Function(u) u.Labels), LAP.NotContainsOnly)
Dim lex As List(Of String) = ListAddList(Nothing, users.SelectMany(Function(u As UserDataBase) u.SpecialLabels), LNC)
Dim initialCount% = l.Count
Dim isOneUser As Boolean = users.Count = 1 AndAlso Not users(0).IsCollection
Dim inclSpec As Boolean = (e.Control And (users.Count > 1 Or (users.Count = 1 And users(0).IsCollection))) Or isOneUser
If Not inclSpec Then l.ListWithRemove(lex)
Using f As New LabelsForm(l) With {.WithDeleteButton = l.Count > 0}
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
Dim labels As List(Of String) = f.LabelsList
Dim lp As New ListAddParams(LAP.NotContainsOnly)
Dim a As Action(Of IUserData) = Sub(u) u.Labels.ListAddList(labels, lp)
Dim cMsg As New MMessage("Operation canceled", MsgTitle)
Dim upMode As Byte
Dim keepSpecial As Boolean = True
If labels.ListExists Then
Select Case MsgBoxE(New MMessage($"What do you want to do with the selected labels?{vbCr}Selected labels:{vbCr}{labels.ListToString(vbCr)}",
MsgTitle,
@@ -806,27 +887,25 @@ CloseResume:
New MsgBoxButton("Remove", "These labels will be removed from the existing ones"),
"Cancel"
}, vbExclamation) With {.ButtonsPerRow = 2}).Index
Case 0 : lp.ClearBeforeAdd = True
Case 1 : lp.ClearBeforeAdd = False
Case 2 : a = Sub(u) u.Labels.ListDisposeRemove(labels)
Case 0 : upMode = 1
Case 1 : upMode = 0
Case 2 : upMode = 2
Case Else : cMsg.Show() : Exit Sub
End Select
Else
If MsgBoxE({"Are you sure you want to remove all labels?", MsgTitle}, vbExclamation + vbYesNo) = vbYes Then
a = Sub(u) u.Labels.Clear()
upMode = 1
Else
cMsg.Show()
Exit Sub
End If
End If
If lex.ListExists AndAlso Not isOneUser AndAlso (l.ListContains(lex) Or (Not inclSpec And Not l.Count = initialCount)) Then _
keepSpecial = UserDataBase.UpdateLabelsKeepSpecial(upMode)
users.ForEach(Sub(ByVal u As IUserData)
If u.IsCollection Then
With DirectCast(u, UserDataBind)
If .Count > 0 Then .Collections.ForEach(a)
End With
Else
a.Invoke(u)
End If
UserDataBase.UpdateLabels(u, labels, upMode, keepSpecial)
u.UpdateUserInformation()
End Sub)
End If
@@ -881,6 +960,8 @@ CloseResume:
Dim _col_user As Predicate(Of IUserData) = Function(u) u.IsCollection
Dim userCollection As UserDataBind = users.Find(_col_user)
Dim _col_name$ = String.Empty
Dim _col_dest As SFile = Nothing
Dim allUsersIsSubscriptions As Boolean
Dim userProvider As IFormatProvider = GetUserListProvider(False)
If Not userCollection Is Nothing Then
i = users.LongCount(Function(u) _col_user(u))
@@ -895,17 +976,23 @@ CloseResume:
If _col_name.IsEmptyString Then
Using f As New CollectionEditorForm
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then _col_name = f.Collection
If f.DialogResult = DialogResult.OK Then
_col_name = f.MyCollection
_col_dest = f.MyCollectionSpecialPath
End If
End Using
End If
If _col_name.IsEmptyString Then
MsgBoxE({"The destination collection has not been selected.", MsgTitle}, vbExclamation)
Else
With (From u In users Where Not u.IsCollection Select u.IsSubscription)
allUsersIsSubscriptions = .ListExists AndAlso .All(Function(u) u)
End With
With Settings
userCollection = .Users.Find(Function(u) u.IsCollection And u.CollectionName = _col_name)
Dim Added As Boolean = userCollection Is Nothing
If Added Then
.Users.Add(New UserDataBind(_col_name))
.Users.Add(New UserDataBind(_col_name, _col_dest))
MainFrameObj.CollectionHandler(DirectCast(.Users.Last, UserDataBind))
userCollection = .Users.Last
End If
@@ -915,10 +1002,18 @@ CloseResume:
Dim __ModelAskForDecision As Boolean = False
If Not Added Then __modelCollection = userCollection.CollectionModel
If Added Then
__ModelAskForDecision = True
If allUsersIsSubscriptions Then
__modelUser = UsageModel.Virtual
__modelCollection = UsageModel.Virtual
Else
__ModelAskForDecision = True
End If
ElseIf userCollection.CollectionModel = UsageModel.Virtual Then
__modelUser = UsageModel.Virtual
__modelCollection = UsageModel.Virtual
ElseIf allUsersIsSubscriptions Then
__modelCollection = userCollection.CollectionModel
__modelUser = UsageModel.Virtual
Else
__ModelAskForDecision = True
End If
@@ -966,7 +1061,11 @@ CloseResume:
For Each user As UserDataBase In users
If Not user.IsCollection Then
Try
user.User.UserModel = IIf(user.HOST.Key = PathPlugin.PluginKey, UsageModel.Virtual, __modelUser)
If user.IsSubscription Then
user.User.UserModel = UsageModel.Virtual
Else
user.User.UserModel = IIf(user.HOST.Key = PathPlugin.PluginKey, UsageModel.Virtual, __modelUser)
End If
user.User.CollectionModel = __modelCollection
userCollection.Add(user)
RemoveUserFromList(user)
@@ -1027,23 +1126,84 @@ CloseResume:
End If
End Sub
Private Sub BTT_CONTEXT_CHANGE_FOLDER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_CHANGE_FOLDER.Click
ChangeUserDestination(GetSelectedUserArray(), True)
End Sub
Private Function ChangeUserDestination(ByVal users As IEnumerable(Of IUserData), ByVal InitialInvoke As Boolean,
Optional ByVal NewUsersLocation As STDownloader.DownloadLocation? = Nothing) As Boolean
Const MsgTitle$ = "Change user folder"
Dim automationPaused As Boolean = Not Settings.Automation.Pause = PauseModes.Disabled
Try
If Downloader.Working Then
MsgBoxE({"Some users are currently downloading." & vbCr &
"You cannot change paths while downloading." & vbCr &
"Wait until the download is complete.", MsgTitle}, vbCritical)
Exit Sub
Else
Downloader.Suspended = True
End If
Dim users As List(Of IUserData) = GetSelectedUserArray()
Dim msgShowing As New ErrorsDescriber(If(InitialInvoke, EDP.ShowMainMsg, EDP.None))
If users.ListExists Then
If Downloader.Working Then
MsgBoxE({"Some users are currently downloading." & vbCr &
"You cannot change paths while downloading." & vbCr &
"Wait until the download is complete.", MsgTitle}, vbCritical)
Return False
Else
If InitialInvoke Then
Downloader.Suspended = True
If Not automationPaused Then Settings.Automation.Pause = PauseModes.Unlimited
End If
End If
Dim locationChooser As GlobalLocationsChooserForm
Dim newLoc As STDownloader.DownloadLocation
If users.Count > 1 Then
Dim multiUserMsgTxt$ = "You have selected multiple users to change their destinations." & vbCr &
"It is highly recommended to change the destination for one user at a time."
If users.ListExists(Function(u) u.IsCollection And Not u.IsVirtual) Then _
multiUserMsgTxt &= vbCr & vbCr & "A collection was also found in your selection." & vbCr &
"The collection movement model is always the only one, regardless of the path model you choose."
multiUserMsgTxt &= vbCr & vbCr & $"Selected users:{vbCr}{users.ListToStringE(vbCr, GetUserListProvider(True))}."
Select Case MsgBoxE({multiUserMsgTxt, MsgTitle}, vbExclamation,,,
{New MsgBoxButton("Process", "Change the destination for all the users you selected"),
New MsgBoxButton("First only", "Process only the first user in the selection"),
"Cancel"}).Index
Case 0
locationChooser = New GlobalLocationsChooserForm With {
.MyIsMultipleUsers = True,
.MyNonMyltipleUser = If(users.FirstOrDefault(Function(u) Not u.IsCollection), users(0)),
.MyIsCollectionSelector = users.All(Function(u) u.IsCollection)
}
With locationChooser
.ShowDialog()
If .DialogResult = DialogResult.OK Then
newLoc = .MyDestination
.Dispose()
Else
.Dispose()
ShowOperationCanceledMsg(MsgTitle)
Return False
End If
End With
With users.Where(Function(u) Not ChangeUserDestination({u}, False, newLoc))
If .ListExists Then
If .Count = users.Count Then
MsgBoxE({"None of the users' destinations have been changed!", MsgTitle}, vbCritical)
Return False
Else
MsgBoxE({$"The following users' destinations have not been changed:{vbCr}" &
users.ListToStringE(vbCr, GetUserListProvider(True)), MsgTitle}, vbCritical)
Return True
End If
Else
MsgBoxE({"Users' data has been moved", MsgTitle})
Return True
End If
End With
Case 1 : users = New List(Of IUserData) From {users.First}
Case Else : ShowOperationCanceledMsg(MsgTitle) : Return False
End Select
End If
If users.Count = 1 Then
Dim CutOption% = 1
Dim _IsCollection As Boolean = False
Dim CurrDir As SFile
Dim colName$ = String.Empty
Dim pathHandler As PathMoverHandler
With users(0)
If .IsCollection Then
_IsCollection = True
@@ -1054,50 +1214,74 @@ CloseResume:
MsgBoxE({"This is a virtual collection." & vbCr &
"The virtual collection path cannot be changed." & vbCr &
"To change the paths of users included in a virtual collection, " &
"you must split the collection and then change the user paths.", MsgTitle}, vbCritical)
Exit Sub
"you must split the collection and then change the user paths.", MsgTitle}, vbCritical, msgShowing)
Return False
Else
CurrDir = .GetRealUserFile
If CurrDir.IsEmptyString Then
MsgBoxE({"Non-virtual users not found", MsgTitle}, vbCritical)
Exit Sub
MsgBoxE({"Non-virtual users not found", MsgTitle}, vbCritical, msgShowing)
Return False
End If
CurrDir = CurrDir.CutPath(IIf(.DataMerging, 3, 2))
colName = CurrDir.Segments.LastOrDefault
colName = .CollectionName
Dim vu As IEnumerable(Of IUserData) = .Where(Function(vuu) vuu.UserModel = UsageModel.Virtual Or vuu.HOST.Key = PathPlugin.PluginKey)
If vu.ListExists Then
If MsgBoxE({"This collection contains virtual users and/or paths." & vbCr &
"If you continue, the virtual user paths will not be changed." & vbCr &
"The following users have been added to the collection in virtual mode:" & vbCr &
vu.ListToStringE(vbCr, GetUserListProvider(False)), MsgTitle},
vbExclamation,,, {"Continue", "Cancel"}) = 1 Then MsgBoxE({"Operation canceled", MsgTitle}) : Exit Sub
If InitialInvoke AndAlso MsgBoxE({"This collection contains virtual users and/or paths." & vbCr &
"If you continue, the virtual user paths will not be changed." & vbCr &
"The following users have been added to the collection in virtual mode:" & vbCr &
vu.ListToStringE(vbCr, GetUserListProvider(False)), MsgTitle},
vbExclamation,,, {"Continue", "Cancel"}) = 1 Then ShowOperationCanceledMsg(MsgTitle) : Return False
End If
End If
End With
ElseIf .HOST.Key = PathPlugin.PluginKey Then
MsgBoxE({"This is the path (not user). The paths cannot be changed.", MsgTitle}, vbCritical)
Exit Sub
MsgBoxE({"This is the path (not user). The paths cannot be changed.", MsgTitle}, vbCritical, msgShowing)
Return False
Else
CurrDir = .Self.File.CutPath(1)
End If
Dim NewDest As SFile = SFile.SelectPath(CurrDir, $"Select a new destination for {IIf(_IsCollection, "collection", "user")} [{ .Self}]")
Dim NewDest2 As SFile
If NewUsersLocation.HasValue Then
newLoc = NewUsersLocation.Value
Else
locationChooser = New GlobalLocationsChooserForm With {.MyInitialLocation = CurrDir}
locationChooser.MyNonMyltipleUser = .Self()
If _IsCollection Then
locationChooser.MyIsCollectionSelector = True
locationChooser.MyCollectionName = colName
End If
With locationChooser
.ShowDialog()
If .DialogResult = DialogResult.OK Then
newLoc = .MyDestination
colName = .MyCollectionName
.Dispose()
Else
.Dispose()
If InitialInvoke Then ShowOperationCanceledMsg(MsgTitle)
Return False
End If
End With
End If
If .IsCollection Then
pathHandler = GlobalLocationsChooserForm.ModelHandler(PathCreationModel.Collection)
Else
pathHandler = GlobalLocationsChooserForm.ModelHandler(newLoc.Model)
End If
Dim NewDest As SFile
If .IsCollection Then
If Not InitialInvoke Then
NewDest = $"{newLoc.Path.CSFilePS}{SettingsCLS.CollectionsFolderName}\{ .CollectionName}\"
Else
NewDest = $"{newLoc.Path.CSFilePS}{ .CollectionName}\"
End If
Else
NewDest = pathHandler.Invoke(DirectCast(.Self, UserDataBase).User, newLoc.Path.CSFileP)
End If
If Not NewDest.IsEmptyString Then
NewDest = $"{NewDest.PathWithSeparator}{colName}\"
NewDest2 = $"{NewDest.PathWithSeparator}{CurrDir.Segments.LastOrDefault().StringAppend("\", String.Empty)}"
Dim choice% = MsgBoxE(New MMessage($"You are changing the user's [{ .Self}] destination" & vbCr &
$"Current destination: {CurrDir.PathNoSeparator}" & vbCr &
$"New destination [1]: {NewDest.PathNoSeparator}" & vbCr &
$"New destination [2]: {NewDest2.PathWithSeparator}",
MsgTitle,
{New MsgBoxButton("Confirm [1] (Enter)", "Move the data to the destination [1]."),
New MsgBoxButton("Confirm [2]", "Move the data to the destination [2].") With {.KeyCode = Keys.D2},
"Cancel"},
MsgBoxStyle.Exclamation) With {.AppendKeyCode = False})
If choice < 2 Then
If choice = 1 Then NewDest = NewDest2
If Not NewDest.IsEmptyString AndAlso
If Not NewDest.IsEmptyString AndAlso
(Not NewDest.Exists(SFO.Path, False) OrElse
(
SFile.GetFiles(NewDest,, IO.SearchOption.AllDirectories, EDP.ThrowException).ListIfNothing.Count = 0 AndAlso
@@ -1105,54 +1289,92 @@ CloseResume:
Not NewDest.Exists(SFO.Path, False)
)
) Then
If SFile.Move(CurrDir, NewDest, SFO.Path,,, EDP.ShowMainMsg + EDP.ReturnValue) Then
Dim ApplyChanges As Action(Of IUserData) = Sub(ByVal __user As IUserData)
With DirectCast(__user, UserDataBase)
Dim u As UserInfo = .User
Settings.UsersList.Remove(u)
If _IsCollection Then
If SFile.Move(CurrDir, NewDest, SFO.Path,,, EDP.ReturnValue + If(InitialInvoke, EDP.ShowMainMsg, 0)) Then
Dim colRootDef As SFile = Settings.CollectionsPathF
Dim __UserSpecialPathsEquals As Func(Of UserInfo, Boolean, Boolean) =
Function(ByVal __user As UserInfo, ByVal __isCol As Boolean) As Boolean
Dim u1 As UserInfo = __user
Dim u2 As UserInfo = __user
If __isCol Then
u1.CollectionName = colName
u1.SpecialPath = Nothing
u1.SpecialCollectionPath = Nothing
u2.CollectionName = colName
u2.SpecialPath = Nothing
u2.SpecialCollectionPath = NewDest
Else
u1.CollectionName = String.Empty
u1.SpecialPath = Nothing
u1.SpecialCollectionPath = Nothing
u2.CollectionName = String.Empty
u2.SpecialPath = NewDest
u2.SpecialCollectionPath = Nothing
End If
u1.UpdateUserFile()
u2.UpdateUserFile()
Return u1.File = u2.File
End Function
Dim ApplyChanges As Action(Of IUserData) = Sub(ByVal __user As IUserData)
With DirectCast(__user, UserDataBase)
Dim u As UserInfo = .User
Settings.UsersList.Remove(u)
If _IsCollection Then
u.CollectionName = colName
If Not __UserSpecialPathsEquals(u, True) Then
u.SpecialCollectionPath = NewDest
Else
u.SpecialPath = NewDest
u.SpecialCollectionPath = Nothing
End If
u.UpdateUserFile()
Settings.UsersList.Add(u)
.User = u
.UpdateUserInformation()
End With
End Sub
If .Self.IsCollection Then
With DirectCast(.Self, UserDataBind)
For Each user In .Collections : ApplyChanges(user) : Next
End With
Else
ApplyChanges(.Self)
End If
Settings.UpdateUsersList()
MsgBoxE({"User data has been moved", MsgTitle})
u.SpecialPath = Nothing
Else
u.CollectionName = String.Empty
If Not __UserSpecialPathsEquals(u, False) Then
u.SpecialPath = NewDest
Else
u.SpecialPath = Nothing
End If
u.SpecialCollectionPath = Nothing
End If
u.UpdateUserFile()
Settings.UsersList.Add(u)
.User = u
.UpdateUserInformation()
End With
End Sub
If .IsCollection Then
With DirectCast(.Self, UserDataBind)
For Each user In .Collections : ApplyChanges(user) : Next
End With
Else
ApplyChanges(.Self)
End If
Else
MsgBoxE({$"Unable to move user data to new destination [{NewDest}]{vbCr}Operation canceled", MsgTitle}, MsgBoxStyle.Critical)
Settings.UpdateUsersList()
MsgBoxE({"User data has been moved", MsgTitle},, msgShowing)
Return True
End If
Else
MsgBoxE({"Operation canceled", MsgTitle})
MsgBoxE({$"Unable to move user data to new destination [{NewDest}]{vbCr}Operation canceled", MsgTitle}, MsgBoxStyle.Critical, msgShowing)
End If
Else
MsgBoxE({$"You have not entered a new destination{vbCr}Operation canceled", MsgTitle}, MsgBoxStyle.Exclamation)
MsgBoxE({$"You have not entered a new destination{vbCr}Operation canceled", MsgTitle}, MsgBoxStyle.Exclamation, msgShowing)
End If
End With
Else
MsgBoxE({"You have selected multiple users. You can change the folder only for one user!", MsgTitle}, MsgBoxStyle.Critical)
MsgBoxE({"You have selected multiple users. You can change the folder only for one user!", MsgTitle}, MsgBoxStyle.Critical, msgShowing)
End If
Else
MsgBoxE({"No one user selected", MsgTitle}, MsgBoxStyle.Exclamation)
MsgBoxE({"No one user selected", MsgTitle}, MsgBoxStyle.Exclamation, msgShowing)
End If
Return False
Catch ex As Exception
ErrorsDescriber.Execute(EDP.ShowAllMsg, ex, "Error while moving user")
Return ErrorsDescriber.Execute(EDP.ReturnValue + If(InitialInvoke, EDP.ShowAllMsg, EDP.SendToLog), ex, "Error while moving user", False)
Finally
Downloader.Suspended = False
If InitialInvoke Then
Downloader.Suspended = False
If Not automationPaused Then Settings.Automation.Pause = PauseModes.Disabled
End If
End Try
End Sub
End Function
#End Region
#Region "3 - change image"
Private Sub BTT_CHANGE_IMAGE_Click(sender As Object, e As EventArgs) Handles BTT_CHANGE_IMAGE.Click
@@ -1193,6 +1415,7 @@ CloseResume:
BTT_CONTEXT_DOWN.DropDownItems.AddRange(.ContextDown)
BTT_CONTEXT_EDIT.DropDownItems.AddRange(.ContextEdit)
BTT_CONTEXT_DELETE.DropDownItems.AddRange(.ContextDelete)
BTT_CONTEXT_ERASE.DropDownItems.AddRange(.ContextErase)
BTT_CONTEXT_OPEN_PATH.DropDownItems.AddRange(.ContextPath)
BTT_CONTEXT_OPEN_SITE.DropDownItems.AddRange(.ContextSite)
End With
@@ -1201,6 +1424,7 @@ CloseResume:
BTT_CONTEXT_DOWN.DropDownItems.Clear()
BTT_CONTEXT_EDIT.DropDownItems.Clear()
BTT_CONTEXT_DELETE.DropDownItems.Clear()
BTT_CONTEXT_ERASE.DropDownItems.Clear()
BTT_CONTEXT_OPEN_PATH.DropDownItems.Clear()
BTT_CONTEXT_OPEN_SITE.DropDownItems.Clear()
End If
@@ -1248,7 +1472,7 @@ CloseResume:
#Region "Operation providers"
Private OperationsUserListProvider As IFormatProvider = Nothing
Private OperationsUserListProviderCollections As IFormatProvider = Nothing
Private Function GetUserListProvider(ByVal WithCollections As Boolean) As IFormatProvider
Friend Function GetUserListProvider(ByVal WithCollections As Boolean) As IFormatProvider
If WithCollections Then
If OperationsUserListProviderCollections Is Nothing Then _
OperationsUserListProviderCollections = New CustomProvider(Function(v, d, p, n, ee)
@@ -1393,46 +1617,46 @@ ResumeDownloadingOperation:
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
Dim NeedToUpdate As Boolean = True
If user.IsCollection Then
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 &
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)
Exit Sub
Else
If Not user.IsVirtual Then
Dim colFile As SFile = DirectCast(user, UserDataBind).GetRealUserFile
If Not colFile.IsEmptyString Then
colFile = colFile.CutPath(IIf(DirectCast(user, UserDataBind).DataMerging, 1, 2))
If Not colFile.IsEmptyString Then
Dim nf As SFile = $"{colFile.CutPath(1).PathWithSeparator}{f.CollectionName}".CSFilePS
If Not SFile.Rename(colFile, New SFile With {.Path = f.CollectionName}, SFO.Path,
New ErrorsDescriber(True, False, False, New SFile)).IsEmptyString Then
RemoveUserFromList(user)
Dim __user As UserInfo
For Each ColUser As UserDataBase In DirectCast(user, UserDataBind).Collections
__user = ColUser.User
Settings.UsersList.Remove(__user)
__user.CollectionName = f.CollectionName
If Not __user.SpecialCollectionPath.IsEmptyString Then __user.SpecialCollectionPath = nf
__user.UpdateUserFile()
ColUser.User = __user
Settings.UsersList.Add(__user)
Next
user.UpdateUserInformation()
UserListUpdate(user, True)
NeedToUpdate = False
End If
Exit Sub
Else
If Not user.IsVirtual Then
Dim rUser As UserDataBase = DirectCast(user, UserDataBind).GetRealUser
If Not rUser Is Nothing Then
Dim colPathCurr As SFile = rUser.User.GetCollectionRootPath
Dim colPathNew As SFile = SFile.GetPath(colPathCurr.CutPath.PathWithSeparator & f.CollectionName)
If Not colPathCurr.Exists(SFO.Path, False) Then
MsgBoxE({"Original location of collection not found. Operation canceled.", MsgTitle}, vbCritical)
ElseIf colPathNew.Exists(SFO.Path, False) Then
MsgBoxE({"The new collection location already exists. Operation canceled.", MsgTitle}, vbCritical)
Else
If Not SFile.Rename(colPathCurr, colPathNew, SFO.Path, New ErrorsDescriber(True, False, False, New SFile)).IsEmptyString Then
RemoveUserFromList(user)
Dim __user As UserInfo
For Each ColUser As UserDataBase In DirectCast(user, UserDataBind).Collections
__user = ColUser.User
Settings.UsersList.Remove(__user)
__user.CollectionName = f.CollectionName
If Not __user.SpecialCollectionPath.IsEmptyString Then __user.SpecialCollectionPath = colPathNew
__user.UpdateUserFile()
ColUser.User = __user
Settings.UsersList.Add(__user)
Next
user.UpdateUserInformation()
UserListUpdate(user, True)
NeedToUpdate = False
End If
End If
Else
RemoveUserFromList(user)
user.CollectionName = f.CollectionName
user.UpdateUserInformation()
UserListUpdate(user, True)
NeedToUpdate = False
End If
Else
RemoveUserFromList(user)
DirectCast(user, UserDataBind).ChangeVirtualCollectionName(f.CollectionName)
UserListUpdate(user, True)
NeedToUpdate = False
End If
End If
End If

Some files were not shown because too many files have changed in this diff Show More