Compare commits
4 Commits
2023.4.28.
...
2023.6.8.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e51debc027 | ||
|
|
938042ea9e | ||
|
|
abdef81e5f | ||
|
|
e868c2e694 |
49
Changelog.md
@@ -1,3 +1,52 @@
|
|||||||
|
# 2023.6.8.0
|
||||||
|
|
||||||
|
*2023-06-08*
|
||||||
|
|
||||||
|
- Added
|
||||||
|
- YouTube: append artist name to music playlist output path
|
||||||
|
- YouTube: save thumbnail path for playlist and channel
|
||||||
|
- Fixed
|
||||||
|
- YouTube: opening paths to downloaded playlists and channels
|
||||||
|
- Twitter: profile not fully downloaded
|
||||||
|
- Corrected form size for small monitors (Issue #136)
|
||||||
|
|
||||||
|
# 2023.6.5.0
|
||||||
|
|
||||||
|
*2023-06-05*
|
||||||
|
|
||||||
|
- Added
|
||||||
|
- **Instagram**: add additional authorization headers
|
||||||
|
- Setting to prevent user icon and banner from downloading (Request #129)
|
||||||
|
- Add standalone downloader to tray context menu
|
||||||
|
- YouTube downloader: added `Replace modification date` property
|
||||||
|
- Minor improvements
|
||||||
|
- Fixed
|
||||||
|
- Fascist **Twitter**: posts not downloading (new API)
|
||||||
|
- Main window: refill bug when the number of filtered profiles = 0
|
||||||
|
- Standalone downloader: new items are not added to the queue
|
||||||
|
- Standalone downloader: bug when not downloaded videos do not appear in the list when loading the program
|
||||||
|
- Standalone downloader: add videos array not working
|
||||||
|
- Saved posts: remove main progress perform when downloading saved posts
|
||||||
|
- Minor bugs
|
||||||
|
|
||||||
|
# 2023.5.12.0
|
||||||
|
|
||||||
|
*2023-05-12*
|
||||||
|
|
||||||
|
- Added
|
||||||
|
- Advanced progress (make progress bars more informative)
|
||||||
|
- User metrics calculation
|
||||||
|
- Reddit: improve parsing function
|
||||||
|
- PornHub: add `Download UHD` option
|
||||||
|
- Fixed
|
||||||
|
- MD5 GIF hash bug
|
||||||
|
- Mastodon: handle 'Forbidden' error
|
||||||
|
- Mastodon: bug in parsing non-user posts
|
||||||
|
- Pinterest: remove cookies requirement for saved posts
|
||||||
|
- PornHub: resolutions issue
|
||||||
|
- Reddit: missing & broken images bug
|
||||||
|
- Main window: collection pointing bug
|
||||||
|
|
||||||
# 2023.4.28.0
|
# 2023.4.28.0
|
||||||
|
|
||||||
*2023-04-28*
|
*2023-04-28*
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
BIN
ProgramScreenshots/UserMetrics.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
31
README.md
@@ -1,3 +1,5 @@
|
|||||||
|
# :rainbow_flag: Happy LGBT Pride Month :tada:
|
||||||
|
|
||||||
# :rainbow_flag: Social networks crawler :rainbow_flag:
|
# :rainbow_flag: Social networks crawler :rainbow_flag:
|
||||||
|
|
||||||
[](https://github.com/AAndyProgram/SCrawler/releases/latest)
|
[](https://github.com/AAndyProgram/SCrawler/releases/latest)
|
||||||
@@ -19,7 +21,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
[**YouTube standalone application:**](https://github.com/AAndyProgram/SCrawler/wiki/YouTube%20downloader)
|
[**YouTube standalone application:**](https://github.com/AAndyProgram/SCrawler/wiki/YouTube-downloader)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||
- PornHub images, videos, save (liked) posts;
|
- PornHub images, videos, save (liked) posts;
|
||||||
- XHamster images, videos, saved posts;
|
- XHamster images, videos, saved posts;
|
||||||
- XVIDEOS videos, saved posts;
|
- XVIDEOS videos, saved posts;
|
||||||
- ThiVid images, videos, saved posts;
|
- ThisVid images, videos, saved posts;
|
||||||
- [Other](#supported-sites) supported sites
|
- [Other](#supported-sites) supported sites
|
||||||
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels)
|
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels)
|
||||||
- Download [saved Reddit, Twitter and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
- Download [saved Reddit, Twitter and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
||||||
@@ -158,11 +160,34 @@ The program has an intuitive interface.
|
|||||||
|
|
||||||
Just add a user profile and **click the ```Download``` button**.
|
Just add a user profile and **click the ```Download``` button**.
|
||||||
|
|
||||||
Read more about adding users and subreddits [here](https://github.com/AAndyProgram/SCrawler/wiki#Add%20user)
|
```mermaid
|
||||||
|
stateDiagram
|
||||||
|
Start: Add site credentials
|
||||||
|
What: What would I like to do
|
||||||
|
DownUser: Download user
|
||||||
|
DownVideo: Download video
|
||||||
|
AUser: Add user (1)
|
||||||
|
OVIF: Open standalone downloader (2)
|
||||||
|
AVideo: Add video url
|
||||||
|
F5: Press 'F5' or click the download button
|
||||||
|
[*]-->Start
|
||||||
|
Start-->What
|
||||||
|
What-->DownUser
|
||||||
|
What-->DownVideo
|
||||||
|
DownUser-->AUser
|
||||||
|
DownVideo-->OVIF
|
||||||
|
OVIF-->AVideo
|
||||||
|
AVideo-->F5
|
||||||
|
AUser-->F5
|
||||||
|
F5-->[*]
|
||||||
|
```
|
||||||
|
1. Press `Insert` or click the `Download` button ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#users-list), [hot keys](https://github.com/AAndyProgram/SCrawler/wiki#hot-keys))
|
||||||
|
2. Click the `Download` button, then `Standalone downloader` ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#download-separate-video))
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Contact me
|
# Contact me
|
||||||
|
|
||||||
Matrix (Element): https://matrix.to/#/@andyprogram:matrix.org
|
Matrix (Element): https://matrix.to/#/@andyprogram:matrix.org
|
||||||
|
|
||||||
Discord: AndyProgram#3804
|
Discord: AndyProgram#3804
|
||||||
@@ -10,6 +10,8 @@ Namespace Plugin
|
|||||||
Public Interface IPluginContentProvider : Inherits IDisposable
|
Public Interface IPluginContentProvider : Inherits IDisposable
|
||||||
Event ProgressChanged(ByVal Value As Integer)
|
Event ProgressChanged(ByVal Value As Integer)
|
||||||
Event ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
Event ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
||||||
|
Event ProgressPreChanged As ProgressChangedEventHandler
|
||||||
|
Event ProgressPreMaximumChanged As ProgressMaximumChangedEventHandler
|
||||||
Property Thrower As IThrower
|
Property Thrower As IThrower
|
||||||
Property LogProvider As ILogProvider
|
Property LogProvider As ILogProvider
|
||||||
Property Settings As ISiteSettings
|
Property Settings As ISiteSettings
|
||||||
|
|||||||
@@ -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.4.28.0")>
|
<Assembly: AssemblyVersion("2023.5.12.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.4.28.0")>
|
<Assembly: AssemblyFileVersion("2023.5.12.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -94,12 +94,12 @@ Namespace API.YouTube.Base
|
|||||||
End Property
|
End Property
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Defaults"
|
#Region "Defaults"
|
||||||
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Replace modification date"),
|
||||||
|
Description("Set the file date to the date the video was added (website) (if available). Default: false.")>
|
||||||
|
Public ReadOnly Property ReplaceModificationDate As XMLValue(Of Boolean)
|
||||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
|
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
|
||||||
Description("By default, use cookies when downloading from YouTube.")>
|
Description("By default, use cookies when downloading from YouTube.")>
|
||||||
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
|
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
|
||||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, 100), Category("Defaults"), DisplayName("Items limit"),
|
|
||||||
Description("Number of items displayed in the list.")>
|
|
||||||
Public ReadOnly Property ItemsListLimit As XMLValue(Of Integer)
|
|
||||||
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
|
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
|
||||||
DisplayName("Auto remove"), Description("Automatically remove downloaded items from the list.")>
|
DisplayName("Auto remove"), Description("Automatically remove downloaded items from the list.")>
|
||||||
Public ReadOnly Property RemoveDownloadedAutomatically As XMLValue(Of Boolean)
|
Public ReadOnly Property RemoveDownloadedAutomatically As XMLValue(Of Boolean)
|
||||||
|
|||||||
BIN
SCrawler.YouTube/Content/Pictures/StartPic_Green_16.png
Normal file
|
After Width: | Height: | Size: 373 B |
@@ -81,6 +81,14 @@ Namespace API.YouTube.Controls
|
|||||||
|
|
||||||
If Not .UserTitle.IsEmptyString Then
|
If Not .UserTitle.IsEmptyString Then
|
||||||
Text = .UserTitle
|
Text = .UserTitle
|
||||||
|
If .ObjectType = Base.YouTubeMediaType.PlayList Then
|
||||||
|
If Not .PlaylistTitle.IsEmptyString AndAlso Not .PlaylistTitle = .UserTitle Then
|
||||||
|
Text &= $" - { .PlaylistTitle}"
|
||||||
|
ElseIf Not .Title.IsEmptyString AndAlso Not .Title = .UserTitle Then
|
||||||
|
Text &= $" - { .Title}"
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
If Not TXT_OUTPUT_PATH.IsEmptyString AndAlso Not TXT_OUTPUT_PATH.Text.Contains(.UserTitle) Then TXT_OUTPUT_PATH.Text = $"{TXT_OUTPUT_PATH.Text.TrimEnd("\")}\{ .UserTitle}\"
|
||||||
ElseIf Not .PlaylistTitle.IsEmptyString Then
|
ElseIf Not .PlaylistTitle.IsEmptyString Then
|
||||||
Text = .PlaylistTitle
|
Text = .PlaylistTitle
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -115,31 +115,36 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.New
|
Me.New
|
||||||
Const d$ = " " & ChrW(183) & " "
|
Const d$ = " " & ChrW(183) & " "
|
||||||
MyContainer = Container
|
MyContainer = Container
|
||||||
MyContainer.Progress = MyProgress
|
With MyContainer
|
||||||
If MyContainer.HasElements Then FileOption = SFO.Path Else FileOption = SFO.File
|
.Progress = MyProgress
|
||||||
If Not MyContainer.SiteKey = YouTubeSiteKey Then
|
If .HasElements Then FileOption = SFO.Path Else FileOption = SFO.File
|
||||||
|
If .DownloadState = Plugin.UserMediaStates.Downloaded AndAlso
|
||||||
|
(.ObjectType = Base.YouTubeMediaType.Channel Or .ObjectType = Base.YouTubeMediaType.PlayList) AndAlso FileOption = SFO.File AndAlso
|
||||||
|
Not .File.Exists AndAlso .File.Exists(SFO.Path, False) Then FileOption = SFO.Path
|
||||||
|
If Not .SiteKey = YouTubeSiteKey Then
|
||||||
BTT_DOWN_AGAIN.Visible = False
|
BTT_DOWN_AGAIN.Visible = False
|
||||||
SEP_DOWN_AGAIN.Visible = False
|
SEP_DOWN_AGAIN.Visible = False
|
||||||
End If
|
End If
|
||||||
|
|
||||||
ICON_SITE.Image = MyContainer.SiteIcon
|
ICON_SITE.Image = .SiteIcon
|
||||||
LBL_TIME.Text = AConvert(Of String)(Container.Duration, TimeToStringProvider, String.Empty)
|
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
|
||||||
LBL_TITLE.Text = Container.ToString(True)
|
LBL_TITLE.Text = .ToString(True)
|
||||||
If Not Container.SiteKey = YouTubeSiteKey And Container.ContentType = Plugin.UserMediaTypes.Picture Then
|
If Not .SiteKey = YouTubeSiteKey And .ContentType = Plugin.UserMediaTypes.Picture Then
|
||||||
LBL_INFO.Text = Container.File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
ElseIf Not Container.IsMusic Then
|
ElseIf Not .IsMusic Then
|
||||||
If Container.Height > 0 Then
|
If .Height > 0 Then
|
||||||
LBL_INFO.Text = $"{Container.File.Extension.StringToUpper}{d}{Container.Height}p"
|
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Height}p"
|
||||||
Else
|
Else
|
||||||
LBL_INFO.Text = Container.File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
If Container.Bitrate > 0 Then
|
If .Bitrate > 0 Then
|
||||||
LBL_INFO.Text = $"{Container.File.Extension.StringToUpper}{d}{Container.Bitrate}k"
|
LBL_INFO.Text = $"{ .File.Extension.StringToUpper}{d}{ .Bitrate}k"
|
||||||
Else
|
Else
|
||||||
LBL_INFO.Text = Container.File.Extension.StringToUpper
|
LBL_INFO.Text = .File.Extension.StringToUpper
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
UpdateMediaIcon()
|
UpdateMediaIcon()
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -277,6 +282,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
#Region "Context buttons' handlers"
|
#Region "Context buttons' handlers"
|
||||||
Public Sub AddToQueue()
|
Public Sub AddToQueue()
|
||||||
ControlInvokeFast(Me, Sub()
|
ControlInvokeFast(Me, Sub()
|
||||||
|
Pending = True
|
||||||
BTT_DOWN.Visible = False
|
BTT_DOWN.Visible = False
|
||||||
SEP_DOWN.Visible = False
|
SEP_DOWN.Visible = False
|
||||||
End Sub, EDP.None)
|
End Sub, EDP.None)
|
||||||
@@ -300,6 +306,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Throw oex
|
Throw oex
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"MediaItem.Download:{vbCr}{MyContainer.ToString}{vbCr}{MyContainer.URL})")
|
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"MediaItem.Download:{vbCr}{MyContainer.ToString}{vbCr}{MyContainer.URL})")
|
||||||
|
Finally
|
||||||
|
Pending = False
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -367,7 +375,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If FileOption = SFO.File And MyContainer.File.Exists(SFO.File, False) Then
|
If FileOption = SFO.File And MyContainer.File.Exists(SFO.File, False) Then
|
||||||
MyContainer.File.Open(SFO.File,, EDP.ShowMainMsg)
|
MyContainer.File.Open(SFO.File,, EDP.ShowMainMsg)
|
||||||
ElseIf MyContainer.File.Exists(SFO.Path, False) Then
|
ElseIf MyContainer.File.Exists(SFO.Path, False) Then
|
||||||
MyContainer.File.Open(SFO.Path,, EDP.ShowMainMsg)
|
GlobalOpenPath(MyContainer.File, EDP.ShowMainMsg)
|
||||||
Else
|
Else
|
||||||
m.Show()
|
m.Show()
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_ADD.Size = New System.Drawing.Size(184, 22)
|
Me.BTT_ADD.Size = New System.Drawing.Size(184, 22)
|
||||||
Me.BTT_ADD.Tag = "a"
|
Me.BTT_ADD.Tag = "a"
|
||||||
Me.BTT_ADD.Text = "Add (Ins)"
|
Me.BTT_ADD.Text = "Add (Ins)"
|
||||||
Me.BTT_ADD.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)."
|
Me.BTT_ADD.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" &
|
||||||
|
"dd without downloading."
|
||||||
'
|
'
|
||||||
'BTT_ADD_PLS_ARR
|
'BTT_ADD_PLS_ARR
|
||||||
'
|
'
|
||||||
@@ -154,7 +155,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_ADD_PLS_ARR.Size = New System.Drawing.Size(184, 22)
|
Me.BTT_ADD_PLS_ARR.Size = New System.Drawing.Size(184, 22)
|
||||||
Me.BTT_ADD_PLS_ARR.Tag = "pls"
|
Me.BTT_ADD_PLS_ARR.Tag = "pls"
|
||||||
Me.BTT_ADD_PLS_ARR.Text = "Add playlist array"
|
Me.BTT_ADD_PLS_ARR.Text = "Add playlist array"
|
||||||
Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)."
|
Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" &
|
||||||
|
"dd without downloading."
|
||||||
'
|
'
|
||||||
'BTT_ADD_NO_SHORTS
|
'BTT_ADD_NO_SHORTS
|
||||||
'
|
'
|
||||||
@@ -166,7 +168,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_ADD_NO_SHORTS.Tag = "ans"
|
Me.BTT_ADD_NO_SHORTS.Tag = "ans"
|
||||||
Me.BTT_ADD_NO_SHORTS.Text = "Add (without Shorts)"
|
Me.BTT_ADD_NO_SHORTS.Text = "Add (without Shorts)"
|
||||||
Me.BTT_ADD_NO_SHORTS.ToolTipText = "Download all videos except 'Shorts'." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies fo" &
|
Me.BTT_ADD_NO_SHORTS.ToolTipText = "Download all videos except 'Shorts'." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies fo" &
|
||||||
"r download (if supported)."
|
"r download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading."
|
||||||
'
|
'
|
||||||
'BTT_ADD_SHORTS_ONLY
|
'BTT_ADD_SHORTS_ONLY
|
||||||
'
|
'
|
||||||
@@ -178,20 +180,21 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Me.BTT_ADD_SHORTS_ONLY.Tag = "as"
|
Me.BTT_ADD_SHORTS_ONLY.Tag = "as"
|
||||||
Me.BTT_ADD_SHORTS_ONLY.Text = "Add (Shorts only)"
|
Me.BTT_ADD_SHORTS_ONLY.Text = "Add (Shorts only)"
|
||||||
Me.BTT_ADD_SHORTS_ONLY.ToolTipText = "Download only 'Shorts' videos." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for down" &
|
Me.BTT_ADD_SHORTS_ONLY.ToolTipText = "Download only 'Shorts' videos." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for down" &
|
||||||
"load (if supported)."
|
"load (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading."
|
||||||
'
|
'
|
||||||
'BTT_DOWN
|
'BTT_DOWN
|
||||||
'
|
'
|
||||||
Me.BTT_DOWN.Image = CType(resources.GetObject("BTT_DOWN.Image"), System.Drawing.Image)
|
Me.BTT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
|
||||||
Me.BTT_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
|
Me.BTT_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
Me.BTT_DOWN.Name = "BTT_DOWN"
|
Me.BTT_DOWN.Name = "BTT_DOWN"
|
||||||
Me.BTT_DOWN.Size = New System.Drawing.Size(81, 22)
|
Me.BTT_DOWN.Size = New System.Drawing.Size(81, 22)
|
||||||
Me.BTT_DOWN.Text = "Download"
|
Me.BTT_DOWN.Text = "Download"
|
||||||
Me.BTT_DOWN.ToolTipText = "Download pending items"
|
Me.BTT_DOWN.ToolTipText = "Download pending items (F5)"
|
||||||
'
|
'
|
||||||
'BTT_STOP
|
'BTT_STOP
|
||||||
'
|
'
|
||||||
Me.BTT_STOP.AutoToolTip = False
|
Me.BTT_STOP.AutoToolTip = False
|
||||||
|
Me.BTT_STOP.Enabled = False
|
||||||
Me.BTT_STOP.Image = CType(resources.GetObject("BTT_STOP.Image"), System.Drawing.Image)
|
Me.BTT_STOP.Image = CType(resources.GetObject("BTT_STOP.Image"), System.Drawing.Image)
|
||||||
Me.BTT_STOP.ImageTransparentColor = System.Drawing.Color.Magenta
|
Me.BTT_STOP.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
Me.BTT_STOP.Name = "BTT_STOP"
|
Me.BTT_STOP.Name = "BTT_STOP"
|
||||||
|
|||||||
@@ -136,243 +136,222 @@
|
|||||||
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_ADD_NO_SHORTS.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_ADD_NO_SHORTS.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_ADD_SHORTS_ONLY.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_ADD_SHORTS_ONLY.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
|
||||||
</data>
|
|
||||||
<data name="BTT_DOWN.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>
|
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
|
||||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN7SURBVEhLrZVJTFNRFIafQhgkQA1OZYriSI0UtUI0vIKg
|
|
||||||
UEGNBRSUIQ4MihElUAgOqeKwcGM07owLYoxxYzSuHBZIjAoKrfpaoBZLJyiaYNxf83vus0QWBAy+k/xp
|
|
||||||
k3vzf+ee99/3hNkq7GZIZ/itEEwnvhbcNvfiRmlWDcu1iNj5UYRBItlE7HflyZDgtrkXN9n4ScMWdAuI
|
|
||||||
eSsg7r2AhL5Q1PoKlQPoJA2LfSdg8ft5WG4JR7oUg9ZAiXKATALwzlOs4dhkj0XO4FJc+V6pHECU0liK
|
|
||||||
NQJb7CoUOOJp/qtwc6JOOcBRScd0NhUKHQk4NLIWde503P3ZqBygWcpihi+JqHKnosGzCc3ebbj/0/Rv
|
|
||||||
gJlyPqkjluxfle51OOXRoW1UxKVAPjp/tGDRg8gZpX4U1Sl3mDeZccp30aCIYkcuql0FOOXdi3b/flwN
|
|
||||||
VNN/Hc769egIFODyuAGdEy24N2GSQXcmGnHjew06xivQ6i+lERahwV0G9eMoyABuHvOGMt4jINESBi3F
|
|
||||||
kCfFOJyCI+71OO3NxLnR7WRgwLXxQhlwaSyfzETUedJxYHg18oaWQWuLQVJ/GFTkU2Yz/gXwzrk5X9Ta
|
|
||||||
ommzGiVB8zO+TJz35+JywECAfFwYy4XJn0XPYjMOj2iwz7kC2YNLsEGKRrwlFKpeAZF0KUs+TgEU2UUk
|
|
||||||
k3k6dZDnUMsxrPVo0eTLwNnRHJwn03Z/Nky+LJzxbkE9rVW5NdjjXA49nVQ27w8Fv4zcfN5zAcbeKYCD
|
|
||||||
jh3Yao+jGCaiwrUOjfQwWygpbWTITZt922Q10ajqaSQ8TbudycgaWILUz1FQfwhBNI04okuA8Iz0mACv
|
|
||||||
pwBOSBnMNKBnZmcVMw8fY+av9czsqqPf4+yi/SS7/e0EmWeg1q1F+cgaFDqT0OatRtmHHb9qpGxWKYms
|
|
||||||
nKQniZ9IfaQekckAHtPpIjYpvun6QBur9aSh3LUau+iUmXTaBk+5vDajeExnK76xw97EDtBzKRhKwGa6
|
|
||||||
0SutkTjsKpZNgtvmXtzELDWw/KF4+UXH36ZxlJRDjuCM/7f+AGrYRlssEikpCynO/NtQOpnz/y1u0ihV
|
|
||||||
sKT+cKgohgteCQh5QSmxKgg4KukZN4+gzufzGD4lwDsFARUUv0jqXKALJDwhPSRAt4KA0s9GeSTGHhJd
|
|
||||||
IGMX6aVSAMoyN5pWs+ZcEH4DgcGuQfDpaFIAAAAASUVORK5CYII=
|
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
VAUAAAAASUVORK5CYII=
|
4dDtOAAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
OqoAAAAASUVORK5CYII=
|
P/QAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
OqoAAAAASUVORK5CYII=
|
P/QAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
OqoAAAAASUVORK5CYII=
|
P/QAAAAASUVORK5CYII=
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
|||||||
@@ -81,7 +81,13 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If Not MyYouTubeSettings Is Nothing Then MyYouTubeSettings.Close()
|
If Not MyYouTubeSettings Is Nothing Then MyYouTubeSettings.Close()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub VideoListForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
Private Sub VideoListForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||||
If e.KeyCode = Keys.Insert Then BTT_ADD.PerformClick() : e.Handled = True
|
Dim b As Boolean = True
|
||||||
|
Select Case e.KeyCode
|
||||||
|
Case Keys.Insert : BTT_ADD.PerformClick()
|
||||||
|
Case Keys.F5 : BTT_DOWN.PerformClick()
|
||||||
|
Case Else : b = False
|
||||||
|
End Select
|
||||||
|
If b Then e.Handled = True
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Refill, save list"
|
#Region "Refill, save list"
|
||||||
@@ -230,10 +236,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
BTT_ADD_NO_SHORTS.KeyClick, BTT_ADD_SHORTS_ONLY.KeyClick
|
BTT_ADD_NO_SHORTS.KeyClick, BTT_ADD_SHORTS_ONLY.KeyClick
|
||||||
Dim pForm As ParsingProgressForm = Nothing
|
Dim pForm As ParsingProgressForm = Nothing
|
||||||
Try
|
Try
|
||||||
Dim canProcess As Boolean = True
|
|
||||||
If TP_CONTROLS.Controls.Count >= MyYouTubeSettings.ItemsListLimit Then canProcess = TP_CONTROLS.Controls.Cast(Of MediaItem).ListExists(ControlsDownloaded)
|
|
||||||
If canProcess Then
|
|
||||||
Dim useCookies As Boolean = MyYouTubeSettings.DefaultUseCookies
|
Dim useCookies As Boolean = MyYouTubeSettings.DefaultUseCookies
|
||||||
|
Dim disableDown As Boolean = e.Shift
|
||||||
If e.Control Then useCookies = True
|
If e.Control Then useCookies = True
|
||||||
Dim useCookiesParse As Boolean? = Nothing
|
Dim useCookiesParse As Boolean? = Nothing
|
||||||
If useCookies Then useCookiesParse = True
|
If useCookies Then useCookiesParse = True
|
||||||
@@ -296,18 +300,11 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If Not f Is Nothing Then
|
If Not f Is Nothing Then
|
||||||
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
If f.DialogResult = DialogResult.OK Then
|
If f.DialogResult = DialogResult.OK Then ControlCreateAndAdd(c, disableDown)
|
||||||
If TP_CONTROLS.Controls.Count >= MyYouTubeSettings.ItemsListLimit Then _
|
|
||||||
RemoveControls(TP_CONTROLS.Controls.Cast(Of MediaItem).LastOrDefault(ControlsDownloaded))
|
|
||||||
ControlCreateAndAdd(c)
|
|
||||||
End If
|
|
||||||
f.Dispose()
|
f.Dispose()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Else
|
|
||||||
MsgBoxE({$"Number of items to download exceeded!{vbCr}Reduce the number of items or increase the limit.", "New download"}, vbCritical)
|
|
||||||
End If
|
|
||||||
Catch oex As OperationCanceledException
|
Catch oex As OperationCanceledException
|
||||||
Catch dex As ObjectDisposedException
|
Catch dex As ObjectDisposedException
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -425,8 +422,10 @@ Namespace DownloadObjects.STDownloader
|
|||||||
UpdateLogButton()
|
UpdateLogButton()
|
||||||
End Sub
|
End Sub
|
||||||
Protected Sub AddToDownload(ByRef Item As MediaItem, ByVal RunThread As Boolean)
|
Protected Sub AddToDownload(ByRef Item As MediaItem, ByVal RunThread As Boolean)
|
||||||
If MyJob.Count = 0 OrElse Not MyJob.Items.Exists(Function(i) i.MyContainer.GetHashCode) Then
|
Dim hc% = Item.MyContainer.GetHashCode
|
||||||
Item.Pending = True
|
If MyJob.Count = 0 OrElse Not MyJob.Items.Exists(Function(i) i.MyContainer.GetHashCode = hc) Then
|
||||||
|
'TODELETE: YT video downloader 'Item.Pending'
|
||||||
|
'Item.Pending = True
|
||||||
MyJob.Add(Item)
|
MyJob.Add(Item)
|
||||||
Item.AddToQueue()
|
Item.AddToQueue()
|
||||||
If RunThread Then StartDownloading()
|
If RunThread Then StartDownloading()
|
||||||
@@ -475,7 +474,10 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Task.WaitAll(t.ToArray)
|
Task.WaitAll(t.ToArray)
|
||||||
MyProgress.Perform(t.Count)
|
MyProgress.Perform(t.Count)
|
||||||
If Indexes.Count > 0 Then
|
If Indexes.Count > 0 Then
|
||||||
For i = Indexes.Count - 1 To 0 Step -1 : MyJob.Items.RemoveAt(Indexes(i)) : Next
|
For i = Indexes.Count - 1 To 0 Step -1
|
||||||
|
MyJob.Item(Indexes(i)).Pending = False
|
||||||
|
MyJob.Items.RemoveAt(Indexes(i))
|
||||||
|
Next
|
||||||
End If
|
End If
|
||||||
t.Clear()
|
t.Clear()
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -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.4.28.0")>
|
<Assembly: AssemblyVersion("2023.6.8.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.4.28.0")>
|
<Assembly: AssemblyFileVersion("2023.6.8.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
10
SCrawler.YouTube/My Project/Resources.Designer.vb
generated
@@ -150,6 +150,16 @@ Namespace My.Resources
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
'''</summary>
|
||||||
|
Public ReadOnly Property StartPic_Green_16() As System.Drawing.Bitmap
|
||||||
|
Get
|
||||||
|
Dim obj As Object = ResourceManager.GetObject("StartPic_Green_16", resourceCulture)
|
||||||
|
Return CType(obj,System.Drawing.Bitmap)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
'''<summary>
|
'''<summary>
|
||||||
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
'''</summary>
|
'''</summary>
|
||||||
|
|||||||
@@ -145,6 +145,9 @@
|
|||||||
<data name="SettingsPic_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="SettingsPic_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Content\Pictures\SettingsPic_16.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Content\Pictures\SettingsPic_16.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="StartPic_Green_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Content\Pictures\StartPic_Green_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
<data name="VideoCamera_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="VideoCamera_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Content\Pictures\VideoCamera_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Content\Pictures\VideoCamera_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ Namespace API.YouTube.Objects
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Protected _Exists As Boolean = True
|
Protected _Exists As Boolean = True
|
||||||
Public ReadOnly Property Exists As Boolean Implements IDownloadableMedia.Exists
|
Public Overridable ReadOnly Property Exists As Boolean Implements IDownloadableMedia.Exists
|
||||||
Get
|
Get
|
||||||
If Not _Exists Then
|
If Not _Exists Then
|
||||||
Return False
|
Return False
|
||||||
@@ -643,6 +643,7 @@ Namespace API.YouTube.Objects
|
|||||||
End If
|
End If
|
||||||
If Not cmd.IsEmptyString Then
|
If Not cmd.IsEmptyString Then
|
||||||
cmd = $"yt-dlp -f ""{cmd}"""
|
cmd = $"yt-dlp -f ""{cmd}"""
|
||||||
|
If Not MyYouTubeSettings.ReplaceModificationDate Then cmd &= " --no-mtime"
|
||||||
cmd.StringAppend(formats, " ")
|
cmd.StringAppend(formats, " ")
|
||||||
cmd.StringAppend(subs, " ")
|
cmd.StringAppend(subs, " ")
|
||||||
cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ")
|
cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ")
|
||||||
@@ -864,6 +865,7 @@ Namespace API.YouTube.Objects
|
|||||||
.Information = $"Download {MediaType}"
|
.Information = $"Download {MediaType}"
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
.MainProcessName = "yt-dlp"
|
||||||
.FileExchanger = MyCache.NewInstance(Of BatchFileExchanger)(CachePath, EDP.ReturnValue)
|
.FileExchanger = MyCache.NewInstance(Of BatchFileExchanger)(CachePath, EDP.ReturnValue)
|
||||||
.FileExchanger.DeleteCacheOnDispose = True
|
.FileExchanger.DeleteCacheOnDispose = True
|
||||||
.AddCommand("chcp 65001")
|
.AddCommand("chcp 65001")
|
||||||
@@ -1038,6 +1040,14 @@ Namespace API.YouTube.Objects
|
|||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Save"
|
#Region "Save"
|
||||||
|
Private Function GetThumbnails() As IEnumerable(Of SFile)
|
||||||
|
If HasElements Then
|
||||||
|
Return ListAddList(Of SFile)(New List(Of SFile)({ThumbnailFile}),
|
||||||
|
Elements.SelectMany(Function(ee As YouTubeMediaContainerBase) ee.GetThumbnails))
|
||||||
|
Else
|
||||||
|
Return {ThumbnailFile}
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
Public Overridable Sub Save() Implements IDownloadableMedia.Save
|
Public Overridable Sub Save() Implements IDownloadableMedia.Save
|
||||||
Try
|
Try
|
||||||
Dim fSettings As SFile = FileSettings
|
Dim fSettings As SFile = FileSettings
|
||||||
@@ -1066,6 +1076,11 @@ Namespace API.YouTube.Objects
|
|||||||
Else
|
Else
|
||||||
If CachePath.Exists(SFO.Path, False) Then CachePath.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
If CachePath.Exists(SFO.Path, False) Then CachePath.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
||||||
CachePath = Nothing
|
CachePath = Nothing
|
||||||
|
If ThumbnailFile.IsEmptyString And HasElements Then
|
||||||
|
With ListAddList(Nothing, GetThumbnails, LAP.NotContainsOnly).ListWithRemove(Function(tf) tf.IsEmptyString)
|
||||||
|
If .ListExists Then _ThumbnailFile = .FirstOrDefault(Function(tf) tf.Exists)
|
||||||
|
End With
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Using x As New XmlFile With {.AllowSameNames = True}
|
Using x As New XmlFile With {.AllowSameNames = True}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Content\Pictures\ImagePic_32.png" />
|
<None Include="Content\Pictures\ImagePic_32.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Content\Pictures\StartPic_Green_16.png" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -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.4.28.0")>
|
<Assembly: AssemblyVersion("2023.6.8.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.4.28.0")>
|
<Assembly: AssemblyFileVersion("2023.6.8.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -72,15 +72,22 @@ Namespace API.Base.GDL
|
|||||||
Friend Const UrlTextStart As String = UrlLibStart & " https"
|
Friend Const UrlTextStart As String = UrlLibStart & " https"
|
||||||
Friend Sub New()
|
Friend Sub New()
|
||||||
MyBase.New(True)
|
MyBase.New(True)
|
||||||
|
MainProcessName = "gallery-dl"
|
||||||
ChangeDirectory(Settings.GalleryDLFile.File)
|
ChangeDirectory(Settings.GalleryDLFile.File)
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Overrides Sub Create()
|
||||||
|
If TempPostsList Is Nothing Then TempPostsList = New List(Of String)
|
||||||
|
MyBase.Create()
|
||||||
|
End Sub
|
||||||
Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
|
Protected Overrides Async Sub OutputDataReceiver(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
|
||||||
|
If Not ProcessKilled Then
|
||||||
MyBase.OutputDataReceiver(Sender, e)
|
MyBase.OutputDataReceiver(Sender, e)
|
||||||
Await Validate(e.Data)
|
Await Validate(e.Data)
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overridable Async Function Validate(ByVal Value As String) As Task
|
Protected Overridable Async Function Validate(ByVal Value As String) As Task
|
||||||
If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
|
If Not ProcessKilled AndAlso Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
|
||||||
TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill(EDP.None)
|
TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill()
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -33,8 +33,10 @@ Namespace API.Base
|
|||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Friend Shared Function Download(ByVal URLs As List(Of String), ByVal DestinationFile As SFile, Optional ByVal Responser As Responser = Nothing,
|
Friend Shared Function Download(ByVal URLs As List(Of String), ByVal DestinationFile As SFile, Optional ByVal Responser As Responser = Nothing,
|
||||||
Optional ByVal Token As CancellationToken = Nothing, Optional ByVal Progress As MyProgress = Nothing) As SFile
|
Optional ByVal Token As CancellationToken = Nothing, Optional ByVal Progress As MyProgress = Nothing,
|
||||||
|
Optional ByVal UsePreProgress As Boolean = True) As SFile
|
||||||
Dim Cache As CacheKeeper = Nothing
|
Dim Cache As CacheKeeper = Nothing
|
||||||
|
Using tmpPr As New PreProgress(Progress)
|
||||||
Try
|
Try
|
||||||
If URLs.ListExists Then
|
If URLs.ListExists Then
|
||||||
Dim ConcatFile As SFile = DestinationFile
|
Dim ConcatFile As SFile = DestinationFile
|
||||||
@@ -44,7 +46,13 @@ Namespace API.Base
|
|||||||
Dim cache2 As CacheKeeper = Cache.NewInstance
|
Dim cache2 As CacheKeeper = Cache.NewInstance
|
||||||
If cache2.RootDirectory.Exists(SFO.Path) Then
|
If cache2.RootDirectory.Exists(SFO.Path) Then
|
||||||
Dim progressExists As Boolean = Not Progress Is Nothing
|
Dim progressExists As Boolean = Not Progress Is Nothing
|
||||||
If progressExists Then Progress.Maximum += URLs.Count
|
If progressExists Then
|
||||||
|
If UsePreProgress Then
|
||||||
|
tmpPr.ChangeMax(URLs.Count)
|
||||||
|
Else
|
||||||
|
Progress.Maximum += URLs.Count
|
||||||
|
End If
|
||||||
|
End If
|
||||||
Dim p As SFileNumbers = SFileNumbers.Default(ConcatFile.Name)
|
Dim p As SFileNumbers = SFileNumbers.Default(ConcatFile.Name)
|
||||||
ConcatFile = SFile.IndexReindex(ConcatFile,,, p, EDP.ReturnValue)
|
ConcatFile = SFile.IndexReindex(ConcatFile,,, p, EDP.ReturnValue)
|
||||||
Dim i%
|
Dim i%
|
||||||
@@ -52,7 +60,13 @@ Namespace API.Base
|
|||||||
dFile.Extension = "ts"
|
dFile.Extension = "ts"
|
||||||
Using w As New DownloadObjects.WebClient2(Responser)
|
Using w As New DownloadObjects.WebClient2(Responser)
|
||||||
For i = 0 To URLs.Count - 1
|
For i = 0 To URLs.Count - 1
|
||||||
If progressExists Then Progress.Perform()
|
If progressExists Then
|
||||||
|
If UsePreProgress Then
|
||||||
|
tmpPr.Perform()
|
||||||
|
Else
|
||||||
|
Progress.Perform()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
Token.ThrowIfCancellationRequested()
|
Token.ThrowIfCancellationRequested()
|
||||||
dFile.Name = $"ConPart_{i}"
|
dFile.Name = $"ConPart_{i}"
|
||||||
w.DownloadFile(URLs(i), dFile)
|
w.DownloadFile(URLs(i), dFile)
|
||||||
@@ -67,6 +81,7 @@ Namespace API.Base
|
|||||||
Finally
|
Finally
|
||||||
Cache.DisposeIfReady
|
Cache.DisposeIfReady
|
||||||
End Try
|
End Try
|
||||||
|
End Using
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -126,6 +126,7 @@ Namespace API.Base
|
|||||||
Private Const Name_ReadyForDownload As String = "ReadyForDownload"
|
Private Const Name_ReadyForDownload As String = "ReadyForDownload"
|
||||||
Private Const Name_DownloadImages As String = "DownloadImages"
|
Private Const Name_DownloadImages As String = "DownloadImages"
|
||||||
Private Const Name_DownloadVideos As String = "DownloadVideos"
|
Private Const Name_DownloadVideos As String = "DownloadVideos"
|
||||||
|
Private Const Name_IconBannerDownloaded As String = "IconBannerDownloaded"
|
||||||
|
|
||||||
Private Const Name_VideoCount As String = "VideoCount"
|
Private Const Name_VideoCount As String = "VideoCount"
|
||||||
Private Const Name_PicturesCount As String = "PicturesCount"
|
Private Const Name_PicturesCount As String = "PicturesCount"
|
||||||
@@ -146,7 +147,18 @@ Namespace API.Base
|
|||||||
Return HOST.Name
|
Return HOST.Name
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
Private _Progress As MyProgress
|
||||||
Friend Property Progress As MyProgress
|
Friend Property Progress As MyProgress
|
||||||
|
Get
|
||||||
|
Return _Progress
|
||||||
|
End Get
|
||||||
|
Set(ByVal p As MyProgress)
|
||||||
|
_Progress = p
|
||||||
|
If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose()
|
||||||
|
ProgressPre = New PreProgress(_Progress)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Protected Property ProgressPre As PreProgress = Nothing
|
||||||
#End Region
|
#End Region
|
||||||
#Region "User name, ID, exist, suspend"
|
#Region "User name, ID, exist, suspend"
|
||||||
Friend User As UserInfo
|
Friend User As UserInfo
|
||||||
@@ -423,6 +435,18 @@ BlockNullPicture:
|
|||||||
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
|
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
|
||||||
Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos
|
Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos
|
||||||
Friend Property DownloadMissingOnly As Boolean = False Implements IUserData.DownloadMissingOnly
|
Friend Property DownloadMissingOnly As Boolean = False Implements IUserData.DownloadMissingOnly
|
||||||
|
Private _IconBannerDownloaded As Boolean = False
|
||||||
|
Friend WriteOnly Property IconBannerDownloaded As Boolean
|
||||||
|
Set(ByVal IsDownloaded As Boolean)
|
||||||
|
If Not _IconBannerDownloaded = IsDownloaded Then _ForceSaveUserInfo = True
|
||||||
|
_IconBannerDownloaded = IsDownloaded
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property DownloadIconBanner As Boolean
|
||||||
|
Get
|
||||||
|
Return Not _IconBannerDownloaded Or Settings.UpdateUserIconBannerEveryTime
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Content"
|
#Region "Content"
|
||||||
Protected ReadOnly _ContentList As List(Of UserMedia)
|
Protected ReadOnly _ContentList As List(Of UserMedia)
|
||||||
@@ -566,6 +590,8 @@ BlockNullPicture:
|
|||||||
#Region "Plugins Support"
|
#Region "Plugins Support"
|
||||||
Protected Event ProgressChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressChanged
|
Protected Event ProgressChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressChanged
|
||||||
Protected Event ProgressMaximumChanged As IPluginContentProvider.ProgressMaximumChangedEventHandler Implements IPluginContentProvider.ProgressMaximumChanged
|
Protected Event ProgressMaximumChanged As IPluginContentProvider.ProgressMaximumChangedEventHandler Implements IPluginContentProvider.ProgressMaximumChanged
|
||||||
|
Protected Event ProgressPreChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressPreChanged
|
||||||
|
Protected Event ProgressPreMaximumChanged As IPluginContentProvider.ProgressMaximumChangedEventHandler Implements IPluginContentProvider.ProgressPreMaximumChanged
|
||||||
Private Property IPluginContentProvider_Settings As ISiteSettings Implements IPluginContentProvider.Settings
|
Private Property IPluginContentProvider_Settings As ISiteSettings Implements IPluginContentProvider.Settings
|
||||||
Get
|
Get
|
||||||
Return HOST.Source
|
Return HOST.Source
|
||||||
@@ -738,6 +764,7 @@ BlockNullPicture:
|
|||||||
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
||||||
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
||||||
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
||||||
|
_IconBannerDownloaded = x.Value(Name_IconBannerDownloaded).FromXML(Of Boolean)(False)
|
||||||
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
||||||
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
||||||
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
||||||
@@ -786,6 +813,7 @@ BlockNullPicture:
|
|||||||
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
||||||
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
||||||
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
||||||
|
x.Add(Name_IconBannerDownloaded, _IconBannerDownloaded.BoolToInteger)
|
||||||
x.Add(Name_VideoCount, DownloadedVideos(True))
|
x.Add(Name_VideoCount, DownloadedVideos(True))
|
||||||
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
||||||
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
||||||
@@ -911,6 +939,7 @@ BlockNullPicture:
|
|||||||
Private _PictureExists As Boolean
|
Private _PictureExists As Boolean
|
||||||
Private _EnvirInvokeUserUpdated As Boolean = False
|
Private _EnvirInvokeUserUpdated As Boolean = False
|
||||||
Protected Sub EnvirDownloadSet()
|
Protected Sub EnvirDownloadSet()
|
||||||
|
ProgressPre.Reset()
|
||||||
UpdateDataFiles()
|
UpdateDataFiles()
|
||||||
_DownloadInProgress = True
|
_DownloadInProgress = True
|
||||||
_DescriptionChecked = False
|
_DescriptionChecked = False
|
||||||
@@ -920,12 +949,12 @@ BlockNullPicture:
|
|||||||
_EnvirUserExists = UserExists
|
_EnvirUserExists = UserExists
|
||||||
_EnvirUserSuspended = UserSuspended
|
_EnvirUserSuspended = UserSuspended
|
||||||
_EnvirChanged = False
|
_EnvirChanged = False
|
||||||
|
_EnvirInvokeUserUpdated = False
|
||||||
UserExists = True
|
UserExists = True
|
||||||
UserSuspended = False
|
UserSuspended = False
|
||||||
DownloadedPictures(False) = 0
|
DownloadedPictures(False) = 0
|
||||||
DownloadedVideos(False) = 0
|
DownloadedVideos(False) = 0
|
||||||
_PictureExists = Settings.ViewModeIsPicture AndAlso Not GetPicture(Of Image)(False) Is Nothing
|
_PictureExists = Settings.ViewModeIsPicture AndAlso Not GetPicture(Of Image)(False) Is Nothing
|
||||||
_EnvirInvokeUserUpdated = False
|
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub EnvirChanged(ByVal NewValue As Object, <CallerMemberName> Optional ByVal Caller As String = Nothing)
|
Private Sub EnvirChanged(ByVal NewValue As Object, <CallerMemberName> Optional ByVal Caller As String = Nothing)
|
||||||
If _DownloadInProgress Then
|
If _DownloadInProgress Then
|
||||||
@@ -962,10 +991,12 @@ BlockNullPicture:
|
|||||||
If Not DownloadMissingOnly Then
|
If Not DownloadMissingOnly Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
DownloadDataF(Token)
|
DownloadDataF(Token)
|
||||||
|
ProgressPre.Done()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If Settings.ReparseMissingInTheRoutine Then ReparseMissing(Token) : ThrowAny(Token)
|
If Settings.ReparseMissingInTheRoutine Then ReparseMissing(Token) : ProgressPre.Done() : ThrowAny(Token)
|
||||||
Else
|
Else
|
||||||
ReparseMissing(Token)
|
ReparseMissing(Token)
|
||||||
|
ProgressPre.Done()
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If _TempMediaList.Count > 0 Then
|
If _TempMediaList.Count > 0 Then
|
||||||
@@ -976,12 +1007,15 @@ BlockNullPicture:
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
ReparseVideo(Token)
|
ReparseVideo(Token)
|
||||||
|
ProgressPre.Done()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
|
||||||
If UseMD5Comparison Then ValidateMD5(Token) : ThrowAny(Token)
|
If UseMD5Comparison Then ValidateMD5(Token) : ProgressPre.Done() : ThrowAny(Token)
|
||||||
|
|
||||||
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then _
|
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then
|
||||||
|
If _TempPostsList.Count > 1000 Then _TempPostsList.ListAddList(_TempPostsList.ListTake(-2, 1000, EDP.ReturnValue).ListReverse, LAP.ClearBeforeAdd)
|
||||||
TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None)
|
TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None)
|
||||||
|
End If
|
||||||
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
|
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
|
||||||
DownloadContent(Token)
|
DownloadContent(Token)
|
||||||
ThrowIfDisposed()
|
ThrowIfDisposed()
|
||||||
@@ -1004,7 +1038,6 @@ BlockNullPicture:
|
|||||||
_ContentList.Clear()
|
_ContentList.Clear()
|
||||||
CreatedByChannel = False
|
CreatedByChannel = False
|
||||||
End If
|
End If
|
||||||
If Not UserExists Then ReadyForDownload = False
|
|
||||||
UpdateUserInformation()
|
UpdateUserInformation()
|
||||||
If _CollectionButtonsExists AndAlso _EnvirChanged Then UpdateButtonsColor()
|
If _CollectionButtonsExists AndAlso _EnvirChanged Then UpdateButtonsColor()
|
||||||
ElseIf _ForceSaveUserInfo Then
|
ElseIf _ForceSaveUserInfo Then
|
||||||
@@ -1031,6 +1064,7 @@ BlockNullPicture:
|
|||||||
DownloadMissingOnly = False
|
DownloadMissingOnly = False
|
||||||
_ForceSaveUserData = False
|
_ForceSaveUserData = False
|
||||||
_ForceSaveUserInfo = False
|
_ForceSaveUserInfo = False
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Protected Sub UpdateDataFiles()
|
Protected Sub UpdateDataFiles()
|
||||||
@@ -1061,11 +1095,10 @@ BlockNullPicture:
|
|||||||
Progress = Data.Progress
|
Progress = Data.Progress
|
||||||
If Not Responser Is Nothing Then Responser.Dispose()
|
If Not Responser Is Nothing Then Responser.Dispose()
|
||||||
Responser = New Responser
|
Responser = New Responser
|
||||||
If Not HOST Is Nothing AndAlso Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser)
|
If Not HOST Is Nothing AndAlso HOST.Available(ISiteSettings.Download.SingleObject, True) AndAlso
|
||||||
|
Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser)
|
||||||
SeparateVideoFolder = False
|
SeparateVideoFolder = False
|
||||||
IsSingleObjectDownload = True
|
IsSingleObjectDownload = True
|
||||||
UseInternalDownloadFileFunction_UseProgress = True
|
|
||||||
UseInternalM3U8Function_UseProgress = True
|
|
||||||
DownloadSingleObject_GetPosts(Data, Token)
|
DownloadSingleObject_GetPosts(Data, Token)
|
||||||
DownloadSingleObject_CreateMedia(Data, Token)
|
DownloadSingleObject_CreateMedia(Data, Token)
|
||||||
DownloadSingleObject_Download(Data, Token)
|
DownloadSingleObject_Download(Data, Token)
|
||||||
@@ -1157,15 +1190,17 @@ BlockNullPicture:
|
|||||||
ImgFormat = GetImageFormat(__data.File)
|
ImgFormat = GetImageFormat(__data.File)
|
||||||
End If
|
End If
|
||||||
If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg
|
If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg
|
||||||
If IsUrl Then
|
If IsUrl And Not __isGif Then
|
||||||
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5))
|
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
|
||||||
|
ElseIf IsUrl And __isGif Then
|
||||||
|
hash = ByteArrayToString(GetMD5FromBytes(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ErrMD5))
|
||||||
Else
|
Else
|
||||||
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
||||||
End If
|
End If
|
||||||
If hash.IsEmptyString And Not __isGif Then
|
If hash.IsEmptyString And Not __isGif Then
|
||||||
If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg
|
If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg
|
||||||
If IsUrl Then
|
If IsUrl Then
|
||||||
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5))
|
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL.IfNullOrEmpty(__data.URL_BASE), ErrMD5), ImgFormat, ErrMD5))
|
||||||
Else
|
Else
|
||||||
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
||||||
End If
|
End If
|
||||||
@@ -1186,7 +1221,9 @@ BlockNullPicture:
|
|||||||
_ForceSaveUserInfo = True
|
_ForceSaveUserInfo = True
|
||||||
If existingFiles.Count > 0 Then
|
If existingFiles.Count > 0 Then
|
||||||
Dim h$
|
Dim h$
|
||||||
|
ProgressPre.ChangeMax(existingFiles.Count)
|
||||||
For i = existingFiles.Count - 1 To 0 Step -1
|
For i = existingFiles.Count - 1 To 0 Step -1
|
||||||
|
ProgressPre.Perform()
|
||||||
h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False)
|
h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False)
|
||||||
If Not h.IsEmptyString Then
|
If Not h.IsEmptyString Then
|
||||||
If hashList.ContainsKey(h) Then
|
If hashList.ContainsKey(h) Then
|
||||||
@@ -1200,8 +1237,10 @@ BlockNullPicture:
|
|||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i = 0 To _ContentList.Count - 1
|
For i = 0 To _ContentList.Count - 1
|
||||||
data = _ContentList(i)
|
data = _ContentList(i)
|
||||||
|
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)
|
||||||
@@ -1215,8 +1254,10 @@ BlockNullPicture:
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
If existingFiles.Count > 0 Then
|
If existingFiles.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(existingFiles.Count)
|
||||||
For i = 0 To existingFiles.Count - 1
|
For i = 0 To existingFiles.Count - 1
|
||||||
f = existingFiles(i)
|
f = existingFiles(i)
|
||||||
|
ProgressPre.Perform()
|
||||||
data = New UserMedia(f.File) With {
|
data = New UserMedia(f.File) With {
|
||||||
.State = UStates.Downloaded,
|
.State = UStates.Downloaded,
|
||||||
.Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture),
|
.Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture),
|
||||||
@@ -1238,7 +1279,9 @@ BlockNullPicture:
|
|||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i = _TempMediaList.Count - 1 To 0 Step -1
|
For i = _TempMediaList.Count - 1 To 0 Step -1
|
||||||
|
ProgressPre.Perform()
|
||||||
If limit > 0 And itemsCount >= limit Then
|
If limit > 0 And itemsCount >= limit Then
|
||||||
_TempMediaList.RemoveAt(i)
|
_TempMediaList.RemoveAt(i)
|
||||||
Else
|
Else
|
||||||
@@ -1262,6 +1305,8 @@ BlockNullPicture:
|
|||||||
Catch iex As ArgumentOutOfRangeException When Disposed
|
Catch iex As ArgumentOutOfRangeException When Disposed
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, "ValidateMD5",, VALIDATE_MD5_ERROR)
|
ProcessException(ex, Token, "ValidateMD5",, VALIDATE_MD5_ERROR)
|
||||||
|
Finally
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -1310,6 +1355,16 @@ BlockNullPicture:
|
|||||||
Dim f As SFile
|
Dim f As SFile
|
||||||
Dim v As UserMedia
|
Dim v As UserMedia
|
||||||
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
|
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
|
||||||
|
Dim __deleteFile As Action(Of SFile, String) = Sub(ByVal FileToDelete As SFile, ByVal FileUrl As String)
|
||||||
|
Try
|
||||||
|
If FileToDelete.Exists Then FileToDelete.Delete(,, EDP.ThrowException)
|
||||||
|
Catch file_io_ex As IOException
|
||||||
|
MyMainLOG = "File download aborted. You should download the following file again." & vbCr &
|
||||||
|
$"File: {FileToDelete}{vbCr}URL: {FileUrl}"
|
||||||
|
Catch file_del_ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
Using w As New OptionalWebClient(Me)
|
Using w As New OptionalWebClient(Me)
|
||||||
If vsf Then CSFileP($"{MyDir}\Video\").Exists(SFO.Path)
|
If vsf Then CSFileP($"{MyDir}\Video\").Exists(SFO.Path)
|
||||||
@@ -1398,7 +1453,9 @@ BlockNullPicture:
|
|||||||
DownloadContentDefault_PostProcessing(v, f, Token)
|
DownloadContentDefault_PostProcessing(v, f, Token)
|
||||||
dCount += 1
|
dCount += 1
|
||||||
Catch woex As OperationCanceledException When Token.IsCancellationRequested
|
Catch woex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
If f.Exists Then f.Delete()
|
'TODELETE: UserDataBase.DownloadContentDefault: remove file when 'OperationCanceledException'
|
||||||
|
'If f.Exists Then f.Delete(,, EDP.SendToLog)
|
||||||
|
__deleteFile.Invoke(f, v.URL_BASE)
|
||||||
v.State = UStates.Missing
|
v.State = UStates.Missing
|
||||||
v.Attempts += 1
|
v.Attempts += 1
|
||||||
_ContentNew(i) = v
|
_ContentNew(i) = v
|
||||||
@@ -1434,13 +1491,11 @@ BlockNullPicture:
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Protected UseInternalM3U8Function As Boolean = False
|
Protected UseInternalM3U8Function As Boolean = False
|
||||||
Protected UseInternalM3U8Function_UseProgress As Boolean = False
|
|
||||||
Protected Overridable Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
Protected Overridable Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
||||||
ByVal Token As CancellationToken) As SFile
|
ByVal Token As CancellationToken) As SFile
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End Function
|
End Function
|
||||||
Protected UseInternalDownloadFileFunction As Boolean = False
|
Protected UseInternalDownloadFileFunction As Boolean = False
|
||||||
Protected UseInternalDownloadFileFunction_UseProgress As Boolean = False
|
|
||||||
Protected Overridable Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
Protected Overridable Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
||||||
ByVal Token As CancellationToken) As SFile
|
ByVal Token As CancellationToken) As SFile
|
||||||
Return Nothing
|
Return Nothing
|
||||||
@@ -1798,6 +1853,7 @@ BlockNullPicture:
|
|||||||
LatestData.Clear()
|
LatestData.Clear()
|
||||||
_TempMediaList.Clear()
|
_TempMediaList.Clear()
|
||||||
_TempPostsList.Clear()
|
_TempPostsList.Clear()
|
||||||
|
If Not ProgressPre Is Nothing Then ProgressPre.Reset() : ProgressPre.Dispose()
|
||||||
If Not Responser Is Nothing Then Responser.Dispose()
|
If Not Responser Is Nothing Then Responser.Dispose()
|
||||||
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
|
If Not BTT_CONTEXT_DOWN Is Nothing Then BTT_CONTEXT_DOWN.Dispose()
|
||||||
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
|
If Not BTT_CONTEXT_EDIT Is Nothing Then BTT_CONTEXT_EDIT.Dispose()
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ Namespace API.Instagram
|
|||||||
If Not token.IsEmptyString Then Destination.Headers.Add(SiteSettings.Header_CSRF_TOKEN, token)
|
If Not token.IsEmptyString Then Destination.Headers.Add(SiteSettings.Header_CSRF_TOKEN, token)
|
||||||
If Not isInternal Then
|
If Not isInternal Then
|
||||||
Destination.Cookies.Update(Source.Cookies, CookieKeeper.UpdateModes.ReplaceByNameAll, False, EDP.SendToLog)
|
Destination.Cookies.Update(Source.Cookies, CookieKeeper.UpdateModes.ReplaceByNameAll, False, EDP.SendToLog)
|
||||||
|
Destination.Cookies.Update(EDP.SendToLog)
|
||||||
Destination.SaveSettings()
|
Destination.SaveSettings()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -70,33 +70,54 @@ Namespace API.Instagram
|
|||||||
End Class
|
End Class
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Authorization properties"
|
#Region "Authorization properties"
|
||||||
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
|
|
||||||
Friend ReadOnly Property HashTagged As PropertyValue
|
|
||||||
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
|
|
||||||
Friend ReadOnly Property CSRF_TOKEN As PropertyValue
|
|
||||||
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3)>
|
|
||||||
Friend Property IG_APP_ID As PropertyValue
|
|
||||||
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True), ControlNumber(4)>
|
|
||||||
Friend Property IG_WWW_CLAIM As PropertyValue
|
|
||||||
Friend Overrides Function BaseAuthExists() As Boolean
|
|
||||||
Return Responser.CookiesExists And ACheck(IG_APP_ID.Value) And ACheck(CSRF_TOKEN.Value)
|
|
||||||
End Function
|
|
||||||
Private Const Header_IG_APP_ID As String = "x-ig-app-id"
|
Private Const Header_IG_APP_ID As String = "x-ig-app-id"
|
||||||
Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
|
Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
|
||||||
Friend Const Header_CSRF_TOKEN As String = "x-csrftoken"
|
Friend Const Header_CSRF_TOKEN As String = "x-csrftoken"
|
||||||
|
Private Const Header_ASBD_ID As String = "X-Asbd-Id"
|
||||||
|
Private ReadOnly Header_Browser As New HttpHeader("Sec-Ch-Ua", """Google Chrome"";v=""113"", ""Chromium"";v=""113"", ""Not-A.Brand"";v=""24""")
|
||||||
|
Private ReadOnly Header_BrowserExt As New HttpHeader("Sec-Ch-Ua-Full-Version-List", """Google Chrome"";v=""113.0.5672.127"", ""Chromium"";v=""113.0.5672.127"", ""Not-A.Brand"";v=""24.0.0.0""")
|
||||||
|
Private ReadOnly Header_Platform As New HttpHeader("Sec-Ch-Ua-Platform-Version", """10.0.0""")
|
||||||
|
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
|
||||||
|
Friend ReadOnly Property HashTagged As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
|
||||||
|
Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3)>
|
||||||
|
Friend Property HH_IG_APP_ID As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-asbd-id", IsAuth:=True, AllowNull:=True), ControlNumber(4)>
|
||||||
|
Friend Property HH_ASBD_ID As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True), ControlNumber(5)>
|
||||||
|
Friend Property HH_IG_WWW_CLAIM As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="sec-ch-ua", IsAuth:=True, AllowNull:=True), ControlNumber(6)>
|
||||||
|
Private Property HH_BROWSER As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", IsAuth:=True, AllowNull:=True), ControlNumber(7)>
|
||||||
|
Private Property HH_BROWSER_EXT As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", IsAuth:=True, AllowNull:=True), ControlNumber(8)>
|
||||||
|
Private Property HH_PLATFORM As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True), ControlNumber(9)>
|
||||||
|
Private Property HH_USER_AGENT As PropertyValue
|
||||||
|
Friend Overrides Function BaseAuthExists() As Boolean
|
||||||
|
Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value) And ACheck(HH_CSRF_TOKEN.Value)
|
||||||
|
End Function
|
||||||
Private _FieldsChangerSuspended As Boolean = False
|
Private _FieldsChangerSuspended As Boolean = False
|
||||||
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
||||||
If Not _FieldsChangerSuspended And Not PropName.IsEmptyString Then
|
If Not _FieldsChangerSuspended And Not PropName.IsEmptyString Then
|
||||||
Dim f$ = String.Empty
|
Dim f$ = String.Empty
|
||||||
|
Dim isUserAgent As Boolean = False
|
||||||
Select Case PropName
|
Select Case PropName
|
||||||
Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID
|
Case NameOf(HH_IG_APP_ID) : f = Header_IG_APP_ID
|
||||||
Case NameOf(IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM
|
Case NameOf(HH_ASBD_ID) : f = Header_ASBD_ID
|
||||||
Case NameOf(CSRF_TOKEN) : f = Header_CSRF_TOKEN
|
Case NameOf(HH_IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM
|
||||||
|
Case NameOf(HH_CSRF_TOKEN) : f = Header_CSRF_TOKEN
|
||||||
|
Case NameOf(HH_BROWSER) : f = Header_Browser.Name
|
||||||
|
Case NameOf(HH_BROWSER_EXT) : f = Header_BrowserExt.Name
|
||||||
|
Case NameOf(HH_PLATFORM) : f = Header_Platform.Name
|
||||||
|
Case NameOf(HH_USER_AGENT) : isUserAgent = True
|
||||||
End Select
|
End Select
|
||||||
If Not f.IsEmptyString Then
|
If Not f.IsEmptyString Then
|
||||||
Responser.Headers.Remove(f)
|
Responser.Headers.Remove(f)
|
||||||
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||||
Responser.SaveSettings()
|
ElseIf isUserAgent Then
|
||||||
|
Responser.UserAgent = CStr(Value)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
@@ -192,13 +213,53 @@ Namespace API.Instagram
|
|||||||
Dim app_id$ = String.Empty
|
Dim app_id$ = String.Empty
|
||||||
Dim www_claim$ = String.Empty
|
Dim www_claim$ = String.Empty
|
||||||
Dim token$ = String.Empty
|
Dim token$ = String.Empty
|
||||||
|
Dim asbd$ = String.Empty
|
||||||
|
Dim browser$ = String.Empty
|
||||||
|
Dim browserExt$ = String.Empty
|
||||||
|
Dim platform$ = String.Empty
|
||||||
|
Dim useragent$ = String.Empty
|
||||||
|
|
||||||
|
Dim __UpdateHeader As Action(Of HttpHeader, Boolean) = Sub(ByVal h As HttpHeader, ByVal UpdateValueIfEmpty As Boolean)
|
||||||
|
With Responser.Headers
|
||||||
|
Dim i% = .IndexOf(h)
|
||||||
|
Dim hh As HttpHeader
|
||||||
|
If i >= 0 Then
|
||||||
|
hh = .Item(i)
|
||||||
|
If hh.Value.IsEmptyString And UpdateValueIfEmpty Then hh.Value = h.Value
|
||||||
|
Else
|
||||||
|
hh = h
|
||||||
|
End If
|
||||||
|
.Add(hh)
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
|
||||||
With Responser
|
With Responser
|
||||||
If .Headers.Count > 0 Then
|
.Accept = "*/*"
|
||||||
token = .Headers.Value(Header_CSRF_TOKEN)
|
useragent = .UserAgent
|
||||||
app_id = .Headers.Value(Header_IG_APP_ID)
|
With .Headers
|
||||||
www_claim = .Headers.Value(Header_IG_WWW_CLAIM)
|
If .Count > 0 Then
|
||||||
|
token = .Value(Header_CSRF_TOKEN)
|
||||||
|
app_id = .Value(Header_IG_APP_ID)
|
||||||
|
www_claim = .Value(Header_IG_WWW_CLAIM)
|
||||||
|
asbd = .Value(Header_ASBD_ID)
|
||||||
|
browser = .Value(Header_Browser.Name)
|
||||||
|
browserExt = .Value(Header_BrowserExt.Name)
|
||||||
|
platform = .Value(Header_Platform.Name)
|
||||||
End If
|
End If
|
||||||
|
.Add("Dnt", 1)
|
||||||
|
__UpdateHeader(Header_Browser, browser.IsEmptyString)
|
||||||
|
browser = .Value(Header_Browser.Name)
|
||||||
|
__UpdateHeader(Header_BrowserExt, browserExt.IsEmptyString)
|
||||||
|
browserExt = .Value(Header_BrowserExt.Name)
|
||||||
|
.Add("Sec-Ch-Ua-Mobile", "?0")
|
||||||
|
.Add("Sec-Ch-Ua-Platform", """Windows""")
|
||||||
|
__UpdateHeader(Header_Platform, platform.IsEmptyString)
|
||||||
|
platform = .Value(Header_Platform.Name)
|
||||||
|
.Add("Sec-Fetch-Dest", "empty")
|
||||||
|
.Add("Sec-Fetch-Mode", "cors")
|
||||||
|
.Add("Sec-Fetch-Site", "same-origin")
|
||||||
|
.Add("X-Requested-With", "XMLHttpRequest")
|
||||||
|
End With
|
||||||
.CookiesExtractMode = Responser.CookiesExtractModes.Response
|
.CookiesExtractMode = Responser.CookiesExtractModes.Response
|
||||||
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll
|
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll
|
||||||
.CookiesExtractedAutoSave = False
|
.CookiesExtractedAutoSave = False
|
||||||
@@ -207,9 +268,14 @@ Namespace API.Instagram
|
|||||||
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
|
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
|
||||||
|
|
||||||
HashTagged = New PropertyValue(String.Empty, GetType(String))
|
HashTagged = New PropertyValue(String.Empty, GetType(String))
|
||||||
CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(CSRF_TOKEN), v))
|
HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v))
|
||||||
IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_APP_ID), v))
|
HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v))
|
||||||
IG_WWW_CLAIM = New PropertyValue(www_claim.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v))
|
HH_ASBD_ID = New PropertyValue(asbd, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_ASBD_ID), v))
|
||||||
|
HH_IG_WWW_CLAIM = New PropertyValue(www_claim.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_WWW_CLAIM), v))
|
||||||
|
HH_BROWSER = New PropertyValue(browser, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_BROWSER), v))
|
||||||
|
HH_BROWSER_EXT = New PropertyValue(browserExt, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_BROWSER_EXT), v))
|
||||||
|
HH_PLATFORM = New PropertyValue(platform, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_PLATFORM), v))
|
||||||
|
HH_USER_AGENT = New PropertyValue(useragent, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_USER_AGENT), v))
|
||||||
|
|
||||||
DownloadTimeline = New PropertyValue(True)
|
DownloadTimeline = New PropertyValue(True)
|
||||||
DownloadStories = New PropertyValue(True)
|
DownloadStories = New PropertyValue(True)
|
||||||
@@ -275,7 +341,7 @@ Namespace API.Instagram
|
|||||||
Private _NextTagged As Boolean = True
|
Private _NextTagged As Boolean = True
|
||||||
Friend Overrides Sub DownloadStarted(ByVal What As Download)
|
Friend Overrides Sub DownloadStarted(ByVal What As Download)
|
||||||
ActiveJobs += 1
|
ActiveJobs += 1
|
||||||
If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(IG_WWW_CLAIM.Value) Then IG_WWW_CLAIM.Value = "0"
|
If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0"
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
|
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
|
||||||
With DirectCast(User, UserData)
|
With DirectCast(User, UserData)
|
||||||
@@ -299,8 +365,8 @@ Namespace API.Instagram
|
|||||||
LastDownloadDate.Value = Now
|
LastDownloadDate.Value = Now
|
||||||
LastRequestsCount.Value = .RequestsCount
|
LastRequestsCount.Value = .RequestsCount
|
||||||
_FieldsChangerSuspended = True
|
_FieldsChangerSuspended = True
|
||||||
IG_WWW_CLAIM.Value = Responser.Headers.Value(Header_IG_WWW_CLAIM)
|
HH_IG_WWW_CLAIM.Value = Responser.Headers.Value(Header_IG_WWW_CLAIM)
|
||||||
CSRF_TOKEN.Value = Responser.Headers.Value(Header_CSRF_TOKEN)
|
HH_CSRF_TOKEN.Value = Responser.Headers.Value(Header_CSRF_TOKEN)
|
||||||
_FieldsChangerSuspended = False
|
_FieldsChangerSuspended = False
|
||||||
End With
|
End With
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -207,19 +207,21 @@ Namespace API.Instagram
|
|||||||
If dt.Invoke And Not LastCursor.IsEmptyString Then
|
If dt.Invoke And Not LastCursor.IsEmptyString Then
|
||||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||||
DownloadData(LastCursor, s, Token)
|
DownloadData(LastCursor, s, Token)
|
||||||
|
ProgressPre.Done()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If Not HasError Then FirstLoadingDone = True
|
If Not HasError Then FirstLoadingDone = True
|
||||||
End If
|
End If
|
||||||
If dt.Invoke And Not HasError Then
|
If dt.Invoke And Not HasError Then
|
||||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||||
DownloadData(String.Empty, s, Token)
|
DownloadData(String.Empty, s, Token)
|
||||||
|
ProgressPre.Done()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If Not HasError Then FirstLoadingDone = True
|
If Not HasError Then FirstLoadingDone = True
|
||||||
End If
|
End If
|
||||||
If FirstLoadingDone Then LastCursor = String.Empty
|
If FirstLoadingDone Then LastCursor = String.Empty
|
||||||
If Not IsSavedPosts AndAlso MySiteSettings.BaseAuthExists() Then
|
If Not IsSavedPosts AndAlso MySiteSettings.BaseAuthExists() Then
|
||||||
If CBool(MySiteSettings.DownloadStories.Value) And GetStories Then s = Sections.Stories : DownloadData(String.Empty, s, Token)
|
If CBool(MySiteSettings.DownloadStories.Value) And GetStories Then s = Sections.Stories : DownloadData(String.Empty, s, Token) : ProgressPre.Done()
|
||||||
If CBool(MySiteSettings.DownloadTagged.Value) And ACheck(MySiteSettings.HashTagged.Value) And GetTaggedData Then s = Sections.Tagged : DownloadData(String.Empty, s, Token)
|
If CBool(MySiteSettings.DownloadTagged.Value) And ACheck(MySiteSettings.HashTagged.Value) And GetTaggedData Then s = Sections.Tagged : DownloadData(String.Empty, s, Token) : ProgressPre.Done()
|
||||||
End If
|
End If
|
||||||
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
||||||
Catch eex As ExitException
|
Catch eex As ExitException
|
||||||
@@ -229,9 +231,24 @@ Namespace API.Instagram
|
|||||||
Finally
|
Finally
|
||||||
E560Thrown = False
|
E560Thrown = False
|
||||||
UpdateResponser()
|
UpdateResponser()
|
||||||
|
ValidateExtension()
|
||||||
If Not errorFound Then LoadSavePostsKV(False)
|
If Not errorFound Then LoadSavePostsKV(False)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub ValidateExtension()
|
||||||
|
Try
|
||||||
|
Const heic$ = "heic"
|
||||||
|
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(mm) mm.File.Extension = heic) Then
|
||||||
|
Dim m As UserMedia
|
||||||
|
For i% = 0 To _TempMediaList.Count - 1
|
||||||
|
m = _TempMediaList(i)
|
||||||
|
If m.Type = UTypes.Picture AndAlso Not m.File.Extension.IsEmptyString AndAlso m.File.Extension = heic Then _
|
||||||
|
m.File.Extension = "jpg" : _TempMediaList(i) = m
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
Private Sub UpdateResponser()
|
Private Sub UpdateResponser()
|
||||||
Try
|
Try
|
||||||
If _DownloadingInProgress AndAlso Not Responser Is Nothing AndAlso Not Responser.Disposed Then
|
If _DownloadingInProgress AndAlso Not Responser Is Nothing AndAlso Not Responser.Disposed Then
|
||||||
@@ -470,7 +487,9 @@ Namespace API.Instagram
|
|||||||
HasNextPage = False
|
HasNextPage = False
|
||||||
End If
|
End If
|
||||||
If If(.Item("edges")?.Count, 0) > 0 Then
|
If If(.Item("edges")?.Count, 0) > 0 Then
|
||||||
|
ProgressPre.ChangeMax(.Item("edges").Count)
|
||||||
For Each nn In .Item("edges")
|
For Each nn In .Item("edges")
|
||||||
|
ProgressPre.Perform()
|
||||||
PostIDKV = New PostKV(Section)
|
PostIDKV = New PostKV(Section)
|
||||||
If nn.Count > 0 AndAlso nn(0).Count > 0 Then
|
If nn.Count > 0 AndAlso nn(0).Count > 0 Then
|
||||||
With nn(0)
|
With nn(0)
|
||||||
@@ -527,6 +546,7 @@ Namespace API.Instagram
|
|||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
Dim dValue% = 1
|
Dim dValue% = 1
|
||||||
Dim _Index% = 0
|
Dim _Index% = 0
|
||||||
|
If PostsToReparse.Count > 0 Then ProgressPre.ChangeMax(PostsToReparse.Count)
|
||||||
Try
|
Try
|
||||||
Do While dValue = 1
|
Do While dValue = 1
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -538,7 +558,9 @@ Namespace API.Instagram
|
|||||||
Dim j As EContainer, jj As EContainer
|
Dim j As EContainer, jj As EContainer
|
||||||
If PostsToReparse.Count > 0 And _Index <= PostsToReparse.Count - 1 Then
|
If PostsToReparse.Count > 0 And _Index <= PostsToReparse.Count - 1 Then
|
||||||
Dim e As New ErrorsDescriber(EDP.ThrowException)
|
Dim e As New ErrorsDescriber(EDP.ThrowException)
|
||||||
|
If Index > 0 Then ProgressPre.ChangeMax(1)
|
||||||
For i% = _Index To PostsToReparse.Count - 1
|
For i% = _Index To PostsToReparse.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
_Index = i
|
_Index = i
|
||||||
URL = $"https://www.instagram.com/api/v1/media/{PostsToReparse(i).ID}/info/"
|
URL = $"https://www.instagram.com/api/v1/media/{PostsToReparse(i).ID}/info/"
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -611,7 +633,9 @@ Namespace API.Instagram
|
|||||||
Case Else : SpecFolder = String.Empty
|
Case Else : SpecFolder = String.Empty
|
||||||
End Select
|
End Select
|
||||||
End If
|
End If
|
||||||
|
ProgressPre.ChangeMax(Items.Count)
|
||||||
For Each nn In Items
|
For Each nn In Items
|
||||||
|
ProgressPre.Perform()
|
||||||
With nn
|
With nn
|
||||||
PostIDKV = New PostKV(.Value("code"), .Value("id"), Section)
|
PostIDKV = New PostKV(.Value("code"), .Value("id"), Section)
|
||||||
Pinned = .Contains("timeline_pinned_user_ids")
|
Pinned = .Contains("timeline_pinned_user_ids")
|
||||||
@@ -799,7 +823,9 @@ Namespace API.Instagram
|
|||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||||
If j.Contains("reels") Then
|
If j.Contains("reels") Then
|
||||||
|
ProgressPre.ChangeMax(j("reels").Count)
|
||||||
For Each jj In j("reels")
|
For Each jj In j("reels")
|
||||||
|
ProgressPre.Perform()
|
||||||
i += 1
|
i += 1
|
||||||
sFolder = jj.Value("title").StringRemoveWinForbiddenSymbols
|
sFolder = jj.Value("title").StringRemoveWinForbiddenSymbols
|
||||||
storyID = jj.Value("id").Replace("highlight:", String.Empty)
|
storyID = jj.Value("id").Replace("highlight:", String.Empty)
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ Namespace API.LPSG
|
|||||||
Dim r As Func(Of String, Integer, String)
|
Dim r As Func(Of String, Integer, String)
|
||||||
Dim indx% = 0
|
Dim indx% = 0
|
||||||
Dim ude As New ErrorsDescriber(EDP.ReturnValue)
|
Dim ude As New ErrorsDescriber(EDP.ReturnValue)
|
||||||
|
ProgressPre.ChangeMax(l.Count)
|
||||||
For Each url$ In l
|
For Each url$ In l
|
||||||
|
ProgressPre.Perform()
|
||||||
If Not url.IsEmptyString Then u = SymbolsConverter.Decode(url, {Converters.HTML, Converters.ASCII}, ude) Else u = String.Empty
|
If Not url.IsEmptyString Then u = SymbolsConverter.Decode(url, {Converters.HTML, Converters.ASCII}, ude) Else u = String.Empty
|
||||||
If Not u.IsEmptyString Then
|
If Not u.IsEmptyString Then
|
||||||
exists = Not IsEmptyString(RegexReplace(u, FileExistsRegEx))
|
exists = Not IsEmptyString(RegexReplace(u, FileExistsRegEx))
|
||||||
|
|||||||
@@ -124,6 +124,15 @@ Namespace API.Mastodon
|
|||||||
If _SiteEditorFormOpened Then
|
If _SiteEditorFormOpened Then
|
||||||
Dim tf$ = GifsSpecialFolder.Value
|
Dim tf$ = GifsSpecialFolder.Value
|
||||||
If Not tf.IsEmptyString Then tf = tf.StringTrim("\") : GifsSpecialFolder.Value = tf
|
If Not tf.IsEmptyString Then tf = tf.StringTrim("\") : GifsSpecialFolder.Value = tf
|
||||||
|
Dim md$ = AConvert(Of String)(MyDomain.Value, String.Empty)
|
||||||
|
If Not md.IsEmptyString AndAlso Not Domains.Domains.Contains(md) AndAlso Not Domains.DomainsTemp.Contains(md) Then
|
||||||
|
If Domains.Changed Then
|
||||||
|
Domains.DomainsTemp.Add(md)
|
||||||
|
Else
|
||||||
|
Domains.Domains.Add(md)
|
||||||
|
Domains.Save()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
MyBase.Update()
|
MyBase.Update()
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Imports PersonalUtilities.Functions.XML
|
|||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
|
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||||
Namespace API.Mastodon
|
Namespace API.Mastodon
|
||||||
Friend Class UserData : Inherits Twitter.UserData
|
Friend Class UserData : Inherits Twitter.UserData
|
||||||
#Region "XML names"
|
#Region "XML names"
|
||||||
@@ -120,7 +121,9 @@ Namespace API.Mastodon
|
|||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using j As EContainer = JsonDocument.Parse(r)
|
Using j As EContainer = JsonDocument.Parse(r)
|
||||||
If If(j?.Count, 0) > 0 Then
|
If If(j?.Count, 0) > 0 Then
|
||||||
|
ProgressPre.ChangeMax(j.Count)
|
||||||
For Each jj As EContainer In j
|
For Each jj As EContainer In j
|
||||||
|
ProgressPre.Perform()
|
||||||
With jj
|
With jj
|
||||||
If Not IsSavedPosts And POST.IsEmptyString And Not .Item("account") Is Nothing Then
|
If Not IsSavedPosts And POST.IsEmptyString And Not .Item("account") Is Nothing Then
|
||||||
With .Item("account")
|
With .Item("account")
|
||||||
@@ -134,12 +137,15 @@ Namespace API.Mastodon
|
|||||||
If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg"
|
If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg"
|
||||||
__imgFile.Path = MyFile.CutPath.Path
|
__imgFile.Path = MyFile.CutPath.Path
|
||||||
If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None)
|
If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None)
|
||||||
|
If __imgFile.Exists Then IconBannerDownloaded = True
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
If DownloadIconBanner Then
|
||||||
__getImage.Invoke(.Value("header").IfNullOrEmpty(.Value("header_static")))
|
__getImage.Invoke(.Value("header").IfNullOrEmpty(.Value("header_static")))
|
||||||
__getImage.Invoke(.Value("avatar").IfNullOrEmpty(.Value("avatar_static")))
|
__getImage.Invoke(.Value("avatar").IfNullOrEmpty(.Value("avatar_static")))
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
|
||||||
@@ -166,7 +172,7 @@ Namespace API.Mastodon
|
|||||||
If If(.Item("media_attachments")?.Count, 0) > 0 Then
|
If If(.Item("media_attachments")?.Count, 0) > 0 Then
|
||||||
s = .Item("media_attachments")
|
s = .Item("media_attachments")
|
||||||
Else
|
Else
|
||||||
s = .Item({"reblog", "account"}, "media_attachments")
|
s = .Item({"reblog"}, "media_attachments")
|
||||||
End If
|
End If
|
||||||
If s.ListExists Then
|
If s.ListExists Then
|
||||||
For Each ss In s : ObtainMedia(ss, PostID, PostDate) : Next
|
For Each ss In s : ObtainMedia(ss, PostID, PostDate) : Next
|
||||||
@@ -233,8 +239,44 @@ Namespace API.Mastodon
|
|||||||
Return $"https://{Domain}/api/v1/statuses/" & "{0}"
|
Return $"https://{Domain}/api/v1/statuses/" & "{0}"
|
||||||
End Function
|
End Function
|
||||||
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||||
SinglePostUrl = GetSinglePostPattern(MyCredentials.Domain)
|
Dim rList As New List(Of Integer)
|
||||||
MyBase.ReparseMissing(Token)
|
Dim URL$ = String.Empty
|
||||||
|
Try
|
||||||
|
If ContentMissingExists Then
|
||||||
|
Dim SinglePostUrl$ = GetSinglePostPattern(MyCredentials.Domain)
|
||||||
|
Dim m As UserMedia
|
||||||
|
Dim r$, PostDate$
|
||||||
|
Dim j As EContainer
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
|
For i% = 0 To _ContentList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
|
If _ContentList(i).State = UStates.Missing Then
|
||||||
|
m = _ContentList(i)
|
||||||
|
If Not m.Post.ID.IsEmptyString Then
|
||||||
|
ThrowAny(Token)
|
||||||
|
URL = String.Format(SinglePostUrl, m.Post.ID)
|
||||||
|
r = Responser.GetResponse(URL,, EDP.ReturnValue)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
j = JsonDocument.Parse(r)
|
||||||
|
If Not j Is Nothing Then
|
||||||
|
PostDate = String.Empty
|
||||||
|
If j.Contains("created_at") Then PostDate = j("created_at").Value Else PostDate = String.Empty
|
||||||
|
ObtainMedia(j, m.Post.ID, PostDate, UStates.Missing)
|
||||||
|
rList.Add(i)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Token, $"ReparseMissing error [{URL}]")
|
||||||
|
Finally
|
||||||
|
If rList.Count > 0 Then
|
||||||
|
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(i) : Next
|
||||||
|
rList.Clear()
|
||||||
|
End If
|
||||||
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "DownloadSingleObject"
|
#Region "DownloadSingleObject"
|
||||||
@@ -268,7 +310,7 @@ Namespace API.Mastodon
|
|||||||
If Responser.Status = Net.WebExceptionStatus.NameResolutionFailure Then
|
If Responser.Status = Net.WebExceptionStatus.NameResolutionFailure Then
|
||||||
MyMainLOG = $"User domain ({UserDomain}) not found: {ToStringForLog()}"
|
MyMainLOG = $"User domain ({UserDomain}) not found: {ToStringForLog()}"
|
||||||
Return 1
|
Return 1
|
||||||
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then
|
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Or Responser.StatusCode = Net.HttpStatusCode.Forbidden Then
|
||||||
UserExists = False
|
UserExists = False
|
||||||
Return 1
|
Return 1
|
||||||
ElseIf Responser.StatusCode = Net.HttpStatusCode.Unauthorized Then
|
ElseIf Responser.StatusCode = Net.HttpStatusCode.Unauthorized Then
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ Namespace API.Pinterest
|
|||||||
Return New UserData
|
Return New UserData
|
||||||
End Function
|
End Function
|
||||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||||
Return Settings.GalleryDLFile.Exists And (Not What = ISiteSettings.Download.SavedPosts OrElse
|
Return Settings.GalleryDLFile.Exists And (Not What = ISiteSettings.Download.SavedPosts OrElse ACheck(SavedPostsUserName.Value))
|
||||||
(Responser.CookiesExists And ACheck(SavedPostsUserName.Value)))
|
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "IsMyUser, IsMyImageVideo, GetUserUrl, GetUserPostUrl"
|
#Region "IsMyUser, IsMyImageVideo, GetUserUrl, GetUserPostUrl"
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ Namespace API.Pinterest
|
|||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||||
|
Finally
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -129,7 +131,9 @@ Namespace API.Pinterest
|
|||||||
Dim urls As List(Of String) = GetDataFromGalleryDL(URL, True)
|
Dim urls As List(Of String) = GetDataFromGalleryDL(URL, True)
|
||||||
If urls.ListExists Then urls.RemoveAll(Function(__url) Not __url.Contains("BoardsResource/get/"))
|
If urls.ListExists Then urls.RemoveAll(Function(__url) Not __url.Contains("BoardsResource/get/"))
|
||||||
If urls.ListExists Then
|
If urls.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(urls.Count)
|
||||||
For Each URL In urls
|
For Each URL In urls
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse(URL,, EDP.ReturnValue)
|
r = Responser.GetResponse(URL,, EDP.ReturnValue)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
@@ -176,14 +180,18 @@ Namespace API.Pinterest
|
|||||||
Dim l As List(Of String) = GetDataFromGalleryDL(Board.URL, False)
|
Dim l As List(Of String) = GetDataFromGalleryDL(Board.URL, False)
|
||||||
If l.ListExists Then l.RemoveAll(Function(ll) Not ll.Contains("BoardFeedResource/get/"))
|
If l.ListExists Then l.RemoveAll(Function(ll) Not ll.Contains("BoardFeedResource/get/"))
|
||||||
If l.ListExists Then
|
If l.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(l.Count)
|
||||||
For Each bUrl In l
|
For Each bUrl In l
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse(bUrl,, EDP.ReturnValue)
|
r = Responser.GetResponse(bUrl,, EDP.ReturnValue)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
j = JsonDocument.Parse(r, jErr)
|
j = JsonDocument.Parse(r, jErr)
|
||||||
If Not j Is Nothing Then
|
If Not j Is Nothing Then
|
||||||
If If(j(rootNode)?.Count, 0) > 0 Then
|
If If(j(rootNode)?.Count, 0) > 0 Then
|
||||||
|
ProgressPre.ChangeMax(j(rootNode).Count)
|
||||||
For Each jj In j(rootNode)
|
For Each jj In j(rootNode)
|
||||||
|
ProgressPre.Perform()
|
||||||
With jj
|
With jj
|
||||||
If .Contains("images") Then
|
If .Contains("images") Then
|
||||||
images = .Item("images").Select(imgSelector).ToList
|
images = .Item("images").Select(imgSelector).ToList
|
||||||
@@ -262,11 +270,11 @@ Namespace API.Pinterest
|
|||||||
If IsBoardsRequested Then
|
If IsBoardsRequested Then
|
||||||
If ErrorOutputData.Count > 0 Then
|
If ErrorOutputData.Count > 0 Then
|
||||||
If Await Task.Run(Of Boolean)(Function() ErrorOutputData.Exists(Function(ee) Not ee.IsEmptyString AndAlso
|
If Await Task.Run(Of Boolean)(Function() ErrorOutputData.Exists(Function(ee) Not ee.IsEmptyString AndAlso
|
||||||
ee.StartsWith(UrlTextStart))) Then Kill(EDP.None)
|
ee.StartsWith(UrlTextStart))) Then Kill()
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
|
If Await Task.Run(Of Boolean)(Function() Not Value.IsEmptyString AndAlso
|
||||||
Source._TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill(EDP.None)
|
Source._TempPostsList.Exists(Function(v) Value.Contains(v))) Then Kill()
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ Namespace API.PornHub
|
|||||||
Private ReadOnly UnicodeHexConverter As Func(Of String, String) = Function(Input) SymbolsConverter.UnicodeHex.Decode(Input, EDP.ReturnValue)
|
Private ReadOnly UnicodeHexConverter As Func(Of String, String) = Function(Input) SymbolsConverter.UnicodeHex.Decode(Input, EDP.ReturnValue)
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Declarations video"
|
#Region "Declarations video"
|
||||||
Friend ReadOnly RegexVideo_FlashVarsBlock As RParams = RParams.DM("(?<=flashvars_\['[nN]ext[vV]ideo'\];[\r\n]*?)(.+?)(?=;flashvars_\d+?)", 0, EDP.ReturnValue)
|
Friend ReadOnly RegexVideo_FlashVarsBlocks As RParams = RParams.DM("(?<=(flashvars_\['[nN]ext[vV]ideo'\]|flashvars_\d+[^ ]+? = media_\d+?);[\r\n]*?)(.+?)(?=;flashvars_\d+?)",
|
||||||
|
0, RegexReturn.List, EDP.ReturnValue)
|
||||||
|
'TODELETE: PornHub old 'RegexVideo_FlashVarsBlock' declaration
|
||||||
|
'Friend ReadOnly RegexVideo_FlashVarsBlock As RParams = RParams.DM("(?<=flashvars_\['[nN]ext[vV]ideo'\];[\r\n]*?)(.+?)(?=;flashvars_\d+?)", 0, EDP.ReturnValue)
|
||||||
Friend ReadOnly RegexVideo_FlashVars_Vars As RParams = RParams.DM("var ([\w\d]{10,})=("".+?)(?=(;|\Z))", 0, RegexReturn.List)
|
Friend ReadOnly RegexVideo_FlashVars_Vars As RParams = RParams.DM("var ([\w\d]{10,})=("".+?)(?=(;|\Z))", 0, RegexReturn.List)
|
||||||
Friend ReadOnly RegexVideo_FlashVars_Compiler As RParams = RParams.DM("(?<=\*/)([\w\d\S]{10,})", 0, RegexReturn.List)
|
Friend ReadOnly RegexVideo_FlashVars_Compiler As RParams = RParams.DM("(?<=\*/)([\w\d\S]{10,})", 0, RegexReturn.List)
|
||||||
|
Friend ReadOnly RegexVideo_FlashVars_UrlResolution As RParams = RParams.DMS("/(\d+)[^/]+\.mp4", 1, EDP.ReturnValue)
|
||||||
Friend ReadOnly RegexVideo_Video_All As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""",
|
Friend ReadOnly RegexVideo_Video_All As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""",
|
||||||
0, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
|
0, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
|
||||||
Friend ReadOnly RegexVideo_Video_Wrong As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""[\w\W\s\r\n]+?(?=\<div class=""videoUploaderBlock)",
|
Friend ReadOnly RegexVideo_Video_Wrong As RParams = RParams.DM("div class=""thumbnail-info-wrapper clearfix.+?[\r\n\s]*?\<span class=""title.+?[\r\n\s]*?\<a href=""([^""]+?)""[\s]+?title=""([^""]*?)""[\w\W\s\r\n]+?(?=\<div class=""videoUploaderBlock)",
|
||||||
@@ -26,6 +30,7 @@ Namespace API.PornHub
|
|||||||
Friend ReadOnly RegexVideoPageTitle As RParams = RParams.DMS("meta (property|name)=""[^:]+?:title"" content=""([^""]+)""", 2, EDP.ReturnValue)
|
Friend ReadOnly RegexVideoPageTitle As RParams = RParams.DMS("meta (property|name)=""[^:]+?:title"" content=""([^""]+)""", 2, EDP.ReturnValue)
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Declarations M3U8"
|
#Region "Declarations M3U8"
|
||||||
|
Friend ReadOnly Regex_M3U8_FilesList As RParams = RParams.DM("RESOLUTION=\d+x(\d+).*?[\r\n]*?(.+?m3u8.*)", 0, RegexReturn.List, EDP.ReturnValue)
|
||||||
Friend ReadOnly Regex_M3U8_FirstFileRegEx As RParams = RParams.DM(".+?m3u8.*", 0)
|
Friend ReadOnly Regex_M3U8_FirstFileRegEx As RParams = RParams.DM(".+?m3u8.*", 0)
|
||||||
Friend ReadOnly Regex_M3U8_FileUrl As RParams = RParams.DMS("((https://([^/]+)/.+?)([^/]+?m3u8))(.*)", 2, EDP.ReturnValue)
|
Friend ReadOnly Regex_M3U8_FileUrl As RParams = RParams.DMS("((https://([^/]+)/.+?)([^/]+?m3u8))(.*)", 2, EDP.ReturnValue)
|
||||||
#End Region
|
#End Region
|
||||||
|
|||||||
@@ -16,11 +16,19 @@ Namespace API.PornHub
|
|||||||
Friend NotInheritable Class M3U8
|
Friend NotInheritable Class M3U8
|
||||||
Private Sub New()
|
Private Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
Private Shared Function GetUrlsList(ByVal URL As String, ByVal Responser As Responser) As List(Of String)
|
Private Shared Function GetUrlsList(ByVal URL As String, ByVal Responser As Responser, ByVal DownloadUHD As Boolean) As List(Of String)
|
||||||
Dim appender$ = RegexReplace(URL, Regex_M3U8_FileUrl)
|
Dim appender$ = RegexReplace(URL, Regex_M3U8_FileUrl)
|
||||||
Dim r$ = Responser.GetResponse(URL)
|
Dim r$ = Responser.GetResponse(URL)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Dim file$ = RegexReplace(r, Regex_M3U8_FirstFileRegEx)
|
Dim files As List(Of Sizes) = RegexFields(Of Sizes)(r, {Regex_M3U8_FilesList}, {1, 2}, EDP.ReturnValue)
|
||||||
|
Dim file$
|
||||||
|
If files.ListExists Then files.RemoveAll(Function(f) f.Value = 0 Or (Not DownloadUHD And f.Value > 1080))
|
||||||
|
If files.ListExists Then
|
||||||
|
files.Sort()
|
||||||
|
file = files(0).Data
|
||||||
|
Else
|
||||||
|
file = RegexReplace(r, Regex_M3U8_FirstFileRegEx)
|
||||||
|
End If
|
||||||
If Not file.IsEmptyString Then
|
If Not file.IsEmptyString Then
|
||||||
Dim NewUrl$ = M3U8Base.CreateUrl(appender, file)
|
Dim NewUrl$ = M3U8Base.CreateUrl(appender, file)
|
||||||
If Not NewUrl.IsEmptyString Then
|
If Not NewUrl.IsEmptyString Then
|
||||||
@@ -37,9 +45,9 @@ Namespace API.PornHub
|
|||||||
End If
|
End If
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End Function
|
End Function
|
||||||
Friend Shared Function Download(ByVal URL As String, ByVal Responser As Responser, ByVal Destination As SFile,
|
Friend Shared Function Download(ByVal URL As String, ByVal Responser As Responser, ByVal Destination As SFile, ByVal DownloadUHD As Boolean,
|
||||||
ByVal Token As CancellationToken, ByVal Progress As MyProgress) As SFile
|
ByVal Token As CancellationToken, ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean) As SFile
|
||||||
Return M3U8Base.Download(GetUrlsList(URL, Responser), Destination, Responser, Token, Progress)
|
Return M3U8Base.Download(GetUrlsList(URL, Responser, DownloadUHD), Destination, Responser, Token, Progress, UsePreProgress)
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -25,6 +25,8 @@ Namespace API.PornHub
|
|||||||
Return My.Resources.SiteResources.PornHubPic_16
|
Return My.Resources.SiteResources.PornHubPic_16
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
|
||||||
|
Friend Property DownloadUHD As PropertyValue
|
||||||
<PropertyOption(ControlText:="Download GIF", ControlToolTip:="Default for new users", ThreeStates:=True), PXML>
|
<PropertyOption(ControlText:="Download GIF", ControlToolTip:="Default for new users", ThreeStates:=True), PXML>
|
||||||
Friend ReadOnly Property DownloadGifs As PropertyValue
|
Friend ReadOnly Property DownloadGifs As PropertyValue
|
||||||
<PropertyOption(ControlText:="Download GIFs as mp4", ControlToolTip:="Download gifs in 'mp4' format instead of native 'webm'"), PXML>
|
<PropertyOption(ControlText:="Download GIFs as mp4", ControlToolTip:="Download gifs in 'mp4' format instead of native 'webm'"), PXML>
|
||||||
@@ -41,6 +43,7 @@ Namespace API.PornHub
|
|||||||
MyBase.New("PornHub", "pornhub.com")
|
MyBase.New("PornHub", "pornhub.com")
|
||||||
With Responser : .CurlSslNoRevoke = True : .CurlInsecure = True : End With
|
With Responser : .CurlSslNoRevoke = True : .CurlInsecure = True : End With
|
||||||
|
|
||||||
|
DownloadUHD = New PropertyValue(False)
|
||||||
DownloadGifsAsMp4 = New PropertyValue(True)
|
DownloadGifsAsMp4 = New PropertyValue(True)
|
||||||
DownloadGifs = New PropertyValue(CInt(CheckState.Indeterminate), GetType(Integer))
|
DownloadGifs = New PropertyValue(CInt(CheckState.Indeterminate), GetType(Integer))
|
||||||
DownloadPhotoOnlyFromModelHub = New PropertyValue(True)
|
DownloadPhotoOnlyFromModelHub = New PropertyValue(True)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Namespace API.PornHub
|
|||||||
Private Const Name_NameTrue As String = "NameTrue"
|
Private Const Name_NameTrue As String = "NameTrue"
|
||||||
Private Const Name_VideoPageModel As String = "VideoPageModel"
|
Private Const Name_VideoPageModel As String = "VideoPageModel"
|
||||||
Private Const Name_PhotoPageModel As String = "PhotoPageModel"
|
Private Const Name_PhotoPageModel As String = "PhotoPageModel"
|
||||||
|
Private Const Name_DownloadUHD As String = "DownloadUHD"
|
||||||
Private Const Name_DownloadGifs As String = "DownloadGifs"
|
Private Const Name_DownloadGifs As String = "DownloadGifs"
|
||||||
Private Const Name_DownloadPhotoOnlyFromModelHub As String = "DownloadPhotoOnlyFromModelHub"
|
Private Const Name_DownloadPhotoOnlyFromModelHub As String = "DownloadPhotoOnlyFromModelHub"
|
||||||
#End Region
|
#End Region
|
||||||
@@ -112,6 +113,7 @@ Namespace API.PornHub
|
|||||||
#Region "Advanced fields"
|
#Region "Advanced fields"
|
||||||
Friend Property VideoPageModel As VideoPageModels = VideoPageModels.Undefined
|
Friend Property VideoPageModel As VideoPageModels = VideoPageModels.Undefined
|
||||||
Private Property PhotoPageModel As PhotoPageModels = PhotoPageModels.Undefined
|
Private Property PhotoPageModel As PhotoPageModels = PhotoPageModels.Undefined
|
||||||
|
Friend Property DownloadUHD As Boolean = False
|
||||||
Friend Property DownloadGifs As Boolean
|
Friend Property DownloadGifs As Boolean
|
||||||
Friend Property DownloadPhotoOnlyFromModelHub As Boolean = True
|
Friend Property DownloadPhotoOnlyFromModelHub As Boolean = True
|
||||||
#End Region
|
#End Region
|
||||||
@@ -122,6 +124,7 @@ Namespace API.PornHub
|
|||||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
||||||
With DirectCast(Obj, UserExchangeOptions)
|
With DirectCast(Obj, UserExchangeOptions)
|
||||||
|
DownloadUHD = .DownloadUHD
|
||||||
DownloadGifs = .DownloadGifs
|
DownloadGifs = .DownloadGifs
|
||||||
DownloadPhotoOnlyFromModelHub = .DownloadPhotoOnlyFromModelHub
|
DownloadPhotoOnlyFromModelHub = .DownloadPhotoOnlyFromModelHub
|
||||||
End With
|
End With
|
||||||
@@ -157,6 +160,7 @@ Namespace API.PornHub
|
|||||||
NameTrue = .Value(Name_NameTrue)
|
NameTrue = .Value(Name_NameTrue)
|
||||||
VideoPageModel = .Value(Name_VideoPageModel).FromXML(Of Integer)(VideoPageModels.Undefined)
|
VideoPageModel = .Value(Name_VideoPageModel).FromXML(Of Integer)(VideoPageModels.Undefined)
|
||||||
PhotoPageModel = .Value(Name_PhotoPageModel).FromXML(Of Integer)(PhotoPageModels.Undefined)
|
PhotoPageModel = .Value(Name_PhotoPageModel).FromXML(Of Integer)(PhotoPageModels.Undefined)
|
||||||
|
DownloadUHD = .Value(Name_DownloadUHD).FromXML(Of Boolean)(False)
|
||||||
DownloadGifs = .Value(Name_DownloadGifs).FromXML(Of Integer)(False)
|
DownloadGifs = .Value(Name_DownloadGifs).FromXML(Of Integer)(False)
|
||||||
DownloadPhotoOnlyFromModelHub = .Value(Name_DownloadPhotoOnlyFromModelHub).FromXML(Of Boolean)(True)
|
DownloadPhotoOnlyFromModelHub = .Value(Name_DownloadPhotoOnlyFromModelHub).FromXML(Of Boolean)(True)
|
||||||
SetNames.Invoke()
|
SetNames.Invoke()
|
||||||
@@ -166,6 +170,7 @@ Namespace API.PornHub
|
|||||||
.Add(Name_NameTrue, NameTrue)
|
.Add(Name_NameTrue, NameTrue)
|
||||||
.Add(Name_VideoPageModel, CInt(VideoPageModel))
|
.Add(Name_VideoPageModel, CInt(VideoPageModel))
|
||||||
.Add(Name_PhotoPageModel, CInt(PhotoPageModel))
|
.Add(Name_PhotoPageModel, CInt(PhotoPageModel))
|
||||||
|
.Add(Name_DownloadUHD, DownloadUHD.BoolToInteger)
|
||||||
.Add(Name_DownloadGifs, DownloadGifs.BoolToInteger)
|
.Add(Name_DownloadGifs, DownloadGifs.BoolToInteger)
|
||||||
.Add(Name_DownloadPhotoOnlyFromModelHub, DownloadPhotoOnlyFromModelHub.BoolToInteger)
|
.Add(Name_DownloadPhotoOnlyFromModelHub, DownloadPhotoOnlyFromModelHub.BoolToInteger)
|
||||||
End If
|
End If
|
||||||
@@ -224,6 +229,7 @@ Namespace API.PornHub
|
|||||||
Finally
|
Finally
|
||||||
Responser.Mode = Responser.Modes.Default
|
Responser.Mode = Responser.Modes.Default
|
||||||
Responser.Method = "GET"
|
Responser.Method = "GET"
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -246,6 +252,7 @@ Namespace API.PornHub
|
|||||||
Const VideoUrlPattern$ = "https://www.pornhub.com/{0}/{1}{2}{3}"
|
Const VideoUrlPattern$ = "https://www.pornhub.com/{0}/{1}{2}{3}"
|
||||||
Const HtmlPageNotFoundVideo$ = "<span>Error Page Not Found</span>"
|
Const HtmlPageNotFoundVideo$ = "<span>Error Page Not Found</span>"
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
|
ProgressPre.ChangeMax(1)
|
||||||
Try
|
Try
|
||||||
Dim p$
|
Dim p$
|
||||||
If PersonType = PersonTypeUser Then
|
If PersonType = PersonTypeUser Then
|
||||||
@@ -289,6 +296,8 @@ Namespace API.PornHub
|
|||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return ProcessException(ex, Token, $"videos downloading error [{URL}]")
|
Return ProcessException(ex, Token, $"videos downloading error [{URL}]")
|
||||||
|
Finally
|
||||||
|
ProgressPre.Perform()
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
@@ -306,11 +315,13 @@ Namespace API.PornHub
|
|||||||
Dim l3 As List(Of String) = Nothing
|
Dim l3 As List(Of String) = Nothing
|
||||||
If l.ListExists Then l2 = l.Select(Function(ll) $"gif/{ll.Arr(0).Replace("gif", String.Empty)}").ToList
|
If l.ListExists Then l2 = l.Select(Function(ll) $"gif/{ll.Arr(0).Replace("gif", String.Empty)}").ToList
|
||||||
If l2.ListExists Then
|
If l2.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(l2.Count)
|
||||||
For Each gif$ In l2
|
For Each gif$ In l2
|
||||||
If Not _TempPostsList.Contains(gif) Then
|
If Not _TempPostsList.Contains(gif) Then
|
||||||
_TempPostsList.Add(gif)
|
_TempPostsList.Add(gif)
|
||||||
URL = $"https://www.pornhub.com/{gif}"
|
URL = $"https://www.pornhub.com/{gif}"
|
||||||
m = New UserMedia(URL, UTypes.Video) With {.Post = gif, .SpecialFolder = "GIFs\"}
|
m = New UserMedia(URL, UTypes.Video) With {.Post = gif, .SpecialFolder = "GIFs\"}
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
Try
|
Try
|
||||||
r = Responser.GetResponse(URL)
|
r = Responser.GetResponse(URL)
|
||||||
@@ -385,8 +396,10 @@ Namespace API.PornHub
|
|||||||
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})
|
||||||
If l.ListExists Then l.RemoveAll(Function(ll) ll.Data.IsEmptyString)
|
If l.ListExists Then l.RemoveAll(Function(ll) ll.Data.IsEmptyString)
|
||||||
If l.ListExists Then
|
If l.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(l.Count)
|
||||||
Dim albumRegex As RParams = RParams.DMS("", 1, EDP.ReturnValue)
|
Dim albumRegex As RParams = RParams.DMS("", 1, EDP.ReturnValue)
|
||||||
For Each block As PhotoBlock In l
|
For Each block As PhotoBlock In l
|
||||||
|
ProgressPre.Perform()
|
||||||
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
||||||
albumRegex.Pattern = "<li id=""" & block.AlbumID & """ class=""modelBox"">[\r\n\s]*?<div class=""modelPhoto"">[\r\n\s]*?\<[^\>]*?alt=""([^""]*)"""
|
albumRegex.Pattern = "<li id=""" & block.AlbumID & """ class=""modelBox"">[\r\n\s]*?<div class=""modelPhoto"">[\r\n\s]*?\<[^\>]*?alt=""([^""]*)"""
|
||||||
albumName = StringTrim(RegexReplace(r, albumRegex))
|
albumName = StringTrim(RegexReplace(r, albumRegex))
|
||||||
@@ -421,7 +434,9 @@ Namespace API.PornHub
|
|||||||
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})
|
||||||
If l.ListExists Then l.RemoveAll(Function(ll) ll.AlbumID.IsEmptyString)
|
If l.ListExists Then l.RemoveAll(Function(ll) ll.AlbumID.IsEmptyString)
|
||||||
If l.ListExists Then
|
If l.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(l.Count)
|
||||||
For Each block As PhotoBlock In l
|
For Each block As PhotoBlock In l
|
||||||
|
ProgressPre.Perform()
|
||||||
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
||||||
albumName = block.Data
|
albumName = block.Data
|
||||||
If albumName.IsEmptyString Then
|
If albumName.IsEmptyString Then
|
||||||
@@ -449,7 +464,9 @@ Namespace API.PornHub
|
|||||||
Dim l As List(Of String) = RegexReplace(r, Regex_Photo_PornHub_AlbumPhotoArr)
|
Dim l As List(Of String) = RegexReplace(r, Regex_Photo_PornHub_AlbumPhotoArr)
|
||||||
If l.ListExists Then l.RemoveAll(Function(_url) _url.IsEmptyString)
|
If l.ListExists Then l.RemoveAll(Function(_url) _url.IsEmptyString)
|
||||||
If l.ListExists Then
|
If l.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(l.Count)
|
||||||
For Each url$ In l
|
For Each url$ In l
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
Try
|
Try
|
||||||
r = Responser.GetResponse(url)
|
r = Responser.GetResponse(url)
|
||||||
@@ -492,7 +509,9 @@ Namespace API.PornHub
|
|||||||
Dim lBefore% = l2.Count
|
Dim lBefore% = l2.Count
|
||||||
If _TempPostsList.Count > 0 Then l2.RemoveAll(Function(media) _TempPostsList.Contains(media.Post.ID))
|
If _TempPostsList.Count > 0 Then l2.RemoveAll(Function(media) _TempPostsList.Contains(media.Post.ID))
|
||||||
If l2.Count > 0 Then
|
If l2.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(l2.Count)
|
||||||
For i% = 0 To l2.Count - 1
|
For i% = 0 To l2.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
m = l2(i)
|
m = l2(i)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
Try
|
Try
|
||||||
@@ -537,7 +556,9 @@ Namespace API.PornHub
|
|||||||
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
||||||
Dim m As UserMedia
|
Dim m As UserMedia
|
||||||
Dim r$, NewUrl$, tmpName$
|
Dim r$, NewUrl$, tmpName$
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
||||||
|
ProgressPre.Perform()
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||||
m = _TempMediaList(i)
|
m = _TempMediaList(i)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -588,7 +609,9 @@ Namespace API.PornHub
|
|||||||
Dim m As UserMedia
|
Dim m As UserMedia
|
||||||
Dim r$
|
Dim r$
|
||||||
Dim eCurl As New ErrorsDescriber(EDP.ReturnValue)
|
Dim eCurl As New ErrorsDescriber(EDP.ReturnValue)
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i% = 0 To _ContentList.Count - 1
|
For i% = 0 To _ContentList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
m = _ContentList(i)
|
m = _ContentList(i)
|
||||||
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -619,31 +642,91 @@ Namespace API.PornHub
|
|||||||
DownloadContentDefault(Token)
|
DownloadContentDefault(Token)
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||||
Return M3U8.Download(URL, Responser, DestinationFile, Token, If(UseInternalM3U8Function_UseProgress, Progress, Nothing))
|
Return M3U8.Download(URL, Responser, DestinationFile, DownloadUHD, Token, Progress, Not IsSingleObjectDownload)
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "CreateVideoURL"
|
#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
|
Private Function CreateVideoURL(ByVal r As String) As String
|
||||||
Try
|
Try
|
||||||
Dim OutStr$ = String.Empty
|
Dim OutStr$ = String.Empty
|
||||||
If Not r.IsEmptyString Then
|
Dim OutList As New List(Of String)
|
||||||
Dim _VarBlock$ = RegexReplace(r, RegexVideo_FlashVarsBlock)
|
Dim tmpUrl$
|
||||||
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%
|
Dim i%
|
||||||
For Each var$ In compiler
|
If Not r.IsEmptyString Then
|
||||||
|
Dim _VarBlock$, var$, v$
|
||||||
|
Dim vars As List(Of FlashVar)
|
||||||
|
Dim compiler As List(Of String)
|
||||||
|
Dim _VarBlocks As List(Of String) = RegexReplace(r, RegexVideo_FlashVarsBlocks)
|
||||||
|
If _VarBlocks.ListExists Then
|
||||||
|
For Each _VarBlock In _VarBlocks
|
||||||
|
tmpUrl = String.Empty
|
||||||
|
vars = RegexFields(Of FlashVar)(_VarBlock, {RegexVideo_FlashVars_Vars}, {1, 2})
|
||||||
|
compiler = RegexReplace(_VarBlock, RegexVideo_FlashVars_Compiler)
|
||||||
|
If vars.ListExists And compiler.ListExists Then
|
||||||
|
For Each var In compiler
|
||||||
i = vars.IndexOf(var)
|
i = vars.IndexOf(var)
|
||||||
If i >= 0 Then
|
If i >= 0 Then
|
||||||
v = vars(i).Value
|
v = vars(i).Value
|
||||||
If Not v.IsEmptyString Then OutStr &= v
|
If Not v.IsEmptyString Then tmpUrl &= v
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
|
vars.Clear()
|
||||||
|
compiler.Clear()
|
||||||
|
End If
|
||||||
|
If Not tmpUrl.IsEmptyString Then OutList.Add(tmpUrl)
|
||||||
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
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)
|
||||||
|
Else
|
||||||
|
Dim newUrls As New List(Of Sizes)
|
||||||
|
Dim tmpSize%?
|
||||||
|
For Each tmpUrl In OutList
|
||||||
|
tmpSize = AConvert(Of Integer)(RegexReplace(tmpUrl, RegexVideo_FlashVars_UrlResolution), AModes.Var, Nothing)
|
||||||
|
If tmpSize.HasValue Then newUrls.Add(New Sizes(tmpSize.Value, tmpUrl))
|
||||||
|
Next
|
||||||
|
If newUrls.Count > 0 Then
|
||||||
|
newUrls.Sort()
|
||||||
|
OutStr = newUrls(0).Data
|
||||||
|
newUrls.Clear()
|
||||||
|
Else
|
||||||
|
OutStr = OutList(0)
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
OutList.Clear()
|
||||||
Return OutStr
|
Return OutStr
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL]", String.Empty)
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL]", String.Empty)
|
||||||
|
|||||||
@@ -9,18 +9,22 @@
|
|||||||
Imports SCrawler.Plugin.Attributes
|
Imports SCrawler.Plugin.Attributes
|
||||||
Namespace API.PornHub
|
Namespace API.PornHub
|
||||||
Friend Class UserExchangeOptions
|
Friend Class UserExchangeOptions
|
||||||
|
<PSetting(NameOf(SiteSettings.DownloadUHD), NameOf(MySettings))>
|
||||||
|
Friend Property DownloadUHD As Boolean
|
||||||
<PSetting(Caption:="Download gifs")>
|
<PSetting(Caption:="Download gifs")>
|
||||||
Friend Property DownloadGifs As Boolean
|
Friend Property DownloadGifs As Boolean
|
||||||
<PSetting(NameOf(SiteSettings.DownloadPhotoOnlyFromModelHub), NameOf(MySettings), Caption:="Download photo only from ModelHub")>
|
<PSetting(NameOf(SiteSettings.DownloadPhotoOnlyFromModelHub), NameOf(MySettings), Caption:="Download photo only from ModelHub")>
|
||||||
Friend Property DownloadPhotoOnlyFromModelHub As Boolean
|
Friend Property DownloadPhotoOnlyFromModelHub As Boolean
|
||||||
Private ReadOnly Property MySettings As SiteSettings
|
Private ReadOnly Property MySettings As SiteSettings
|
||||||
Friend Sub New(ByVal u As UserData)
|
Friend Sub New(ByVal u As UserData)
|
||||||
|
DownloadUHD = u.DownloadUHD
|
||||||
DownloadGifs = u.DownloadGifs
|
DownloadGifs = u.DownloadGifs
|
||||||
DownloadPhotoOnlyFromModelHub = u.DownloadPhotoOnlyFromModelHub
|
DownloadPhotoOnlyFromModelHub = u.DownloadPhotoOnlyFromModelHub
|
||||||
MySettings = u.HOST.Source
|
MySettings = u.HOST.Source
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal s As SiteSettings)
|
Friend Sub New(ByVal s As SiteSettings)
|
||||||
Dim v As CheckState = CInt(s.DownloadGifs.Value)
|
Dim v As CheckState = CInt(s.DownloadGifs.Value)
|
||||||
|
DownloadUHD = s.DownloadUHD.Value
|
||||||
DownloadGifs = Not v = CheckState.Unchecked
|
DownloadGifs = Not v = CheckState.Unchecked
|
||||||
DownloadPhotoOnlyFromModelHub = s.DownloadPhotoOnlyFromModelHub.Value
|
DownloadPhotoOnlyFromModelHub = s.DownloadPhotoOnlyFromModelHub.Value
|
||||||
MySettings = s
|
MySettings = s
|
||||||
|
|||||||
@@ -59,8 +59,10 @@ Namespace API.Reddit
|
|||||||
Private ReadOnly CacheFiles As CacheKeeper
|
Private ReadOnly CacheFiles As CacheKeeper
|
||||||
Private ReadOnly Property Progress As MyProgress
|
Private ReadOnly Property Progress As MyProgress
|
||||||
Private ReadOnly ProgressExists As Boolean
|
Private ReadOnly ProgressExists As Boolean
|
||||||
|
Private ReadOnly Property ProgressPre As PreProgress
|
||||||
|
Private ReadOnly UsePreProgress As Boolean
|
||||||
#End Region
|
#End Region
|
||||||
Private Sub New(ByVal URL As String, ByVal OutFile As SFile, ByVal Progress As MyProgress)
|
Private Sub New(ByVal URL As String, ByVal OutFile As SFile, ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean)
|
||||||
PlayListURL = URL
|
PlayListURL = URL
|
||||||
BaseURL = RegexReplace(URL, BaseUrlPattern)
|
BaseURL = RegexReplace(URL, BaseUrlPattern)
|
||||||
Video = New List(Of String)
|
Video = New List(Of String)
|
||||||
@@ -70,6 +72,8 @@ Namespace API.Reddit
|
|||||||
Me.OutFile.Extension = "mp4"
|
Me.OutFile.Extension = "mp4"
|
||||||
Me.Progress = Progress
|
Me.Progress = Progress
|
||||||
ProgressExists = Not Me.Progress Is Nothing
|
ProgressExists = Not Me.Progress Is Nothing
|
||||||
|
ProgressPre = New PreProgress(Progress)
|
||||||
|
Me.UsePreProgress = UsePreProgress
|
||||||
Cache = New CacheKeeper($"{OutFile.PathWithSeparator}_{Base.M3U8Base.TempCacheFolderName}\")
|
Cache = New CacheKeeper($"{OutFile.PathWithSeparator}_{Base.M3U8Base.TempCacheFolderName}\")
|
||||||
CacheFiles = Cache.NewInstance
|
CacheFiles = Cache.NewInstance
|
||||||
End Sub
|
End Sub
|
||||||
@@ -142,12 +146,24 @@ Namespace API.Reddit
|
|||||||
If tmpCache.Validate Then
|
If tmpCache.Validate Then
|
||||||
Dim i%
|
Dim i%
|
||||||
Dim dFile As SFile = tmpCache.RootDirectory
|
Dim dFile As SFile = tmpCache.RootDirectory
|
||||||
If ProgressExists Then Progress.Maximum += Urls.Count
|
If ProgressExists Then
|
||||||
|
If UsePreProgress Then
|
||||||
|
ProgressPre.ChangeMax(Urls.Count)
|
||||||
|
Else
|
||||||
|
Progress.Maximum += Urls.Count
|
||||||
|
End If
|
||||||
|
End If
|
||||||
dFile.Extension = New SFile(Urls(0)).Extension
|
dFile.Extension = New SFile(Urls(0)).Extension
|
||||||
If dFile.Extension.IsEmptyString Then dFile.Extension = "ts"
|
If dFile.Extension.IsEmptyString Then dFile.Extension = "ts"
|
||||||
Using w As New WebClient
|
Using w As New WebClient
|
||||||
For i = 0 To Urls.Count - 1
|
For i = 0 To Urls.Count - 1
|
||||||
If ProgressExists Then Progress.Perform()
|
If ProgressExists Then
|
||||||
|
If UsePreProgress Then
|
||||||
|
ProgressPre.Perform()
|
||||||
|
Else
|
||||||
|
Progress.Perform()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
Token.ThrowIfCancellationRequested()
|
Token.ThrowIfCancellationRequested()
|
||||||
dFile.Name = $"ConPart_{i}"
|
dFile.Name = $"ConPart_{i}"
|
||||||
w.DownloadFile(Urls(i), dFile)
|
w.DownloadFile(Urls(i), dFile)
|
||||||
@@ -185,8 +201,9 @@ Namespace API.Reddit
|
|||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Statics"
|
#Region "Statics"
|
||||||
Friend Shared Function Download(ByVal URL As String, ByVal f As SFile, ByVal Token As CancellationToken, ByVal Progress As MyProgress) As SFile
|
Friend Shared Function Download(ByVal URL As String, ByVal f As SFile, ByVal Token As CancellationToken,
|
||||||
Using m As New M3U8(URL, f, Progress) : Return m.Download(Token) : End Using
|
ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean) As SFile
|
||||||
|
Using m As New M3U8(URL, f, Progress, UsePreProgress) : Return m.Download(Token) : End Using
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "IDisposable Support"
|
#Region "IDisposable Support"
|
||||||
@@ -197,6 +214,7 @@ Namespace API.Reddit
|
|||||||
Video.Clear()
|
Video.Clear()
|
||||||
Audio.Clear()
|
Audio.Clear()
|
||||||
Cache.Dispose()
|
Cache.Dispose()
|
||||||
|
ProgressPre.Dispose()
|
||||||
End If
|
End If
|
||||||
disposedValue = True
|
disposedValue = True
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Imports SCrawler.API.YouTube.Objects
|
|||||||
Imports SCrawler.Plugin.Hosts
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.ImageRenderer
|
||||||
Imports PersonalUtilities.Tools.Web.Clients
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||||
@@ -222,6 +223,7 @@ Namespace API.Reddit
|
|||||||
GetUserInfo()
|
GetUserInfo()
|
||||||
DownloadDataUser(String.Empty, Token)
|
DownloadDataUser(String.Empty, Token)
|
||||||
End If
|
End If
|
||||||
|
ProgressPre.Done()
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Download Functions (User, Channel)"
|
#Region "Download Functions (User, Channel)"
|
||||||
@@ -247,7 +249,6 @@ Namespace API.Reddit
|
|||||||
Dim ExistsDetected As Boolean = False
|
Dim ExistsDetected As Boolean = False
|
||||||
Dim IsCrossPost As Predicate(Of EContainer) = Function(e) Not e.Value(Node_CrosspostRootId).IsEmptyString Or Not e.Value(Node_CrosspostParentId).IsEmptyString Or Not e.Value(Node_CrosspostParent).IsEmptyString
|
Dim IsCrossPost As Predicate(Of EContainer) = Function(e) Not e.Value(Node_CrosspostRootId).IsEmptyString Or Not e.Value(Node_CrosspostParentId).IsEmptyString Or Not e.Value(Node_CrosspostParent).IsEmptyString
|
||||||
Dim CheckNode As Predicate(Of EContainer) = Function(e) Not ParseUserMediaOnly OrElse If(e("author")?.Value, "/").ToLower.Equals(TrueName.StringToLower)
|
Dim CheckNode As Predicate(Of EContainer) = Function(e) Not ParseUserMediaOnly OrElse If(e("author")?.Value, "/").ToLower.Equals(TrueName.StringToLower)
|
||||||
Dim UPicType As Func(Of String, UTypes) = Function(input) IIf(input = "image", UTypes.Picture, UTypes.GIF)
|
|
||||||
Dim _PostID As Func(Of String) = Function() PostTmp.IfNullOrEmpty(PostID)
|
Dim _PostID As Func(Of String) = Function() PostTmp.IfNullOrEmpty(PostID)
|
||||||
|
|
||||||
URL = $"https://gateway.reddit.com/desktopapi/v1/user/{TrueName}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
|
URL = $"https://gateway.reddit.com/desktopapi/v1/user/{TrueName}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
|
||||||
@@ -258,7 +259,9 @@ Namespace API.Reddit
|
|||||||
If w.Count > 0 Then
|
If w.Count > 0 Then
|
||||||
n = w.GetNode(JsonNodesJson)
|
n = w.GetNode(JsonNodesJson)
|
||||||
If Not n Is Nothing AndAlso n.Count > 0 Then
|
If Not n Is Nothing AndAlso n.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(n.Count)
|
||||||
For Each nn In n
|
For Each nn In n
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If nn.Count > 0 Then
|
If nn.Count > 0 Then
|
||||||
If CheckNode(nn) Then
|
If CheckNode(nn) Then
|
||||||
@@ -340,7 +343,9 @@ Namespace API.Reddit
|
|||||||
If w.Count > 0 Then
|
If w.Count > 0 Then
|
||||||
n = w.GetNode(ChannelJsonNodes)
|
n = w.GetNode(ChannelJsonNodes)
|
||||||
If Not n Is Nothing AndAlso n.Count > 0 Then
|
If Not n Is Nothing AndAlso n.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(n.Count)
|
||||||
For Each nn In n
|
For Each nn In n
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
s = nn.ItemF({eCount})
|
s = nn.ItemF({eCount})
|
||||||
If If(s?.Count, 0) > 0 Then
|
If If(s?.Count, 0) > 0 Then
|
||||||
@@ -422,11 +427,14 @@ Namespace API.Reddit
|
|||||||
If f.Extension.IsEmptyString Then f.Extension = "jpg"
|
If f.Extension.IsEmptyString Then f.Extension = "jpg"
|
||||||
f.Path = dir.Path
|
f.Path = dir.Path
|
||||||
If Not f.Exists Then GetWebFile(img, f, EDP.ReturnValue)
|
If Not f.Exists Then GetWebFile(img, f, EDP.ReturnValue)
|
||||||
|
If f.Exists Then IconBannerDownloaded = True
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
If DownloadIconBanner Then
|
||||||
__getFile.Invoke(.Value("icon_img"))
|
__getFile.Invoke(.Value("icon_img"))
|
||||||
__getFile.Invoke(.Value("banner_img"))
|
__getFile.Invoke(.Value("banner_img"))
|
||||||
|
End If
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
@@ -467,8 +475,40 @@ Namespace API.Reddit
|
|||||||
Select Case t
|
Select Case t
|
||||||
Case "gallery" : If DownloadGallery(.Self, PostID, PostDate) Then _TotalPostsDownloaded += 1 Else added = False
|
Case "gallery" : If DownloadGallery(.Self, PostID, PostDate) Then _TotalPostsDownloaded += 1 Else added = False
|
||||||
Case "image", "gifvideo"
|
Case "image", "gifvideo"
|
||||||
|
|
||||||
|
Dim resolution As Sizes = Nothing
|
||||||
|
Dim content As Sizes = Nothing
|
||||||
|
Dim chosenVal$ = String.Empty
|
||||||
|
ParseResolutions(e("media"), e("preview"), resolution)
|
||||||
If .Contains("content") Then
|
If .Contains("content") Then
|
||||||
_TempMediaList.ListAddValue(MediaFromData(UPicType(t), .Value("content"), PostID, PostDate, UserID), LNC)
|
content = CreateSize(.Self, "content")
|
||||||
|
If content.HasError Or content.Data.IsEmptyString Then content = Nothing
|
||||||
|
End If
|
||||||
|
|
||||||
|
If UPicType(t) = UTypes.Picture Then
|
||||||
|
If Not content.Data.IsEmptyString Then
|
||||||
|
If Not resolution.Data.IsEmptyString Then
|
||||||
|
If content.Value >= resolution.Value AndAlso TryImage(content.Data) Then
|
||||||
|
chosenVal = content.Data
|
||||||
|
Else
|
||||||
|
chosenVal = resolution.Data
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
chosenVal = content.Data
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
chosenVal = resolution.Data
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
If Not resolution.Data.IsEmptyString Then
|
||||||
|
chosenVal = resolution.Data
|
||||||
|
ElseIf Not content.Data.IsEmptyString Then
|
||||||
|
chosenVal = content.Data
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
If Not chosenVal.IsEmptyString Then
|
||||||
|
_TempMediaList.ListAddValue(MediaFromData(UPicType(t), chosenVal, PostID, PostDate, UserID), LNC)
|
||||||
_TotalPostsDownloaded += 1
|
_TotalPostsDownloaded += 1
|
||||||
Else
|
Else
|
||||||
added = False
|
added = False
|
||||||
@@ -512,6 +552,7 @@ Namespace API.Reddit
|
|||||||
added = ParseContainer(e.ItemF({"crosspost_parent_list", 0}), PostID, PostDate, UserID, True)
|
added = ParseContainer(e.ItemF({"crosspost_parent_list", 0}), PostID, PostDate, UserID, True)
|
||||||
Else
|
Else
|
||||||
Dim tPostId$ = e.Value(Node_CrosspostParent).IfNullOrEmpty(e.Value(Node_CrosspostParentId)).IfNullOrEmpty(e.Value(Node_CrosspostRootId))
|
Dim tPostId$ = e.Value(Node_CrosspostParent).IfNullOrEmpty(e.Value(Node_CrosspostParentId)).IfNullOrEmpty(e.Value(Node_CrosspostRootId))
|
||||||
|
If Not PostID.IsEmptyString Then
|
||||||
Dim r$ = Responser.GetResponse($"https://www.reddit.com/comments/{tPostId.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
Dim r$ = Responser.GetResponse($"https://www.reddit.com/comments/{tPostId.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||||
@@ -524,6 +565,7 @@ Namespace API.Reddit
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
If Not added Then
|
If Not added Then
|
||||||
Dim node As EContainer = e({"source", "url"})
|
Dim node As EContainer = e({"source", "url"})
|
||||||
Dim tmpType As UTypes = UTypes.Undefined
|
Dim tmpType As UTypes = UTypes.Undefined
|
||||||
@@ -557,6 +599,19 @@ Namespace API.Reddit
|
|||||||
Return False
|
Return False
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
Private Function TryImage(ByVal URL As String) As Boolean
|
||||||
|
Try
|
||||||
|
Dim img As Image = GetImage(SFile.GetBytesFromNet(URL, EDP.ThrowException), EDP.ThrowException)
|
||||||
|
If Not img Is Nothing Then
|
||||||
|
img.Dispose()
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
Catch
|
||||||
|
Return False
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Download Base Functions"
|
#Region "Download Base Functions"
|
||||||
Private Function CreateImgurMedia(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
Private Function CreateImgurMedia(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||||
@@ -640,26 +695,7 @@ Namespace API.Reddit
|
|||||||
If Not Node Is Nothing Then
|
If Not Node Is Nothing Then
|
||||||
Dim n As EContainer = Node.ItemF({"preview", "images", 0})
|
Dim n As EContainer = Node.ItemF({"preview", "images", 0})
|
||||||
Dim DestNode$() = Nothing
|
Dim DestNode$() = Nothing
|
||||||
If If(n?.Count, 0) > 0 Then
|
If If(n?.Count, 0) > 0 Then Return ParseResolutions(n)
|
||||||
If If(n("resolutions")?.Count, 0) > 0 Then
|
|
||||||
DestNode = {"resolutions"}
|
|
||||||
ElseIf If(n({"variants", "nsfw", "resolutions"})?.Count, 0) > 0 Then
|
|
||||||
DestNode = {"variants", "nsfw", "resolutions"}
|
|
||||||
End If
|
|
||||||
If Not DestNode Is Nothing Then
|
|
||||||
With n(DestNode)
|
|
||||||
Dim sl As List(Of Sizes) = .Select(Function(e) New Sizes(e.Value("width"), e.Value("url"))).
|
|
||||||
ListWithRemove(Function(ss) ss.HasError Or ss.Data.IsEmptyString)
|
|
||||||
If sl.ListExists Then
|
|
||||||
Dim s As Sizes
|
|
||||||
sl.Sort()
|
|
||||||
s = sl.First
|
|
||||||
sl.Clear()
|
|
||||||
Return s.Data
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
Return String.Empty
|
Return String.Empty
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
@@ -667,6 +703,46 @@ Namespace API.Reddit
|
|||||||
Return String.Empty
|
Return String.Empty
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
|
Private Function ParseResolutions(ByVal Node As EContainer, Optional ByVal PreviewNode As EContainer = Nothing,
|
||||||
|
Optional ByRef SResult As Sizes = Nothing) As String
|
||||||
|
Try
|
||||||
|
If If(Node?.Count, 0) > 0 Then
|
||||||
|
Dim DestNode$() = Nothing
|
||||||
|
If If(Node("resolutions")?.Count, 0) > 0 Then
|
||||||
|
DestNode = {"resolutions"}
|
||||||
|
ElseIf If(Node({"variants", "nsfw", "resolutions"})?.Count, 0) > 0 Then
|
||||||
|
DestNode = {"variants", "nsfw", "resolutions"}
|
||||||
|
End If
|
||||||
|
If Not DestNode Is Nothing Then
|
||||||
|
With Node(DestNode)
|
||||||
|
Dim sl As List(Of Sizes) = .Select(Function(e) CreateSize(e)).
|
||||||
|
ListWithRemove(Function(ss) ss.HasError Or ss.Data.IsEmptyString)
|
||||||
|
If If(PreviewNode?.Count, 0) > 0 Then
|
||||||
|
Dim sp As Sizes = CreateSize(PreviewNode)
|
||||||
|
If Not sp.HasError And Not sp.Data.IsEmptyString Then
|
||||||
|
If sl Is Nothing Then sl = New List(Of Sizes)
|
||||||
|
sl.Add(sp)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
If sl.ListExists Then
|
||||||
|
Dim s As Sizes
|
||||||
|
sl.Sort()
|
||||||
|
s = sl.First
|
||||||
|
sl.Clear()
|
||||||
|
SResult = s
|
||||||
|
Return s.Data
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return String.Empty
|
||||||
|
Catch ex As Exception
|
||||||
|
Return String.Empty
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Private Function CreateSize(ByVal Node As EContainer, Optional ByVal UrlNodeName As String = "url") As Sizes
|
||||||
|
Return New Sizes(Node.Value("width"), Node.Value(UrlNodeName))
|
||||||
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "ReparseVideo"
|
#Region "ReparseVideo"
|
||||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||||
@@ -681,8 +757,10 @@ Namespace API.Reddit
|
|||||||
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey)
|
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey)
|
||||||
Dim _repeatForRedgifs As Boolean
|
Dim _repeatForRedgifs As Boolean
|
||||||
RedGifsResponser = RedGifsHost.Responser.Copy
|
RedGifsResponser = RedGifsHost.Responser.Copy
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
ProgressPre.Perform()
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Or _TempMediaList(i).Type = v2 Then
|
If _TempMediaList(i).Type = UTypes.VideoPre Or _TempMediaList(i).Type = v2 Then
|
||||||
m = _TempMediaList(i)
|
m = _TempMediaList(i)
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||||
@@ -728,6 +806,7 @@ Namespace API.Reddit
|
|||||||
ProcessException(ex, Token, "video reparsing error", False)
|
ProcessException(ex, Token, "video reparsing error", False)
|
||||||
Finally
|
Finally
|
||||||
If Not RedGifsResponser Is Nothing Then RedGifsResponser.Dispose()
|
If Not RedGifsResponser Is Nothing Then RedGifsResponser.Dispose()
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -744,8 +823,10 @@ Namespace API.Reddit
|
|||||||
Dim r$
|
Dim r$
|
||||||
Dim j As EContainer
|
Dim j As EContainer
|
||||||
Dim lastCount%, li%
|
Dim lastCount%, li%
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i% = 0 To _ContentList.Count - 1
|
For i% = 0 To _ContentList.Count - 1
|
||||||
m = _ContentList(i)
|
m = _ContentList(i)
|
||||||
|
ProgressPre.Perform()
|
||||||
If m.State = UStates.Missing AndAlso Not m.Post.ID.IsEmptyString Then
|
If m.State = UStates.Missing AndAlso Not m.Post.ID.IsEmptyString Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse($"https://www.reddit.com/comments/{m.Post.ID.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
r = Responser.GetResponse($"https://www.reddit.com/comments/{m.Post.ID.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
||||||
@@ -781,6 +862,7 @@ Namespace API.Reddit
|
|||||||
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
|
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
|
||||||
rList.Clear()
|
rList.Clear()
|
||||||
End If
|
End If
|
||||||
|
ProgressPre.Done()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
@@ -804,17 +886,13 @@ Namespace API.Reddit
|
|||||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||||
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID, .UserID = _UserID}}
|
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID, .UserID = _UserID}}
|
||||||
If t = UTypes.Picture Or t = UTypes.GIF Then m.File = CreateFileFromUrl(m.URL) Else m.File = Nothing
|
If t = UTypes.Picture Or t = UTypes.GIF Then m.File = CreateFileFromUrl(m.URL) Else m.File = Nothing
|
||||||
If ReplacePreview And m.URL.Contains("preview") Then m.URL = $"https://i.redd.it/{m.File.File}"
|
If ReplacePreview And m.URL.Contains("preview") And Not t = UTypes.Picture Then m.URL = $"https://i.redd.it/{m.File.File}"
|
||||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateTrueProvider(IsChannel), Nothing) Else m.Post.Date = Nothing
|
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateTrueProvider(IsChannel), Nothing) Else m.Post.Date = Nothing
|
||||||
Return m
|
Return m
|
||||||
End Function
|
End Function
|
||||||
Private Function TryFile(ByVal URL As String) As Boolean
|
Private Function TryFile(ByVal URL As String) As Boolean
|
||||||
Try
|
Try
|
||||||
If Not URL.IsEmptyString AndAlso URL.StringContains({".jpg", ".png", ".jpeg"}) Then
|
Return Not URL.IsEmptyString AndAlso Not CreateFileFromUrl(URL).IsEmptyString
|
||||||
Return Not CreateFileFromUrl(URL).IsEmptyString
|
|
||||||
Else
|
|
||||||
Return False
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return False
|
Return False
|
||||||
End Try
|
End Try
|
||||||
@@ -861,7 +939,7 @@ Namespace API.Reddit
|
|||||||
Return URL.Contains(SiteRedGifsKey)
|
Return URL.Contains(SiteRedGifsKey)
|
||||||
End Function
|
End Function
|
||||||
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||||
Return M3U8.Download(URL, DestinationFile, Token, IIf(IsSingleObjectDownload, Progress, Nothing))
|
Return M3U8.Download(URL, DestinationFile, Token, Progress, Not IsSingleObjectDownload)
|
||||||
End Function
|
End Function
|
||||||
Protected Overrides Function ChangeFileNameByProvider(ByVal f As SFile, ByVal m As UserMedia) As SFile
|
Protected Overrides Function ChangeFileNameByProvider(ByVal f As SFile, ByVal m As UserMedia) As SFile
|
||||||
If Not IsChannel Or Not SaveToCache Then
|
If Not IsChannel Or Not SaveToCache Then
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ Namespace API.RedGifs
|
|||||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||||
If j.Contains("gifs") Then
|
If j.Contains("gifs") Then
|
||||||
pTotal = j.Value("pages").FromXML(Of Integer)(0)
|
pTotal = j.Value("pages").FromXML(Of Integer)(0)
|
||||||
|
ProgressPre.ChangeMax(j("gifs").Count)
|
||||||
For Each g As EContainer In j("gifs")
|
For Each g As EContainer In j("gifs")
|
||||||
|
ProgressPre.Perform()
|
||||||
postDate = g.Value("createDate")
|
postDate = g.Value("createDate")
|
||||||
Select Case CheckDatesLimit(postDate, UnixDate32Provider)
|
Select Case CheckDatesLimit(postDate, UnixDate32Provider)
|
||||||
Case DateResult.Skip : Continue For
|
Case DateResult.Skip : Continue For
|
||||||
@@ -102,11 +104,13 @@ Namespace API.RedGifs
|
|||||||
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||||
Dim rList As New List(Of Integer)
|
Dim rList As New List(Of Integer)
|
||||||
Try
|
Try
|
||||||
If _ContentList.Exists(MissingFinder) Then
|
If ContentMissingExists Then
|
||||||
Dim url$, r$
|
Dim url$, r$
|
||||||
Dim u As UserMedia
|
Dim u As UserMedia
|
||||||
Dim j As EContainer
|
Dim j As EContainer
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i% = 0 To _ContentList.Count - 1
|
For i% = 0 To _ContentList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
If _ContentList(i).State = UStates.Missing Then
|
If _ContentList(i).State = UStates.Missing Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
u = _ContentList(i)
|
u = _ContentList(i)
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ Namespace API.ThisVid
|
|||||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal IsPublic As Boolean, ByVal Token As CancellationToken)
|
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal IsPublic As Boolean, ByVal Token As CancellationToken)
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
Try
|
Try
|
||||||
|
ProgressPre.ChangeMax(1)
|
||||||
Dim p$ = IIf(Page = 1, String.Empty, $"{Page}/")
|
Dim p$ = IIf(Page = 1, String.Empty, $"{Page}/")
|
||||||
If IsSavedPosts Then
|
If IsSavedPosts Then
|
||||||
URL = $"https://thisvid.com/my_favourite_videos/{p}"
|
URL = $"https://thisvid.com/my_favourite_videos/{p}"
|
||||||
@@ -136,6 +137,7 @@ Namespace API.ThisVid
|
|||||||
URL = $"https://thisvid.com/members/{ID}/{IIf(IsPublic, "public", "private")}_videos/{p}"
|
URL = $"https://thisvid.com/members/{ID}/{IIf(IsPublic, "public", "private")}_videos/{p}"
|
||||||
End If
|
End If
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
ProgressPre.Perform()
|
||||||
Dim r$ = Responser.GetResponse(URL)
|
Dim r$ = Responser.GetResponse(URL)
|
||||||
Dim cBefore% = _TempMediaList.Count
|
Dim cBefore% = _TempMediaList.Count
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
@@ -182,7 +184,9 @@ Namespace API.ThisVid
|
|||||||
__continue = True
|
__continue = True
|
||||||
If albums.ListExists Then
|
If albums.ListExists Then
|
||||||
If albums.Count < 20 Then __continue = False
|
If albums.Count < 20 Then __continue = False
|
||||||
|
ProgressPre.ChangeMax(albums.Count)
|
||||||
For Each a As Album In albums
|
For Each a As Album In albums
|
||||||
|
ProgressPre.Perform()
|
||||||
If Not a.URL.IsEmptyString Then
|
If Not a.URL.IsEmptyString Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse(a.URL,, rErr)
|
r = Responser.GetResponse(a.URL,, rErr)
|
||||||
@@ -191,7 +195,9 @@ Namespace API.ThisVid
|
|||||||
If a.Title.IsEmptyString Then a.Title = albumId
|
If a.Title.IsEmptyString Then a.Title = albumId
|
||||||
images = RegexReplace(r, RegExAlbumImagesList)
|
images = RegexReplace(r, RegExAlbumImagesList)
|
||||||
If images.ListExists Then
|
If images.ListExists Then
|
||||||
|
ProgressPre.ChangeMax(images.Count)
|
||||||
For Each img In images
|
For Each img In images
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse(img,, rErr)
|
r = Responser.GetResponse(img,, rErr)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
@@ -242,7 +248,9 @@ Namespace API.ThisVid
|
|||||||
Dim cookieFile As SFile = DirectCast(HOST.Source, SiteSettings).CookiesNetscapeFile
|
Dim cookieFile As SFile = DirectCast(HOST.Source, SiteSettings).CookiesNetscapeFile
|
||||||
Dim command$
|
Dim command$
|
||||||
Dim e As EContainer
|
Dim e As EContainer
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
||||||
|
ProgressPre.Perform()
|
||||||
u = _TempMediaList(i)
|
u = _TempMediaList(i)
|
||||||
If u.Type = UserMedia.Types.VideoPre Then
|
If u.Type = UserMedia.Types.VideoPre Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ Namespace API.Twitter
|
|||||||
Friend Const TwitterSite As String = "Twitter"
|
Friend Const TwitterSite As String = "Twitter"
|
||||||
Friend Const TwitterSiteKey As String = "AndyProgram_Twitter"
|
Friend Const TwitterSiteKey As String = "AndyProgram_Twitter"
|
||||||
Friend ReadOnly DateProvider As ADateTime = GetDateProvider()
|
Friend ReadOnly DateProvider As ADateTime = GetDateProvider()
|
||||||
Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)}
|
|
||||||
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
|
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
|
||||||
Private Function GetDateProvider() As ADateTime
|
Private Function GetDateProvider() As ADateTime
|
||||||
Dim n As DateTimeFormatInfo = CultureInfo.GetCultureInfo("en-us").DateTimeFormat.Clone
|
Dim n As DateTimeFormatInfo = CultureInfo.GetCultureInfo("en-us").DateTimeFormat.Clone
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Imports SCrawler.Plugin.Attributes
|
|||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports PersonalUtilities.Tools.Web.Clients
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
Namespace API.Twitter
|
Namespace API.Twitter
|
||||||
<Manifest(TwitterSiteKey), SavedPosts, SpecialForm(False)>
|
<Manifest(TwitterSiteKey), SavedPosts, SeparatedTasks, SpecialForm(False)>
|
||||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||||
#Region "Token names"
|
#Region "Token names"
|
||||||
Friend Const Header_Authorization As String = "authorization"
|
Friend Const Header_Authorization As String = "authorization"
|
||||||
@@ -41,19 +41,20 @@ Namespace API.Twitter
|
|||||||
Return My.Resources.SiteResources.TwitterPic_400
|
Return My.Resources.SiteResources.TwitterPic_400
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
#Region "Auth"
|
'TODELETE: twitter headers
|
||||||
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Authorization",
|
'#Region "Auth"
|
||||||
ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
|
' <PropertyOption(AllowNull:=False, IsAuth:=False, ControlText:="Authorization",
|
||||||
Private ReadOnly Property Auth As PropertyValue
|
' ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
|
||||||
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
|
' Private ReadOnly Property Auth As PropertyValue
|
||||||
Private ReadOnly Property Token As PropertyValue
|
' <PropertyOption(AllowNull:=False, IsAuth:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
|
||||||
#End Region
|
' Private ReadOnly Property Token As PropertyValue
|
||||||
|
'#End Region
|
||||||
#Region "Other properties"
|
#Region "Other properties"
|
||||||
<PropertyOption(IsAuth:=False, ControlText:=GifsDownload_Text), PXML>
|
<PropertyOption(ControlText:=GifsDownload_Text), PXML>
|
||||||
Friend ReadOnly Property GifsDownload As PropertyValue
|
Friend ReadOnly Property GifsDownload As PropertyValue
|
||||||
<PropertyOption(IsAuth:=False, ControlText:=GifsSpecialFolder_Text, ControlToolTip:=GifsSpecialFolder_ToolTip), PXML>
|
<PropertyOption(ControlText:=GifsSpecialFolder_Text, ControlToolTip:=GifsSpecialFolder_ToolTip), PXML>
|
||||||
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
|
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
|
||||||
<PropertyOption(IsAuth:=False, ControlText:=GifsPrefix_Text, ControlToolTip:=GifsPrefix_ToolTip), PXML>
|
<PropertyOption(ControlText:=GifsPrefix_Text, ControlToolTip:=GifsPrefix_ToolTip), PXML>
|
||||||
Friend ReadOnly Property GifsPrefix As PropertyValue
|
Friend ReadOnly Property GifsPrefix As PropertyValue
|
||||||
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
|
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
|
||||||
Private ReadOnly Property GifStringChecker As IFormatProvider
|
Private ReadOnly Property GifStringChecker As IFormatProvider
|
||||||
@@ -75,68 +76,52 @@ Namespace API.Twitter
|
|||||||
Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]")
|
Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]")
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
<PropertyOption(IsAuth:=False, ControlText:=UseMD5Comparison_Text, ControlToolTip:=UseMD5Comparison_ToolTip), PXML>
|
<PropertyOption(ControlText:=UseMD5Comparison_Text, ControlToolTip:=UseMD5Comparison_ToolTip), PXML>
|
||||||
Friend ReadOnly Property UseMD5Comparison As PropertyValue
|
Friend ReadOnly Property UseMD5Comparison As PropertyValue
|
||||||
|
<PXML, PropertyOption(ControlText:="Concurrent downloads", ControlToolTip:="The number of concurrent downloads.", LeftOffset:=120), TaskCounter>
|
||||||
|
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
|
||||||
#End Region
|
#End Region
|
||||||
Friend Overrides ReadOnly Property Responser As Responser
|
'TODELETE: twitter headers
|
||||||
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
'Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
||||||
If Not PropName.IsEmptyString Then
|
' If Not PropName.IsEmptyString Then
|
||||||
Dim f$ = String.Empty
|
' Dim f$ = String.Empty
|
||||||
Select Case PropName
|
' Select Case PropName
|
||||||
Case NameOf(Auth) : f = Header_Authorization
|
' Case NameOf(Auth) : f = Header_Authorization
|
||||||
Case NameOf(Token) : f = Header_Token
|
' Case NameOf(Token) : f = Header_Token
|
||||||
End Select
|
' End Select
|
||||||
If Not f.IsEmptyString Then
|
' If Not f.IsEmptyString Then
|
||||||
Responser.Headers.Remove(f)
|
' Responser.Headers.Remove(f)
|
||||||
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
' If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||||
Responser.SaveSettings()
|
' Responser.SaveSettings()
|
||||||
End If
|
' End If
|
||||||
End If
|
' End If
|
||||||
End Sub
|
'End Sub
|
||||||
#End Region
|
#End Region
|
||||||
Friend Sub New()
|
Friend Sub New()
|
||||||
MyBase.New(TwitterSite)
|
MyBase.New(TwitterSite, "twitter.com")
|
||||||
Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml") With {.DeclaredError = EDP.ThrowException}
|
|
||||||
|
|
||||||
Dim a$ = String.Empty
|
'TODELETE: twitter headers
|
||||||
Dim t$ = String.Empty
|
'Dim a$ = String.Empty
|
||||||
|
'Dim t$ = String.Empty
|
||||||
|
|
||||||
With Responser
|
With Responser
|
||||||
If .File.Exists Then
|
'TODELETE: twitter headers
|
||||||
.CookiesDomain = "twitter.com"
|
'a = .Headers.Value(Header_Authorization)
|
||||||
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
't = .Headers.Value(Header_Token)
|
||||||
.LoadSettings()
|
|
||||||
a = .Headers.Value(Header_Authorization)
|
|
||||||
t = .Headers.Value(Header_Token)
|
|
||||||
Else
|
|
||||||
.ContentType = "application/json"
|
|
||||||
.Accept = "*/*"
|
|
||||||
.CookiesDomain = "twitter.com"
|
|
||||||
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
|
||||||
.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
|
||||||
.Headers.Add("sec-ch-ua", """Chromium"";v=""112"", ""Google Chrome"";v=""112"", ""Not:A-Brand"";v=""99""")
|
|
||||||
.Headers.Add("sec-ch-ua-mobile", "?0")
|
|
||||||
.Headers.Add("sec-fetch-dest", "empty")
|
|
||||||
.Headers.Add("sec-fetch-mode", "cors")
|
|
||||||
.Headers.Add("sec-fetch-site", "same-origin")
|
|
||||||
.Headers.Add(Header_Token, String.Empty)
|
|
||||||
.Headers.Add("x-twitter-active-user", "yes")
|
|
||||||
.Headers.Add("x-twitter-auth-type", "OAuth2Session")
|
|
||||||
.Headers.Add(Header_Authorization, String.Empty)
|
|
||||||
.SaveSettings()
|
|
||||||
End If
|
|
||||||
.Cookies.ChangedAllowInternalDrop = False
|
.Cookies.ChangedAllowInternalDrop = False
|
||||||
.Cookies.Changed = False
|
.Cookies.Changed = False
|
||||||
End With
|
End With
|
||||||
|
|
||||||
Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
|
'TODELETE: twitter headers
|
||||||
Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
|
'Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
|
||||||
|
'Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
|
||||||
|
|
||||||
GifsDownload = New PropertyValue(True)
|
GifsDownload = New PropertyValue(True)
|
||||||
GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
|
GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
|
||||||
GifsPrefix = New PropertyValue("GIF_")
|
GifsPrefix = New PropertyValue("GIF_")
|
||||||
GifStringChecker = New GifStringProvider
|
GifStringChecker = New GifStringProvider
|
||||||
UseMD5Comparison = New PropertyValue(False)
|
UseMD5Comparison = New PropertyValue(False)
|
||||||
|
ConcurrentDownloads = New PropertyValue(1)
|
||||||
|
|
||||||
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
|
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
|
||||||
UrlPatternUser = "https://twitter.com/{0}"
|
UrlPatternUser = "https://twitter.com/{0}"
|
||||||
@@ -151,18 +136,10 @@ Namespace API.Twitter
|
|||||||
Return $"https://twitter.com/{User.Name}/status/{Media.Post.ID}"
|
Return $"https://twitter.com/{User.Name}/status/{Media.Post.ID}"
|
||||||
End Function
|
End Function
|
||||||
Friend Overrides Function BaseAuthExists() As Boolean
|
Friend Overrides Function BaseAuthExists() As Boolean
|
||||||
Return Responser.CookiesExists And ACheck(Token.Value) And ACheck(Auth.Value)
|
Return Responser.CookiesExists
|
||||||
End Function
|
End Function
|
||||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||||
If MyBase.Available(What, Silent) Then
|
Return Settings.GalleryDLFile.Exists And BaseAuthExists()
|
||||||
If What = ISiteSettings.Download.SavedPosts Then
|
|
||||||
Return Settings.GalleryDLFile.Exists
|
|
||||||
Else
|
|
||||||
Return True
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
Return False
|
|
||||||
End If
|
|
||||||
End Function
|
End Function
|
||||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||||
If Options Is Nothing OrElse (Not TypeOf Options Is EditorExchangeOptions OrElse
|
If Options Is Nothing OrElse (Not TypeOf Options Is EditorExchangeOptions OrElse
|
||||||
|
|||||||
@@ -6,19 +6,17 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports System.Net
|
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports SCrawler.API.Base
|
Imports SCrawler.API.Base
|
||||||
Imports SCrawler.API.YouTube.Objects
|
Imports SCrawler.API.YouTube.Objects
|
||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports PersonalUtilities.Tools.Web.Clients
|
Imports PersonalUtilities.Tools
|
||||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
Namespace API.Twitter
|
Namespace API.Twitter
|
||||||
Friend Class UserData : Inherits UserDataBase
|
Friend Class UserData : Inherits UserDataBase
|
||||||
Protected SinglePostUrl As String = "https://api.twitter.com/1.1/statuses/show.json?id={0}&tweet_mode=extended"
|
|
||||||
#Region "XML names"
|
#Region "XML names"
|
||||||
Private Const Name_GifsDownload As String = "GifsDownload"
|
Private Const Name_GifsDownload As String = "GifsDownload"
|
||||||
Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
|
Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
|
||||||
@@ -29,6 +27,19 @@ Namespace API.Twitter
|
|||||||
Friend Property GifsSpecialFolder As String = String.Empty
|
Friend Property GifsSpecialFolder As String = String.Empty
|
||||||
Friend Property GifsPrefix As String = String.Empty
|
Friend Property GifsPrefix As String = String.Empty
|
||||||
Private ReadOnly _DataNames As List(Of String)
|
Private ReadOnly _DataNames As List(Of String)
|
||||||
|
Private ReadOnly Property MySettings As SiteSettings
|
||||||
|
Get
|
||||||
|
Return HOST.Source
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Private FileNameProvider As ANumbers = Nothing
|
||||||
|
Private Sub ResetFileNameProvider(Optional ByVal GroupSize As Integer? = Nothing)
|
||||||
|
FileNameProvider = New ANumbers With {.FormatOptions = ANumbers.Options.FormatNumberGroup + ANumbers.Options.Groups}
|
||||||
|
FileNameProvider.GroupSize = If(GroupSize, 3)
|
||||||
|
End Sub
|
||||||
|
Private Function RenameGdlFile(ByVal Input As SFile, ByVal i As Integer) As SFile
|
||||||
|
Return SFile.Rename(Input, $"{Input.PathWithSeparator}{i.NumToString(FileNameProvider)}.{Input.Extension}",, EDP.ThrowException)
|
||||||
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Exchange options"
|
#Region "Exchange options"
|
||||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||||
@@ -79,31 +90,108 @@ Namespace API.Twitter
|
|||||||
DownloadData_SavedPosts(Token)
|
DownloadData_SavedPosts(Token)
|
||||||
Else
|
Else
|
||||||
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||||
DownloadData(String.Empty, Token)
|
DownloadData_Timeline(Token)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken)
|
Private Sub DownloadData_Timeline(ByVal Token As CancellationToken)
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
|
Dim tCache As CacheKeeper = Nothing
|
||||||
Try
|
Try
|
||||||
|
Const entry$ = "entry"
|
||||||
Dim PostID$ = String.Empty
|
Dim PostID$ = String.Empty
|
||||||
Dim PostDate$
|
Dim PostDate$, tmpUserId$
|
||||||
Dim nn As EContainer
|
Dim i%
|
||||||
Dim NewPostDetected As Boolean = False
|
Dim dirIndx% = -1
|
||||||
Dim ExistsDetected As Boolean = False
|
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
|
||||||
|
Dim sourceIdPredicate As Predicate(Of EContainer) = Function(ee) ee.Name = "source_user_id_str" Or ee.Name = "source_user_id"
|
||||||
|
Dim p As Predicate(Of EContainer)
|
||||||
|
Dim pIndx%
|
||||||
|
Dim isOneNode As Boolean, isPins As Boolean, ExistsDetected As Boolean, userInfoParsed As Boolean = False
|
||||||
|
Dim j As EContainer, rootNode As EContainer, tmpNode As EContainer, nn As EContainer = Nothing
|
||||||
|
|
||||||
Dim UID As Func(Of EContainer, String) = Function(e) e.XmlIfNothing.Item({"user", "id"}).XmlIfNothingValue
|
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
|
||||||
|
End If
|
||||||
|
|
||||||
URL = $"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={Name}&count=200&exclude_replies=false&include_rts=1&tweet_mode=extended"
|
If Not nn.ListExists Then nn = ee({"content", "itemContent", "tweet_results", "result", "tweet", "legacy"})
|
||||||
If Not POST.IsEmptyString Then URL &= $"&max_id={POST}"
|
If nn.ListExists Then
|
||||||
|
PostID = nn.Value("id_str").IfNullOrEmpty(nn.Value("id"))
|
||||||
|
|
||||||
|
'Date Pattern:
|
||||||
|
'Sat Jan 01 01:10:15 +0000 2000
|
||||||
|
If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty
|
||||||
|
Select Case CheckDatesLimit(PostDate, Declarations.DateProvider)
|
||||||
|
Case DateResult.Skip, DateResult.Exit : Return False
|
||||||
|
End Select
|
||||||
|
|
||||||
|
If Not _TempPostsList.Contains(PostID) Then
|
||||||
|
_TempPostsList.Add(PostID)
|
||||||
|
ElseIf isPins Then
|
||||||
|
Return False
|
||||||
|
Else
|
||||||
|
ExistsDetected = True
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
|
||||||
|
tmpUserId = nn({"retweeted_status_result", "result", "legacy", "user_id_str"}).XmlIfNothingValue
|
||||||
|
|
||||||
|
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)
|
||||||
|
End If
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
|
||||||
|
tCache = New CacheKeeper($"{DownloadContentDefault_GetRootDir()}\_tCache\")
|
||||||
|
If tCache.RootDirectory.Exists(SFO.Path, False) Then tCache.RootDirectory.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.ReturnValue)
|
||||||
|
tCache.Validate()
|
||||||
|
|
||||||
|
Dim dirs As List(Of SFile) = GetTimelineFromGalleryDL(tCache, Token)
|
||||||
|
If dirs.ListExists Then
|
||||||
|
For Each dir As SFile In dirs
|
||||||
|
dirIndx += 1
|
||||||
|
|
||||||
|
ExistsDetected = False
|
||||||
|
|
||||||
|
If Not dir.IsEmptyString Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
Dim r$ = Responser.GetResponse(URL)
|
Dim timelineFiles As List(Of SFile) = SFile.GetFiles(dir, "*.txt",, EDP.ReturnValue)
|
||||||
If Not r.IsEmptyString Then
|
If timelineFiles.ListExists Then
|
||||||
Using w As EContainer = JsonDocument.Parse(r)
|
ResetFileNameProvider(Math.Max(timelineFiles.Count.ToString.Length, 2))
|
||||||
If w.ListExists Then
|
'rename files
|
||||||
|
For i = 0 To timelineFiles.Count - 1 : timelineFiles(i) = RenameGdlFile(timelineFiles(i), i) : Next
|
||||||
If POST.IsEmptyString And Not w.ItemF({0, "user"}) Is Nothing Then
|
'parse files
|
||||||
With w.ItemF({0, "user"})
|
For i = 0 To timelineFiles.Count - 1
|
||||||
|
j = JsonDocument.Parse(timelineFiles(i).GetText)
|
||||||
|
If Not j Is Nothing Then
|
||||||
|
If i = 0 Then
|
||||||
|
If Not userInfoParsed Then
|
||||||
|
userInfoParsed = True
|
||||||
|
Dim resValue$ = j.Value({"data", "user", "result"}, "__typename").StringTrim.StringToLower
|
||||||
|
If resValue.IsEmptyString Then
|
||||||
|
UserExists = False
|
||||||
|
j.Dispose()
|
||||||
|
Exit Sub
|
||||||
|
ElseIf resValue = "userunavailable" Then
|
||||||
|
UserSuspended = True
|
||||||
|
j.Dispose()
|
||||||
|
Exit Sub
|
||||||
|
Else
|
||||||
|
With j({"data", "user", "result"})
|
||||||
|
If .ListExists Then
|
||||||
|
If ID.IsEmptyString Then
|
||||||
|
ID = .Value("rest_id")
|
||||||
|
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
|
||||||
|
End If
|
||||||
|
With .Item({"legacy"})
|
||||||
|
If .ListExists Then
|
||||||
If .Value("screen_name").StringToLower = Name.ToLower Then
|
If .Value("screen_name").StringToLower = Name.ToLower Then
|
||||||
UserSiteNameUpdate(.Value("name"))
|
UserSiteNameUpdate(.Value("name"))
|
||||||
UserDescriptionUpdate(.Value("description"))
|
UserDescriptionUpdate(.Value("description"))
|
||||||
@@ -114,91 +202,104 @@ Namespace API.Twitter
|
|||||||
If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg"
|
If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg"
|
||||||
__imgFile.Path = MyFile.CutPath.Path
|
__imgFile.Path = MyFile.CutPath.Path
|
||||||
If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None)
|
If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None)
|
||||||
|
If __imgFile.Exists Then IconBannerDownloaded = True
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Dim icon$ = .Value("profile_image_url_https")
|
Dim icon$ = .Value("profile_image_url_https")
|
||||||
If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty)
|
If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty)
|
||||||
|
If DownloadIconBanner Then
|
||||||
__getImage.Invoke(.Value("profile_banner_url"))
|
__getImage.Invoke(.Value("profile_banner_url"))
|
||||||
__getImage.Invoke(icon)
|
__getImage.Invoke(icon)
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
For Each nn In If(IsSavedPosts, w({"globalObjects", "tweets"}).XmlIfNothing, w)
|
|
||||||
ThrowAny(Token)
|
|
||||||
If nn.Count > 0 Then
|
|
||||||
PostID = nn.Value("id")
|
|
||||||
If ID.IsEmptyString Then
|
|
||||||
ID = UID(nn)
|
|
||||||
If Not ID.IsEmptyString Then UpdateUserInformation()
|
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
'Date Pattern:
|
Else
|
||||||
'Sat Jan 01 01:10:15 +0000 2000
|
For pIndx = 0 To IIf(dirIndx < 2, 1, 0)
|
||||||
If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty
|
Select Case dirIndx
|
||||||
Select Case CheckDatesLimit(PostDate, Declarations.DateProvider)
|
Case 0, 1
|
||||||
Case DateResult.Skip : Continue For
|
rootNode = j({"data", "user", "result", "timeline_v2", "timeline", "instructions"})
|
||||||
Case DateResult.Exit : Exit Sub
|
If rootNode.ListExists Then
|
||||||
|
p = If(pIndx = 0, pinNode, timelineNode)
|
||||||
|
isPins = pIndx = 0
|
||||||
|
rootNode = rootNode.Find(p, False)
|
||||||
|
If rootNode.ListExists Then rootNode = rootNode.Find(entriesNode, False)
|
||||||
|
End If
|
||||||
|
Case Else
|
||||||
|
isPins = False
|
||||||
|
rootNode = j({"globalObjects", "tweets"})
|
||||||
End Select
|
End Select
|
||||||
|
|
||||||
If Not _TempPostsList.Contains(PostID) Then
|
If rootNode.ListExists Then
|
||||||
NewPostDetected = True
|
With rootNode
|
||||||
_TempPostsList.Add(PostID)
|
isOneNode = dirIndx < 2 AndAlso .Name = entry
|
||||||
|
ProgressPre.ChangeMax(If(isOneNode, 1, .Count))
|
||||||
|
If isOneNode Then
|
||||||
|
ProgressPre.Perform()
|
||||||
|
If Not __parseContainer(.Self) Then Exit For
|
||||||
Else
|
Else
|
||||||
ExistsDetected = True
|
For Each tmpNode In .Self
|
||||||
Continue For
|
ProgressPre.Perform()
|
||||||
|
If Not __parseContainer(tmpNode) Then Exit For
|
||||||
|
Next
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
|
||||||
If Not ParseUserMediaOnly OrElse
|
'TODO: Twitter: is this line needed?
|
||||||
(Not nn.Contains("retweeted_status") OrElse (Not ID.IsEmptyString AndAlso UID(nn("retweeted_status")) = ID)) Then _
|
If ExistsDetected And i = 1 Then Exit For Else ExistsDetected = False
|
||||||
ObtainMedia(nn, PostID, PostDate)
|
End If
|
||||||
|
j.Dispose()
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
timelineFiles.Clear()
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End Using
|
|
||||||
|
|
||||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
|
||||||
If Not PostID.IsEmptyString And NewPostDetected Then DownloadData(PostID, Token)
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||||
|
Finally
|
||||||
|
If Not tCache Is Nothing Then tCache.Dispose()
|
||||||
|
If _TempPostsList.Count > 0 Then _TempPostsList.Sort()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub DownloadData_SavedPosts(ByVal Token As CancellationToken)
|
Private Sub DownloadData_SavedPosts(ByVal Token As CancellationToken)
|
||||||
Try
|
Try
|
||||||
Dim urls As List(Of String) = GetBookmarksUrlsFromGalleryDL()
|
Dim f As SFile = GetDataFromGalleryDL("https://twitter.com/i/bookmarks", Settings.Cache, True, Token)
|
||||||
If urls.ListExists Then
|
Dim files As List(Of SFile) = SFile.GetFiles(f, "*.txt")
|
||||||
Dim postIds As New List(Of String)
|
If files.ListExists Then
|
||||||
Dim r$
|
ResetFileNameProvider(Math.Max(files.Count.ToString.Length, 3))
|
||||||
|
Dim id$
|
||||||
Dim j As EContainer, jj As EContainer
|
Dim j As EContainer, jj As EContainer
|
||||||
Dim jErr As New ErrorsDescriber(EDP.ReturnValue)
|
Dim jErr As New ErrorsDescriber(EDP.ReturnValue)
|
||||||
Dim rPattern As RParams = RParams.DM("(?<=tweet-)(\d+)\Z", 0, EDP.ReturnValue)
|
For i% = 0 To files.Count - 1
|
||||||
For Each url$ In urls
|
f = RenameGdlFile(files(i), i)
|
||||||
r = Responser.GetResponse(url)
|
j = JsonDocument.Parse(f.GetText, jErr)
|
||||||
If Not r.IsEmptyString Then
|
|
||||||
j = JsonDocument.Parse(r, jErr)
|
|
||||||
If Not j Is Nothing Then
|
If Not j Is Nothing Then
|
||||||
jj = j.ItemF({"data", "bookmark_timeline_v2", "timeline", "instructions", 0, "entries"})
|
With j.ItemF({"data", 0, "timeline", "instructions", 0, "entries"})
|
||||||
If If(jj?.Count, 0) > 0 Then postIds.ListAddList(jj.Select(Function(jj2) CStr(RegexReplace(jj2.Value("entryId"), rPattern))), LNC)
|
If .ListExists Then
|
||||||
j.Dispose()
|
ProgressPre.ChangeMax(.Count)
|
||||||
End If
|
For Each jj In .Self
|
||||||
End If
|
ProgressPre.Perform()
|
||||||
Next
|
With jj({"content", "itemContent", "tweet_results", "result", "legacy"})
|
||||||
If postIds.Count > 0 Then postIds.RemoveAll(Function(pid) pid.IsEmptyString OrElse (_TempPostsList.Contains(pid) Or _DataNames.Contains(pid)))
|
If .ListExists Then
|
||||||
If postIds.Count > 0 Then
|
id = .Value("id_str")
|
||||||
For Each __id$ In postIds
|
If _TempPostsList.Contains(id) Then j.Dispose() : Exit Sub Else ObtainMedia(.Self, id, .Value("created_at"))
|
||||||
_TempPostsList.Add(__id)
|
|
||||||
r = Responser.GetResponse(String.Format(SinglePostUrl, __id),, EDP.ReturnValue)
|
|
||||||
If Not r.IsEmptyString Then
|
|
||||||
j = JsonDocument.Parse(r, jErr)
|
|
||||||
If Not j Is Nothing Then
|
|
||||||
If j.Count > 0 Then ObtainMedia(j, __id, j.Value("created_at"))
|
|
||||||
j.Dispose()
|
|
||||||
End If
|
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
|
j.Dispose()
|
||||||
|
End If
|
||||||
|
Next
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, "data downloading error (Saved Posts)")
|
ProcessException(ex, Token, "data downloading error (Saved Posts)")
|
||||||
@@ -207,22 +308,25 @@ Namespace API.Twitter
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "Obtain media"
|
#Region "Obtain media"
|
||||||
Private Sub ObtainMedia(ByVal e As EContainer, ByVal PostID As String, ByVal PostDate As String, Optional ByVal State As UStates = UStates.Unknown)
|
Private Sub ObtainMedia(ByVal e As EContainer, ByVal PostID As String, ByVal PostDate As String, Optional ByVal State As UStates = UStates.Unknown)
|
||||||
If Not CheckVideoNode(e, PostID, PostDate, State) Then
|
Dim s As EContainer = e({"extended_entities", "media"})
|
||||||
Dim s As EContainer = e.ItemF({"extended_entities", "media"})
|
If If(s?.Count, 0) = 0 Then s = e({"retweeted_status", "extended_entities", "media"})
|
||||||
If s Is Nothing OrElse s.Count = 0 Then s = e.ItemF({"retweeted_status", "extended_entities", "media"})
|
If If(s?.Count, 0) = 0 Then s = e({"retweeted_status_result", "result", "legacy", "extended_entities", "media"})
|
||||||
|
|
||||||
If If(s?.Count, 0) > 0 Then
|
If If(s?.Count, 0) > 0 Then
|
||||||
For Each m In s
|
Dim mUrl$
|
||||||
If m.Contains("media_url") Then
|
For Each m As EContainer In s
|
||||||
Dim dName$ = UrlFile(m("media_url").Value)
|
If Not CheckVideoNode(m, PostID, PostDate, State) Then
|
||||||
|
mUrl = m.Value("media_url").IfNullOrEmpty(m.Value("media_url_https"))
|
||||||
|
If Not mUrl.IsEmptyString Then
|
||||||
|
Dim dName$ = UrlFile(mUrl)
|
||||||
If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then
|
If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then
|
||||||
_DataNames.Add(dName)
|
_DataNames.Add(dName)
|
||||||
_TempMediaList.ListAddValue(MediaFromData(m("media_url").Value,
|
_TempMediaList.ListAddValue(MediaFromData(mUrl, PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC)
|
||||||
PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC)
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String,
|
Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String,
|
||||||
Optional ByVal State As UStates = UStates.Unknown) As Boolean
|
Optional ByVal State As UStates = UStates.Unknown) As Boolean
|
||||||
@@ -252,9 +356,8 @@ Namespace API.Twitter
|
|||||||
Dim url$, ff$
|
Dim url$, ff$
|
||||||
Dim f As SFile
|
Dim f As SFile
|
||||||
Dim m As UserMedia
|
Dim m As UserMedia
|
||||||
With w({"extended_entities", "media"})
|
If w.ListExists Then
|
||||||
If .ListExists Then
|
For Each n As EContainer In w
|
||||||
For Each n As EContainer In .Self
|
|
||||||
If n.Value("type") = "animated_gif" Then
|
If n.Value("type") = "animated_gif" Then
|
||||||
With n({"video_info", "variants"})
|
With n({"video_info", "variants"})
|
||||||
If .ListExists Then
|
If .ListExists Then
|
||||||
@@ -279,7 +382,6 @@ Namespace API.Twitter
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End With
|
|
||||||
Return False
|
Return False
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LogError(ex, "[API.Twitter.UserData.CheckForGif]")
|
LogError(ex, "[API.Twitter.UserData.CheckForGif]")
|
||||||
@@ -287,63 +389,169 @@ Namespace API.Twitter
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Private Function GetVideoNodeURL(ByVal w As EContainer) As String
|
Private Function GetVideoNodeURL(ByVal w As EContainer) As String
|
||||||
Dim v As EContainer = w.GetNode(VideoNode)
|
With w({"video_info", "variants"})
|
||||||
If v.ListExists Then
|
If .ListExists Then
|
||||||
Dim l As New List(Of Sizes)
|
Dim l As New List(Of Sizes)
|
||||||
Dim u$
|
Dim u$
|
||||||
Dim nn As EContainer
|
For Each n As EContainer In .Self
|
||||||
For Each n As EContainer In v
|
|
||||||
If n.Count > 0 Then
|
If n.Count > 0 Then
|
||||||
For Each nn In n
|
If n("content_type").XmlIfNothingValue("none").Contains("mp4") AndAlso n.Contains("url") Then
|
||||||
If nn("content_type").XmlIfNothingValue("none").Contains("mp4") AndAlso nn.Contains("url") Then
|
u = n.Value("url")
|
||||||
u = nn.Value("url")
|
|
||||||
l.Add(New Sizes(RegexReplace(u, VideoSizeRegEx), u))
|
l.Add(New Sizes(RegexReplace(u, VideoSizeRegEx), u))
|
||||||
End If
|
End If
|
||||||
Next
|
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
If l.Count > 0 Then l.RemoveAll(Function(s) s.HasError)
|
If l.Count > 0 Then l.RemoveAll(Function(s) s.HasError)
|
||||||
If l.Count > 0 Then l.Sort() : Return l(0).Data
|
If l.Count > 0 Then l.Sort() : Return l(0).Data
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
Return String.Empty
|
Return String.Empty
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Gallery-DL Support"
|
#Region "Gallery-DL Support"
|
||||||
Private Function GetBookmarksUrlsFromGalleryDL() As List(Of String)
|
Private Class TwitterGDL : Inherits GDL.GDLBatch
|
||||||
Dim command$ = $"gallery-dl --verbose --simulate --cookies ""{DirectCast(HOST.Source, SiteSettings).CookiesNetscapeFile}"" https://twitter.com/i/bookmarks"
|
Private Property Token As CancellationToken
|
||||||
|
Friend Sub New(ByVal Dir As SFile, ByVal _Token As CancellationToken)
|
||||||
|
MyBase.New
|
||||||
|
Commands.Clear()
|
||||||
|
If Not Dir.IsEmptyString Then ChangeDirectory(Dir)
|
||||||
|
Token = _Token
|
||||||
|
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()
|
||||||
|
End Function
|
||||||
|
Private Function IdExists(ByVal Value As String) As Boolean
|
||||||
Try
|
Try
|
||||||
Using batch As New GDL.GDLBatch With {.TempPostsList = _TempPostsList} : Return GDL.GetUrlsFromGalleryDl(batch, command) : End Using
|
Value = Value.StringTrim
|
||||||
|
If Not Value.IsEmptyString AndAlso (Value.StartsWith("*") Or Value.StartsWith(".\gallery-dl\")) Then
|
||||||
|
Dim id$ = Value.Split("\").Last.Split(".").First.Split("_").First
|
||||||
|
If Not id.IsEmptyString Then Return TempPostsList.Contains(id)
|
||||||
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
HasError = True
|
|
||||||
LogError(ex, $"GetJson({command})")
|
|
||||||
Return Nothing
|
|
||||||
End Try
|
End Try
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
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 "
|
||||||
|
Try
|
||||||
|
Dim dir As SFile = Cache.NewPath
|
||||||
|
If dir.Exists(SFO.Path,, EDP.ThrowException) Then
|
||||||
|
Using batch As New TwitterGDL(dir, Token)
|
||||||
|
If UseTempPostList Then
|
||||||
|
batch.TempPostsList = _TempPostsList
|
||||||
|
command &= GdlGetIdFilterString()
|
||||||
|
End If
|
||||||
|
command &= URL
|
||||||
|
'#If DEBUG Then
|
||||||
|
'Debug.WriteLine(command)
|
||||||
|
'#End If
|
||||||
|
batch.Execute(command)
|
||||||
|
End Using
|
||||||
|
Return dir
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{ToStringForLog()}: GetDataFromGalleryDL({command})")
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Private Function GetTimelineFromGalleryDL(ByVal Cache As CacheKeeper, ByVal Token As CancellationToken) As List(Of SFile)
|
||||||
|
Dim command$ = String.Empty
|
||||||
|
Try
|
||||||
|
Dim conf As SFile = $"{Cache.NewPath.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 outList As New List(Of SFile)
|
||||||
|
Dim rootDir As CacheKeeper = Cache.NewInstance
|
||||||
|
Dim dir As SFile
|
||||||
|
|
||||||
|
Using tgdl As New TwitterGDL(Nothing, Token) With {.TempPostsList = _TempPostsList, .AutoClear = True, .AutoReset = True}
|
||||||
|
For i As Byte = 0 To 2
|
||||||
|
dir = rootDir.NewPath
|
||||||
|
dir.Exists(SFO.Path, True, EDP.ThrowException)
|
||||||
|
outList.Add(dir)
|
||||||
|
tgdl.ChangeDirectory(dir)
|
||||||
|
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"
|
||||||
|
Case 1 : command &= $"https://twitter.com/{Name}"
|
||||||
|
Case 2 : command &= $"https://twitter.com/search?q=from:{Name}+include:nativeretweets"
|
||||||
|
End Select
|
||||||
|
'#If DEBUG Then
|
||||||
|
'Debug.WriteLine(command)
|
||||||
|
'#End If
|
||||||
|
tgdl.Execute(command)
|
||||||
|
Next
|
||||||
|
End Using
|
||||||
|
|
||||||
|
Return outList
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{ToStringForLog()}: GetTimelineFromGalleryDL({command})")
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Private Function GdlGetIdFilterString() As String
|
||||||
|
Return If(_TempPostsList.Count > 0, $"--filter ""int(tweet_id) > {_TempPostsList.Last} or abort()"" ", String.Empty)
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "ReparseMissing"
|
#Region "ReparseMissing"
|
||||||
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||||
|
Const SinglePostPattern$ = "https://twitter.com/{0}/status/{1}"
|
||||||
Dim rList As New List(Of Integer)
|
Dim rList As New List(Of Integer)
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
|
Dim cache As CacheKeeper = Nothing
|
||||||
Try
|
Try
|
||||||
If ContentMissingExists Then
|
If ContentMissingExists Then
|
||||||
Dim m As UserMedia
|
Dim m As UserMedia
|
||||||
Dim r$, PostDate$
|
Dim PostDate$
|
||||||
Dim j As EContainer
|
Dim j As EContainer
|
||||||
For i% = 0 To _ContentList.Count - 1
|
Dim f As SFile
|
||||||
|
Dim i%, ii%
|
||||||
|
Dim files As List(Of SFile)
|
||||||
|
ResetFileNameProvider()
|
||||||
|
If IsSingleObjectDownload Then
|
||||||
|
cache = Settings.Cache
|
||||||
|
Else
|
||||||
|
cache = New CacheKeeper(DownloadContentDefault_GetRootDir.CSFilePS)
|
||||||
|
End If
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
|
For i = 0 To _ContentList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
If _ContentList(i).State = UStates.Missing Then
|
If _ContentList(i).State = UStates.Missing Then
|
||||||
m = _ContentList(i)
|
m = _ContentList(i)
|
||||||
If Not m.Post.ID.IsEmptyString Then
|
If Not m.Post.ID.IsEmptyString Or (IsSingleObjectDownload And Not m.URL_BASE.IsEmptyString) Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
URL = String.Format(SinglePostUrl, m.Post.ID)
|
If IsSingleObjectDownload Then
|
||||||
r = Responser.GetResponse(URL,, EDP.ReturnValue)
|
URL = m.URL_BASE
|
||||||
If Not r.IsEmptyString Then
|
Else
|
||||||
j = JsonDocument.Parse(r)
|
URL = String.Format(SinglePostPattern, Name, m.Post.ID)
|
||||||
|
End If
|
||||||
|
f = GetDataFromGalleryDL(URL, cache, Favorite, Token)
|
||||||
|
If Not f.IsEmptyString Then
|
||||||
|
files = SFile.GetFiles(f, "*.txt")
|
||||||
|
If files.ListExists Then
|
||||||
|
For ii = 0 To files.Count - 1
|
||||||
|
f = RenameGdlFile(files(ii), ii)
|
||||||
|
j = JsonDocument.Parse(f.GetText)
|
||||||
If Not j Is Nothing Then
|
If Not j Is Nothing Then
|
||||||
|
With j.ItemF({"data", 0, "instructions", 0, "entries", 0,
|
||||||
|
"content", "itemContent", "tweet_results", "result", "legacy"})
|
||||||
|
If .ListExists Then
|
||||||
PostDate = String.Empty
|
PostDate = String.Empty
|
||||||
If j.Contains("created_at") Then PostDate = j("created_at").Value Else PostDate = String.Empty
|
If .Contains("created_at") Then PostDate = .Value("created_at") Else PostDate = String.Empty
|
||||||
ObtainMedia(j, m.Post.ID, PostDate, UStates.Missing)
|
ObtainMedia(.Self, m.Post.ID, PostDate, UStates.Missing)
|
||||||
rList.Add(i)
|
rList.Add(i)
|
||||||
End If
|
End If
|
||||||
|
End With
|
||||||
|
j.Dispose()
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
files.Clear()
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -352,6 +560,7 @@ Namespace API.Twitter
|
|||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, $"ReparseMissing error [{URL}]")
|
ProcessException(ex, Token, $"ReparseMissing error [{URL}]")
|
||||||
Finally
|
Finally
|
||||||
|
If Not cache Is Nothing And Not IsSingleObjectDownload Then cache.Dispose()
|
||||||
If rList.Count > 0 Then
|
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(i) : Next
|
||||||
rList.Clear()
|
rList.Clear()
|
||||||
@@ -361,15 +570,8 @@ Namespace API.Twitter
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "DownloadSingleObject"
|
#Region "DownloadSingleObject"
|
||||||
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||||
Dim PostID$ = RegexReplace(Data.URL, RParams.DM("(?<=/)\d+", 0))
|
_ContentList.Add(New UserMedia(Data.URL) With {.State = UStates.Missing})
|
||||||
If Not PostID.IsEmptyString Then
|
ReparseMissing(Token)
|
||||||
Dim r$ = Responser.GetResponse(String.Format(SinglePostUrl, PostID),, EDP.ReturnValue)
|
|
||||||
If Not r.IsEmptyString Then
|
|
||||||
Using j As EContainer = JsonDocument.Parse(r)
|
|
||||||
If j.ListExists Then ObtainMedia(j, j.Value("id"), j.Value("created_at"))
|
|
||||||
End Using
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Picture options"
|
#Region "Picture options"
|
||||||
@@ -449,26 +651,7 @@ Namespace API.Twitter
|
|||||||
#Region "Exception"
|
#Region "Exception"
|
||||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
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
|
Optional ByVal EObj As Object = Nothing) As Integer
|
||||||
If AEquals(EObj, VALIDATE_MD5_ERROR) Then
|
|
||||||
If Not FromPE Then LogError(ex, Message)
|
|
||||||
Return 0
|
Return 0
|
||||||
Else
|
|
||||||
With Responser
|
|
||||||
If .StatusCode = HttpStatusCode.NotFound Then
|
|
||||||
UserExists = False
|
|
||||||
ElseIf .StatusCode = HttpStatusCode.Unauthorized Then
|
|
||||||
UserSuspended = True
|
|
||||||
ElseIf .StatusCode = HttpStatusCode.BadRequest Then
|
|
||||||
MyMainLOG = "Twitter has invalid credentials"
|
|
||||||
ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then
|
|
||||||
MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})"
|
|
||||||
Else
|
|
||||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
|
||||||
Return 0
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
End If
|
|
||||||
Return 1
|
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "IDisposable support"
|
#Region "IDisposable support"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Namespace API.XVIDEOS
|
|||||||
Private Sub New()
|
Private Sub New()
|
||||||
End Sub
|
End Sub
|
||||||
Friend Shared Function Download(ByVal URL As String, ByVal Appender As String, ByVal f As SFile,
|
Friend Shared Function Download(ByVal URL As String, ByVal Appender As String, ByVal f As SFile,
|
||||||
ByVal Token As CancellationToken, ByVal Progress As MyProgress) As SFile
|
ByVal Token As CancellationToken, ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean) As SFile
|
||||||
Try
|
Try
|
||||||
If Not URL.IsEmptyString Then
|
If Not URL.IsEmptyString Then
|
||||||
Using w As New WebClient
|
Using w As New WebClient
|
||||||
@@ -22,7 +22,7 @@ Namespace API.XVIDEOS
|
|||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Dim l As List(Of String) = ListAddList(Nothing, r.StringFormatLines.StringToList(Of String)(vbNewLine).ListWithRemove(Function(v) v.Trim.StartsWith("#")),
|
Dim l As List(Of String) = ListAddList(Nothing, r.StringFormatLines.StringToList(Of String)(vbNewLine).ListWithRemove(Function(v) v.Trim.StartsWith("#")),
|
||||||
New ListAddParams With {.Converter = Function(Input) $"{Appender}/{Input.ToString.Trim}"})
|
New ListAddParams With {.Converter = Function(Input) $"{Appender}/{Input.ToString.Trim}"})
|
||||||
If l.ListExists Then Return Base.M3U8Base.Download(l, f,, Token, Progress)
|
If l.ListExists Then Return Base.M3U8Base.Download(l, f,, Token, Progress, UsePreProgress)
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -91,8 +91,10 @@ Namespace API.XVIDEOS
|
|||||||
If .Contains("videos") Then
|
If .Contains("videos") Then
|
||||||
With .Item("videos")
|
With .Item("videos")
|
||||||
If .Count > 0 Then
|
If .Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(.Count)
|
||||||
NextPage += 1
|
NextPage += 1
|
||||||
For Each jj In .Self
|
For Each jj In .Self
|
||||||
|
ProgressPre.Perform()
|
||||||
p = New UserMedia With {
|
p = New UserMedia With {
|
||||||
.Post = jj.Value("id"),
|
.Post = jj.Value("id"),
|
||||||
.URL = $"https://www.xvideos.com/{jj.Value(n).StringTrimStart("/")}"
|
.URL = $"https://www.xvideos.com/{jj.Value(n).StringTrimStart("/")}"
|
||||||
@@ -123,7 +125,9 @@ Namespace API.XVIDEOS
|
|||||||
If Not j Is Nothing Then j.Dispose()
|
If Not j Is Nothing Then j.Dispose()
|
||||||
|
|
||||||
If _TempMediaList.Count > 0 Then
|
If _TempMediaList.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = 0 To _TempMediaList.Count - 1
|
For i% = 0 To _TempMediaList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
|
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
|
||||||
Next
|
Next
|
||||||
@@ -180,7 +184,9 @@ Namespace API.XVIDEOS
|
|||||||
Loop While NextPage < 100 And __continue
|
Loop While NextPage < 100 And __continue
|
||||||
|
|
||||||
If _TempMediaList.Count > 0 Then
|
If _TempMediaList.Count > 0 Then
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = 0 To _TempMediaList.Count - 1
|
For i% = 0 To _TempMediaList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
|
_TempMediaList(i) = GetVideoData(_TempMediaList(i))
|
||||||
Next
|
Next
|
||||||
@@ -244,7 +250,7 @@ Namespace API.XVIDEOS
|
|||||||
If Not m.URL.IsEmptyString Then _TempMediaList.Add(m)
|
If Not m.URL.IsEmptyString Then _TempMediaList.Add(m)
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||||
Return M3U8.Download(Media.URL, Media.PictureOption, DestinationFile, Token, If(UseInternalM3U8Function_UseProgress, Progress, Nothing))
|
Return M3U8.Download(Media.URL, Media.PictureOption, DestinationFile, Token, Progress, Not IsSingleObjectDownload)
|
||||||
End Function
|
End Function
|
||||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
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
|
Optional ByVal EObj As Object = Nothing) As Integer
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ Namespace API.Xhamster
|
|||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Friend Shared Function Download(ByVal Media As UserMedia, ByVal Responser As Responser, ByVal UHD As Boolean,
|
Friend Shared Function Download(ByVal Media As UserMedia, ByVal Responser As Responser, ByVal UHD As Boolean,
|
||||||
ByVal Token As CancellationToken, ByVal Progress As MyProgress) As SFile
|
ByVal Token As CancellationToken, ByVal Progress As MyProgress, ByVal UsePreProgress As Boolean) As SFile
|
||||||
Return M3U8Base.Download(ObtainUrls(Media.URL, Responser, UHD), Media.File, Responser, Token, Progress)
|
Return M3U8Base.Download(ObtainUrls(Media.URL, Responser, UHD), Media.File, Responser, Token, Progress, UsePreProgress)
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -112,7 +112,9 @@ Namespace API.Xhamster
|
|||||||
|
|
||||||
With j(listNode)
|
With j(listNode)
|
||||||
If .ListExists Then
|
If .ListExists Then
|
||||||
|
ProgressPre.ChangeMax(.Count)
|
||||||
For Each e As EContainer In .Self
|
For Each e As EContainer In .Self
|
||||||
|
ProgressPre.Perform()
|
||||||
m = ExtractMedia(e, Type)
|
m = ExtractMedia(e, Type)
|
||||||
If Not m.URL.IsEmptyString Then
|
If Not m.URL.IsEmptyString Then
|
||||||
If m.File.IsEmptyString Then Continue For
|
If m.File.IsEmptyString Then Continue For
|
||||||
@@ -160,7 +162,9 @@ Namespace API.Xhamster
|
|||||||
Try
|
Try
|
||||||
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
||||||
Dim m As UserMedia, m2 As UserMedia
|
Dim m As UserMedia, m2 As UserMedia
|
||||||
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
||||||
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
||||||
|
ProgressPre.Perform()
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||||
m = _TempMediaList(i)
|
m = _TempMediaList(i)
|
||||||
If Not m.URL_BASE.IsEmptyString Then
|
If Not m.URL_BASE.IsEmptyString Then
|
||||||
@@ -182,7 +186,8 @@ Namespace API.Xhamster
|
|||||||
End Sub
|
End Sub
|
||||||
Private Overloads Sub ReparsePhoto(ByVal Token As CancellationToken)
|
Private Overloads Sub ReparsePhoto(ByVal Token As CancellationToken)
|
||||||
If _TempPhotoData.Count > 0 Then
|
If _TempPhotoData.Count > 0 Then
|
||||||
For i% = 0 To _TempPhotoData.Count - 1 : ReparsePhoto(i, 1, Token) : Next
|
ProgressPre.ChangeMax(_TempPhotoData.Count)
|
||||||
|
For i% = 0 To _TempPhotoData.Count - 1 : ProgressPre.Perform() : ReparsePhoto(i, 1, Token) : Next
|
||||||
_TempPhotoData.Clear()
|
_TempPhotoData.Clear()
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
@@ -235,7 +240,9 @@ Namespace API.Xhamster
|
|||||||
Try
|
Try
|
||||||
If ContentMissingExists Then
|
If ContentMissingExists Then
|
||||||
Dim m As UserMedia, m2 As UserMedia
|
Dim m As UserMedia, m2 As UserMedia
|
||||||
|
ProgressPre.ChangeMax(_ContentList.Count)
|
||||||
For i% = 0 To _ContentList.Count - 1
|
For i% = 0 To _ContentList.Count - 1
|
||||||
|
ProgressPre.Perform()
|
||||||
m = _ContentList(i)
|
m = _ContentList(i)
|
||||||
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -297,7 +304,7 @@ Namespace API.Xhamster
|
|||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||||
Media.File = DestinationFile
|
Media.File = DestinationFile
|
||||||
Return M3U8.Download(Media, Responser, MySettings.DownloadUHD.Value, Token, If(UseInternalM3U8Function_UseProgress, Progress, Nothing))
|
Return M3U8.Download(Media, Responser, MySettings.DownloadUHD.Value, Token, Progress, Not IsSingleObjectDownload)
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Create media"
|
#Region "Create media"
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ Namespace API.YouTube
|
|||||||
#Region "Download"
|
#Region "Download"
|
||||||
'Playlist reconfiguration implemented only for channels + music
|
'Playlist reconfiguration implemented only for channels + music
|
||||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||||
|
Dim pr As New YTPreProgress(ProgressPre)
|
||||||
Try
|
Try
|
||||||
Dim container As IYouTubeMediaContainer = Nothing
|
Dim container As IYouTubeMediaContainer = Nothing
|
||||||
Dim list As New List(Of IYouTubeMediaContainer)
|
Dim list As New List(Of IYouTubeMediaContainer)
|
||||||
@@ -154,7 +155,7 @@ Namespace API.YouTube
|
|||||||
maxDate = Nothing
|
maxDate = Nothing
|
||||||
LastDownloadDatePlaylist = nDate(LastDownloadDatePlaylist)
|
LastDownloadDatePlaylist = nDate(LastDownloadDatePlaylist)
|
||||||
url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={ID}"
|
url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/playlist?list={ID}"
|
||||||
container = YouTubeFunctions.Parse(url, YTUseCookies, Token,, True, False,, LastDownloadDatePlaylist)
|
container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, True, False,, LastDownloadDatePlaylist)
|
||||||
applySpecFolder.Invoke(String.Empty, False)
|
applySpecFolder.Invoke(String.Empty, False)
|
||||||
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
||||||
ElseIf YTMediaType = YouTubeMediaType.Channel Then
|
ElseIf YTMediaType = YouTubeMediaType.Channel Then
|
||||||
@@ -162,7 +163,7 @@ Namespace API.YouTube
|
|||||||
maxDate = Nothing
|
maxDate = Nothing
|
||||||
LastDownloadDateVideos = nDate(LastDownloadDateVideos)
|
LastDownloadDateVideos = nDate(LastDownloadDateVideos)
|
||||||
url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/{IIf(IsMusic Or IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}"
|
url = $"https://{IIf(IsMusic, "music", "www")}.youtube.com/{IIf(IsMusic Or IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}"
|
||||||
container = YouTubeFunctions.Parse(url, YTUseCookies, Token,, True, False,, LastDownloadDateVideos)
|
container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, True, False,, LastDownloadDateVideos)
|
||||||
applySpecFolder.Invoke(IIf(IsMusic, String.Empty, "Videos"), False)
|
applySpecFolder.Invoke(IIf(IsMusic, String.Empty, "Videos"), False)
|
||||||
If fillList.Invoke(LastDownloadDateVideos) Then LastDownloadDateVideos = If(maxDate, Now)
|
If fillList.Invoke(LastDownloadDateVideos) Then LastDownloadDateVideos = If(maxDate, Now)
|
||||||
End If
|
End If
|
||||||
@@ -170,7 +171,7 @@ Namespace API.YouTube
|
|||||||
maxDate = Nothing
|
maxDate = Nothing
|
||||||
LastDownloadDateShorts = nDate(LastDownloadDateShorts)
|
LastDownloadDateShorts = nDate(LastDownloadDateShorts)
|
||||||
url = $"https://www.youtube.com/{IIf(IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}/shorts"
|
url = $"https://www.youtube.com/{IIf(IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}/shorts"
|
||||||
container = YouTubeFunctions.Parse(url, YTUseCookies, Token,, True, False,, LastDownloadDateShorts)
|
container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, True, False,, LastDownloadDateShorts)
|
||||||
applySpecFolder.Invoke("Shorts", False)
|
applySpecFolder.Invoke("Shorts", False)
|
||||||
If fillList.Invoke(LastDownloadDateShorts) Then LastDownloadDateShorts = If(maxDate, Now)
|
If fillList.Invoke(LastDownloadDateShorts) Then LastDownloadDateShorts = If(maxDate, Now)
|
||||||
End If
|
End If
|
||||||
@@ -178,7 +179,7 @@ Namespace API.YouTube
|
|||||||
maxDate = Nothing
|
maxDate = Nothing
|
||||||
LastDownloadDatePlaylist = nDate(LastDownloadDatePlaylist)
|
LastDownloadDatePlaylist = nDate(LastDownloadDatePlaylist)
|
||||||
url = $"https://www.youtube.com/{IIf(IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}/playlists"
|
url = $"https://www.youtube.com/{IIf(IsChannelUser, $"{YouTubeFunctions.UserChannelOption}/", "@")}{ID}/playlists"
|
||||||
container = YouTubeFunctions.Parse(url, YTUseCookies, Token,, True, False,, LastDownloadDatePlaylist)
|
container = YouTubeFunctions.Parse(url, YTUseCookies, Token, pr, True, False,, LastDownloadDatePlaylist)
|
||||||
applySpecFolder.Invoke("Playlists", True)
|
applySpecFolder.Invoke("Playlists", True)
|
||||||
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
||||||
End If
|
End If
|
||||||
@@ -196,6 +197,8 @@ Namespace API.YouTube
|
|||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, "data downloading error")
|
ProcessException(ex, Token, "data downloading error")
|
||||||
|
Finally
|
||||||
|
pr.Dispose()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||||
|
|||||||
38
SCrawler/API/YouTube/YTPreProgress.vb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
' 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 PersonalUtilities.Forms.Toolbars
|
||||||
|
Namespace API.YouTube
|
||||||
|
Friend Class YTPreProgress : Inherits MyProgress
|
||||||
|
Private ReadOnly AssocProgress As PreProgress
|
||||||
|
Friend Sub New(ByRef ExtProgress As PreProgress)
|
||||||
|
AssocProgress = ExtProgress
|
||||||
|
End Sub
|
||||||
|
Public Overrides Property Maximum As Double
|
||||||
|
Get
|
||||||
|
Return _Maximum
|
||||||
|
End Get
|
||||||
|
Set(ByVal Max As Double)
|
||||||
|
_Maximum = Max
|
||||||
|
AssocProgress.ChangeMax(Max, False)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Public Overrides Sub Perform(Optional ByVal Value As Double = 1)
|
||||||
|
AssocProgress.Perform(Value)
|
||||||
|
End Sub
|
||||||
|
Public Overrides Sub Done()
|
||||||
|
AssocProgress.Done()
|
||||||
|
End Sub
|
||||||
|
Public Overrides Property Visible(Optional ByVal ProgressBar As Boolean = True, Optional ByVal Label As Boolean = True) As Boolean
|
||||||
|
Get
|
||||||
|
Return True
|
||||||
|
End Get
|
||||||
|
Set : End Set
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -63,6 +63,7 @@ Namespace DownloadObjects
|
|||||||
.RowCount += 1
|
.RowCount += 1
|
||||||
JobsList.Add(New DownloadProgress(j))
|
JobsList.Add(New DownloadProgress(j))
|
||||||
AddHandler JobsList.Last.ProgressMaximumChanged, AddressOf Jobs_ProgressMaximumChanged
|
AddHandler JobsList.Last.ProgressMaximumChanged, AddressOf Jobs_ProgressMaximumChanged
|
||||||
|
AddHandler JobsList.Last.ProgressMaximum0Changed, AddressOf Jobs_ProgressMaximum0Changed
|
||||||
.Controls.Add(JobsList.Last.Get, 0, .RowStyles.Count - 1)
|
.Controls.Add(JobsList.Last.Get, 0, .RowStyles.Count - 1)
|
||||||
End With
|
End With
|
||||||
Next
|
Next
|
||||||
@@ -90,5 +91,9 @@ Namespace DownloadObjects
|
|||||||
If MainProgress.Value > 0 Then MainProgress.Perform()
|
If MainProgress.Value > 0 Then MainProgress.Perform()
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub Jobs_ProgressMaximum0Changed()
|
||||||
|
If JobsList.Count > 0 And Not DisableProgressChange Then _
|
||||||
|
MainProgress.Maximum0 = JobsList.Sum(Function(j) CLng(DirectCast(j.Job.Progress, MyProgressExt).Maximum0))
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -14,6 +14,7 @@ Namespace DownloadObjects
|
|||||||
#Region "Events"
|
#Region "Events"
|
||||||
Friend Event DownloadDone As NotificationEventHandler
|
Friend Event DownloadDone As NotificationEventHandler
|
||||||
Friend Event ProgressMaximumChanged()
|
Friend Event ProgressMaximumChanged()
|
||||||
|
Friend Event ProgressMaximum0Changed()
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
#Region "Controls"
|
#Region "Controls"
|
||||||
@@ -114,10 +115,12 @@ Namespace DownloadObjects
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
With Job
|
With Job
|
||||||
.Progress = New MyProgress(PR_MAIN, LBL_INFO) With {.ResetProgressOnMaximumChanges = False}
|
.Progress = New MyProgressExt(PR_MAIN, LBL_INFO) With {.ResetProgressOnMaximumChanges = False}
|
||||||
With .Progress
|
With DirectCast(.Progress, MyProgressExt)
|
||||||
AddHandler .ProgressChanged, AddressOf JobProgress_ProgressChanged
|
AddHandler .ProgressChanged, AddressOf JobProgress_ProgressChanged
|
||||||
AddHandler .MaximumChanged, AddressOf JobProgress_MaximumChanged
|
AddHandler .MaximumChanged, AddressOf JobProgress_MaximumChanged
|
||||||
|
AddHandler .Maximum0Changed, AddressOf JobProgress_Maximum0Changed
|
||||||
|
AddHandler .Progress0Changed, AddressOf JobProgress_Progress0Changed
|
||||||
End With
|
End With
|
||||||
End With
|
End With
|
||||||
|
|
||||||
@@ -183,8 +186,20 @@ Namespace DownloadObjects
|
|||||||
Private Sub JobProgress_MaximumChanged(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
Private Sub JobProgress_MaximumChanged(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
RaiseEvent ProgressMaximumChanged()
|
RaiseEvent ProgressMaximumChanged()
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub JobProgress_Maximum0Changed(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
|
RaiseEvent ProgressMaximum0Changed()
|
||||||
|
End Sub
|
||||||
Private Sub JobProgress_ProgressChanged(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
Private Sub JobProgress_ProgressChanged(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
If Not Job.Type = Download.SavedPosts Then MainProgress.Perform()
|
If Not Job.Type = Download.SavedPosts Then
|
||||||
|
MainProgress.Value = DirectCast(Sender, MyProgressExt).Value
|
||||||
|
MainProgress.Perform(0)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub JobProgress_Progress0Changed(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
|
If Not Job.Type = Download.SavedPosts Then
|
||||||
|
MainProgress.Value0 = DirectCast(Sender, MyProgressExt).Value0
|
||||||
|
MainProgress.Perform0(0)
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "IDisposable Support"
|
#Region "IDisposable Support"
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "VideoListForm.LoadData_GetFiles", New List(Of IYouTubeMediaContainer))
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "VideoListForm.LoadData_GetFiles", New List(Of IYouTubeMediaContainer))
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs)
|
Protected Overrides Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) Handles BTT_ADD_URLS_ARR.KeyClick
|
||||||
Dim __tag$ = UniversalFunctions.IfNullOrEmpty(Of Object)(Sender.Tag, String.Empty)
|
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 Then
|
||||||
MyBase.BTT_ADD_KeyClick(Sender, e)
|
MyBase.BTT_ADD_KeyClick(Sender, e)
|
||||||
@@ -51,6 +51,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Dim url$ = String.Empty
|
Dim url$ = String.Empty
|
||||||
Try
|
Try
|
||||||
url = BufferText
|
url = BufferText
|
||||||
|
Dim disableDown As Boolean = e.Shift
|
||||||
Dim output As SFile = Settings.LatestSavingPath
|
Dim output As SFile = Settings.LatestSavingPath
|
||||||
Dim isArr As Boolean = __tag = UrlsArrTag
|
Dim isArr As Boolean = __tag = UrlsArrTag
|
||||||
Dim formOpened As Boolean = False
|
Dim formOpened As Boolean = False
|
||||||
@@ -152,7 +153,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If media Is Nothing Then
|
If media Is Nothing Then
|
||||||
MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical)
|
MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical)
|
||||||
Else
|
Else
|
||||||
ControlCreateAndAdd(media)
|
ControlCreateAndAdd(media, disableDown)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
|||||||
111
SCrawler/Editors/GlobalSettingsForm.Designer.vb
generated
@@ -122,6 +122,8 @@ Namespace Editors
|
|||||||
Me.CH_NAME_SITE_FRIENDLY = New System.Windows.Forms.CheckBox()
|
Me.CH_NAME_SITE_FRIENDLY = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_STD = New System.Windows.Forms.CheckBox()
|
Me.CH_STD = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_STD_EVERY = New System.Windows.Forms.CheckBox()
|
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.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox()
|
Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox()
|
||||||
@@ -157,8 +159,7 @@ Namespace Editors
|
|||||||
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
|
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
|
||||||
Me.TAB_ENVIR = New System.Windows.Forms.TabPage()
|
Me.TAB_ENVIR = New System.Windows.Forms.TabPage()
|
||||||
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||||
Me.CH_STD_YT_LOAD = New System.Windows.Forms.CheckBox()
|
Me.CH_UICON_UP = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_STD_YT_REMOVE = New System.Windows.Forms.CheckBox()
|
|
||||||
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
|
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
|
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
|
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
|
||||||
@@ -508,13 +509,13 @@ Namespace Editors
|
|||||||
TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0)
|
TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0)
|
||||||
TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0)
|
TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0)
|
||||||
TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_FILE_NAME.Location = New System.Drawing.Point(1, 53)
|
TP_FILE_NAME.Location = New System.Drawing.Point(1, 79)
|
||||||
TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0)
|
TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0)
|
||||||
TP_FILE_NAME.Name = "TP_FILE_NAME"
|
TP_FILE_NAME.Name = "TP_FILE_NAME"
|
||||||
TP_FILE_NAME.RowCount = 1
|
TP_FILE_NAME.RowCount = 1
|
||||||
TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_FILE_NAME.Size = New System.Drawing.Size(574, 30)
|
TP_FILE_NAME.Size = New System.Drawing.Size(574, 30)
|
||||||
TP_FILE_NAME.TabIndex = 2
|
TP_FILE_NAME.TabIndex = 3
|
||||||
'
|
'
|
||||||
'OPT_FILE_NAME_REPLACE
|
'OPT_FILE_NAME_REPLACE
|
||||||
'
|
'
|
||||||
@@ -566,14 +567,14 @@ Namespace Editors
|
|||||||
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0)
|
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0)
|
||||||
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0)
|
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0)
|
||||||
TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 84)
|
TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 110)
|
||||||
TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0)
|
TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0)
|
||||||
TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS"
|
TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS"
|
||||||
TP_FILE_PATTERNS.RowCount = 1
|
TP_FILE_PATTERNS.RowCount = 1
|
||||||
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!))
|
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!))
|
||||||
TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30)
|
TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30)
|
||||||
TP_FILE_PATTERNS.TabIndex = 3
|
TP_FILE_PATTERNS.TabIndex = 4
|
||||||
'
|
'
|
||||||
'CH_FILE_DATE
|
'CH_FILE_DATE
|
||||||
'
|
'
|
||||||
@@ -880,10 +881,10 @@ Namespace Editors
|
|||||||
'
|
'
|
||||||
Me.CH_DOWN_REPARSE_MISSING.AutoSize = True
|
Me.CH_DOWN_REPARSE_MISSING.AutoSize = True
|
||||||
Me.CH_DOWN_REPARSE_MISSING.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.CH_DOWN_REPARSE_MISSING.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 202)
|
Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 228)
|
||||||
Me.CH_DOWN_REPARSE_MISSING.Name = "CH_DOWN_REPARSE_MISSING"
|
Me.CH_DOWN_REPARSE_MISSING.Name = "CH_DOWN_REPARSE_MISSING"
|
||||||
Me.CH_DOWN_REPARSE_MISSING.Size = New System.Drawing.Size(568, 19)
|
Me.CH_DOWN_REPARSE_MISSING.Size = New System.Drawing.Size(568, 19)
|
||||||
Me.CH_DOWN_REPARSE_MISSING.TabIndex = 7
|
Me.CH_DOWN_REPARSE_MISSING.TabIndex = 8
|
||||||
Me.CH_DOWN_REPARSE_MISSING.Text = "Trying to download missing posts using regular download"
|
Me.CH_DOWN_REPARSE_MISSING.Text = "Trying to download missing posts using regular download"
|
||||||
TT_MAIN.SetToolTip(Me.CH_DOWN_REPARSE_MISSING, "If missing posts exist, the missing posts will attempt to be downloaded via user " &
|
TT_MAIN.SetToolTip(Me.CH_DOWN_REPARSE_MISSING, "If missing posts exist, the missing posts will attempt to be downloaded via user " &
|
||||||
"download")
|
"download")
|
||||||
@@ -925,6 +926,34 @@ Namespace Editors
|
|||||||
TT_MAIN.SetToolTip(Me.CH_STD_EVERY, "Show notifications when download in standalone downloader is complete")
|
TT_MAIN.SetToolTip(Me.CH_STD_EVERY, "Show notifications when download in standalone downloader is complete")
|
||||||
Me.CH_STD_EVERY.UseVisualStyleBackColor = True
|
Me.CH_STD_EVERY.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
|
'CH_STD_YT_LOAD
|
||||||
|
'
|
||||||
|
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.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.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.")
|
||||||
|
Me.CH_STD_YT_LOAD.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'CH_STD_YT_REMOVE
|
||||||
|
'
|
||||||
|
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.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.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
|
||||||
|
'
|
||||||
'TP_CHANNELS_IMGS
|
'TP_CHANNELS_IMGS
|
||||||
'
|
'
|
||||||
TP_CHANNELS_IMGS.ColumnCount = 2
|
TP_CHANNELS_IMGS.ColumnCount = 2
|
||||||
@@ -1265,18 +1294,20 @@ Namespace Editors
|
|||||||
TP_DOWNLOADING.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
TP_DOWNLOADING.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||||
TP_DOWNLOADING.ColumnCount = 1
|
TP_DOWNLOADING.ColumnCount = 1
|
||||||
TP_DOWNLOADING.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_DOWNLOADING.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 2)
|
TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 3)
|
||||||
TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 3)
|
TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 4)
|
||||||
TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 4)
|
TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 5)
|
||||||
TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0)
|
TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0)
|
||||||
TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 5)
|
TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 6)
|
||||||
TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 6)
|
TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 7)
|
||||||
TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 7)
|
TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 8)
|
||||||
TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1)
|
TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1)
|
||||||
|
TP_DOWNLOADING.Controls.Add(Me.CH_UICON_UP, 0, 2)
|
||||||
TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0)
|
TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0)
|
||||||
TP_DOWNLOADING.Name = "TP_DOWNLOADING"
|
TP_DOWNLOADING.Name = "TP_DOWNLOADING"
|
||||||
TP_DOWNLOADING.RowCount = 9
|
TP_DOWNLOADING.RowCount = 10
|
||||||
|
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.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.Absolute, 25.0!))
|
||||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||||
@@ -1305,12 +1336,12 @@ Namespace Editors
|
|||||||
Me.TXT_SCRIPT.CaptionWidth = 120.0R
|
Me.TXT_SCRIPT.CaptionWidth = 120.0R
|
||||||
Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False
|
Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False
|
||||||
Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 118)
|
Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 144)
|
||||||
Me.TXT_SCRIPT.Name = "TXT_SCRIPT"
|
Me.TXT_SCRIPT.Name = "TXT_SCRIPT"
|
||||||
Me.TXT_SCRIPT.PlaceholderEnabled = True
|
Me.TXT_SCRIPT.PlaceholderEnabled = True
|
||||||
Me.TXT_SCRIPT.PlaceholderText = "Enter script path here..."
|
Me.TXT_SCRIPT.PlaceholderText = "Enter script path here..."
|
||||||
Me.TXT_SCRIPT.Size = New System.Drawing.Size(568, 22)
|
Me.TXT_SCRIPT.Size = New System.Drawing.Size(568, 22)
|
||||||
Me.TXT_SCRIPT.TabIndex = 4
|
Me.TXT_SCRIPT.TabIndex = 5
|
||||||
'
|
'
|
||||||
'TXT_DOWN_COMPLETE_SCRIPT
|
'TXT_DOWN_COMPLETE_SCRIPT
|
||||||
'
|
'
|
||||||
@@ -1320,12 +1351,12 @@ Namespace Editors
|
|||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipText = "This command will be executed after all downloads are completed"
|
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.CaptionWidth = 120.0R
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 147)
|
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.Name = "TXT_DOWN_COMPLETE_SCRIPT"
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True
|
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderText = "Enter command here..."
|
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderText = "Enter command here..."
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.Size = New System.Drawing.Size(568, 22)
|
Me.TXT_DOWN_COMPLETE_SCRIPT.Size = New System.Drawing.Size(568, 22)
|
||||||
Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 5
|
Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 6
|
||||||
'
|
'
|
||||||
'TP_MISSING_DATA
|
'TP_MISSING_DATA
|
||||||
'
|
'
|
||||||
@@ -1336,14 +1367,14 @@ Namespace Editors
|
|||||||
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_TO_LOG, 0, 0)
|
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_TO_LOG, 0, 0)
|
||||||
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_ERROS_TO_LOG, 1, 0)
|
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_ERROS_TO_LOG, 1, 0)
|
||||||
TP_MISSING_DATA.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_MISSING_DATA.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_MISSING_DATA.Location = New System.Drawing.Point(1, 173)
|
TP_MISSING_DATA.Location = New System.Drawing.Point(1, 199)
|
||||||
TP_MISSING_DATA.Margin = New System.Windows.Forms.Padding(0)
|
TP_MISSING_DATA.Margin = New System.Windows.Forms.Padding(0)
|
||||||
TP_MISSING_DATA.Name = "TP_MISSING_DATA"
|
TP_MISSING_DATA.Name = "TP_MISSING_DATA"
|
||||||
TP_MISSING_DATA.RowCount = 1
|
TP_MISSING_DATA.RowCount = 1
|
||||||
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24.0!))
|
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24.0!))
|
||||||
TP_MISSING_DATA.Size = New System.Drawing.Size(574, 25)
|
TP_MISSING_DATA.Size = New System.Drawing.Size(574, 25)
|
||||||
TP_MISSING_DATA.TabIndex = 6
|
TP_MISSING_DATA.TabIndex = 7
|
||||||
'
|
'
|
||||||
'CH_UNAME_UP
|
'CH_UNAME_UP
|
||||||
'
|
'
|
||||||
@@ -1352,7 +1383,7 @@ Namespace Editors
|
|||||||
Me.CH_UNAME_UP.Location = New System.Drawing.Point(4, 30)
|
Me.CH_UNAME_UP.Location = New System.Drawing.Point(4, 30)
|
||||||
Me.CH_UNAME_UP.Name = "CH_UNAME_UP"
|
Me.CH_UNAME_UP.Name = "CH_UNAME_UP"
|
||||||
Me.CH_UNAME_UP.Size = New System.Drawing.Size(568, 19)
|
Me.CH_UNAME_UP.Size = New System.Drawing.Size(568, 19)
|
||||||
Me.CH_UNAME_UP.TabIndex = 7
|
Me.CH_UNAME_UP.TabIndex = 1
|
||||||
Me.CH_UNAME_UP.Text = "Update user site name every time"
|
Me.CH_UNAME_UP.Text = "Update user site name every time"
|
||||||
Me.CH_UNAME_UP.UseVisualStyleBackColor = True
|
Me.CH_UNAME_UP.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
@@ -1843,33 +1874,16 @@ Namespace Editors
|
|||||||
Me.CONTAINER_MAIN.TabIndex = 0
|
Me.CONTAINER_MAIN.TabIndex = 0
|
||||||
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
|
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||||
'
|
'
|
||||||
'CH_STD_YT_LOAD
|
'CH_UICON_UP
|
||||||
'
|
'
|
||||||
Me.CH_STD_YT_LOAD.AutoSize = True
|
Me.CH_UICON_UP.AutoSize = True
|
||||||
Me.CH_STD_YT_LOAD.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.CH_UICON_UP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.CH_STD_YT_LOAD.Location = New System.Drawing.Point(4, 166)
|
Me.CH_UICON_UP.Location = New System.Drawing.Point(4, 56)
|
||||||
Me.CH_STD_YT_LOAD.Name = "CH_STD_YT_LOAD"
|
Me.CH_UICON_UP.Name = "CH_UICON_UP"
|
||||||
Me.CH_STD_YT_LOAD.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
|
Me.CH_UICON_UP.Size = New System.Drawing.Size(568, 19)
|
||||||
Me.CH_STD_YT_LOAD.Size = New System.Drawing.Size(568, 19)
|
Me.CH_UICON_UP.TabIndex = 2
|
||||||
Me.CH_STD_YT_LOAD.TabIndex = 6
|
Me.CH_UICON_UP.Text = "Update user icon and banner every time (where supported)"
|
||||||
Me.CH_STD_YT_LOAD.Text = "Load downloaded YouTube videos to the form"
|
Me.CH_UICON_UP.UseVisualStyleBackColor = True
|
||||||
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.")
|
|
||||||
Me.CH_STD_YT_LOAD.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'CH_STD_YT_REMOVE
|
|
||||||
'
|
|
||||||
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.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.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
|
|
||||||
'
|
'
|
||||||
'GlobalSettingsForm
|
'GlobalSettingsForm
|
||||||
'
|
'
|
||||||
@@ -2041,5 +2055,6 @@ Namespace Editors
|
|||||||
Private WithEvents CH_STD_UPDATE_YT_PATH As CheckBox
|
Private WithEvents CH_STD_UPDATE_YT_PATH As CheckBox
|
||||||
Private WithEvents CH_STD_YT_LOAD As CheckBox
|
Private WithEvents CH_STD_YT_LOAD As CheckBox
|
||||||
Private WithEvents CH_STD_YT_REMOVE As CheckBox
|
Private WithEvents CH_STD_YT_REMOVE As CheckBox
|
||||||
|
Private WithEvents CH_UICON_UP As CheckBox
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -89,6 +89,7 @@ Namespace Editors
|
|||||||
'Downloading
|
'Downloading
|
||||||
CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime
|
CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime
|
||||||
CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime
|
CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime
|
||||||
|
CH_UICON_UP.Checked = .UpdateUserIconBannerEveryTime
|
||||||
TXT_SCRIPT.Checked = .ScriptData.Attribute
|
TXT_SCRIPT.Checked = .ScriptData.Attribute
|
||||||
TXT_SCRIPT.Text = .ScriptData.Value
|
TXT_SCRIPT.Text = .ScriptData.Value
|
||||||
TXT_DOWN_COMPLETE_SCRIPT.Text = .DownloadsCompleteCommand
|
TXT_DOWN_COMPLETE_SCRIPT.Text = .DownloadsCompleteCommand
|
||||||
@@ -244,6 +245,7 @@ Namespace Editors
|
|||||||
'Downloading
|
'Downloading
|
||||||
.UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked
|
.UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked
|
||||||
.UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked
|
.UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked
|
||||||
|
.UpdateUserIconBannerEveryTime.Value = CH_UICON_UP.Checked
|
||||||
.ScriptData.Value = TXT_SCRIPT.Text
|
.ScriptData.Value = TXT_SCRIPT.Text
|
||||||
.ScriptData.Attribute.Value = TXT_SCRIPT.Checked
|
.ScriptData.Attribute.Value = TXT_SCRIPT.Checked
|
||||||
.DownloadsCompleteCommand.Value = TXT_DOWN_COMPLETE_SCRIPT.Text
|
.DownloadsCompleteCommand.Value = TXT_DOWN_COMPLETE_SCRIPT.Text
|
||||||
|
|||||||
6
SCrawler/Editors/SiteEditorForm.Designer.vb
generated
@@ -54,7 +54,7 @@ Namespace Editors
|
|||||||
'CONTAINER_MAIN.ContentPanel
|
'CONTAINER_MAIN.ContentPanel
|
||||||
'
|
'
|
||||||
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
|
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
|
||||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(544, 218)
|
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(544, 243)
|
||||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
@@ -84,7 +84,7 @@ Namespace Editors
|
|||||||
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.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.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
Me.TP_MAIN.Size = New System.Drawing.Size(544, 218)
|
Me.TP_MAIN.Size = New System.Drawing.Size(544, 243)
|
||||||
Me.TP_MAIN.TabIndex = 0
|
Me.TP_MAIN.TabIndex = 0
|
||||||
'
|
'
|
||||||
'TXT_PATH
|
'TXT_PATH
|
||||||
@@ -135,7 +135,7 @@ Namespace Editors
|
|||||||
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
Me.TP_SITE_PROPS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
Me.TP_SITE_PROPS.Size = New System.Drawing.Size(538, 78)
|
Me.TP_SITE_PROPS.Size = New System.Drawing.Size(538, 103)
|
||||||
Me.TP_SITE_PROPS.TabIndex = 5
|
Me.TP_SITE_PROPS.TabIndex = 5
|
||||||
'
|
'
|
||||||
'TXT_PATH_SAVED_POSTS
|
'TXT_PATH_SAVED_POSTS
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ Namespace Editors
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
If .PropList.Count > 0 Then
|
If .PropList.Count > 0 Then
|
||||||
|
With TP_SITE_PROPS
|
||||||
|
With .RowStyles : .RemoveAt(.Count - 1) : End With
|
||||||
|
.RowCount -= 1
|
||||||
|
End With
|
||||||
|
|
||||||
Dim laAdded As Boolean = False
|
Dim laAdded As Boolean = False
|
||||||
Dim loAdded As Boolean = False
|
Dim loAdded As Boolean = False
|
||||||
Dim pArr() As Boolean
|
Dim pArr() As Boolean
|
||||||
@@ -134,6 +139,19 @@ Namespace Editors
|
|||||||
CH_GET_USER_MEDIA_ONLY.Padding = New PaddingE(CH_GET_USER_MEDIA_ONLY.Padding) With {.Left = offset}
|
CH_GET_USER_MEDIA_ONLY.Padding = New PaddingE(CH_GET_USER_MEDIA_ONLY.Padding) With {.Left = offset}
|
||||||
If c > 0 Or h <> 0 Then
|
If c > 0 Or h <> 0 Then
|
||||||
Dim ss As New Size(Size.Width, Size.Height + h + c)
|
Dim ss As New Size(Size.Width, Size.Height + h + c)
|
||||||
|
Dim minScrh% = Screen.AllScreens.Min(Function(scr) scr.WorkingArea.Height)
|
||||||
|
|
||||||
|
If ss.Height >= minScrh - 20 Then
|
||||||
|
ss.Height = minScrh - 40
|
||||||
|
With TP_SITE_PROPS
|
||||||
|
.AutoScroll = True
|
||||||
|
Dim p As Padding = .Padding
|
||||||
|
p.Right = 3
|
||||||
|
.Padding = p
|
||||||
|
.PerformLayout()
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
|
||||||
MinimumSize = ss
|
MinimumSize = ss
|
||||||
Size = ss
|
Size = ss
|
||||||
MaximumSize = ss
|
MaximumSize = ss
|
||||||
|
|||||||
11
SCrawler/Editors/UserCreatorForm.Designer.vb
generated
@@ -105,10 +105,10 @@ Namespace Editors
|
|||||||
'BTT_OTHER_SETTINGS
|
'BTT_OTHER_SETTINGS
|
||||||
'
|
'
|
||||||
Me.BTT_OTHER_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.BTT_OTHER_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(2, 2)
|
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(1, 1)
|
||||||
Me.BTT_OTHER_SETTINGS.Margin = New System.Windows.Forms.Padding(1)
|
Me.BTT_OTHER_SETTINGS.Margin = New System.Windows.Forms.Padding(1)
|
||||||
Me.BTT_OTHER_SETTINGS.Name = "BTT_OTHER_SETTINGS"
|
Me.BTT_OTHER_SETTINGS.Name = "BTT_OTHER_SETTINGS"
|
||||||
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(101, 24)
|
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(101, 26)
|
||||||
Me.BTT_OTHER_SETTINGS.TabIndex = 1
|
Me.BTT_OTHER_SETTINGS.TabIndex = 1
|
||||||
Me.BTT_OTHER_SETTINGS.Text = "Options (F2)"
|
Me.BTT_OTHER_SETTINGS.Text = "Options (F2)"
|
||||||
TT_MAIN.SetToolTip(Me.BTT_OTHER_SETTINGS, "Other settings")
|
TT_MAIN.SetToolTip(Me.BTT_OTHER_SETTINGS, "Other settings")
|
||||||
@@ -177,7 +177,6 @@ Namespace Editors
|
|||||||
'
|
'
|
||||||
'TP_SITE
|
'TP_SITE
|
||||||
'
|
'
|
||||||
Me.TP_SITE.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
|
||||||
Me.TP_SITE.ColumnCount = 2
|
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.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.Percent, 100.0!))
|
||||||
@@ -209,10 +208,10 @@ Namespace Editors
|
|||||||
Me.CMB_SITE.Columns.Add(ListColumn1)
|
Me.CMB_SITE.Columns.Add(ListColumn1)
|
||||||
Me.CMB_SITE.Columns.Add(ListColumn2)
|
Me.CMB_SITE.Columns.Add(ListColumn2)
|
||||||
Me.CMB_SITE.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.CMB_SITE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.CMB_SITE.Location = New System.Drawing.Point(108, 3)
|
Me.CMB_SITE.Location = New System.Drawing.Point(103, 3)
|
||||||
Me.CMB_SITE.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
|
Me.CMB_SITE.Margin = New System.Windows.Forms.Padding(0, 3, 3, 3)
|
||||||
Me.CMB_SITE.Name = "CMB_SITE"
|
Me.CMB_SITE.Name = "CMB_SITE"
|
||||||
Me.CMB_SITE.Size = New System.Drawing.Size(340, 21)
|
Me.CMB_SITE.Size = New System.Drawing.Size(346, 22)
|
||||||
Me.CMB_SITE.TabIndex = 0
|
Me.CMB_SITE.TabIndex = 0
|
||||||
Me.CMB_SITE.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
|
Me.CMB_SITE.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
|
||||||
'
|
'
|
||||||
|
|||||||
287
SCrawler/Editors/UsersInfoForm.Designer.vb
generated
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Editors
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class UsersInfoForm : Inherits System.Windows.Forms.Form
|
||||||
|
<System.Diagnostics.DebuggerNonUserCode()>
|
||||||
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
Try
|
||||||
|
If disposing AndAlso components IsNot Nothing Then
|
||||||
|
components.Dispose()
|
||||||
|
End If
|
||||||
|
Finally
|
||||||
|
MyBase.Dispose(disposing)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private components As System.ComponentModel.IContainer
|
||||||
|
<System.Diagnostics.DebuggerStepThrough()>
|
||||||
|
Private Sub InitializeComponent()
|
||||||
|
Me.components = New System.ComponentModel.Container()
|
||||||
|
Dim SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim CONTEXT_SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim MENU_SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim MENU_SEP_2 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(UsersInfoForm))
|
||||||
|
Me.Toolbar_TOP = New System.Windows.Forms.ToolStrip()
|
||||||
|
Me.BTT_START = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_CANCEL = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
|
||||||
|
Me.OPT_DATE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.OPT_SIZE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.OPT_AMOUNT = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.OPT_ASC = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.OPT_DESC = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.CH_GROUP_DRIVE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.CH_GROUP_COL = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.Toolbar_BOTTOM = New System.Windows.Forms.StatusStrip()
|
||||||
|
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
|
||||||
|
Me.LBL_STATUS = New System.Windows.Forms.ToolStripStatusLabel()
|
||||||
|
Me.LIST_DATA = New System.Windows.Forms.ListView()
|
||||||
|
Me.COL_DEFAULT = CType(New System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
|
||||||
|
Me.CONTEXT_LIST = New System.Windows.Forms.ContextMenuStrip(Me.components)
|
||||||
|
Me.CONTEXT_BTT_FIND = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.CONTEXT_BTT_INFO = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.CONTEXT_BTT_OPEN_FOLDER = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.CONTEXT_BTT_OPEN_SITE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
MENU_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
MENU_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
Me.Toolbar_TOP.SuspendLayout()
|
||||||
|
Me.Toolbar_BOTTOM.SuspendLayout()
|
||||||
|
Me.CONTEXT_LIST.SuspendLayout()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'SEP_1
|
||||||
|
'
|
||||||
|
SEP_1.Name = "SEP_1"
|
||||||
|
SEP_1.Size = New System.Drawing.Size(6, 25)
|
||||||
|
'
|
||||||
|
'CONTEXT_SEP_1
|
||||||
|
'
|
||||||
|
CONTEXT_SEP_1.Name = "CONTEXT_SEP_1"
|
||||||
|
CONTEXT_SEP_1.Size = New System.Drawing.Size(166, 6)
|
||||||
|
'
|
||||||
|
'MENU_SEP_1
|
||||||
|
'
|
||||||
|
MENU_SEP_1.Name = "MENU_SEP_1"
|
||||||
|
MENU_SEP_1.Size = New System.Drawing.Size(175, 6)
|
||||||
|
'
|
||||||
|
'MENU_SEP_2
|
||||||
|
'
|
||||||
|
MENU_SEP_2.Name = "MENU_SEP_2"
|
||||||
|
MENU_SEP_2.Size = New System.Drawing.Size(175, 6)
|
||||||
|
'
|
||||||
|
'Toolbar_TOP
|
||||||
|
'
|
||||||
|
Me.Toolbar_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||||
|
Me.Toolbar_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_START, Me.BTT_CANCEL, SEP_1, Me.MENU_VIEW})
|
||||||
|
Me.Toolbar_TOP.Location = New System.Drawing.Point(0, 0)
|
||||||
|
Me.Toolbar_TOP.Name = "Toolbar_TOP"
|
||||||
|
Me.Toolbar_TOP.ShowItemToolTips = False
|
||||||
|
Me.Toolbar_TOP.Size = New System.Drawing.Size(284, 25)
|
||||||
|
Me.Toolbar_TOP.TabIndex = 0
|
||||||
|
'
|
||||||
|
'BTT_START
|
||||||
|
'
|
||||||
|
Me.BTT_START.AutoToolTip = False
|
||||||
|
Me.BTT_START.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
|
||||||
|
Me.BTT_START.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_START.Name = "BTT_START"
|
||||||
|
Me.BTT_START.Size = New System.Drawing.Size(76, 22)
|
||||||
|
Me.BTT_START.Text = "Calculate"
|
||||||
|
'
|
||||||
|
'BTT_CANCEL
|
||||||
|
'
|
||||||
|
Me.BTT_CANCEL.AutoToolTip = False
|
||||||
|
Me.BTT_CANCEL.Enabled = False
|
||||||
|
Me.BTT_CANCEL.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
|
||||||
|
Me.BTT_CANCEL.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_CANCEL.Name = "BTT_CANCEL"
|
||||||
|
Me.BTT_CANCEL.Size = New System.Drawing.Size(63, 22)
|
||||||
|
Me.BTT_CANCEL.Text = "Cancel"
|
||||||
|
'
|
||||||
|
'MENU_VIEW
|
||||||
|
'
|
||||||
|
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.OPT_DATE, Me.OPT_SIZE, Me.OPT_AMOUNT, MENU_SEP_1, Me.OPT_ASC, Me.OPT_DESC, MENU_SEP_2, Me.CH_GROUP_DRIVE, Me.CH_GROUP_COL})
|
||||||
|
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(61, 22)
|
||||||
|
Me.MENU_VIEW.Text = "View"
|
||||||
|
'
|
||||||
|
'OPT_DATE
|
||||||
|
'
|
||||||
|
Me.OPT_DATE.CheckOnClick = True
|
||||||
|
Me.OPT_DATE.Name = "OPT_DATE"
|
||||||
|
Me.OPT_DATE.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.OPT_DATE.Text = "Sort by date"
|
||||||
|
'
|
||||||
|
'OPT_SIZE
|
||||||
|
'
|
||||||
|
Me.OPT_SIZE.CheckOnClick = True
|
||||||
|
Me.OPT_SIZE.Name = "OPT_SIZE"
|
||||||
|
Me.OPT_SIZE.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.OPT_SIZE.Text = "Sort by size"
|
||||||
|
'
|
||||||
|
'OPT_AMOUNT
|
||||||
|
'
|
||||||
|
Me.OPT_AMOUNT.CheckOnClick = True
|
||||||
|
Me.OPT_AMOUNT.Name = "OPT_AMOUNT"
|
||||||
|
Me.OPT_AMOUNT.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.OPT_AMOUNT.Text = "Sort by amount"
|
||||||
|
'
|
||||||
|
'OPT_ASC
|
||||||
|
'
|
||||||
|
Me.OPT_ASC.CheckOnClick = True
|
||||||
|
Me.OPT_ASC.Name = "OPT_ASC"
|
||||||
|
Me.OPT_ASC.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.OPT_ASC.Text = "Ascending"
|
||||||
|
'
|
||||||
|
'OPT_DESC
|
||||||
|
'
|
||||||
|
Me.OPT_DESC.CheckOnClick = True
|
||||||
|
Me.OPT_DESC.Name = "OPT_DESC"
|
||||||
|
Me.OPT_DESC.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.OPT_DESC.Text = "Descending"
|
||||||
|
'
|
||||||
|
'CH_GROUP_DRIVE
|
||||||
|
'
|
||||||
|
Me.CH_GROUP_DRIVE.CheckOnClick = True
|
||||||
|
Me.CH_GROUP_DRIVE.Name = "CH_GROUP_DRIVE"
|
||||||
|
Me.CH_GROUP_DRIVE.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.CH_GROUP_DRIVE.Text = "Group by drive"
|
||||||
|
'
|
||||||
|
'CH_GROUP_COL
|
||||||
|
'
|
||||||
|
Me.CH_GROUP_COL.CheckOnClick = True
|
||||||
|
Me.CH_GROUP_COL.Name = "CH_GROUP_COL"
|
||||||
|
Me.CH_GROUP_COL.Size = New System.Drawing.Size(178, 22)
|
||||||
|
Me.CH_GROUP_COL.Text = "Group by collection"
|
||||||
|
'
|
||||||
|
'Toolbar_BOTTOM
|
||||||
|
'
|
||||||
|
Me.Toolbar_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_MAIN, Me.LBL_STATUS})
|
||||||
|
Me.Toolbar_BOTTOM.Location = New System.Drawing.Point(0, 239)
|
||||||
|
Me.Toolbar_BOTTOM.Name = "Toolbar_BOTTOM"
|
||||||
|
Me.Toolbar_BOTTOM.Size = New System.Drawing.Size(284, 22)
|
||||||
|
Me.Toolbar_BOTTOM.TabIndex = 1
|
||||||
|
'
|
||||||
|
'PR_MAIN
|
||||||
|
'
|
||||||
|
Me.PR_MAIN.Name = "PR_MAIN"
|
||||||
|
Me.PR_MAIN.Size = New System.Drawing.Size(200, 16)
|
||||||
|
Me.PR_MAIN.Visible = False
|
||||||
|
'
|
||||||
|
'LBL_STATUS
|
||||||
|
'
|
||||||
|
Me.LBL_STATUS.Name = "LBL_STATUS"
|
||||||
|
Me.LBL_STATUS.Size = New System.Drawing.Size(0, 17)
|
||||||
|
'
|
||||||
|
'LIST_DATA
|
||||||
|
'
|
||||||
|
Me.LIST_DATA.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.COL_DEFAULT})
|
||||||
|
Me.LIST_DATA.ContextMenuStrip = Me.CONTEXT_LIST
|
||||||
|
Me.LIST_DATA.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.LIST_DATA.FullRowSelect = True
|
||||||
|
Me.LIST_DATA.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None
|
||||||
|
Me.LIST_DATA.HideSelection = False
|
||||||
|
Me.LIST_DATA.Location = New System.Drawing.Point(0, 25)
|
||||||
|
Me.LIST_DATA.MultiSelect = False
|
||||||
|
Me.LIST_DATA.Name = "LIST_DATA"
|
||||||
|
Me.LIST_DATA.Size = New System.Drawing.Size(284, 214)
|
||||||
|
Me.LIST_DATA.TabIndex = 2
|
||||||
|
Me.LIST_DATA.UseCompatibleStateImageBehavior = False
|
||||||
|
Me.LIST_DATA.View = System.Windows.Forms.View.Details
|
||||||
|
'
|
||||||
|
'COL_DEFAULT
|
||||||
|
'
|
||||||
|
Me.COL_DEFAULT.Text = "User"
|
||||||
|
Me.COL_DEFAULT.Width = 280
|
||||||
|
'
|
||||||
|
'CONTEXT_LIST
|
||||||
|
'
|
||||||
|
Me.CONTEXT_LIST.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.CONTEXT_BTT_FIND, Me.CONTEXT_BTT_INFO, CONTEXT_SEP_1, Me.CONTEXT_BTT_OPEN_FOLDER, Me.CONTEXT_BTT_OPEN_SITE})
|
||||||
|
Me.CONTEXT_LIST.Name = "CONTEXT_LIST"
|
||||||
|
Me.CONTEXT_LIST.Size = New System.Drawing.Size(170, 98)
|
||||||
|
'
|
||||||
|
'CONTEXT_BTT_FIND
|
||||||
|
'
|
||||||
|
Me.CONTEXT_BTT_FIND.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
|
||||||
|
Me.CONTEXT_BTT_FIND.Name = "CONTEXT_BTT_FIND"
|
||||||
|
Me.CONTEXT_BTT_FIND.Size = New System.Drawing.Size(169, 22)
|
||||||
|
Me.CONTEXT_BTT_FIND.Text = "Find user"
|
||||||
|
'
|
||||||
|
'CONTEXT_BTT_INFO
|
||||||
|
'
|
||||||
|
Me.CONTEXT_BTT_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
|
||||||
|
Me.CONTEXT_BTT_INFO.Name = "CONTEXT_BTT_INFO"
|
||||||
|
Me.CONTEXT_BTT_INFO.Size = New System.Drawing.Size(169, 22)
|
||||||
|
Me.CONTEXT_BTT_INFO.Text = "Show information"
|
||||||
|
'
|
||||||
|
'CONTEXT_BTT_OPEN_FOLDER
|
||||||
|
'
|
||||||
|
Me.CONTEXT_BTT_OPEN_FOLDER.Image = Global.SCrawler.My.Resources.Resources.FolderPic_32
|
||||||
|
Me.CONTEXT_BTT_OPEN_FOLDER.Name = "CONTEXT_BTT_OPEN_FOLDER"
|
||||||
|
Me.CONTEXT_BTT_OPEN_FOLDER.Size = New System.Drawing.Size(169, 22)
|
||||||
|
Me.CONTEXT_BTT_OPEN_FOLDER.Text = "Open folder"
|
||||||
|
'
|
||||||
|
'CONTEXT_BTT_OPEN_SITE
|
||||||
|
'
|
||||||
|
Me.CONTEXT_BTT_OPEN_SITE.Image = Global.SCrawler.My.Resources.Resources.GlobePic_32
|
||||||
|
Me.CONTEXT_BTT_OPEN_SITE.Name = "CONTEXT_BTT_OPEN_SITE"
|
||||||
|
Me.CONTEXT_BTT_OPEN_SITE.Size = New System.Drawing.Size(169, 22)
|
||||||
|
Me.CONTEXT_BTT_OPEN_SITE.Text = "Open site"
|
||||||
|
'
|
||||||
|
'UsersInfoForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(284, 261)
|
||||||
|
Me.Controls.Add(Me.LIST_DATA)
|
||||||
|
Me.Controls.Add(Me.Toolbar_BOTTOM)
|
||||||
|
Me.Controls.Add(Me.Toolbar_TOP)
|
||||||
|
Me.Icon = Global.SCrawler.My.Resources.Resources.UsersIcon_32
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(300, 300)
|
||||||
|
Me.Name = "UsersInfoForm"
|
||||||
|
Me.Text = "Users info"
|
||||||
|
Me.Toolbar_TOP.ResumeLayout(False)
|
||||||
|
Me.Toolbar_TOP.PerformLayout()
|
||||||
|
Me.Toolbar_BOTTOM.ResumeLayout(False)
|
||||||
|
Me.Toolbar_BOTTOM.PerformLayout()
|
||||||
|
Me.CONTEXT_LIST.ResumeLayout(False)
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
Me.PerformLayout()
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents Toolbar_TOP As ToolStrip
|
||||||
|
Private WithEvents Toolbar_BOTTOM As StatusStrip
|
||||||
|
Private WithEvents PR_MAIN As ToolStripProgressBar
|
||||||
|
Private WithEvents LBL_STATUS As ToolStripStatusLabel
|
||||||
|
Private WithEvents LIST_DATA As ListView
|
||||||
|
Private WithEvents BTT_START As ToolStripButton
|
||||||
|
Private WithEvents BTT_CANCEL As ToolStripButton
|
||||||
|
Private WithEvents COL_DEFAULT As ColumnHeader
|
||||||
|
Private WithEvents CONTEXT_LIST As ContextMenuStrip
|
||||||
|
Private WithEvents CONTEXT_BTT_FIND As ToolStripMenuItem
|
||||||
|
Private WithEvents CONTEXT_BTT_INFO As ToolStripMenuItem
|
||||||
|
Private WithEvents CONTEXT_BTT_OPEN_FOLDER As ToolStripMenuItem
|
||||||
|
Private WithEvents CONTEXT_BTT_OPEN_SITE As ToolStripMenuItem
|
||||||
|
Private WithEvents MENU_VIEW As ToolStripDropDownButton
|
||||||
|
Private WithEvents OPT_DATE As ToolStripMenuItem
|
||||||
|
Private WithEvents OPT_SIZE As ToolStripMenuItem
|
||||||
|
Private WithEvents OPT_AMOUNT As ToolStripMenuItem
|
||||||
|
Private WithEvents OPT_ASC As ToolStripMenuItem
|
||||||
|
Private WithEvents OPT_DESC As ToolStripMenuItem
|
||||||
|
Private WithEvents CH_GROUP_DRIVE As ToolStripMenuItem
|
||||||
|
Private WithEvents CH_GROUP_COL As ToolStripMenuItem
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
150
SCrawler/Editors/UsersInfoForm.resx
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="CONTEXT_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="MENU_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="MENU_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="Toolbar_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABkSURBVDhPY6AKyO86WFDQfeg/iIYKkQZAmkNbnvyXta76
|
||||||
|
DxViYGFi+Y8PQ5VBAMhmkGYgJs8FAw9GA5EKILFiWUFixfL/IBoqRBoAafYsOvpf0jiTvEAE2QzSLGmU
|
||||||
|
MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="Toolbar_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>138, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="CONTEXT_LIST.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>286, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
514
SCrawler/Editors/UsersInfoForm.vb
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
' 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 PersonalUtilities.Forms
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
|
Namespace Editors
|
||||||
|
Friend Class UsersInfoForm
|
||||||
|
#Region "Declarations"
|
||||||
|
Private ReadOnly MyView As FormView
|
||||||
|
Private ReadOnly MyProgress As MyProgress
|
||||||
|
Private MyThread As Thread = Nothing
|
||||||
|
Private TokenSource As CancellationTokenSource = Nothing
|
||||||
|
Private Token As CancellationToken = Nothing
|
||||||
|
Private ReadOnly MyUsers As List(Of UserOpt)
|
||||||
|
Private ReadOnly LetterGroups As Dictionary(Of String, ListViewGroup)
|
||||||
|
Private ReadOnly MyNumberProvider As ANumbers
|
||||||
|
Private ReadOnly SizeNumberProvider As ANumbers
|
||||||
|
Private Enum EComparers As Integer
|
||||||
|
Size = 0
|
||||||
|
[Date] = 1
|
||||||
|
Amount = 2
|
||||||
|
End Enum
|
||||||
|
#Region "Comparers declarations"
|
||||||
|
Private ReadOnly MyComparerDate As New ComparerDate
|
||||||
|
Private ReadOnly MyComparerSize As New ComparerSize
|
||||||
|
Private ReadOnly MyComparerAmount As New ComparerAmount
|
||||||
|
#End Region
|
||||||
|
#Region "Comparers classes"
|
||||||
|
Private Class ComparerDate : Implements IComparer(Of UserOpt)
|
||||||
|
Protected _Order As Integer = -1
|
||||||
|
Friend Property Order As SortOrder
|
||||||
|
Get
|
||||||
|
Return IIf(_Order = -1, SortOrder.Descending, SortOrder.Ascending)
|
||||||
|
End Get
|
||||||
|
Set(ByVal _Order As SortOrder)
|
||||||
|
If _Order = SortOrder.Descending Then Me._Order = -1 Else Me._Order = 1
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Friend Overridable Function Compare(ByVal x As UserOpt, ByVal y As UserOpt) As Integer Implements IComparer(Of UserOpt).Compare
|
||||||
|
Dim xd& = If(x.User.LastUpdated, New Date).Ticks
|
||||||
|
Dim yd& = If(y.User.LastUpdated, New Date).Ticks
|
||||||
|
Return xd.CompareTo(yd) * _Order
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
Private Class ComparerSize : Inherits ComparerDate
|
||||||
|
Friend Overrides Function Compare(ByVal x As UserOpt, ByVal y As UserOpt) As Integer
|
||||||
|
Return x.TotalSize.CompareTo(y.TotalSize) * _Order
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
Private Class ComparerAmount : Inherits ComparerDate
|
||||||
|
Friend Overrides Function Compare(ByVal x As UserOpt, ByVal y As UserOpt) As Integer
|
||||||
|
Return x.Files.Count.CompareTo(y.Files.Count) * _Order
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
#End Region
|
||||||
|
#Region "Classes"
|
||||||
|
Private Structure FileOpt
|
||||||
|
Friend File As SFile
|
||||||
|
Friend Size As Double
|
||||||
|
Friend Type As UTypes
|
||||||
|
Friend Sub New(ByVal f As SFile, Optional ByVal CalculateSize As Boolean = False)
|
||||||
|
File = f
|
||||||
|
If CalculateSize Then Size = File.Size
|
||||||
|
Type = UTypes.Undefined
|
||||||
|
If Not f.Extension.IsEmptyString Then
|
||||||
|
Select Case f.Extension
|
||||||
|
Case "jpg", "jped", "png", "webp" : Type = UTypes.Picture
|
||||||
|
Case "gif" : Type = UTypes.GIF
|
||||||
|
Case "mp4", "mkv" : Type = UTypes.Video
|
||||||
|
End Select
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Public Shared Widening Operator CType(ByVal f As SFile) As FileOpt
|
||||||
|
Return New FileOpt(f)
|
||||||
|
End Operator
|
||||||
|
Public Shared Widening Operator CType(ByVal f As FileOpt) As SFile
|
||||||
|
Return f.File
|
||||||
|
End Operator
|
||||||
|
Public Shared Narrowing Operator CType(ByVal f As FileOpt) As Double
|
||||||
|
Return f.Size
|
||||||
|
End Operator
|
||||||
|
End Structure
|
||||||
|
Private NotInheritable Class UserOpt : Implements IComparable(Of UserOpt), IDisposable
|
||||||
|
Friend Property User As UserDataBase
|
||||||
|
Friend Property UserPath As SFile
|
||||||
|
Friend Property Letter As String
|
||||||
|
Friend ReadOnly Property Files As List(Of FileOpt)
|
||||||
|
Friend Property TotalSize As Double = 0
|
||||||
|
Friend Property CollectionName As String
|
||||||
|
Friend Property Name As String
|
||||||
|
Friend Property Site As String
|
||||||
|
Friend Property Key As String
|
||||||
|
Private ReadOnly NumberProvider As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral, .DecimalDigits = 2, .TrimDecimalDigits = True}
|
||||||
|
Friend Sub New(ByVal User As UserDataBase)
|
||||||
|
Me.User = User
|
||||||
|
Files = New List(Of FileOpt)
|
||||||
|
CollectionName = User.CollectionName
|
||||||
|
Site = User.Site
|
||||||
|
Name = User.FriendlyName.IfNullOrEmpty(User.Name)
|
||||||
|
Key = User.LVIKey
|
||||||
|
UserPath = User.User.File.CutPath
|
||||||
|
Letter = UserPath.Segments.FirstOrDefault.StringToUpper.StringTrimEnd(":")
|
||||||
|
End Sub
|
||||||
|
Friend Sub GetFiles()
|
||||||
|
If UserPath.Exists(SFO.Path, False) Then
|
||||||
|
Dim files As List(Of SFile) = SFile.GetFiles(UserPath,, IO.SearchOption.AllDirectories, EDP.ReturnValue)
|
||||||
|
If files.ListExists Then
|
||||||
|
For Each f As SFile In files : Me.Files.Add(New FileOpt(f, True)) : Next
|
||||||
|
TotalSize = Me.Files.Sum(Function(ff) ff.Size)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Friend Function GetLVI(ByVal LetterGroup As ListViewGroup, ByVal CollectionGroup As Boolean) As ListViewItem
|
||||||
|
Dim lvi As New ListViewItem
|
||||||
|
Dim s$ = String.Empty
|
||||||
|
If Not CollectionName.IsEmptyString Then s = $"{IIf(CollectionGroup, " ", String.Empty)}{CollectionName}"
|
||||||
|
s.StringAppend(Site, ".")
|
||||||
|
s.StringAppend(Name, ".")
|
||||||
|
s &= $" [{GetSizeStr(TotalSize)}]"
|
||||||
|
If Not User.UserExists Then
|
||||||
|
s &= " DELETED"
|
||||||
|
ElseIf User.UserSuspended Then
|
||||||
|
s &= " SUSPENDED"
|
||||||
|
End If
|
||||||
|
s &= ": "
|
||||||
|
Dim infoStr$ = String.Empty
|
||||||
|
infoStr.StringAppend(GetInfoStr(UTypes.Picture), "; ")
|
||||||
|
infoStr.StringAppend(GetInfoStr(UTypes.GIF), "; ")
|
||||||
|
infoStr.StringAppend(GetInfoStr(UTypes.Video), "; ")
|
||||||
|
infoStr.StringAppend(GetInfoStr(UTypes.Undefined), "; ")
|
||||||
|
If Not infoStr.IsEmptyString Then infoStr &= "; "
|
||||||
|
If User.LastUpdated.HasValue Then
|
||||||
|
infoStr &= $"({User.LastUpdated.Value.ToStringDate(ADateTime.Formats.BaseDate)})"
|
||||||
|
Else
|
||||||
|
infoStr &= "(not downloaded yet)"
|
||||||
|
End If
|
||||||
|
s &= infoStr
|
||||||
|
lvi.Text = s
|
||||||
|
lvi.Name = Key
|
||||||
|
lvi.Tag = Me
|
||||||
|
lvi.Group = LetterGroup
|
||||||
|
Return lvi
|
||||||
|
End Function
|
||||||
|
Private Function GetSizeStr(ByVal Value As Double) As String
|
||||||
|
If Value > 0 Then
|
||||||
|
Dim sizeText$ = "Mb"
|
||||||
|
Dim sizeValue# = Value / 1024 / 1024
|
||||||
|
If sizeValue > 1000 Then sizeValue /= 1024 : sizeText = "Gb"
|
||||||
|
Return $"{sizeValue.RoundVal(2).NumToString(NumberProvider)}{sizeText}"
|
||||||
|
Else
|
||||||
|
Return "0Kb"
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Private Function GetInfoStr(ByVal t As UTypes, Optional ByVal Separator As String = " ") As String
|
||||||
|
Dim OutStr$ = String.Empty
|
||||||
|
Dim d As IEnumerable(Of FileOpt) = Files.Where(Function(f) f.Type = t)
|
||||||
|
If d.ListExists Then
|
||||||
|
Return $"{t} ({d.Count.NumToString(NumberProvider)}){Separator}[{GetSizeStr(d.Sum(Function(dd) dd.Size))}]"
|
||||||
|
Else
|
||||||
|
Return String.Empty
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Friend Function GetInfornation() As String
|
||||||
|
Dim s$ = String.Empty
|
||||||
|
|
||||||
|
If Not CollectionName.IsEmptyString Then s &= $"Collection: {CollectionName}"
|
||||||
|
s.StringAppendLine(Site)
|
||||||
|
s.StringAppendLine(Name)
|
||||||
|
s.StringAppendLine($"Total size: {GetSizeStr(TotalSize)}")
|
||||||
|
|
||||||
|
s &= vbNewLine
|
||||||
|
|
||||||
|
s.StringAppendLine(GetInfoStr(UTypes.Picture, ": "))
|
||||||
|
s.StringAppendLine(GetInfoStr(UTypes.GIF, ": "))
|
||||||
|
s.StringAppendLine(GetInfoStr(UTypes.Video, ": "))
|
||||||
|
s.StringAppendLine(GetInfoStr(UTypes.Undefined, ": "))
|
||||||
|
|
||||||
|
If Not User.UserExists Then
|
||||||
|
s.StringAppendLine("User DELETED")
|
||||||
|
ElseIf User.UserSuspended Then
|
||||||
|
s.StringAppendLine("User SUSPENDED")
|
||||||
|
End If
|
||||||
|
|
||||||
|
s.StringAppendLine("Last download date: ")
|
||||||
|
If User.LastUpdated.HasValue Then
|
||||||
|
s &= User.LastUpdated.Value.ToStringDate(ADateTime.Formats.BaseDate)
|
||||||
|
Else
|
||||||
|
s &= "not downloaded yet"
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return s
|
||||||
|
End Function
|
||||||
|
#Region "IComparable Support"
|
||||||
|
Private Function CompareTo(ByVal Other As UserOpt) As Integer Implements IComparable(Of UserOpt).CompareTo
|
||||||
|
Return TotalSize.CompareTo(Other.TotalSize) * -1
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
#Region "IDisposable Support"
|
||||||
|
Private disposedValue As Boolean = False
|
||||||
|
Protected Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue Then
|
||||||
|
If disposing Then Files.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
|
||||||
|
#End Region
|
||||||
|
#Region "Initializer"
|
||||||
|
Friend Sub New()
|
||||||
|
InitializeComponent()
|
||||||
|
MyView = New FormView(Me, Settings.Design)
|
||||||
|
MyProgress = New MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS)
|
||||||
|
MyUsers = New List(Of UserOpt)
|
||||||
|
LetterGroups = New Dictionary(Of String, ListViewGroup)
|
||||||
|
MyNumberProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||||
|
SizeNumberProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral, .DecimalDigits = 2, .TrimDecimalDigits = True}
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Form handlers"
|
||||||
|
Private Sub UsersInfoForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
MyView.Import()
|
||||||
|
MyView.SetFormSize()
|
||||||
|
|
||||||
|
OPT_DATE.Tag = CInt(EComparers.Date)
|
||||||
|
OPT_SIZE.Tag = CInt(EComparers.Size)
|
||||||
|
OPT_AMOUNT.Tag = CInt(EComparers.Amount)
|
||||||
|
Select Case Settings.UMetrics_What.Value
|
||||||
|
Case EComparers.Date : OPT_DATE.Checked = True
|
||||||
|
Case EComparers.Amount : OPT_AMOUNT.Checked = True
|
||||||
|
Case Else : OPT_SIZE.Checked = True
|
||||||
|
End Select
|
||||||
|
|
||||||
|
OPT_ASC.Tag = CInt(SortOrder.Ascending)
|
||||||
|
OPT_DESC.Tag = CInt(SortOrder.Descending)
|
||||||
|
If Settings.UMetrics_Order.Value = SortOrder.Ascending Then
|
||||||
|
OPT_ASC.Checked = True
|
||||||
|
Else
|
||||||
|
OPT_DESC.Checked = True
|
||||||
|
End If
|
||||||
|
|
||||||
|
CH_GROUP_DRIVE.Checked = Settings.UMetrics_ShowDrives
|
||||||
|
CH_GROUP_COL.Checked = Settings.UMetrics_ShowCollections
|
||||||
|
LIST_DATA.ShowGroups = CH_GROUP_DRIVE.Checked
|
||||||
|
|
||||||
|
COL_DEFAULT.Width = -2
|
||||||
|
End Sub
|
||||||
|
Private Sub UsersInfoForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||||
|
e.Cancel = True
|
||||||
|
Hide()
|
||||||
|
End Sub
|
||||||
|
Private Sub UsersInfoForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||||
|
Abort()
|
||||||
|
MyProgress.Dispose()
|
||||||
|
MyView.Dispose()
|
||||||
|
End Sub
|
||||||
|
Private Sub UsersInfoForm_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
|
||||||
|
Try : ControlInvokeFast(LIST_DATA, Sub() COL_DEFAULT.Width = -2, EDP.None) : Catch : End Try
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Calculating"
|
||||||
|
Private Sub Abort()
|
||||||
|
Try
|
||||||
|
If If(MyThread?.IsAlive, False) Then TokenSource.Cancel() : MyThread.Abort()
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private _CalculationInProgress As Boolean = False
|
||||||
|
Private Sub BTT_START_Click(sender As Object, e As EventArgs) Handles BTT_START.Click
|
||||||
|
If Not If(MyThread?.IsAlive, False) Then
|
||||||
|
_CalculationInProgress = True
|
||||||
|
MyUsers.ListClearDispose
|
||||||
|
LetterGroups.Clear()
|
||||||
|
LIST_DATA.Groups.Clear()
|
||||||
|
LIST_DATA.Items.Clear()
|
||||||
|
If Not TokenSource Is Nothing Then TokenSource.Dispose()
|
||||||
|
TokenSource = New CancellationTokenSource
|
||||||
|
Token = TokenSource.Token
|
||||||
|
ChangeControlsEnabled(True)
|
||||||
|
MyThread = New Thread(New ThreadStart(AddressOf Calculate))
|
||||||
|
MyThread.SetApartmentState(ApartmentState.MTA)
|
||||||
|
MyThread.IsBackground = True
|
||||||
|
MyThread.Start()
|
||||||
|
Else
|
||||||
|
MsgBoxE({"The calculating is already underway", "Calculating"}, vbCritical)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
|
||||||
|
TokenSource.Cancel()
|
||||||
|
ControlInvokeFast(Toolbar_TOP, BTT_CANCEL, Sub() BTT_CANCEL.Enabled = False, EDP.None)
|
||||||
|
End Sub
|
||||||
|
Private Sub ChangeControlsEnabled(ByVal Working As Boolean)
|
||||||
|
Try
|
||||||
|
ControlInvokeFast(Toolbar_TOP, BTT_START, Sub()
|
||||||
|
BTT_START.Enabled = Not Working
|
||||||
|
BTT_CANCEL.Enabled = Working
|
||||||
|
End Sub, EDP.None)
|
||||||
|
If Not Working Then MainFrameObj.UpdateLogButton()
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub Calculate()
|
||||||
|
Try
|
||||||
|
MyProgress.Visible = True
|
||||||
|
MyProgress.Reset()
|
||||||
|
If Settings.Users.Count > 0 Then
|
||||||
|
With Settings.Users.SelectMany(Function(ByVal u As IUserData) As IEnumerable(Of IUserData)
|
||||||
|
If u.IsCollection Then
|
||||||
|
With DirectCast(u, API.UserDataBind)
|
||||||
|
If .Count > 0 Then Return .Collections Else Return New UserDataBase() {}
|
||||||
|
End With
|
||||||
|
Else
|
||||||
|
Return {u}
|
||||||
|
End If
|
||||||
|
End Function)
|
||||||
|
If .ListExists Then .ToList.ForEach(Sub(u As UserDataBase) MyUsers.Add(New UserOpt(u)))
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
|
||||||
|
If MyUsers.Count > 0 Then
|
||||||
|
MyProgress.Maximum += MyUsers.Count
|
||||||
|
Dim i% = 0
|
||||||
|
|
||||||
|
Dim letters As IEnumerable(Of String) = MyUsers.Select(Function(u) u.Letter).Distinct
|
||||||
|
LetterGroups.Clear()
|
||||||
|
If letters.ListExists(2) Then
|
||||||
|
ControlInvokeFast(LIST_DATA, Sub()
|
||||||
|
For Each l$ In letters
|
||||||
|
LetterGroups.Add(l, New ListViewGroup(l, $"Drive {l}"))
|
||||||
|
LIST_DATA.Groups.Add(LetterGroups.Last.Value)
|
||||||
|
Next
|
||||||
|
End Sub, EDP.None)
|
||||||
|
End If
|
||||||
|
|
||||||
|
MyProgress.Information = "Calculating of user metrics"
|
||||||
|
For Each user As UserOpt In MyUsers
|
||||||
|
Token.ThrowIfCancellationRequested()
|
||||||
|
i += 1
|
||||||
|
MyProgress.Perform()
|
||||||
|
user.GetFiles()
|
||||||
|
Next
|
||||||
|
|
||||||
|
_CalculationInProgress = False
|
||||||
|
RefillList()
|
||||||
|
End If
|
||||||
|
MyProgress.Done()
|
||||||
|
MyProgress.InformationTemporary = "All user metrics have been calculated."
|
||||||
|
Catch oex As OperationCanceledException
|
||||||
|
MyProgress.Done()
|
||||||
|
MyProgress.InformationTemporary = "Operation canceled"
|
||||||
|
Catch ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[UsersInfoForm.Calculate]")
|
||||||
|
MyProgress.Done()
|
||||||
|
MyProgress.InformationTemporary = "An error occurred while calculating user metrics."
|
||||||
|
Finally
|
||||||
|
MyProgress.Visible(, False) = False
|
||||||
|
ChangeControlsEnabled(False)
|
||||||
|
_CalculationInProgress = False
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private _RefillInProgress As Boolean = False
|
||||||
|
Private Sub RefillList()
|
||||||
|
If Not _CalculationInProgress AndAlso Not _RefillInProgress AndAlso MyUsers.Count > 0 Then
|
||||||
|
_RefillInProgress = True
|
||||||
|
ControlInvokeFast(LIST_DATA, Sub() LIST_DATA.Items.Clear(), EDP.None)
|
||||||
|
If MyUsers.Count > 0 Then
|
||||||
|
Dim i% = 0
|
||||||
|
Dim g As Func(Of UserOpt, ListViewGroup) = Function(u) If(LetterGroups.Count > 1, LetterGroups(u.Letter), Nothing)
|
||||||
|
Dim comparer As IComparer(Of UserOpt)
|
||||||
|
|
||||||
|
Select Case True
|
||||||
|
Case OPT_DATE.Checked : comparer = MyComparerDate
|
||||||
|
Case OPT_AMOUNT.Checked : comparer = MyComparerAmount
|
||||||
|
Case Else : comparer = MyComparerSize
|
||||||
|
End Select
|
||||||
|
DirectCast(comparer, ComparerDate).Order = IIf(OPT_ASC.Checked, SortOrder.Ascending, SortOrder.Descending)
|
||||||
|
|
||||||
|
MyUsers.Sort(comparer)
|
||||||
|
ControlInvokeFast(LIST_DATA, Sub()
|
||||||
|
Dim user As UserOpt
|
||||||
|
Dim gg As Boolean = CH_GROUP_COL.Checked
|
||||||
|
Dim colUsers As New Dictionary(Of String, List(Of UserOpt))
|
||||||
|
Dim colUsersNo As New List(Of UserOpt)
|
||||||
|
Dim lvi As ListViewItem
|
||||||
|
Dim s#
|
||||||
|
Dim sn$
|
||||||
|
|
||||||
|
For Each user In MyUsers
|
||||||
|
If gg And Not user.CollectionName.IsEmptyString Then
|
||||||
|
If colUsers.ContainsKey(user.CollectionName) Then
|
||||||
|
colUsers(user.CollectionName).Add(user)
|
||||||
|
Else
|
||||||
|
colUsers.Add(user.CollectionName, New List(Of UserOpt) From {user})
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
colUsersNo.Add(user)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
|
||||||
|
If colUsers.Count > 0 Then
|
||||||
|
For Each kv As KeyValuePair(Of String, List(Of UserOpt)) In colUsers
|
||||||
|
sn = "Mb"
|
||||||
|
s = kv.Value.Sum(Function(v) v.TotalSize) / 1024 / 1024
|
||||||
|
If s > 1000 Then s /= 1024 : sn = "Gb"
|
||||||
|
lvi = New ListViewItem($"Collection: {kv.Key}: {s.RoundVal(2).NumToString(SizeNumberProvider)}{sn}") With {
|
||||||
|
.Tag = kv.Value(0),
|
||||||
|
.Name = Settings.GetUser(kv.Value(0).User, True).Key,
|
||||||
|
.Group = g(kv.Value(0))
|
||||||
|
}
|
||||||
|
LIST_DATA.Items.Add(lvi)
|
||||||
|
For Each user In kv.Value : LIST_DATA.Items.Add(user.GetLVI(g(user), gg)) : Next
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
|
||||||
|
If colUsersNo.Count > 0 Then
|
||||||
|
For Each user In colUsersNo : LIST_DATA.Items.Add(user.GetLVI(g(user), gg)) : Next
|
||||||
|
End If
|
||||||
|
|
||||||
|
COL_DEFAULT.Width = -2
|
||||||
|
End Sub, EDP.None)
|
||||||
|
End If
|
||||||
|
_RefillInProgress = False
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "View"
|
||||||
|
Private Sub OPT_SORT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DATE.Click, OPT_SIZE.Click, OPT_AMOUNT.Click
|
||||||
|
If Not Sender.Checked Then
|
||||||
|
Sender.Checked = True
|
||||||
|
Else
|
||||||
|
Settings.UMetrics_What.Value = Sender.Tag
|
||||||
|
For Each obj As ToolStripMenuItem In {OPT_DATE, OPT_SIZE, OPT_AMOUNT}
|
||||||
|
If Not obj Is Sender Then obj.Checked = False
|
||||||
|
Next
|
||||||
|
RefillList()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub OPT_ASC_DESC_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_ASC.Click, OPT_DESC.Click
|
||||||
|
If Not Sender.Checked Then
|
||||||
|
Sender.Checked = True
|
||||||
|
Else
|
||||||
|
Settings.UMetrics_Order.Value = Sender.Tag
|
||||||
|
For Each obj As ToolStripMenuItem In {OPT_ASC, OPT_DESC}
|
||||||
|
If Not obj Is Sender Then obj.Checked = False
|
||||||
|
Next
|
||||||
|
RefillList()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub CH_GROUP_DRIVE_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles CH_GROUP_DRIVE.Click
|
||||||
|
LIST_DATA.ShowGroups = Sender.Checked
|
||||||
|
Settings.UMetrics_ShowDrives.Value = Sender.Checked
|
||||||
|
End Sub
|
||||||
|
Private Sub CH_GROUP_COL_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles CH_GROUP_COL.Click
|
||||||
|
Settings.UMetrics_ShowCollections.Value = Sender.Checked
|
||||||
|
RefillList()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Context handlers"
|
||||||
|
Private Function GetUserFromList() As UserOpt
|
||||||
|
Try
|
||||||
|
If LIST_DATA.SelectedItems.Count > 0 Then
|
||||||
|
Dim i As ListViewItem = LIST_DATA.SelectedItems(0)
|
||||||
|
If Not i Is Nothing Then Return i.Tag
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Private Sub CONTEXT_BTT_FIND_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_FIND.Click
|
||||||
|
MainFrameObj.FocusUser(If(GetUserFromList()?.Key, String.Empty), True)
|
||||||
|
End Sub
|
||||||
|
Private Sub CONTEXT_BTT_INFO_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_INFO.Click
|
||||||
|
Dim info$ = If(GetUserFromList()?.GetInfornation(), String.Empty)
|
||||||
|
If Not info.IsEmptyString Then MsgBoxE({info, "User information"})
|
||||||
|
End Sub
|
||||||
|
Private Sub CONTEXT_BTT_OPEN_FOLDER_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_OPEN_FOLDER.Click
|
||||||
|
OpenUserFolder()
|
||||||
|
End Sub
|
||||||
|
Private Sub CONTEXT_BTT_OPEN_SITE_Click(sender As Object, e As EventArgs) Handles CONTEXT_BTT_OPEN_SITE.Click
|
||||||
|
Dim u As UserOpt = GetUserFromList()
|
||||||
|
If Not u Is Nothing Then u.User.OpenSite()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "List handlers"
|
||||||
|
Private Sub LIST_DATA_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_DATA.MouseDoubleClick
|
||||||
|
OpenUserFolder()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Functions"
|
||||||
|
Private Sub OpenUserFolder()
|
||||||
|
Dim u As UserOpt = GetUserFromList()
|
||||||
|
If Not u Is Nothing Then u.User.OpenFolder()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -122,6 +122,8 @@ Friend Class ListImagesLoader
|
|||||||
UserDataList.Clear()
|
UserDataList.Clear()
|
||||||
UpdateInProgress = False
|
UpdateInProgress = False
|
||||||
End If
|
End If
|
||||||
|
Else
|
||||||
|
UpdateInProgress = False
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
Dim t As New List(Of Task)
|
Dim t As New List(Of Task)
|
||||||
|
|||||||
20
SCrawler/MainFrame.Designer.vb
generated
@@ -51,7 +51,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Me.BTT_EDIT_USER = New System.Windows.Forms.ToolStripButton()
|
Me.BTT_EDIT_USER = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_DELETE_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_REFRESH = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_SHOW_INFO = 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_FEED = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_CHANNELS = New System.Windows.Forms.ToolStripButton()
|
Me.BTT_CHANNELS = New System.Windows.Forms.ToolStripButton()
|
||||||
Me.BTT_DOWN_SAVED = New System.Windows.Forms.ToolStripButton()
|
Me.BTT_DOWN_SAVED = New System.Windows.Forms.ToolStripButton()
|
||||||
@@ -125,6 +125,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Me.BTT_TRAY_SHOW_HIDE = New System.Windows.Forms.ToolStripMenuItem()
|
Me.BTT_TRAY_SHOW_HIDE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
Me.BTT_TRAY_CLOSE = New System.Windows.Forms.ToolStripMenuItem()
|
Me.BTT_TRAY_CLOSE = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
Me.BTT_TRAY_CLOSE_NO_SCRIPT = New System.Windows.Forms.ToolStripMenuItem()
|
Me.BTT_TRAY_CLOSE_NO_SCRIPT = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.BTT_TRAY_DOWNLOADER = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
@@ -327,8 +328,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Me.BTT_SHOW_INFO.Name = "BTT_SHOW_INFO"
|
Me.BTT_SHOW_INFO.Name = "BTT_SHOW_INFO"
|
||||||
Me.BTT_SHOW_INFO.Size = New System.Drawing.Size(48, 22)
|
Me.BTT_SHOW_INFO.Size = New System.Drawing.Size(48, 22)
|
||||||
Me.BTT_SHOW_INFO.Text = "Info"
|
Me.BTT_SHOW_INFO.Text = "Info"
|
||||||
Me.BTT_SHOW_INFO.ToolTipText = "Left-click: open the 'Info' form (show download summary)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Right click: open the " &
|
Me.BTT_SHOW_INFO.ToolTipText = resources.GetString("BTT_SHOW_INFO.ToolTipText")
|
||||||
"'Missing' form (show information about missing posts)."
|
|
||||||
'
|
'
|
||||||
'BTT_FEED
|
'BTT_FEED
|
||||||
'
|
'
|
||||||
@@ -827,9 +827,9 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
'
|
'
|
||||||
'TRAY_CONTEXT
|
'TRAY_CONTEXT
|
||||||
'
|
'
|
||||||
Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, Me.BTT_TRAY_CHANNELS, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT})
|
Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, Me.BTT_TRAY_CHANNELS, Me.BTT_TRAY_DOWNLOADER, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT})
|
||||||
Me.TRAY_CONTEXT.Name = "TRAY_CONTEXT"
|
Me.TRAY_CONTEXT.Name = "TRAY_CONTEXT"
|
||||||
Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 170)
|
Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 192)
|
||||||
'
|
'
|
||||||
'BTT_TRAY_PAUSE_AUTOMATION
|
'BTT_TRAY_PAUSE_AUTOMATION
|
||||||
'
|
'
|
||||||
@@ -893,6 +893,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Me.BTT_TRAY_CLOSE_NO_SCRIPT.ToolTipText = "Close the program without executing the script"
|
Me.BTT_TRAY_CLOSE_NO_SCRIPT.ToolTipText = "Close the program without executing the script"
|
||||||
Me.BTT_TRAY_CLOSE_NO_SCRIPT.Visible = False
|
Me.BTT_TRAY_CLOSE_NO_SCRIPT.Visible = False
|
||||||
'
|
'
|
||||||
|
'BTT_TRAY_DOWNLOADER
|
||||||
|
'
|
||||||
|
Me.BTT_TRAY_DOWNLOADER.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
|
||||||
|
Me.BTT_TRAY_DOWNLOADER.Name = "BTT_TRAY_DOWNLOADER"
|
||||||
|
Me.BTT_TRAY_DOWNLOADER.Size = New System.Drawing.Size(170, 22)
|
||||||
|
Me.BTT_TRAY_DOWNLOADER.Text = "Downloader"
|
||||||
|
'
|
||||||
'MainFrame
|
'MainFrame
|
||||||
'
|
'
|
||||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
@@ -940,7 +947,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Private WithEvents BTT_CONTEXT_COL_MERGE As ToolStripMenuItem
|
Private WithEvents BTT_CONTEXT_COL_MERGE As ToolStripMenuItem
|
||||||
Private WithEvents LBL_JOBS_COUNT As ToolStripStatusLabel
|
Private WithEvents LBL_JOBS_COUNT As ToolStripStatusLabel
|
||||||
Private WithEvents BTT_DOWN_VIDEO As ToolStripMenuItem
|
Private WithEvents BTT_DOWN_VIDEO As ToolStripMenuItem
|
||||||
Private WithEvents BTT_SHOW_INFO As ToolStripButton
|
Private WithEvents BTT_SHOW_INFO As PersonalUtilities.Forms.Controls.KeyClick.ToolStripButtonKeyClick
|
||||||
Private WithEvents BTT_CHANNELS As ToolStripButton
|
Private WithEvents BTT_CHANNELS As ToolStripButton
|
||||||
Private WithEvents LIST_PROFILES As ListView
|
Private WithEvents LIST_PROFILES As ListView
|
||||||
Private WithEvents MENU_VIEW As ToolStripDropDownButton
|
Private WithEvents MENU_VIEW As ToolStripDropDownButton
|
||||||
@@ -997,4 +1004,5 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
|||||||
Private WithEvents BTT_TRAY_FEED_SHOW As ToolStripMenuItem
|
Private WithEvents BTT_TRAY_FEED_SHOW As ToolStripMenuItem
|
||||||
Friend WithEvents MENU_DOWN_ALL As ToolStripDropDownButton
|
Friend WithEvents MENU_DOWN_ALL As ToolStripDropDownButton
|
||||||
Private WithEvents BTT_TRAY_CHANNELS As ToolStripMenuItem
|
Private WithEvents BTT_TRAY_CHANNELS As ToolStripMenuItem
|
||||||
|
Private WithEvents BTT_TRAY_DOWNLOADER As ToolStripMenuItem
|
||||||
End Class
|
End Class
|
||||||
@@ -183,6 +183,11 @@
|
|||||||
<metadata name="Toolbar_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="Toolbar_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>132, 17</value>
|
<value>132, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<data name="BTT_SHOW_INFO.ToolTipText" xml:space="preserve">
|
||||||
|
<value>Left-click: open the 'Info' form (show download summary).
|
||||||
|
Right click: open the 'Missing' form (show information about missing posts).
|
||||||
|
Ctrl+Shift+Click: open the "User metrics' form (show information about the user's metrics (such as size, number of files, etc.)).</value>
|
||||||
|
</data>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="MENU_VIEW.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ Public Class MainFrame
|
|||||||
Private MyMissingPosts As MissingPostsForm
|
Private MyMissingPosts As MissingPostsForm
|
||||||
Private MyFeed As DownloadFeedForm
|
Private MyFeed As DownloadFeedForm
|
||||||
Private MySearch As UserSearchForm
|
Private MySearch As UserSearchForm
|
||||||
|
Private MyUserMetrics As UsersInfoForm = Nothing
|
||||||
Private _UFinit As Boolean = True
|
Private _UFinit As Boolean = True
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Initializer"
|
#Region "Initializer"
|
||||||
@@ -57,7 +58,7 @@ Public Class MainFrame
|
|||||||
YouTube.MyCache = Settings.Cache
|
YouTube.MyCache = Settings.Cache
|
||||||
YouTube.MyYouTubeSettings = New YouTube.YTSettings_Internal
|
YouTube.MyYouTubeSettings = New YouTube.YTSettings_Internal
|
||||||
UpdateYouTubeSettings()
|
UpdateYouTubeSettings()
|
||||||
MainProgress = New Toolbars.MyProgress(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS, "Downloading profiles' data") With {
|
MainProgress = New MyProgressExt(Toolbar_BOTTOM, PR_MAIN, LBL_STATUS, "Downloading profiles' data") With {
|
||||||
.ResetProgressOnMaximumChanges = False, .Visible = False}
|
.ResetProgressOnMaximumChanges = False, .Visible = False}
|
||||||
Downloader = New TDownloader
|
Downloader = New TDownloader
|
||||||
InfoForm = New DownloadedInfoForm
|
InfoForm = New DownloadedInfoForm
|
||||||
@@ -158,6 +159,7 @@ Public Class MainFrame
|
|||||||
VideoDownloader.DisposeIfReady()
|
VideoDownloader.DisposeIfReady()
|
||||||
MySavedPosts.DisposeIfReady()
|
MySavedPosts.DisposeIfReady()
|
||||||
MySearch.DisposeIfReady()
|
MySearch.DisposeIfReady()
|
||||||
|
MyUserMetrics.DisposeIfReady()
|
||||||
MyView.Dispose(Settings.Design)
|
MyView.Dispose(Settings.Design)
|
||||||
Settings.Dispose()
|
Settings.Dispose()
|
||||||
Else
|
Else
|
||||||
@@ -401,13 +403,18 @@ CloseResume:
|
|||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Info, Feed, Channels, Saved posts"
|
#Region "Info, Feed, Channels, Saved posts"
|
||||||
Private Sub BTT_SHOW_INFO_MouseDown(sender As Object, e As MouseEventArgs) Handles BTT_SHOW_INFO.MouseDown
|
Private Sub BTT_SHOW_INFO_KeyClick(ByVal Sender As Object, ByVal e As Controls.KeyClick.KeyClickEventArgs) Handles BTT_SHOW_INFO.KeyClick
|
||||||
If e.Button = MouseButtons.Right Then
|
If e.MouseButton = MouseButtons.Right Then
|
||||||
If MyMissingPosts Is Nothing Then MyMissingPosts = New MissingPostsForm
|
If MyMissingPosts Is Nothing Then MyMissingPosts = New MissingPostsForm
|
||||||
If MyMissingPosts.Visible Then MyMissingPosts.BringToFront() Else MyMissingPosts.Show()
|
If MyMissingPosts.Visible Then MyMissingPosts.BringToFront() Else MyMissingPosts.Show()
|
||||||
ElseIf e.Button = MouseButtons.Left Then
|
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()
|
InfoForm.FormShow()
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
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
|
||||||
@@ -445,9 +452,9 @@ CloseResume:
|
|||||||
Downloader.AddRange(Settings.GetUsers(UserExistsPredicate), e.IncludeInTheFeed)
|
Downloader.AddRange(Settings.GetUsers(UserExistsPredicate), e.IncludeInTheFeed)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_DOWN_SITE_FULL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL.KeyClick
|
Private Sub BTT_DOWN_SITE_FULL_KeyClick(sender As Object, e As MyKeyEventArgs) Handles BTT_DOWN_SITE_FULL.KeyClick
|
||||||
DownloadSiteFull(False, e.IncludeInTheFeed)
|
DownloadSiteFull(False, e.IncludeInTheFeed, e.Shift)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean)
|
Private Sub DownloadSiteFull(ByVal ReadyForDownloadOnly As Boolean, ByVal IncludeInTheFeed As Boolean, Optional ByVal IgnoreExists As Boolean = False)
|
||||||
Using f As New SiteSelectionForm(Settings.LatestDownloadedSites.ValuesList)
|
Using f As New SiteSelectionForm(Settings.LatestDownloadedSites.ValuesList)
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
If f.DialogResult = DialogResult.OK Then
|
If f.DialogResult = DialogResult.OK Then
|
||||||
@@ -455,7 +462,7 @@ CloseResume:
|
|||||||
Settings.LatestDownloadedSites.AddRange(f.SelectedSites)
|
Settings.LatestDownloadedSites.AddRange(f.SelectedSites)
|
||||||
Settings.LatestDownloadedSites.Update()
|
Settings.LatestDownloadedSites.Update()
|
||||||
If f.SelectedSites.Count > 0 Then
|
If f.SelectedSites.Count > 0 Then
|
||||||
Downloader.AddRange(Settings.GetUsers(Function(u) f.SelectedSites.Contains(u.Site) And u.Exists And
|
Downloader.AddRange(Settings.GetUsers(Function(u) f.SelectedSites.Contains(u.Site) And (u.Exists Or IgnoreExists) And
|
||||||
(Not ReadyForDownloadOnly Or u.ReadyForDownload)), IncludeInTheFeed)
|
(Not ReadyForDownloadOnly Or u.ReadyForDownload)), IncludeInTheFeed)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -506,7 +513,7 @@ CloseResume:
|
|||||||
TrayIcon.ContextMenuStrip.Hide()
|
TrayIcon.ContextMenuStrip.Hide()
|
||||||
MainFrameObj.PauseButtons.UpdatePauseButtons()
|
MainFrameObj.PauseButtons.UpdatePauseButtons()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_DOWN_VIDEO_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_VIDEO.Click
|
Private Sub BTT_DOWN_VIDEO_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_VIDEO.Click, BTT_TRAY_DOWNLOADER.Click
|
||||||
VideoDownloader.FormShow()
|
VideoDownloader.FormShow()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_DOWN_STOP_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_STOP.Click
|
Private Sub BTT_DOWN_STOP_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_STOP.Click
|
||||||
@@ -1206,15 +1213,19 @@ CloseResume:
|
|||||||
FocusUser(Key, True)
|
FocusUser(Key, True)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overloads Sub FocusUser(ByVal Key As String, Optional ByVal ActivateMe As Boolean = False)
|
Friend Overloads Sub FocusUser(ByVal Key As String, Optional ByVal ActivateMe As Boolean = False)
|
||||||
|
If Not Key.IsEmptyString Then
|
||||||
Dim a As Action = Sub()
|
Dim a As Action = Sub()
|
||||||
Dim i% = LIST_PROFILES.Items.IndexOfKey(Key)
|
Dim i% = LIST_PROFILES.Items.IndexOfKey(Key)
|
||||||
If i < 0 Then
|
If i < 0 Then
|
||||||
Dim u As IUserData = Settings.GetUser(Key, True)
|
Dim u As IUserData = Settings.GetUser(Key, True)
|
||||||
If Not u Is Nothing Then
|
If Not u Is Nothing Then
|
||||||
|
i = LIST_PROFILES.Items.IndexOfKey(u.Key)
|
||||||
|
If i < 0 Then
|
||||||
UserListUpdate(u, True)
|
UserListUpdate(u, True)
|
||||||
i = LIST_PROFILES.Items.IndexOfKey(u.Key)
|
i = LIST_PROFILES.Items.IndexOfKey(u.Key)
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
If i >= 0 Then
|
If i >= 0 Then
|
||||||
LIST_PROFILES.Select()
|
LIST_PROFILES.Select()
|
||||||
LIST_PROFILES.SelectedIndices.Clear()
|
LIST_PROFILES.SelectedIndices.Clear()
|
||||||
@@ -1226,6 +1237,7 @@ CloseResume:
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
If LIST_PROFILES.InvokeRequired Then LIST_PROFILES.Invoke(a) Else a.Invoke
|
If LIST_PROFILES.InvokeRequired Then LIST_PROFILES.Invoke(a) Else a.Invoke
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Toolbar bottom"
|
#Region "Toolbar bottom"
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ Friend Module MainMod
|
|||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
#End Region
|
#End Region
|
||||||
Friend Property MainProgress As MyProgress
|
Friend Property MainProgress As MyProgressExt
|
||||||
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal IsCollection As Boolean) As ListViewGroup()
|
Friend Function GetLviGroupName(ByVal Host As SettingsHost, ByVal IsCollection As Boolean) As ListViewGroup()
|
||||||
Dim l As New List(Of ListViewGroup)
|
Dim l As New List(Of ListViewGroup)
|
||||||
Dim t$
|
Dim t$
|
||||||
|
|||||||
@@ -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.4.28.0")>
|
<Assembly: AssemblyVersion("2023.6.8.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.4.28.0")>
|
<Assembly: AssemblyFileVersion("2023.6.8.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
176
SCrawler/MyProgressExt.vb
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
' 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 PersonalUtilities.Forms.Toolbars
|
||||||
|
Friend Class PreProgress : Implements IDisposable
|
||||||
|
Private ReadOnly Progress As MyProgressExt = Nothing
|
||||||
|
Private ReadOnly ProgressExists As Boolean = False
|
||||||
|
Private ReadOnly Property Ready As Boolean
|
||||||
|
Get
|
||||||
|
Return ProgressExists And Not disposedValue
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Sub New(ByVal PR As MyProgress)
|
||||||
|
If Not PR Is Nothing AndAlso TypeOf PR Is MyProgressExt Then
|
||||||
|
Progress = PR
|
||||||
|
ProgressExists = True
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private _Maximum As Integer = 0
|
||||||
|
Friend Sub ChangeMax(ByVal Value As Integer, Optional ByVal Add As Boolean = True)
|
||||||
|
If Ready Then
|
||||||
|
If Add Then
|
||||||
|
_Maximum += Value
|
||||||
|
If Value > 0 Then Progress.Maximum0 += Value
|
||||||
|
Else
|
||||||
|
_Maximum = Value
|
||||||
|
Progress.Maximum0 = Value
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private CumulVal As Integer = 0
|
||||||
|
Friend Sub Perform(Optional ByVal Value As Integer = 1)
|
||||||
|
If Ready Then
|
||||||
|
CumulVal += Value
|
||||||
|
Progress.Perform0(Value)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Friend Sub Reset()
|
||||||
|
_Maximum = 0
|
||||||
|
CumulVal = 0
|
||||||
|
End Sub
|
||||||
|
Friend Sub Done()
|
||||||
|
If Ready Then
|
||||||
|
Dim v# = _Maximum - CumulVal
|
||||||
|
If v > 0 Then
|
||||||
|
With Progress
|
||||||
|
If v + .Value0 > .Maximum0 Then v = .Maximum0 - .Value0
|
||||||
|
If v < 0 Then v = 0
|
||||||
|
.Perform0(v)
|
||||||
|
Reset()
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
#Region "IDisposable Support"
|
||||||
|
Private disposedValue As Boolean = False
|
||||||
|
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue Then
|
||||||
|
If disposing Then Done()
|
||||||
|
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
|
||||||
|
Friend Class MyProgressExt : Inherits MyProgress
|
||||||
|
Private ReadOnly _Progress0ChangedEventHandlers As List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
Friend Custom Event Progress0Changed As EventHandler(Of ProgressEventArgs)
|
||||||
|
AddHandler(ByVal h As EventHandler(Of ProgressEventArgs))
|
||||||
|
If Not _Progress0ChangedEventHandlers.Contains(h) Then _Progress0ChangedEventHandlers.Add(h)
|
||||||
|
End AddHandler
|
||||||
|
RemoveHandler(ByVal h As EventHandler(Of ProgressEventArgs))
|
||||||
|
_Progress0ChangedEventHandlers.Remove(h)
|
||||||
|
End RemoveHandler
|
||||||
|
RaiseEvent(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
|
If _Progress0ChangedEventHandlers.Count > 0 Then
|
||||||
|
Try
|
||||||
|
For i% = 0 To _Progress0ChangedEventHandlers.Count - 1
|
||||||
|
Try : _Progress0ChangedEventHandlers(i).Invoke(Sender, e) : Catch : End Try
|
||||||
|
Next
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
End If
|
||||||
|
End RaiseEvent
|
||||||
|
End Event
|
||||||
|
Private ReadOnly _Maximum0ChangedEventHandlers As List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
Friend Custom Event Maximum0Changed As EventHandler(Of ProgressEventArgs)
|
||||||
|
AddHandler(ByVal h As EventHandler(Of ProgressEventArgs))
|
||||||
|
If Not _Maximum0ChangedEventHandlers.Contains(h) Then _Maximum0ChangedEventHandlers.Add(h)
|
||||||
|
End AddHandler
|
||||||
|
RemoveHandler(ByVal h As EventHandler(Of ProgressEventArgs))
|
||||||
|
_Maximum0ChangedEventHandlers.Remove(h)
|
||||||
|
End RemoveHandler
|
||||||
|
RaiseEvent(ByVal Sender As Object, ByVal e As ProgressEventArgs)
|
||||||
|
If _Maximum0ChangedEventHandlers.Count > 0 Then
|
||||||
|
Try
|
||||||
|
For i% = 0 To _Maximum0ChangedEventHandlers.Count - 1
|
||||||
|
Try : _Maximum0ChangedEventHandlers(i).Invoke(Sender, e) : Catch : End Try
|
||||||
|
Next
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
End If
|
||||||
|
End RaiseEvent
|
||||||
|
End Event
|
||||||
|
Friend Sub New()
|
||||||
|
_Progress0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
_Maximum0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
End Sub
|
||||||
|
Friend Sub New(ByRef StatusStrip As StatusStrip, ByRef ProgressBar As ToolStripProgressBar, ByRef Label As ToolStripStatusLabel,
|
||||||
|
Optional ByVal Information As String = Nothing)
|
||||||
|
MyBase.New(StatusStrip, ProgressBar, Label, Information)
|
||||||
|
_Progress0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
_Maximum0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
End Sub
|
||||||
|
Friend Sub New(ByRef ProgressBar As ProgressBar, ByRef Label As Label, Optional ByVal Information As String = Nothing)
|
||||||
|
MyBase.New(ProgressBar, Label, Information)
|
||||||
|
_Progress0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
_Maximum0ChangedEventHandlers = New List(Of EventHandler(Of ProgressEventArgs))
|
||||||
|
End Sub
|
||||||
|
Private _Maximum0 As Double = 0
|
||||||
|
Friend Property Maximum0 As Double
|
||||||
|
Get
|
||||||
|
Return _Maximum0
|
||||||
|
End Get
|
||||||
|
Set(ByVal v As Double)
|
||||||
|
Dim b As Boolean = Not _Maximum0 = v
|
||||||
|
_Maximum0 = v
|
||||||
|
If ResetProgressOnMaximumChanges Then Value0 = 0
|
||||||
|
If b Then RaiseEvent Maximum0Changed(Me, Nothing)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Friend Property Value0 As Double = 0
|
||||||
|
Friend Sub Perform0(Optional ByVal Value As Double = 1)
|
||||||
|
Value0 += Value
|
||||||
|
If Perform(0, 10, False, False) Then RaiseEvent Progress0Changed(Me, Nothing)
|
||||||
|
End Sub
|
||||||
|
Public Overloads Overrides Sub Perform(Optional ByVal Value As Double = 1)
|
||||||
|
If Perform(Value, PerformMod, True, True) Then OnProgressChanged()
|
||||||
|
End Sub
|
||||||
|
Public Overloads Function Perform(ByVal Value As Double, ByVal pm As Integer, ByVal SetText As Boolean, ByVal InvokeProgressChangeHandler As Boolean) As Boolean
|
||||||
|
Me.Value += Value
|
||||||
|
If Me.Value < 0 Then Me.Value = 0
|
||||||
|
Dim v# = Me.Value + Value0
|
||||||
|
Dim m# = Maximum + Maximum0
|
||||||
|
If pm = 0 OrElse (v Mod pm) = 0 OrElse v = m Then PerformImpl(GetPercentage(v, m), SetText, InvokeProgressChangeHandler) : Return True
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
Public Overrides Sub Done()
|
||||||
|
Value0 = Maximum0
|
||||||
|
MyBase.Done()
|
||||||
|
End Sub
|
||||||
|
Public Overrides Sub Reset()
|
||||||
|
MyBase.Reset()
|
||||||
|
Value0 = 0
|
||||||
|
Maximum0 = 0
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue And disposing Then
|
||||||
|
_Progress0ChangedEventHandlers.Clear()
|
||||||
|
_Maximum0ChangedEventHandlers.Clear()
|
||||||
|
End If
|
||||||
|
MyBase.Dispose(disposing)
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
@@ -23,6 +23,15 @@ Namespace Plugin.Hosts
|
|||||||
End Property
|
End Property
|
||||||
Friend Property Instance As UserDataBase
|
Friend Property Instance As UserDataBase
|
||||||
Friend ReadOnly Property ExternalSource As IDownloadableMedia = Nothing
|
Friend ReadOnly Property ExternalSource As IDownloadableMedia = Nothing
|
||||||
|
Public Overrides ReadOnly Property Exists As Boolean
|
||||||
|
Get
|
||||||
|
If SiteKey = API.YouTube.YouTubeSiteKey Then
|
||||||
|
Return MyBase.Exists
|
||||||
|
Else
|
||||||
|
Return _Exists
|
||||||
|
End If
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Public Overrides Property File As SFile
|
Public Overrides Property File As SFile
|
||||||
Get
|
Get
|
||||||
Return _File
|
Return _File
|
||||||
@@ -128,7 +137,7 @@ Namespace Plugin.Hosts
|
|||||||
End Sub
|
End Sub
|
||||||
Public Overrides Sub Load(ByVal f As SFile)
|
Public Overrides Sub Load(ByVal f As SFile)
|
||||||
MyBase.Load(f)
|
MyBase.Load(f)
|
||||||
If _Exists Then _Exists = File.Exists
|
If _Exists Then _Exists = Not MediaState = UserMediaStates.Downloaded OrElse File.Exists
|
||||||
End Sub
|
End Sub
|
||||||
Public Overrides Sub Save()
|
Public Overrides Sub Save()
|
||||||
If FileSettings.IsEmptyString Then
|
If FileSettings.IsEmptyString Then
|
||||||
@@ -142,6 +151,9 @@ Namespace Plugin.Hosts
|
|||||||
x.Save(FileSettings)
|
x.Save(FileSettings)
|
||||||
End Using
|
End Using
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Overrides Function GetHashCode() As Integer
|
||||||
|
Return URL.GetHashCode
|
||||||
|
End Function
|
||||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
If Not disposedValue And disposing Then Instance.DisposeIfReady() : ExternalSource.DisposeIfReady(False)
|
If Not disposedValue And disposing Then Instance.DisposeIfReady() : ExternalSource.DisposeIfReady(False)
|
||||||
MyBase.Dispose(disposing)
|
MyBase.Dispose(disposing)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ Namespace Plugin.Hosts
|
|||||||
UseInternalDownloader = Not ExternalPlugin.GetType.GetCustomAttribute(Of Attributes.UseInternalDownloader)() Is Nothing
|
UseInternalDownloader = Not ExternalPlugin.GetType.GetCustomAttribute(Of Attributes.UseInternalDownloader)() Is Nothing
|
||||||
AddHandler ExternalPlugin.ProgressChanged, AddressOf ExternalPlugin_ProgressChanged
|
AddHandler ExternalPlugin.ProgressChanged, AddressOf ExternalPlugin_ProgressChanged
|
||||||
AddHandler ExternalPlugin.ProgressMaximumChanged, AddressOf ExternalPlugin_ProgressMaximumChanged
|
AddHandler ExternalPlugin.ProgressMaximumChanged, AddressOf ExternalPlugin_ProgressMaximumChanged
|
||||||
|
AddHandler ExternalPlugin.ProgressPreChanged, AddressOf ExternalPlugin_Progress0Changed
|
||||||
|
AddHandler ExternalPlugin.ProgressPreMaximumChanged, AddressOf ExternalPlugin_Progress0MaximumChanged
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
If Loading Then
|
If Loading Then
|
||||||
@@ -111,6 +113,12 @@ Namespace Plugin.Hosts
|
|||||||
Private Sub ExternalPlugin_ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
Private Sub ExternalPlugin_ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
||||||
Progress.Maximum = Value + If(Add, Progress.Maximum, 0)
|
Progress.Maximum = Value + If(Add, Progress.Maximum, 0)
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub ExternalPlugin_Progress0Changed(ByVal Value As Integer)
|
||||||
|
ProgressPre.Perform(Value)
|
||||||
|
End Sub
|
||||||
|
Private Sub ExternalPlugin_Progress0MaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
|
||||||
|
ProgressPre.ChangeMax(Value, Add)
|
||||||
|
End Sub
|
||||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
If disposing And Not disposedValue Then
|
If disposing And Not disposedValue Then
|
||||||
With ExternalPlugin
|
With ExternalPlugin
|
||||||
|
|||||||
@@ -224,6 +224,7 @@
|
|||||||
<Compile Include="API\YouTube\SiteSettings.vb" />
|
<Compile Include="API\YouTube\SiteSettings.vb" />
|
||||||
<Compile Include="API\YouTube\UserData.vb" />
|
<Compile Include="API\YouTube\UserData.vb" />
|
||||||
<Compile Include="API\YouTube\UserExchangeOptions.vb" />
|
<Compile Include="API\YouTube\UserExchangeOptions.vb" />
|
||||||
|
<Compile Include="API\YouTube\YTPreProgress.vb" />
|
||||||
<Compile Include="API\YouTube\YTSettings_Internal.vb" />
|
<Compile Include="API\YouTube\YTSettings_Internal.vb" />
|
||||||
<Compile Include="Download\ActiveDownloadingProgress.Designer.vb">
|
<Compile Include="Download\ActiveDownloadingProgress.Designer.vb">
|
||||||
<DependentUpon>ActiveDownloadingProgress.vb</DependentUpon>
|
<DependentUpon>ActiveDownloadingProgress.vb</DependentUpon>
|
||||||
@@ -309,6 +310,12 @@
|
|||||||
<Compile Include="Editors\ColorPicker.vb">
|
<Compile Include="Editors\ColorPicker.vb">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Editors\UsersInfoForm.Designer.vb">
|
||||||
|
<DependentUpon>UsersInfoForm.vb</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Editors\UsersInfoForm.vb">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="GlobalSuppressions.vb" />
|
<Compile Include="GlobalSuppressions.vb" />
|
||||||
<Compile Include="MainFrameObjects.vb" />
|
<Compile Include="MainFrameObjects.vb" />
|
||||||
<Compile Include="My Project\Resources.Designer.vb">
|
<Compile Include="My Project\Resources.Designer.vb">
|
||||||
@@ -316,6 +323,7 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="MyProgressExt.vb" />
|
||||||
<Compile Include="PluginsEnvironment\Attributes\Attributes.vb" />
|
<Compile Include="PluginsEnvironment\Attributes\Attributes.vb" />
|
||||||
<Compile Include="PluginsEnvironment\Hosts\DownloadableMediaHost.vb" />
|
<Compile Include="PluginsEnvironment\Hosts\DownloadableMediaHost.vb" />
|
||||||
<Compile Include="PluginsEnvironment\Hosts\UserDataHost.vb" />
|
<Compile Include="PluginsEnvironment\Hosts\UserDataHost.vb" />
|
||||||
@@ -523,6 +531,9 @@
|
|||||||
<EmbeddedResource Include="Editors\UserCreatorForm.resx">
|
<EmbeddedResource Include="Editors\UserCreatorForm.resx">
|
||||||
<DependentUpon>UserCreatorForm.vb</DependentUpon>
|
<DependentUpon>UserCreatorForm.vb</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Editors\UsersInfoForm.resx">
|
||||||
|
<DependentUpon>UsersInfoForm.vb</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="MainFrame.resx">
|
<EmbeddedResource Include="MainFrame.resx">
|
||||||
<DependentUpon>MainFrame.vb</DependentUpon>
|
<DependentUpon>MainFrame.vb</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
SearchInDescription = New XMLValue(Of Boolean)("SearchInDescription", False, MyXML, n)
|
SearchInDescription = New XMLValue(Of Boolean)("SearchInDescription", False, MyXML, n)
|
||||||
SearchInLabel = New XMLValue(Of Boolean)("SearchInLabel", False, MyXML, n)
|
SearchInLabel = New XMLValue(Of Boolean)("SearchInLabel", False, MyXML, n)
|
||||||
|
|
||||||
|
n = {"Metrics"}
|
||||||
|
UMetrics_What = New XMLValue(Of Integer)("What", -1, MyXML, n)
|
||||||
|
UMetrics_Order = New XMLValue(Of Integer)("Order", SortOrder.Descending, MyXML, n)
|
||||||
|
UMetrics_ShowDrives = New XMLValue(Of Boolean)("ShowDrives", True, MyXML, n)
|
||||||
|
UMetrics_ShowCollections = New XMLValue(Of Boolean)("ShowCollections", True, MyXML, n)
|
||||||
|
|
||||||
n = {"Defaults"}
|
n = {"Defaults"}
|
||||||
DefaultTemporary = New XMLValue(Of Boolean)("Temporary", False, MyXML, n)
|
DefaultTemporary = New XMLValue(Of Boolean)("Temporary", False, MyXML, n)
|
||||||
DefaultDownloadImages = New XMLValue(Of Boolean)("DownloadImages", True, MyXML, n)
|
DefaultDownloadImages = New XMLValue(Of Boolean)("DownloadImages", True, MyXML, n)
|
||||||
@@ -232,6 +238,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
FromChannelDownloadTopUse = New XMLValue(Of Boolean)("FromChannelDownloadTopUse", False, MyXML, n)
|
FromChannelDownloadTopUse = New XMLValue(Of Boolean)("FromChannelDownloadTopUse", False, MyXML, n)
|
||||||
FromChannelCopyImageToUser = New XMLValue(Of Boolean)("FromChannelCopyImageToUser", True, MyXML, n)
|
FromChannelCopyImageToUser = New XMLValue(Of Boolean)("FromChannelCopyImageToUser", True, MyXML, n)
|
||||||
UpdateUserDescriptionEveryTime = New XMLValue(Of Boolean)("UpdateUserDescriptionEveryTime", True, MyXML, n)
|
UpdateUserDescriptionEveryTime = New XMLValue(Of Boolean)("UpdateUserDescriptionEveryTime", True, MyXML, n)
|
||||||
|
UpdateUserIconBannerEveryTime = New XMLValue(Of Boolean)("UpdateUserIconBannerEveryTime", True, MyXML, n)
|
||||||
ScriptData = New XMLValueAttribute(Of String, Boolean)("ScriptData", "Use",,, MyXML, n)
|
ScriptData = New XMLValueAttribute(Of String, Boolean)("ScriptData", "Use",,, MyXML, n)
|
||||||
|
|
||||||
n = {"Users", "FileName"}
|
n = {"Users", "FileName"}
|
||||||
@@ -310,7 +317,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
End Using
|
End Using
|
||||||
|
|
||||||
Dim NeedUpdate As Boolean = False
|
Dim NeedUpdate As Boolean = False
|
||||||
Dim i%, indx% ', c%
|
Dim i%, indx%
|
||||||
Dim UsersListInitialCount% = UsersList.Count
|
Dim UsersListInitialCount% = UsersList.Count
|
||||||
Dim iUser As UserInfo
|
Dim iUser As UserInfo
|
||||||
Dim userFileExists As Boolean, pluginFound As Boolean
|
Dim userFileExists As Boolean, pluginFound As Boolean
|
||||||
@@ -349,9 +356,7 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
'Check paths
|
'Check paths
|
||||||
'c = IIf((Not .IncludedInCollection Or (.Merged Or .IsVirtual)) And Not .Plugin = PathPlugin.PluginKey, 1, 2)
|
userFileExists = .File.Exists
|
||||||
'URGENT: changed user file validation
|
|
||||||
userFileExists = .File.Exists ' SFile.GetPath(.File.CutPath(c - 1).Path).Exists(SFO.Path, False)
|
|
||||||
If Not pluginFound Or Not userFileExists Then
|
If Not pluginFound Or Not userFileExists Then
|
||||||
If Not .IsProtected Then
|
If Not .IsProtected Then
|
||||||
If userFileExists Then
|
If userFileExists Then
|
||||||
@@ -705,11 +710,18 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
Friend ReadOnly Property STDownloader_RemoveYTVideosOnClear 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_LoadYTVideos As XMLValue(Of Boolean)
|
||||||
#End Region
|
#End Region
|
||||||
|
#Region "User metrics"
|
||||||
|
Friend ReadOnly Property UMetrics_What As XMLValue(Of Integer)
|
||||||
|
Friend ReadOnly Property UMetrics_Order As XMLValue(Of Integer)
|
||||||
|
Friend ReadOnly Property UMetrics_ShowDrives As XMLValue(Of Boolean)
|
||||||
|
Friend ReadOnly Property UMetrics_ShowCollections As XMLValue(Of Boolean)
|
||||||
|
#End Region
|
||||||
#Region "User data"
|
#Region "User data"
|
||||||
Friend ReadOnly Property FromChannelDownloadTop As XMLValue(Of Integer)
|
Friend ReadOnly Property FromChannelDownloadTop As XMLValue(Of Integer)
|
||||||
Friend ReadOnly Property FromChannelDownloadTopUse As XMLValue(Of Boolean)
|
Friend ReadOnly Property FromChannelDownloadTopUse As XMLValue(Of Boolean)
|
||||||
Friend ReadOnly Property FromChannelCopyImageToUser As XMLValue(Of Boolean)
|
Friend ReadOnly Property FromChannelCopyImageToUser As XMLValue(Of Boolean)
|
||||||
Friend ReadOnly Property UpdateUserDescriptionEveryTime As XMLValue(Of Boolean)
|
Friend ReadOnly Property UpdateUserDescriptionEveryTime As XMLValue(Of Boolean)
|
||||||
|
Friend ReadOnly Property UpdateUserIconBannerEveryTime As XMLValue(Of Boolean)
|
||||||
#Region "File naming"
|
#Region "File naming"
|
||||||
Friend ReadOnly Property FileAddDateToFileName As XMLValue(Of Boolean)
|
Friend ReadOnly Property FileAddDateToFileName As XMLValue(Of Boolean)
|
||||||
Friend ReadOnly Property FileAddTimeToFileName As XMLValue(Of Boolean)
|
Friend ReadOnly Property FileAddTimeToFileName As XMLValue(Of Boolean)
|
||||||
|
|||||||