Files
SCrawler/SCrawler/Download/Automation/AutoDownloader.vb
Andy e6d5fc2b95 2026.1.17.0
UserDataBase: move GLD functions from 'Twitter'
Instagram: add 'Reposts' and 'Likes' to the 'Sections' enum
OnlyFans: update the regex in 'DynamicRulesEnv'; handling error 502
PornHub: fix videos aren't downloading
ThreadsNet: add user name and description extraction
TikTok: fix downloading new videos; add downloading 'Stories' and 'Reposts'
Twitter: move GLD functions to 'UserDataBase'
Xhamster: fix a bug when adding new users; fix incorrect cache location
Download groups: add excluded groups
MainFrame: fix the 'Feed' tooltip
2026-01-17 20:06:37 +03:00

697 lines
34 KiB
VB.net

' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.Threading
Imports SCrawler.API.Base
Imports SCrawler.DownloadObjects.Groups
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Notifications
Namespace DownloadObjects
Friend Class AutoDownloader : Inherits GroupParameters : Implements IIndexable, IEContainerProvider, IComparable(Of AutoDownloader)
Friend Event PauseChanged(ByVal Value As PauseModes)
Friend Event PlanChanged As Scheduler.PlanChangedEventHandler
Friend Const NoPauseMode As Integer = -100
Friend Enum PauseModes As Integer
Disabled = -2
Enabled = -1
Unlimited = -1
Until = 0
H1 = 1
H2 = 2
H3 = 3
H4 = 4
H6 = 6
H12 = 12
End Enum
Friend Const DefaultTimer As Integer = 60
#Region "Notifications"
Private Const KeyOpenFolder As String = "_____OPEN_FOLDER_SCRAWLER_AUTOMATION"
Private Const KeyOpenSite As String = "_____OPEN_SITE_SCRAWLER_AUTOMATION"
Private Const KeyOpenFeed As String = "_____OPEN_FEED_SCRAWLER_AUTOMATION"
Private Const KeyBttDismiss As String = "_____DISMISS_SCRAWLER_AUTOMATION"
Private Const KeyBttPhoto As String = "_____PHOTO_SCRAWLER_AUTOMATION"
Private ReadOnly UserKeys As List(Of NotifiedUser)
Private Class NotifiedUser : Implements IDisposable
Private ReadOnly Property User As IUserData
Friend ReadOnly Property IUserDataKey As String
Private ReadOnly Property Key As String
Private ReadOnly Property KeyFolder As String
Private ReadOnly Property KeySite As String
Private ReadOnly Property KeyFeed As String
Private ReadOnly Property KeyDismiss As String
Private ReadOnly Property Images As Dictionary(Of String, SFile)
Private ReadOnly Property AutoDownloaderSource As AutoDownloader
Private Sub New()
Images = New Dictionary(Of String, SFile)
End Sub
Private Sub New(ByVal _Key As String)
Me.New
Key = _Key
KeyFolder = $"{Key}{KeyOpenFolder}"
KeySite = $"{Key}{KeyOpenSite}"
KeyFeed = $"{Key}{KeyOpenFeed}"
KeyDismiss = $"{Key}{KeyBttDismiss}"
End Sub
Friend Sub New(ByVal _Key As String, ByRef _User As IUserData, ByRef Source As AutoDownloader)
Me.New(_Key)
User = _User
IUserDataKey = _User.Key
AutoDownloaderSource = Source
If _User.IncludedInCollection Then
Dim cn$ = _User.CollectionName
Dim i% = Settings.Users.FindIndex(Function(u) u.IsCollection And u.Name = cn)
If i >= 0 Then IUserDataKey = Settings.Users(i).Key
End If
End Sub
Public Shared Widening Operator CType(ByVal Key As String) As NotifiedUser
Return New NotifiedUser(Key)
End Operator
Friend Sub ShowNotification()
Try
If Not AutoDownloaderSource Is Nothing And Settings.ProcessNotification(SettingsCLS.NotificationObjects.AutoDownloader) Then
If AutoDownloaderSource.ShowNotifications Then
If Not User Is Nothing Then
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
Title = User.CollectionName
Else
Title = User.ToString
End If
Using Notify As New Notification(Text, Title) With {.Key = Key}
Dim uPic As SFile = Nothing
Dim uif As SFile = Nothing
Dim uif_orig As SFile = Nothing
Dim uif_compressed As SFile = Nothing
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 And Not User.IsSubscription Then
uif = DirectCast(User, UserDataBase).GetLastImageAddress
uif_orig = uif
If uif.Exists Then
uif_compressed = uif
uif_compressed.Path = Settings.Cache.RootDirectory.Path
uif_compressed.Name = $"360_{uif.Name}"
Using imgR As New ImageRenderer(uif, EDP.SendToLog)
Try : imgR.FitToWidth(360).Save(uif_compressed) : Catch : End Try
End Using
If uif_compressed.Exists Then uif = uif_compressed
If uif.Exists Then
Notify.Images = {New ToastImage(uif, IImage.Modes.Inline)}
uifKey = $"{Key}_{Images.Keys.Count + 1}_{KeyBttPhoto}"
If Not Images.ContainsKey(uifKey) Then Images.Add(uifKey, uif_orig)
End If
End If
End If
Notify.Buttons = {
New ToastButton(KeyFolder, "Folder"),
New ToastButton(KeySite, "Site"),
New ToastButton(KeyFeed, "Feed")
}
If Not uifKey.IsEmptyString Then Notify.Buttons = {New ToastButton(uifKey, "Photo")}
Notify.Buttons = {New ToastButton(KeyDismiss, "Dismiss")}
Notify.Show()
End Using
End If
End If
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[AutoDownloader.NotifiedUser.ShowNotification]")
If Not User Is Nothing Then
MainFrameObj.ShowNotification(SettingsCLS.NotificationObjects.AutoDownloader,
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
End Try
End Sub
''' <returns>True to activate</returns>
Friend Function Open(ByVal _Key As String) As Boolean
If Not User Is Nothing Then
If KeyDismiss = _Key Then
ElseIf Key = _Key Then
Return True
ElseIf KeyFolder = _Key Then
If User.IsSubscription Then
Return True
Else
User.OpenFolder()
End If
ElseIf KeySite = _Key Then
User.OpenSite()
ElseIf KeyFeed = _Key Then
With MainFrameObj : ControlInvokeFast(.MF, AddressOf .MF.ShowFeed, EDP.LogMessageValue) : End With
ElseIf Images.ContainsKey(_Key) Then
Images(_Key).Open()
End If
Else
Return True
End If
Return False
End Function
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
With CType(Obj, NotifiedUser)
Return .Key = Key Or .Key = KeyFolder Or .Key = KeySite Or .Key = KeyFeed Or .Key = KeyDismiss Or Images.ContainsKey(.Key)
End With
End Function
#Region "IDisposable Support"
Private disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then
If disposing Then Images.Clear()
disposedValue = True
End If
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
#End Region
#Region "XML Names"
'TODELETE: AutoDownloader.Modes
<Obsolete> Private Const Name_Mode As String = "Mode"
Private Const Name_Enabled As String = "Enabled"
Private Const Name_IsManual As String = "IsManual"
Private Const Name_Timer As String = "Timer"
Private Const Name_StartupDelay As String = "StartupDelay"
Private Const Name_LastDownloadDate As String = "LastDownloadDate"
Private Const Name_ShowNotifications As String = "Notify"
Private Const Name_ShowPictureDown As String = "ShowDownloadedPicture"
Private Const Name_ShowPictureUser As String = "ShowUserPicture"
Private Const Name_ShowSimpleNotification As String = "ShowSimpleNotification"
#End Region
#Region "Declarations"
Private _LVIState As Integer = 0
Friend Function LVIStateChanged() As Boolean
Dim ____LVIState%
Dim result As Boolean
If Downloading Then
____LVIState = 1
ElseIf DownloadReady(True, True) Or ForceStartRequested Then
____LVIState = 2
ElseIf Not Working And Not IsManual Then
____LVIState = 3
ElseIf IsPaused Then
____LVIState = 4
ElseIf Settings.AutomationBrushUndownloadedPlansMinutes.Value > 0 AndAlso
LastDownloadDate.AddMinutes(Settings.AutomationBrushUndownloadedPlansMinutes.Value) < Now Then
____LVIState = 5
Else
____LVIState = 0
End If
result = Not _LVIState = ____LVIState
_LVIState = ____LVIState
Return result
End Function
Friend ReadOnly Property LVI As ListViewItem
Get
Dim l As New ListViewItem(ToString)
If Downloading Then
l.BackColor = MyColor.OkBack
l.ForeColor = MyColor.OkFore
ElseIf DownloadReady(True, True) Or ForceStartRequested Then
l.BackColor = MyColor.EditBack
l.ForeColor = MyColor.EditFore
ElseIf Not Working And Not IsManual Then
l.BackColor = MyColor.DeleteBack
l.ForeColor = MyColor.DeleteFore
ElseIf Working And IsPaused And Not IsManual Then
l.BackColor = MyColor.UpdateBack
l.ForeColor = MyColor.UpdateFore
ElseIf Settings.AutomationBrushUndownloadedPlansMinutes.Value > 0 AndAlso
LastDownloadDate.AddMinutes(Settings.AutomationBrushUndownloadedPlansMinutes.Value) < Now Then
l.BackColor = Color.FromArgb(224, 224, 224)
l.ForeColor = Color.FromArgb(64, 64, 64)
End If
LVIStateChanged()
Return l
End Get
End Property
Friend Property Source As Scheduler
Private _Enabled As Boolean = False
Friend Property Enabled As Boolean
Get
Return _Enabled
End Get
Set(ByVal e As Boolean)
_Enabled = e
If Not _Enabled Then [Stop]()
End Set
End Property
Friend Property IsManual As Boolean = False
Friend Property Timer As Integer = DefaultTimer
Friend Property StartupDelay As Integer = 1
Friend Property ShowNotifications As Boolean = True
Friend Property ShowPictureDownloaded As Boolean = True
Friend Property ShowPictureUser As Boolean = True
Friend Property ShowSimpleNotification As Boolean = False
Friend Property Index As Integer = -1 Implements IIndexable.Index
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
DirectCast(Obj, AutoDownloader).Index = Index
Return Obj
End Function
#Region "Date"
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
End Get
Set(ByVal d As Date)
_LastDownloadDate = d
If Not Initialization Then _LastDownloadDateChanged = True
End Set
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, lds}.Max
Else
Return {LastDownloadDate.AddMinutes(Timer), _StartTime.AddMinutes(StartupDelay), lds}.Max
End If
End Get
End Property
Private ReadOnly DateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
Private Function GetLastDateString() As String
If LastDownloadDateXML.HasValue Or _LastDownloadDateChanged Then
Return LastDownloadDate.ToStringDate(DateProvider)
Else
Return "never"
End If
End Function
Private Function GetNextDateString() As String
Return NextExecutionDate.ToStringDate(DateProvider)
End Function
#End Region
#Region "Information"
Friend ReadOnly Property Information As String
Get
Return $"Last download date: {GetLastDateString()} ({GetWorkingState()})"
End Get
End Property
Private Function GetWorkingState() As String
Dim OutStr$
If Working And Not IsManual Then
If _Downloading Then
OutStr = "downloading"
ElseIf _ForceStartRequested Then
OutStr = "force start pending"
ElseIf _StopRequested Then
OutStr = "stopping"
ElseIf StartupDelay > 0 And _StartTime.AddMinutes(StartupDelay) > Now Then
OutStr = $"delayed ({StartupDelay}) until {_StartTime.AddMinutes(StartupDelay).ToStringDate(ADateTime.Formats.BaseDateTime)}"
Else
OutStr = "working"
End If
If IsPaused Then
Select Case Pause
Case PauseModes.Unlimited : OutStr &= ", paused"
Case PauseModes.Until : OutStr &= $", paused (until {AConvert(Of String)(_PauseValue, ADateTime.Formats.BaseDateTime, "?")})"
Case Else : OutStr &= $", paused ([{Pause}] until {AConvert(Of String)(_PauseValue, ADateTime.Formats.BaseDateTime, "?")})"
End Select
End If
ElseIf IsManual Then
If _Downloading Then
OutStr = "downloading"
ElseIf _ForceStartRequested Then
OutStr = "force start pending"
Else
OutStr = String.Empty
End If
Else
OutStr = "stopped"
End If
Return OutStr
End Function
Private Function GetWorkingState_Manual() As String
Dim OutStr$ = GetWorkingState()
If Not OutStr.IsEmptyString Then Return $" ({OutStr})" Else Return String.Empty
End Function
Public Overrides Function ToString() As String
If IsManual Then
Return $"{Name} (manual{GetWorkingState_Manual()}): last download date: {GetLastDateString()}"
Else
Return $"{Name} ({GetWorkingState()}): last download date: {GetLastDateString()}; next run: {GetNextDateString()}"
End If
End Function
Friend Overrides Function ToStringViewFilters() As String
Return $"Scheduler plan '{Name}'{IIf(IsManual, " (manual)", String.Empty)}"
End Function
#End Region
#End Region
#Region "Initializer"
Private ReadOnly Initialization As Boolean = True
Private _IsNewPlan As Boolean = False
Friend ReadOnly Property IsNewPlan As Boolean
Get
Return _IsNewPlan
End Get
End Property
Friend Sub New(Optional ByVal IsNewPlan As Boolean = False)
UserKeys = New List(Of NotifiedUser)
_IsNewPlan = IsNewPlan
Initialization = False
End Sub
Friend Sub New(ByVal x As EContainer)
Me.New
Initialization = True
Import(x)
#Disable Warning BC40008
If x.Contains(Name_Mode) Then
Dim g% = x.Value(Name_Mode).FromXML(Of Integer)(0)
If g = 4 Then GroupsOnly = True
Enabled = g
Else
Enabled = x.Value(Name_Enabled).FromXML(Of Boolean)(False)
End If
#Enable Warning
If Name.IsEmptyString Then Name = "Default"
IsManual = x.Value(Name_IsManual).FromXML(Of Boolean)(False)
Timer = x.Value(Name_Timer).FromXML(Of Integer)(DefaultTimer)
If Timer <= 0 Then Timer = DefaultTimer
StartupDelay = x.Value(Name_StartupDelay).FromXML(Of Integer)(0)
If StartupDelay < 0 Then StartupDelay = 0
ShowNotifications = x.Value(Name_ShowNotifications).FromXML(Of Boolean)(True)
ShowPictureDownloaded = x.Value(Name_ShowPictureDown).FromXML(Of Boolean)(True)
ShowPictureUser = x.Value(Name_ShowPictureUser).FromXML(Of Boolean)(True)
ShowSimpleNotification = x.Value(Name_ShowSimpleNotification).FromXML(Of Boolean)(False)
LastDownloadDateXML = AConvert(Of Date)(x.Value(Name_LastDownloadDate), DateProvider, Nothing)
If LastDownloadDateXML.HasValue Then
LastDownloadDate = LastDownloadDateXML.Value
Else
LastDownloadDate = Now.AddYears(-1)
End If
Initialization = False
End Sub
#End Region
#Region "ICopier Support"
Friend Overrides Function Copy() As Object
Dim newObj As New AutoDownloader(True)
newObj.Copy(Me)
With newObj
.Name = String.Empty
.Enabled = Enabled
.IsManual = IsManual
.Timer = Timer
.StartupDelay = StartupDelay
.ShowNotifications = ShowNotifications
.ShowPictureDownloaded = ShowPictureDownloaded
.ShowPictureUser = ShowPictureUser
.ShowSimpleNotification = ShowSimpleNotification
End With
Return newObj
End Function
#End Region
#Region "Groups Support"
Friend Sub GROUPS_Updated(ByVal Sender As DownloadGroup)
If Groups.Count > 0 Then
Dim i% = Groups.IndexOf(Sender.NameBefore)
If i >= 0 Then Groups(i) = Sender.Name : Update()
End If
End Sub
Friend Sub GROUPS_Deleted(ByVal Sender As DownloadGroup)
If Groups.Count > 0 Then
Dim i% = Groups.IndexOf(Sender.Name)
If i >= 0 Then Groups.RemoveAt(i) : Update()
End If
End Sub
#End Region
#Region "Update"
Friend Sub Update()
If Not Source Is Nothing Then Source.Update()
End Sub
Private Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
Return Export(New EContainer(Scheduler.Name_Plan, String.Empty) From {
New EContainer(Name_Enabled, Enabled.BoolToInteger),
New EContainer(Name_IsManual, IsManual.BoolToInteger),
New EContainer(Name_Timer, Timer),
New EContainer(Name_StartupDelay, StartupDelay),
New EContainer(Name_ShowNotifications, ShowNotifications.BoolToInteger),
New EContainer(Name_ShowPictureDown, ShowPictureDownloaded.BoolToInteger),
New EContainer(Name_ShowPictureUser, ShowPictureUser.BoolToInteger),
New EContainer(Name_ShowSimpleNotification, ShowSimpleNotification.BoolToInteger),
New EContainer(Name_LastDownloadDate, CStr(AConvert(Of String)(If(LastDownloadDateXML.HasValue Or _LastDownloadDateChanged,
CObj(LastDownloadDate), Nothing), DateProvider, String.Empty)))
})
End Function
#End Region
#Region "Execution"
Private _Working As Boolean = False
Friend ReadOnly Property Working As Boolean
Get
Return _Working
End Get
End Property
Private _StartTime As Date = Now
Friend Sub Start(ByVal Init As Boolean, Optional ByVal Force As Boolean = False)
If Not IsManual Or Force Then
If Init Then _StartTime = Now
_IsNewPlan = False
If Not Working And Enabled Then _Working = True
RaiseEvent PlanChanged(Me)
End If
End Sub
Private _StopRequested As Boolean = False
Private _Pause As PauseModes = PauseModes.Disabled
Private _PauseValue As Date? = Nothing
Friend Property Pause(Optional ByVal DateLimit As Date? = Nothing) As PauseModes
Get
Return _Pause
End Get
Set(ByVal p As PauseModes)
_Pause = p
Select Case p
Case PauseModes.Disabled, PauseModes.Unlimited : _PauseValue = Nothing
Case PauseModes.H1 : _PauseValue = Now.AddHours(1)
Case PauseModes.H2 : _PauseValue = Now.AddHours(2)
Case PauseModes.H3 : _PauseValue = Now.AddHours(3)
Case PauseModes.H4 : _PauseValue = Now.AddHours(4)
Case PauseModes.H6 : _PauseValue = Now.AddHours(6)
Case PauseModes.H12 : _PauseValue = Now.AddHours(12)
Case PauseModes.Until : _PauseValue = DateLimit
Case Else : _PauseValue = Nothing
End Select
RaiseEvent PauseChanged(p)
RaiseEvent PlanChanged(Me)
End Set
End Property
Private ReadOnly Property IsPaused As Boolean
Get
If Not _Pause = PauseModes.Disabled Then
If _PauseValue.HasValue Then
If _PauseValue.Value > Now Then
Return True
Else
_Pause = PauseModes.Disabled
_PauseValue = Nothing
RaiseEvent PauseChanged(_Pause)
Return False
End If
Else
Return True
End If
Else
Return False
End If
End Get
End Property
Friend Sub [Stop]()
If Working Then
If Downloading Then _StopRequested = True Else _Working = False
RaiseEvent PlanChanged(Me)
End If
End Sub
Friend Overloads Sub Skip()
If LastDownloadDate.AddMinutes(Timer) <= Now Then
_LastDownloadDateSkip = Now.AddMinutes(Timer)
Else
_LastDownloadDateSkip = LastDownloadDate.AddMinutes(Timer)
End If
RaiseEvent PlanChanged(Me)
End Sub
Friend Overloads Sub Skip(ByVal Minutes As Integer)
_LastDownloadDateSkip = If(_LastDownloadDateSkip, Now).AddMinutes(Minutes)
RaiseEvent PlanChanged(Me)
End Sub
Friend Overloads Sub Skip(ByVal ToDate As Date)
_LastDownloadDateSkip = ToDate
RaiseEvent PlanChanged(Me)
End Sub
Friend Sub SkipReset()
_LastDownloadDateSkip = Nothing
RaiseEvent PlanChanged(Me)
End Sub
Friend Sub ForceStart()
_ForceStartRequested = True
If IsManual Then Start(False, True)
RaiseEvent PlanChanged(Me)
End Sub
Private _ForceStartRequested As Boolean = False
Friend ReadOnly Property ForceStartRequested As Boolean
Get
Return _ForceStartRequested
End Get
End Property
Friend ReadOnly Property DownloadReady(Optional ByVal IgnorePause As Boolean = False, Optional ByVal IgnoreDownloaderWorking As Boolean = False) As Boolean
Get
If _StopRequested Then _Working = False
Return (Working Or IsManual) And ((IsManual And _ForceStartRequested) Or (Not IsManual And NextExecutionDate < Now And (Not IsPaused Or IgnorePause)) Or _ForceStartRequested) And
Not _StopRequested And Enabled And (Not Downloader.Working Or IgnoreDownloaderWorking)
End Get
End Property
Friend ReadOnly Property NextDate As Date?
Get
If Not _StopRequested And Enabled Then
If IsManual Or _ForceStartRequested Then
Return Now.AddYears(-10)
ElseIf Not IsPaused And Not IsManual And Working Then
Return NextExecutionDate
End If
End If
Return Nothing
End Get
End Property
Private _Downloading As Boolean = False
Friend ReadOnly Property Downloading As Boolean
Get
Return _Downloading
End Get
End Property
Friend Sub Download()
_Downloading = True
RaiseEvent PlanChanged(Me)
Dim Keys As New List(Of String)
Try
Dim users As New List(Of IUserData)
Dim doRound% = -1, doLim% = Settings.Plugins.Count
Dim DownloadedUsersCount% = 0
Dim DownloadedSubscriptionsCount% = 0
Dim simple As Boolean = ShowSimpleNotification And ShowNotifications
Dim notify As Action = Sub()
Try
With Downloader.Downloaded
If ShowNotifications And .Count > 0 Then
For indx% = 0 To .Count - 1
With .Item(indx)
If Keys.Contains(.Key) Then
If simple Then
If .IsSubscription Then
DownloadedSubscriptionsCount += 1
Else
DownloadedUsersCount += 1
End If
Else
ShowNotification(.Self)
End If
Keys.Remove(.Key)
End If
End With
Next
End If
End With
Catch n_ex As Exception
End Try
End Sub
If Enabled Then users.ListAddList(DownloadGroup.GetUsers(Me))
If users.Count > 0 Then
Keys.ListAddList(users.Select(Function(u) u.Key))
With Downloader
.AutoDownloaderWorking = True
If .Downloaded.Count > 0 Then .Downloaded.RemoveAll(Function(u) Keys.Contains(u.Key)) : .InvokeDownloadsChangeEvent()
Do
Try
doRound += 1
.AddRange(users, True)
Exit Do
Catch iex As Exception
If doRound = doLim Then
Throw iex
Else
Thread.Sleep(200)
End If
End Try
Loop While doRound <= doLim
While .Working Or .Count > 0 : notify.Invoke() : Thread.Sleep(200) : End While
.AutoDownloaderWorking = False
notify.Invoke
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
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[AutoDownloader.Download({Name})]")
Finally
Keys.Clear()
LastDownloadDate = Now
Update()
_Downloading = False
_ForceStartRequested = False
_LastDownloadDateSkip = Nothing
If _StopRequested Then _Working = False
RaiseEvent PlanChanged(Me)
End Try
End Sub
Private Sub ShowNotification(ByVal u As IUserData)
Dim k$ = $"{Name}_{u.Key}"
Dim i% = UserKeys.IndexOf(k)
If i >= 0 Then
UserKeys(i).ShowNotification()
Else
UserKeys.Add(New NotifiedUser(k, Settings.GetUser(u), Me))
UserKeys.Last.ShowNotification()
End If
End Sub
Friend Function NotificationClicked(ByVal Key As String, ByRef Found As Boolean, ByRef ActivateForm As Boolean) As Boolean
Dim i% = UserKeys.IndexOf(Key)
If i >= 0 Then
Found = True
ActivateForm = UserKeys(i).Open(Key)
MainFrameObj.FocusUser(UserKeys(i).IUserDataKey, ActivateForm)
Return True
Else
Return False
End If
End Function
#End Region
#Region "IComparable Support"
Private Function CompareTo(ByVal Other As AutoDownloader) As Integer Implements IComparable(Of AutoDownloader).CompareTo
Return Index.CompareTo(Other.Index)
End Function
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then
[Stop]()
UserKeys.ListClearDispose()
End If
MyBase.Dispose(disposing)
End Sub
#End Region
End Class
End Namespace