2023.8.27.0

API.JFF: remove PXML attribute for some properties
API.Reddit.Channels: save channel info right after download; replace date providers with default
API.Reddit.SiteSettings: improve 'UpdateToken' function
AutoDownloader: add 'Copy' function
SchedulerEditorForm: add cloning plans
DownloadedInfoForm: add 'Try...Catch' for some functions
DownloadFeedForm: add button to go to custom page
FeedMedia: color typo
GroupParameters: add 'ICopier'
This commit is contained in:
Andy
2023-08-27 19:39:50 +03:00
parent f0014d2874
commit 2a60ace18f
23 changed files with 245 additions and 142 deletions

View File

@@ -1,3 +1,22 @@
# 2023.8.27.0
*2023-08-27*
- Added
- **JustForFans**
- Advanced download (`Download` - `Download (advanced)`)
- Advanced filter (`View` - `Advanced filter`)
- Auto downloader: cloning plans
- Feed: add button to go to custom page
- Special log for non-existent users
- Twitter: group 'limit' notifications
- Ability to set custom color for subscription users
- Other improvements
- Fixed
- Auto downloader: new plan date display bug
- Auto downloader: downloading stuck
- Minor bugs
# 2023.8.6.0 # 2023.8.6.0
*2023-08-06* *2023-08-06*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -11,7 +11,7 @@
:eu: :eu:
:greece: :greece:
A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, OnlyFans, Reddit, Twitter, Mastodon, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest). A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, OnlyFans, Reddit, Twitter, Mastodon, Instagram, TikTok, RedGifs, JustForFans, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest).
**If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)** **If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)**
<!---Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush: <!---Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
@@ -34,6 +34,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- Redgifs videos (https://www.redgifs.com/); - Redgifs videos (https://www.redgifs.com/);
- Twitter images and videos, saved (bookmarked) posts; - Twitter images and videos, saved (bookmarked) posts;
- OnlyFans images and videos, saved (bookmarked) posts; - OnlyFans images and videos, saved (bookmarked) posts;
- JustForFans images and videos, saved (bookmarked) posts;
- Mastodon images and videos, saved (bookmarked) posts; - Mastodon images and videos, saved (bookmarked) posts;
- Instagram images and videos, tagged posts, stories, saved posts; - Instagram images and videos, tagged posts, stories, saved posts;
- TikTok videos; - TikTok videos;
@@ -72,6 +73,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- **OnlyFans** - **OnlyFans**
- **Mastodon** - **Mastodon**
- **Instagram** - **Instagram**
- JustForFans
- TikTok - TikTok
- RedGifs - RedGifs
- Pinterest - Pinterest
@@ -90,14 +92,6 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
First, the program downloads the full profile. After the program downloads only new posts. The program remembers downloaded posts. First, the program downloads the full profile. After the program downloads only new posts. The program remembers downloaded posts.
## Reddit
The program parses user posts, obtain MD5 images hash and compares them with existing ones to remove duplicates. Then the media will be downloaded.
## Other sites
The program parses user posts and compares file names with existing ones to remove duplicates. Then the media will be downloaded.
## How to request a new site ## How to request a new site
<!---Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about---> <!---Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about--->
@@ -128,16 +122,17 @@ The program parses user posts and compares file names with existing ones to remo
- [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit) - [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit)
- [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter) - [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter)
- [OnlyFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans) - [OnlyFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#onlyfans)
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Mastodon) - [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#mastodon)
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram) - [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
- [JustForFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#justforfans)
- [TikTok](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok) - [TikTok](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok)
- [RedGifs](https://github.com/AAndyProgram/SCrawler/wiki/Settings#redgifs) - [RedGifs](https://github.com/AAndyProgram/SCrawler/wiki/Settings#redgifs)
- [YouTube](https://github.com/AAndyProgram/SCrawler/wiki/Settings#YouTube) - [YouTube](https://github.com/AAndyProgram/SCrawler/wiki/Settings#youtube)
- [Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Pinterest) - [Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Pinterest)
- [PornHub](https://github.com/AAndyProgram/SCrawler/wiki/Settings#pornhub) - [PornHub](https://github.com/AAndyProgram/SCrawler/wiki/Settings#pornhub)
- [XHamster](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xhamster) - [XHamster](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xhamster)
- [XVIDEOS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xvideos) - [XVIDEOS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xvideos)
- [ThisVid](https://github.com/AAndyProgram/SCrawler/wiki/Settings#ThisVid) - [ThisVid](https://github.com/AAndyProgram/SCrawler/wiki/Settings#thisvid)
- [LPSG](https://github.com/AAndyProgram/SCrawler/wiki/Settings#lpsg) - [LPSG](https://github.com/AAndyProgram/SCrawler/wiki/Settings#lpsg)
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)** **Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.8.17.0")> <Assembly: AssemblyVersion("2023.8.27.0")>
<Assembly: AssemblyFileVersion("2023.8.17.0")> <Assembly: AssemblyFileVersion("2023.8.27.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.8.17.0")> <Assembly: AssemblyVersion("2023.8.27.0")>
<Assembly: AssemblyFileVersion("2023.8.17.0")> <Assembly: AssemblyFileVersion("2023.8.27.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>

View File

@@ -1448,7 +1448,7 @@ BlockNullPicture:
For i = 0 To _ContentList.Count - 1 For i = 0 To _ContentList.Count - 1
data = _ContentList(i) data = _ContentList(i)
ProgressPre.Perform() ProgressPre.Perform()
If (data.Type = UTypes.GIF Or data.Type = UTypes.Picture) Then If data.Type = UTypes.GIF Or data.Type = UTypes.Picture Then
If data.MD5.IsEmptyString Then If data.MD5.IsEmptyString Then
ThrowAny(Token) ThrowAny(Token)
eIndx = existingFiles.FindIndex(eFinder) eIndx = existingFiles.FindIndex(eFinder)

View File

@@ -30,10 +30,9 @@ Namespace API.JustForFans
Friend ReadOnly Property UserID As PropertyValue Friend ReadOnly Property UserID As PropertyValue
<PropertyOption, PXML> <PropertyOption, PXML>
Friend ReadOnly Property UserHash4 As PropertyValue Friend ReadOnly Property UserHash4 As PropertyValue
<PropertyOption(ControlText:="Accept", ControlToolTip:="Header 'Accept'"), PXML> <PropertyOption(ControlText:="Accept", ControlToolTip:="Header 'Accept'")>
Friend ReadOnly Property HeaderAccept As PropertyValue Friend ReadOnly Property HeaderAccept As PropertyValue
<PropertyOption, PXML> <PropertyOption> Friend ReadOnly Property UserAgent As PropertyValue
Friend ReadOnly Property UserAgent As PropertyValue
Private Sub UpdateHeader(ByVal HeaderName As String, ByVal HeaderValue As String) Private Sub UpdateHeader(ByVal HeaderName As String, ByVal HeaderValue As String)
Select Case HeaderName Select Case HeaderName
Case NameOf(HeaderAccept) : If HeaderValue.IsEmptyString Then Responser.Accept = Nothing Else Responser.Accept = HeaderValue Case NameOf(HeaderAccept) : If HeaderValue.IsEmptyString Then Responser.Accept = Nothing Else Responser.Accept = HeaderValue

View File

@@ -270,13 +270,14 @@ Namespace API.Reddit
End With End With
Dim b% = Posts.Count Dim b% = Posts.Count
Posts.ListAddList(d.GetNewChannelPosts(), LNC) Posts.ListAddList(d.GetNewChannelPosts(), LNC)
If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b) If Posts.Count - b > 0 Then _Saved = False : CountOfLoadedPostsPerSession.Add(Posts.Count - b)
Posts.Sort() Posts.Sort()
LatestParsedDate = If(Posts.FirstOrDefault(Function(pp) pp.Date.HasValue).Date, LatestParsedDate) LatestParsedDate = If(Posts.FirstOrDefault(Function(pp) pp.Date.HasValue).Date, LatestParsedDate)
UpdateUsersStats() UpdateUsersStats()
End Using End Using
Catch oex As OperationCanceledException When Token.IsCancellationRequested Catch oex As OperationCanceledException When Token.IsCancellationRequested
Finally Finally
SaveUnsaved()
_Downloading = False _Downloading = False
End Try End Try
End Sub End Sub
@@ -344,14 +345,13 @@ Namespace API.Reddit
Using x As New XmlFile(f, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True} Using x As New XmlFile(f, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True}
x.LoadData() x.LoadData()
If x.Count > 0 Then If x.Count > 0 Then
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
Dim lc As New ListAddParams(LAP.ClearBeforeAdd) Dim lc As New ListAddParams(LAP.ClearBeforeAdd)
Name = x.Value(Name_Name) Name = x.Value(Name_Name)
ID = x.Value(Name_ID) ID = x.Value(Name_ID)
ViewMode = x.Value(Name_ViewMode).FromXML(Of Integer)(CInt(View.[New])) ViewMode = x.Value(Name_ViewMode).FromXML(Of Integer)(CInt(View.[New]))
ViewPeriod = x.Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(Period.All)) ViewPeriod = x.Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(Period.All))
If FilePosts.Exists Then PostsNames.ListAddList(FilePosts.GetText.StringToList(Of String)("|"), LNC) If FilePosts.Exists Then PostsNames.ListAddList(FilePosts.GetText.StringToList(Of String)("|"), LNC)
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing) LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), DateTimeDefaultProvider, Nothing)
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc) CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc)
CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), lc) CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), lc)
ChannelExistentUserNames.ListAddList(x.Value(Name_UsersExistent).StringToList(Of String)("|"), LNC) ChannelExistentUserNames.ListAddList(x.Value(Name_UsersExistent).StringToList(Of String)("|"), LNC)
@@ -359,7 +359,7 @@ Namespace API.Reddit
With x(Name_PostsNode).XmlIfNothing With x(Name_PostsNode).XmlIfNothing
If .Count > 0 Then .ForEach(Sub(ee) PostsLatest.Add(New UserPost With { If .Count > 0 Then .ForEach(Sub(ee) PostsLatest.Add(New UserPost With {
.ID = ee.Attribute(Name_ID), .ID = ee.Attribute(Name_ID),
.[Date] = AConvert(Of Date)(ee.Attribute(Name_Date).Value, XMLDateProvider, Nothing)})) .[Date] = AConvert(Of Date)(ee.Attribute(Name_Date).Value, DateTimeDefaultProvider, Nothing)}))
End With End With
End If End If
End If End If
@@ -367,45 +367,53 @@ Namespace API.Reddit
End If End If
Return True Return True
End Function End Function
Private _Saved As Boolean = True
Friend Function SaveUnsaved() As Boolean
Return _Saved OrElse Save()
End Function
Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime) Try
UpdateUsersStats() UpdateUsersStats()
If Not ViewMode = View.New Then If Not ViewMode = View.New Then
Dim l As New List(Of String) Dim l As New List(Of String)
If Posts.Count > 0 Or PostsLatest.Count > 0 Then l.ListAddList((From p In PostsAll Where Not p.ID.IsEmptyString Select p.ID), LNC) If Posts.Count > 0 Or PostsLatest.Count > 0 Then l.ListAddList((From p In PostsAll Where Not p.ID.IsEmptyString Select p.ID), LNC)
l.ListAddList(PostsNames, LNC) l.ListAddList(PostsNames, LNC)
If l.Count > 0 Then TextSaver.SaveTextToFile(l.ListToString("|"), FilePosts, True,, EDP.SendToLog) If l.Count > 0 Then TextSaver.SaveTextToFile(l.ListToString("|"), FilePosts, True,, EDP.SendToLog)
End If
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"}
x.Add(Name_Name, Name)
x.Add(Name_ID, ID)
x.Add(Name_ViewMode, CInt(ViewMode))
x.Add(Name_ViewPeriod, CInt(ViewPeriod))
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString("|"))
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString("|"))
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString("|"))
If Posts.Count > 0 Or PostsLatest.Count > 0 Then
Dim tmpPostList As List(Of UserPost) = Nothing
tmpPostList.ListAddList(Posts).ListAddList(PostsLatest)
tmpPostList.Sort()
LatestParsedDate = tmpPostList.FirstOrDefault(Function(pd) pd.Date.HasValue).Date
x.Add(Name_Date, AConvert(Of String)(LatestParsedDate, XMLDateProvider, String.Empty))
x.Add(Name_PostsNode, String.Empty)
With x(Name_PostsNode)
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
String.Empty,
{
New EAttribute(Name_ID, p.ID),
New EAttribute(Name_Date, AConvert(Of String)(p.Date, XMLDateProvider, String.Empty))
})
)
)
End With
tmpPostList.Clear()
End If End If
x.Save(File) Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"}
End Using x.Add(Name_Name, Name)
Return True x.Add(Name_ID, ID)
x.Add(Name_ViewMode, CInt(ViewMode))
x.Add(Name_ViewPeriod, CInt(ViewPeriod))
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString("|"))
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString("|"))
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString("|"))
If Posts.Count > 0 Or PostsLatest.Count > 0 Then
Dim tmpPostList As List(Of UserPost) = Nothing
tmpPostList.ListAddList(Posts).ListAddList(PostsLatest)
tmpPostList.Sort()
LatestParsedDate = tmpPostList.FirstOrDefault(Function(pd) pd.Date.HasValue).Date
x.Add(Name_Date, AConvert(Of String)(LatestParsedDate, DateTimeDefaultProvider, String.Empty))
x.Add(Name_PostsNode, String.Empty)
With x(Name_PostsNode)
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
String.Empty,
{
New EAttribute(Name_ID, p.ID),
New EAttribute(Name_Date, AConvert(Of String)(p.Date, DateTimeDefaultProvider, String.Empty))
})
)
)
End With
tmpPostList.Clear()
End If
_Saved = x.Save(File)
End Using
Return True
Catch ex As Exception
If Not e.Exists Then e = EDP.ReturnValue
Return ErrorsDescriber.Execute(e, ex, "API.Reddit.Channel.Save", _Saved)
End Try
End Function End Function
#End Region #End Region
#Region "IDisposable Support" #Region "IDisposable Support"

View File

@@ -90,7 +90,7 @@ Namespace API.Reddit
End If End If
End Sub End Sub
Friend Sub Update() Friend Sub Update()
If Count > 0 Then Channels.ForEach(Sub(c) c.Save()) If Count > 0 Then Channels.ForEach(Sub(c) c.SaveUnsaved())
End Sub End Sub
Friend ReadOnly Property Count As Integer Implements ICollection(Of Channel).Count, IMyEnumerator(Of Channel).MyEnumeratorCount Friend ReadOnly Property Count As Integer Implements ICollection(Of Channel).Count, IMyEnumerator(Of Channel).MyEnumeratorCount
Get Get

View File

@@ -218,39 +218,57 @@ Namespace API.Reddit
Return True Return True
End Function End Function
Private Overloads Function UpdateToken() As Boolean Private Overloads Function UpdateToken() As Boolean
Return UpdateToken(AuthUserName.Value, AuthPassword.Value, ApiClientID.Value, ApiClientSecret.Value) Return UpdateToken(AuthUserName.Value, AuthPassword.Value, ApiClientID.Value, ApiClientSecret.Value, EDP.SendToLog + EDP.ReturnValue)
End Function End Function
<PropertyUpdater(NameOf(BearerToken), {NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret)})> <PropertyUpdater(NameOf(BearerToken), {NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret)})>
Private Overloads Function UpdateToken(ByVal UserName As String, ByVal Password As String, ByVal ClientID As String, ByVal ClientSecret As String) As Boolean Private Overloads Function UpdateToken(ByVal UserName As String, ByVal Password As String, ByVal ClientID As String, ByVal ClientSecret As String) As Boolean
Return UpdateToken(UserName, Password, ClientID, ClientSecret, EDP.LogMessageValue)
End Function
Private Overloads Function UpdateToken(ByVal UserName As String, ByVal Password As String, ByVal ClientID As String, ByVal ClientSecret As String, ByVal e As ErrorsDescriber) As Boolean
Try Try
Dim result As Boolean = True Dim result As Boolean = True
If {UserName, Password, ClientID, ClientSecret}.All(Function(v) Not v.IsEmptyString) Then If {UserName, Password, ClientID, ClientSecret}.All(Function(v) Not v.IsEmptyString) Then
result = False result = False
Dim r$ = String.Empty Dim r$ = String.Empty
Using resp As New Responser With { Dim c% = 0
.Mode = Responser.Modes.Curl, Dim _found As Boolean
.Method = "POST", Do
.CurlArgumentsLeft = $"-d ""grant_type=password&username={UserName}&password={Password}"" --user ""{ClientID}:{ClientSecret}""" c += 1
} Using resp As New Responser With {
r = resp.GetResponse("https://www.reddit.com/api/v1/access_token") .Method = "POST",
End Using .ProcessExceptionDecision = Function(status, obj, ee) If(status.StatusCode = 429, EDP.ReturnValue, ee)
If Not r.IsEmptyString Then }
Using j As EContainer = JsonDocument.Parse(r) With resp
If j.ListExists Then With .PayLoadValues
Dim newToken$ = j.Value("access_token") .Add("grant_type", "password")
If Not newToken.IsEmptyString Then .Add("username", UserName)
BearerToken.Value = $"Bearer {newToken}" .Add("password", Password)
BearerTokenDateUpdate.Value = Now End With
Responser.SaveSettings() .CredentialsUserName = ClientID
result = True .CredentialsPassword = ClientSecret
End If .PreAuthenticate = True
End If End With
r = resp.GetResponse("https://www.reddit.com/api/v1/access_token",, EDP.ThrowException)
End Using End Using
End If If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
_found = True
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
Loop While c < 5 And Not _found
End If End If
Return result Return result
Catch ex As Exception Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[Reddit.SiteSettings.UpdateToken]", False) Return ErrorsDescriber.Execute(e, ex, "[Reddit.SiteSettings.UpdateToken]", False)
End Try End Try
End Function End Function
#End Region #End Region

View File

@@ -324,6 +324,24 @@ Namespace DownloadObjects
Initialization = False Initialization = False
End Sub End Sub
#End Region #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
._Mode = _Mode
.Groups.ListAddList(Groups, LAP.ClearBeforeAdd)
.Timer = Timer
.StartupDelay = StartupDelay
.ShowNotifications = ShowNotifications
.ShowPictureDownloaded = ShowPictureDownloaded
.ShowPictureUser = ShowPictureUser
.ShowSimpleNotification = ShowSimpleNotification
End With
Return newObj
End Function
#End Region
#Region "Groups Support" #Region "Groups Support"
Friend Sub GROUPS_Updated(ByVal Sender As DownloadGroup) Friend Sub GROUPS_Updated(ByVal Sender As DownloadGroup)
If Groups.Count > 0 Then If Groups.Count > 0 Then

View File

@@ -8,10 +8,12 @@
' but WITHOUT ANY WARRANTY ' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Toolbars Imports PersonalUtilities.Forms.Toolbars
Imports ECI = PersonalUtilities.Forms.Toolbars.EditToolbar.ControlItem
Namespace DownloadObjects Namespace DownloadObjects
Friend Class SchedulerEditorForm Friend Class SchedulerEditorForm
#Region "Declarations" #Region "Declarations"
Private WithEvents MyDefs As DefaultFormOptions Private WithEvents MyDefs As DefaultFormOptions
Private WithEvents BTT_CLONE As ToolStripButton
Private ReadOnly MENU_SKIP As ToolStripDropDownButton Private ReadOnly MENU_SKIP As ToolStripDropDownButton
Private WithEvents BTT_SKIP As ToolStripMenuItem Private WithEvents BTT_SKIP As ToolStripMenuItem
Private WithEvents BTT_SKIP_MIN As ToolStripMenuItem Private WithEvents BTT_SKIP_MIN As ToolStripMenuItem
@@ -26,6 +28,13 @@ Namespace DownloadObjects
Friend Sub New() Friend Sub New()
InitializeComponent() InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design) MyDefs = New DefaultFormOptions(Me, Settings.Design)
BTT_CLONE = New ToolStripButton With {
.Text = "Clone",
.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
.Image = My.Resources.PlusPic_24,
.ToolTipText = "Create a copy of the selected plan",
.AutoToolTip = True
}
MENU_SKIP = New ToolStripDropDownButton With { MENU_SKIP = New ToolStripDropDownButton With {
.Text = "Skip", .Text = "Skip",
.ToolTipText = String.Empty, .ToolTipText = String.Empty,
@@ -86,7 +95,7 @@ Namespace DownloadObjects
Private Sub SchedulerEditorForm_Load(sender As Object, e As EventArgs) Handles Me.Load Private Sub SchedulerEditorForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs With MyDefs
.MyViewInitialize() .MyViewInitialize()
.AddEditToolbarPlus({New ToolStripSeparator, BTT_START, BTT_START_FORCE, MENU_SKIP, BTT_PAUSE}) .AddEditToolbar({ECI.Add, BTT_CLONE, ECI.Edit, ECI.Delete, ECI.Update, ECI.Separator, BTT_START, BTT_START_FORCE, MENU_SKIP, BTT_PAUSE})
PauseArr.AddButtons(BTT_PAUSE, .MyEditToolbar.ToolStrip) PauseArr.AddButtons(BTT_PAUSE, .MyEditToolbar.ToolStrip)
Refill() Refill()
.EndLoaderOperations(False) .EndLoaderOperations(False)
@@ -118,17 +127,24 @@ Namespace DownloadObjects
End Try End Try
End Sub End Sub
#Region "Add, Edit, Delete" #Region "Add, Edit, Delete"
Private Sub MyDefs_ButtonAddClick(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonAddClick Private Sub MyDefs_ButtonAddClick(ByVal Sender As Object, ByVal e As EventArgs) Handles MyDefs.ButtonAddClick, BTT_CLONE.Click
Dim a As New AutoDownloader(True) Dim a As AutoDownloader = Nothing
Using f As New AutoDownloaderEditorForm(a) If Sender Is BTT_CLONE Then
f.ShowDialog() If _LatestSelected.ValueBetween(0, Settings.Automation.Count - 1) Then a = Settings.Automation(_LatestSelected).Copy
If f.DialogResult = DialogResult.OK Then Else
Settings.Automation.Add(a) a = New AutoDownloader(True)
Refill() End If
Else If Not a Is Nothing Then
a.Dispose() Using f As New AutoDownloaderEditorForm(a)
End If f.ShowDialog()
End Using If f.DialogResult = DialogResult.OK Then
Settings.Automation.Add(a)
Refill()
Else
a.Dispose()
End If
End Using
End If
End Sub End Sub
Private Sub Edit() Handles MyDefs.ButtonEditClick Private Sub Edit() Handles MyDefs.ButtonEditClick
If _LatestSelected.ValueBetween(0, LIST_PLANS.Items.Count - 1) Then If _LatestSelected.ValueBetween(0, LIST_PLANS.Items.Count - 1) Then

View File

@@ -165,33 +165,45 @@ Namespace DownloadObjects
#End Region #End Region
#Region "Toolbar controls" #Region "Toolbar controls"
Private Sub MENU_VIEW_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles MENU_VIEW_SESSION.Click, MENU_VIEW_ALL.Click 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 Try
Dim clicked As ToolStripMenuItem = Sender Dim __refill As Boolean = False
Dim other As ToolStripMenuItem = If(Sender Is MENU_VIEW_SESSION, MENU_VIEW_ALL, MENU_VIEW_SESSION) Dim clicked As ToolStripMenuItem = Sender
If other.Checked Then Dim other As ToolStripMenuItem = If(Sender Is MENU_VIEW_SESSION, MENU_VIEW_ALL, MENU_VIEW_SESSION)
clicked.Checked = True ControlInvokeFast(ToolbarTOP, clicked, Sub()
other.Checked = False If other.Checked Then
__refill = True clicked.Checked = True
Else other.Checked = False
clicked.Checked = False __refill = True
End If Else
ViewMode = IIf(MENU_VIEW_SESSION.Checked, ViewModes.Session, ViewModes.All) clicked.Checked = False
ControlInvokeFast(ToolbarTOP, BTT_CLEAR, Sub() BTT_CLEAR.Visible = ViewMode = ViewModes.Session) End If
If __refill Then RefillList() ViewMode = IIf(MENU_VIEW_SESSION.Checked, ViewModes.Session, ViewModes.All)
BTT_CLEAR.Visible = ViewMode = ViewModes.Session
End Sub, EDP.SendToLog)
If __refill Then RefillList()
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "DownloadedInfoForm.ViewChange")
End Try
End Sub End Sub
Private Sub OPT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DEFAULT.Click, OPT_SUBSCRIPTIONS.Click Private Sub OPT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DEFAULT.Click, OPT_SUBSCRIPTIONS.Click
Dim __refill As Boolean = False Try
Dim clicked As ToolStripMenuItem = Sender Dim __refill As Boolean = False
Dim other As ToolStripMenuItem = If(Sender Is OPT_DEFAULT, OPT_SUBSCRIPTIONS, OPT_DEFAULT) Dim clicked As ToolStripMenuItem = Sender
If other.Checked Then Dim other As ToolStripMenuItem = If(Sender Is OPT_DEFAULT, OPT_SUBSCRIPTIONS, OPT_DEFAULT)
clicked.Checked = True ControlInvokeFast(ToolbarTOP, clicked, Sub()
other.Checked = False If other.Checked Then
__refill = True clicked.Checked = True
Else other.Checked = False
clicked.Checked = False __refill = True
End If Else
Settings.InfoViewDefault.Value = OPT_DEFAULT.Checked clicked.Checked = False
If __refill Then RefillList() End If
End Sub, EDP.SendToLog)
Settings.InfoViewDefault.Value = OPT_DEFAULT.Checked
If __refill Then RefillList()
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "DownloadedInfoForm.SubscriptionChange")
End Try
End Sub End Sub
Private Sub BTT_FIND_Click(sender As Object, e As EventArgs) Handles BTT_FIND.Click Private Sub BTT_FIND_Click(sender As Object, e As EventArgs) Handles BTT_FIND.Click
Try : RaiseEvent UserFind(If(Settings.GetUser(SelectedUser, True)?.Key, String.Empty)) : Catch : End Try Try : RaiseEvent UserFind(If(Settings.GetUser(SelectedUser, True)?.Key, String.Empty)) : Catch : End Try

View File

@@ -58,8 +58,10 @@ Namespace DownloadObjects
LastWinState = WindowState LastWinState = WindowState
With MyRange With MyRange
.AutoToolTip = True .AutoToolTip = True
.Buttons = {RCI.First, RCI.Previous, RCI.Label, RCI.Next, RCI.Last, RCI.Separator, RCI.GoTo}
.ButtonKey(RCI.Previous) = Keys.F3 .ButtonKey(RCI.Previous) = Keys.F3
.ButtonKey(RCI.Next) = Keys.F4 .ButtonKey(RCI.Next) = Keys.F4
.ButtonKey(RCI.GoTo) = New ButtonKey(Keys.G, True)
.AddThisToolbar() .AddThisToolbar()
End With End With
ToolbarTOP.Items.AddRange({New ToolStripSeparator, BTT_DELETE_SELECTED}) ToolbarTOP.Items.AddRange({New ToolStripSeparator, BTT_DELETE_SELECTED})
@@ -88,15 +90,7 @@ Namespace DownloadObjects
DataList.Clear() DataList.Clear()
End Sub End Sub
Private Sub DownloadFeedForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown Private Sub DownloadFeedForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True If e.KeyCode = Keys.F5 Then RefillList() : e.Handled = 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 Sub
#End Region #End Region
#Region "Settings" #Region "Settings"

View File

@@ -112,7 +112,7 @@ Namespace DownloadObjects
If Media.User.ForeColor.HasValue Then f = Media.User.ForeColor If Media.User.ForeColor.HasValue Then f = Media.User.ForeColor
If Media.User.IsSubscription And Media.User.IsUser Then If Media.User.IsSubscription And Media.User.IsUser Then
If Not b.HasValue And Settings.MainFrameUsersSubscriptionsColorBack_USERS.Exists Then b = Settings.MainFrameUsersSubscriptionsColorBack_USERS.Value If Not b.HasValue And Settings.MainFrameUsersSubscriptionsColorBack_USERS.Exists Then b = Settings.MainFrameUsersSubscriptionsColorBack_USERS.Value
If Not f.HasValue And Settings.MainFrameUsersSubscriptionsColorFore_USERS.Exists Then b = Settings.MainFrameUsersSubscriptionsColorFore_USERS.Value If Not f.HasValue And Settings.MainFrameUsersSubscriptionsColorFore_USERS.Exists Then f = Settings.MainFrameUsersSubscriptionsColorFore_USERS.Value
End If End If
End If End If
If Not b.HasValue And Settings.FeedBackColor.Exists Then b = Settings.FeedBackColor.Value If Not b.HasValue And Settings.FeedBackColor.Exists Then b = Settings.FeedBackColor.Value

View File

@@ -22,7 +22,7 @@ Namespace DownloadObjects.Groups
Property SubscriptionsOnly As Boolean Property SubscriptionsOnly As Boolean
Property UsersCount As Integer Property UsersCount As Integer
End Interface End Interface
Friend Class GroupParameters : Implements IGroup, IDisposable Friend Class GroupParameters : Implements IGroup, IDisposable, ICopier
Protected Const Name_Name As String = "Name" Protected Const Name_Name As String = "Name"
Protected Const Name_Temporary As String = "Temporary" Protected Const Name_Temporary As String = "Temporary"
Protected Const Name_Favorite As String = "Favorite" Protected Const Name_Favorite As String = "Favorite"
@@ -53,6 +53,28 @@ Namespace DownloadObjects.Groups
Sites = New List(Of String) Sites = New List(Of String)
SitesExcluded = New List(Of String) SitesExcluded = New List(Of String)
End Sub End Sub
#Region "ICopier Support"
Friend Overridable Overloads Function Copy() As Object Implements ICopier.Copy
Return (New GroupParameters).Copy(Me)
End Function
Friend Overridable Overloads Function Copy(ByVal Source As Object) As Object Implements ICopier.Copy
With DirectCast(Source, GroupParameters)
Name = .Name
Labels.ListAddList(.Labels, LAP.ClearBeforeAdd)
LabelsExcluded.ListAddList(.LabelsExcluded, LAP.ClearBeforeAdd)
Sites.ListAddList(.Sites, LAP.ClearBeforeAdd)
SitesExcluded.ListAddList(.SitesExcluded, LAP.ClearBeforeAdd)
Temporary = .Temporary
Favorite = .Favorite
ReadyForDownload = .ReadyForDownload
ReadyForDownloadIgnore = .ReadyForDownloadIgnore
Subscriptions = .Subscriptions
SubscriptionsOnly = .SubscriptionsOnly
UsersCount = .UsersCount
End With
Return Source
End Function
#End Region
Protected Sub Import(ByVal e As EContainer) Protected Sub Import(ByVal e As EContainer)
Name = e.Value(Name_Name) Name = e.Value(Name_Name)
Temporary = e.Value(Name_Temporary).FromXML(Of Integer)(CInt(CheckState.Indeterminate)) Temporary = e.Value(Name_Temporary).FromXML(Of Integer)(CInt(CheckState.Indeterminate))

View File

@@ -22,7 +22,7 @@ Namespace DownloadObjects
Private WithEvents BTT_INFO As ToolStripButton Private WithEvents BTT_INFO As ToolStripButton
#End Region #End Region
#Region "Initializer" #Region "Initializer"
Friend Sub New() Public Sub New()
InitializeComponent() InitializeComponent()
MUsers = New List(Of IUserData) MUsers = New List(Of IUserData)
MyDefs = New DefaultFormOptions(Me, Settings.Design) MyDefs = New DefaultFormOptions(Me, Settings.Design)

View File

@@ -225,7 +225,7 @@ Namespace Editors
#End Region #End Region
#End Region #End Region
#Region "Initializer" #Region "Initializer"
Friend Sub New() Public Sub New()
InitializeComponent() InitializeComponent()
MyView = New FormView(Me, Settings.Design) MyView = New FormView(Me, Settings.Design)
MyProgress = New MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS) MyProgress = New MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS)

View File

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

View File

@@ -418,20 +418,20 @@ CloseResume:
End Sub End Sub
#End Region #End Region
#Region "Info, Feed, Channels, Saved posts" #Region "Info, Feed, Channels, Saved posts"
#Region "Info"
Private Sub MENU_INFO_SHOW_INFO_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_INFO.Click Private Sub MENU_INFO_SHOW_INFO_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_INFO.Click
InfoForm.FormShow() InfoForm.FormShow(EDP.LogMessageValue)
End Sub End Sub
Private Sub MENU_INFO_SHOW_QUEUE_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_QUEUE.Click Private Sub MENU_INFO_SHOW_QUEUE_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_QUEUE.Click
DownloadQueue.FormShow() DownloadQueue.FormShow(EDP.LogMessageValue)
End Sub End Sub
Private Sub MENU_INFO_SHOW_MISSING_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_MISSING.Click 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 MyMissingPosts.FormShow(EDP.LogMessageValue)
If MyMissingPosts.Visible Then MyMissingPosts.BringToFront() Else MyMissingPosts.Show()
End Sub End Sub
Private Sub MENU_INFO_SHOW_USER_METRICS_Click(sender As Object, e As EventArgs) Handles MENU_INFO_SHOW_USER_METRICS.Click 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.FormShow(EDP.LogMessageValue)
MyUserMetrics.FormShowS
End Sub End Sub
#End Region
Private Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click 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 If MyFeed Is Nothing Then MyFeed = New DownloadFeedForm : AddHandler Downloader.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
If MyFeed.Visible Then MyFeed.BringToFront() Else MyFeed.Show() If MyFeed.Visible Then MyFeed.BringToFront() Else MyFeed.Show()

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below: ' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.8.19.0")> <Assembly: AssemblyVersion("2023.8.27.0")>
<Assembly: AssemblyFileVersion("2023.8.19.0")> <Assembly: AssemblyFileVersion("2023.8.27.0")>
<Assembly: NeutralResourcesLanguage("en")> <Assembly: NeutralResourcesLanguage("en")>