2024.3.30.0

UPDATE DOWNLOAD GROUP ENVIRONMENT

Add the ability to filter users who have been (not)downloaded in the last x days.
DownloadedInfoForm: fix possible bug
Feed: fix scrolling bug
IUserData, UserDataBase, UserDataBind: remove 'FitToAddParams'
UserDataBase: update 'GetLVIGroup' function; wrong decision to set 'LastUpdated' date
AutoDownloader: remove 'All' and 'Default' options
SettingsCLS: refactoring the code and XML file
This commit is contained in:
Andy
2024-03-30 09:40:52 +03:00
parent b252d32a7e
commit efa09fb457
32 changed files with 2404 additions and 1699 deletions

View File

@@ -10,22 +10,44 @@ Imports SCrawler.API.Base
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Namespace DownloadObjects.Groups
Friend Class DownloadGroup : Inherits GroupParameters : Implements IIndexable, IEContainerProvider
Friend Class DownloadGroup : Inherits GroupParameters : Implements IIndexable, IEContainerProvider, IComparable(Of DownloadGroup)
#Region "Events"
Friend Delegate Sub GroupEventHandler(ByVal Sender As DownloadGroup)
Friend Event Deleted As GroupEventHandler
Friend Event Updated As GroupEventHandler
#End Region
#Region "XML names"
Private Const Name_FilterViewMode As String = "FilterViewMode"
Private Const Name_FilterGroupUsers As String = "FilterGroupUsers"
Private Const Name_FilterShowGroupsInsteadLabels As String = "FilterShowGroupsInsteadLabels"
#End Region
#Region "Declarations"
#Region "Controls"
Private WithEvents BTT_EDIT As ToolStripMenuItem
Private WithEvents BTT_DELETE As ToolStripMenuItem
Private WithEvents BTT_DOWNLOAD As ToolStripMenuItem
Private WithEvents BTT_DOWNLOAD_FULL As ToolStripMenuItem
Private WithEvents BTT_DOWNLOAD As ToolStripKeyMenuItem
Private WithEvents BTT_CLONE_ADD As ToolStripMenuItem
Private WithEvents BTT_CLONE_TEMP As ToolStripKeyMenuItem
Private ReadOnly SEP_1 As ToolStripSeparator
Private WithEvents BTT_MENU As ToolStripMenuItem
Private ReadOnly SEP_2 As ToolStripSeparator
Private WithEvents BTT_MENU As ToolStripKeyMenuItem
#End Region
#Region "Filter declarations"
Friend Property FilterViewMode As ViewModes = ViewModes.IconLarge
Friend Property FilterGroupUsers As Boolean = True
Friend Property FilterShowGroupsInsteadLabels As Boolean = True
#End Region
Private File As SFile = Nothing
Friend Overrides Property Name As String
Get
Return MyBase.Name
End Get
Set(ByVal NewName As String)
Dim b As Boolean = Not MyBase.Name.IsEmptyString AndAlso Not MyBase.Name = NewName
MyBase.Name = NewName
If b Then RaiseEvent Updated(Me)
End Set
End Property
Friend Property NameBefore As String = String.Empty
Private _Key As String = String.Empty
Friend ReadOnly Property Key As String
@@ -49,55 +71,114 @@ Namespace DownloadObjects.Groups
DirectCast(Obj, DownloadGroup).Index = _Index
Return Obj
End Function
Friend Shared ReadOnly Property GroupImage As Bitmap
Get
Return My.Resources.GroupByIcon_16.ToBitmap
End Get
End Property
#End Region
#Region "Initializers"
Friend ReadOnly NeedToSave As Boolean = False
Friend Sub New()
BTT_MENU = New ToolStripMenuItem With {
Me.New(True)
End Sub
Friend Sub New(ByVal InitButtons As Boolean)
If InitButtons Then
BTT_MENU = New ToolStripKeyMenuItem With {
.ToolTipText = "Download users of this group",
.AutoToolTip = True,
.Image = My.Resources.GroupByIcon_16.ToBitmap
.Image = GroupImage
}
BTT_DELETE = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.DeletePic_Red_24,
.BackColor = MyColor.DeleteBack,
.ForeColor = MyColor.DeleteFore,
.Text = "Delete",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
BTT_EDIT = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.PencilPic_16,
.BackColor = MyColor.EditBack,
.ForeColor = MyColor.EditFore,
.Text = "Edit",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
SEP_1 = New ToolStripSeparator
BTT_DOWNLOAD = New ToolStripMenuItem With {
.Image = My.Resources.StartPic_Green_16,
.Text = "Download",
.ToolTipText = "Download users of this group (respect the 'Ready for download' parameter)",
.AutoToolTip = True
}
BTT_DOWNLOAD_FULL = New ToolStripMenuItem With {
.Image = My.Resources.StartPic_Green_16,
.Text = "Download FULL",
.ToolTipText = "Download users of this group (ignore the 'Ready for download' parameter)",
.AutoToolTip = True
}
BTT_MENU.DropDownItems.AddRange({BTT_EDIT, BTT_DELETE, SEP_1, BTT_DOWNLOAD, BTT_DOWNLOAD_FULL})
BTT_DELETE = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.DeletePic_Red_24,
.BackColor = MyColor.DeleteBack,
.ForeColor = MyColor.DeleteFore,
.Text = "Delete",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
BTT_EDIT = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.PencilPic_16,
.BackColor = MyColor.EditBack,
.ForeColor = MyColor.EditFore,
.Text = "Edit",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
BTT_CLONE_ADD = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.PlusPic_Green_24,
.BackColor = MyColor.OkBack,
.ForeColor = MyColor.OkFore,
.Text = "Clone and add",
.ToolTipText = "Clone the group, change parameters and add this group as a new one",
.AutoToolTip = True
}
BTT_CLONE_TEMP = New ToolStripKeyMenuItem With {
.Image = PersonalUtilities.My.Resources.PlusPic_Green_24,
.BackColor = MyColor.OkBack,
.ForeColor = MyColor.OkFore,
.Text = "Clone and download",
.ToolTipText = "Clone the group, change parameters and download filtered users (this group will not be added as a new one)",
.AutoToolTip = True
}
SEP_1 = New ToolStripSeparator
SEP_2 = New ToolStripSeparator
BTT_DOWNLOAD = New ToolStripKeyMenuItem With {
.Image = My.Resources.StartPic_Green_16,
.Text = "Download",
.ToolTipText = "Download users of this group (respect the 'Ready for download' parameter)",
.AutoToolTip = True
}
BTT_MENU.DropDownItems.AddRange({BTT_EDIT, BTT_DELETE, SEP_1, BTT_CLONE_ADD, BTT_CLONE_TEMP, SEP_2, BTT_DOWNLOAD})
End If
End Sub
Friend Sub New(ByVal e As EContainer)
Me.New
Me.New(Not e.Value(Name_IsViewFilter).FromXML(Of Boolean)(False))
Import(e)
End Sub
#End Region
#Region "Import/Export"
Protected Overrides Sub Import(ByVal e As EContainer)
MyBase.Import(e)
If IsViewFilter Then
FilterViewMode = e.Value(Name_FilterViewMode).FromXML(Of Integer)(ViewModes.IconLarge)
FilterGroupUsers = e.Value(Name_FilterGroupUsers).FromXML(Of Boolean)(True)
FilterShowGroupsInsteadLabels = e.Value(Name_FilterShowGroupsInsteadLabels).FromXML(Of Boolean)(True)
End If
End Sub
Protected Overrides Function Export(ByVal e As EContainer) As EContainer
MyBase.Export(e)
e.AddRange({New EContainer(Name_FilterViewMode, CInt(FilterViewMode)),
New EContainer(Name_FilterGroupUsers, FilterGroupUsers.BoolToInteger),
New EContainer(Name_FilterShowGroupsInsteadLabels, FilterShowGroupsInsteadLabels.BoolToInteger)})
Return e
End Function
#End Region
#Region "Copy"
Friend Overloads Overrides Function Copy() As Object
Return (New DownloadGroup).Copy(Me)
End Function
Friend Overloads Overrides Function Copy(ByVal Source As Object) As Object
MyBase.Copy(Source)
If TypeOf Source Is DownloadGroup Then
With DirectCast(Source, DownloadGroup)
If .IsViewFilter Then
FilterViewMode = .FilterViewMode
FilterGroupUsers = .FilterGroupUsers
FilterShowGroupsInsteadLabels = .FilterShowGroupsInsteadLabels
End If
End With
End If
Return Me
End Function
#End Region
#Region "ToString"
Public Overrides Function ToString() As String
Return $"{IIf(Index.ValueBetween(0, 8), $"#{Index + 1}: ", String.Empty)}{Name}"
End Function
Friend Overrides Function ToStringViewFilters() As String
Return $"{IIf(IsViewFilter, "View filter", "Group")} '{Name}'"
End Function
#End Region
#Region "GetControl"
Private _ControlSent As Boolean = False
@@ -111,9 +192,39 @@ Namespace DownloadObjects.Groups
End Function
#End Region
#Region "Buttons"
Private Sub BTT_MENU_Click(sender As Object, e As EventArgs) Handles BTT_MENU.Click
DownloadUsers()
Private Sub BTT_MENU_Click(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_MENU.KeyClick
Try
With BTT_MENU
.HideDropDown()
Dim obj As Object = .Owner
Dim r% = 0
Do While Not obj Is Nothing And r < 5 : obj = TryHide(obj) : r += 1 : Loop
End With
Catch
End Try
ProcessDownloadUsers(e.IncludeInTheFeed)
End Sub
Private Function TryHide(ByVal Sender As Object) As Object
Dim retObj As Object = Nothing
Try
If Not Sender Is Nothing Then
If TypeOf Sender Is ToolStripDropDownMenu Then
With DirectCast(Sender, ToolStripDropDownMenu)
retObj = .OwnerItem
.Hide()
End With
ElseIf TypeOf Sender Is ToolStripMenuItem Then
With DirectCast(Sender, ToolStripMenuItem)
retObj = .Owner
.HideDropDown()
End With
End If
End If
Catch
End Try
If Not retObj Is Nothing AndAlso Not (TypeOf retObj Is ToolStripMenuItem Or TypeOf retObj Is ToolStripDropDownMenu) Then retObj = Nothing
Return retObj
End Function
Private Sub BTT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_EDIT.Click
Using f As New GroupEditorForm(Me)
f.ShowDialog()
@@ -121,67 +232,98 @@ Namespace DownloadObjects.Groups
End Using
End Sub
Private Sub BTT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE.Click
If MsgBoxE({$"Are you sure you want to delete the [{Name}] group?", "Deleting a group"}, vbExclamation + vbYesNo) = vbYes Then
Delete()
End Sub
Friend Function Delete(Optional ByVal Silent As Boolean = False) As Boolean
Dim msgTitle$ = $"Deleting a {IIf(IsViewFilter, "filter", "group")}"
If Silent OrElse MsgBoxE({$"Are you sure you want to delete the '{Name}' {IIf(IsViewFilter, "filter", "group")}?", msgTitle}, vbExclamation + vbYesNo) = vbYes Then
If Not Settings.Automation Is Nothing AndAlso Settings.Automation.Count > 0 Then
Dim aIncl As New List(Of String)
For Each plan As AutoDownloader In Settings.Automation
If plan.Mode = AutoDownloader.Modes.Groups AndAlso plan.Groups.Count > 0 AndAlso plan.Groups.Contains(Name) Then aIncl.Add(plan.Name)
Next
If aIncl.Count > 0 Then
MsgBoxE({$"The '{Name}' group cannot be deleted because it is included in the following scheduler plans:{vbCr}{vbCr}" &
aIncl.ListToString(vbCr), msgTitle}, vbCritical)
aIncl.Clear()
Return False
End If
End If
RaiseEvent Deleted(Me)
MsgBoxE({$"Group [{Name}] deleted", "Deleting a group"})
If Not Silent Then MsgBoxE({$"{IIf(IsViewFilter, "Filter", "Group")} '{Name}' deleted", msgTitle})
Return True
End If
Return False
End Function
Private Sub BTT_CLONE_ADD_Click(sender As Object, e As EventArgs) Handles BTT_CLONE_ADD.Click
Settings.Groups.CloneAndAdd(Me)
End Sub
Private Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click
DownloadUsers()
Private Sub BTT_CLONE_TEMP_Click(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_CLONE_TEMP.KeyClick
Using f As New GroupEditorForm(New DownloadGroup(False).Copy(Me)) With {.IsTemporaryGroup = True}
f.ShowDialog()
If f.DialogResult = DialogResult.OK AndAlso Not f.MyGroup Is Nothing Then
f.MyGroup.Name = String.Empty
f.MyGroup.ProcessDownloadUsers(e.IncludeInTheFeed)
End If
If Not f.MyGroup Is Nothing Then f.MyGroup.Dispose()
End Using
End Sub
Private Sub BTT_DOWNLOAD_FULL_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD_FULL.Click
DownloadUsers(, False)
Private Sub BTT_DOWNLOAD_Click(ByVal Sender As Object, ByVal e As MyKeyEventArgs) Handles BTT_DOWNLOAD.KeyClick
ProcessDownloadUsers(e.IncludeInTheFeed)
End Sub
#End Region
#Region "Get users"
Friend Overloads Function GetUsers() As IEnumerable(Of IUserData)
Return GetUsers(Me)
End Function
Friend Overloads Shared Function GetUsers(ByVal Instance As IGroup, Optional ByVal UseReadyOption As Boolean = True,
Optional ByVal IncludeNonExistentUsers As Boolean = False,
Optional ByVal OnlyNonExistentUsers As Boolean = False) As IEnumerable(Of IUserData)
Friend Overloads Shared Function GetUsers(ByVal Instance As IGroup) As IEnumerable(Of IUserData)
Try
If Settings.Users.Count > 0 Then
With Instance
Dim downDate As Date? = Nothing
If .DaysNumber > 0 Then
With Now.AddDays(- .DaysNumber) : downDate = New Date(.Year, .Month, .Day, 0, 0, 0) : End With
End If
Dim CheckUserExists As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If user.Exists Then
If IncludeNonExistentUsers And OnlyNonExistentUsers Then
Return False
Else
Return True
End If
ElseIf IncludeNonExistentUsers Then
Return True
If Not user.Exists Then
Return .UserDeleted
ElseIf user.Suspended Then
Return .UserSuspended
Else
Return False
Return .UserExists
End If
End Function
Dim CheckParams As Predicate(Of IUserData) = Function(user) _
(.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 CheckUserExists.Invoke(user)
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
Dim CheckUserCategory As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If user.Favorite Then
Return .Favorite
ElseIf user.Temporary Then
Return .Temporary
Else
Return user.IsSubscription = False
Return .Regular
End If
End Function
Dim CheckParams As Predicate(Of IUserData) = Function(user) _
CheckUserCategory.Invoke(user) And
(.ReadyForDownloadIgnore Or user.ReadyForDownload = .ReadyForDownload) And CheckUserExists.Invoke(user)
Dim CheckSubscription As Predicate(Of IUserData) = Function(user) (.DownloadSubscriptions And user.IsSubscription) Or
(.DownloadUsers And Not user.IsSubscription)
Dim CheckLabelsExcluded As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If .LabelsExcluded.Count = 0 Then
Return True
ElseIf user.Labels.Count = 0 Then
Return True
If Not .LabelsExcludedIgnore Then
If .LabelsExcluded.Count = 0 Then
Return True
ElseIf user.Labels.Count = 0 Then
Return True
Else
Return Not user.Labels.ListContains(.LabelsExcluded)
End If
Else
Return Not user.Labels.ListContains(.LabelsExcluded)
Return True
End If
End Function
Dim CheckLabels As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If .Labels.Count = 0 Then
If .LabelsNo Then
Return user.Labels.Count = 0
ElseIf .Labels.Count = 0 Then
Return CheckLabelsExcluded.Invoke(user)
ElseIf user.Labels.Count = 0 Then
Return False
@@ -189,19 +331,42 @@ Namespace DownloadObjects.Groups
Return user.Labels.ListContains(.Labels) And CheckLabelsExcluded.Invoke(user)
End If
End Function
Dim CheckDays As Predicate(Of IUserData) = Function(ByVal user As IUserData) As Boolean
If downDate.HasValue Then
Dim ld As Date? = DirectCast(user, UserDataBase).LastUpdated
If .DaysIsDownloaded Then
Return ld.HasValue AndAlso ld.Value >= downDate.Value
Else
Return Not ld.HasValue OrElse ld.Value < downDate.Value
End If
Else
Return True
End If
End Function
Dim CheckDateRange As Predicate(Of IUserData) =
Function(ByVal user As IUserData) As Boolean
If Not .DateMode = ShowingDates.Off Then
Dim ld As Date? = DirectCast(user, UserDataBase).LastUpdated
If ld.HasValue Then
Dim df As Date = If(.DateFrom, Date.MinValue.Date)
Dim dt As Date = If(.DateTo, Date.MaxValue.Date)
Return ld.Value.ValueBetween(df, dt) = (.DateMode = ShowingDates.In)
End If
End If
Return True
End Function
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))
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
CheckParams.Invoke(user) AndAlso CheckSubscription.Invoke(user) AndAlso
CheckDays.Invoke(user) AndAlso CheckDateRange.Invoke(user))
If .UsersCount <> 0 And users.ListExists Then
users = users.ListTake(If(.UsersCount > 0, -1, -2), Math.Abs(.UsersCount))
If .UsersCount < 0 Then users = users.ListReverse
Return users
End If
Return users
End With
Else
Return Nothing
@@ -212,16 +377,14 @@ Namespace DownloadObjects.Groups
End Function
#End Region
#Region "Download users"
Friend Sub DownloadUsers(Optional ByVal IncludeInTheFeed As Boolean = True, Optional ByVal UseReadyOption As Boolean = True,
Optional ByVal IncludeNonExistentUsers As Boolean = False,
Optional ByVal OnlyNonExistentUsers As Boolean = False)
Friend Sub ProcessDownloadUsers(Optional ByVal IncludeInTheFeed As Boolean = True, Optional ByVal ShowNoUsersMessage As Boolean = True)
Try
If Settings.Users.Count > 0 Then
Dim u As IEnumerable(Of IUserData) = GetUsers(Me, UseReadyOption, IncludeNonExistentUsers, OnlyNonExistentUsers)
Dim u As IEnumerable(Of IUserData) = GetUsers(Me)
If u.ListExists Then
Downloader.AddRange(u, IncludeInTheFeed)
Else
MsgBoxE({$"No users found for group [{Name}].", "No users found"}, vbExclamation)
ElseIf ShowNoUsersMessage Then
MsgBoxE({$"No users found{If(Not Name.IsEmptyString, $" in group '{Name}'", String.Empty)}!", "No users found"}, vbExclamation)
End If
End If
Catch ex As Exception
@@ -249,15 +412,37 @@ Namespace DownloadObjects.Groups
Return Export(New EContainer("Group"))
End Function
#End Region
#Region "IComparable Support"
Private Function CompareTo(ByVal Other As DownloadGroup) As Integer Implements IComparable(Of DownloadGroup).CompareTo
If IsViewFilter Then
Return IIf(Other.IsViewFilter, Name.CompareTo(Other.Name), 1)
ElseIf Other.IsViewFilter Then
Return -1
Else
Return Index.CompareTo(Other.Index)
End If
End Function
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then
BTT_DELETE.Dispose()
BTT_EDIT.Dispose()
BTT_MENU.Dispose()
SEP_1.Dispose()
BTT_DOWNLOAD.Dispose()
BTT_DOWNLOAD_FULL.Dispose()
If Not disposedValue Then
If disposing Then
BTT_EDIT.DisposeIfReady
BTT_DELETE.DisposeIfReady
BTT_DOWNLOAD.DisposeIfReady
BTT_CLONE_ADD.DisposeIfReady
BTT_CLONE_TEMP.DisposeIfReady
SEP_1.DisposeIfReady
SEP_2.DisposeIfReady
If Not BTT_MENU Is Nothing Then BTT_MENU.DropDownItems.Clear()
BTT_MENU.DisposeIfReady
End If
BTT_EDIT = Nothing
BTT_DELETE = Nothing
BTT_DOWNLOAD = Nothing
BTT_CLONE_ADD = Nothing
BTT_CLONE_TEMP = Nothing
BTT_MENU = Nothing
End If
MyBase.Dispose(disposing)
End Sub