).)*?)(\)",
+ 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
diff --git a/SCrawler/API/PornHub/SiteSettings.vb b/SCrawler/API/PornHub/SiteSettings.vb
index e3d6969..67eecbf 100644
--- a/SCrawler/API/PornHub/SiteSettings.vb
+++ b/SCrawler/API/PornHub/SiteSettings.vb
@@ -27,6 +27,14 @@ Namespace API.PornHub
End Property
Friend Property DownloadUHD As PropertyValue
+
+ Friend Property DownloadUploaded As PropertyValue
+
+ Friend Property DownloadTagged As PropertyValue
+
+ Friend Property DownloadPrivate As PropertyValue
+
+ Friend Property DownloadFavorite As PropertyValue
Friend ReadOnly Property DownloadGifs As PropertyValue
@@ -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
-
+
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"
diff --git a/SCrawler/API/PornHub/UserData.vb b/SCrawler/API/PornHub/UserData.vb
index c2f21d7..15b1811 100644
--- a/SCrawler/API/PornHub/UserData.vb
+++ b/SCrawler/API/PornHub/UserData.vb
@@ -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$ = "Error Page Not Found"
+ 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
\ No newline at end of file
diff --git a/SCrawler/API/PornHub/UserExchangeOptions.vb b/SCrawler/API/PornHub/UserExchangeOptions.vb
index f2d1556..1a4fde3 100644
--- a/SCrawler/API/PornHub/UserExchangeOptions.vb
+++ b/SCrawler/API/PornHub/UserExchangeOptions.vb
@@ -8,9 +8,17 @@
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes
Namespace API.PornHub
- Friend Class UserExchangeOptions
+ Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
Friend Property DownloadUHD As Boolean
+
+ Friend Property DownloadUploaded As Boolean
+
+ Friend Property DownloadTagged As Boolean
+
+ Friend Property DownloadPrivate As Boolean
+
+ Friend Property DownloadFavorite As Boolean
Friend Property DownloadGifs As Boolean
@@ -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
diff --git a/SCrawler/API/Reddit/IChannelLimits.vb b/SCrawler/API/Reddit/IChannelLimits.vb
new file mode 100644
index 0000000..e224ce2
--- /dev/null
+++ b/SCrawler/API/Reddit/IChannelLimits.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/API/Reddit/M3U8.vb b/SCrawler/API/Reddit/M3U8.vb
index 0c9b331..c064beb 100644
--- a/SCrawler/API/Reddit/M3U8.vb
+++ b/SCrawler/API/Reddit/M3U8.vb
@@ -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"
diff --git a/SCrawler/API/Reddit/SiteSettings.vb b/SCrawler/API/Reddit/SiteSettings.vb
index 8aa0bba..0c38160 100644
--- a/SCrawler/API/Reddit/SiteSettings.vb
+++ b/SCrawler/API/Reddit/SiteSettings.vb
@@ -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
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
-
+#End Region
+#Region "Declarations"
+#Region "Authorization"
+
+ Friend ReadOnly Property AuthUserName As PropertyValue
+
+ Friend ReadOnly Property AuthPassword As PropertyValue
+
+ Friend ReadOnly Property ApiClientID As PropertyValue
+
+ Friend ReadOnly Property ApiClientSecret As PropertyValue
+
+ Friend ReadOnly Property BearerToken As PropertyValue
+#Region "TokenUpdateInterval"
+
+ Friend ReadOnly Property TokenUpdateInterval As PropertyValue
+
+ Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
+#End Region
+ Private ReadOnly Property BearerTokenDateUpdate As PropertyValue
+
+ Friend ReadOnly Property UseTokenForTimelines As PropertyValue
+
+ Friend ReadOnly Property UseTokenForSavedPosts As PropertyValue
+
+ Friend ReadOnly Property UseCookiesForTimelines As PropertyValue
+
Friend ReadOnly Property SavedPostsUserName As PropertyValue
-
+#End Region
+#Region "Other"
+
Friend ReadOnly Property UseM3U8 As PropertyValue
+#End Region
+#End Region
+#Region "Initializer"
Friend Sub New()
MyBase.New(RedditSite, "reddit.com")
+
+ 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"
+
+ 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
+
+ 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
\ No newline at end of file
diff --git a/SCrawler/API/Reddit/UserData.vb b/SCrawler/API/Reddit/UserData.vb
index e8d78c8..3464cd6 100644
--- a/SCrawler/API/Reddit/UserData.vb
+++ b/SCrawler/API/Reddit/UserData.vb
@@ -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
diff --git a/SCrawler/API/Redgifs/SiteSettings.vb b/SCrawler/API/Redgifs/SiteSettings.vb
index e664b28..8319762 100644
--- a/SCrawler/API/Redgifs/SiteSettings.vb
+++ b/SCrawler/API/Redgifs/SiteSettings.vb
@@ -28,7 +28,7 @@ Namespace API.RedGifs
Return My.Resources.SiteResources.RedGifsPic_32
End Get
End Property
-
+
Friend ReadOnly Property Token As PropertyValue
Private ReadOnly Property UserAgent As PropertyValue
@@ -38,22 +38,6 @@ Namespace API.RedGifs
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
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"
diff --git a/SCrawler/API/ThisVid/Declarations.vb b/SCrawler/API/ThisVid/Declarations.vb
index a95bc94..bec2da1 100644
--- a/SCrawler/API/ThisVid/Declarations.vb
+++ b/SCrawler/API/ThisVid/Declarations.vb
@@ -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("\
@@ -28,6 +30,8 @@ Namespace API.ThisVid
Friend ReadOnly Property DownloadPublic As PropertyValue
Friend ReadOnly Property DownloadPrivate As PropertyValue
+
+ Friend ReadOnly Property DownloadFavourite As PropertyValue
= 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
diff --git a/SCrawler/API/ThisVid/UserData.vb b/SCrawler/API/ThisVid/UserData.vb
index 6958ede..6c4c57d 100644
--- a/SCrawler/API/ThisVid/UserData.vb
+++ b/SCrawler/API/ThisVid/UserData.vb
@@ -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
diff --git a/SCrawler/API/ThisVid/UserExchangeOptions.vb b/SCrawler/API/ThisVid/UserExchangeOptions.vb
index 3b91793..3bf8a38 100644
--- a/SCrawler/API/ThisVid/UserExchangeOptions.vb
+++ b/SCrawler/API/ThisVid/UserExchangeOptions.vb
@@ -8,24 +8,29 @@
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes
Namespace API.ThisVid
- Friend Class UserExchangeOptions
+ Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
Friend Property DownloadPublic As Boolean = True
Friend Property DownloadPrivate As Boolean = True
+
+ Friend Property DownloadFavourite As Boolean = False
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
diff --git a/SCrawler/API/TikTok/Declarations.vb b/SCrawler/API/TikTok/Declarations.vb
index 2b030da..de31241 100644
--- a/SCrawler/API/TikTok/Declarations.vb
+++ b/SCrawler/API/TikTok/Declarations.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/API/TikTok/SiteSettings.vb b/SCrawler/API/TikTok/SiteSettings.vb
index bf9df98..3105533 100644
--- a/SCrawler/API/TikTok/SiteSettings.vb
+++ b/SCrawler/API/TikTok/SiteSettings.vb
@@ -11,7 +11,7 @@ Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.TikTok
-
+
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
+
+ Friend Property RemoveTagsFromTitle As PropertyValue
+
+ Friend Property TitleUseNative As PropertyValue
+
+ Friend Property TitleUseNativeSTD As PropertyValue
+
+ 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
\ No newline at end of file
diff --git a/SCrawler/API/TikTok/UserData.vb b/SCrawler/API/TikTok/UserData.vb
index 9ff3590..b6425d1 100644
--- a/SCrawler/API/TikTok/UserData.vb
+++ b/SCrawler/API/TikTok/UserData.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/API/TikTok/UserExchangeOptions.vb b/SCrawler/API/TikTok/UserExchangeOptions.vb
new file mode 100644
index 0000000..35b2f1f
--- /dev/null
+++ b/SCrawler/API/TikTok/UserExchangeOptions.vb
@@ -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
+
+ Friend Property RemoveTagsFromTitle As Boolean
+
+ Friend Property TitleUseNative As Boolean
+
+ 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
diff --git a/SCrawler/API/Twitter/EditorExchangeOptions.vb b/SCrawler/API/Twitter/EditorExchangeOptions.vb
index 86d5e70..60f6a78 100644
--- a/SCrawler/API/Twitter/EditorExchangeOptions.vb
+++ b/SCrawler/API/Twitter/EditorExchangeOptions.vb
@@ -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
+
+ Friend Overridable Property MediaModelAllowNonUserTweets As Boolean = False
@@ -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
+
+ 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)
diff --git a/SCrawler/API/Twitter/SiteSettings.vb b/SCrawler/API/Twitter/SiteSettings.vb
index f1b1cf7..d6cac57 100644
--- a/SCrawler/API/Twitter/SiteSettings.vb
+++ b/SCrawler/API/Twitter/SiteSettings.vb
@@ -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
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"
- '
- ' Private ReadOnly Property Auth As PropertyValue
- '
- ' Private ReadOnly Property Token As PropertyValue
- '#End Region
#Region "Other properties"
-
+
+ Friend ReadOnly Property UseAppropriateModel As PropertyValue
+#Region "End points"
+
+ Friend Property UseNewEndPointSearch As PropertyValue
+
+ Friend Property UseNewEndPointProfiles As PropertyValue
+#End Region
+#Region "Limits"
+
+ Friend Property AbortOnLimit As PropertyValue
+
+ Friend Property DownloadAlreadyParsed As PropertyValue
+#End Region
+
+ Friend ReadOnly Property MediaModelAllowNonUserTweets As PropertyValue
+
Friend ReadOnly Property GifsDownload As PropertyValue
-
+
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
-
+
Friend ReadOnly Property GifsPrefix As PropertyValue
Private ReadOnly Property GifStringChecker As IFormatProvider
@@ -76,52 +74,38 @@ Namespace API.Twitter
Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]")
End Function
End Class
-
+
Friend ReadOnly Property UseMD5Comparison As PropertyValue
-
+
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
+
+ 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 _
diff --git a/SCrawler/API/Twitter/UserData.vb b/SCrawler/API/Twitter/UserData.vb
index c5f295d..d456bb7 100644
--- a/SCrawler/API/Twitter/UserData.vb
+++ b/SCrawler/API/Twitter/UserData.vb
@@ -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
diff --git a/SCrawler/API/UserDataBind.vb b/SCrawler/API/UserDataBind.vb
index 86d3b2a..9fbaf4a 100644
--- a/SCrawler/API/UserDataBind.vb
+++ b/SCrawler/API/UserDataBind.vb
@@ -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
'''
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 &
diff --git a/SCrawler/API/XVIDEOS/Declarations.vb b/SCrawler/API/XVIDEOS/Declarations.vb
index f174492..3113c34 100644
--- a/SCrawler/API/XVIDEOS/Declarations.vb
+++ b/SCrawler/API/XVIDEOS/Declarations.vb
@@ -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("\
+
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
\ No newline at end of file
diff --git a/SCrawler/API/XVIDEOS/UserData.vb b/SCrawler/API/XVIDEOS/UserData.vb
index b1354e8..13e520a 100644
--- a/SCrawler/API/XVIDEOS/UserData.vb
+++ b/SCrawler/API/XVIDEOS/UserData.vb
@@ -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
diff --git a/SCrawler/API/XVIDEOS/UserExchangeOptions.vb b/SCrawler/API/XVIDEOS/UserExchangeOptions.vb
new file mode 100644
index 0000000..593fefc
--- /dev/null
+++ b/SCrawler/API/XVIDEOS/UserExchangeOptions.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/API/Xhamster/SiteSettings.vb b/SCrawler/API/Xhamster/SiteSettings.vb
index 39b1b5e..df33387 100644
--- a/SCrawler/API/Xhamster/SiteSettings.vb
+++ b/SCrawler/API/Xhamster/SiteSettings.vb
@@ -12,7 +12,7 @@ Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Xhamster
-
+
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
\ No newline at end of file
diff --git a/SCrawler/API/Xhamster/UserData.vb b/SCrawler/API/Xhamster/UserData.vb
index d5c8b5a..73102c1 100644
--- a/SCrawler/API/Xhamster/UserData.vb
+++ b/SCrawler/API/Xhamster/UserData.vb
@@ -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
diff --git a/SCrawler/API/Xhamster/UserExchangeOptions.vb b/SCrawler/API/Xhamster/UserExchangeOptions.vb
new file mode 100644
index 0000000..39ae828
--- /dev/null
+++ b/SCrawler/API/Xhamster/UserExchangeOptions.vb
@@ -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
+
+ 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
\ No newline at end of file
diff --git a/SCrawler/API/YouTube/SiteSettings.vb b/SCrawler/API/YouTube/SiteSettings.vb
index 7f9f69d..9163f25 100644
--- a/SCrawler/API/YouTube/SiteSettings.vb
+++ b/SCrawler/API/YouTube/SiteSettings.vb
@@ -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"
diff --git a/SCrawler/API/YouTube/UserData.vb b/SCrawler/API/YouTube/UserData.vb
index dea39bd..7a7ffc8 100644
--- a/SCrawler/API/YouTube/UserData.vb
+++ b/SCrawler/API/YouTube/UserData.vb
@@ -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
diff --git a/SCrawler/Channels/ChannelViewForm.vb b/SCrawler/Channels/ChannelViewForm.vb
index 134d478..6c03476 100644
--- a/SCrawler/Channels/ChannelViewForm.vb
+++ b/SCrawler/Channels/ChannelViewForm.vb
@@ -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)
diff --git a/SCrawler/Content/Pictures/BrushToolPic_16.png b/SCrawler/Content/Pictures/BrushToolPic_16.png
new file mode 100644
index 0000000..301dba0
Binary files /dev/null and b/SCrawler/Content/Pictures/BrushToolPic_16.png differ
diff --git a/SCrawler/Content/Pictures/SitePictures/TwitterPic_400.png b/SCrawler/Content/Pictures/SitePictures/TwitterPic_400.png
deleted file mode 100644
index 24efa51..0000000
Binary files a/SCrawler/Content/Pictures/SitePictures/TwitterPic_400.png and /dev/null differ
diff --git a/SCrawler/Download/Automation/AutoDownloader.vb b/SCrawler/Download/Automation/AutoDownloader.vb
index a0cd6b8..9630b0a 100644
--- a/SCrawler/Download/Automation/AutoDownloader.vb
+++ b/SCrawler/Download/Automation/AutoDownloader.vb
@@ -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)
diff --git a/SCrawler/Download/Automation/AutoDownloaderEditorForm.Designer.vb b/SCrawler/Download/Automation/AutoDownloaderEditorForm.Designer.vb
index 88633df..5190e4c 100644
--- a/SCrawler/Download/Automation/AutoDownloaderEditorForm.Designer.vb
+++ b/SCrawler/Download/Automation/AutoDownloaderEditorForm.Designer.vb
@@ -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"
diff --git a/SCrawler/Download/Automation/AutoDownloaderEditorForm.vb b/SCrawler/Download/Automation/AutoDownloaderEditorForm.vb
index d5c771c..be19b9f 100644
--- a/SCrawler/Download/Automation/AutoDownloaderEditorForm.vb
+++ b/SCrawler/Download/Automation/AutoDownloaderEditorForm.vb
@@ -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
diff --git a/SCrawler/Download/Automation/SchedulerEditorForm.vb b/SCrawler/Download/Automation/SchedulerEditorForm.vb
index 485c58e..55d79f4 100644
--- a/SCrawler/Download/Automation/SchedulerEditorForm.vb
+++ b/SCrawler/Download/Automation/SchedulerEditorForm.vb
@@ -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
diff --git a/SCrawler/Download/DownloadedInfoForm.Designer.vb b/SCrawler/Download/DownloadedInfoForm.Designer.vb
index cbbeaf2..0fba052 100644
--- a/SCrawler/Download/DownloadedInfoForm.Designer.vb
+++ b/SCrawler/Download/DownloadedInfoForm.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/DownloadedInfoForm.resx b/SCrawler/Download/DownloadedInfoForm.resx
index 51b1704..ed9625a 100644
--- a/SCrawler/Download/DownloadedInfoForm.resx
+++ b/SCrawler/Download/DownloadedInfoForm.resx
@@ -123,10 +123,21 @@
False
+
+ False
+
17, 17
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABkSURBVDhPY6AKyO86WFDQfeg/iIYKkQZAmkNbnvyXta76
+ DxViYGFi+Y8PQ5VBAMhmkGYgJs8FAw9GA5EKILFiWUFixfL/IBoqRBoAafYsOvpf0jiTvEAE2QzSLGmU
+ MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
+
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
diff --git a/SCrawler/Download/DownloadedInfoForm.vb b/SCrawler/Download/DownloadedInfoForm.vb
index 5423f04..8442ced 100644
--- a/SCrawler/Download/DownloadedInfoForm.vb
+++ b/SCrawler/Download/DownloadedInfoForm.vb
@@ -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
diff --git a/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb b/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb
index 2ae226f..053b185 100644
--- a/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb
+++ b/SCrawler/Download/Feed/DownloadFeedForm.Designer.vb
@@ -23,15 +23,25 @@ Namespace DownloadObjects
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
\ No newline at end of file
diff --git a/SCrawler/Download/Feed/DownloadFeedForm.resx b/SCrawler/Download/Feed/DownloadFeedForm.resx
index d0947eb..913b26b 100644
--- a/SCrawler/Download/Feed/DownloadFeedForm.resx
+++ b/SCrawler/Download/Feed/DownloadFeedForm.resx
@@ -120,6 +120,21 @@
False
+
+ False
+
+
+ False
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABkSURBVDhPY6AKyO86WFDQfeg/iIYKkQZAmkNbnvyXta76
+ DxViYGFi+Y8PQ5VBAMhmkGYgJs8FAw9GA5EKILFiWUFixfL/IBoqRBoAafYsOvpf0jiTvEAE2QzSLGmU
+ MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
+
+
17, 17
diff --git a/SCrawler/Download/Feed/DownloadFeedForm.vb b/SCrawler/Download/Feed/DownloadFeedForm.vb
index 2ed3b68..01a90bf 100644
--- a/SCrawler/Download/Feed/DownloadFeedForm.vb
+++ b/SCrawler/Download/Feed/DownloadFeedForm.vb
@@ -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
diff --git a/SCrawler/Download/Feed/FeedMedia.Designer.vb b/SCrawler/Download/Feed/FeedMedia.Designer.vb
index 458d764..d9dca91 100644
--- a/SCrawler/Download/Feed/FeedMedia.Designer.vb
+++ b/SCrawler/Download/Feed/FeedMedia.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/Feed/FeedMedia.resx b/SCrawler/Download/Feed/FeedMedia.resx
index 6a1dbbc..d0a3aa8 100644
--- a/SCrawler/Download/Feed/FeedMedia.resx
+++ b/SCrawler/Download/Feed/FeedMedia.resx
@@ -123,9 +123,6 @@
False
-
- False
-
False
diff --git a/SCrawler/Download/Feed/FeedMedia.vb b/SCrawler/Download/Feed/FeedMedia.vb
index 45c2c80..7606931 100644
--- a/SCrawler/Download/Feed/FeedMedia.vb
+++ b/SCrawler/Download/Feed/FeedMedia.vb
@@ -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
diff --git a/SCrawler/Download/Groups/DownloadGroup.vb b/SCrawler/Download/Groups/DownloadGroup.vb
index 081566b..45f1fa3 100644
--- a/SCrawler/Download/Groups/DownloadGroup.vb
+++ b/SCrawler/Download/Groups/DownloadGroup.vb
@@ -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
diff --git a/SCrawler/Download/Groups/GroupDefaults.vb b/SCrawler/Download/Groups/GroupDefaults.vb
index a5a99b4..3f433a8 100644
--- a/SCrawler/Download/Groups/GroupDefaults.vb
+++ b/SCrawler/Download/Groups/GroupDefaults.vb
@@ -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
diff --git a/SCrawler/Download/Groups/GroupEditorForm.Designer.vb b/SCrawler/Download/Groups/GroupEditorForm.Designer.vb
index 9cc09f8..a27c27f 100644
--- a/SCrawler/Download/Groups/GroupEditorForm.Designer.vb
+++ b/SCrawler/Download/Groups/GroupEditorForm.Designer.vb
@@ -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
diff --git a/SCrawler/Download/Groups/GroupParameters.vb b/SCrawler/Download/Groups/GroupParameters.vb
index 1d77172..6451ee9 100644
--- a/SCrawler/Download/Groups/GroupParameters.vb
+++ b/SCrawler/Download/Groups/GroupParameters.vb
@@ -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("|")),
diff --git a/SCrawler/Download/MissingPostsForm.vb b/SCrawler/Download/MissingPostsForm.vb
index a09e926..be0d017 100644
--- a/SCrawler/Download/MissingPostsForm.vb
+++ b/SCrawler/Download/MissingPostsForm.vb
@@ -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]")
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb b/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb
index a61a221..8047e66 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb
+++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.resx b/SCrawler/Download/STDownloader/DownloaderUrlForm.resx
index f385b3a..299ec6d 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlForm.resx
+++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.resx
@@ -144,11 +144,123 @@
+
+ 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
+ AAAASUVORK5CYII=
\ No newline at end of file
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlForm.vb b/SCrawler/Download/STDownloader/DownloaderUrlForm.vb
index 2a405cc..dcd4b49 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlForm.vb
+++ b/SCrawler/Download/STDownloader/DownloaderUrlForm.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb
index ffc7698..babbd6f 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb
+++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx
index fbe3f6b..04fd3f1 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx
+++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.resx
@@ -136,11 +136,123 @@
+
+ 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
+
+
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
+ 3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
+ GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
+ nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMK3O3r79wVUIz65jfGNVxI/VIX69CvGO9M//a9P+e8o3B/8v
+ vKn9s+3fyX8dAJgmaWd+fl3E96Wd/E9XdvZHkfbvXNa+Rn45AGCS3bvjj/E/h3box5OrmxjPyy8PAEyS
+ XXO7zqhCeH/HDnwUOdCE+J6zdux4eH47YIrEGE8uy/Ls9Bnx/LooL0oH9b9Th/I1TVG+rCqKC+q6Xsh/
+ FJgmO8vy6WknfdPQTnsjckMdwlPy2wITLO3wF6si/lGas1ekuXvX0Fzuyg9S3psOCl6qDwimQB3ji9Ok
+ 3btmEm907kpnEa/Mbw9Mlq1pB/6cdHZ/ZcfcPZrcXoXyrVVVFfl1gUmSdsS/libqPUMTd5NSvjktwrbB
+ kgDjVi1UT26K+Nnu+XrMuaud60uPWHpIfhtg3JqyfEaanHcPTdZNTRPCPy4uLj40LxIwBudt2fKAtOP/
+ 0zQnN+5koIg3tpca81sC49J+LZcm5a3rJulYEq6LSV40YBOFEB6V5uFV6+flRiTsSwf9r81vDYzBCSO4
+ vjfq/KAuiqfm5QM2QRPjuWnubUbz71DCn6W33zpYCmDT1EX5m92Tcuy5q47xFXkxgQ3UduqnOXfn0Bzc
+ xJSvz4sCbIb2pzlp8v1w/WScnKSzkjekRT1hsMTAKC0vL5/Ydud3zb1NT1FelBcL2GiDm3d0TMTJy0ea
+ pjk1LzYwAu3NvtLc+uTQXBtn7tYYCJtja/vQno5JOJFpQrzWb4hhNJoQnpjm1Q3D82wCcnNRFKfnxQQ2
+ Qttk1zH5JjzhFmcIcHzyzb6O5aFem5J0sP/OvKjARmg7b7sm3xRkT3vDorwawJHb1t6Ep2NOTVoOtDch
+ yssMjFr6IPh8x8SbnsT4lrQamgPhCMzPzz+sifHjnXNpMnN5XnRglJaWlk5KE2z/0ISbxnzQQ0bgvlXz
+ 1ePSXPnG0NyZ+DRF8Zi8CsCo7Azh0V0TbkrzRc2B0G3wIJ9429CcmZLce4MgYJTyff87JtzU5uayLM/J
+ qwcM7vD5+jQ3DgzNlWnKDXldgFFJZwW/2jHZpj1727uZ5VWE3mofqJXmw4eG5sdUpqqqXXm1gFGoQnhJ
+ 12SbgRxoYvzjtIruK04vxRjPSvPgK0PzYmqTPqtemVcNGIU6xgu7JtusJH1ovH9ubu6UvLrQC2ncPyuN
+ /58Mz4fpTvnmvHrAKJQL5dO6J9ssJXxucWFhLq8yzLKtaUf5h2ncb9zz+8eUKsYP53UERmHX/PyOrsk2
+ g7nJDUWYZUuPWHpIE8oPdIz92UiMn86rCoxIOmOYta8KD5uftk2Peb1hZtTzdVOHcF3HmJ+ZVCF+Ia8u
+ MCppcl0+PNlmOG1zYPtYYc2BzIQ0np+ZxvWPh8b5LObqvMrAqEzRo4BHmctijCfnEsBUqkP5u2ksz8Kd
+ PI8g5SfyagOj0jbIpQk2c01DR5Brmh3NfC4DTI324LWO8V0dY3pm48mAsEGm7OEgo0sRb9wZ4+NzGWDi
+ lWUZ0ti9Zt1YnvUU8fdyCYBRmsFbAh9xqhDvqEN4Xi4FTKz8s93vD4/hPiSdpJyXywCMWPtrgKuGJ12P
+ ck/6gPmDXAuYOHVR/lY6UN3XMXb7kDv17MAGqhaqJ6WJ1sdegDUJ726a5oG5JDB2917vL+Kl3eO1N/lQ
+ LgewUdIO8E0dk69vubosy+25JDA2bYNuFeJnOsZovxLjhbkkwEZZXl4+0QfOvfl2Ogg4O5cFNl1dFE9N
+ 4/B7Q+Oyj7mh/VzKZQE2UtM0j6iL+LWOidizhN3OPBiHuigvSmPwrvVjsn9pQnh1LguwGQa3Fo3fHp6M
+ Pcw97c1WcllgQy0tLZ2UDr7/qmMc9jJNiF/WkwNjMHhQ0GzfX/yIU8RLfRCxkdq+kzTfrugcf/3MgZ1l
+ +fRcHmCztU8Yq2P8h47J2cdcpTmQjdCE8IQ0vnzjdkjKP8nlAcZoWxXin3dP0n4l1eGb9UL92FwXOG51
+ Ub48ja09w2Otz2nvTJpKs21QIWDs0lnKb6TJqTEphN3NQvncXBY4VtvSju4N3WOs17l6cXHxoblGwKRo
+ r8mlHeAtHZO2b9mfDohem8sCR2XX3K4z0hj65NCYklSTGONpuUzApNlVFFWaqP81NHF7mvD2tnM7lwbu
+ V/vwqTR2vrV+LPU7VSjf4ff+MAU0B65NeWVd12fm0sBhpTnzosHDp7rGUV8T9lVFvDiXCJgSrmEezDea
+ onhMrgsM25rmyuvSODkwNG56nvZyYvi5XCNg2mgOXM3tVVH9ci4L3KtpmlN9W7Y+VYhfiEkuEzCt8n3L
+ fzA8yXuY/b7OZEVZlovt3ew6xknf8965ublTcpmAaac5cG3C2zQ09Vv7bVAaC/+7fmz0Og6QYVZpDlyT
+ GD/dPlgpl4b+2Nru5NIYuGfdmOhxmhB/VBblL+QaATNKc+DBfH1nCI/OdWHGtTewSdv874fGgIT4xfYb
+ wlwmYNZpDlzNbVUIz85lYUblJ2i6BDacGP/u7O3bH5zLBPSF5sDV7K+L+Nu5LMyYtJP7xbSNfzy0zfue
+ A+03gak8WwdVAnpHc+CaxHiJ5sCZsnK9f/+6bd3v3JZ2/r+SawT0mebAg0kfjB93v/Pp136t3X693bWN
+ e56v6nsBhmkOXE24Ph0EnJXrwpSp63qhDuXnu7dtn1P+U1VVP5PLBHAozYGDtD+LchvU6TN4Iqa+lqGs
+ XO8/YVAlgMPQHLiSsC+dNb0ml4UJVxflRWm73b1+O/Y5YXcVwvNziQDun+bANYnxkvO2bHlALg0TJsZ4
+ cl3ESzu3Xa8Trm+KYimXCeDIaQ48mKqIH9McOHl2zc/vaIr42a5t1vN8tCiK03OZAI6J5sCVFPFr7QNk
+ cl0Ys3yp6nvrtlO/s3K9f9ugSgDHSXPgILk58PxcFsYkX+93J8s1qUK8oynKF+YSAYyO5sCVhH3pgOjV
+ uSxsoqZpHpjq//bu7dLjFPHGND+Xc5kARk9z4JrE+JZUEl+1bpLFhYW5VPf/WLcd5N/ruj4zlwlg42gO
+ PCQfdXOVjdeE8MRU6xuGai9uXw2MgebA1YTrFkMoc10YsaYoX5rqfOf6uvc6e9LO/xW5RACbT3Pgam5N
+ B0Q/m8vCCLT3XnCQ2ZXwnWqhenIuE8D4aA5czV3OykZj19yuM1I9PzlUXwnhirIst+cyAYyf5sA1GTQH
+ uu/6MdoZ4+NTHb+1rq59j+v9wKTSHHhIPtI0zam5NByhNH5enGr306Fa9j1720ttuUQAE0tz4Epi/FJM
+ cl24b8ZNd25KdTk31whg8mkOXEm4pX1EbS4LHebn5x+WdnIf765fr3NVCOFRuUwA00Nz4Gr21kX58lwW
+ 1qjmq8el+nxjqF4S4yVLS0sn5TIBTB/NgWuiOfAQTVE+J9XltnV16nXCvqqIF+cSAUw3zYGH5INnb9/+
+ 4Fyavtra7uRSLe4Zqk3f88MmxvNyjQBmhiavg/liVVVFrkuvLC4uPjSt/4eG6iEhXlOWZchlApg9mgNX
+ c3P6wD8nl6UXqvlqZ1rv/xmqQ+/ThPJv5ufnH5TLBDC7NAeuZm97n/tclplWhfCstL4/GVr/nsf1fqCH
+ NAeu5kB7aSSVZFabA13v786tVVFckGsE0C+aAw8mnSG/f25u7pRcmpnQbt8mlB/oWt8+pwnxWk+PBNAc
+ uJoqxC/MSnNgs7BQ1yFc17WePc97Z+1AD+C4aA5czU3T/qjXdED3zLQePx5ar75nf77ev3VQJQBWaQ5c
+ zZ4qhJfkskyVuigvapvbOtapt2lC/FFTls/IJQKgi+bA1aw0B07FGWOM8eQ6xnd1rEe/E+OX2jGdywTA
+ fdEcuCYx/u2kXzNudjTz6az/c53L3+NUMX7YI6EBjp7mwIO5pt3J5rpMlHKhfFpavu8PLW/fM+s/7QTY
+ eJoDV/PduiiWc1kmwuB6f7x7aDn7ntvrGC/MJQLgeGgOHKQK8Y46hOflsoxN0zQPbEJ8Z9cy9jxf3RnC
+ o3OZABgFzYGrab9efl0qyViaAxcXFubSgchnOpar77k8xnhaLhMAo6Q5cE2K+L7NfoBMHcJT0nvfvG5Z
+ +h3X+wE2iebAg7m6LMvtuS4bKl/v14txSMLuKoQX5BIBsBk0B64kfCfV4om5LCN33pYtD3DA1ZVwfb1Q
+ PzaXCYDNpDlwJWH3RnSe75rbdUZ6/X9b/369z0eLojg9lwmAcdAcuJqV5sCRaEJ4QnrNbw+9R9+zcr1/
+ 26BKAIyV5sBDcll7W95cmmPSPocgvc6dQ6/b9+xpivJluUQATBDNgQdz1TE2B6phV4p446TdhAmAIens
+ 9ZXpQ1tz4KA58Am5LPfrrB07Hp7+zr90v1Z/UxXxU3Vdn5nLBMAk0xy4krC7WSifm8tyWGVZnl2F+M3u
+ 1+hxYrxkeXn5xFwmAKaB5sDV7E9nsRfnsqyTdnIvGtxiuPPv9jV7Ul1ekUsEwLTRHHgwVSjfsbS0dFIu
+ TWtr+6uB9P8ODP/Znue7ZVmek2sEwBTT2Laa8sr2enb7jHoHRl0JV8QYH5nHDQCzwJ0DV/P1tKO7vuO/
+ 9zpVKN/qej/AjNIcKB3Z24TyVXmIADCrNAfKmtzUxHhuHhoAzDrNgZJyVQjhUXlIANAjmgN7m/Du471d
+ MgBTzp0D+5Sw777uiQBAz2gO7EPCLSnn500OAAOaA2c615RlGfKmBoBDaQ6cvTQhvmd+fv5BeRMDwGFp
+ DpyJuN4PwDHQHDjVubUqigvypgSAo6M5cPrShHjtYghl3oQAcGw0B05Rivi+ubm5U/KmA4Djozlw4rM/
+ X+/fOthiADA6mgMnME2IP2rK8hl5GwHAxtAcOFH5SozxrLxpAGBjaQ4cf6oYP9w0zal5kwDA5tAcOLYc
+ aC/FpE1wwmBLAMAm0xy46bk91fvCXH4AGCvNgZuRIn6tKYrH5JoDwGTQHLihuTzGeFouNQBMFs2BI4/r
+ /QBMB82Bo0rYXYXwglxWAJh8mgOPN+H6eqF+bC4nAEwVzYHHkiL+c1EUp+caAsB00hx4FInxLalk2waV
+ A4AppznwfrOnLsqX53IBwOzQHHiYFPHGaqF6Ui4TAMwezYGHpirip+q6PjOXBwBmmubANjFesry8fGKu
+ CQD0Q4+bA/dWMf56LgMA9E8PmwO/W5blOXn1AaC/+tMcWF4ZY3xkXm0AYOabA2O8ZGlp6aS8ugDAGrPY
+ HLi3CeWr8voBAIczQ82BN6UDmnPzagEA92f6mwPLz1dVVeTVAQCO1LQ2B1Yh/PX8/PyD8moAAEdrupoD
+ w76qiBfnRQcAjtMUNAeGW1LOz8sLAIzKBDcHXlOWZciLCQCM2gQ2B142Nzd3Sl48AGCjTEhz4H7X+wFg
+ k425OfDWqqh+Pi8KALDJtqWDgDemHfKBoR30hqUJ8dqY5PcHAMalKcrnpJ3z94Z31qNO+/t+1/sBYIKk
+ k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
+ 8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
+ gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
+ AAAASUVORK5CYII=
diff --git a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb
index 500b26a..b3e5597 100644
--- a/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb
+++ b/SCrawler/Download/STDownloader/DownloaderUrlsArrForm.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb
index 813c339..8045573 100644
--- a/SCrawler/Download/STDownloader/VideoDownloaderForm.vb
+++ b/SCrawler/Download/STDownloader/VideoDownloaderForm.vb
@@ -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)
diff --git a/SCrawler/Download/TDownloader.vb b/SCrawler/Download/TDownloader.vb
index 6976014..c941801 100644
--- a/SCrawler/Download/TDownloader.vb
+++ b/SCrawler/Download/TDownloader.vb
@@ -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
diff --git a/SCrawler/Download/UserDownloadQueueForm.Designer.vb b/SCrawler/Download/UserDownloadQueueForm.Designer.vb
new file mode 100644
index 0000000..3148764
--- /dev/null
+++ b/SCrawler/Download/UserDownloadQueueForm.Designer.vb
@@ -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
+
+ Partial Friend Class UserDownloadQueueForm : Inherits System.Windows.Forms.Form
+
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+ Private components As System.ComponentModel.IContainer
+
+ Private Sub InitializeComponent()
+ Dim 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
\ No newline at end of file
diff --git a/SCrawler/Download/UserDownloadQueueForm.resx b/SCrawler/Download/UserDownloadQueueForm.resx
new file mode 100644
index 0000000..c9c1d89
--- /dev/null
+++ b/SCrawler/Download/UserDownloadQueueForm.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/SCrawler/Download/UserDownloadQueueForm.vb b/SCrawler/Download/UserDownloadQueueForm.vb
new file mode 100644
index 0000000..ca4ed96
--- /dev/null
+++ b/SCrawler/Download/UserDownloadQueueForm.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Editors/CollectionEditorForm.Designer.vb b/SCrawler/Editors/CollectionEditorForm.Designer.vb
index c091daa..5035e9a 100644
--- a/SCrawler/Editors/CollectionEditorForm.Designer.vb
+++ b/SCrawler/Editors/CollectionEditorForm.Designer.vb
@@ -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"
diff --git a/SCrawler/Editors/CollectionEditorForm.resx b/SCrawler/Editors/CollectionEditorForm.resx
index c30579c..669ae0e 100644
--- a/SCrawler/Editors/CollectionEditorForm.resx
+++ b/SCrawler/Editors/CollectionEditorForm.resx
@@ -144,6 +144,17 @@
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
+ WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
+ aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
+ 5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
+ vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
+ cMaRN0UdBBkAAAAASUVORK5CYII=
+
+
+
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
diff --git a/SCrawler/Editors/CollectionEditorForm.vb b/SCrawler/Editors/CollectionEditorForm.vb
index cbe0d35..450f7e4 100644
--- a/SCrawler/Editors/CollectionEditorForm.vb
+++ b/SCrawler/Editors/CollectionEditorForm.vb
@@ -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
diff --git a/SCrawler/Editors/ColorPicker.vb b/SCrawler/Editors/ColorPicker.vb
index 6d1226f..a318dc3 100644
--- a/SCrawler/Editors/ColorPicker.vb
+++ b/SCrawler/Editors/ColorPicker.vb
@@ -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,
diff --git a/SCrawler/Editors/GlobalLocationsChooserForm.Designer.vb b/SCrawler/Editors/GlobalLocationsChooserForm.Designer.vb
new file mode 100644
index 0000000..19f2b07
--- /dev/null
+++ b/SCrawler/Editors/GlobalLocationsChooserForm.Designer.vb
@@ -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
+
+ Partial Friend Class GlobalLocationsChooserForm : Inherits System.Windows.Forms.Form
+
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+ Private components As System.ComponentModel.IContainer
+
+ Private Sub InitializeComponent()
+ Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
+ Dim 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
\ No newline at end of file
diff --git a/SCrawler/Editors/GlobalLocationsChooserForm.resx b/SCrawler/Editors/GlobalLocationsChooserForm.resx
new file mode 100644
index 0000000..6b21a20
--- /dev/null
+++ b/SCrawler/Editors/GlobalLocationsChooserForm.resx
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
+ WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
+ aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
+ 5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
+ vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
+ cMaRN0UdBBkAAAAASUVORK5CYII=
+
+
+
+
+ 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
+ AAAASUVORK5CYII=
+
+
+
+ False
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
\ No newline at end of file
diff --git a/SCrawler/Editors/GlobalLocationsChooserForm.vb b/SCrawler/Editors/GlobalLocationsChooserForm.vb
new file mode 100644
index 0000000..9dc6d53
--- /dev/null
+++ b/SCrawler/Editors/GlobalLocationsChooserForm.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Editors/GlobalSettingsForm.Designer.vb b/SCrawler/Editors/GlobalSettingsForm.Designer.vb
index 8adcac7..3b40d7c 100644
--- a/SCrawler/Editors/GlobalSettingsForm.Designer.vb
+++ b/SCrawler/Editors/GlobalSettingsForm.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Editors/GlobalSettingsForm.resx b/SCrawler/Editors/GlobalSettingsForm.resx
index 1ff4215..847ff0a 100644
--- a/SCrawler/Editors/GlobalSettingsForm.resx
+++ b/SCrawler/Editors/GlobalSettingsForm.resx
@@ -238,6 +238,22 @@
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
@@ -288,7 +304,7 @@ You can find more detailed information about the missing posts in the form that
False
-
+
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
-
+
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
False
-
+
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=
-
+
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
False
-
-
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
- WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
- aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
- 5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
- vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
- cMaRN0UdBBkAAAAASUVORK5CYII=
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
- tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
- AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
-
-
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
@@ -433,6 +430,25 @@ You can find more detailed information about the missing posts in the form that
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
+ WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
+ aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
+ 5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
+ vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
+ cMaRN0UdBBkAAAAASUVORK5CYII=
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
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==
-
+
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
False
-
+
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
diff --git a/SCrawler/Editors/GlobalSettingsForm.vb b/SCrawler/Editors/GlobalSettingsForm.vb
index 34d205c..d49e5e4 100644
--- a/SCrawler/Editors/GlobalSettingsForm.vb
+++ b/SCrawler/Editors/GlobalSettingsForm.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Editors/UserCreatorForm.Designer.vb b/SCrawler/Editors/UserCreatorForm.Designer.vb
index 1d427e9..84340b4 100644
--- a/SCrawler/Editors/UserCreatorForm.Designer.vb
+++ b/SCrawler/Editors/UserCreatorForm.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/Editors/UserCreatorForm.resx b/SCrawler/Editors/UserCreatorForm.resx
index 7e231d4..6c89bed 100644
--- a/SCrawler/Editors/UserCreatorForm.resx
+++ b/SCrawler/Editors/UserCreatorForm.resx
@@ -216,6 +216,12 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
AAAASUVORK5CYII=
+
+
+ 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.
@@ -264,6 +270,96 @@
+
+ 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
+ AAAASUVORK5CYII=
+
+
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
@@ -274,7 +370,7 @@
cMaRN0UdBBkAAAAASUVORK5CYII=
-
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
diff --git a/SCrawler/Editors/UserCreatorForm.vb b/SCrawler/Editors/UserCreatorForm.vb
index 0b2ac0c..656e3b0 100644
--- a/SCrawler/Editors/UserCreatorForm.vb
+++ b/SCrawler/Editors/UserCreatorForm.vb
@@ -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"
''' Create new user
@@ -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
diff --git a/SCrawler/GlobalSuppressions.vb b/SCrawler/GlobalSuppressions.vb
index 03e7648..94960e5 100644
--- a/SCrawler/GlobalSuppressions.vb
+++ b/SCrawler/GlobalSuppressions.vb
@@ -5,4 +5,5 @@
Imports System.Diagnostics.CodeAnalysis
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/SCrawler/ListImagesLoader.vb b/SCrawler/ListImagesLoader.vb
index 4c3effb..e5d65ef 100644
--- a/SCrawler/ListImagesLoader.vb
+++ b/SCrawler/ListImagesLoader.vb
@@ -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
diff --git a/SCrawler/MainFrame.Designer.vb b/SCrawler/MainFrame.Designer.vb
index a36f9d3..07e02cc 100644
--- a/SCrawler/MainFrame.Designer.vb
+++ b/SCrawler/MainFrame.Designer.vb
@@ -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
\ No newline at end of file
diff --git a/SCrawler/MainFrame.resx b/SCrawler/MainFrame.resx
index 56e777a..64790e9 100644
--- a/SCrawler/MainFrame.resx
+++ b/SCrawler/MainFrame.resx
@@ -147,46 +147,51 @@
False
-
+
+ False
+
+
False
False
-
- False
-
False
False
+
+ False
+
False
False
-
- False
-
False
-
+
False
-
+
False
132, 17
-
- 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.)).
+
+ 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.
+
+
+ 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.
@@ -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
+
+
+
+
+ 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==
diff --git a/SCrawler/MainFrame.vb b/SCrawler/MainFrame.vb
index 74cf8e0..68fd7f4 100644
--- a/SCrawler/MainFrame.vb
+++ b/SCrawler/MainFrame.vb
@@ -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
diff --git a/SCrawler/MainFrameObjects.vb b/SCrawler/MainFrameObjects.vb
index 7c6c7ce..6b4ffa7 100644
--- a/SCrawler/MainFrameObjects.vb
+++ b/SCrawler/MainFrameObjects.vb
@@ -62,6 +62,9 @@ Friend Class MainFrameObjects : Implements INotificator
Friend Sub UpdateLogButton()
MyMainLOG_UpdateLogButton(MF.BTT_LOG, MF.Toolbar_TOP)
End Sub
+ Friend Function GetUserListProvider(ByVal WithCollections As Boolean) As IFormatProvider
+ Return MF.GetUserListProvider(WithCollections)
+ End Function
#End Region
#Region "Notifications"
Private Sub INotificator_ShowNotification(ByVal Text As String, ByVal Image As SFile) Implements INotificator.ShowNotification
diff --git a/SCrawler/MainMod.vb b/SCrawler/MainMod.vb
index 875cc00..0729dbf 100644
--- a/SCrawler/MainMod.vb
+++ b/SCrawler/MainMod.vb
@@ -9,9 +9,7 @@
Imports System.Runtime.CompilerServices
Imports PersonalUtilities.Functions.XML.Objects
Imports PersonalUtilities.Functions.RegularExpressions
-Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Tools
-Imports PersonalUtilities.Tools.Web
Imports SCrawler.API.Base
Imports SCrawler.Plugin.Hosts
Imports SCrawler.DownloadObjects
@@ -21,6 +19,8 @@ Friend Module MainMod
Friend ReadOnly LinkPattern As RParams = RParams.DMS("[htps:]{0,6}[/]{0,2}(.+)", 1)
Friend ReadOnly FilesPattern As RParams = RParams.DM("[^\./]+?\.\w+", 1, EDP.ReturnValue)
Friend Delegate Sub NotificationEventHandler(ByVal Sender As SettingsCLS.NotificationObjects, ByVal Message As String)
+ Friend Delegate Sub UserDownloadStateChangedEventHandler(ByVal User As IUserData, ByVal IsDownloading As Boolean)
+ Friend Delegate Function PathMoverHandler(ByVal User As UserInfo, ByVal DestinationPattern As SFile) As SFile
Friend Const LVI_TempOption As String = "Temp"
Friend Const LVI_FavOption As String = "Favorite"
Friend Const LVI_CollectionOption As String = "Collection"
@@ -68,6 +68,14 @@ Friend Module MainMod
[Default] = 0
Virtual = 1
End Enum
+ Friend Enum PathCreationModel As Integer
+ Undefined = -1
+ Path = 1
+ Path_UserName = 2
+ Path_UserSite_UserName = 3
+ DefaultUser = Path_UserSite_UserName
+ Collection = 4
+ End Enum
Friend Downloader As TDownloader
Friend InfoForm As DownloadedInfoForm
Friend VideoDownloader As STDownloader.VideoDownloaderForm
@@ -77,6 +85,8 @@ Friend Module MainMod
Friend ReadOnly DateTimeDefaultProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
Friend ReadOnly UserExistsPredicate As New FPredicate(Of IUserData)(Function(u) u.Exists)
+ Friend ReadOnly UserExistsSubscriptionsPredicate As New FPredicate(Of IUserData)(Function(u) u.Exists And u.IsSubscription)
+ Friend ReadOnly UserExistsNonSubscriptionsPredicate As New FPredicate(Of IUserData)(Function(u) u.Exists And Not u.IsSubscription)
Friend ReadOnly LogConnector As New LogHost
Friend DefaultUserAgent As String = String.Empty
#Region "File name operations"
@@ -91,6 +101,11 @@ Friend Module MainMod
End Class
#End Region
Friend Property MainProgress As MyProgressExt
+ Friend Sub ShowOperationCanceledMsg(Optional ByVal MsgTitle As String = Nothing)
+ Dim m As New MMessage("Operation canceled")
+ If Not MsgTitle.IsEmptyString Then m.Title = MsgTitle
+ m.Show()
+ End Sub
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal IsCollection As Boolean) As ListViewGroup()
Dim l As New List(Of ListViewGroup)
Dim t$
@@ -125,8 +140,11 @@ Friend Module MainMod
End If
End Function
Friend Sub CheckVersion(ByVal Force As Boolean)
- If Settings.CheckUpdatesAtStart Or Force Then _
- GitHub.DefaultVersionChecker(My.Application.Info.Version, "AAndyProgram", "SCrawler",
- Settings.LatestVersion.Value, Settings.ShowNewVersionNotification.Value, Force)
+ With Settings
+ If .CheckUpdatesAtStart Or Force Then
+ ShowProgramInfo(.ProgramText.Value.IfNullOrEmpty("SCrawler"), My.Application.Info.Version, True, Force, .Self, False,
+ .LatestVersion.Value, .ShowNewVersionNotification.Value, .ProgramDescription)
+ End If
+ End With
End Sub
End Module
\ No newline at end of file
diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb
index a6c5e50..835ef06 100644
--- a/SCrawler/My Project/AssemblyInfo.vb
+++ b/SCrawler/My Project/AssemblyInfo.vb
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
'
-
-
+
+
diff --git a/SCrawler/My Project/Resources.Designer.vb b/SCrawler/My Project/Resources.Designer.vb
index 0953ba6..60a588e 100644
--- a/SCrawler/My Project/Resources.Designer.vb
+++ b/SCrawler/My Project/Resources.Designer.vb
@@ -110,6 +110,16 @@ Namespace My.Resources
End Get
End Property
+ '''
+ ''' Looks up a localized resource of type System.Drawing.Bitmap.
+ '''
+ Friend ReadOnly Property BrushToolPic_16() As System.Drawing.Bitmap
+ Get
+ Dim obj As Object = ResourceManager.GetObject("BrushToolPic_16", resourceCulture)
+ Return CType(obj,System.Drawing.Bitmap)
+ End Get
+ End Property
+
'''
''' Looks up a localized resource of type System.Drawing.Bitmap.
'''
diff --git a/SCrawler/My Project/Resources.resx b/SCrawler/My Project/Resources.resx
index 6e7f93e..a3b77c7 100644
--- a/SCrawler/My Project/Resources.resx
+++ b/SCrawler/My Project/Resources.resx
@@ -217,4 +217,7 @@
..\Content\Pictures\TagPic_24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Content\Pictures\BrushToolPic_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb
index 778393a..0f57803 100644
--- a/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/DownloadableMediaHost.vb
@@ -145,11 +145,13 @@ Namespace Plugin.Hosts
f.Extension = "xml"
FileSettings = f
End If
- Using x As New XmlFile With {.AllowSameNames = True}
- x.AddRange(ToEContainer.Elements)
- x.Name = "MediaContainer"
- x.Save(FileSettings)
- End Using
+ If NeedToSave() Then
+ Using x As New XmlFile With {.AllowSameNames = True}
+ x.AddRange(ToEContainer.Elements)
+ x.Name = "MediaContainer"
+ x.Save(FileSettings)
+ End Using
+ End If
End Sub
Public Overrides Function GetHashCode() As Integer
Return URL.GetHashCode
diff --git a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
index cff7a9e..286e2ba 100644
--- a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
@@ -16,9 +16,15 @@ Imports PersonalUtilities.Forms.Controls.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace Plugin.Hosts
Friend Class PropertyValueHost : Implements IPropertyValue, IComparable(Of PropertyValueHost)
- Friend Const LeftOffsetDefault As Integer = 100
- Friend Event OnPropertyUpdateRequested(ByVal Sender As PropertyValueHost)
+#Region "Events"
Private Event ValueChanged As IPropertyValue.ValueChangedEventHandler Implements IPropertyValue.ValueChanged
+#End Region
+#Region "Declarations"
+ Private ReadOnly Keeper As SettingsHost
+ Protected Source As Object 'ReadOnly
+ Protected Member As MemberInfo
+ Friend ReadOnly Options As PropertyOption
+ Friend Overridable ReadOnly Property Name As String
Protected _Type As Type
Friend Overridable Property [Type] As Type Implements IPropertyValue.Type
Get
@@ -28,6 +34,11 @@ Namespace Plugin.Hosts
_Type = t
End Set
End Property
+ Friend ReadOnly IsTaskCounter As Boolean
+ Friend ReadOnly Exists As Boolean = False
+#Region "XML"
+ Private ReadOnly _XmlName As String
+#End Region
#Region "Control"
Friend Property Control As Control
Protected ControlNumber As Integer = -1
@@ -40,6 +51,20 @@ Namespace Plugin.Hosts
End If
End Get
End Property
+ Friend Const LeftOffsetDefault As Integer = 100
+ Protected _LeftOffset As Integer? = Nothing
+ Friend Overridable Property LeftOffset As Integer
+ Get
+ If _LeftOffset.HasValue Then
+ Return _LeftOffset
+ Else
+ Return If(Options?.LeftOffset, LeftOffsetDefault)
+ End If
+ End Get
+ Set(ByVal NewOffset As Integer)
+ _LeftOffset = NewOffset
+ End Set
+ End Property
Protected Overridable ReadOnly Property Control_ThreeStates As Boolean
Get
Return Options.ThreeStates
@@ -91,7 +116,11 @@ Namespace Plugin.Hosts
With DirectCast(Control, TextBoxExtended)
.CaptionText = Control_Caption
.CaptionToolTipEnabled = Not Control_ToolTip.IsEmptyString
- .CaptionWidth = LeftOffset
+ If LeftOffset > 0 Then
+ .CaptionWidth = LeftOffset
+ Else
+ Using l As New Label : .CaptionWidth = .CaptionText.MeasureTextDefault(l.Font).Width : End Using
+ End If
If Not Control_ToolTip.IsEmptyString Then .CaptionToolTipText = Control_ToolTip : .CaptionToolTipEnabled = True
.Text = CStr(AConvert(Of String)(Value, String.Empty))
With .Buttons
@@ -114,9 +143,19 @@ Namespace Plugin.Hosts
Private Sub TextBoxClick(ByVal Sender As ActionButton, ByVal e As EventArgs)
Try
If Sender.DefaultButton = ADB.Refresh AndAlso Not Source Is Nothing AndAlso Not UpdateMethod Is Nothing Then
- If CBool(UpdateMethod.Invoke(Source, Nothing)) Then
- RaiseEvent OnPropertyUpdateRequested(Me)
+ Dim args As Object = Nothing
+ Dim i%
+ If UpdateMethodArguments.ListExists Then
+ Dim a As New List(Of String)
+ For Each arg$ In UpdateMethodArguments
+ i = Keeper.PropList.FindIndex(Function(p) Not p Is Me And p.Name = arg)
+ If i >= 0 Then a.Add(AConvert(Of String)(Keeper.PropList(i).GetControlValue(), String.Empty)) Else a.Add(String.Empty)
+ Next
+ If a.Count > 0 Then args = a.ToArray
+ End If
+ If CBool(UpdateMethod.Invoke(Source, args)) Then
DirectCast(Control, TextBoxExtended).Text = CStr(AConvert(Of String)(Value, String.Empty))
+ If Dependents.Count > 0 Then Dependents.ForEach(Sub(d) d.UpdateDependence())
End If
End If
Catch ex As Exception
@@ -158,29 +197,7 @@ Namespace Plugin.Hosts
Return Nothing
End If
End Function
- Private Sub UpdateProviderPropertyName()
- If ProviderValueIsPropertyProvider Then DirectCast(ProviderValue, IPropertyProvider).PropertyName = Name
- End Sub
#End Region
-#Region "Compatibility"
- Protected Source As Object 'ReadOnly
- Protected Member As MemberInfo
- Friend Overridable ReadOnly Property Name As String
- Private ReadOnly _XmlName As String
- Friend ReadOnly Options As PropertyOption
- Protected _LeftOffset As Integer? = Nothing
- Friend Overridable Property LeftOffset As Integer
- Get
- If _LeftOffset.HasValue Then
- Return _LeftOffset
- Else
- Return If(Options?.LeftOffset, LeftOffsetDefault)
- End If
- End Get
- Set(ByVal NewOffset As Integer)
- _LeftOffset = NewOffset
- End Set
- End Property
#Region "Providers"
Friend Property ProviderFieldsChecker As IFormatProvider
Private Property ProviderValue As IFormatProvider
@@ -195,27 +212,37 @@ Namespace Plugin.Hosts
ProviderValueInteraction = Instance.Interaction
End If
End Sub
+ Private Sub UpdateProviderPropertyName()
+ If ProviderValueIsPropertyProvider Then DirectCast(ProviderValue, IPropertyProvider).PropertyName = Name
+ End Sub
#End Region
+#Region "Updaters, Checkers"
Friend PropertiesChecking As String()
Friend PropertiesCheckingMethod As MethodInfo
Private UpdateMethod As MethodInfo
- Private _UpdateDependencies As String() = Nothing
- Friend ReadOnly Property UpdateDependencies As String()
- Get
- Return _UpdateDependencies
- End Get
- End Property
- Friend Sub SetUpdateMethod(ByVal m As MethodInfo, ByVal Dependencies As String())
+ Private UpdateMethodArguments As String()
+ Friend Sub SetUpdateMethod(ByVal m As MethodInfo, ByVal _UpdateMethodArguments As String())
UpdateMethod = m
- _UpdateDependencies = Dependencies
+ UpdateMethodArguments = _UpdateMethodArguments
End Sub
- Friend ReadOnly IsTaskCounter As Boolean
#End Region
- Friend ReadOnly Exists As Boolean = False
+#Region "Dependents"
+ Private ReadOnly DependentNames As New List(Of String)
+ Private ReadOnly Dependents As New List(Of PropertyValueHost)
+ Private Sub UpdateDependence()
+ If TypeOf Control Is CheckBox Then
+ DirectCast(Control, CheckBox).Checked = CBool(AConvert(Of Boolean)(Value, False))
+ Else
+ DirectCast(Control, TextBoxExtended).Text = CStr(AConvert(Of String)(Value, String.Empty))
+ End If
+ End Sub
+#End Region
+#End Region
#Region "Initializer"
Protected Sub New()
End Sub
- Friend Sub New(ByRef PropertySource As Object, ByVal Member As MemberInfo)
+ Friend Sub New(ByRef Keeper As SettingsHost, ByRef PropertySource As Object, ByVal Member As MemberInfo)
+ Me.Keeper = Keeper
Source = PropertySource
Name = Member.Name
@@ -229,6 +256,7 @@ Namespace Plugin.Hosts
IsTaskCounter = Not Member.GetCustomAttribute(Of TaskCounter)() Is Nothing
_XmlName = If(Member.GetCustomAttribute(Of PXML)()?.ElementName, String.Empty)
If Not _XmlName.IsEmptyString Then XValue = CreateXMLValueInstance([Type], True)
+ DependentNames.ListAddList(Member.GetCustomAttribute(Of DependentFields)?.Fields, LAP.NotContainsOnly)
Exists = True
End If
End Sub
@@ -239,6 +267,13 @@ Namespace Plugin.Hosts
Value(False) = XValue.Value
End If
End Sub
+ Friend Sub SetDependents(ByVal Props As List(Of PropertyValueHost))
+ If DependentNames.Count > 0 And Props.Count > 0 Then
+ For Each prop As PropertyValueHost In Props
+ If DependentNames.Contains(prop.Name) Then Dependents.Add(prop)
+ Next
+ End If
+ End Sub
#End Region
#Region "Value"
Protected ReadOnly Property ExternalValue As PropertyValue
diff --git a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
index 9ab651c..d40d84e 100644
--- a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
@@ -131,17 +131,6 @@ Namespace Plugin.Hosts
End Set
End Property
Friend ReadOnly Property GetUserMediaOnly As XMLValue(Of Boolean)
-#End Region
-#Region "Host internal functions"
- Private Sub PropHost_OnPropertyUpdateRequested(ByVal Sender As PropertyValueHost)
- If Sender.UpdateDependencies.ListExists Then
- Settings.BeginUpdate()
- For Each p As PropertyValueHost In PropList
- If Sender.UpdateDependencies.Contains(p.Name) Then p.UpdateValueByControl()
- Next
- Settings.EndUpdate()
- End If
- End Sub
#End Region
Friend Sub New(ByVal Plugin As ISiteSettings, ByRef _XML As XmlFile, ByVal GlobalPath As SFile,
ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean))
@@ -188,10 +177,11 @@ Namespace Plugin.Hosts
Dim Updaters As New List(Of MemberInfo)
Dim Providers As New List(Of MemberInfo)
Dim PropCheckers As New List(Of MemberInfo)
+
Dim m As MemberInfo
For Each m In Members
If m.MemberType = MemberTypes.Property Then
- PropList.Add(New PropertyValueHost(Source, m))
+ PropList.Add(New PropertyValueHost(Me, Source, m))
With DirectCast(m, PropertyInfo)
If .PropertyType Is GetType(Responser) AndAlso m.GetCustomAttribute(Of DoNotUse)() Is Nothing Then _ResponserGetMethod = .GetMethod
End With
@@ -218,7 +208,7 @@ Namespace Plugin.Hosts
For Each m In Updaters
up = m.GetCustomAttribute(Of PropertyUpdater)()
i = PropList.FindIndex(Function(p) p.Name = up.Name)
- If i >= 0 Then PropList(i).SetUpdateMethod(DirectCast(m, MethodInfo), up.Dependencies)
+ If i >= 0 Then PropList(i).SetUpdateMethod(DirectCast(m, MethodInfo), up.Arguments)
Next
Updaters.Clear()
End If
@@ -252,6 +242,7 @@ Namespace Plugin.Hosts
Next
PropCheckers.Clear()
End If
+ PropList.ForEach(Sub(p) p.SetDependents(PropList))
End If
_Path = New XMLValue(Of SFile)("Path",, _XML, n, New XMLToFilePathProvider)
@@ -277,7 +268,6 @@ Namespace Plugin.Hosts
For Each p As PropertyValueHost In PropList
p.SetXmlEnvironment(_XML, n)
p.LeftOffset = MaxOffset
- AddHandler p.OnPropertyUpdateRequested, AddressOf PropHost_OnPropertyUpdateRequested
Next
End If
diff --git a/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb b/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb
index a5ba1fa..f051bdc 100644
--- a/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/UserDataHost.vb
@@ -48,11 +48,13 @@ Namespace Plugin.Hosts
.LogProvider = LogConnector
.Name = Name
.ID = ID
+ .Options = Options
.ParseUserMediaOnly = ParseUserMediaOnly
.UserDescription = UserDescription
.UserExists = .UserExists
.UserSuspended = UserSuspended
.IsSavedPosts = IsSavedPosts
+ .IsSubscription = IsSubscription
.SeparateVideoFolder = SeparateVideoFolderF
.DataPath = MyFile.CutPath.PathNoSeparator
.PostsNumberLimit = DownloadTopCount
diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj
index ba8e50d..c983650 100644
--- a/SCrawler/SCrawler.vbproj
+++ b/SCrawler/SCrawler.vbproj
@@ -113,11 +113,11 @@
My Project\app.manifest
-
- ..\packages\LibVLCSharp.3.6.6\lib\net40\LibVLCSharp.dll
+
+ ..\packages\LibVLCSharp.3.7.0\lib\net40\LibVLCSharp.dll
-
- ..\packages\LibVLCSharp.WinForms.3.6.6\lib\net40\LibVLCSharp.WinForms.dll
+
+ ..\packages\LibVLCSharp.WinForms.3.7.0\lib\net40\LibVLCSharp.WinForms.dll
..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll
@@ -166,12 +166,15 @@
Form
+
+
+
@@ -191,6 +194,7 @@
+
@@ -202,6 +206,7 @@
+
RedditViewSettingsForm.vb
@@ -216,15 +221,18 @@
+
+
+
@@ -307,6 +315,12 @@
Form
+
+ UserDownloadQueueForm.vb
+
+
+ Form
+
ColorPicker.vb
@@ -314,6 +328,12 @@
UserControl
+
+ GlobalLocationsChooserForm.vb
+
+
+ Form
+
UsersInfoForm.vb
@@ -514,12 +534,18 @@
VideoDownloaderForm.vb
+
+ UserDownloadQueueForm.vb
+
CollectionEditorForm.vb
ColorPicker.vb
+
+ GlobalLocationsChooserForm.vb
+
GlobalSettingsForm.vb
@@ -618,7 +644,6 @@
-
@@ -670,14 +695,17 @@
+
+
+
-
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
+
\ No newline at end of file
diff --git a/SCrawler/SettingsCLS.vb b/SCrawler/SettingsCLS.vb
index baddf2e..65d6663 100644
--- a/SCrawler/SettingsCLS.vb
+++ b/SCrawler/SettingsCLS.vb
@@ -26,6 +26,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Private Const SitesValuesSeparator As String = ","
Friend Const CookieEncryptKey As String = "SCrawlerCookiesEncryptKeyword"
Private Const EnvironmentPath As String = "Environment\"
+ Friend Const CollectionsFolderName As String = "Collections"
Friend Const DefaultCmdEncoding As Integer = BatchExecutor.UnicodeEncoding
Friend ReadOnly Design As XmlFile
Private ReadOnly MyXML As XmlFile
@@ -83,8 +84,41 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property YtdlpFile As ProgramFile
Friend ReadOnly Property GalleryDLFile As ProgramFile
Friend ReadOnly Property CurlFile As ProgramFile
+ Private ReadOnly Property ENVIR_FFMPEG As SFile Implements IDownloaderSettings.ENVIR_FFMPEG
+ Get
+ Return FfmpegFile
+ End Get
+ End Property
+ Private ReadOnly Property ENVIR_YTDLP As SFile Implements IDownloaderSettings.ENVIR_YTDLP
+ Get
+ Return YtdlpFile
+ End Get
+ End Property
+ Private ReadOnly Property ENVIR_GDL As SFile Implements IDownloaderSettings.ENVIR_GDL
+ Get
+ Return GalleryDLFile
+ End Get
+ End Property
+ Private ReadOnly Property ENVIR_CURL As SFile Implements IDownloaderSettings.ENVIR_CURL
+ Get
+ Return CurlFile
+ End Get
+ End Property
#End Region
Friend ReadOnly Property Cache As CacheKeeper
+ Private _CacheSnapshots As CacheKeeper = Nothing
+ Friend ReadOnly Property CacheSnapshots(ByVal Permanent As Boolean) As CacheKeeper
+ Get
+ If Permanent Then
+ If _CacheSnapshots Is Nothing Then _CacheSnapshots = New CacheKeeper("_CacheSnapshots\") With {.DeleteCacheOnDispose = False, .DeleteRootOnDispose = False}
+ Return _CacheSnapshots
+ Else
+ Dim dir As SFile = $"{Cache.RootDirectory.PathWithSeparator}Snapshots\"
+ Cache.AddPath(dir)
+ Return Cache.GetInstance(dir)
+ End If
+ End Get
+ End Property
Friend ReadOnly Plugins As List(Of PluginHost)
Friend ReadOnly Property Users As List(Of IUserData)
Friend ReadOnly Property UsersList As List(Of UserInfo)
@@ -92,6 +126,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property Labels As LabelsKeeper
Friend ReadOnly Property Groups As Groups.DownloadGroupCollection
Friend ReadOnly Property LastCollections As List(Of String)
+ Friend ReadOnly Property DownloadLocations As STDownloader.DownloadLocationsCollection
+ Friend ReadOnly Property GlobalLocations As STDownloader.DownloadLocationsCollection
Friend Property Automation As Scheduler
Friend ReadOnly Property BlackList As List(Of UserBan)
Private ReadOnly BlackListFile As SFile = $"{SettingsFolderName}\BlackList.txt"
@@ -108,6 +144,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
BlackList = New List(Of UserBan)
Plugins = New List(Of PluginHost)
LastCollections = New List(Of String)
+ GlobalLocations = New STDownloader.DownloadLocationsCollection
+ GlobalLocations.Load(True,, $"{SettingsFolderName}\GlobalLocations.xml")
Dim n() As String = {"MediaEnvironment"}
@@ -130,7 +168,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
LastCopyPath = New XMLValue(Of SFile)("LastCopyPath",, MyXML,, New XMLToFilePathProvider)
SeparateVideoFolder = New XMLValue(Of Boolean)("SeparateVideoFolder", True, MyXML)
- CollectionsPath = New XMLValue(Of String)("CollectionsPath", "Collections", MyXML)
+ CollectionsPath = New XMLValue(Of String)("CollectionsPath", CollectionsFolderName, MyXML)
UserAgent = New XMLValue(Of String)("UserAgent",, MyXML)
If Not UserAgent.IsEmptyString Then DefaultUserAgent = UserAgent
@@ -162,6 +200,10 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
DefaultDownloadImages, DefaultDownloadVideos)
If tmpPluginList.ListExists Then Plugins.AddRange(tmpPluginList)
+ MainFrameUsersShowDefaults = New XMLValue(Of Boolean)("UsersShowDefaults", True, MyXML)
+ MainFrameUsersShowSubscriptions = New XMLValue(Of Boolean)("UsersShowSubscriptions", True, MyXML)
+ MainFrameUsersSubscriptionsColorBack = New XMLValue(Of Color)("UsersSubscriptionsColorBack", MyColor.OkBack, MyXML)
+ MainFrameUsersSubscriptionsColorFore = New XMLValue(Of Color)("UsersSubscriptionsColorFore", MyColor.OkFore, MyXML)
FastProfilesLoading = New XMLValue(Of Boolean)("FastProfilesLoading", True, MyXML)
MaxLargeImageHeight = New XMLValue(Of Integer)("MaxLargeImageHeight", 150, MyXML)
MaxSmallImageHeight = New XMLValue(Of Integer)("MaxSmallImageHeight", 15, MyXML)
@@ -176,6 +218,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
ClosingCommand = New XMLValueAttribute(Of String, Boolean)("ClosingCommand", "Use",,, MyXML)
AddHandler ClosingCommand.ValueChanged, Sub(s, ev) MainFrameObj?.ChangeCloseVisible()
InfoViewMode = New XMLValue(Of Integer)("InfoViewMode", DownloadedInfoForm.ViewModes.Session, MyXML)
+ InfoViewDefault = New XMLValue(Of Boolean)("InfoViewDefault", True, MyXML)
ViewMode = New XMLValue(Of Integer)("ViewMode", ViewModes.IconLarge, MyXML)
ShowingMode = New XMLValue(Of Integer)("ShowingMode", ShowingModes.All, MyXML)
ShowGroupsInsteadLabels = New XMLValue(Of Boolean)("ShowGroupsInsteadLabels", False, MyXML)
@@ -217,8 +260,15 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
STDownloader_RemoveDownloadedAutomatically = New XMLValue(Of Boolean)("RemoveDownloadedAutomatically", False, MyXML, n)
STDownloader_OnItemDoubleClick = New XMLValue(Of DoubleClickBehavior)("OnItemDoubleClick", DoubleClickBehavior.Folder, MyXML, n)
STDownloader_TakeSnapshot = New XMLValue(Of Boolean)("TakeSnapshot", True, MyXML, n)
+ STDownloader_SnapshotsKeepWithFiles = New XMLValue(Of Boolean)("SnapshotsKeepWithFiles", True, MyXML, n)
+ STDownloader_SnapShotsCachePermamnent = New XMLValue(Of Boolean)("SnapShotsCachePermamnent", False, MyXML, n)
STDownloader_RemoveYTVideosOnClear = New XMLValue(Of Boolean)("RemoveYouTubeVideosOnClear", False, MyXML, n)
STDownloader_LoadYTVideos = New XMLValue(Of Boolean)("LoadYouTubeVideos", False, MyXML, n)
+ STDownloader_OutputPathUseYT = New XMLValue(Of Boolean)("OutputPathUseYT", False, MyXML, n)
+ STDownloader_OutputPathAskForName = New XMLValue(Of Boolean)("OutputPathAskForName", True, MyXML, n)
+ STDownloader_OutputPathAutoAddPaths = New XMLValue(Of Boolean)("OutputPathAutoAddPaths", True, MyXML, n)
+ DownloadLocations = New STDownloader.DownloadLocationsCollection
+ DownloadLocations.Load(False, STDownloader_OutputPathUseYT)
n = {"Feed"}
FeedDataColumns = New XMLValue(Of Integer)("DataColumns", 1, MyXML, n)
@@ -232,6 +282,9 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
FeedBackColor.SetExtended("FeedColorBack",, MyXML, n)
FeedForeColor = New XMLValue(Of Color)
FeedForeColor.SetExtended("FeedColorFore",, MyXML, n)
+ FeedOpenLastMode = New XMLValue(Of Boolean)("OpenLastMode", False, MyXML, n)
+ FeedLastModeSubscriptions = New XMLValue(Of Boolean)("LastModeSubscriptions", False, MyXML, n)
+ FeedShowFriendlyNames = New XMLValue(Of Boolean)("ShowFriendlyNames", True, MyXML, n)
n = {"Users"}
FromChannelDownloadTop = New XMLValue(Of Integer)("FromChannelDownloadTop", 10, MyXML, n)
@@ -264,6 +317,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
ShowNotificationsSTDownloader = New XMLValue(Of Boolean)("STDownloader", True, MyXML, n)
ShowNotificationsSTDownloaderEveryDownload = New XMLValue(Of Boolean)("STDownloaderEveryDownload", True, MyXML, n)
+ ProgramText = New XMLValue(Of String)("ProgramText",, MyXML)
+ ProgramDescription = New XMLValue(Of String)("ProgramDescription",, MyXML)
ExitConfirm = New XMLValue(Of Boolean)("ExitConfirm", True, MyXML)
CloseToTray = New XMLValue(Of Boolean)("CloseToTray", True, MyXML)
OpenFolderInOtherProgram = New XMLValueUse(Of String)("OpenFolderInOtherProgram",,, MyXML)
@@ -707,8 +762,23 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
End Get
End Property
Friend ReadOnly Property STDownloader_TakeSnapshot As XMLValue(Of Boolean)
+ Friend ReadOnly Property STDownloader_SnapshotsKeepWithFiles As XMLValue(Of Boolean)
+ Friend ReadOnly Property STDownloader_SnapShotsCachePermamnent As XMLValue(Of Boolean)
Friend ReadOnly Property STDownloader_RemoveYTVideosOnClear As XMLValue(Of Boolean)
Friend ReadOnly Property STDownloader_LoadYTVideos As XMLValue(Of Boolean)
+ Friend ReadOnly Property STDownloader_OutputPathUseYT As XMLValue(Of Boolean)
+ Friend ReadOnly Property STDownloader_OutputPathAskForName As XMLValue(Of Boolean)
+ Private ReadOnly Property IDownloaderSettings_OutputPathAskForName As Boolean Implements IDownloaderSettings.OutputPathAskForName
+ Get
+ Return STDownloader_OutputPathAskForName
+ End Get
+ End Property
+ Friend ReadOnly Property STDownloader_OutputPathAutoAddPaths As XMLValue(Of Boolean)
+ Private ReadOnly Property IDownloaderSettings_OutputPathAutoAddPaths As Boolean Implements IDownloaderSettings.OutputPathAutoAddPaths
+ Get
+ Return STDownloader_OutputPathAutoAddPaths
+ End Get
+ End Property
#End Region
#Region "User metrics"
Friend ReadOnly Property UMetrics_What As XMLValue(Of Integer)
@@ -730,6 +800,10 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
#End Region
#End Region
#Region "View"
+ Friend ReadOnly Property MainFrameUsersShowDefaults As XMLValue(Of Boolean)
+ Friend ReadOnly Property MainFrameUsersShowSubscriptions As XMLValue(Of Boolean)
+ Friend ReadOnly Property MainFrameUsersSubscriptionsColorBack As XMLValue(Of Color)
+ Friend ReadOnly Property MainFrameUsersSubscriptionsColorFore As XMLValue(Of Color)
Friend ReadOnly Property FastProfilesLoading As XMLValue(Of Boolean)
Friend ReadOnly Property MaxLargeImageHeight As XMLValue(Of Integer)
Friend ReadOnly Property MaxSmallImageHeight As XMLValue(Of Integer)
@@ -751,6 +825,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property DownloadsCompleteCommand As XMLValueAttribute(Of String, Boolean)
Friend ReadOnly Property ClosingCommand As XMLValueAttribute(Of String, Boolean)
Friend ReadOnly Property InfoViewMode As XMLValue(Of Integer)
+ Friend ReadOnly Property InfoViewDefault As XMLValue(Of Boolean)
Friend ReadOnly Property ViewMode As XMLValue(Of Integer)
Friend ReadOnly Property ViewModeIsPicture As Boolean
Get
@@ -812,6 +887,9 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property FeedStoreSessionsData As XMLValue(Of Boolean)
Friend ReadOnly Property FeedBackColor As XMLValue(Of Color)
Friend ReadOnly Property FeedForeColor As XMLValue(Of Color)
+ Friend ReadOnly Property FeedOpenLastMode As XMLValue(Of Boolean)
+ Friend ReadOnly Property FeedLastModeSubscriptions As XMLValue(Of Boolean)
+ Friend ReadOnly Property FeedShowFriendlyNames As XMLValue(Of Boolean)
#End Region
#Region "New version properties"
Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean)
@@ -854,6 +932,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
Friend ReadOnly Property ShowNotificationsSTDownloaderEveryDownload As XMLValue(Of Boolean)
#End Region
#Region "Other program properties"
+ Friend ReadOnly Property ProgramText As XMLValue(Of String)
+ Friend ReadOnly Property ProgramDescription As XMLValue(Of String)
Friend ReadOnly Property ExitConfirm As XMLValue(Of Boolean)
Friend ReadOnly Property CloseToTray As XMLValue(Of Boolean)
Friend ReadOnly Property OpenFolderInOtherProgram As XMLValueUse(Of String)
diff --git a/SCrawler/SiteResources.Designer.vb b/SCrawler/SiteResources.Designer.vb
index dff6ac0..2322380 100644
--- a/SCrawler/SiteResources.Designer.vb
+++ b/SCrawler/SiteResources.Designer.vb
@@ -274,16 +274,6 @@ Namespace My.Resources
End Get
End Property
- '''
- ''' Looks up a localized resource of type System.Drawing.Bitmap.
- '''
- Friend Shared ReadOnly Property TwitterPic_400() As System.Drawing.Bitmap
- Get
- Dim obj As Object = ResourceManager.GetObject("TwitterPic_400", resourceCulture)
- Return CType(obj,System.Drawing.Bitmap)
- End Get
- End Property
-
'''
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
'''
diff --git a/SCrawler/SiteResources.resx b/SCrawler/SiteResources.resx
index fc91260..93beb33 100644
--- a/SCrawler/SiteResources.resx
+++ b/SCrawler/SiteResources.resx
@@ -181,9 +181,6 @@
Content\Icons\SiteIcons\TwitterIcon_32.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- Content\Pictures\SitePictures\TwitterPic_400.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
Content\Icons\SiteIcons\XhamsterIcon_32.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
diff --git a/SCrawler/UserFinder.vb b/SCrawler/UserFinder.vb
index bca903e..8eac2f2 100644
--- a/SCrawler/UserFinder.vb
+++ b/SCrawler/UserFinder.vb
@@ -83,7 +83,8 @@ Friend Class UserFinder : Implements IDisposable
.SpecialCollectionPath = x.Value(UserInfo.Name_SpecialCollectionPath),
.UserModel = x.Value(UserInfo.Name_Model_User).FromXML(Of Integer)(UsageModel.Default),
.CollectionModel = x.Value(UserInfo.Name_Model_Collection).FromXML(Of Integer)(UsageModel.Default),
- .CollectionName = x.Value(UserInfo.Name_Collection)
+ .CollectionName = x.Value(UserInfo.Name_Collection),
+ .IsSubscription = x.Value(UserInfo.Name_IsSubscription).FromXML(Of Boolean)(False)
}
u.Merged = x.Value(UserInfo.Name_Merged).FromXML(Of Boolean)(False)
FoundUsers.Add(u)
diff --git a/SCrawler/UserInfo.vb b/SCrawler/UserInfo.vb
index 639c6c3..223daaa 100644
--- a/SCrawler/UserInfo.vb
+++ b/SCrawler/UserInfo.vb
@@ -12,11 +12,12 @@ Imports SCrawler.Plugin.Hosts
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Partial Friend Module MainMod
- Friend Structure UserInfo : Implements IComparable(Of UserInfo), IEquatable(Of UserInfo), ICloneable, IEContainerProvider
+ Friend Structure UserInfo : Implements IComparable(Of UserInfo), IEquatable(Of UserInfo), IEContainerProvider
#Region "XML Names"
Friend Const Name_UserNode As String = "User"
Friend Const Name_Site As String = "Site"
Friend Const Name_Plugin As String = "Plugin"
+ Friend Const Name_IsSubscription As String = "IsSubscription"
Friend Const Name_Collection As String = "Collection"
Friend Const Name_Model_User As String = "ModelUser"
Friend Const Name_Model_Collection As String = "ModelCollection"
@@ -30,6 +31,7 @@ Partial Friend Module MainMod
Friend Site As String
Friend Plugin As String
Friend File As SFile
+ Friend IsSubscription As Boolean
Friend SpecialPath As SFile
Friend SpecialCollectionPath As SFile
Friend Merged As Boolean
@@ -65,6 +67,7 @@ Partial Friend Module MainMod
Name = x.Value
Site = x.Attribute(Name_Site).Value
Plugin = x.Attribute(Name_Plugin).Value
+ IsSubscription = x.Attribute(Name_IsSubscription).Value.FromXML(Of Boolean)(False)
CollectionName = x.Attribute(Name_Collection).Value
CollectionModel = x.Attribute(Name_Model_Collection).Value.FromXML(Of Integer)(UsageModel.Default)
UserModel = x.Attribute(Name_Model_User).Value.FromXML(Of Integer)(UsageModel.Default)
@@ -101,6 +104,7 @@ Partial Friend Module MainMod
End Function
#End Region
#Region "FilePath"
+ Friend Const CollectionUserPathPattern As String = "{0}\{1}_{2}\"
Friend Sub UpdateUserFile()
File = New SFile With {
.Separator = "\",
@@ -109,23 +113,39 @@ Partial Friend Module MainMod
.Name = $"{UserDataBase.UserFileAppender}_{Site}_{Name}"
}
End Sub
+ Friend Function GetCollectionRootPath() As SFile
+ If IncludedInCollection And Not IsVirtual Then
+ Dim ColPath$ = If(SpecialCollectionPath.IsEmptyString, Settings.CollectionsPathF, SpecialCollectionPath).PathNoSeparator
+ If SpecialCollectionPath.IsEmptyString Then ColPath &= $"\{CollectionName}"
+ Return ColPath.CSFileP
+ Else
+ Return Nothing
+ End If
+ End Function
Private Function GetFilePathByParams() As String
If [Protected] Then Return String.Empty
- Dim ColPath$ = If(SpecialCollectionPath.IsEmptyString, Settings.CollectionsPathF, SpecialCollectionPath).PathNoSeparator
- If SpecialCollectionPath.IsEmptyString Then ColPath &= $"\{CollectionName}"
- If Not SpecialPath.IsEmptyString Then
- Return $"{SpecialPath.PathWithSeparator}{SettingsFolderName}"
- ElseIf Merged And IncludedInCollection Then
- Return $"{ColPath}\{SettingsFolderName}"
- Else
- If IncludedInCollection And Not IsVirtual Then
- Return $"{ColPath}\{Site}_{Name}\{SettingsFolderName}"
- ElseIf Not Settings(Plugin) Is Nothing Then
- Return $"{Settings(Plugin).Path.PathNoSeparator}\{Name}\{SettingsFolderName}"
+ If IsSubscription Then
+ If Not Settings(Plugin) Is Nothing Then
+ Return $"{Application.StartupPath.CSFilePSN}\{SettingsFolderName}\Subscriptions\{Settings(Plugin).Key}\{Name}\{SettingsFolderName}"
Else
- Dim s$ = Site.ToLower
- Dim i% = Settings.Plugins.FindIndex(Function(p) p.Name.ToLower = s)
- If i >= 0 Then Return $"{Settings.Plugins(i).Settings.Path.PathNoSeparator}\{Name}\{SettingsFolderName}" Else Return String.Empty
+ Return String.Empty
+ End If
+ Else
+ Dim ColPath$ = GetCollectionRootPath().PathNoSeparator
+ If Not SpecialPath.IsEmptyString Then
+ Return $"{SpecialPath.PathWithSeparator}{SettingsFolderName}"
+ ElseIf Merged And IncludedInCollection Then
+ Return $"{ColPath}\{SettingsFolderName}"
+ Else
+ If IncludedInCollection And Not IsVirtual Then
+ Return $"{String.Format(CollectionUserPathPattern, ColPath, Site, Name)}{SettingsFolderName}"
+ ElseIf Not Settings(Plugin) Is Nothing Then
+ Return $"{Settings(Plugin).Path.PathNoSeparator}\{Name}\{SettingsFolderName}"
+ Else
+ Dim s$ = Site.ToLower
+ Dim i% = Settings.Plugins.FindIndex(Function(p) p.Name.ToLower = s)
+ If i >= 0 Then Return $"{Settings.Plugins(i).Settings.Path.PathNoSeparator}\{Name}\{SettingsFolderName}" Else Return String.Empty
+ End If
End If
End If
End Function
@@ -134,6 +154,7 @@ Partial Friend Module MainMod
Friend Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
Return New EContainer(Name_UserNode, Name, {New EAttribute(Name_Site, Site),
New EAttribute(Name_Plugin, Plugin),
+ New EAttribute(Name_IsSubscription, IsSubscription.BoolToInteger),
New EAttribute(Name_Collection, CollectionName),
New EAttribute(Name_Model_User, CInt(UserModel)),
New EAttribute(Name_Model_Collection, CInt(CollectionModel)),
@@ -155,27 +176,11 @@ Partial Friend Module MainMod
#Region "IEquatable Support"
Friend Overloads Function Equals(ByVal Other As UserInfo) As Boolean Implements IEquatable(Of UserInfo).Equals
Return Site.StringToLower = Other.Site.StringToLower And Name.StringToLower = Other.Name.StringToLower And
- (Not Plugin = PathPlugin.PluginKey Or SpecialPath = Other.SpecialPath)
+ IsSubscription = Other.IsSubscription And (Not Plugin = PathPlugin.PluginKey Or SpecialPath = Other.SpecialPath)
End Function
Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
Return Equals(DirectCast(Obj, UserInfo))
End Function
-#End Region
-#Region "ICloneable Support"
- Friend Function Clone() As Object Implements ICloneable.Clone
- Return New UserInfo With {
- .Name = Name,
- .Site = Site,
- .Plugin = Plugin,
- .File = File,
- .SpecialPath = SpecialPath,
- .Merged = Merged,
- .CollectionName = CollectionName,
- .CollectionModel = CollectionModel,
- .UserModel = UserModel,
- .[Protected] = [Protected]
- }
- End Function
#End Region
End Structure
End Module
\ No newline at end of file
diff --git a/SCrawler/UserSearchForm.vb b/SCrawler/UserSearchForm.vb
index 8dc50cc..ea18085 100644
--- a/SCrawler/UserSearchForm.vb
+++ b/SCrawler/UserSearchForm.vb
@@ -24,14 +24,14 @@ Friend Class UserSearchForm
Friend Sub New(ByVal User As IUserData, ByVal Mode As Modes)
Key = User.Key
IsCollection = User.IsCollection
- Text = $"[{IIf(IsCollection, "C", "U")}] "
+ Me.Mode = Mode
+ Text = $"[{Mode.ToString.First.ToString.ToUpper}] [{IIf(IsCollection, "C", "U")}] "
If IsCollection Then
Text &= $"[{User.CollectionName}] "
Else
If User.IncludedInCollection Then Text &= $"[{User.CollectionName}] "
Text &= $"[{User.Site}] [{User.Name}]"
End If
- Me.Mode = Mode
End Sub
Private Function CompareTo(ByVal Other As SearchResult) As Integer Implements IComparable(Of SearchResult).CompareTo
If CInt(Mode).CompareTo(CInt(Other.Mode)) = 0 Then
@@ -41,7 +41,9 @@ Friend Class UserSearchForm
End If
End Function
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
- With DirectCast(Obj, SearchResult) : Return Key = .Key And Mode = .Mode : End With
+ 'TODO: [UserSearchForm]: updated equal function
+ With DirectCast(Obj, SearchResult) : Return Key = .Key : End With
+ 'With DirectCast(Obj, SearchResult) : Return Key = .Key And Mode = .Mode : End With
End Function
End Structure
Public Sub New()
@@ -125,7 +127,7 @@ Friend Class UserSearchForm
If .Count > 0 Then
For i = 0 To .Count - 1
With .Item(i)
- If Not __isUrl AndAlso __name AndAlso .Self.Name.ToLower = t Then Results.ListAddValue(New SearchResult(.Self, SearchResult.Modes.Name), RLP)
+ If Not __isUrl AndAlso __name AndAlso .Self.Name.ToLower.Contains(t) Then Results.ListAddValue(New SearchResult(.Self, SearchResult.Modes.Name), RLP)
_addValue(.Self, SearchResult.Modes.URL, _p_url)
_addValue(.Self, SearchResult.Modes.Description, _p_descr)
_addValue(.Self, SearchResult.Modes.Label, _p_labels)
diff --git a/SCrawler/packages.config b/SCrawler/packages.config
index ac4353d..1e554cb 100644
--- a/SCrawler/packages.config
+++ b/SCrawler/packages.config
@@ -1,10 +1,10 @@
-
-
+
+
-
+
\ No newline at end of file