Compare commits

..

9 Commits

Author SHA1 Message Date
Andy
45adf735a7 2023.11.17.0 2023-11-17 02:30:23 +03:00
Andy
496c9487cd 2023.11.15.0
ADD FACEBOOK
SiteSettingsBase: update 'CLONE_PROPERTIES' function (exclude 'DoNotUse' attribute)
API.Instagram: handle 401 error
API.ThreadsNet.SiteSettings: make the class compatible for Facebook
xHanster, XVideos, PornHub, ThisVid: update download function for search queries
Hosts.PropertyValueHost: set the 'Exists' value based on the 'DoNotUse' attribute
Hosts.SettingsHost: use 'GetObjectMembers' instead of 'GetTypeInfo.DeclaredMembers' to get class members
2023-11-17 02:30:23 +03:00
Andy
96705f1c59 2023.11.13.1
PornHub: add playlists downloading
2023-11-13 23:18:21 +03:00
Andy
f08a5f9259 2023.11.13.0
API.JFF: update UserAgent start value
ActiveDownloadingProgress: fix unnecessary focus of inactive form
FeedMedia: add additional buttons to the context menu
FeedSpecialCollection: 'Favorite' feed does not appear in the feeds list if it is created manually
UserCreatorForm: disable account selection when opening an empty form
MainFrame: fix background image resizing on form state changes
SettingsHost: inherit path when cloning an instance
SettingsHostCollection: Extract user path change function to static
2023-11-13 20:53:32 +03:00
Andy
95cbb6aeb1 2023.11.12.2
API.Instagram: handle JSON primitive error (simple line)
API.OnlyFans: handle 401 error; handle file update error
API.Xhamster: handle 503 error
Scheduler: handle automation start error
2023-11-12 22:34:47 +03:00
Andy
5af0dcc46e 2023.11.12.1
YouTube: add cc and subtitles merge
2023-11-12 20:57:05 +03:00
Andy
f5789862ba 2023.11.12.0
Add special feeds
2023-11-12 20:34:53 +03:00
Andy
12c02580f6 2023.11.9.0
ADD MULTI-ACCOUNT

PluginProvider
IDownloadableMedia: added 'AccountName' property
IPluginContentProvider: added 'AccountName' property
ISiteSettings: added properties: 'AccountName', 'Temporary', 'AvailableText', 'DefaultInstance'; added functions: 'Clone', 'Update', 'Delete'; removed 'Load' function; implement 'IDisposable' interface
PropertyValue: added functions: 'BeginInit', 'EndInit', 'Clone'

YT
YouTubeSettings: make the class compatible for multi-acc
YouTubeMediaContainerBase: add 'AccountName' property

SCrawler
IUserData: add properties: 'HostStatic', 'AccountName'
ProfileSaved: add the ability to download saved posts from all accounts
SiteSettingsBase: add multi-acc support; add 'UserOptionsType' for future purposes; update initializers; update responser initializing; add 'CLONE_PROPERTIES' and 'CloneGetEmptySettingsInstance' functions; 'IDisposable' support
UserDataBase: add multi-acc support; change host retrieval method
DomainsContainer: implements 'IDisposable' interface

API.All sites: add multi-acc support; move the Icon and Image setting to the initializer; update initializer
API.Instagram: change some property types
API.Reddit: set 'AvailableText'; update 'UpdateRedGifsToken' and 'UserOptions' functions
API.Mastodon: remove 'MastodonDomains' class and 'SettingsForm' form; replace 'MastodonDomains' with 'DomainsContainer'; update functions 'IsMyUser' and 'IsMyImageVideo'; update to 'DefaultInstance' environment; update 'UserData.ResetCredentials' function
API.XVIDEOS: update to 'DefaultInstance' environment
API.Xhamster: update to 'DefaultInstance' environment

STDownloader: add multi-acc compatibility

SiteEditorForm: add option 'Download saved posts'; update providers; add additional providers; add multi-acc support

PluginsEnvironment: add 'PClonableAttribute'; add multi-acc support
2023-11-12 01:31:09 +03:00
Andy
6def34d5e9 2023.10.12.0
API.ThisVid: update parser ('SessionPosts')
2023-10-12 19:47:02 +03:00
123 changed files with 5352 additions and 1828 deletions

View File

@@ -39,5 +39,4 @@ I welcome requests! Follow these steps to contribute:
If I'm interested in a site you want to add, it may be added in future releases.
# Sites I will never develop
- Facebook
- Tumblr

View File

@@ -1,3 +1,33 @@
# 2023.11.17.0
*2023-11-17*
- Added
- **Facebook**
- **Multi-account**
- **Special feeds**
- Site settings: option `Download saved posts`
- Standalone downloader: support for multiple account
- PornHub: add playlists downloading
- YouTube: ability to download subtitles **and** `CC` if they both exists
- Other improvements
- PluginProvider
- `IDownloadableMedia`: added `AccountName` property
- `IPluginContentProvider`: added `AccountName` property
- `ISiteSettings`: added properties: `AccountName`, `Temporary`, `AvailableText`, `DefaultInstance`; added functions: `Clone`, `Update`, `Delete`; removed `Load` function; implement `IDisposable` interface
- `PropertyValue`: added functions: `BeginInit`, `EndInit`, `Clone`
- `Attributes.DoNotUse` - add `Value` field
- Fixed
- Instagram: handling 401 error
- OnlyFans: handling 401 error
- xHamster: handling 503 error
- xHamster: incorrect parsing of search queries
- XVideos: incorrect parsing of search queries
- ThisVid: incorrect parsing of search queries
- PornHub: incorrect parsing of search queries
- Automation: handle automation start error (in some cases) when changing scheduler
- Minor bugs
# 2023.10.10.0
*2023-10-10*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -12,7 +12,7 @@
:eu:
:greece:
A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, OnlyFans, Reddit, Twitter, Mastodon, Instagram, Threads, TikTok, RedGifs, JustForFans, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest).
A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, OnlyFans, Reddit, Twitter, Mastodon, Instagram, Threads, Facebook, TikTok, RedGifs, JustForFans, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest).
**If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)**
<!---Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
@@ -39,6 +39,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- Mastodon images and videos, saved (bookmarked) posts;
- Instagram images and videos, tagged posts, stories, saved posts;
- Threads images and videos;
- Facebook images and videos, saved posts;
- TikTok videos;
- Pinterest boards, users, saved posts;
- Imgur images, galleries and videos;
@@ -54,6 +55,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- **Advanced user management**
- **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every ```X``` minutes)
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files and subscriptions posts)
- Multiple accounts support
- Labeling users
- Create [download groups](https://github.com/AAndyProgram/SCrawler/wiki/Settings#download-groups)
- Adding users to favorites and temporary
@@ -76,6 +78,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
- **Mastodon**
- **Instagram**
- **Threads**
- **Facebook**
- JustForFans
- TikTok
- RedGifs
@@ -128,6 +131,7 @@ First, the program downloads the full profile. After the program downloads only
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#mastodon)
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
- [Threads](https://github.com/AAndyProgram/SCrawler/wiki/Settings#threads)
- [Facebook](https://github.com/AAndyProgram/SCrawler/wiki/Settings#facebook)
- [JustForFans](https://github.com/AAndyProgram/SCrawler/wiki/Settings#justforfans)
- [TikTok](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok)
- [RedGifs](https://github.com/AAndyProgram/SCrawler/wiki/Settings#redgifs)
@@ -195,7 +199,6 @@ F5-->[*]
Discord server: https://discord.gg/uFNUXvFFmg
[e-mail](mailto:andyprogram@proton.me): andyprogram@proton.me
<!--
[e-mail](mailto:andyprogram@proton.me): andyprogram@proton.me

View File

@@ -65,6 +65,12 @@ Namespace Plugin.Attributes
End Class
''' <summary>Attribute to disable some properties for host use</summary>
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class DoNotUse : Inherits Attribute
Public ReadOnly Value As Boolean = True
Public Sub New()
End Sub
Public Sub New(ByVal Value As Boolean)
Me.Value = Value
End Sub
End Class
''' <summary>Special property updater</summary>
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class PropertyUpdater : Inherits Attribute

View File

@@ -14,6 +14,7 @@ Namespace Plugin
ReadOnly Property SiteIcon As Drawing.Image
ReadOnly Property Site As String
ReadOnly Property SiteKey As String
Property AccountName As String
Property ThumbnailUrl As String
Property ThumbnailFile As String
Property Title As String

View File

@@ -15,6 +15,7 @@ Namespace Plugin
Property Thrower As IThrower
Property LogProvider As ILogProvider
Property Settings As ISiteSettings
Property AccountName As String
Property Name As String
Property ID As String
Property Options As String

View File

@@ -8,7 +8,7 @@
' but WITHOUT ANY WARRANTY
Imports System.Drawing
Namespace Plugin
Public Interface ISiteSettings
Public Interface ISiteSettings : Inherits IDisposable
Enum Download As Integer
Main = 0
SavedPosts = 1
@@ -17,6 +17,9 @@ Namespace Plugin
ReadOnly Property Icon As Icon
ReadOnly Property Image As Image
ReadOnly Property Site As String
Property AccountName As String
Property Temporary As Boolean
Property DefaultInstance As ISiteSettings
ReadOnly Property SubscriptionsAllowed As Boolean
Property Logger As ILogProvider
Function GetUserUrl(ByVal User As IPluginContentProvider) As String
@@ -25,9 +28,6 @@ Namespace Plugin
Function GetInstance(ByVal What As Download) As IPluginContentProvider
Function GetSingleMediaInstance(ByVal URL As String, ByVal OutputFile As String) As IDownloadableMedia
Function GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String
#Region "XML Support"
Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String)))
#End Region
#Region "Initialization"
Sub BeginInit()
Sub EndInit()
@@ -37,6 +37,7 @@ Namespace Plugin
Sub EndEdit()
#End Region
#Region "Site availability"
Property AvailableText As String
Function Available(ByVal What As Download, ByVal Silent As Boolean) As Boolean
Function ReadyToDownload(ByVal What As Download) As Boolean
#End Region
@@ -46,7 +47,10 @@ Namespace Plugin
Sub AfterDownload(ByVal User As Object, ByVal What As Download)
Sub DownloadDone(ByVal What As Download)
#End Region
Sub Update()
Function Clone(ByVal Full As Boolean) As ISiteSettings
Sub Delete()
Overloads Sub Update()
Overloads Sub Update(ByVal Source As ISiteSettings)
Sub Reset()
Sub OpenSettingsForm()
Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("Plugin provider for SCrawler")>
<Assembly: AssemblyCompany("AndyProgram")>
<Assembly: AssemblyProduct("SCrawler.PluginProvider")>
<Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyCopyright("Copyright © 2024")>
<Assembly: AssemblyTrademark("AndyProgram")>
<Assembly: ComVisible(False)>
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.10.1.0")>
<Assembly: AssemblyFileVersion("2023.10.1.0")>
<Assembly: AssemblyVersion("2023.11.17.0")>
<Assembly: AssemblyFileVersion("2023.11.17.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -11,6 +11,7 @@ Namespace Plugin
Public Event ValueChanged As IPropertyValue.ValueChangedEventHandler Implements IPropertyValue.ValueChanged
Public Property [Type] As Type Implements IPropertyValue.Type
Public Property OnChangeFunction As IPropertyValue.ValueChangedEventHandler
Private _Initialization As Boolean = False
''' <inheritdoc cref="PropertyValue.New(Object, Type, ByRef IPropertyValue.ValueChangedEventHandler)"/>
''' <exception cref="ArgumentNullException"></exception>
Public Sub New(ByVal InitValue As Object)
@@ -41,10 +42,25 @@ Namespace Plugin
End Get
Set(ByVal NewValue As Object)
_Value = NewValue
If Not OnChangeFunction Is Nothing Then OnChangeFunction.Invoke(Value)
RaiseEvent ValueChanged(_Value)
If Not _Initialization Then
If Not OnChangeFunction Is Nothing Then OnChangeFunction.Invoke(Value)
RaiseEvent ValueChanged(_Value)
End If
End Set
End Property
Public Sub BeginInit()
_Initialization = True
End Sub
Public Sub EndInit()
_Initialization = False
End Sub
Public Sub Clone(ByVal Source As PropertyValue)
_Initialization = True
Type = Source.Type
OnChangeFunction = Source.OnChangeFunction
_Value = Source._Value
_Initialization = False
End Sub
End Class
Public Interface IPropertyValue
''' <summary>Event for internal exchange</summary>

View File

@@ -28,8 +28,19 @@ Namespace API.YouTube.Base
End Structure
Public Structure Subtitles : Implements IIndexable, IComparable(Of Subtitles)
Public ID As String
Public Name As String
Private _Name As String
Public Property Name As String
Get
Dim n$ = _Name.IfNullOrEmpty(ID)
If CC Then n &= " (CC)"
Return n
End Get
Set(ByVal NewName As String)
_Name = NewName
End Set
End Property
Public Formats As String
Public CC As Boolean
Public ReadOnly Property FullID As String
Get
Return IIf(ID = "en", "en.*", ID)

View File

@@ -35,6 +35,7 @@ Namespace API.YouTube.Base
<Browsable(False)> Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
<Browsable(False)> Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection
<Browsable(False)> Public Overridable Property AccountName As String
#Region "Environment"
#Region "Programs"
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment programs"), DisplayName("Path to yt-dlp.exe"),
@@ -300,9 +301,17 @@ Namespace API.YouTube.Base
#End Region
#Region "Initializer"
Public Sub New()
Me.New(String.Empty)
End Sub
Public Sub New(ByVal AccountName As String)
Me.AccountName = AccountName
DownloadLocations = New DownloadLocationsCollection
DownloadLocations.Load(False, True)
XML = New XmlFile(YouTubeSettingsFile,, False) With {.AutoUpdateFile = True}
Dim acc$ = String.Empty
If Not AccountName.IsEmptyString Then acc = $"_{AccountName}"
Dim f As SFile = YouTubeSettingsFile
f.Name &= acc
XML = New XmlFile(f,, False) With {.AutoUpdateFile = True}
XML.LoadData(EDP.None)
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
DesignXml.LoadData(EDP.None)
@@ -310,7 +319,9 @@ Namespace API.YouTube.Base
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
Cookies = New CookieKeeper
Grid.Abstract.DesignerXmlSource.Add(New Grid.Abstract.DesignerXmlData(GetType(CookieListForm2), DesignXml, "CookiesListForm"))
If YouTubeCookieNetscapeFile.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(YouTubeCookieNetscapeFile.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
f = YouTubeCookieNetscapeFile
f.Name &= acc
If f.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(f.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
If Not YTDLP.Value.Exists Then YTDLP.Value = ProgramPath("yt-dlp.exe")
If Not FFMPEG.Value.Exists Then FFMPEG.Value = ProgramPath("ffmpeg.exe")
If Not OutputPath.Value.Exists(SFO.Path, False) Then OutputPath.Value = YouTubeDownloadPathDefault

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("YouTube plugin environment")>
<Assembly: AssemblyCompany("AndyProgram")>
<Assembly: AssemblyProduct("SCrawler.YouTube")>
<Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyCopyright("Copyright © 2024")>
<Assembly: AssemblyTrademark("AndyProgram")>
<Assembly: ComVisible(False)>
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.10.10.0")>
<Assembly: AssemblyFileVersion("2023.10.10.0")>
<Assembly: AssemblyVersion("2023.11.17.0")>
<Assembly: AssemblyFileVersion("2023.11.17.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -111,6 +111,7 @@ Namespace API.YouTube.Objects
_SiteKey = Key
End Set
End Property
<XMLEC> Public Property AccountName As String = String.Empty Implements IDownloadableMedia.AccountName
<XMLEC(Name_IsMusic)> Public Property IsMusic As Boolean = False Implements IYouTubeMediaContainer.IsMusic
<XMLEC> Public Property IsShorts As Boolean = False Implements IYouTubeMediaContainer.IsShorts
<XMLEC> Public Property ID As String Implements IYouTubeMediaContainer.ID, IUserMedia.PostID
@@ -1421,28 +1422,36 @@ Namespace API.YouTube.Objects
Protected Sub ParseSubtitles(ByVal e As EContainer)
Dim subt As Subtitles
Dim ee As EContainer
Dim se As EContainer = e({"subtitles"})
If If(se?.Count, 0) = 0 OrElse (se.Count = 1 And se(0).Name = "live_chat") Then se = e({"automatic_captions"})
If If(se?.Count, 0) > 0 Then
If se.Count > 1 OrElse Not se(0).Name = "live_chat" Then
Dim eSUB As EContainer = e({"subtitles"})
Dim eCC As EContainer = e({"automatic_captions"})
If If(eSUB?.Count, 0) = 0 OrElse (eSUB.Count = 1 And eSUB(0).Name = "live_chat") Then eSUB = Nothing
If If(eCC?.Count, 0) = 0 OrElse (eCC.Count = 1 And eCC(0).Name = "live_chat") Then eCC = Nothing
If If(eSUB?.Count, 0) > 0 Or If(eCC?.Count, 0) > 0 Then
Dim sl As New List(Of EContainer)
Dim ccExists As Boolean = False
Dim ccIndx% = -1, rIndx% = -1
If If(eSUB?.Count, 0) > 0 Then sl.Add(eSUB) : ccIndx += 1
If If(eCC?.Count, 0) > 0 Then sl.Add(eCC) : ccIndx += 1 : ccExists = True
For Each se As EContainer In sl
rIndx += 1
For Each ee In se
subt = New Subtitles With {.ID = ee.Name}
subt = New Subtitles With {.ID = ee.Name, .CC = rIndx = ccIndx And ccExists}
If ee.Count > 0 Then
subt.Name = ee(0).Value("name")
subt.Formats = ee.Select(Function(f) f.Value("ext")).ListToString(",")
End If
If Not subt.ID.IsEmptyString Then _Subtitles.Add(subt)
Next
With MyYouTubeSettings
If Not .DefaultSubtitlesFormat.IsEmptyString Then OutputSubtitlesFormat = .DefaultSubtitlesFormat
If _Subtitles.Count > 0 And .DefaultSubtitles.Count > 0 Then
_Subtitles.Sort()
_Subtitles.ListReindex
SubtitlesSelectedIndexesReset()
PostProcessing_OutputSubtitlesFormats_Reset()
End If
End With
End If
Next
With MyYouTubeSettings
If Not .DefaultSubtitlesFormat.IsEmptyString Then OutputSubtitlesFormat = .DefaultSubtitlesFormat
If _Subtitles.Count > 0 And .DefaultSubtitles.Count > 0 Then
_Subtitles.Sort()
_Subtitles.ListReindex
SubtitlesSelectedIndexesReset()
PostProcessing_OutputSubtitlesFormats_Reset()
End If
End With
End If
End Sub
#End Region

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("SCrawler YouTube downloader")>
<Assembly: AssemblyCompany("AndyProgram")>
<Assembly: AssemblyProduct("SCrawler.YouTubeDownloader")>
<Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyCopyright("Copyright © 2024")>
<Assembly: AssemblyTrademark("AndyProgram")>
<Assembly: ComVisible(False)>
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.10.10.0")>
<Assembly: AssemblyFileVersion("2023.10.10.0")>
<Assembly: AssemblyVersion("2023.11.17.0")>
<Assembly: AssemblyFileVersion("2023.11.17.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -11,6 +11,8 @@ Namespace API.Base
Friend Const Header_Authorization As String = "authorization"
Friend Const Header_CSRFToken As String = "x-csrf-token"
Friend Const Header_FB_FRIENDLY_NAME As String = "x-fb-friendly-name"
Friend Const ConcurrentDownloadsCaption As String = "Concurrent downloads"
Friend Const ConcurrentDownloadsToolTip As String = "The number of concurrent downloads."
Friend Const SavedPostsUserNameCaption As String = "Saved posts user"

View File

@@ -50,6 +50,8 @@ Namespace API.Base
Property Suspended As Boolean
Property ReadyForDownload As Boolean
Property HOST As SettingsHost
Property HostStatic As Boolean
Property AccountName As String
Property [File] As SFile
Property FileExists As Boolean
Property DownloadedPictures(ByVal Total As Boolean) As Integer

View File

@@ -12,43 +12,72 @@ Imports PersonalUtilities.Forms.Toolbars
Imports PDownload = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Base
Friend NotInheritable Class ProfileSaved
Private ReadOnly Property HOST As SettingsHost
Private ReadOnly Property HOST As SettingsHostCollection
Private ReadOnly Property Progress As MyProgress
Friend Sub New(ByRef h As SettingsHost, ByRef Bar As MyProgress)
Private _Unavailable As Integer, _NotReady As Integer, _ErrorCount As Integer
Private _TotalImages As Integer, _TotalVideos As Integer
Friend Sub New(ByRef h As SettingsHostCollection, ByRef Bar As MyProgress)
HOST = h
Progress = Bar
End Sub
Friend Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean)
Friend Overloads Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean)
Dim n% = 0
Dim c% = HOST.Sum(Function(h) IIf(h.DownloadSavedPosts, 1, 0))
_Unavailable = 0
_NotReady = 0
_ErrorCount = 0
_TotalImages = 0
_TotalVideos = 0
If c > 0 Then
For i% = 0 To HOST.Count - 1
If HOST(i).DownloadSavedPosts Then n += 1 : Download(HOST(i), n, c, Token, Multiple)
Next
If c > 1 Then
Dim s% = {_Unavailable, _NotReady, _ErrorCount}.Sum
Progress.InformationTemporary = $"{HOST.Name} ({c - s}/{c}) Images: {_TotalImages}; Videos: {_TotalVideos}"
End If
End If
End Sub
Private Overloads Sub Download(ByVal Host As SettingsHost, ByVal Number As Integer, ByVal Count As Integer,
ByVal Token As CancellationToken, ByVal Multiple As Boolean)
Dim aStr$ = String.Empty
If Count > 1 Then aStr = $" ({Number}/{Count})"
Try
If HOST.Source.ReadyToDownload(PDownload.SavedPosts) Then
If HOST.Available(PDownload.SavedPosts, Multiple) Then
HOST.DownloadStarted(PDownload.SavedPosts)
Dim u As New UserInfo With {.Plugin = HOST.Key, .Site = HOST.Name, .SpecialPath = HOST.SavedPostsPath}
Using user As IUserData = HOST.GetInstance(PDownload.SavedPosts, Nothing, False, False)
If Host.Source.ReadyToDownload(PDownload.SavedPosts) Then
If Host.Available(PDownload.SavedPosts, Multiple Or Count > 1) Then
Host.DownloadStarted(PDownload.SavedPosts)
If Count > 1 Then Progress.Information = $"{Host.Name} - {Host.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)}"
Using user As IUserData = Host.GetInstance(PDownload.SavedPosts, Nothing, False, False)
If Not user Is Nothing Then
With DirectCast(user, UserDataBase)
.HostStatic = True
.IsSavedPosts = True
.LoadUserInformation()
.Progress = Progress
If Not .FileExists Then .UpdateUserInformation()
End With
HOST.BeforeStartDownload(user, PDownload.SavedPosts)
Host.BeforeStartDownload(user, PDownload.SavedPosts)
user.DownloadData(Token)
Progress.InformationTemporary = $"{HOST.Name} Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}"
HOST.AfterDownload(user, PDownload.SavedPosts)
_TotalImages += user.DownloadedPictures(False)
_TotalVideos += user.DownloadedVideos(False)
Progress.InformationTemporary = $"{Host.Name}{aStr} Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}"
Host.AfterDownload(user, PDownload.SavedPosts)
End If
End Using
Else
Progress.InformationTemporary = $"Host [{HOST.Name}] is unavailable"
_Unavailable += 1
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is unavailable"
End If
Else
Progress.InformationTemporary = $"Host [{HOST.Name}] is not ready"
_NotReady += 1
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready"
End If
Catch ex As Exception
Progress.InformationTemporary = $"{HOST.Name} downloading error"
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({HOST.Key})]")
_ErrorCount += 1
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error"
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[API.Base.ProfileSaved.Download({Host.Key}{aStr})]")
Finally
HOST.DownloadDone(PDownload.SavedPosts)
Host.DownloadDone(PDownload.SavedPosts)
MainFrameObj.UpdateLogButton()
End Try
End Sub

View File

@@ -6,15 +6,32 @@
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.Reflection
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Functions.RegularExpressions
Imports Download = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Base
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer
#Region "Declarations"
Friend ReadOnly Property Site As String Implements ISiteSettings.Site
Protected _Icon As Icon = Nothing
Friend Overridable ReadOnly Property Icon As Icon Implements ISiteSettings.Icon
Get
Return _Icon
End Get
End Property
Protected _Image As Image = Nothing
Friend Overridable ReadOnly Property Image As Image Implements ISiteSettings.Image
Get
Return _Image
End Get
End Property
Friend Property AccountName As String Implements ISiteSettings.AccountName
Friend Property Temporary As Boolean = False Implements ISiteSettings.Temporary
Friend Property DefaultInstance As ISiteSettings = Nothing Implements ISiteSettings.DefaultInstance
Protected _AllowUserAgentUpdate As Boolean = True
Protected _SubscriptionsAllowed As Boolean = False
Friend ReadOnly Property SubscriptionsAllowed As Boolean Implements ISiteSettings.SubscriptionsAllowed
@@ -24,7 +41,25 @@ Namespace API.Base
End Property
Private Property Logger As ILogProvider = LogConnector Implements ISiteSettings.Logger
Friend Overridable ReadOnly Property Responser As Responser
Private _UserOptionsExists As Boolean = False
Private _UserOptionsType As Type = Nothing
Protected Property UserOptionsType As Type
Get
Return _UserOptionsType
End Get
Set(ByVal t As Type)
_UserOptionsType = t
_UserOptionsExists = Not t Is Nothing
End Set
End Property
#End Region
#Region "Responser and cookies support"
Private _CookiesNetscapeFile As SFile = Nothing
Friend ReadOnly Property CookiesNetscapeFile As SFile
Get
Return _CookiesNetscapeFile
End Get
End Property
Protected CheckNetscapeCookiesOnEndInit As Boolean = False
Private _UseNetscapeCookies As Boolean = False
Protected Property UseNetscapeCookies As Boolean
@@ -47,22 +82,46 @@ Namespace API.Base
End Get
Set : End Set
End Property
Protected Sub UpdateResponserFile()
Dim acc$ = If(Not AccountName.IsEmptyString, $"_{AccountName}", String.Empty)
Responser.File = $"{SettingsFolderName}\Responser_{Site}{acc}.xml"
_CookiesNetscapeFile = Responser.File
_CookiesNetscapeFile.Name &= "_Cookies_Netscape"
_CookiesNetscapeFile.Extension = "txt"
End Sub
#End Region
#Region "GetInstance"
Friend MustOverride Function GetInstance(ByVal What As Download) As IPluginContentProvider Implements ISiteSettings.GetInstance
Friend Sub New(ByVal SiteName As String)
#End Region
#Region "Initializers"
Friend Sub New(ByVal SiteName As String, Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing)
Site = SiteName
CookiesNetscapeFile = $"{SettingsFolderName}\Responser_{Site}_Cookies_Netscape.txt"
_Icon = __Icon
_Image = __Image
Responser = New Responser With {.DeclaredError = EDP.ThrowException}
UpdateResponserFile()
End Sub
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String)
Me.New(SiteName)
Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml") With {.DeclaredError = EDP.ThrowException}
With Responser
.CookiesDomain = CookiesDomain
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
If .File.Exists Then .LoadSettings() Else .SaveSettings()
End With
End Sub
#Region "XML"
Friend Overridable Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Implements ISiteSettings.Load
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing)
Me.New(SiteName, __Icon, __Image)
Temporary = Temp
AccountName = AccName
If Temporary Then
With Responser
.File = Nothing
.Cookies.File = Nothing
.CookiesDomain = CookiesDomain
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
End With
_CookiesNetscapeFile = Nothing
Else
UpdateResponserFile()
With Responser
.CookiesDomain = CookiesDomain
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
If .File.Exists Then .LoadSettings() Else .SaveSettings()
End With
End If
End Sub
#End Region
#Region "Initialize"
@@ -86,7 +145,7 @@ Namespace API.Base
If _SiteEditorFormOpened Then DomainsReset()
_SiteEditorFormOpened = False
End Sub
Friend Overridable Sub Update() Implements ISiteSettings.Update
Friend Overridable Overloads Sub Update() Implements ISiteSettings.Update
If _SiteEditorFormOpened Then
If UseNetscapeCookies Then Update_SaveCookiesNetscape()
If Not Responser Is Nothing Then
@@ -98,6 +157,17 @@ Namespace API.Base
End If
If Not Responser Is Nothing Then Responser.SaveSettings()
End Sub
Friend Overridable Overloads Sub Update(ByVal Source As ISiteSettings) Implements ISiteSettings.Update
AccountName = Source.AccountName
If Not Responser Is Nothing Then Responser.Copy(DirectCast(Source, SiteSettingsBase).Responser) : UpdateResponserFile() : Responser.SaveSettings()
Update_CloneProperties(Source)
UpdateImpl(Source)
End Sub
Protected Overridable Sub Update_CloneProperties(ByVal Source As ISiteSettings)
CLONE_PROPERTIES(Source, Me, True)
End Sub
Protected Overridable Sub UpdateImpl(ByVal Source As ISiteSettings)
End Sub
Protected Sub Update_SaveCookiesNetscape(Optional ByVal Force As Boolean = False, Optional ByVal IsInit As Boolean = False)
If Not Responser Is Nothing Then
With Responser
@@ -142,6 +212,7 @@ Namespace API.Base
End Sub
''' <inheritdoc cref="DownloadStarted(Download)"/>
Friend Overridable Sub DownloadDone(ByVal What As Download) Implements ISiteSettings.DownloadDone
AvailableText = String.Empty
End Sub
#End Region
#Region "User info"
@@ -184,6 +255,7 @@ Namespace API.Base
End Function
#End Region
#Region "Ready, Available"
Friend Property AvailableText As String Implements ISiteSettings.AvailableText
''' <returns>True</returns>
Friend Overridable Function BaseAuthExists() As Boolean
Return True
@@ -199,12 +271,119 @@ Namespace API.Base
Return True
End Function
#End Region
Protected Sub CLONE_PROPERTIES(ByVal Source As ISiteSettings, ByVal Destination As ISiteSettings, ByVal IsUpdate As Boolean,
Optional ByVal Full As Boolean = True)
Dim comparer As New MembersDistinctComparer
'0 = update
'1 = clone
'2 = any
Dim filterUC As Func(Of MemberInfo, Byte, Boolean) = Function(ByVal m As MemberInfo, ByVal __mode As Byte) As Boolean
If m.GetCustomAttribute(Of DoNotUse) Is Nothing Then
Return False
Else
With m.GetCustomAttribute(Of PClonableAttribute)
Return Not .Self Is Nothing AndAlso (__mode = 2 OrElse If(__mode = 0, .Update, .Clone))
End With
End If
End Function
Dim filterAll As Func(Of MemberInfo, Boolean) = Function(m) filterUC.Invoke(m, 2)
Dim filterC As Func(Of MemberInfo, Boolean) = Function(m) If(Full, filterAll.Invoke(m), filterUC.Invoke(m, 1))
Dim filterU As Func(Of MemberInfo, Boolean) = Function(m) filterUC.Invoke(m, 0)
Dim membersSource As IEnumerable(Of MemberInfo) = GetObjectMembers(Source, filterAll,, True, comparer)
If membersSource.ListExists Then
Dim membersDest As IEnumerable(Of MemberInfo) = GetObjectMembers(Destination, If(IsUpdate, filterU, filterC),, True, comparer)
If membersDest.ListExists Then
Dim mSource As MemberInfo = Nothing, mDest As MemberInfo = Nothing
Dim destIndx%
Dim isPropertyValue As Boolean
Dim sourceValue As Object
For Each mSource In membersSource
destIndx = membersDest.ListIndexOf(mSource, comparer, EDP.ReturnValue)
If destIndx.ValueBetween(0, membersDest.Count - 1) Then mDest = membersDest(destIndx) Else mDest = Nothing
If Not mDest Is Nothing Then
sourceValue = mSource.GetMemberValue(Source)
If mDest.MemberType = MemberTypes.Property Then
isPropertyValue = DirectCast(mDest, PropertyInfo).PropertyType Is GetType(PropertyValue)
Else
isPropertyValue = DirectCast(mDest, FieldInfo).FieldType Is GetType(PropertyValue)
End If
If isPropertyValue Then
DirectCast(mDest.GetMemberValue(Destination), PropertyValue).Clone(sourceValue)
Else
mDest.SetMemberValue(Destination, sourceValue)
End If
End If
Next
End If
End If
End Sub
Protected Overridable Function CloneGetEmptySettingsInstance() As ISiteSettings
Dim _max% = -1
Dim c As ConstructorInfo = Nothing
With Me.GetType.GetTypeInfo.DeclaredConstructors
If .ListExists Then
With .Where(Function(m) If(m.GetParameters?.Count, 0).ValueBetween(0, 2))
If .ListExists Then
_max = .Max(Function(m) If(m.GetParameters?.Count, 0))
c = .First(Function(m) If(m.GetParameters?.Count, 0) = _max)
End If
End With
End If
Select Case _max
Case 2 : Return c.Invoke({String.Empty, True})
Case 1 : Return c.Invoke({String.Empty})
Case 0 : Return c.Invoke(Nothing)
Case Else : Return Activator.CreateInstance(Me.GetType)
End Select
End With
End Function
Friend Overridable Function Clone(ByVal Full As Boolean) As ISiteSettings Implements ISiteSettings.Clone
Dim obj As ISiteSettings = CloneGetEmptySettingsInstance()
CLONE_PROPERTIES(Me, obj, False, Full)
Return obj
End Function
Friend Sub Delete() Implements ISiteSettings.Delete
If Not Responser Is Nothing Then
With Responser
If .File.Exists Then .File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
If .Cookies.File.Exists Then .Cookies.File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
End With
If _CookiesNetscapeFile.Exists Then _CookiesNetscapeFile.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
End If
End Sub
Friend Overridable Sub Reset() Implements ISiteSettings.Reset
End Sub
Friend Overridable Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
Options = Nothing
If _UserOptionsExists Then
If Options Is Nothing OrElse Not Options.GetType Is _UserOptionsType Then
Options = AConvert(Me, AModes.Var, _UserOptionsType,, True, Nothing)
If Options Is Nothing Then Options = Activator.CreateInstance(_UserOptionsType)
End If
If OpenForm Then
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
Else
Options = Nothing
End If
End Sub
Friend Overridable Sub OpenSettingsForm() Implements ISiteSettings.OpenSettingsForm
End Sub
#Region "IDisposable Support"
Protected disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then
If disposing Then Responser.DisposeIfReady
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 Namespace

View File

@@ -18,6 +18,7 @@ Namespace API.Base
Tags = 2
Categories = 3
Pornstars = 4
Playlists = 5
End Enum
Friend Structure UserMedia : Implements IUserMedia, IEquatable(Of UserMedia), IEContainerProvider
#Region "XML Names"

View File

@@ -126,6 +126,7 @@ Namespace API.Base
#Region "XML Declarations"
Private Const Name_Site As String = UserInfo.Name_Site
Private Const Name_Plugin As String = UserInfo.Name_Plugin
Private Const Name_AccountName As String = UserInfo.Name_AccountName
Protected Const Name_IsChannel As String = "IsChannel"
Friend Const Name_UserName As String = "UserName"
Private Const Name_Model_User As String = UserInfo.Name_Model_User
@@ -168,10 +169,56 @@ Namespace API.Base
Protected Const Name_UseMD5Comparison As String = "UseMD5Comparison"
Protected Const Name_RemoveExistingDuplicates As String = "RemoveExistingDuplicates"
Protected Const Name_StartMD5Checked As String = "StartMD5Checked"
#Region "Additional names"
Protected Const Name_SiteMode As String = "SiteMode"
Protected Const Name_TrueName As String = "TrueName"
Protected Const Name_Arguments As String = "Arguments"
#End Region
#End Region
#Region "Declarations"
#Region "Host, Site, Progress"
Friend Property HostCollection As SettingsHostCollection
Private Function HostObtainCollection() As Boolean
If HostCollection Is Nothing Then
Dim k$ = If(_HOST?.Key, _HostKey)
If Not k.IsEmptyString Then HostCollection = Settings(k)
End If
Return Not HostCollection Is Nothing
End Function
Private _HOST As SettingsHost
Private _HostKey As String = String.Empty
Private _HostObtained As Boolean = False
Friend Property HOST As SettingsHost Implements IUserData.HOST
Get
If _HostObtained Or HostStatic Then
Return _HOST
ElseIf HostObtainCollection() Then
_HOST = HostCollection(AccountName)
_HostObtained = Not _HOST Is Nothing
Return _HOST
Else
Return Nothing
End If
End Get
Set(ByVal h As SettingsHost)
_HOST = h
_HostKey = h.Key
End Set
End Property
Private Sub ResetHost()
_HostObtained = False
End Sub
Friend Property HostStatic As Boolean = False Implements IUserData.HostStatic
Private _AccountName As String = String.Empty
Friend Overridable Property AccountName As String Implements IUserData.AccountName, IPluginContentProvider.AccountName
Get
Return _AccountName.IfNullOrEmpty(User.AccountName)
End Get
Set(ByVal name As String)
If Not _AccountName = name Then ResetHost()
_AccountName = name
End Set
End Property
Friend ReadOnly Property Site As String Implements IUserData.Site
Get
Return HOST.Name
@@ -845,6 +892,7 @@ BlockNullPicture:
Friend Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
Optional ByVal AttachUserInfo As Boolean = True) Implements IUserData.SetEnvironment
HOST = h
HostObtainCollection()
If AttachUserInfo Then
User = u
If _LoadUserInformation Then LoadUserInformation()
@@ -853,7 +901,7 @@ BlockNullPicture:
''' <exception cref="ArgumentOutOfRangeException"></exception>
Friend Shared Function GetInstance(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True) As IUserData
If Not u.Plugin.IsEmptyString Then
Return Settings(u.Plugin).GetInstance(ISiteSettings.Download.Main, u, _LoadUserInformation)
Return Settings(u.Plugin).Default.GetInstance(ISiteSettings.Download.Main, u, _LoadUserInformation)
Else
Throw New ArgumentOutOfRangeException("Plugin", $"Plugin [{u.Plugin}] information does not recognized by loader")
End If
@@ -865,7 +913,7 @@ BlockNullPicture:
With DirectCast(u, UserDataBase)
If Not .User.Plugin.IsEmptyString Then
uName = .User.Name
Return Settings(.User.Plugin).GetUserPostUrl(.Self, PostData)
Return Settings(.User.Plugin).Default.GetUserPostUrl(.Self, PostData)
End If
End With
End If
@@ -937,6 +985,7 @@ BlockNullPicture:
Using x As New XmlFile With {.Name = "User"}
x.Add(Name_Site, Site)
x.Add(Name_Plugin, HOST.Key)
x.Add(Name_AccountName, AccountName)
x.Add(Name_UserName, User.Name)
x.Add(Name_Model_User, CInt(UserModel))
x.Add(Name_Model_Collection, CInt(CollectionModel))
@@ -1130,11 +1179,13 @@ BlockNullPicture:
End If
End Sub
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IUserData.DownloadData
ResetHost()
__DOWNLOAD_IN_PROGRESS = True
OnUserDownloadStateChanged(True)
Dim Canceled As Boolean = False
TokenQueue = Token
Try
If HOST Is Nothing Then Throw New ExitException($"Host '{AccountName}' not found")
EnvirDownloadSet()
If Not Responser Is Nothing Then Responser.Dispose()
Responser = New Responser
@@ -1291,7 +1342,12 @@ BlockNullPicture:
#Region "DownloadSingleObject"
Protected IsSingleObjectDownload As Boolean = False
Friend Overridable Sub DownloadSingleObject(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken) Implements IUserData.DownloadSingleObject
Dim URL$ = String.Empty
Try
ResetHost()
URL = Data.URL
AccountName = Data.AccountName
If HOST Is Nothing Then Throw New ExitException($"Host '{AccountName}' not found")
Data.DownloadState = UserMediaStates.Tried
Progress = Data.Progress
If Not Progress Is Nothing Then Progress.ResetProgressOnMaximumChanges = False
@@ -1307,11 +1363,19 @@ BlockNullPicture:
DownloadSingleObject_PostProcessing(Data)
Catch oex As OperationCanceledException When Token.IsCancellationRequested
Data.DownloadState = UserMediaStates.Missing
ErrorsDescriber.Execute(EDP.SendToLog, oex, $"{Site} download canceled: {Data.URL}")
ErrorsDescriber.Execute(EDP.SendToLog, oex, $"{Site} download canceled: {URL}")
Catch dex As ObjectDisposedException When Disposed
Catch exit_ex As ExitException
If Not exit_ex.Silent Then
If exit_ex.SimpleLogLine Then
MyMainLOG = $"{URL}: downloading canceled (exit) ({exit_ex.Message})"
Else
ErrorsDescriber.Execute(EDP.SendToLog, exit_ex, $"{URL}: downloading canceled (exit)")
End If
End If
Catch ex As Exception
Data.DownloadState = UserMediaStates.Missing
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{Site} single data downloader error: {Data.URL}")
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"{Site} single data downloader error: {URL}")
End Try
End Sub
Protected Overridable Sub DownloadSingleObject_CreateMedia(ByVal Data As YouTube.Objects.IYouTubeMediaContainer, ByVal Token As CancellationToken)

View File

@@ -11,7 +11,7 @@ Imports PersonalUtilities.Forms
Imports PersonalUtilities.Tools
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace API.Base
Friend Class DomainsContainer : Implements IEnumerable(Of String), IMyEnumerator(Of String)
Friend Class DomainsContainer : Implements IEnumerable(Of String), IMyEnumerator(Of String), IDisposable
Friend Event DomainsUpdated(ByVal Sender As DomainsContainer)
Friend ReadOnly Property Domains As List(Of String)
Friend ReadOnly Property DomainsTemp As List(Of String)
@@ -98,11 +98,33 @@ Namespace API.Base
End If
End Using
End Sub
#Region "IEnumerable Support"
Private Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator
Return New MyEnumerator(Of String)(Me)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
#End Region
#Region "IDisposable Support"
Private disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then
If disposing Then
Domains.Clear()
DomainsTemp.Clear()
End If
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 Namespace

View File

@@ -20,7 +20,7 @@ Namespace API.Base
Private ReadOnly Property MyMembers As List(Of MemberOption)
''' <summary>Default: 200</summary>
Friend Property MinimumWidth As Integer = 200
Private Class MemberOption : Inherits Hosts.PropertyValueHost : Implements IDisposable
Private Class MemberOption : Inherits Hosts.PropertyValueHost
Friend ToolTip As String
Friend Caption As String
Friend ThreeState As Boolean = False
@@ -102,24 +102,6 @@ Namespace API.Base
CreateControl(TT)
If Not Provider Is Nothing Then f.AddControl(Control, Caption, Type, AllowNull, Activator.CreateInstance(Provider))
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 Control.Dispose()
Control = Nothing
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 Sub New(ByVal Obj As Object, ByVal s As ISiteSettings, ByVal _IsSettingsForm As Boolean)
InitializeComponent()

View File

@@ -0,0 +1,37 @@
' 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.Text.RegularExpressions
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Facebook
Friend Module Declarations
Friend ReadOnly Regex_UserToken_dtsg As RParams = RParams.DMS("DTSGInitialData.:.?{\s*.token.:\s*""([^""]+)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_UserToken_lsd As RParams = RParams.DMS("LSD.:.?{\s*.token.:\s*""([^""]+)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_UserID As RParams = RParams.DMS("userid.:.(\d+)", 1, RegexOptions.IgnoreCase, EDP.ReturnValue)
Friend ReadOnly Regex_Photos_by As RParams = RParams.DMS("photos_by"",""id"":""([^""]+)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_FileName As RParams = RParams.DM("([^/\?]+\..{3,4})(?=(\?|\Z))", 0, EDP.ReturnValue)
Friend ReadOnly Regex_ProfileUrlID As RParams = RParams.DMS("profile.php\?id=(\d+)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_VideoPageID As RParams = RParams.DMS("pageid.:.(\d+)", 1, RegexOptions.IgnoreCase, EDP.ReturnValue)
Friend ReadOnly Regex_StoryBucket As RParams = RParams.DMS("story_bucket[^\>]*?(\d+)", 1, EDP.ReturnValue)
Friend ReadOnly Regex_VideoIDFromURL As RParams = RParams.DMS("facebook.com/([^/]+/videos/|watch/\D*[\?&]{1}v=)(\d+)", 2, EDP.ReturnValue)
Friend ReadOnly Regex_PostHtmlFullPicture As RParams = RParams.DM("^((?!_[ps]{1}\d+x\d+).)*$", 0, EDP.ReturnValue)
Friend ReadOnly SpecialNode() As NodeParams = {New NodeParams("attachment", True, True, True, True, 30),
New NodeParams("media", True, True, True, True, 0),
New NodeParams("photo_image", True, True, True, True, 0),
New NodeParams("uri", True, True, True, True, 0)}
Friend ReadOnly SpecialNode2() As NodeParams = {New NodeParams("result", True, True, True, True, 30),
New NodeParams("data", True, True, True, True, 0),
New NodeParams("currmedia", True, True, True, True, 0),
New NodeParams("image", True, True, True, True, 0),
New NodeParams("uri", True, True, True, True, 0)}
End Module
End Namespace

View File

@@ -0,0 +1,110 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports SCrawler.API.Base
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Facebook
<Manifest("AndyProgram_Facebook"), SavedPosts, SeparatedTasks(1), SpecialForm(False)>
Friend Class SiteSettings : Inherits ThreadsNet.SiteSettings
#Region "Declarations"
#Region "Auth"
<PropertyOption(AllowNull:=False, ControlText:="Accept", ControlToolTip:="Header 'Accept'", IsAuth:=True), ControlNumber(21), PXML, PClonable>
Friend ReadOnly Property Header_Accept As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", AllowNull:=True, IsAuth:=True)>
Friend Overrides ReadOnly Property HH_IG_APP_ID As PropertyValue
Get
Return __HH_IG_APP_ID
End Get
End Property
<DoNotUse> Friend Overrides ReadOnly Property HH_CSRF_TOKEN As PropertyValue
Get
Return __HH_CSRF_TOKEN
End Get
End Property
<PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", IsAuth:=True, LeftOffset:=120), ControlNumber(51), PXML, PClonable>
Friend ReadOnly Property HH_PLATFORM_VER As PropertyValue
#End Region
#Region "Defaults"
<PropertyOption(ControlText:="Download photos", IsAuth:=False), PXML, PClonable>
Friend ReadOnly Property ParsePhotoBlock As PropertyValue
<PropertyOption(ControlText:="Download videos", IsAuth:=False), PXML, PClonable>
Friend ReadOnly Property ParseVideoBlock As PropertyValue
<PropertyOption(ControlText:="Download stories", IsAuth:=False), PXML, PClonable>
Friend ReadOnly Property ParseStoriesBlock As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("Facebook", "facebook.com", AccName, Temp, My.Resources.SiteResources.FacebookIcon_32, My.Resources.SiteResources.FacebookPic_37)
With Responser.Headers
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.facebook.com"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.facebook.com"))
.Remove(DeclaredNames.Header_FB_FRIENDLY_NAME)
End With
Header_Accept = New PropertyValue(String.Empty, GetType(String))
HH_PLATFORM_VER = New PropertyValue(String.Empty, GetType(String))
ParsePhotoBlock = New PropertyValue(True)
ParseVideoBlock = New PropertyValue(True)
ParseStoriesBlock = New PropertyValue(True)
UrlPatternUser = "https://www.facebook.com/{0}"
UserRegex = RParams.DMS("facebook.com/(profile.php\?id=\d+|[^\?&/]+)", 1)
ImageVideoContains = "facebook.com"
UserOptionsType = GetType(UserExchangeOptions)
End Sub
#End Region
#Region "GetInstance"
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
Return New UserData
End Function
#End Region
#Region "UpdateResponserData"
Friend Overrides Sub UpdateResponserData(ByVal Resp As Responser)
With Responser.Cookies
.Update(Resp.Cookies)
If .Changed Then Responser.SaveCookies() : .Changed = False
End With
End Sub
#End Region
#Region "BaseAuthExists, GetUserUrl, GetUserPostUrl, IsMyUser, IsMyImageVideo"
Friend Overrides Function BaseAuthExists() As Boolean
Return Responser.CookiesExists And ACheck(HH_IG_APP_ID.Value)
End Function
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider) As String
Return DirectCast(User, UserData).GetProfileUrl
End Function
Friend Overrides Function GetUserPostUrl(ByVal User As UserDataBase, ByVal Media As UserMedia) As String
Return Media.URL_BASE
End Function
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Dim e As ExchangeOptions = MyBase.IsMyUser(UserURL)
If e.Exists Then
e.Options = e.UserName
Dim v$ = RegexReplace(e.UserName, Regex_ProfileUrlID)
If Not v.IsEmptyString Then
e.UserName = v
Else
e.UserName = e.UserName.StringRemoveWinForbiddenSymbols
End If
End If
Return e
End Function
Friend Overrides Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
If Not URL.IsEmptyString AndAlso Not CStr(AConvert(Of String)(URL, Regex_VideoIDFromURL, String.Empty)).IsEmptyString Then
Return New ExchangeOptions(Site, String.Empty) With {.Exists = True}
Else
Return Nothing
End If
End Function
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,713 @@
' 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.Text.RegularExpressions
Imports SCrawler.API.Base
Imports SCrawler.API.YouTube.Objects
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Documents.JSON
Imports IG = SCrawler.API.Instagram.SiteSettings
Imports UTypes = SCrawler.API.Base.UserMedia.Types
Imports UStates = SCrawler.API.Base.UserMedia.States
Namespace API.Facebook
Friend Class UserData : Inherits Instagram.UserData
#Region "XML names"
Private Const Name_IsNoNameProfile As String = "IsNoNameProfile"
Private Const Name_OptionsParsed As String = "OptionsParsed"
Private Const Name_VideoPageID As String = "VideoPageID"
Private Const Name_StoryBucket As String = "StoryBucket"
Private Const Name_ParsePhotoBlock As String = "ParsePhotoBlock"
Private Const Name_ParseVideoBlock As String = "ParseVideoBlock"
Private Const Name_ParseStoriesBlock As String = "ParseStoriesBlock"
#End Region
#Region "Declarations"
Friend ReadOnly Property MySettings As SiteSettings
Get
Return HOST.Source
End Get
End Property
Private IsNoNameProfile As Boolean = False
Private OptionsParsed As Boolean = False
Private Property VideoPageID As String = String.Empty
Private Property StoryBucket As String = String.Empty
Friend Property ParsePhotoBlock As Boolean = True
Friend Property ParseVideoBlock As Boolean = True
Friend Property ParseStoriesBlock As Boolean = True
Private Enum PageBlock As Integer
Timeline = Sections.Timeline
Stories = Sections.Stories
Photos = 100
Videos = 101
Undefined = -1
End Enum
#End Region
#Region "GetProfileUrl"
Friend Function GetProfileUrl() As String
If IsNoNameProfile Then
Return $"https://www.facebook.com/profile.php?id={ID}"
Else
Return $"https://www.facebook.com/{NameTrue}"
End If
End Function
#End Region
#Region "Exchange"
Friend Overrides Function ExchangeOptionsGet() As Object
Return New UserExchangeOptions(Me)
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
With DirectCast(Obj, UserExchangeOptions)
ParsePhotoBlock = .ParsePhotoBlock
ParseVideoBlock = .ParseVideoBlock
ParseStoriesBlock = .ParseStoriesBlock
End With
End If
End Sub
#End Region
#Region "Loader"
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
Dim updateNames As Action = Sub()
If Not OptionsParsed AndAlso Not Options.IsEmptyString Then
OptionsParsed = True
Dim v$ = RegexReplace(Options, Regex_ProfileUrlID)
If Not v.IsEmptyString Then ID = v : IsNoNameProfile = True
End If
End Sub
With Container
If Loading Then
If .Contains(Name_IsNoNameProfile) Then
IsNoNameProfile = .Value(Name_IsNoNameProfile).FromXML(Of Boolean)(False)
Else
updateNames.Invoke
End If
OptionsParsed = .Value(Name_OptionsParsed).FromXML(Of Boolean)(False)
VideoPageID = .Value(Name_VideoPageID)
StoryBucket = .Value(Name_StoryBucket)
ParsePhotoBlock = .Value(Name_ParsePhotoBlock).FromXML(Of Boolean)(True)
ParseVideoBlock = .Value(Name_ParseVideoBlock).FromXML(Of Boolean)(True)
ParseStoriesBlock = .Value(Name_ParseStoriesBlock).FromXML(Of Boolean)(True)
Else
updateNames.Invoke
.Add(Name_IsNoNameProfile, IsNoNameProfile.BoolToInteger)
.Add(Name_OptionsParsed, OptionsParsed.BoolToInteger)
.Add(Name_VideoPageID, VideoPageID)
.Add(Name_StoryBucket, StoryBucket)
.Add(Name_ParsePhotoBlock, ParsePhotoBlock.BoolToInteger)
.Add(Name_ParseVideoBlock, ParseVideoBlock.BoolToInteger)
.Add(Name_ParseStoriesBlock, ParseStoriesBlock.BoolToInteger)
End If
End With
End Sub
#End Region
#Region "Download functions"
Private Token_dtsg As String = String.Empty
Private Token_lsd As String = String.Empty
Private Token_Photosby As String = String.Empty
Private Limit As Integer = -1
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Try
GetUserTokens(Token)
LoadSavePostsKV(True)
Limit = If(DownloadTopCount, -1)
If IsSavedPosts Then
DownloadData_SavedPosts(String.Empty, Token)
Else
If DownloadImages And ParsePhotoBlock Then DownloadData_Photo(String.Empty, Token)
If DownloadVideos And ParseVideoBlock Then DownloadData_Video(String.Empty, Token)
If (DownloadImages Or DownloadVideos) And ParseStoriesBlock Then DownloadData_Stories(Token)
End If
LoadSavePostsKV(False)
Finally
MySettings.UpdateResponserData(Responser)
End Try
End Sub
Private Const Header_fb_fr_name_Photo As String = "ProfileCometAppCollectionPhotosRendererPaginationQuery"
Private Const Header_fb_fr_name_Video As String = "PagesCometChannelTabAllVideosCardImplPaginationQuery"
Private Const Header_fb_fr_name_Stories As String = "StoriesSuspenseContentPaneRootWithEntryPointQuery"
Private Const Header_fb_fr_name_SavedPosts As String = "CometSaveDashboardAllItemsPaginationQuery"
Private Const DocID_Photo As String = "6684543058255697"
Private Const DocID_Video As String = "24545934291687581"
Private Const DocID_Stories As String = "6771064226315961"
Private Const DocID_SavedPosts As String = "7112228098805003"
Private Const Graphql_UrlPattern As String = "https://www.facebook.com/api/graphql?lsd={0}&doc_id={1}&server_timestamps=true&fb_dtsg={3}&fb_api_req_friendly_name={2}&variables={4}"
Private Const VideoHtmlUrlPattern As String = "https://www.facebook.com/watch/?v={0}"
Private Sub DownloadData_Photo(ByVal Cursor As String, ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Const VarPattern$ = """count"":8,""cursor"":""{0}"",""scale"":1,""id"":""{1}"""
Try
Dim nextCursor$ = String.Empty
Dim newPostsDetected As Boolean = False
Dim pUrl$, pUrlBase$
Dim pid As PostKV
ValidateBaseTokens()
If Token_Photosby.IsEmptyString Then Throw New ArgumentNullException("Token_Photosby", "Unable to obtain token")
URL = String.Format(Graphql_UrlPattern, Token_lsd, DocID_Photo, Header_fb_fr_name_Photo,
SymbolsConverter.ASCII.EncodeSymbolsOnly(Token_dtsg),
SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & String.Format(VarPattern, Cursor, Token_Photosby) & "}"))
ResponserApplyDefs(Header_fb_fr_name_Photo)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
With j({"data", "node", "pageItems", "edges"})
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each jNode As EContainer In .Self
ProgressPre.Perform()
With jNode
If Not .Value("cursor").IsEmptyString Then nextCursor = .Value("cursor")
With .Item({"node"})
If .ListExists Then
pUrl = .Value({"node", "viewer_image"}, "uri")
pUrlBase = .Value("url")
If Not pUrl.IsEmptyString Then
pid = New PostKV(.Value("id"), .Value({"node"}, "id"), PageBlock.Photos)
If Not PostKvExists(pid) Then
newPostsDetected = True
PostsKVIDs.ListAddValue(pid, LNC)
_TempPostsList.Add(pid.ID)
_TempMediaList.ListAddValue(New UserMedia(pUrl, UTypes.Picture) With {
.URL_BASE = pUrlBase,
.File = CreateFileFromUrl(pUrl),
.Post = pid.ID.IfNullOrEmpty(pid.Code)}, LNC)
If Limit > 0 And _TempMediaList.Count >= Limit Then Exit Sub
Else
Exit Sub
End If
End If
End If
End With
End With
Next
End If
End With
End If
End Using
End If
If newPostsDetected And Not nextCursor.IsEmptyString Then DownloadData_Photo(nextCursor, Token)
Catch ex As Exception
ProcessException(ex, Token, $"data (photo) downloading error [{URL}]",, Responser)
End Try
End Sub
Private Sub DownloadData_Video(ByVal Cursor As String, ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Const VarPattern$ = """alwaysIncludeAudioRooms"":true,""count"":6,""cursor"":{0},""pageID"":""{1}"",""scale"":4,""showReactions"":true,""useDefaultActor"":false,""id"":""{1}"""
Try
Dim nextCursor$ = String.Empty
Dim newPostsDetected As Boolean = False
Dim pid As PostKV
If VideoPageID.IsEmptyString Then GetVideoPageID(Token)
If VideoPageID.IsEmptyString Then Throw New ArgumentNullException("VideoPageID", "Unable to obtain VideoPageID")
ValidateBaseTokens()
URL = String.Format(Graphql_UrlPattern, Token_lsd, DocID_Video, Header_fb_fr_name_Video,
SymbolsConverter.ASCII.EncodeSymbolsOnly(Token_dtsg),
SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & String.Format(VarPattern, If(Cursor.IsEmptyString, "null", $"""{Cursor}"""), VideoPageID) & "}"))
ResponserApplyDefs(Header_fb_fr_name_Video)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
With j({"data", "node", "all_videos", "edges"})
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each jNode As EContainer In .Self
ProgressPre.Perform()
pid = New PostKV(String.Empty, jNode.Value({"node"}, "id"), PageBlock.Videos)
pid.Code = $"Stories:{pid.ID}"
nextCursor = jNode.Value("cursor")
If Not PostKvExists(pid) Then
newPostsDetected = True
PostsKVIDs.ListAddValue(pid, LNC)
_TempPostsList.Add(pid.Code)
_TempMediaList.ListAddValue(New UserMedia(String.Format(VideoHtmlUrlPattern, pid.ID),
UTypes.VideoPre) With {.Post = pid.ID}, LNC)
If Limit > 0 And _TempMediaList.Count >= Limit Then Exit Sub
Else
Exit Sub
End If
Next
End If
End With
End If
End Using
End If
If newPostsDetected And Not nextCursor.IsEmptyString Then DownloadData_Video(nextCursor, Token)
Catch ex As Exception
ProcessException(ex, Token, $"data (video) downloading error [{URL}]",, Responser)
End Try
End Sub
Private Sub DownloadData_Stories(ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Const VarPattern$ = """UFI2CommentsProvider_commentsKey"":""StoriesSuspenseContentPaneRootWithEntryPointQuery"",""blur"":10,""bucketID"":""{0}"",""displayCommentsContextEnableComment"":true,""displayCommentsContextIsAdPreview"":false,""displayCommentsContextIsAggregatedShare"":false,""displayCommentsContextIsStorySet"":false,""displayCommentsFeedbackContext"":null,""feedbackSource"":65,""feedLocation"":""COMET_MEDIA_VIEWER"",""focusCommentID"":null,""initialBucketID"":""{0}"",""initialLoad"":true,""isInitialLoadFromCommentsNotification"":false,""isStoriesArchive"":false,""isStoryCommentingEnabled"":false,""scale"":1,""shouldDeferLoad"":false,""shouldEnableArmadilloStoryReply"":false,""shouldEnableLiveInStories"":true,""__relay_internal__pv__StoriesIsCommentEnabledrelayprovider"":false,""__relay_internal__pv__StoriesIsContextualReplyDisabledrelayprovider"":false,""__relay_internal__pv__StoriesIsShareToStoryEnabledrelayprovider"":false,""__relay_internal__pv__StoriesRingrelayprovider"":false,""__relay_internal__pv__StoriesLWRVariantrelayprovider"":""www_new_reactions"""
Try
Dim pUrl$, pUrlBase$
Dim pid As PostKV
Dim t As UTypes
Dim postDate As Date?
ValidateBaseTokens()
If StoryBucket.IsEmptyString Then Throw New ArgumentNullException("StoryBucket", "Unable to obtain StoryBucket")
URL = String.Format(Graphql_UrlPattern, Token_lsd, DocID_Stories, Header_fb_fr_name_Stories,
SymbolsConverter.ASCII.EncodeSymbolsOnly(Token_dtsg),
SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & String.Format(VarPattern, StoryBucket) & "}"))
ResponserApplyDefs(Header_fb_fr_name_Stories)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then r = RegexReplace(r, RParams.DM("[^\r\n]+", 0, EDP.ReturnValue))
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
With j({"data", "bucket", "unified_stories", "edges"})
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each jNode As EContainer In .Self
ProgressPre.Perform()
With jNode({"node"})
If .ListExists Then
pid = New PostKV(.Value("id"), "", Sections.Stories)
With .ItemF({"attachments", 0, "media"})
If .ListExists Then
pid.ID = .Value("id")
pUrl = String.Empty
postDate = AConvert(Of Date)(.Value("creation_time"), UnixDate32Provider, Nothing)
Select Case .Value("__typename")
Case "Photo"
t = UTypes.Picture
pUrl = .Value({"image"}, "uri")
Case "Video"
t = UTypes.Video
pUrl = .Value("browser_native_hd_url").IfNullOrEmpty(.Value("browser_native_sd_url"))
End Select
If Not pUrl.IsEmptyString AndAlso Not PostKvExists(pid) Then
pUrlBase = $"https://www.facebook.com/stories/{StoryBucket}"
PostsKVIDs.Add(pid)
_TempMediaList.ListAddValue(New UserMedia(pUrl, t) With {
.URL_BASE = pUrlBase,
.File = CreateFileFromUrl(pUrl),
.SpecialFolder = $"{StoriesFolder} (user)",
.Post = New UserPost(pid.ID, postDate)}, LNC)
End If
End If
End With
End If
End With
Next
End If
End With
End If
End Using
End If
Catch ex As Exception
ProcessException(ex, Token, $"data (stories) downloading error [{URL}]",, Responser)
End Try
End Sub
Private Sub DownloadData_SavedPosts(ByVal Cursor As String, ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Const VarPattern$ = """content_filter"":[],""count"":10,""cursor"":{0},""scale"":1,""use_case"":""SAVE_DEFAULT"""
Try
Dim nextCursor$ = String.Empty
Dim newPostsDetected As Boolean = False
Dim pUrl$, videoId$, imgUri$
Dim imgFile As SFile
Dim pid As PostKV
ValidateBaseTokens()
URL = String.Format(Graphql_UrlPattern, Token_lsd, DocID_SavedPosts, Header_fb_fr_name_SavedPosts,
SymbolsConverter.ASCII.EncodeSymbolsOnly(Token_dtsg),
SymbolsConverter.ASCII.EncodeSymbolsOnly("{" & String.Format(VarPattern, If(Cursor.IsEmptyString, "null", $"""{Cursor}""")) & "}"))
ResponserApplyDefs(Header_fb_fr_name_SavedPosts)
ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r)
If j.ListExists Then
With j({"data", "viewer", "saver_info", "all_saves", "edges"})
If .ListExists Then
ProgressPre.ChangeMax(.Count)
For Each jNode As EContainer In .Self
ProgressPre.Perform()
nextCursor = jNode.Value("cursor")
pid = New PostKV("", jNode.Value({"node"}, "id"), Sections.SavedPosts)
If Not PostKvExists(pid) Then
PostsKVIDs.Add(pid)
newPostsDetected = True
With jNode({"node", "savable"})
If .ListExists Then
pUrl = .Value("savable_permalink")
If Not pUrl.IsEmptyString Then
Select Case .Value("savable_default_category").StringToLower
Case "post_with_photo"
imgUri = .Value({"savable_image"}, "uri")
If Not imgUri.IsEmptyString Then
imgFile = CreateFileFromUrl(imgUri)
If Not imgFile.Name.IsEmptyString Then
ThrowAny(Token)
_TempMediaList.ListAddList(DownloadData_SavedPosts_ParseImagePost(pUrl, imgFile.Name, Token))
End If
End If
Case "video"
videoId = RegexReplace(pUrl, Regex_VideoIDFromURL)
If Not videoId.IsEmptyString Then _
_TempMediaList.ListAddValue(New UserMedia(pUrl, UTypes.VideoPre) With {.Post = videoId}, LNC)
Case Else : Continue For
End Select
End If
End If
End With
End If
Next
End If
End With
End If
End Using
End If
If newPostsDetected And Not nextCursor.IsEmptyString Then DownloadData_SavedPosts(nextCursor, Token)
Catch ex As Exception
ProcessException(ex, Token, $"data (saved posts) downloading error [{URL}]",, Responser)
End Try
End Sub
Private Function DownloadData_SavedPosts_ParseImagePost(ByVal PostUrl As String, ByVal ImageName As String, ByVal Token As CancellationToken,
Optional ByVal Round As Integer = 0) As IEnumerable(Of UserMedia)
Dim resp As Responser = HtmlResponserCreate()
Try
If Round > 0 Then ThrowAny(Token)
Dim script$, newUrl$
Dim jNode As EContainer, jNode2 As EContainer
Dim r$ = resp.GetResponse(PostUrl)
If Not r.IsEmptyString Then
script = RegexReplace(r, RParams.DMS($"<script type=""application/json""[^\>]*data-sjs>([^<]+?{ImageName}[^<]+)<", 1, EDP.ReturnValue))
If Not script.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(script)
If j.ListExists Then
jNode = j.Find(Function(jj) Not jj.Name.IsEmptyString AndAlso jj.Name.ToLower = "prefetch_uris_v2", True)
If jNode.ListExists Then
For Each vNode As EContainer In jNode
newUrl = RegexReplace(vNode.Value("uri"), Regex_PostHtmlFullPicture)
If Not newUrl.IsEmptyString Then _
Return {New UserMedia(newUrl, UTypes.Picture) With {.URL_BASE = PostUrl, .File = CreateFileFromUrl(newUrl)}}
Next
End If
If Round = 0 Then
j.SetSourceReferences()
jNode = j.GetNode(SpecialNode)
If Not jNode Is Nothing AndAlso Not jNode.Value.IsEmptyString AndAlso Not jNode.Source Is Nothing Then
With DirectCast(jNode.Source, EContainer)
If Not .Source Is Nothing Then
newUrl = DirectCast(.Source, EContainer).Value("url")
If Not newUrl.IsEmptyString Then
Dim __data As IEnumerable(Of UserMedia) =
DownloadData_SavedPosts_ParseImagePost(newUrl, CreateFileFromUrl(jNode.Value).Name, Token, Round + 1)
If __data.ListExists Then Return __data
End If
End If
End With
End If
End If
jNode = j.Find(Function(jj) Not jj.Name.IsEmptyString AndAlso jj.Name = "viewer_image", True)
If Not jNode Is Nothing AndAlso Not jNode.Source Is Nothing Then
Dim doRound% = 0
Do : doRound += 1 : jNode = jNode.Source : Loop While doRound <= 30 AndAlso Not jNode Is Nothing AndAlso Not jNode.Name = "nodes"
If Not jNode Is Nothing AndAlso jNode.Name = "nodes" AndAlso jNode.Count > 0 Then
Dim mList As New List(Of UserMedia)
For Each jNode2 In jNode
With jNode2
newUrl = .Value({"media", "viewer_image"}, "uri")
If Not newUrl.IsEmptyString Then _
mList.Add(New UserMedia(newUrl, UTypes.Picture) With {.URL_BASE = PostUrl, .File = CreateFileFromUrl(newUrl)})
End With
Next
Return mList
End If
End If
newUrl = j.GetNode(SpecialNode2).XmlIfNothingValue
If Not newUrl.IsEmptyString Then _
Return {New UserMedia(newUrl, UTypes.Picture) With {.URL_BASE = PostUrl, .File = CreateFileFromUrl(newUrl)}}
End If
End Using
End If
End If
Return Nothing
Catch ex As Exception
ProcessException(ex, Token, $"data (saved posts) downloading error [{PostUrl}]",, resp, False)
Return Nothing
Finally
HtmlResponserDispose(resp)
End Try
End Function
#End Region
#Region "ValidateBaseTokens, GetVideoPageID, GetUserTokens"
''' <exception cref="ArgumentNullException"></exception>
Private Sub ValidateBaseTokens()
If Token_dtsg.IsEmptyString Then Throw New ArgumentNullException("Token_dtsg", "Unable to obtain token")
If Token_lsd.IsEmptyString Then Throw New ArgumentNullException("Token_lsd", "Unable to obtain token")
End Sub
Private Sub GetVideoPageID(ByVal Token As CancellationToken)
Dim URL$ = $"{GetProfileUrl()}\videos"
Dim resp As Responser = HtmlResponserCreate()
Try
Dim r$ = resp.GetResponse(URL)
If Not r.IsEmptyString Then VideoPageID = RegexReplace(r, Regex_VideoPageID)
Catch ex As Exception
ProcessException(ex, Token, "get video page ID",, resp)
Finally
HtmlResponserDispose(resp)
End Try
End Sub
Private Sub GetUserTokens(ByVal Token As CancellationToken)
Dim URL$ = If(IsSavedPosts, "https://www.facebook.com/saved", GetProfileUrl())
Dim resp As Responser = HtmlResponserCreate()
Try
Token_dtsg = String.Empty
Token_lsd = String.Empty
Token_Photosby = String.Empty
Dim r$ = resp.GetResponse(URL)
If Not r.IsEmptyString Then
If Responser.CookiesExists Then Responser.Cookies.Update(resp.Cookies)
Token_dtsg = RegexReplace(r, Regex_UserToken_dtsg)
Token_lsd = RegexReplace(r, Regex_UserToken_lsd)
Token_Photosby = RegexReplace(r, Regex_Photos_by)
If StoryBucket.IsEmptyString Then StoryBucket = RegexReplace(r, Regex_StoryBucket)
If ID.IsEmptyString Then
ID = RegexReplace(r, Regex_UserID)
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
End If
End If
Catch ex As Exception
ProcessException(ex, Token, "get user token",, resp)
Finally
HtmlResponserDispose(resp)
End Try
End Sub
#End Region
#Region "Responser options"
Private Sub ResponserApplyDefs(ByVal __fb_friendly_name As String)
With Responser
.Headers.Add(ThreadsNet.UserData.Header_FB_LSD, Token_lsd)
.Headers.Add(DeclaredNames.Header_FB_FRIENDLY_NAME, __fb_friendly_name)
.Method = "POST"
.Accept = "*/*"
.Referer = GetProfileUrl()
End With
End Sub
Private Function HtmlResponserCreate() As Responser
Dim r As Responser = Responser.Copy
With r
.Accept = CStr(AConvert(Of String)(MySettings.Header_Accept.Value, String.Empty))
.Referer = Nothing
.Method = "GET"
With .Headers
.Clear()
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.facebook.com"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchDest, "document"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchMode, "navigate"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchSite, "none"))
.Add("Sec-Fetch-User", "?1")
.Add("Upgrade-Insecure-Requests", 1)
Dim h$ = Responser.Headers.Value(IG.Header_Browser)
If Not h.IsEmptyString Then .Add(IG.Header_Browser, h)
h = Responser.Headers.Value(IG.Header_BrowserExt)
If Not h.IsEmptyString Then .Add(IG.Header_BrowserExt, h)
h = .Value(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaPlatform))
If Not h.IsEmptyString Then .Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaPlatform, h))
If ACheck(MySettings.HH_PLATFORM_VER.Value) Then _
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaPlatformVersion, MySettings.HH_PLATFORM_VER.Value))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaMobile, "?0"))
.Add("Sec-Ch-Ua-Model", "")
End With
End With
Return r
End Function
Private Sub HtmlResponserDispose(ByVal r As Responser)
If Not r Is Nothing Then
Responser.Cookies.Update(r.Cookies)
r.Dispose()
End If
End Sub
#End Region
#Region "ReparseMissing"
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
Dim rList As New List(Of Integer)
Dim resp As Responser = HtmlResponserCreate()
Try
If ContentMissingExists Then
Dim m As UserMedia
Dim result As Boolean
ProgressPre.ChangeMax(_ContentList.Count)
For i% = 0 To _ContentList.Count - 1
ProgressPre.Perform()
m = _ContentList(i)
If (m.State = UStates.Missing And (m.Type = UTypes.Video Or m.Type = UTypes.VideoPre)) AndAlso Not m.URL_BASE.IsEmptyString Then
ThrowAny(Token)
result = False
m = ReparseSingleVideo(m, resp, result)
If result Then
rList.Add(i)
m.State = UStates.Missing
_TempMediaList.ListAddValue(m, LNC)
End If
End If
Next
End If
Catch ex As Exception
ProcessException(ex, Token, "missing data downloading error")
Finally
If rList.Count > 0 Then
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
rList.Clear()
End If
HtmlResponserDispose(resp)
End Try
End Sub
#End Region
#Region "ReparseVideo"
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
Dim URL$ = String.Empty
Dim resp As Responser = HtmlResponserCreate()
Try
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(mm) mm.Type = UTypes.VideoPre) Then
ProgressPre.ChangeMax(_TempMediaList.Count)
Dim m As UserMedia
Dim result As Boolean
For i% = 0 To _TempMediaList.Count - 1
m = _TempMediaList(i)
If m.Type = UTypes.VideoPre Then
ThrowAny(Token)
result = False
m = ReparseSingleVideo(m, resp, result)
If Not result Then m.State = UStates.Missing
_TempMediaList(i) = m
End If
ProgressPre.Perform()
Next
End If
Catch ex As Exception
ProcessException(ex, Token, $"video reparsing error [{URL}]",, resp)
Finally
HtmlResponserDispose(resp)
End Try
End Sub
Protected Function ReparseSingleVideo(ByVal m As UserMedia, ByVal resp As Responser, ByRef result As Boolean) As UserMedia
Const nameSD$ = "browser_native_sd_url"
Const nameHD$ = "browser_native_hd_url"
Const pattern$ = "<script type=""application/json""[^\>]*data-sjs>([^<]+?{0}[^<]+)<"
Dim URL$ = String.Empty
Dim j As EContainer = Nothing
Try
Dim r$, script$, __url$
Dim jNode As EContainer
Dim jf As Predicate(Of EContainer) = Function(ee) Not ee.Name.IsEmptyString AndAlso (ee.Name.ToLower = nameSD Or ee.Name.ToLower = nameHD)
Dim re As RParams = RParams.DMS("", 1, RegexOptions.IgnoreCase, EDP.ReturnValue)
If m.Post.ID.IsEmptyString Then
URL = m.URL_BASE
Else
URL = String.Format(VideoHtmlUrlPattern, m.Post.ID)
End If
r = resp.GetResponse(URL)
If Not r.IsEmptyString Then
re.Pattern = String.Format(pattern, nameHD)
script = RegexReplace(r, re)
If script.IsEmptyString Then
re.Pattern = String.Format(pattern, nameSD)
script = RegexReplace(r, re)
End If
If Not script.IsEmptyString Then
j = JsonDocument.Parse(script)
If j.ListExists Then
j.SetSourceReferences()
jNode = j.Find(jf, True)
If Not jNode Is Nothing Then
With DirectCast(jNode.Source, EContainer)
__url = .Value(nameHD).IfNullOrEmpty(.Value(nameSD))
If Not __url.IsEmptyString Then
m.URL = __url
m.URL_BASE = URL
m.Type = UTypes.Video
m.File = CreateFileFromUrl(__url)
m.Post.Date = AConvert(Of Date)(.Value("publish_time"), UnixDate32Provider, Nothing)
result = True
Return m
End If
End With
End If
End If
End If
End If
Catch ex As Exception
End Try
j.DisposeIfReady
result = False
Return m
End Function
#End Region
#Region "CreateFileFromUrl"
Protected Overrides Function CreateFileFromUrl(ByVal URL As String) As SFile
If Not URL.IsEmptyString Then
Dim f$ = RegexReplace(URL, Regex_FileName)
If Not f.IsEmptyString Then
Return f
Else
Dim ff As New SFile(URL)
If Not ff.Extension.IsEmptyString Then
If ff.Length > 4 Then ff.Extension = ff.Extension.Split("?").FirstOrDefault
ff.Extension = ff.Extension.StringRemoveWinForbiddenSymbols
End If
ff.Name = ff.Name.StringRemoveWinForbiddenSymbols
Return ff
End If
End If
Return String.Empty
End Function
#End Region
#Region "DownloadContent"
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
DownloadContentDefault(Token)
End Sub
#End Region
#Region "DownloadSingleObject"
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
_ContentList.Add(New UserMedia(Data.URL, UTypes.VideoPre) With {.Post = CStr(AConvert(Of String)(Data.URL, Regex_VideoIDFromURL, String.Empty))})
ReparseMissing(Token)
End Sub
#End Region
#Region "ThrowAny"
Friend Overrides Sub ThrowAny(ByVal Token As CancellationToken)
ThrowAnyImpl(Token)
End Sub
#End Region
#Region "Exception"
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal EObj As Object = Nothing) As Integer
Return 0
End Function
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,32 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Attributes
Namespace API.Facebook
Friend Class UserExchangeOptions
<PSetting(NameOf(SiteSettings.ParsePhotoBlock), NameOf(MySettings))>
Friend Property ParsePhotoBlock As Boolean = True
<PSetting(NameOf(SiteSettings.ParseVideoBlock), NameOf(MySettings))>
Friend Property ParseVideoBlock As Boolean = True
<PSetting(NameOf(SiteSettings.ParseStoriesBlock), NameOf(MySettings))>
Friend Property ParseStoriesBlock As Boolean = True
Private ReadOnly Property MySettings As SiteSettings
Friend Sub New(ByVal u As UserData)
MySettings = u.HostCollection.Default.Source
ParsePhotoBlock = u.ParsePhotoBlock
ParseVideoBlock = u.ParseVideoBlock
ParseStoriesBlock = u.ParseStoriesBlock
End Sub
Friend Sub New(ByVal s As SiteSettings)
MySettings = s
ParsePhotoBlock = s.ParsePhotoBlock.Value
ParseVideoBlock = s.ParseVideoBlock.Value
ParseStoriesBlock = s.ParseStoriesBlock.Value
End Sub
End Class
End Namespace

View File

@@ -39,8 +39,8 @@ Namespace API.Gfycat
If Not urlVideo.IsEmptyString Then
If urlVideo.Contains("redgifs.com") Then
_IsRedGifs = True
DirectCast(Settings(RedGifs.RedGifsSiteKey).Source, RedGifs.SiteSettings).UpdateTokenIfRequired()
Dim newData As IYouTubeMediaContainer = Settings(RedGifs.RedGifsSiteKey).GetSingleMediaInstance(urlVideo, Data.File)
DirectCast(Settings(RedGifs.RedGifsSiteKey).Default.Source, RedGifs.SiteSettings).UpdateTokenIfRequired()
Dim newData As IYouTubeMediaContainer = Settings(RedGifs.RedGifsSiteKey).Default.GetSingleMediaInstance(urlVideo, Data.File)
If Not newData Is Nothing Then
newData.Progress = Data.Progress
newData.Download(Data.UseCookies, Token)
@@ -49,7 +49,7 @@ Namespace API.Gfycat
With DirectCast(Data, YouTubeMediaContainerBase)
.Site = RedGifs.RedGifsSite
.SiteKey = RedGifs.RedGifsSiteKey
.SiteIcon = Settings(RedGifs.RedGifsSiteKey).Source.Image
.SiteIcon = Settings(RedGifs.RedGifsSiteKey).Default.Source.Image
End With
Else
Throw New Exception($"Unable to get RedGifs instance{vbCr}{Data.URL}{vbCr}{urlVideo}")

View File

@@ -10,9 +10,6 @@ Imports SCrawler.API.Base
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Objects
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies
@@ -21,18 +18,6 @@ Namespace API.Instagram
<Manifest(InstagramSiteKey), SeparatedTasks(1), SavedPosts, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
#Region "Images"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.InstagramIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.InstagramPic_76
End Get
End Property
#End Region
#Region "Providers"
Private Class TimersChecker : Inherits FieldsCheckerProviderBase
Private ReadOnly LVProvider As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
@@ -78,23 +63,23 @@ Namespace API.Instagram
Friend Const Header_Browser As String = "Sec-Ch-Ua"
Friend Const Header_BrowserExt As String = "Sec-Ch-Ua-Full-Version-List"
Friend Const Header_Platform As String = "Sec-Ch-Ua-Platform-Version"
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0), PClonable(Clone:=False)>
Friend ReadOnly Property HashTagged As PropertyValue
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2), PClonable(Clone:=False)>
Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3)>
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3), PClonable(Clone:=False)>
Friend Property HH_IG_APP_ID As PropertyValue
<PropertyOption(ControlText:="x-asbd-id", IsAuth:=True, AllowNull:=True), ControlNumber(4)>
<PropertyOption(ControlText:="x-asbd-id", IsAuth:=True, AllowNull:=True), ControlNumber(4), PClonable(Clone:=False)>
Friend Property HH_ASBD_ID As PropertyValue
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True), ControlNumber(5)>
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True), ControlNumber(5), PClonable(Clone:=False)>
Friend Property HH_IG_WWW_CLAIM As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua", IsAuth:=True, AllowNull:=True), ControlNumber(6)>
<PropertyOption(ControlText:="sec-ch-ua", IsAuth:=True, AllowNull:=True), ControlNumber(6), PClonable>
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)>
<PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", IsAuth:=True, AllowNull:=True), ControlNumber(7), PClonable>
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)>
<PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", IsAuth:=True, AllowNull:=True), ControlNumber(8), PClonable>
Private Property HH_PLATFORM As PropertyValue
<PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True), ControlNumber(9)>
<PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True), ControlNumber(9), PClonable>
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)
@@ -124,68 +109,69 @@ Namespace API.Instagram
End Sub
#End Region
#Region "Download properties"
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(20)>
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(20), PClonable>
Friend ReadOnly Property RequestsWaitTimer As PropertyValue
<Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(21)>
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(21), PClonable>
Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue
<Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider
<PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(22)>
<PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(22), PClonable>
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users"), PXML, ControlNumber(23)>
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users"), PXML, ControlNumber(23), PClonable>
Friend ReadOnly Property GetTimeline As PropertyValue
<PropertyOption(ControlText:="Get stories", ControlToolTip:="Default value for new users"), PXML, ControlNumber(24)>
<PropertyOption(ControlText:="Get stories", ControlToolTip:="Default value for new users"), PXML, ControlNumber(24), PClonable>
Friend ReadOnly Property GetStories As PropertyValue
<PropertyOption(ControlText:="Get stories: user", ControlToolTip:="Default value for new users"), PXML, ControlNumber(25)>
<PropertyOption(ControlText:="Get stories: user", ControlToolTip:="Default value for new users"), PXML, ControlNumber(25), PClonable>
Friend ReadOnly Property GetStoriesUser As PropertyValue
<PropertyOption(ControlText:="Get tagged photos", ControlToolTip:="Default value for new users"), PXML, ControlNumber(26)>
<PropertyOption(ControlText:="Get tagged photos", ControlToolTip:="Default value for new users"), PXML, ControlNumber(26), PClonable>
Friend ReadOnly Property GetTagged As PropertyValue
<PropertyOption(ControlText:="Tagged notify limit",
ControlToolTip:="If the number of tagged posts exceeds this number you will be notified." & vbCr &
"-1 to disable"), PXML, ControlNumber(27)>
"-1 to disable"), PXML, ControlNumber(27), PClonable>
Friend ReadOnly Property TaggedNotifyLimit As PropertyValue
<Provider(NameOf(TaggedNotifyLimit), FieldsChecker:=True)>
Private ReadOnly Property TaggedNotifyLimitProvider As IFormatProvider
#End Region
#Region "Download ready"
<PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download timeline"), PXML, ControlNumber(10)>
<PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download timeline"), PXML, ControlNumber(10), PClonable>
Friend ReadOnly Property DownloadTimeline As PropertyValue
<PropertyOption(ControlText:="Download stories", ControlToolTip:="Download stories"), PXML, ControlNumber(11)>
<PropertyOption(ControlText:="Download stories", ControlToolTip:="Download stories"), PXML, ControlNumber(11), PClonable>
Friend ReadOnly Property DownloadStories As PropertyValue
<PropertyOption(ControlText:="Download stories: user", ControlToolTip:="Download stories (user)"), PXML, ControlNumber(12)>
<PropertyOption(ControlText:="Download stories: user", ControlToolTip:="Download stories (user)"), PXML, ControlNumber(12), PClonable>
Friend ReadOnly Property DownloadStoriesUser As PropertyValue
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged posts"), PXML, ControlNumber(13)>
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged posts"), PXML, ControlNumber(13), PClonable>
Friend ReadOnly Property DownloadTagged As PropertyValue
#End Region
#Region "429 bypass"
Private ReadOnly Property DownloadingErrorDate As XMLValue(Of Date)
<PXML("InstagramDownloadingErrorDate")>
Private ReadOnly Property DownloadingErrorDate As PropertyValue
Friend Property LastApplyingValue As Integer? = Nothing
Friend ReadOnly Property ReadyForDownload As Boolean
Get
If SkipUntilNextSession Then Return False
With DownloadingErrorDate
If .ValueF.Exists Then
Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10)) < Now
If ACheck(Of Date)(.Value) Then
Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10)) < Now
Else
Return True
End If
End With
End Get
End Property
Private ReadOnly Property LastDownloadDate As XMLValue(Of Date)
Private ReadOnly Property LastRequestsCount As XMLValue(Of Integer)
<PXML> Private ReadOnly Property LastDownloadDate As PropertyValue
<PXML> Private ReadOnly Property LastRequestsCount As PropertyValue
<PropertyOption(IsInformationLabel:=True), ControlNumber(100)>
Private Property LastRequestsCountLabel As PropertyValue
Private ReadOnly LastRequestsCountLabelStr As Func(Of Integer, String) = Function(r) $"Number of spent requests: {r.NumToGroupIntegral}"
Private TooManyRequestsReadyForCatch As Boolean = True
Friend Function GetWaitDate() As Date
With DownloadingErrorDate
If .ValueF.Exists Then
Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10))
If ACheck(Of Date)(.Value) Then
Return CDate(.Value).AddMinutes(If(LastApplyingValue, 10))
Else
Return Now
End If
@@ -194,7 +180,7 @@ Namespace API.Instagram
Friend Sub TooManyRequests(ByVal Catched As Boolean)
With DownloadingErrorDate
If Catched Then
If Not .ValueF.Exists Then
If Not ACheck(Of Date)(.Value) Then
.Value = Now
If TooManyRequestsReadyForCatch Then
LastApplyingValue = If(LastApplyingValue, 0) + 10
@@ -203,7 +189,7 @@ Namespace API.Instagram
End If
End If
Else
.ValueF = Nothing
.Value = Nothing
LastApplyingValue = Nothing
TooManyRequestsReadyForCatch = True
End If
@@ -212,8 +198,8 @@ Namespace API.Instagram
#End Region
#End Region
#Region "Initializer"
Friend Sub New(ByRef _XML As XmlFile, ByVal GlobalPath As SFile)
MyBase.New(InstagramSite, "instagram.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New(InstagramSite, "instagram.com", AccName, Temp, My.Resources.SiteResources.InstagramIcon_32, My.Resources.SiteResources.InstagramPic_76)
Dim app_id$ = String.Empty
Dim www_claim$ = String.Empty
@@ -226,7 +212,7 @@ Namespace API.Instagram
With Responser
.Accept = "*/*"
useragent = .UserAgent
If .UserAgentExists Then useragent = .UserAgent Else .UserAgent = String.Empty
With .Headers
If .Count > 0 Then
token = .Value(Header_CSRF_TOKEN)
@@ -250,8 +236,6 @@ Namespace API.Instagram
.CookiesExtractedAutoSave = False
End With
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
HashTagged = New PropertyValue(String.Empty, GetType(String))
HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v))
HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v))
@@ -281,12 +265,11 @@ Namespace API.Instagram
TaggedNotifyLimit = New PropertyValue(200)
TaggedNotifyLimitProvider = New TaggedNotifyLimitChecker
DownloadingErrorDate = New XMLValue(Of Date) With {.Provider = New XMLValueConversionProvider(Function(ss, nn, vv, dd) AConvert(Of String)(vv, AModes.Var, Nothing))}
DownloadingErrorDate.SetExtended("InstagramDownloadingErrorDate", Now.AddYears(-10), _XML, n)
LastDownloadDate = New XMLValue(Of Date)("LastDownloadDate", Now.AddDays(-1), _XML, n)
LastRequestsCount = New XMLValue(Of Integer)("LastRequestsCount", 0, _XML, n)
DownloadingErrorDate = New PropertyValue(Nothing, GetType(Date))
LastDownloadDate = New PropertyValue(Now.AddDays(-1))
LastRequestsCount = New PropertyValue(0)
LastRequestsCountLabel = New PropertyValue(LastRequestsCountLabelStr.Invoke(LastRequestsCount.Value))
AddHandler LastRequestsCount.ValueChanged, Sub(sender, e) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(DirectCast(sender, XMLValue(Of Integer)).ValueF.Value)
LastRequestsCount.OnChangeFunction = Sub(vv) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(vv)
_AllowUserAgentUpdate = False
UrlPatternUser = "https://www.instagram.com/{0}/"
@@ -329,7 +312,7 @@ Namespace API.Instagram
Private _NextTagged As Boolean = True
Friend Overrides Sub DownloadStarted(ByVal What As Download)
ActiveJobs += 1
If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0"
If CDate(LastDownloadDate.Value).AddMinutes(120) < Now Or Not ACheck(HH_IG_WWW_CLAIM.Value) Then HH_IG_WWW_CLAIM.Value = "0"
End Sub
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
With DirectCast(User, UserData)
@@ -337,8 +320,8 @@ Namespace API.Instagram
.WaitNotificationMode = _NextWNM
.TaggedCheckSession = _NextTagged
End If
If LastDownloadDate.Value.AddMinutes(60) > Now Then
.RequestsCount = LastRequestsCount
If CDate(LastDownloadDate.Value).AddMinutes(60) > Now Then
.RequestsCount = LastRequestsCount.Value
Else
LastRequestsCount.Value = 0
.RequestsCount = 0

View File

@@ -71,7 +71,7 @@ Namespace API.Instagram
Return DirectCast(HOST.Source, SiteSettings)
End Get
End Property
Private ReadOnly PostsKVIDs As List(Of PostKV)
Protected ReadOnly PostsKVIDs As List(Of PostKV)
Private ReadOnly PostsToReparse As List(Of PostKV)
Private LastCursor As String = String.Empty
Private FirstLoadingDone As Boolean = False
@@ -175,7 +175,7 @@ Namespace API.Instagram
End If
End If
End Sub
Private Overloads Function PostKvExists(ByVal pkv As PostKV) As Boolean
Protected Overloads Function PostKvExists(ByVal pkv As PostKV) As Boolean
Return PostKvExists(pkv.ID, False, pkv.Section) OrElse PostKvExists(pkv.Code, True, pkv.Section)
End Function
Private Overloads Function PostKvExists(ByVal PostCodeId As String, ByVal IsCode As Boolean, ByVal Section As Sections) As Boolean
@@ -297,7 +297,7 @@ Namespace API.Instagram
Declarations.UpdateResponser(e, Responser)
End Sub
Protected Enum Sections : Timeline : Tagged : Stories : UserStories : SavedPosts : End Enum
Private Const StoriesFolder As String = "Stories"
Protected Const StoriesFolder As String = "Stories"
Private Const TaggedFolder As String = "Tagged"
#Region "429 bypass"
Private Const MaxPostsCount As Integer = 200
@@ -973,7 +973,8 @@ Namespace API.Instagram
Try
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/highlights/{ID}/highlights_tray/",, EDP.ThrowException)
If Not r.IsEmptyString Then
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing()("tray").XmlIfNothing
Dim ee As New ErrorsDescriber(EDP.ReturnValue) With {.DeclaredMessage = New MMessage($"{ToStringForLog()}:")}
Using j As EContainer = JsonDocument.Parse(r, ee).XmlIfNothing()("tray").XmlIfNothing
If j.Count > 0 Then Return j.Select(Function(jj) jj.Value("id").Replace("highlight:", String.Empty)).ListIfNothing
End Using
End If
@@ -1010,7 +1011,7 @@ Namespace API.Instagram
Optional ByVal s As Object = Nothing) As Integer
If Responser.StatusCode = HttpStatusCode.NotFound Then '404
If Not UserNameRequested AndAlso GetUserNameById() Then Return 1 Else UserExists = False
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then '400
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Or Responser.StatusCode = HttpStatusCode.Unauthorized Then '400, 401
HasError = True
MyMainLOG = $"Instagram credentials have expired [{CInt(Responser.StatusCode)}]: {ToStringForLog()} [{s}]"
DisableSection(s)

View File

@@ -15,32 +15,22 @@ Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.JustForFans
<Manifest("AndyProgram_JustForFans"), SavedPosts, SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.JFFIcon_64
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.JFFPic_76
End Get
End Property
Friend Const UserHash4_CookieName As String = "userhash4"
<PropertyOption(ControlText:="User ID", AllowNull:=False), PXML>
<PropertyOption(ControlText:="User ID", AllowNull:=False), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property UserID As PropertyValue
<PropertyOption, PXML>
<PropertyOption, PXML, PClonable(Clone:=False)>
Friend ReadOnly Property UserHash4 As PropertyValue
<PropertyOption(ControlText:="Accept", ControlToolTip:="Header 'Accept'")>
<PropertyOption(ControlText:="Accept", ControlToolTip:="Header 'Accept'"), PClonable>
Friend ReadOnly Property HeaderAccept As PropertyValue
<PropertyOption> Friend ReadOnly Property UserAgent As PropertyValue
<PropertyOption, PClonable> Friend ReadOnly Property UserAgent As PropertyValue
Private Sub UpdateHeader(ByVal HeaderName As String, ByVal HeaderValue As String)
Select Case HeaderName
Case NameOf(HeaderAccept) : If HeaderValue.IsEmptyString Then Responser.Accept = Nothing Else Responser.Accept = HeaderValue
Case NameOf(UserAgent) : If Not HeaderValue.IsEmptyString Then Responser.UserAgent = HeaderValue
End Select
End Sub
Friend Sub New()
MyBase.New("JustForFans", "justfor.fans")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("JustForFans", "justfor.fans", AccName, Temp, My.Resources.SiteResources.JFFIcon_64, My.Resources.SiteResources.JFFPic_76)
With Responser
.CookiesExtractMode = Responser.CookiesExtractModes.Any
@@ -53,7 +43,7 @@ Namespace API.JustForFans
UserID = New PropertyValue(String.Empty, GetType(String))
UserHash4 = New PropertyValue(String.Empty, GetType(String))
HeaderAccept = New PropertyValue(Responser.Accept.Value, GetType(String), Sub(v) UpdateHeader(NameOf(HeaderAccept), v))
UserAgent = New PropertyValue(Responser.UserAgent, GetType(String), Sub(v) UpdateHeader(NameOf(UserAgent), v))
UserAgent = New PropertyValue(If(Responser.UserAgentExists, Responser.UserAgent, String.Empty), GetType(String), Sub(v) UpdateHeader(NameOf(UserAgent), v))
_AllowUserAgentUpdate = False
UserRegex = RParams.DMS("https://justfor.fans/([^/\?]+)", 1, EDP.ReturnValue)

View File

@@ -297,7 +297,7 @@ Namespace API.JustForFans
InitializeFileSerial()
Dim r$
Dim m As UserMedia
Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ii As Integer) As UserMedia
Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ByVal ii As Integer) As UserMedia
input.State = UserMedia.States.Missing
input.Attempts = m.Attempts
Return input

View File

@@ -12,18 +12,8 @@ Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.LPSG
<Manifest("AndyProgram_LPSG")>
Friend Class SiteSettings : Inherits Base.SiteSettingsBase
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.LPSGIcon_48
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.LPSGPic_32
End Get
End Property
Friend Sub New()
MyBase.New("LPSG", "www.lpsg.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("LPSG", "www.lpsg.com", AccName, Temp, My.Resources.SiteResources.LPSGIcon_48, My.Resources.SiteResources.LPSGPic_32)
UrlPatternUser = "https://www.lpsg.com/threads/{0}/"
UserRegex = RParams.DMS(".+?lpsg.com/threads/[^/]+?\.(\d+)", 1, EDP.ReturnValue)
End Sub

View File

@@ -1,65 +0,0 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin
Imports SCrawler.API.Base
Imports PersonalUtilities.Functions.XML
Namespace API.Mastodon
Friend Class MastodonDomains : Inherits DomainsContainer
Friend ReadOnly Property Credentials As List(Of Credentials)
Friend ReadOnly Property CredentialsTemp As List(Of Credentials)
Private ReadOnly CredentialsFile As SFile = $"{SettingsFolderName}\Responser_Mastodon_DomainsCredentials.xml"
Friend Sub New(ByVal _Instance As ISiteSettings, ByVal DefaultValue As String)
MyBase.New(_Instance, DefaultValue)
Credentials = New List(Of Credentials)
CredentialsTemp = New List(Of Credentials)
If CredentialsFile.Exists Then
Using x As New XmlFile(CredentialsFile,, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Count > 0 Then Credentials.ListAddList(x, LAP.IgnoreICopier)
End Using
End If
End Sub
Friend Overrides Function Apply() As Boolean
If Changed Then
Credentials.Clear()
If CredentialsTemp.Count > 0 Then Credentials.AddRange(CredentialsTemp)
CredentialsTemp.Clear()
End If
Return MyBase.Apply()
End Function
Friend Overrides Sub Save()
If Credentials.Count > 0 Then
Using x As New XmlFile With {.AllowSameNames = True}
x.AddRange(Credentials)
x.Name = "DomainsCredentials"
x.Save(CredentialsFile)
End Using
Else
CredentialsFile.Delete(,, EDP.None)
End If
MyBase.Save()
End Sub
Friend Overrides Sub Reset()
CredentialsTemp.Clear()
MyBase.Reset()
End Sub
Friend Overrides Sub OpenSettingsForm()
Using f As New SettingsForm(Instance)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
Changed = True
CredentialsTemp.Clear()
If f.MyCredentials.Count > 0 Then CredentialsTemp.AddRange(f.MyCredentials)
DomainsTemp.Clear()
If f.MyDomains.Count > 0 Then DomainsTemp.ListAddList(f.MyDomains, LAP.NotContainsOnly)
End If
End Using
End Sub
End Class
End Namespace

View File

@@ -1,165 +0,0 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.Mastodon
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class SettingsForm : 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()
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SettingsForm))
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.CMB_DOMAINS = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.TXT_AUTH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_TOKEN = New PersonalUtilities.Forms.Controls.TextBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
TP_MAIN.SuspendLayout()
CType(Me.CMB_DOMAINS, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_AUTH, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_TOKEN, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 361)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
CONTAINER_MAIN.RightToolStripPanelVisible = False
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 361)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'TP_MAIN
'
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Controls.Add(Me.CMB_DOMAINS, 0, 0)
TP_MAIN.Controls.Add(Me.TXT_AUTH, 0, 1)
TP_MAIN.Controls.Add(Me.TXT_TOKEN, 0, 2)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.Size = New System.Drawing.Size(384, 361)
TP_MAIN.TabIndex = 0
'
'CMB_DOMAINS
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Add"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Add
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Delete"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Delete
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "Clear"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Name = "ArrowDown"
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
ActionButton4.Visible = False
Me.CMB_DOMAINS.Buttons.Add(ActionButton1)
Me.CMB_DOMAINS.Buttons.Add(ActionButton2)
Me.CMB_DOMAINS.Buttons.Add(ActionButton3)
Me.CMB_DOMAINS.Buttons.Add(ActionButton4)
Me.CMB_DOMAINS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_DOMAINS.ListDropDownStyle = PersonalUtilities.Forms.Controls.ComboBoxExtended.ListMode.Simple
Me.CMB_DOMAINS.Location = New System.Drawing.Point(4, 4)
Me.CMB_DOMAINS.Name = "CMB_DOMAINS"
Me.CMB_DOMAINS.Size = New System.Drawing.Size(378, 296)
Me.CMB_DOMAINS.TabIndex = 0
'
'TXT_AUTH
'
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Name = "Clear"
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_AUTH.Buttons.Add(ActionButton5)
Me.TXT_AUTH.CaptionText = "Auth"
Me.TXT_AUTH.CaptionToolTipEnabled = True
Me.TXT_AUTH.CaptionToolTipText = "Bearer token"
Me.TXT_AUTH.CaptionWidth = 50.0R
Me.TXT_AUTH.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_AUTH.Location = New System.Drawing.Point(4, 306)
Me.TXT_AUTH.Name = "TXT_AUTH"
Me.TXT_AUTH.Size = New System.Drawing.Size(376, 22)
Me.TXT_AUTH.TabIndex = 1
'
'TXT_TOKEN
'
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Name = "Clear"
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_TOKEN.Buttons.Add(ActionButton6)
Me.TXT_TOKEN.CaptionText = "Token"
Me.TXT_TOKEN.CaptionToolTipEnabled = True
Me.TXT_TOKEN.CaptionToolTipText = "csrf token"
Me.TXT_TOKEN.CaptionWidth = 50.0R
Me.TXT_TOKEN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_TOKEN.Location = New System.Drawing.Point(4, 335)
Me.TXT_TOKEN.Name = "TXT_TOKEN"
Me.TXT_TOKEN.Size = New System.Drawing.Size(376, 22)
Me.TXT_TOKEN.TabIndex = 2
'
'SettingsForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(384, 361)
Me.Controls.Add(CONTAINER_MAIN)
Me.Icon = Global.SCrawler.My.Resources.SiteResources.MastodonIcon_48
Me.MinimumSize = New System.Drawing.Size(400, 400)
Me.Name = "SettingsForm"
Me.ShowInTaskbar = False
Me.Text = "Mastodon domains"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
CType(Me.CMB_DOMAINS, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_AUTH, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_TOKEN, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents CMB_DOMAINS As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents TXT_AUTH As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_TOKEN As PersonalUtilities.Forms.Controls.TextBoxExtended
End Class
End Namespace

View File

@@ -1,292 +0,0 @@
<?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="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
QVRIS62WWWxMURjHL220JW1HausmlFrDFKUhnUGH6bRFzJ2idImlC0Vp2mlji1A8iNhCPIjIRES8EU+W
h2oEtbSDTk3HNNM7S01VKsXjkb/vXBo3k1Ee7sMvmZzzzf//ne/+z50RAAxL1MUIG4G/YAv3HSVhF5Vw
IYNdz3LadVj9RgdTB+HQYYPHIJuE1ocSdlEJFzG+1bPRLQLinglIeCkg+XUkKvz56hnkOfQs/rmA8S9H
YEp7FDI64tAQtKhnsMapZ7zzNHsUFnbGY4VzIk70l6hnIH4wsDR7NBZ3apDrSqL5T8eFgUr1DLZ78lim
Q4N8VzK29MxEpZSBa4M16hnU+c3M9CEFpdJsVHsXos63DDcHrf9nQEXD5VymwW/5USLNwl5vJhp7dTgW
NML2pR7jbsUMS+KdMTa5Q8NQxinfBU4dRFcOyjy52OtbhwOBDTgZLKPPmTgY0ON4MBdNfSbYBupxY8Aq
G10dqMG5/nIc7ytGQ6CQRliAamkTN/g1Ai4e95Qy3iogpX0UtBRDnhRzdxq2SXOxz5eFQ70rScCEU335
ssGxj0YS06HSm4GN3ekwdE2C1hGH1LZR0JDOJof5jwHvnIvzTa0jlooTYfktvt+fhcOBHDQFTWRgxJGP
ObAGsulZLMLWnjlY756K5c4JmNcRi6T2SGheCIihS2l5ozAo6NRhMolnUAcGV6IcwwqvFrX+JTjYuwKH
SfRAYDms/mzs9y1GFe2VSnOw1j0FejqpLN4WCX4ZufiIBwLMLxQGm12rsLQzgWKYgmLPLNTQw6ynpDSS
IBet8y+TqaVRVdFIeJrWuCcj+/0EzH43BomvIhBLI45uFiDcJ+6QwROFwa6+Amb9bGFNg6Xs9Ncd7Oy3
Knb2eyU7/20nu9y/m136tIvEl6BC0qKoZwby3alo9JVhj7T5R7m/kJVIIityi8zyXmTiW+I10SqyIQNb
uIgNwYuuf25kFd75KPKkI49OmUWnrfYWyXv/wBb2cijhhVf6a9lGei65XclYRDd6mj0GWz2iLBJaH0rY
RSVc5Eywmhm7kuQXHX+bJlBStrh+zTi0PpSwi0q4yNFAOVvgiEcKJWUsxZn/NhT+znlofShhF5VwkRpv
MUtti4KGYjj6sYCIh5QSu4oG27stjItHU+cjeQzvkcFzFQ2KnSKLoc4FukDCXeI2GbSoaFD4ziyPxNxK
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -1,154 +0,0 @@
' 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
Imports PersonalUtilities.Forms.Controls.Base
Namespace API.Mastodon
Friend Class SettingsForm
Private WithEvents MyDefs As DefaultFormOptions
Friend ReadOnly Property MyCredentials As List(Of Credentials)
Friend ReadOnly Property MyDomains As List(Of String)
Friend Sub New(ByVal s As SiteSettings)
InitializeComponent()
MyCredentials = New List(Of Credentials)
If s.Domains.Credentials.Count > 0 Then MyCredentials.AddRange(s.Domains.Credentials)
MyDomains = New List(Of String)
MyDomains.ListAddList(s.Domains)
MyDefs = New DefaultFormOptions(Me, Settings.Design)
End Sub
Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyView = New FormView(Me, Settings.Design, "MastodonSettingsForm")
.MyView.Import()
.MyView.SetFormSize()
.AddOkCancelToolbar()
RefillList()
.EndLoaderOperations()
End With
End Sub
Private Sub SettingsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyCredentials.Clear()
MyDomains.Clear()
End Sub
Private Sub RefillList()
CMB_DOMAINS.Items.Clear()
If MyDomains.Count > 0 Then
MyDomains.Sort()
CMB_DOMAINS.BeginUpdate()
CMB_DOMAINS.Items.AddRange(MyDomains.Select(Function(d) New ListItem(d)))
CMB_DOMAINS.EndUpdate(True)
End If
End Sub
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
ApplyCredentials()
If MyCredentials.Count > 0 Then MyCredentials.RemoveAll(Function(c) c.Domain.IsEmptyString Or c.Bearer.IsEmptyString Or c.Csrf.IsEmptyString)
If MyDomains.Count > 0 Then
If MyCredentials.Count > 0 Then
MyCredentials.RemoveAll(Function(c) Not MyDomains.Contains(c.Domain))
Else
MyCredentials.Clear()
End If
End If
MyDefs.CloseForm()
End Sub
Private Sub CMB_DOMAINS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles CMB_DOMAINS.ActionOnButtonClick
Try
Dim d$
Dim i% = -1
Select Case e.DefaultButton
Case ActionButton.DefaultButtons.Add
d = InputBoxE("Enter a new domain using the pattern [mastodon.social]:", "New domain")
If Not d.IsEmptyString Then
If MyDomains.Count > 0 Then i = MyDomains.IndexOf(d)
If i >= 0 Then
MsgBoxE({$"Domain '{d}' already exists", "Add domain"}, vbExclamation)
If i <= CMB_DOMAINS.Count - 1 Then CMB_DOMAINS.SelectedIndex = i
Else
ApplyCredentials()
ClearCredentials()
MyDomains.Add(d)
_Suspended = True
RefillList()
_Suspended = False
i = MyDomains.IndexOf(d)
If i.ValueBetween(0, CMB_DOMAINS.Count - 1) Then
CMB_DOMAINS.SelectedIndex = i
Else
_LatestSelected = -1
_CurrentCredentialsIndex = -1
_CurrentDomain = String.Empty
End If
End If
End If
Case ActionButton.DefaultButtons.Delete
If _LatestSelected >= 0 Then
d = CMB_DOMAINS.Items(_LatestSelected).Value(0)
If Not d.IsEmptyString AndAlso MsgBoxE({$"Are you sure you want to delete the [{d}] domain?",
"Removing domains"}, vbYesNo) = vbYes Then
i = MyDomains.IndexOf(d)
Dim l% = _LatestSelected
If i >= 0 Then
ClearCredentials()
MyDomains.RemoveAt(i)
_Suspended = True
RefillList()
_Suspended = False
If (l - 1).ValueBetween(0, CMB_DOMAINS.Count - 1) Then
CMB_DOMAINS.SelectedIndex = l - 1
Else
_LatestSelected = -1
_CurrentCredentialsIndex = -1
_CurrentDomain = String.Empty
End If
End If
End If
End If
End Select
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "API.Mastodon.SettingsForm.ActionButtonClick")
End Try
End Sub
Private _LatestSelected As Integer = -1
Private _CurrentCredentialsIndex As Integer = -1
Private _CurrentDomain As String = String.Empty
Private _Suspended As Boolean = False
Private Sub CMB_DOMAINS_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_DOMAINS.ActionSelectedItemChanged
If Not MyDefs.Initializing And Not _Suspended Then
Dim DropCredentials As Boolean = True
If Not Item Is Nothing Then
ApplyCredentials()
_LatestSelected = Item.Index
_CurrentDomain = Item.Text
If MyCredentials.Count > 0 And Not _CurrentDomain.IsEmptyString Then
_CurrentCredentialsIndex = MyCredentials.IndexOf(_CurrentDomain)
If _CurrentCredentialsIndex >= 0 Then
With MyCredentials(_CurrentCredentialsIndex) : TXT_AUTH.Text = .Bearer : TXT_TOKEN.Text = .Csrf : End With
DropCredentials = False
End If
Else
_CurrentCredentialsIndex = -1
End If
End If
If DropCredentials Then ClearCredentials()
End If
End Sub
Private Sub ClearCredentials()
TXT_AUTH.Clear()
TXT_TOKEN.Clear()
End Sub
Private Sub ApplyCredentials()
Try
If _LatestSelected >= 0 And Not _CurrentDomain.IsEmptyString Then
Dim c As New Credentials With {.Domain = _CurrentDomain, .Bearer = TXT_AUTH.Text, .Csrf = TXT_TOKEN.Text}
If _CurrentCredentialsIndex.ValueBetween(0, MyCredentials.Count - 1) Then MyCredentials(_CurrentCredentialsIndex) = c Else MyCredentials.Add(c)
End If
Catch ex As Exception
End Try
End Sub
End Class
End Namespace

View File

@@ -18,29 +18,34 @@ Namespace API.Mastodon
<Manifest(MastodonSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.MastodonIcon_48
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.MastodonPic_48
End Get
End Property
#Region "Domains"
<PXML("Domains")> Private ReadOnly Property SiteDomains As PropertyValue
Friend ReadOnly Property Domains As MastodonDomains
<PXML> Private ReadOnly Property DomainsLastUpdateDate As PropertyValue
<PXML("Domains"), PClonable> Private ReadOnly Property SiteDomains As PropertyValue
Private Shadows ReadOnly Property DefaultInstance As SiteSettings
Get
Return MyBase.DefaultInstance
End Get
End Property
Private ReadOnly _Domains As DomainsContainer
Friend ReadOnly Property Domains As DomainsContainer
Get
Return If(DefaultInstance?.Domains, _Domains)
End Get
End Property
<PXML("DomainsLastUpdateDate")> Private ReadOnly Property Base_DomainsLastUpdateDate As PropertyValue
Private ReadOnly Property DomainsLastUpdateDate As PropertyValue
Get
Return If(DefaultInstance?.DomainsLastUpdateDate, Base_DomainsLastUpdateDate)
End Get
End Property
#End Region
#Region "Auth"
<PropertyOption(IsAuth:=True, AllowNull:=False, ControlText:="My domain",
ControlToolTip:="Your account domain without 'https://' (for example, 'mastodon.social')"), PXML>
ControlToolTip:="Your account domain without 'https://' (for example, 'mastodon.social')"), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property MyDomain As PropertyValue
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Authorization",
ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word"), PClonable(Clone:=False)>
Friend ReadOnly Property Auth As PropertyValue
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header"), PClonable(Clone:=False)>
Friend ReadOnly Property Token As PropertyValue
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
If Not PropName.IsEmptyString Then
@@ -58,29 +63,29 @@ Namespace API.Mastodon
End Sub
#End Region
#Region "Other properties"
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsDownloadCaption), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsDownloadCaption), PXML, PClonable>
Friend ReadOnly Property GifsDownload As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML, PClonable>
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML, PClonable>
Friend ReadOnly Property GifsPrefix As PropertyValue
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
Private ReadOnly Property GifStringChecker As IFormatProvider
<PropertyOption(IsAuth:=False, ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML>
<PropertyOption(IsAuth:=False, ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML, PClonable>
Friend ReadOnly Property UseMD5Comparison As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:="User related to my domain",
ControlToolTip:="Open user profiles and user posts through my domain."), PXML>
ControlToolTip:="Open user profiles and user posts through my domain."), PXML, PClonable>
Friend ReadOnly Property UserRelatedToMyDomain As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("Mastodon", "mastodon.social")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("Mastodon", "mastodon.social", AccName, Temp, My.Resources.SiteResources.MastodonIcon_48, My.Resources.SiteResources.MastodonPic_48)
Domains = New MastodonDomains(Me, "mastodon.social")
_Domains = New DomainsContainer(Me, "mastodon.social")
SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String))
Domains.DestinationProp = SiteDomains
DomainsLastUpdateDate = New PropertyValue(Now.AddYears(-1))
Base_DomainsLastUpdateDate = New PropertyValue(Now.AddYears(-1))
Auth = New PropertyValue(Responser.Headers.Value(DN.Header_Authorization), GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
Token = New PropertyValue(Responser.Headers.Value(DN.Header_CSRFToken), GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
@@ -182,20 +187,32 @@ Namespace API.Mastodon
#End Region
#Region "IsMyUser, IsMyImageVideo"
Private Const UserRegexDefault As String = "https?://{0}/@([^/@]+)@?([^/]*)"
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Friend Overloads Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
If Domains.Count > 0 Then
Dim l As List(Of String)
Dim e As ExchangeOptions
If ACheck(MyDomain.Value) Then
e = IsMyUser(UserURL, MyDomain.Value)
If Not e.SiteName.IsEmptyString Then Return e
End If
For Each domain$ In Domains
UserRegex.Pattern = String.Format(UserRegexDefault, domain)
l = RegexReplace(UserURL, UserRegex)
If l.ListExists(2) Then Return New ExchangeOptions(Site, $"{l(2).IfNullOrEmpty(domain)}@{l(1)}")
e = IsMyUser(UserURL, domain)
If Not e.SiteName.IsEmptyString Then Return e
Next
End If
Return Nothing
End Function
Private Overloads Function IsMyUser(ByVal UserURL As String, ByVal Domain As String) As ExchangeOptions
UserRegex.Pattern = String.Format(UserRegexDefault, Domain)
Dim l As List(Of String) = RegexReplace(UserURL, UserRegex)
If l.ListExists(2) Then Return New ExchangeOptions(Site, $"{l(2).IfNullOrEmpty(Domain)}@{l(1)}") Else Return Nothing
End Function
Friend Overrides Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
If Not URL.IsEmptyString And Domains.Count > 0 Then
If Domains.Domains.Exists(Function(d) URL.Contains(d)) Then Return New ExchangeOptions(Site, URL) With {.Exists = True}
Dim urlDomain$ = RegexReplace(URL, RParams.DM("[^/]+", 1, EDP.ReturnValue, String.Empty))
If Not urlDomain.IsEmptyString Then
urlDomain = urlDomain.StringToLower
If Domains.Domains.Exists(Function(d) urlDomain = d.StringToLower) Then Return New ExchangeOptions(Site, URL) With {.Exists = True}
End If
End If
Return Nothing
End Function
@@ -222,6 +239,12 @@ Namespace API.Mastodon
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.Mastodon.SiteSettings.UpdateServersList]")
End Try
End Sub
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then _Domains.Dispose()
MyBase.Dispose(disposing)
End Sub
#End Region
End Class
End Namespace

View File

@@ -18,7 +18,6 @@ Namespace API.Mastodon
Friend Class UserData : Inherits Twitter.UserData
#Region "XML names"
Private Const Name_UserDomain As String = "UserDomain"
Private Const Name_TrueName As String = "TrueName"
#End Region
#Region "Declarations"
Private _UserDomain As String = String.Empty
@@ -38,22 +37,7 @@ Namespace API.Mastodon
End Property
Private MyCredentials As Credentials
Private Sub ResetCredentials()
MyCredentials = Nothing
With MySettings
Dim setDef As Boolean = True
If Not IsSavedPosts Then
If ACheck(.MyDomain.Value) AndAlso UserDomain = .MyDomain.Value Then
setDef = True
ElseIf .Domains.Credentials.Count > 0 Then
Dim i% = .Domains.Credentials.IndexOf(UserDomain)
If i >= 0 Then
MyCredentials = .Domains.Credentials(i)
setDef = Not MyCredentials.Exists
End If
End If
End If
If setDef Then MyCredentials = New Credentials With {.Domain = UserDomain, .Bearer = MySettings.Auth.Value, .Csrf = MySettings.Token.Value}
End With
MyCredentials = New Credentials With {.Domain = MySettings.MyDomain.Value, .Bearer = MySettings.Auth.Value, .Csrf = MySettings.Token.Value}
With MyCredentials
Responser.Headers.Add(DeclaredNames.Header_Authorization, .Bearer)
Responser.Headers.Add(DeclaredNames.Header_CSRFToken, .Csrf)

View File

@@ -16,23 +16,11 @@ Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.OnlyFans
<Manifest("AndyProgram_OnlyFans"), SavedPosts, SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Icon"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.OnlyFansIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.OnlyFansPic_32
End Get
End Property
#End Region
#Region "Declarations"
#Region "Options"
<PropertyOption(ControlText:="Download highlights", ControlToolTip:="Download profile highlights if they exists"), PXML>
<PropertyOption(ControlText:="Download highlights", ControlToolTip:="Download profile highlights if they exists"), PXML, PClonable>
Friend Property DownloadHighlights As PropertyValue
<PropertyOption(ControlText:="Download chat", ControlToolTip:="Download unlocked chat media"), PXML>
<PropertyOption(ControlText:="Download chat", ControlToolTip:="Download unlocked chat media"), PXML, PClonable>
Friend Property DownloadChatMedia As PropertyValue
#End Region
#Region "Headers"
@@ -40,15 +28,15 @@ Namespace API.OnlyFans
Private Const HeaderUserID As String = "User-Id"
Private Const HeaderXBC As String = "X-Bc"
Private Const HeaderAppToken As String = "App-Token"
<PropertyOption(ControlText:=HeaderUserID, AllowNull:=False)>
<PropertyOption(ControlText:=HeaderUserID, AllowNull:=False), PClonable(Clone:=False)>
Friend ReadOnly Property HH_USER_ID As PropertyValue
<PropertyOption(ControlText:=HeaderXBC, AllowNull:=False)>
<PropertyOption(ControlText:=HeaderXBC, AllowNull:=False), PClonable(Clone:=False)>
Private ReadOnly Property HH_X_BC As PropertyValue
<PropertyOption(ControlText:=HeaderAppToken, AllowNull:=False)>
<PropertyOption(ControlText:=HeaderAppToken, AllowNull:=False), PClonable(Clone:=False)>
Private ReadOnly Property HH_APP_TOKEN As PropertyValue
<PropertyOption(ControlText:=HeaderBrowser, ControlToolTip:="Can be null", AllowNull:=True)>
<PropertyOption(ControlText:=HeaderBrowser, ControlToolTip:="Can be null", AllowNull:=True), PClonable>
Private ReadOnly Property HH_BROWSER As PropertyValue
<PropertyOption(AllowNull:=False)>
<PropertyOption(AllowNull:=False), PClonable>
Private ReadOnly Property UserAgent As PropertyValue
Private Sub UpdateHeader(ByVal PropertyName As String, ByVal Value As String)
Dim hName$ = String.Empty
@@ -79,21 +67,21 @@ Namespace API.OnlyFans
End Property
<PropertyOption(ControlText:="Use old authorization rules",
ControlToolTip:="Use old dynamic rules (from 'DATAHOARDERS') or new ones (from 'DIGITALCRIMINALS')." & vbCr &
"Change this value only if you know what you are doing."), PXML>
"Change this value only if you know what you are doing."), PXML, PClonable>
Friend ReadOnly Property UseOldAuthRules As PropertyValue
<PropertyOption(ControlText:="Dynamic rules update", ControlToolTip:="'Dynamic rules' update interval (minutes). Default: 1440", LeftOffset:=110), PXML>
<PropertyOption(ControlText:="Dynamic rules update", ControlToolTip:="'Dynamic rules' update interval (minutes). Default: 1440", LeftOffset:=110), PXML, PClonable>
Friend ReadOnly Property DynamicRulesUpdateInterval As PropertyValue
<Provider(NameOf(DynamicRulesUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property DynamicRulesUpdateIntervalProvider As IFormatProvider
<PropertyOption(ControlText:="Dynamic rules",
ControlToolTip:="Overwrite 'Dynamic rules' with this URL" & vbCr &
"Change this value only if you know what you are doing."), PXML>
"Change this value only if you know what you are doing."), PXML, PClonable>
Friend ReadOnly Property DynamicRules As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("OnlyFans", ".onlyfans.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("OnlyFans", ".onlyfans.com", AccName, Temp, My.Resources.SiteResources.OnlyFansIcon_32, My.Resources.SiteResources.OnlyFansPic_32)
With Responser
.Accept = "application/json, text/plain, */*"

View File

@@ -380,7 +380,7 @@ Namespace API.OnlyFans
Try
If ContentMissingExists Then
Dim m As UserMedia
Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ii As Integer) As UserMedia
Dim stateRefill As Func(Of UserMedia, Integer, UserMedia) = Function(ByVal input As UserMedia, ByVal ii As Integer) As UserMedia
input.State = UStates.Missing
input.Attempts = m.Attempts
Return input
@@ -444,42 +444,56 @@ Namespace API.OnlyFans
Return f
End Get
End Property
Private Function UpdateSignature(ByVal Path As String, Optional ByVal ForceUpdateAuth As Boolean = False) As Boolean
Private Function UpdateSignature(ByVal Path As String, Optional ByVal ForceUpdateAuth As Boolean = False,
Optional ByVal Round As Integer = 0) As Boolean
Try
If UpdateAuthFile(ForceUpdateAuth) Then
Const nullMsg$ = "The auth parameter is null"
Dim j As EContainer = JsonDocument.Parse(AuthFile.GetText)
Dim pattern$ = j.Value("format")
If pattern.IsEmptyString Then Throw New ArgumentNullException("format", nullMsg)
pattern = pattern.Replace("{}", "{0}").Replace("{:x}", "{1:x}")
Dim j As EContainer
Try
j = JsonDocument.Parse(AuthFile.GetText)
Catch jex As Exception
If Round = 0 Then
AuthFile.Delete()
UpdateAuthFile(True)
Return UpdateSignature(Path, ForceUpdateAuth, Round + 1)
Else
MySettings.SessionAborted = True
Return False
End If
End Try
If Not j Is Nothing Then
Dim pattern$ = j.Value("format")
If pattern.IsEmptyString Then Throw New ArgumentNullException("format", nullMsg)
pattern = pattern.Replace("{}", "{0}").Replace("{:x}", "{1:x}")
Dim li%() = j("checksum_indexes").Select(Function(e) CInt(e(0).Value)).ToArray
Dim li%() = j("checksum_indexes").Select(Function(e) CInt(e(0).Value)).ToArray
If Not li.ListExists Then Throw New ArgumentNullException("checksum_indexes", nullMsg)
If j.Value("static_param").IsEmptyString Then Throw New ArgumentNullException("static_param", nullMsg)
If j.Value("checksum_constant").IsEmptyString Then Throw New ArgumentNullException("checksum_constant", nullMsg)
If Not li.ListExists Then Throw New ArgumentNullException("checksum_indexes", nullMsg)
If j.Value("static_param").IsEmptyString Then Throw New ArgumentNullException("static_param", nullMsg)
If j.Value("checksum_constant").IsEmptyString Then Throw New ArgumentNullException("checksum_constant", nullMsg)
Dim t$ = ADateTime.ConvertToUnix64(Now.ToUniversalTime).ToString
Dim h$ = String.Join(vbLf, j.Value("static_param"), t, Path, MySettings.HH_USER_ID.Value.ToString)
Dim t$ = ADateTime.ConvertToUnix64(Now.ToUniversalTime).ToString
Dim h$ = String.Join(vbLf, j.Value("static_param"), t, Path, MySettings.HH_USER_ID.Value.ToString)
Dim hash$ = GetHashSha1(h)
Dim hashBytes() As Byte = System.Text.Encoding.ASCII.GetBytes(hash)
Dim hashSum% = li.Sum(Function(i) hashBytes(i)) + CInt(j.Value("checksum_constant"))
Dim sign$ = String.Format(pattern, hash, Math.Abs(hashSum))
Dim hash$ = GetHashSha1(h)
Dim hashBytes() As Byte = System.Text.Encoding.ASCII.GetBytes(hash)
Dim hashSum% = li.Sum(Function(i) hashBytes(i)) + CInt(j.Value("checksum_constant"))
Dim sign$ = String.Format(pattern, hash, Math.Abs(hashSum))
'#If DEBUG Then
'Debug.WriteLine(sign)
'Debug.WriteLine(t)
'#End If
'#If DEBUG Then
'Debug.WriteLine(sign)
'Debug.WriteLine(t)
'#End If
Responser.Headers.Add(HeaderSign, sign)
Responser.Headers.Add(HeaderTime, t)
Responser.Headers.Add(HeaderSign, sign)
Responser.Headers.Add(HeaderTime, t)
j.Dispose()
Return True
Else
Return False
j.Dispose()
Return True
End If
End If
Return False
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, $"{ToStringForLog()}: UpdateSignature", False)
End Try
@@ -526,7 +540,7 @@ Namespace API.OnlyFans
Private _DownloadingException_AuthFileUpdate 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
If Responser.StatusCode = Net.HttpStatusCode.BadRequest Then
If Responser.StatusCode = Net.HttpStatusCode.BadRequest Then '400
If Not _DownloadingException_AuthFileUpdate AndAlso UpdateAuthFile(True) Then
_DownloadingException_AuthFileUpdate = True
Return 2
@@ -535,13 +549,17 @@ Namespace API.OnlyFans
MyMainLOG = $"{ToStringForLog()}: OnlyFans credentials expired"
Return 1
End If
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then
ElseIf Responser.StatusCode = Net.HttpStatusCode.NotFound Then '404
UserExists = False
Return 1
ElseIf Responser.StatusCode = Net.HttpStatusCode.GatewayTimeout Or Responser.StatusCode = 429 Then
ElseIf Responser.StatusCode = Net.HttpStatusCode.GatewayTimeout Or Responser.StatusCode = 429 Then '504, 429
If Responser.StatusCode = 429 Then MyMainLOG = $"[429] OnlyFans too many requests ({ToStringForLog()})"
MySettings.SessionAborted = True
Return 1
ElseIf Responser.StatusCode = Net.HttpStatusCode.Unauthorized Then '401
MySettings.SessionAborted = True
MyMainLOG = $"{ToStringForLog()}: OnlyFans credentials expired"
Return 1
Else
Return 0
End If

View File

@@ -12,19 +12,8 @@ Imports SCrawler.Plugin.Attributes
Namespace API.PathPlugin
<Manifest(PluginKey)>
Friend Class SiteSettings : Inherits SiteSettingsBase
Private ReadOnly _Icon As Icon = Nothing
Friend Overrides ReadOnly Property Icon As Icon
Get
Return _Icon
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return PersonalUtilities.My.Resources.FolderOpenPic_Orange_16
End Get
End Property
Friend Sub New()
MyBase.New(PluginName)
MyBase.New(PluginName,, PersonalUtilities.My.Resources.FolderOpenPic_Orange_16)
_Icon = PersonalUtilities.Tools.ImageRenderer.GetIcon(PersonalUtilities.My.Resources.FolderOpenPic_Orange_16, EDP.ReturnValue)
End Sub
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider

View File

@@ -9,33 +9,22 @@
Imports SCrawler.API.Base
Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Pinterest
<Manifest("AndyProgram_Pinterest"), SavedPosts, SeparatedTasks>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.PinterestIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.PinterestPic_48
End Get
End Property
<PropertyOption(ControlText:=DeclaredNames.ConcurrentDownloadsCaption,
ControlToolTip:=DeclaredNames.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter>
ControlToolTip:=DeclaredNames.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter, PClonable>
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
<Provider(NameOf(ConcurrentDownloads), FieldsChecker:=True)>
Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML>
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("Pinterest", "pinterest.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("Pinterest", "pinterest.com", AccName, Temp, My.Resources.SiteResources.PinterestIcon_32, My.Resources.SiteResources.PinterestPic_48)
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
ConcurrentDownloads = New PropertyValue(1)
MyConcurrentDownloadsProvider = New ConcurrentDownloadsProvider

View File

@@ -24,6 +24,7 @@ Namespace API.PornHub
0, RegexOptions.Singleline, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
Friend ReadOnly RegexVideo_Video_VideoKey As RParams = RParams.DMS("viewkey=([\w\d]+)", 1, EDP.ReturnValue)
Friend ReadOnly RegexVideoPageTitle As RParams = RParams.DMS("meta (property|name)=""[^:]+?:title"" content=""([^""]+)""", 2, EDP.ReturnValue)
Friend ReadOnly RegexDataToken As RParams = RParams.DMS("data-token=""([^""]+)", 1, EDP.ReturnValue)
#End Region
#Region "Declarations M3U8"
Friend ReadOnly Regex_M3U8_FilesList As RParams = RParams.DM("RESOLUTION=\d+x(\d+).*?[\r\n]*?(.+?m3u8.*)", 0, RegexReturn.List, EDP.ReturnValue)

View File

@@ -15,40 +15,30 @@ Namespace API.PornHub
<Manifest("AndyProgram_PornHub"), SavedPosts, SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.PornHubIcon_16
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.PornHubPic_16
End Get
End Property
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML, PClonable>
Friend Property DownloadUHD As PropertyValue
<PropertyOption(ControlText:="Download uploaded", ControlToolTip:="Download uploaded videos"), PXML>
<PropertyOption(ControlText:="Download uploaded", ControlToolTip:="Download uploaded videos"), PXML, PClonable>
Friend Property DownloadUploaded As PropertyValue
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged videos"), PXML>
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged videos"), PXML, PClonable>
Friend Property DownloadTagged As PropertyValue
<PropertyOption(ControlText:="Download private", ControlToolTip:="Download private videos"), PXML>
<PropertyOption(ControlText:="Download private", ControlToolTip:="Download private videos"), PXML, PClonable>
Friend Property DownloadPrivate As PropertyValue
<PropertyOption(ControlText:="Download favorite", ControlToolTip:="Download favorite videos"), PXML>
<PropertyOption(ControlText:="Download favorite", ControlToolTip:="Download favorite videos"), PXML, PClonable>
Friend Property DownloadFavorite 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, PClonable>
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, PClonable>
Friend ReadOnly Property DownloadGifsAsMp4 As PropertyValue
<PropertyOption(ControlText:="Photo ModelHub only",
ControlToolTip:="Download photo only from ModelHub. Prornstar photos hosted on PornHub itself will not be downloaded." & vbCr &
"Attention! Downloading photos hosted on PornHub is a very heavy job."), PXML>
"Attention! Downloading photos hosted on PornHub is a very heavy job."), PXML, PClonable>
Friend ReadOnly Property DownloadPhotoOnlyFromModelHub As PropertyValue
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML>
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("PornHub", "pornhub.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("PornHub", "pornhub.com", AccName, Temp, My.Resources.SiteResources.PornHubIcon_16, My.Resources.SiteResources.PornHubPic_16)
With Responser : .CurlSslNoRevoke = True : .CurlInsecure = True : End With
DownloadUHD = New PropertyValue(False)

View File

@@ -29,7 +29,7 @@ Namespace API.PornHub
Private Const Name_DownloadFavorite As String = "DownloadFavorite"
Private Const Name_DownloadGifs As String = "DownloadGifs"
Private Const Name_DownloadPhotoOnlyFromModelHub As String = "DownloadPhotoOnlyFromModelHub"
Private Const Name_IsUser As String = "IsUser"
<Obsolete> Private Const Name_IsUser As String = "IsUser"
#End Region
#Region "Structures"
Private Structure FlashVar : Implements IRegExCreator
@@ -117,6 +117,8 @@ Namespace API.PornHub
Private Const PersonTypeUser As String = "users"
Private Const PersonTypePornstar As String = "pornstar"
Private Const PersonTypeCannel As String = "channels"
Private Const PersonTypePlaylist As String = "playlist"
Private Const PlaylistsLabelName As String = "Playlist"
#End Region
#Region "Person"
Friend Property PersonType As String
@@ -133,7 +135,7 @@ Namespace API.PornHub
#Region "Advanced fields"
Friend Overrides ReadOnly Property FeedIsUser As Boolean
Get
Return IsUser
Return IsUser Or SiteMode = SiteModes.Playlists
End Get
End Property
Private Property PhotoPageModel As PhotoPageModels = PhotoPageModels.Undefined
@@ -144,12 +146,12 @@ Namespace API.PornHub
Friend Property DownloadFavorite As Boolean = False
Friend Property DownloadGifs As Boolean
Friend Property DownloadPhotoOnlyFromModelHub As Boolean = True
Private _IsUser As Boolean = True
Friend Overrides ReadOnly Property IsUser As Boolean
Get
Return _IsUser
Return SiteMode = SiteModes.User
End Get
End Property
Friend Property SiteMode As SiteModes = SiteModes.User
Friend Property QueryString As String
Get
If IsUser Then
@@ -164,7 +166,7 @@ Namespace API.PornHub
End Property
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
Return {SearchRequestLabelName, PlaylistsLabelName}
End Get
End Property
#End Region
@@ -192,38 +194,43 @@ Namespace API.PornHub
Return DirectCast(HOST.Source, SiteSettings)
End Get
End Property
Private ReadOnly LastPageIDs As List(Of String)
#End Region
#Region "Initializer"
Friend Sub New()
LastPageIDs = New List(Of String)
UseInternalM3U8Function = True
UseClientTokens = True
SessionPosts = New List(Of String)
End Sub
#End Region
#Region "Loader"
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
If Not Force OrElse (Not IsUser AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
If Not Force OrElse (Not IsUser AndAlso Not SiteMode = SiteModes.Playlists AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
Dim eObj As Plugin.ExchangeOptions = Nothing
If Force Then eObj = MySettings.IsMyUser(NewUrl)
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And Not Name.IsEmptyString And NameTrue.IsEmptyString) Then
If Not If(Force, eObj.Options, Options).IsEmptyString Then
If IsUser And Force Then
If (IsUser Or SiteMode = SiteModes.Playlists) And Force Then
Return False
Else
_IsUser = False
SiteMode = SiteModes.Search
Options = If(Force, eObj.Options, Options)
NameTrue = Options
If Options.ToLower.StartsWith(PersonTypePlaylist) Then
SiteMode = SiteModes.Playlists
NameTrue = Options.ToLower.Replace(PersonTypePlaylist, String.Empty).StringTrim.TrimStart("/")
Else
NameTrue = Options
End If
If Not Force Then
Settings.Labels.Add(SearchRequestLabelName)
Labels.ListAddValue(SearchRequestLabelName, LNC)
Dim l$ = IIf(SiteMode = SiteModes.Playlists, PlaylistsLabelName, SearchRequestLabelName)
Settings.Labels.Add(l)
Labels.ListAddValue(l, LNC)
Labels.Sort()
Return True
End If
End If
Else
_IsUser = True
SiteMode = SiteModes.User
Dim n$() = Name.Split("_")
If n.ListExists(2) Then
NameTrue = Name.Replace($"{n(0)}_", String.Empty)
@@ -247,7 +254,14 @@ Namespace API.PornHub
DownloadFavorite = .Value(Name_DownloadFavorite).FromXML(Of Boolean)(False)
DownloadGifs = .Value(Name_DownloadGifs).FromXML(Of Integer)(False)
DownloadPhotoOnlyFromModelHub = .Value(Name_DownloadPhotoOnlyFromModelHub).FromXML(Of Boolean)(True)
_IsUser = .Value(Name_IsUser).FromXML(Of Boolean)(True)
If .Contains(Name_SiteMode) Then
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
Else
'TODELETE: PornHub 'IsUser' 20231113
#Disable Warning BC40008
SiteMode = IIf(.Value(Name_IsUser).FromXML(Of Boolean)(True), SiteModes.User, SiteModes.Search)
#Enable Warning
End If
UpdateUserOptions()
Else
If UpdateUserOptions() Then .Value(Name_LabelsName) = LabelsString
@@ -261,7 +275,7 @@ Namespace API.PornHub
.Add(Name_DownloadFavorite, DownloadFavorite.BoolToInteger)
.Add(Name_DownloadGifs, DownloadGifs.BoolToInteger)
.Add(Name_DownloadPhotoOnlyFromModelHub, DownloadPhotoOnlyFromModelHub.BoolToInteger)
.Add(Name_IsUser, IsUser.BoolToInteger)
.Add(Name_SiteMode, CInt(SiteMode))
'Debug.WriteLine(GetNonUserUrl(0))
'Debug.WriteLine(GetNonUserUrl(2))
@@ -271,9 +285,16 @@ Namespace API.PornHub
#End Region
#Region "Downloading"
#Region "Download override"
Private Const PlayListUrlPattern As String = "https://www.pornhub.com/playlist/viewChunked?id={0}&token={1}&page={2}"
Private PlaylistToken As String = String.Empty
Private ReadOnly SessionPosts As List(Of String)
Private _PageVideosRepeat As Integer = 0
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
Try
PlaylistToken = String.Empty
Responser.ResetStatus()
_PageVideosRepeat = 0
SessionPosts.Clear()
If IsSavedPosts Then
PersonType = PersonTypeUser
@@ -283,28 +304,32 @@ Namespace API.PornHub
Dim limit% = If(DownloadTopCount, -1)
If DownloadVideos Then
If IsSavedPosts Or Not IsUser Or PersonType = PersonTypeUser Then
If SiteMode = SiteModes.Playlists Then
Responser.Mode = Responser.Modes.Default
GetPlaylistToken(Token)
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
ElseIf IsSavedPosts Or Not IsUser Or PersonType = PersonTypeUser Then
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
Else
If DownloadUploaded Then
LastPageIDs.Clear()
SessionPosts.Clear()
DownloadUserVideos(1, VideoTypes.Uploaded, False, Token)
End If
If DownloadTagged Then
LastPageIDs.Clear()
SessionPosts.Clear()
Dim lBefore% = _TempMediaList.Count
DownloadUserVideos(1, VideoTypes.Tagged, False, Token)
If PersonType = PersonTypePornstar And lBefore = _TempMediaList.Count Then
LastPageIDs.Clear()
SessionPosts.Clear()
DownloadUserVideos(1, VideoTypes.Tagged, True, Token)
End If
End If
If DownloadPrivate Then
LastPageIDs.Clear()
SessionPosts.Clear()
DownloadUserVideos(1, VideoTypes.Private, False, Token)
End If
If DownloadFavorite Then
LastPageIDs.Clear()
SessionPosts.Clear()
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
End If
End If
@@ -348,6 +373,7 @@ Namespace API.PornHub
Dim specFolder$ = String.Empty
Dim tryNextPage As Boolean = False
Dim limit% = If(DownloadTopCount, -1)
Dim cBefore% = _TempMediaList.Count
If IsUser Then
URL = $"https://www.pornhub.com/{PersonType}/{NameTrue}"
If Type = VideoTypes.Uploaded Then
@@ -365,6 +391,9 @@ Namespace API.PornHub
Throw New ArgumentException($"Type '{Type}' is not implemented in the video download function", "Type")
End If
If Page > 1 Then URL &= $"?page={Page}"
ElseIf SiteMode = SiteModes.Playlists Then
If PlaylistToken.IsEmptyString Then Throw New ArgumentNullException("PlaylistToken", "Unable to get 'PlaylistToken'")
URL = String.Format(PlayListUrlPattern, NameTrue, PlaylistToken, Page)
Else
URL = GetNonUserUrl(Page)
End If
@@ -375,7 +404,7 @@ Namespace API.PornHub
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexUserVideos}, {6, 7, 3, 10})
If l.ListExists Then l = l.ListTake(3, l.Count).ToList
If l.ListExists And Not SiteMode = SiteModes.Playlists Then l = l.ListTake(3, l.Count).ToList
If l.ListExists Then
If IsUser Then
If Type = VideoTypes.Favorite Then
@@ -389,23 +418,37 @@ Namespace API.PornHub
Dim lBefore% = l.Count
Dim nonLastPageDetected As Boolean = False
Dim newLastPageIDs As New List(Of String)
Dim pageRepeatSet As Boolean = False, prevPostsFound As Boolean = False, newPostsFound As Boolean = False
l.RemoveAll(Function(ByVal uv As UserVideo) As Boolean
newLastPageIDs.Add(uv.ID)
If Not _TempPostsList.Contains(uv.ID) Then
_TempPostsList.Add(uv.ID)
newLastPageIDs.Add(uv.ID)
Return False
ElseIf SessionPosts.Count > 0 AndAlso SessionPosts.Contains(uv.id) Then
prevPostsFound = True
If pageRepeatSet Then pageRepeatSet = False : _PageVideosRepeat -= 1
Return True
Else
If Not LastPageIDs.Contains(uv.ID) Then nonLastPageDetected = True
'TODELETE: PornHub old validating
'If Not SessionPosts.Contains(uv.ID) Then nonLastPageDetected = True
If Not pageRepeatSet And Not newPostsFound Then pageRepeatSet = True : _PageVideosRepeat += 1
'Debug.WriteLine($"[REMOVED]: {uv.Title}")
Return True
End If
End Function)
'Debug.WriteLineIf(l.Count > 0, l.Select(Function(ll) ll.Title).ListToString(vbNewLine))
If l.Count > 0 Then _TempMediaList.ListAddList(l.Select(Function(uv) uv.ToUserMedia(specFolder)))
LastPageIDs.Clear()
If newLastPageIDs.Count > 0 Then LastPageIDs.AddRange(newLastPageIDs) : newLastPageIDs.Clear()
If l.Count > 0 AndAlso (l.Count = lBefore Or Not nonLastPageDetected) AndAlso
Not (limit > 0 And _TempMediaList.Count >= limit) Then tryNextPage = True
SessionPosts.ListAddList(newLastPageIDs, LNC)
newLastPageIDs.Clear()
'TODELETE: PornHub old validating
'If l.Count > 0 AndAlso (l.Count = lBefore Or Not nonLastPageDetected) AndAlso
' Not (limit > 0 And _TempMediaList.Count >= limit) Then tryNextPage = True
If limit > 0 And _TempMediaList.Count >= limit Then Exit Sub
If (Not IsUser And prevPostsFound And Not newPostsFound And Page < 1000) Or
(Not cBefore = _TempMediaList.Count And (IsUser Or Page < 1000)) Then tryNextPage = True
l.Clear()
End If
End If
End If
@@ -419,6 +462,15 @@ Namespace API.PornHub
ProgressPre.Perform()
End Try
End Sub
Private Sub GetPlaylistToken(ByVal Token As CancellationToken)
Dim URL$ = GetNonUserUrl(0)
Try
Dim r$ = Responser.GetResponse(URL)
If Not r.IsEmptyString Then PlaylistToken = RegexReplace(r, RegexDataToken)
Catch ex As Exception
ProcessException(ex, Token, $"token getting error [{URL}]")
End Try
End Sub
#End Region
#Region "Download GIF"
Private Sub DownloadUserGifs(ByVal Token As CancellationToken)
@@ -931,7 +983,7 @@ Namespace API.PornHub
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then LastPageIDs.Clear()
If Not disposedValue And disposing Then SessionPosts.Clear()
MyBase.Dispose(disposing)
End Sub
#End Region

View File

@@ -18,7 +18,7 @@ Imports Period = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit
Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel),
IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IRedditView, IDisposable
#Region "XML Nodes' Names"
#Region "XML Names"
Private Const Name_Name As String = "Name"
Private Const Name_ID As String = "ID"
Private Const Name_Date As String = "Date"
@@ -88,10 +88,14 @@ Namespace API.Reddit
End Property
Friend Property ViewMode As View = View.New Implements IRedditView.ViewMode
Friend Property ViewPeriod As Period = Period.All Implements IRedditView.ViewPeriod
Friend Property RedGifsAccount As String = String.Empty Implements IRedditView.RedGifsAccount
Friend Property RedditAccount As String = String.Empty Implements IRedditView.RedditAccount
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
RedditAccount = Options.RedditAccount
RedGifsAccount = Options.RedGifsAccount
End If
End Sub
#Region "Statistics support"
@@ -215,7 +219,17 @@ Namespace API.Reddit
End Sub
Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits
#End Region
Private _HOST As SettingsHost
Friend ReadOnly Property HOST As SettingsHost
Get
_HOST = Settings(RedditSiteKey, RedditAccount)
If _HOST Is Nothing Then
MyMainLOG = $"Reddit account '{RedditAccount}' for channel '{Name}' not found in the accounts. The default account will be used."
_HOST = Settings(RedditSiteKey).Default
End If
Return _HOST
End Get
End Property
Friend Sub New()
Posts = New List(Of UserPost)
PostsLatest = New List(Of UserPost)
@@ -223,7 +237,6 @@ Namespace API.Reddit
CountOfAddedUsers = New List(Of Integer)
CountOfLoadedPostsPerSession = New List(Of Integer)
ChannelExistentUserNames = New List(Of String)
HOST = Settings(RedditSiteKey)
End Sub
Friend Sub New(ByVal f As SFile)
Me.New
@@ -350,6 +363,8 @@ Namespace API.Reddit
ID = x.Value(Name_ID)
ViewMode = x.Value(Name_ViewMode).FromXML(Of Integer)(CInt(View.[New]))
ViewPeriod = x.Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(Period.All))
RedGifsAccount = x.Value(Name_RedGifsAccount)
RedditAccount = x.Value(Name_RedditAccount)
If FilePosts.Exists Then PostsNames.ListAddList(FilePosts.GetText.StringToList(Of String)("|"), LNC)
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), DateTimeDefaultProvider, Nothing)
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc)
@@ -388,6 +403,8 @@ Namespace API.Reddit
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString("|"))
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString("|"))
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString("|"))
x.Add(Name_RedGifsAccount, RedGifsAccount)
x.Add(Name_RedditAccount, RedditAccount)
If Posts.Count > 0 Or PostsLatest.Count > 0 Then
Dim tmpPostList As List(Of UserPost) = Nothing
tmpPostList.ListAddList(Posts).ListAddList(PostsLatest)

View File

@@ -23,17 +23,25 @@ Namespace API.Reddit
End Enum
Property ViewMode As View
Property ViewPeriod As Period
Property RedGifsAccount As String
Property RedditAccount As String
Sub SetView(ByVal Options As IRedditView)
End Interface
Friend Class RedditViewExchange : Implements IRedditView
Friend Const Name_ViewMode As String = "ViewMode"
Friend Const Name_ViewPeriod As String = "ViewPeriod"
Friend Const Name_RedGifsAccount As String = "RedGifsAccount"
Friend Const Name_RedditAccount As String = "RedditAccount"
Friend Property ViewMode As IRedditView.View Implements IRedditView.ViewMode
Friend Property ViewPeriod As IRedditView.Period Implements IRedditView.ViewPeriod
Friend Property RedGifsAccount As String Implements IRedditView.RedGifsAccount
Friend Property RedditAccount As String Implements IRedditView.RedditAccount
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
RedGifsAccount = Options.RedGifsAccount
RedditAccount = Options.RedditAccount
End If
End Sub
End Class

View File

@@ -23,10 +23,13 @@ Namespace API.Reddit
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim TP_VIEW_MODE As System.Windows.Forms.TableLayoutPanel
Dim LBL_VIEW_MODE As System.Windows.Forms.Label
Dim LBL_PERIOD As System.Windows.Forms.Label
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(RedditViewSettingsForm))
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.OPT_VIEW_MODE_NEW = New System.Windows.Forms.RadioButton()
Me.OPT_VIEW_MODE_HOT = New System.Windows.Forms.RadioButton()
Me.OPT_VIEW_MODE_TOP = New System.Windows.Forms.RadioButton()
@@ -37,16 +40,19 @@ Namespace API.Reddit
Me.OPT_PERIOD_WEEK = New System.Windows.Forms.RadioButton()
Me.OPT_PERIOD_MONTH = New System.Windows.Forms.RadioButton()
Me.OPT_PERIOD_YEAR = New System.Windows.Forms.RadioButton()
Me.CMB_REDGIFS_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.CMB_REDDIT_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_VIEW_MODE = New System.Windows.Forms.TableLayoutPanel()
LBL_VIEW_MODE = New System.Windows.Forms.Label()
LBL_PERIOD = New System.Windows.Forms.Label()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
TP_MAIN.SuspendLayout()
Me.TP_MAIN.SuspendLayout()
TP_VIEW_MODE.SuspendLayout()
Me.TP_PERIOD.SuspendLayout()
CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'CONTAINER_MAIN
@@ -54,34 +60,37 @@ Namespace API.Reddit
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 87)
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 169)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
CONTAINER_MAIN.RightToolStripPanelVisible = False
CONTAINER_MAIN.Size = New System.Drawing.Size(477, 112)
CONTAINER_MAIN.Size = New System.Drawing.Size(477, 169)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'TP_MAIN
'
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(TP_VIEW_MODE, 0, 0)
TP_MAIN.Controls.Add(Me.TP_PERIOD, 0, 1)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Size = New System.Drawing.Size(477, 87)
TP_MAIN.TabIndex = 0
Me.TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
Me.TP_MAIN.ColumnCount = 1
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_MAIN.Controls.Add(TP_VIEW_MODE, 0, 0)
Me.TP_MAIN.Controls.Add(Me.TP_PERIOD, 0, 1)
Me.TP_MAIN.Controls.Add(Me.CMB_REDGIFS_ACC, 0, 3)
Me.TP_MAIN.Controls.Add(Me.CMB_REDDIT_ACC, 0, 2)
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TP_MAIN.Name = "TP_MAIN"
Me.TP_MAIN.RowCount = 5
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
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(477, 169)
Me.TP_MAIN.TabIndex = 0
'
'TP_VIEW_MODE
'
@@ -258,19 +267,55 @@ Namespace API.Reddit
Me.OPT_PERIOD_YEAR.Text = "Year"
Me.OPT_PERIOD_YEAR.UseVisualStyleBackColor = True
'
'CMB_REDGIFS_ACC
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "ArrowDown"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_REDGIFS_ACC.Buttons.Add(ActionButton1)
Me.CMB_REDGIFS_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.CMB_REDGIFS_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent
Me.CMB_REDGIFS_ACC.CaptionText = "RedGifs account"
Me.CMB_REDGIFS_ACC.CaptionVisible = True
Me.CMB_REDGIFS_ACC.CaptionWidth = 26.0R
Me.CMB_REDGIFS_ACC.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_REDGIFS_ACC.Location = New System.Drawing.Point(4, 119)
Me.CMB_REDGIFS_ACC.Name = "CMB_REDGIFS_ACC"
Me.CMB_REDGIFS_ACC.Size = New System.Drawing.Size(469, 22)
Me.CMB_REDGIFS_ACC.TabIndex = 4
Me.CMB_REDGIFS_ACC.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'CMB_REDDIT_ACC
'
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "ArrowDown"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_REDDIT_ACC.Buttons.Add(ActionButton2)
Me.CMB_REDDIT_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.CMB_REDDIT_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent
Me.CMB_REDDIT_ACC.CaptionText = "Reddit account"
Me.CMB_REDDIT_ACC.CaptionVisible = True
Me.CMB_REDDIT_ACC.CaptionWidth = 26.0R
Me.CMB_REDDIT_ACC.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_REDDIT_ACC.Location = New System.Drawing.Point(4, 90)
Me.CMB_REDDIT_ACC.Name = "CMB_REDDIT_ACC"
Me.CMB_REDDIT_ACC.Size = New System.Drawing.Size(469, 22)
Me.CMB_REDDIT_ACC.TabIndex = 3
Me.CMB_REDDIT_ACC.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'RedditViewSettingsForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(477, 112)
Me.ClientSize = New System.Drawing.Size(477, 169)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.SiteResources.RedditIcon_128
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(493, 151)
Me.MaximumSize = New System.Drawing.Size(493, 208)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(493, 151)
Me.MinimumSize = New System.Drawing.Size(493, 208)
Me.Name = "RedditViewSettingsForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
@@ -278,11 +323,13 @@ Namespace API.Reddit
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
Me.TP_MAIN.ResumeLayout(False)
TP_VIEW_MODE.ResumeLayout(False)
TP_VIEW_MODE.PerformLayout()
Me.TP_PERIOD.ResumeLayout(False)
Me.TP_PERIOD.PerformLayout()
CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
@@ -296,5 +343,8 @@ Namespace API.Reddit
Private WithEvents OPT_PERIOD_MONTH As RadioButton
Private WithEvents OPT_PERIOD_YEAR As RadioButton
Private WithEvents TP_PERIOD As TableLayoutPanel
Private WithEvents CMB_REDGIFS_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents CMB_REDDIT_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents TP_MAIN As TableLayoutPanel
End Class
End Namespace

View File

@@ -120,9 +120,6 @@
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_VIEW_MODE.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
@@ -132,4 +129,185 @@
<metadata name="LBL_PERIOD.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMK3O3r79wVUIz65jfGNVxI/VIX69CvGO9M//a9P+e8o3B/8v
vKn9s+3fyX8dAJgmaWd+fl3E96Wd/E9XdvZHkfbvXNa+Rn45AGCS3bvjj/E/h3box5OrmxjPyy8PAEyS
XXO7zqhCeH/HDnwUOdCE+J6zdux4eH47YIrEGE8uy/Ls9Bnx/LooL0oH9b9Th/I1TVG+rCqKC+q6Xsh/
FJgmO8vy6WknfdPQTnsjckMdwlPy2wITLO3wF6si/lGas1ekuXvX0Fzuyg9S3psOCl6qDwimQB3ji9Ok
3btmEm907kpnEa/Mbw9Mlq1pB/6cdHZ/ZcfcPZrcXoXyrVVVFfl1gUmSdsS/libqPUMTd5NSvjktwrbB
kgDjVi1UT26K+Nnu+XrMuaud60uPWHpIfhtg3JqyfEaanHcPTdZNTRPCPy4uLj40LxIwBudt2fKAtOP/
0zQnN+5koIg3tpca81sC49J+LZcm5a3rJulYEq6LSV40YBOFEB6V5uFV6+flRiTsSwf9r81vDYzBCSO4
vjfq/KAuiqfm5QM2QRPjuWnubUbz71DCn6W33zpYCmDT1EX5m92Tcuy5q47xFXkxgQ3UduqnOXfn0Bzc
xJSvz4sCbIb2pzlp8v1w/WScnKSzkjekRT1hsMTAKC0vL5/Ydud3zb1NT1FelBcL2GiDm3d0TMTJy0ea
pjk1LzYwAu3NvtLc+uTQXBtn7tYYCJtja/vQno5JOJFpQrzWb4hhNJoQnpjm1Q3D82wCcnNRFKfnxQQ2
Qttk1zH5JjzhFmcIcHzyzb6O5aFem5J0sP/OvKjARmg7b7sm3xRkT3vDorwawJHb1t6Ep2NOTVoOtDch
yssMjFr6IPh8x8SbnsT4lrQamgPhCMzPzz+sifHjnXNpMnN5XnRglJaWlk5KE2z/0ISbxnzQQ0bgvlXz
1ePSXPnG0NyZ+DRF8Zi8CsCo7Azh0V0TbkrzRc2B0G3wIJ9429CcmZLce4MgYJTyff87JtzU5uayLM/J
qwcM7vD5+jQ3DgzNlWnKDXldgFFJZwW/2jHZpj1727uZ5VWE3mofqJXmw4eG5sdUpqqqXXm1gFGoQnhJ
12SbgRxoYvzjtIruK04vxRjPSvPgK0PzYmqTPqtemVcNGIU6xgu7JtusJH1ovH9ubu6UvLrQC2ncPyuN
/58Mz4fpTvnmvHrAKJQL5dO6J9ssJXxucWFhLq8yzLKtaUf5h2ncb9zz+8eUKsYP53UERmHX/PyOrsk2
g7nJDUWYZUuPWHpIE8oPdIz92UiMn86rCoxIOmOYta8KD5uftk2Peb1hZtTzdVOHcF3HmJ+ZVCF+Ia8u
MCppcl0+PNlmOG1zYPtYYc2BzIQ0np+ZxvWPh8b5LObqvMrAqEzRo4BHmctijCfnEsBUqkP5u2ksz8Kd
PI8g5SfyagOj0jbIpQk2c01DR5Brmh3NfC4DTI324LWO8V0dY3pm48mAsEGm7OEgo0sRb9wZ4+NzGWDi
lWUZ0ti9Zt1YnvUU8fdyCYBRmsFbAh9xqhDvqEN4Xi4FTKz8s93vD4/hPiSdpJyXywCMWPtrgKuGJ12P
ck/6gPmDXAuYOHVR/lY6UN3XMXb7kDv17MAGqhaqJ6WJ1sdegDUJ726a5oG5JDB2917vL+Kl3eO1N/lQ
LgewUdIO8E0dk69vubosy+25JDA2bYNuFeJnOsZovxLjhbkkwEZZXl4+0QfOvfl2Ogg4O5cFNl1dFE9N
4/B7Q+Oyj7mh/VzKZQE2UtM0j6iL+LWOidizhN3OPBiHuigvSmPwrvVjsn9pQnh1LguwGQa3Fo3fHp6M
Pcw97c1WcllgQy0tLZ2UDr7/qmMc9jJNiF/WkwNjMHhQ0GzfX/yIU8RLfRCxkdq+kzTfrugcf/3MgZ1l
+fRcHmCztU8Yq2P8h47J2cdcpTmQjdCE8IQ0vnzjdkjKP8nlAcZoWxXin3dP0n4l1eGb9UL92FwXOG51
Ub48ja09w2Otz2nvTJpKs21QIWDs0lnKb6TJqTEphN3NQvncXBY4VtvSju4N3WOs17l6cXHxoblGwKRo
r8mlHeAtHZO2b9mfDohem8sCR2XX3K4z0hj65NCYklSTGONpuUzApNlVFFWaqP81NHF7mvD2tnM7lwbu
V/vwqTR2vrV+LPU7VSjf4ff+MAU0B65NeWVd12fm0sBhpTnzosHDp7rGUV8T9lVFvDiXCJgSrmEezDea
onhMrgsM25rmyuvSODkwNG56nvZyYvi5XCNg2mgOXM3tVVH9ci4L3KtpmlN9W7Y+VYhfiEkuEzCt8n3L
fzA8yXuY/b7OZEVZlovt3ew6xknf8965ublTcpmAaac5cG3C2zQ09Vv7bVAaC/+7fmz0Og6QYVZpDlyT
GD/dPlgpl4b+2Nru5NIYuGfdmOhxmhB/VBblL+QaATNKc+DBfH1nCI/OdWHGtTewSdv874fGgIT4xfYb
wlwmYNZpDlzNbVUIz85lYUblJ2i6BDacGP/u7O3bH5zLBPSF5sDV7K+L+Nu5LMyYtJP7xbSNfzy0zfue
A+03gak8WwdVAnpHc+CaxHiJ5sCZsnK9f/+6bd3v3JZ2/r+SawT0mebAg0kfjB93v/Pp136t3X693bWN
e56v6nsBhmkOXE24Ph0EnJXrwpSp63qhDuXnu7dtn1P+U1VVP5PLBHAozYGDtD+LchvU6TN4Iqa+lqGs
XO8/YVAlgMPQHLiSsC+dNb0ml4UJVxflRWm73b1+O/Y5YXcVwvNziQDun+bANYnxkvO2bHlALg0TJsZ4
cl3ESzu3Xa8Trm+KYimXCeDIaQ48mKqIH9McOHl2zc/vaIr42a5t1vN8tCiK03OZAI6J5sCVFPFr7QNk
cl0Ys3yp6nvrtlO/s3K9f9ugSgDHSXPgILk58PxcFsYkX+93J8s1qUK8oynKF+YSAYyO5sCVhH3pgOjV
uSxsoqZpHpjq//bu7dLjFPHGND+Xc5kARk9z4JrE+JZUEl+1bpLFhYW5VPf/WLcd5N/ruj4zlwlg42gO
PCQfdXOVjdeE8MRU6xuGai9uXw2MgebA1YTrFkMoc10YsaYoX5rqfOf6uvc6e9LO/xW5RACbT3Pgam5N
B0Q/m8vCCLT3XnCQ2ZXwnWqhenIuE8D4aA5czV3OykZj19yuM1I9PzlUXwnhirIst+cyAYyf5sA1GTQH
uu/6MdoZ4+NTHb+1rq59j+v9wKTSHHhIPtI0zam5NByhNH5enGr306Fa9j1720ttuUQAE0tz4Epi/FJM
cl24b8ZNd25KdTk31whg8mkOXEm4pX1EbS4LHebn5x+WdnIf765fr3NVCOFRuUwA00Nz4Gr21kX58lwW
1qjmq8el+nxjqF4S4yVLS0sn5TIBTB/NgWuiOfAQTVE+J9XltnV16nXCvqqIF+cSAUw3zYGH5INnb9/+
4Fyavtra7uRSLe4Zqk3f88MmxvNyjQBmhiavg/liVVVFrkuvLC4uPjSt/4eG6iEhXlOWZchlApg9mgNX
c3P6wD8nl6UXqvlqZ1rv/xmqQ+/ThPJv5ufnH5TLBDC7NAeuZm97n/tclplWhfCstL4/GVr/nsf1fqCH
NAeu5kB7aSSVZFabA13v786tVVFckGsE0C+aAw8mnSG/f25u7pRcmpnQbt8mlB/oWt8+pwnxWk+PBNAc
uJoqxC/MSnNgs7BQ1yFc17WePc97Z+1AD+C4aA5czU3T/qjXdED3zLQePx5ar75nf77ev3VQJQBWaQ5c
zZ4qhJfkskyVuigvapvbOtapt2lC/FFTls/IJQKgi+bA1aw0B07FGWOM8eQ6xnd1rEe/E+OX2jGdywTA
fdEcuCYx/u2kXzNudjTz6az/c53L3+NUMX7YI6EBjp7mwIO5pt3J5rpMlHKhfFpavu8PLW/fM+s/7QTY
eJoDV/PduiiWc1kmwuB6f7x7aDn7ntvrGC/MJQLgeGgOHKQK8Y46hOflsoxN0zQPbEJ8Z9cy9jxf3RnC
o3OZABgFzYGrab9efl0qyViaAxcXFubSgchnOpar77k8xnhaLhMAo6Q5cE2K+L7NfoBMHcJT0nvfvG5Z
+h3X+wE2iebAg7m6LMvtuS4bKl/v14txSMLuKoQX5BIBsBk0B64kfCfV4om5LCN33pYtD3DA1ZVwfb1Q
PzaXCYDNpDlwJWH3RnSe75rbdUZ6/X9b/369z0eLojg9lwmAcdAcuJqV5sCRaEJ4QnrNbw+9R9+zcr1/
26BKAIyV5sBDcll7W95cmmPSPocgvc6dQ6/b9+xpivJluUQATBDNgQdz1TE2B6phV4p446TdhAmAIens
9ZXpQ1tz4KA58Am5LPfrrB07Hp7+zr90v1Z/UxXxU3Vdn5nLBMAk0xy4krC7WSifm8tyWGVZnl2F+M3u
1+hxYrxkeXn5xFwmAKaB5sDV7E9nsRfnsqyTdnIvGtxiuPPv9jV7Ul1ekUsEwLTRHHgwVSjfsbS0dFIu
TWtr+6uB9P8ODP/Znue7ZVmek2sEwBTT2Laa8sr2enb7jHoHRl0JV8QYH5nHDQCzwJ0DV/P1tKO7vuO/
9zpVKN/qej/AjNIcKB3Z24TyVXmIADCrNAfKmtzUxHhuHhoAzDrNgZJyVQjhUXlIANAjmgN7m/Du471d
MgBTzp0D+5Sw777uiQBAz2gO7EPCLSnn500OAAOaA2c615RlGfKmBoBDaQ6cvTQhvmd+fv5BeRMDwGFp
DpyJuN4PwDHQHDjVubUqigvypgSAo6M5cPrShHjtYghl3oQAcGw0B05Rivi+ubm5U/KmA4Djozlw4rM/
X+/fOthiADA6mgMnME2IP2rK8hl5GwHAxtAcOFH5SozxrLxpAGBjaQ4cf6oYP9w0zal5kwDA5tAcOLYc
aC/FpE1wwmBLAMAm0xy46bk91fvCXH4AGCvNgZuRIn6tKYrH5JoDwGTQHLihuTzGeFouNQBMFs2BI4/r
/QBMB82Bo0rYXYXwglxWAJh8mgOPN+H6eqF+bC4nAEwVzYHHkiL+c1EUp+caAsB00hx4FInxLalk2waV
A4AppznwfrOnLsqX53IBwOzQHHiYFPHGaqF6Ui4TAMwezYGHpirip+q6PjOXBwBmmubANjFesry8fGKu
CQD0Q4+bA/dWMf56LgMA9E8PmwO/W5blOXn1AaC/+tMcWF4ZY3xkXm0AYOabA2O8ZGlp6aS8ugDAGrPY
HLi3CeWr8voBAIczQ82BN6UDmnPzagEA92f6mwPLz1dVVeTVAQCO1LQ2B1Yh/PX8/PyD8moAAEdrupoD
w76qiBfnRQcAjtMUNAeGW1LOz8sLAIzKBDcHXlOWZciLCQCM2gQ2B142Nzd3Sl48AGCjTEhz4H7X+wFg
k425OfDWqqh+Pi8KALDJtqWDgDemHfKBoR30hqUJ8dqY5PcHAMalKcrnpJ3z94Z31qNO+/t+1/sBYIKk
k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
AAAASUVORK5CYII=
</value>
</data>
</root>

View File

@@ -6,16 +6,21 @@
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports SCrawler.Plugin.Hosts
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base
Imports CView = SCrawler.API.Reddit.IRedditView.View
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit
Friend Class RedditViewSettingsForm
Private WithEvents MyDefs As DefaultFormOptions
Private ReadOnly Property MyOptions As IRedditView
Friend Sub New(ByRef opt As IRedditView)
Private ReadOnly Property IsUserSettings As Boolean
Friend Sub New(ByRef opt As IRedditView, ByVal _IsUserSettings As Boolean)
InitializeComponent()
MyOptions = opt
IsUserSettings = _IsUserSettings
MyDefs = New DefaultFormOptions(Me, Settings.Design)
End Sub
Private Sub RedditViewSettingsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
@@ -44,12 +49,52 @@ Namespace API.Reddit
Case Else : OPT_PERIOD_ALL.Checked = True
End Select
ChangePeriodEnabled()
PopulateCMB(Settings(RedditSiteKey), CMB_REDDIT_ACC, MyOptions.RedditAccount)
PopulateCMB(Settings(RedGifs.RedGifsSiteKey), CMB_REDGIFS_ACC, MyOptions.RedGifsAccount)
If IsUserSettings Then
TP_MAIN.Controls.Remove(CMB_REDDIT_ACC)
TP_MAIN.RowStyles(2).Height = 0
TP_MAIN.Refresh()
Dim s As Size = Size
s.Height -= 28
MaximumSize = Nothing
MinimumSize = Nothing
Size = s
MinimumSize = s
MaximumSize = s
Refresh()
End If
.EndLoaderOperations()
End With
Catch ex As Exception
MyDefs.InvokeLoaderError(ex)
End Try
End Sub
Private Sub PopulateCMB(ByVal Plugin As SettingsHostCollection, ByRef CMB As ComboBoxExtended, ByVal Acc As String)
With CMB
Dim indx% = 0
.BeginUpdate()
If Plugin.Count = 1 Then
.Text = SettingsHost.NameAccountNameDefault
.LeaveDefaultButtons = False
.Buttons.Clear()
.Buttons.UpdateButtonsPositions(True)
.CaptionWidth -= 1
Else
Dim data As List(Of String) = Plugin.Select(Function(h) h.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).ToList
If Not Acc.IsEmptyString Then
indx = data.IndexOf(Acc)
If indx = -1 Then indx = 0
End If
.Items.AddRange(data.Select(Function(d) New ListItem(d)))
End If
.EndUpdate(True)
If .Count > 0 Then .SelectedIndex = indx
.Enabled = .Count > 1
End With
End Sub
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
With MyOptions
Select Case True
@@ -65,6 +110,8 @@ Namespace API.Reddit
Case OPT_PERIOD_YEAR.Checked : .ViewPeriod = CPeriod.Year
Case Else : .ViewPeriod = CPeriod.All
End Select
.RedGifsAccount = CMB_REDGIFS_ACC.Text
If Not IsUserSettings Then .RedditAccount = CMB_REDDIT_ACC.Text
End With
MyDefs.CloseForm()
End Sub

View File

@@ -18,27 +18,15 @@ Imports Download = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Reddit
<Manifest(RedditSiteKey), SavedPosts, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Icons"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.RedditIcon_128
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.RedditPic_512
End Get
End Property
#End Region
#Region "Declarations"
#Region "Authorization"
<PropertyOption(ControlText:="Login", ControlToolTip:="Your authorization username", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Login", ControlToolTip:="Your authorization username", IsAuth:=True), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property AuthUserName As PropertyValue
<PropertyOption(ControlText:="Password", ControlToolTip:="Your authorization password", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Password", ControlToolTip:="Your authorization password", IsAuth:=True), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property AuthPassword As PropertyValue
<PropertyOption(ControlText:="Client ID", ControlToolTip:="Your registered app client ID", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Client ID", ControlToolTip:="Your registered app client ID", IsAuth:=True), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property ApiClientID As PropertyValue
<PropertyOption(ControlText:="Client Secret", ControlToolTip:="Your registered app client secret", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Client Secret", ControlToolTip:="Your registered app client secret", IsAuth:=True), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property ApiClientSecret As PropertyValue
<PropertyOption(ControlText:="Bearer token",
ControlToolTip:="Bearer token (can be null)." & vbCr &
@@ -48,29 +36,29 @@ Namespace API.Reddit
Friend ReadOnly Property BearerToken As PropertyValue
#Region "TokenUpdateInterval"
<PropertyOption(ControlText:="Token refresh interval", ControlToolTip:="Interval (in minutes) to refresh the token",
AllowNull:=False, LeftOffset:=120, IsAuth:=True), PXML>
AllowNull:=False, LeftOffset:=120, IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property TokenUpdateInterval As PropertyValue
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
#End Region
<PXML> Private ReadOnly Property BearerTokenDateUpdate As PropertyValue
<PropertyOption(ControlText:="Use the token to download the timeline", IsAuth:=True), PXML>
<PXML, PClonable> Private ReadOnly Property BearerTokenDateUpdate As PropertyValue
<PropertyOption(ControlText:="Use the token to download the timeline", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property UseTokenForTimelines As PropertyValue
<PropertyOption(ControlText:="Use the token to download saved posts", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Use the token to download saved posts", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property UseTokenForSavedPosts As PropertyValue
<PropertyOption(ControlText:="Use cookies to download the timeline", IsAuth:=True), PXML>
<PropertyOption(ControlText:="Use cookies to download the timeline", IsAuth:=True), PXML, PClonable>
Friend ReadOnly Property UseCookiesForTimelines As PropertyValue
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip, IsAuth:=True), PXML>
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip, IsAuth:=True), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Other"
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos", IsAuth:=False), PXML>
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos", IsAuth:=False), PXML, PClonable>
Friend ReadOnly Property UseM3U8 As PropertyValue
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New(RedditSite, "reddit.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New(RedditSite, "reddit.com", AccName, Temp, My.Resources.SiteResources.RedditIcon_128, My.Resources.SiteResources.RedditPic_512)
Dim token$
With Responser
@@ -144,6 +132,7 @@ Namespace API.Reddit
End Function
Private Function AvailableImpl(ByVal What As Download, ByVal Silent As Boolean) As Boolean
Try
AvailableText = String.Empty
Dim trueValue As Boolean = Not What = Download.SavedPosts OrElse (Responser.CookiesExists And ACheck(SavedPostsUserName.Value))
If Not trueValue Then Return False
Dim dl As List(Of DownDetector.Data) = DownDetector.GetData("reddit")
@@ -151,13 +140,13 @@ Namespace API.Reddit
dl = dl.Take(4).ToList
Dim avg% = dl.Average(Function(d) d.Value)
If avg > 100 Then
AvailableText = "Over the past hour, Reddit has received an average of " &
avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr &
dl.ListToString(vbCr)
If Silent Then
Return False
Else
If MsgBoxE({"Over the past hour, Reddit has received an average of " &
avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr &
dl.ListToString(vbCr) & vbCr & vbCr &
"Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes Then
If MsgBoxE({$"{AvailableText}{vbCr}{vbCr}Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes Then
If trueValue Then UpdateRedGifsToken()
Return trueValue AndAlso UpdateTokenIfRequired()
Else
@@ -182,7 +171,7 @@ Namespace API.Reddit
MyBase.DownloadDone(What)
End Sub
Private Sub UpdateRedGifsToken()
DirectCast(Settings(RedGifs.RedGifsSiteKey).Source, RedGifs.SiteSettings).UpdateTokenIfRequired()
Settings(RedGifs.RedGifsSiteKey).ListForEach(Sub(h, i) DirectCast(h.Source, RedGifs.SiteSettings).UpdateTokenIfRequired())
End Sub
#End Region
#Region "IsMyUser, GetUserUrl, GetUserPostUrl"
@@ -212,7 +201,7 @@ Namespace API.Reddit
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is RedditViewExchange Then Options = New RedditViewExchange
If OpenForm Then
Using f As New RedditViewSettingsForm(Options) : f.ShowDialog() : End Using
Using f As New RedditViewSettingsForm(Options, True) : f.ShowDialog() : End Using
End If
End Sub
#End Region

View File

@@ -23,9 +23,6 @@ Imports CView = SCrawler.API.Reddit.IRedditView.View
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit
Friend Class UserData : Inherits UserDataBase : Implements IChannelLimits, IRedditView
#Region "XML names"
Private Const Name_TrueName As String = "TrueName"
#End Region
#Region "Declarations"
Private Const CannelsLabelName As String = "Channels"
Friend Const CannelsLabelName_ChannelsForm As String = "RChannels"
@@ -51,6 +48,42 @@ Namespace API.Reddit
Return {CannelsLabelName, CannelsLabelName_ChannelsForm, UserLabelName}
End Get
End Property
Private _RedGifsAccount As String = String.Empty
Friend Property RedGifsAccount As String Implements IRedditView.RedGifsAccount
Get
If Not _RedGifsAccount.IsEmptyString Then
Return _RedGifsAccount
ElseIf Not ChannelInfo Is Nothing Then
Return ChannelInfo.RedGifsAccount
Else
Return String.Empty
End If
End Get
Set(ByVal acc As String)
_RedGifsAccount = acc
End Set
End Property
Private _RedditAccount As String = String.Empty
Friend Property RedditAccount As String Implements IRedditView.RedditAccount
Get
If IsChannelForm Then
Return _RedditAccount
Else
Return MyBase.AccountName
End If
End Get
Set(ByVal acc As String)
_RedditAccount = acc
End Set
End Property
Friend Overrides Property AccountName As String
Get
Return RedditAccount
End Get
Set(ByVal acc As String)
MyBase.AccountName = acc
End Set
End Property
#End Region
#Region "Channels Support"
#Region "IChannelLimits Support"
@@ -72,6 +105,11 @@ Namespace API.Reddit
End With
End Sub
Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits
Private ReadOnly Property IsChannelForm As Boolean
Get
Return Not IsSavedPosts AndAlso IsChannel AndAlso Not ChannelInfo Is Nothing
End Get
End Property
#End Region
Friend Property ChannelInfo As Channel
Private ReadOnly ChannelPostsNames As List(Of String)
@@ -91,6 +129,8 @@ Namespace API.Reddit
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
RedGifsAccount = Options.RedGifsAccount
RedditAccount = Options.RedditAccount
End If
End Sub
Private ReadOnly Property View As String
@@ -162,6 +202,8 @@ Namespace API.Reddit
ViewPeriod = .Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(CPeriod.All))
IsChannel = .Value(Name_IsChannel).FromXML(Of Boolean)(False)
TrueName = .Value(Name_TrueName)
RedGifsAccount = .Value(Name_RedGifsAccount)
RedditAccount = .Value(Name_RedditAccount)
UpdateNames()
Else
If UpdateNames() Then .Value(Name_LabelsName) = LabelsString
@@ -169,11 +211,13 @@ Namespace API.Reddit
.Add(Name_ViewPeriod, CInt(ViewPeriod))
.Add(Name_IsChannel, IsChannel.BoolToInteger)
.Add(Name_TrueName, TrueName)
.Add(Name_RedGifsAccount, RedGifsAccount)
.Add(Name_RedditAccount, RedditAccount)
End If
End With
End Sub
Friend Overrides Function ExchangeOptionsGet() As Object
Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod}
Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod, .RedGifsAccount = RedGifsAccount, .RedditAccount = RedditAccount}
End Function
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
If Not Obj Is Nothing AndAlso TypeOf Obj Is IRedditView Then SetView(DirectCast(Obj, IRedditView))
@@ -187,7 +231,7 @@ Namespace API.Reddit
If IsChannel Or IsSavedPosts Then UseMD5Comparison = False
If IsSavedPosts Then TrueName = MySiteSettings.SavedPostsUserName.Value
UpdateNames()
If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo Is Nothing) Then
If IsChannelForm Then
UseMD5Comparison = False
EnvirDownloadSet()
If Not Responser Is Nothing Then Responser.Dispose()
@@ -790,8 +834,9 @@ Namespace API.Reddit
Dim r$, v$
Dim e As New ErrorsDescriber(EDP.ReturnValue)
Dim m As UserMedia, m2 As UserMedia
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey)
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey, RedGifsAccount)
Dim _repeatForRedgifs As Boolean
If RedGifsHost Is Nothing Then RedGifsHost = Settings(RedGifs.RedGifsSiteKey).Default
RedGifsResponser = RedGifsHost.Responser.Copy
ProgressPre.ChangeMax(_TempMediaList.Count)
For i% = _TempMediaList.Count - 1 To 0 Step -1
@@ -806,7 +851,7 @@ Namespace API.Reddit
r = Gfycat.Envir.GetVideo(m.URL)
If Not r.IsEmptyString AndAlso r.Contains("redgifs.com") Then m.URL = r : _repeatForRedgifs = True
ElseIf m.URL.Contains(SiteRedGifsKey) Then
m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost)
m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost, RedGifsAccount)
If m2.State = UStates.Missing Then
m.State = UStates.Missing
_ContentList.Add(m)
@@ -853,7 +898,8 @@ Namespace API.Reddit
Try
If Not ChannelInfo Is Nothing Or SaveToCache Then Exit Sub
If ContentMissingExists Then
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey)
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey, RedGifsAccount)
If RedGifsHost Is Nothing Then RedGifsHost = Settings(RedGifs.RedGifsSiteKey).Default
RedGifsResponser = RedGifsHost.Responser.Copy
Dim m As UserMedia, m2 As UserMedia
Dim r$
@@ -945,7 +991,7 @@ Namespace API.Reddit
If _ContentNew.Count > 0 Then
Try
If Not _RedGifsResponser Is Nothing Then _RedGifsResponser.Dispose()
_RedGifsResponser = Settings(RedGifs.RedGifsSiteKey).Responser.Copy
_RedGifsResponser = If(Settings(RedGifs.RedGifsSiteKey, RedGifsAccount), Settings(RedGifs.RedGifsSiteKey).Default).Responser.Copy
DownloadContentDefault(Token)
Finally
If Not _RedGifsResponser Is Nothing Then _RedGifsResponser.Dispose() : _RedGifsResponser = Nothing

View File

@@ -18,33 +18,23 @@ Namespace API.RedGifs
<Manifest(RedGifsSiteKey)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.RedGifsIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.RedGifsPic_32
End Get
End Property
<PropertyOption(ControlToolTip:="Bearer token", AllowNull:=False), DependentFields(NameOf(UserAgent)), ControlNumber(1)>
<PropertyOption(ControlToolTip:="Bearer token", AllowNull:=False), DependentFields(NameOf(UserAgent)), ControlNumber(1), PClonable(Clone:=False)>
Friend ReadOnly Property Token As PropertyValue
<PropertyOption, ControlNumber(2)>
<PropertyOption, ControlNumber(2), PClonable>
Private ReadOnly Property UserAgent As PropertyValue
<PXML> Friend ReadOnly Property TokenLastDateUpdated As PropertyValue
Private Const TokenName As String = "authorization"
#Region "TokenUpdateInterval"
<PropertyOption(ControlText:="Token refresh interval", ControlToolTip:="Interval (in minutes) to refresh the token", AllowNull:=False, LeftOffset:=120),
PXML, ControlNumber(0)>
PXML, ControlNumber(0), PClonable>
Friend ReadOnly Property TokenUpdateInterval As PropertyValue
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New(RedGifsSite, "redgifs.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New(RedGifsSite, "redgifs.com", AccName, Temp, My.Resources.SiteResources.RedGifsIcon_32, My.Resources.SiteResources.RedGifsPic_32)
Dim t$ = String.Empty
With Responser
.Mode = Responser.Modes.WebClient

View File

@@ -166,16 +166,19 @@ Namespace API.RedGifs
End If
End Function
Friend Shared Function GetDataFromUrlId(ByVal Obj As String, ByVal ObjIsID As Boolean, ByVal Responser As Responser,
ByVal Host As Plugin.Hosts.SettingsHost) As UserMedia
ByVal Host As Plugin.Hosts.SettingsHost, ByVal AccountName As String) As UserMedia
Dim URL$ = String.Empty
Try
If Obj.IsEmptyString Then Return Nothing
If Not ObjIsID Then
Obj = GetVideoIdFromUrl(Obj)
If Not Obj.IsEmptyString Then Return GetDataFromUrlId(Obj, True, Responser, Host)
If Not Obj.IsEmptyString Then Return GetDataFromUrlId(Obj, True, Responser, Host, AccountName)
Else
If Host Is Nothing Then Host = Settings(RedGifsSiteKey)
If Host.Source.Available(Plugin.ISiteSettings.Download.Main, True) Then
If Host Is Nothing Then
Host = Settings(RedGifsSiteKey, AccountName)
If Host Is Nothing Then Host = Settings(RedGifsSiteKey).Default
End If
If Not Host Is Nothing AndAlso Host.Source.Available(Plugin.ISiteSettings.Download.Main, True) Then
If Responser Is Nothing Then Responser = Host.Responser.Copy
URL = String.Format(PostDataUrl, Obj.ToLower)
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
@@ -220,7 +223,7 @@ Namespace API.RedGifs
#End Region
#Region "Single data downloader"
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
Dim m As UserMedia = GetDataFromUrlId(Data.URL, False, Responser, HOST)
Dim m As UserMedia = GetDataFromUrlId(Data.URL, False, Responser, HOST, AccountName)
If Not m.State = UStates.Missing And Not m.State = DataGone And (m.Type = UTypes.Picture Or m.Type = UTypes.Video) Then
m.URL_BASE = MySettings.GetUserPostUrl(Me, m)
_TempMediaList.Add(m)

View File

@@ -16,31 +16,21 @@ Namespace API.ThisVid
<Manifest(ThisVidSiteKey), SeparatedTasks(1), SpecialForm(False), SavedPosts>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.ThisVidIcon_16
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.ThisVidPic_16
End Get
End Property
<PXML, PropertyOption(ControlText:="Public videos", ControlToolTip:="Download public videos")>
<PXML, PropertyOption(ControlText:="Public videos", ControlToolTip:="Download public videos"), PClonable>
Friend ReadOnly Property DownloadPublic As PropertyValue
<PXML, PropertyOption(ControlText:="Private videos", ControlToolTip:="Download private videos")>
<PXML, PropertyOption(ControlText:="Private videos", ControlToolTip:="Download private videos"), PClonable>
Friend ReadOnly Property DownloadPrivate As PropertyValue
<PXML, PropertyOption(ControlText:="Favourite videos", ControlToolTip:="Download favourite videos")>
<PXML, PropertyOption(ControlText:="Favourite videos", ControlToolTip:="Download favourite videos"), PClonable>
Friend ReadOnly Property DownloadFavourite As PropertyValue
<PXML, PropertyOption(ControlText:="Different folders",
ControlToolTip:="Use different folders to store video files." & vbCr &
"If true, then public videos will be stored in the 'Public' folder, private - in the 'Private' folder." & vbCr &
"If false, all videos will be stored in the 'Video' folder.")>
"If false, all videos will be stored in the 'Video' folder."), PClonable>
Friend ReadOnly Property DifferentFolders As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("ThisVid", "thisvid.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("ThisVid", "thisvid.com", AccName, Temp, My.Resources.SiteResources.ThisVidIcon_16, My.Resources.SiteResources.ThisVidPic_16)
With Responser
.CookiesExtractMode = Responser.CookiesExtractModes.Any
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll

View File

@@ -20,9 +20,6 @@ Namespace API.ThisVid
Private Const Name_DownloadPrivate As String = "DownloadPrivate"
Private Const Name_DownloadFavourite As String = "DownloadFavourite"
Private Const Name_DifferentFolders As String = "DifferentFolders"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_Arguments As String = "Arguments"
#End Region
#Region "Structures"
Private Structure Album : Implements IRegExCreator
@@ -180,7 +177,7 @@ Namespace API.ThisVid
#Region "Initializer"
Friend Sub New()
UseClientTokens = True
PagePosts = New List(Of String)
SessionPosts = New List(Of String)
End Sub
#End Region
#Region "Validation"
@@ -224,11 +221,14 @@ Namespace API.ThisVid
End Function
#End Region
#Region "Download functions"
Private ReadOnly PagePosts As List(Of String)
Private ReadOnly SessionPosts As List(Of String)
Private AddedCount As Integer = 0
Private _PageVideosRepeat As Integer = 0
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
PagePosts.Clear()
SessionPosts.Clear()
AddedCount = 0
_PageVideosRepeat = 0
SessionPosts.Clear()
Responser.Cookies.ChangedAllowInternalDrop = False
Responser.Cookies.Changed = False
If ID.IsEmptyString Then ID = Name
@@ -289,6 +289,8 @@ Namespace API.ThisVid
ProgressPre.Perform()
Dim r$ = Responser.GetResponse(URL)
Dim cBefore% = _TempMediaList.Count
Dim pageRepeatSet As Boolean = False, prevPostsFound As Boolean = False, newPostsFound As Boolean = False
If Not r.IsEmptyString Then
Dim __SpecialFolder$ = If(DifferentFolders And Not IsSavedPosts And IsUser,
Interaction.Switch(Model = 0, "Public", Model = 1, "Private", Model = 2, "Favourite"),
@@ -301,20 +303,29 @@ Namespace API.ThisVid
_TempPostsList.Add(u)
_TempMediaList.Add(New UserMedia(u) With {.Type = UserMedia.Types.VideoPre, .SpecialFolder = __SpecialFolder})
AddedCount += 1
newPostsFound = True
If pageRepeatSet Then pageRepeatSet = False : _PageVideosRepeat -= 1
If limit > 0 And AddedCount >= limit Then Exit Sub
ElseIf PagePosts.Count > 0 AndAlso PagePosts.Contains(u) Then
ElseIf SessionPosts.Count > 0 AndAlso SessionPosts.Contains(u) Then
prevPostsFound = True
If pageRepeatSet Then pageRepeatSet = False : _PageVideosRepeat -= 1
Continue For
Else
Exit Sub
If _PageVideosRepeat > 2 Then
Exit Sub
ElseIf Not pageRepeatSet And Not newPostsFound Then
pageRepeatSet = True
_PageVideosRepeat += 1
End If
End If
End If
Next
PagePosts.Clear()
PagePosts.AddRange(l)
SessionPosts.ListAddList(l, LNC)
l.Clear()
End If
End If
If Not cBefore = _TempMediaList.Count And (IsUser Or Page < 1000) Then DownloadData(Page + 1, Model, Token)
If (Not IsUser And prevPostsFound And Not newPostsFound And Page < 1000) Or
(Not cBefore = _TempMediaList.Count And (IsUser Or Page < 1000)) Then DownloadData(Page + 1, Model, Token)
Catch aex As ArgumentNullException When aex.HelpLink = 1
Catch ex As Exception
ProcessException(ex, Token, $"videos downloading error [{URL}]")
@@ -548,7 +559,7 @@ Namespace API.ThisVid
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then PagePosts.Clear()
If Not disposedValue And disposing Then SessionPosts.Clear()
MyBase.Dispose(disposing)
End Sub
#End Region

View File

@@ -17,31 +17,30 @@ Namespace API.ThreadsNet
<Manifest("AndyProgram_ThreadsNet"), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.ThreadsIcon_192
End Get
End Property
Private ReadOnly _Image As Image
Friend Overrides ReadOnly Property Image As Image
Get
Return _Image
End Get
End Property
#Region "Authorization"
<PropertyOption(ControlText:="x-csrftoken", AllowNull:=False)>
Friend ReadOnly Property HH_CSRF_TOKEN As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", AllowNull:=False)>
Friend Property HH_IG_APP_ID As PropertyValue
<PropertyOption(ControlText:="x-asbd-id", AllowNull:=True)>
Friend Property HH_ASBD_ID As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua", AllowNull:=True)>
Private Property HH_BROWSER As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", AllowNull:=True)>
Private Property HH_BROWSER_EXT As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-platform-ver", ControlToolTip:="sec-ch-ua-platform-version", AllowNull:=True, LeftOffset:=120)>
Private Property HH_PLATFORM As PropertyValue
<PropertyOption(ControlText:="UserAgent")>
<PClonable(Clone:=False)> Protected ReadOnly __HH_CSRF_TOKEN As PropertyValue
<PropertyOption(ControlText:="x-csrftoken", AllowNull:=False, IsAuth:=True), ControlNumber(0)>
Friend Overridable ReadOnly Property HH_CSRF_TOKEN As PropertyValue
Get
Return __HH_CSRF_TOKEN
End Get
End Property
<PClonable> Protected ReadOnly __HH_IG_APP_ID As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", AllowNull:=False, IsAuth:=True), ControlNumber(10)>
Friend Overridable ReadOnly Property HH_IG_APP_ID As PropertyValue
Get
Return __HH_IG_APP_ID
End Get
End Property
<PropertyOption(ControlText:="x-asbd-id", AllowNull:=True, IsAuth:=True), ControlNumber(20), PClonable>
Friend ReadOnly Property HH_ASBD_ID As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua", AllowNull:=True, IsAuth:=True), ControlNumber(30), PClonable>
Private ReadOnly Property HH_BROWSER As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-full", ControlToolTip:="sec-ch-ua-full-version-list", AllowNull:=True, IsAuth:=True), ControlNumber(40), PClonable>
Private ReadOnly Property HH_BROWSER_EXT As PropertyValue
<PropertyOption(ControlText:="sec-ch-ua-platform", ControlToolTip:="sec-ch-ua-platform", AllowNull:=True, IsAuth:=True, LeftOffset:=120), ControlNumber(50), PClonable>
Private ReadOnly Property HH_PLATFORM As PropertyValue
<PropertyOption(ControlText:="UserAgent", IsAuth:=True), ControlNumber(60), PClonable>
Private ReadOnly Property HH_USER_AGENT As PropertyValue
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
If Not PropName.IsEmptyString Then
@@ -67,10 +66,15 @@ Namespace API.ThreadsNet
#End Region
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("Threads", "threads.net")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
Me.New("Threads", "threads.net", AccName, Temp, My.Resources.SiteResources.ThreadsIcon_192, My.Resources.SiteResources.ThreadsIcon_192.ToBitmap)
End Sub
Protected Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing)
MyBase.New(SiteName, CookiesDomain, AccName, Temp,
If(__Icon, My.Resources.SiteResources.ThreadsIcon_192),
If(__Image, My.Resources.SiteResources.ThreadsIcon_192.ToBitmap))
_AllowUserAgentUpdate = False
_Image = My.Resources.SiteResources.ThreadsIcon_192.ToBitmap
Dim app_id$ = String.Empty
Dim token$ = String.Empty
@@ -94,17 +98,17 @@ Namespace API.ThreadsNet
browserExt = .Value(IG.Header_BrowserExt)
platform = .Value(IG.Header_Platform)
End If
.Add("Authority", "www.threads.net")
.Add("Origin", "https://www.threads.net")
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.threads.net"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.threads.net"))
.Add("Upgrade-Insecure-Requests", 1)
.Add("Sec-Ch-Ua-Model", "")
.Add("Sec-Ch-Ua-Mobile", "?0")
.Add("Sec-Ch-Ua-Platform", """Windows""")
.Add("Sec-Fetch-Dest", "empty")
.Add("Sec-Fetch-Mode", "cors")
.Add("Sec-Fetch-Site", "same-origin")
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaMobile, "?0"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaPlatform, """Windows"""))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchDest, "empty"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchMode, "cors"))
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecFetchSite, "same-origin"))
.Add("Sec-Fetch-User", "?1")
.Add("x-fb-friendly-name", "BarcelonaProfileThreadsTabRefetchableQuery")
.Add(DeclaredNames.Header_FB_FRIENDLY_NAME, "BarcelonaProfileThreadsTabRefetchableQuery")
End With
.CookiesExtractMode = Responser.CookiesExtractModes.Any
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll
@@ -113,8 +117,8 @@ Namespace API.ThreadsNet
.Cookies.Changed = False
End With
HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v))
HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v))
__HH_CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_CSRF_TOKEN), v))
__HH_IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_IG_APP_ID), v))
HH_ASBD_ID = New PropertyValue(asbd, GetType(String), Sub(v) ChangeResponserFields(NameOf(HH_ASBD_ID), 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))
@@ -127,7 +131,7 @@ Namespace API.ThreadsNet
End Sub
#End Region
#Region "UpdateResponserData"
Friend Sub UpdateResponserData(ByVal Resp As Responser)
Friend Overridable Sub UpdateResponserData(ByVal Resp As Responser)
With Responser.Cookies
Dim csrf$ = String.Empty
.Update(Resp.Cookies)

View File

@@ -18,7 +18,7 @@ Imports IGS = SCrawler.API.Instagram.SiteSettings
Namespace API.ThreadsNet
Friend Class UserData : Inherits Instagram.UserData
#Region "Declarations"
Private Const Header_FB_LSD As String = "x-fb-lsd"
Friend Const Header_FB_LSD As String = "x-fb-lsd"
Private ReadOnly Property MySettings As SiteSettings
Get
Return HOST.Source

View File

@@ -13,27 +13,17 @@ Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.TikTok
<Manifest("AndyProgram_TikTok"), SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.TikTokIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.TikTokPic_192
End Get
End Property
<PropertyOption(ControlText:="Remove tags from title"), PXML>
<PropertyOption(ControlText:="Remove tags from title"), PXML, PClonable>
Friend Property RemoveTagsFromTitle As PropertyValue
<PropertyOption(ControlText:="Use native title", ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML>
<PropertyOption(ControlText:="Use native title", ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML, PClonable>
Friend Property TitleUseNative As PropertyValue
<PropertyOption(ControlText:="Use native title in standalone downloader",
ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML>
ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML, PClonable>
Friend Property TitleUseNativeSTD As PropertyValue
<PropertyOption(ControlText:="Add video ID to video title"), PXML>
<PropertyOption(ControlText:="Add video ID to video title"), PXML, PClonable>
Friend Property TitleAddVideoID As PropertyValue
Friend Sub New()
MyBase.New("TikTok", "www.tiktok.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("TikTok", "www.tiktok.com", AccName, Temp, My.Resources.SiteResources.TikTokIcon_32, My.Resources.SiteResources.TikTokPic_192)
RemoveTagsFromTitle = New PropertyValue(False)
TitleUseNative = New PropertyValue(True)
TitleUseNativeSTD = New PropertyValue(False)

View File

@@ -16,43 +16,32 @@ Namespace API.Twitter
<Manifest(TwitterSiteKey), SavedPosts, SeparatedTasks, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.TwitterIcon_32
End Get
End Property
Private ReadOnly _Image As Image
Friend Overrides ReadOnly Property Image As Image
Get
Return _Image
End Get
End Property
#Region "Other properties"
<PropertyOption(ControlText:="Use the appropriate model",
ControlToolTip:="Use the appropriate model for new users." & vbCr &
"If disabled, all download models will be used for the first download. " &
"Next, the appropriate download model will be automatically selected." & vbCr &
"Otherwise the appropriate download model will be selected right from the start."), PXML>
"Otherwise the appropriate download model will be selected right from the start."), PXML, PClonable>
Friend ReadOnly Property UseAppropriateModel As PropertyValue
#Region "End points"
<PropertyOption(ControlText:="New endpoint: search", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the search model."), PXML>
<PropertyOption(ControlText:="New endpoint: search", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the search model."), PXML, PClonable>
Friend Property UseNewEndPointSearch As PropertyValue
<PropertyOption(ControlText:="New endpoint: profiles", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the profile models."), PXML>
<PropertyOption(ControlText:="New endpoint: profiles", ControlToolTip:="Use new endpoint argument (-o search-endpoint=graphql) for the profile models."), PXML, PClonable>
Friend Property UseNewEndPointProfiles As PropertyValue
#End Region
#Region "Limits"
<PropertyOption(ControlText:="Abort on limit", ControlToolTip:="Abort twitter downloading when limit is reached"), PXML>
<PropertyOption(ControlText:="Abort on limit", ControlToolTip:="Abort twitter downloading when limit is reached"), PXML, PClonable>
Friend Property AbortOnLimit As PropertyValue
<PropertyOption(ControlText:="Download already parsed", ControlToolTip:="Download already parsed content on abort"), PXML>
<PropertyOption(ControlText:="Download already parsed", ControlToolTip:="Download already parsed content on abort"), PXML, PClonable>
Friend Property DownloadAlreadyParsed As PropertyValue
#End Region
<PropertyOption(ControlText:="Media Model: allow non-user tweets", ControlToolTip:="Allow downloading non-user tweets in the media-model."), PXML>
<PropertyOption(ControlText:="Media Model: allow non-user tweets", ControlToolTip:="Allow downloading non-user tweets in the media-model."), PXML, PClonable>
Friend ReadOnly Property MediaModelAllowNonUserTweets As PropertyValue
<PropertyOption(ControlText:=DN.GifsDownloadCaption), PXML>
<PropertyOption(ControlText:=DN.GifsDownloadCaption), PXML, PClonable>
Friend ReadOnly Property GifsDownload As PropertyValue
<PropertyOption(ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML>
<PropertyOption(ControlText:=DN.GifsSpecialFolderCaption, ControlToolTip:=DN.GifsSpecialFolderToolTip), PXML, PClonable>
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
<PropertyOption(ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML>
<PropertyOption(ControlText:=DN.GifsPrefixCaption, ControlToolTip:=DN.GifsPrefixToolTip), PXML, PClonable>
Friend ReadOnly Property GifsPrefix As PropertyValue
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
Private ReadOnly Property GifStringChecker As IFormatProvider
@@ -74,19 +63,18 @@ Namespace API.Twitter
Throw New NotImplementedException("[GetFormat] is not available in the context of [GifStringProvider]")
End Function
End Class
<PropertyOption(ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML>
<PropertyOption(ControlText:=DN.UseMD5ComparisonCaption, ControlToolTip:=DN.UseMD5ComparisonToolTip), PXML, PClonable>
Friend ReadOnly Property UseMD5Comparison As PropertyValue
<PropertyOption(ControlText:=DN.ConcurrentDownloadsCaption,
ControlToolTip:=DN.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter>
ControlToolTip:=DN.ConcurrentDownloadsToolTip, AllowNull:=False, LeftOffset:=120), PXML, TaskCounter, PClonable>
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
<Provider(NameOf(ConcurrentDownloads), FieldsChecker:=True)>
Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider
#End Region
#End Region
Friend Sub New()
MyBase.New(TwitterSite, "twitter.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New(TwitterSite, "twitter.com", AccName, Temp, My.Resources.SiteResources.TwitterIcon_32, My.Resources.SiteResources.TwitterIcon_32.ToBitmap)
_Image = My.Resources.SiteResources.TwitterIcon_32.ToBitmap
LimitSkippedUsers = New List(Of UserDataBase)
With Responser

View File

@@ -15,31 +15,31 @@ Namespace API.XVIDEOS
<Manifest(XvideosSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
<PXML("Domains"), PClonable> Private ReadOnly Property SiteDomains As PropertyValue
Private Shadows ReadOnly Property DefaultInstance As SiteSettings
Get
Return My.Resources.SiteResources.XvideosIcon_48
Return MyBase.DefaultInstance
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.XvideosPic_32
End Get
End Property
<PXML("Domains")> Private ReadOnly Property SiteDomains As PropertyValue
Private ReadOnly _Domains As DomainsContainer
Friend ReadOnly Property Domains As DomainsContainer
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
Get
Return If(DefaultInstance?.Domains, _Domains)
End Get
End Property
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML, PClonable>
Friend Property DownloadUHD As PropertyValue
<PropertyOption(ControlText:="Playlist of saved videos",
ControlToolTip:="Your personal videos playlist to download as 'saved posts'. " & vbCr &
"This playlist must be private (Visibility = 'Only me'). It also required cookies." & vbCr &
"This playlist must be entered by pattern: https://www.xvideos.com/favorite/01234567/playlistname.",
LeftOffset:=130), PXML>
LeftOffset:=130), PXML, PClonable(Clone:=False)>
Friend ReadOnly Property SavedVideosPlaylist As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("XVIDEOS", "www.xvideos.com")
Domains = New DomainsContainer(Me, "xvideos.com|xnxx.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("XVIDEOS", "www.xvideos.com", AccName, Temp, My.Resources.SiteResources.XvideosIcon_48, My.Resources.SiteResources.XvideosPic_32)
_Domains = New DomainsContainer(Me, "xvideos.com|xnxx.com")
SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String))
Domains.DestinationProp = SiteDomains
DownloadUHD = New PropertyValue(False)
@@ -156,6 +156,12 @@ Namespace API.XVIDEOS
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then _Domains.Dispose()
MyBase.Dispose(disposing)
End Sub
#End Region
End Class
End Namespace

View File

@@ -17,9 +17,6 @@ Imports UTypes = SCrawler.API.Base.UserMedia.Types
Namespace API.XVIDEOS
Friend Class UserData : Inherits UserDataBase
#Region "XML names"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_Arguments As String = "Arguments"
Private Const Name_PersonType As String = "PersonType"
#End Region
#Region "Structures"
@@ -56,6 +53,11 @@ Namespace API.XVIDEOS
Return SiteMode = SiteModes.User
End Get
End Property
Friend ReadOnly Property IsSearch As Boolean
Get
Return SiteMode = SiteModes.Search Or SiteMode = SiteModes.Tags Or SiteMode = SiteModes.Categories
End Get
End Property
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
@@ -175,6 +177,7 @@ Namespace API.XVIDEOS
UseClientTokens = True
End Sub
#End Region
#Region "GetUserUrl"
Friend Function GetUserUrl(ByVal Page As Integer) As String
Dim url$ = String.Empty
If SiteMode = SiteModes.User Then
@@ -196,6 +199,8 @@ Namespace API.XVIDEOS
End If
Return url
End Function
#End Region
#Region "Download functions"
Private Sub Wait429(ByVal Round As Integer)
If (Round Mod 5) = 0 Then
Thread.Sleep(5000 + (Round / 5).RoundDown)
@@ -321,7 +326,11 @@ Namespace API.XVIDEOS
Dim r$
Dim round% = 0
Dim data As List(Of PlayListVideo)
Dim pids As New List(Of String)
Dim cBefore%
Dim pageRepeatSet As Boolean, prevPostsFound As Boolean, newPostsFound As Boolean
Dim sessionPosts As New List(Of String)
Dim pageVideosRepeat As Integer = 0
Dim limit% = If(DownloadTopCount, -1)
Do
@@ -329,7 +338,11 @@ Namespace API.XVIDEOS
Wait429(round)
ThrowAny(Token)
NextPage += 1
newPostsFound = False
pageRepeatSet = False
prevPostsFound = False
cBefore = _TempMediaList.Count
pids.Clear()
If SiteMode = SiteModes.User Then
URL = $"{MySettings.SavedVideosPlaylist.Value}{If(NextPage = 0, String.Empty, $"/{NextPage}")}"
@@ -355,14 +368,35 @@ Namespace API.XVIDEOS
If Not r.IsEmptyString Then
data = RegexFields(Of PlayListVideo)(r, {Regex_SavedVideosPlaylist}, {1, 2, 3}, EDP.ReturnValue)
If data.ListExists Then
If data.RemoveAll(Function(d) _TempPostsList.Contains(d.ID)) > 0 Then __continue = False
pids.ListAddList(data.Select(Function(d) d.ID), LNC)
If data.RemoveAll(Function(d) _TempPostsList.Contains(d.ID)) > 0 And Not IsSearch Then __continue = False
If data.ListExists Then
_TempPostsList.ListAddList(data.Select(Function(d) d.ID), LNC)
_TempMediaList.ListAddList(data.Select(Function(d) d.ToUserMedia()), LNC)
newPostsFound = cBefore <> _TempMediaList.Count
ElseIf sessionPosts.Count > 0 AndAlso sessionPosts.ListContains(pids) Then
If pageRepeatSet Then pageRepeatSet = False : pageVideosRepeat -= 1
Else
If pageVideosRepeat > 2 Then
Exit Do
ElseIf Not pageRepeatSet And Not newPostsFound Then
pageRepeatSet = True
pageVideosRepeat += 1
End If
End If
sessionPosts.ListAddList(pids, LNC)
End If
End If
Loop While NextPage < 100 And __continue And _TempMediaList.Count > cBefore And (limit < 0 Or _TempMediaList.Count < limit)
If limit > 0 And _TempMediaList.Count >= limit Then Exit Do
If IsSearch Then
__continue = NextPage < 1000 And (newPostsFound Or (prevPostsFound And Not newPostsFound))
ElseIf __continue Then
__continue = Not cBefore = _TempMediaList.Count
End If
Loop While NextPage < 1000 And __continue
pids.Clear()
sessionPosts.Clear()
If limit > 0 And _TempMediaList.Count >= limit Then _TempMediaList.ListAddList(_TempMediaList.ListTake(-1, limit), LAP.ClearBeforeAdd)
If _TempMediaList.Count > 0 Then
@@ -451,16 +485,22 @@ Namespace API.XVIDEOS
Return Nothing
End Try
End Function
#End Region
#Region "DownloadContent"
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
DownloadContentDefault(Token)
End Sub
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
Dim m As UserMedia = GetVideoData(New UserMedia(Data.URL, UTypes.VideoPre))
If Not m.URL.IsEmptyString Then _TempMediaList.Add(m)
End Sub
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, Progress, Not IsSingleObjectDownload)
End Function
#End Region
#Region "SingleObject"
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
Dim m As UserMedia = GetVideoData(New UserMedia(Data.URL, UTypes.VideoPre))
If Not m.URL.IsEmptyString Then _TempMediaList.Add(m)
End Sub
#End Region
#Region "Exception"
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal EObj As Object = Nothing) As Integer
Dim isQuickies As Boolean = False
@@ -474,5 +514,6 @@ Namespace API.XVIDEOS
Return 0
End If
End Function
#End Region
End Class
End Namespace

View File

@@ -15,26 +15,26 @@ Namespace API.Xhamster
<Manifest(XhamsterSiteKey), SavedPosts, SpecialForm(True), SpecialForm(False), TaskGroup(SettingsCLS.TaskStackNamePornSite)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
<PXML("Domains"), PClonable> Private ReadOnly Property SiteDomains As PropertyValue
Private Shadows ReadOnly Property DefaultInstance As SiteSettings
Get
Return My.Resources.SiteResources.XhamsterIcon_32
Return MyBase.DefaultInstance
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteResources.XhamsterPic_32
End Get
End Property
<PXML("Domains")> Private ReadOnly Property SiteDomains As PropertyValue
Private ReadOnly _Domains As DomainsContainer
Friend ReadOnly Property Domains As DomainsContainer
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
Get
Return If(DefaultInstance?.Domains, _Domains)
End Get
End Property
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML, PClonable>
Friend Property DownloadUHD As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New("XHamster", "xhamster.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New("XHamster", "xhamster.com", AccName, Temp, My.Resources.SiteResources.XhamsterIcon_32, My.Resources.SiteResources.XhamsterPic_32)
Domains = New DomainsContainer(Me, "xhamster.com")
_Domains = New DomainsContainer(Me, "xhamster.com")
SiteDomains = New PropertyValue(Domains.DomainsDefault, GetType(String))
Domains.DestinationProp = SiteDomains
DownloadUHD = New PropertyValue(False)
@@ -149,6 +149,12 @@ Namespace API.Xhamster
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
End If
End Sub
#End Region
#Region "IDisposable Support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then _Domains.Dispose()
MyBase.Dispose(disposing)
End Sub
#End Region
End Class
End Namespace

View File

@@ -18,10 +18,7 @@ Imports UTypes = SCrawler.API.Base.UserMedia.Types
Namespace API.Xhamster
Friend Class UserData : Inherits UserDataBase
#Region "XML names"
Private Const Name_TrueName As String = "TrueName"
Private Const Name_Gender As String = "Gender"
Private Const Name_SiteMode As String = "SiteMode"
Private Const Name_Arguments As String = "Arguments"
#End Region
#Region "Declarations"
Friend Overrides ReadOnly Property FeedIsUser As Boolean
@@ -39,6 +36,11 @@ Namespace API.Xhamster
Return SiteMode = SiteModes.User Or SiteMode = SiteModes.Pornstars
End Get
End Property
Friend ReadOnly Property IsSearch As Boolean
Get
Return SiteMode = SiteModes.Search Or SiteMode = SiteModes.Tags Or SiteMode = SiteModes.Categories
End Get
End Property
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
Get
Return {SearchRequestLabelName}
@@ -171,6 +173,7 @@ Namespace API.Xhamster
UseInternalM3U8Function = True
UseClientTokens = True
_TempPhotoData = New List(Of UserMedia)
SessionPosts = New List(Of String)
End Sub
#End Region
#Region "Download functions"
@@ -218,9 +221,13 @@ Namespace API.Xhamster
End If
End Function
Private SearchPostsCount As Integer = 0
Private ReadOnly SessionPosts As List(Of String)
Private _PageVideosRepeat As Integer = 0
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
_TempPhotoData.Clear()
SearchPostsCount = 0
_PageVideosRepeat = 0
SessionPosts.Clear()
If DownloadVideos Then DownloadData(1, True, Token)
If Not IsChannel And DownloadImages And Not IsSubscription Then
DownloadData(1, False, Token)
@@ -238,6 +245,8 @@ Namespace API.Xhamster
Dim skipped As Boolean = False
Dim limit% = If(DownloadTopCount, -1)
Dim cBefore% = _TempMediaList.Count
Dim pageRepeatSet As Boolean = False, prevPostsFound As Boolean = False, newPostsFound As Boolean = False
Dim pids As New List(Of String)
Dim m As UserMedia
Dim checkLimit As Func(Of Boolean) = Function() limit > 0 And SearchPostsCount >= limit And IsVideo
@@ -284,6 +293,7 @@ Namespace API.Xhamster
ProgressPre.Perform()
m = ExtractMedia(e, Type)
If Not m.URL.IsEmptyString Then
pids.ListAddValue(m.Post.ID, LNC)
If m.File.IsEmptyString Then Continue For
If m.Post.Date.HasValue Then
@@ -297,6 +307,8 @@ Namespace API.Xhamster
_TempPostsList.Add(m.Post.ID)
_TempMediaList.ListAddValue(m, LNC)
SearchPostsCount += 1
newPostsFound = True
If pageRepeatSet Then pageRepeatSet = False : _PageVideosRepeat -= 1
If checkLimit.Invoke Then Exit Sub
ElseIf Not IsVideo Then
If DirectCast(m.Object, ExchObj).IsPhoto Then
@@ -307,11 +319,24 @@ Namespace API.Xhamster
Else
_TempPhotoData.ListAddValue(m, LNC)
End If
ElseIf IsVideo And _TempPostsList.Contains(m.Post.ID) Then
If SessionPosts.Count > 0 AndAlso SessionPosts.Contains(m.Post.ID) Then
prevPostsFound = True
If pageRepeatSet Then pageRepeatSet = False : _PageVideosRepeat -= 1
Continue For
ElseIf _PageVideosRepeat > 2 Then
Exit Sub
ElseIf Not pageRepeatSet And Not newPostsFound Then
pageRepeatSet = True
_PageVideosRepeat += 1
End If
Else
Exit Sub
End If
End If
Next
SessionPosts.ListAddList(pids, LNC)
pids.Clear()
Exit For
End If
End With
@@ -322,8 +347,11 @@ Namespace API.Xhamster
containerNodes.Clear()
If (Not _TempMediaList.Count = cBefore Or skipped) And
(IsChannel Or (MaxPage > 0 And Page < MaxPage) Or (Not SiteMode = SiteModes.User And Page < 1000)) Then DownloadData(Page + 1, IsVideo, Token)
If (
(MaxPage = -1 Or Page < MaxPage) And
((Not _TempMediaList.Count = cBefore Or skipped) And (IsUser Or Page < 1000))
) Or
(IsChannel Or (Not IsUser And Page < 1000 And prevPostsFound And Not newPostsFound)) Then DownloadData(Page + 1, IsVideo, Token)
Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]")
End Try
@@ -344,6 +372,7 @@ Namespace API.Xhamster
m = _TempMediaList(i)
If Not m.URL_BASE.IsEmptyString Then
m2 = Nothing
ThrowAny(Token)
If GetM3U8(m2, m.URL_BASE) Then
m2.URL_BASE = m.URL_BASE
_TempMediaList(i) = m2
@@ -373,6 +402,7 @@ Namespace API.Xhamster
m = _TempMediaList(i)
If Not m.URL_BASE.IsEmptyString Then
m2 = Nothing
ThrowAny(Token)
If GetM3U8(m2, m.URL_BASE) Then
m2.URL_BASE = m.URL_BASE
_TempMediaList(i) = m2
@@ -582,12 +612,13 @@ Namespace API.Xhamster
#Region "Exception"
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
Optional ByVal EObj As Object = Nothing) As Integer
Return If(Responser.Status = Net.WebExceptionStatus.ConnectionClosed, 1, 0)
'8, 503
Return If(Responser.Status = Net.WebExceptionStatus.ConnectionClosed Or Responser.StatusCode = Net.HttpStatusCode.ServiceUnavailable, 1, 0)
End Function
#End Region
#Region "IDisposable support"
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue And disposing Then _TempPhotoData.Clear()
If Not disposedValue And disposing Then _TempPhotoData.Clear() : SessionPosts.Clear()
MyBase.Dispose(disposing)
End Sub
#End Region

View File

@@ -14,28 +14,18 @@ Namespace API.YouTube
<Manifest(YouTubeSiteKey), SpecialForm(True), SpecialForm(False), SeparatedTasks(1)>
Friend Class SiteSettings : Inherits SiteSettingsBase
#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteYouTube.YouTubeIcon_32
End Get
End Property
Friend Overrides ReadOnly Property Image As Image
Get
Return My.Resources.SiteYouTube.YouTubePic_96
End Get
End Property
<PXML, PropertyOption(ControlText:="Download user videos")>
<PXML, PropertyOption(ControlText:="Download user videos"), PClonable>
Friend ReadOnly Property DownloadVideos As PropertyValue
<PXML, PropertyOption(ControlText:="Download user shorts")>
<PXML, PropertyOption(ControlText:="Download user shorts"), PClonable>
Friend ReadOnly Property DownloadShorts As PropertyValue
<PXML, PropertyOption(ControlText:="Download user playlists")>
<PXML, PropertyOption(ControlText:="Download user playlists"), PClonable>
Friend ReadOnly Property DownloadPlaylists As PropertyValue
<PXML, PropertyOption(ControlText:="Use cookies", ControlToolTip:="Default value for new users." & vbCr & "Use cookies when downloading data.")>
<PXML, PropertyOption(ControlText:="Use cookies", ControlToolTip:="Default value for new users." & vbCr & "Use cookies when downloading data."), PClonable>
Friend ReadOnly Property UseCookies As PropertyValue
#End Region
#Region "Initializer"
Friend Sub New()
MyBase.New(YouTubeSite, "youtube.com")
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
MyBase.New(YouTubeSite, "youtube.com", AccName, Temp, My.Resources.SiteYouTube.YouTubeIcon_32, My.Resources.SiteYouTube.YouTubePic_96)
Responser.Cookies.ChangedAllowInternalDrop = False
DownloadVideos = New PropertyValue(True)
DownloadShorts = New PropertyValue(False)

View File

@@ -124,7 +124,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
Private Sub SetLimit(ByVal Source As IChannelLimits) Implements IChannelLimits.SetLimit
End Sub
#End Region
Private ReadOnly HOST As SettingsHost
Private ReadOnly HOST_COLLECTION As SettingsHostCollection
Private ReadOnly PendingUsers As List(Of PendingUser)
Private ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly)
Private WithEvents MyRange As RangeSwitcherToolbar(Of UserPost)
@@ -148,7 +148,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
CProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
LimitProvider = New ADateTime("dd.MM.yyyy HH:mm")
PendingUsers = New List(Of PendingUser)
HOST = Settings(RedditSiteKey)
HOST_COLLECTION = Settings(RedditSiteKey)
CMB_CHANNELS = New ComboBoxExtended With {
.CaptionMode = ICaptionControl.Modes.CheckBox,
@@ -312,7 +312,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
Dim Added% = 0, Skipped% = 0
Dim StartIndex% = Settings.Users.Count
Dim f As SFile
Dim umo As Boolean = HOST.GetUserMediaOnly
Dim umo As Boolean
Settings.Labels.Add(UserData.CannelsLabelName_ChannelsForm)
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
Dim rUsers$() = UserBanned(PendingUsers.Select(Function(u) u.ID).ToArray)
@@ -321,13 +321,23 @@ Friend Class ChannelViewForm : Implements IChannelLimits
Dim c As New ListAddParams(LAP.NotContainsOnly)
Dim cn$
Dim tmpUser As IUserData
With PendingUsers.Select(Function(u) New UserInfo(u, HOST))
Dim h As SettingsHost
With PendingUsers.Select(Function(u) New UserInfo(u, If(u.Channel?.HOST, HOST_COLLECTION.Default)))
For i = 0 To .Count - 1
If Not Settings.UsersList.Contains(.ElementAt(i)) Then
f = PendingUsers(i).File
cn = If(PendingUsers(i).Channel?.Name, String.Empty)
If Not PendingUsers(i).Channel Is Nothing Then
cn = PendingUsers(i).Channel.Name
umo = PendingUsers(i).Channel.HOST.GetUserMediaOnly
h = PendingUsers(i).Channel.HOST
Else
cn = String.Empty
umo = True
h = Nothing
End If
If h Is Nothing Then h = HOST_COLLECTION.Default
Settings.UpdateUsersList(.ElementAt(i))
tmpUser = HOST.GetInstance(Plugin.ISiteSettings.Download.Main, .ElementAt(i), False)
tmpUser = h.GetInstance(Plugin.ISiteSettings.Download.Main, .ElementAt(i), False)
With DirectCast(tmpUser, UserData)
.Temporary = Settings.ChannelsDefaultTemporary
.CreatedByChannel = True
@@ -417,7 +427,18 @@ Friend Class ChannelViewForm : Implements IChannelLimits
Private Async Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click
Try
AppendPendingUsers()
If Not TokenSource Is Nothing OrElse Not HOST.Source.Available(Plugin.ISiteSettings.Download.Main, False) Then Exit Sub
Dim c As Channel
If CMB_CHANNELS.Count > 0 Then
Dim hList As IEnumerable(Of String) = Nothing
If CMB_CHANNELS.Checked Then
hList = Settings.Channels.Select(Function(cc) cc.RedditAccount.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).Distinct
Else
c = GetCurrentChannel()
If Not c Is Nothing Then hList = {c.RedditAccount}
End If
If Not TokenSource Is Nothing OrElse Not HOST_COLLECTION.Available(Plugin.ISiteSettings.Download.Main, False, False,
hList, Not hList Is Nothing) Then Exit Sub
End If
Dim InvokeToken As Action = Sub()
If TokenSource Is Nothing Then
CProgress.Maximum = 0
@@ -437,7 +458,6 @@ Friend Class ChannelViewForm : Implements IChannelLimits
MyRange.Enabled = False
End If
End Sub
Dim c As Channel
If CMB_CHANNELS.Count > 0 Then
BTT_DOWNLOAD.Enabled = False
BTT_STOP.Enabled = True
@@ -607,7 +627,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
Try
c = GetCurrentChannel()
If Not c Is Nothing Then
Using f As New RedditViewSettingsForm(c)
Using f As New RedditViewSettingsForm(c, False)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then c.Save()
End Using

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -11,6 +11,8 @@ Imports PersonalUtilities.Forms
Namespace DownloadObjects
Friend Class ActiveDownloadingProgress
Private Const MinWidth As Integer = 450
Private Const TP_RowHeight As Integer = 30
Private Const TP_LowestValue As Integer = 39
Private MyView As FormView
Private Opened As Boolean = False
Friend ReadOnly Property ReadyToOpen As Boolean
@@ -40,9 +42,26 @@ Namespace DownloadObjects
Private Sub ActiveDownloadingProgress_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyView.DisposeIfReady()
End Sub
Private Sub ActiveDownloadingProgress_VisibleChanged(sender As Object, e As EventArgs) Handles Me.VisibleChanged
Try
If Visible Then
ControlInvokeFast(Me, Sub()
Dim s As Size = Size
Dim ss As Size = Screen.PrimaryScreen.WorkingArea.Size
Dim c% = TP_MAIN.RowStyles.Count - 1
s.Height = c * TP_RowHeight + TP_LowestValue + (PaddingE.GetOf({TP_MAIN}).Vertical(c) / c).RoundDown
If s.Height > ss.Height Then s.Height = ss.Height
MinimumSize = Nothing
Size = s
MinimumSize = New Size(MinWidth, s.Height)
End Sub)
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "Change 'ActiveDownloadingProgress' size")
MainFrameObj.UpdateLogButton()
End Try
End Sub
Private Sub Downloader_Reconfigured()
Const RowHeight% = 30
Const LowestValue% = 39
Dim a As Action = Sub()
With TP_MAIN
If .Controls.Count > 0 Then
@@ -59,7 +78,7 @@ Namespace DownloadObjects
If .Pool.Count > 0 Then
For Each j As TDownloader.Job In .Pool
With TP_MAIN
.RowStyles.Add(New RowStyle(SizeType.Absolute, RowHeight))
.RowStyles.Add(New RowStyle(SizeType.Absolute, TP_RowHeight))
.RowCount += 1
JobsList.Add(New DownloadProgress(j))
AddHandler JobsList.Last.ProgressChanged, AddressOf Jobs_ProgressChanged
@@ -69,14 +88,14 @@ Namespace DownloadObjects
TP_MAIN.RowStyles.Add(New RowStyle(SizeType.AutoSize))
TP_MAIN.RowCount += 1
Dim s As Size = Size
Dim ss As Size = Screen.PrimaryScreen.WorkingArea.Size
Dim c% = TP_MAIN.RowStyles.Count - 1
s.Height = c * RowHeight + LowestValue + (PaddingE.GetOf({TP_MAIN}).Vertical(c) / c).RoundDown
If s.Height > ss.Height Then s.Height = ss.Height
MinimumSize = Nothing
Size = s
MinimumSize = New Size(MinWidth, s.Height)
'Dim s As Size = Size
'Dim ss As Size = Screen.PrimaryScreen.WorkingArea.Size
'Dim c% = TP_MAIN.RowStyles.Count - 1
's.Height = c * TP_RowHeight + TP_LowestValue + (PaddingE.GetOf({TP_MAIN}).Vertical(c) / c).RoundDown
'If s.Height > ss.Height Then s.Height = ss.Height
'MinimumSize = Nothing
'Size = s
'MinimumSize = New Size(MinWidth, s.Height)
End If
End With
TP_MAIN.Refresh()

View File

@@ -130,16 +130,25 @@ Namespace DownloadObjects
#End Region
#Region "Execution"
Friend Async Function Start(ByVal Init As Boolean) As Task
Await Task.Run(Sub()
If Count > 0 Then
If Plans.Exists(PlanDownloading) Then PlansWaiter(PlanDownloading)
For Each Plan In Plans
Plan.Start(Init)
PlansWaiter(PlanDownloading)
Thread.Sleep(1000)
Next
End If
End Sub)
Try
Await Task.Run(Sub()
If Count > 0 Then
If Plans.Exists(PlanDownloading) Then PlansWaiter(PlanDownloading)
For Each Plan In Plans
Plan.Start(Init)
PlansWaiter(PlanDownloading)
Thread.Sleep(1000)
Next
End If
End Sub)
Catch ex As Exception
If Init Then
ErrorsDescriber.Execute(EDP.SendToLog, ex, "Start automation")
MainFrameObj.UpdateLogButton()
Else
Throw ex
End If
End Try
End Function
Friend Sub [Stop]()
If Count > 0 Then Plans.ForEach(Sub(p) p.Stop())

View File

@@ -49,8 +49,8 @@ Namespace DownloadObjects
}
CreateButton(BTT_STOP, My.Resources.DeletePic_24)
Dim img As Image = Nothing
If Not _Job.Host Is Nothing Then
With Job.Host.Source
If Not _Job.Host(String.Empty) Is Nothing Then
With Job.Host(String.Empty).Source
If Not .Icon Is Nothing Then img = .Icon.ToBitmap
If img Is Nothing AndAlso Not .Image Is Nothing Then img = .Image
End With
@@ -131,8 +131,8 @@ Namespace DownloadObjects
End With
End With
If Job.Type = Download.SavedPosts And Not Job.Progress Is Nothing Then Job.Progress.InformationTemporary = Job.Host.Name
Instance = New API.Base.ProfileSaved(Job.Host, Job.Progress)
If Job.Type = Download.SavedPosts And Not Job.Progress Is Nothing Then Job.Progress.InformationTemporary = Job.HostCollection.Name
Instance = New API.Base.ProfileSaved(Job.HostCollection, Job.Progress)
End Sub
Private Sub CreateButton(ByRef BTT As Button, ByVal Img As Image)
BTT = New Button With {
@@ -154,7 +154,7 @@ Namespace DownloadObjects
[Stop]()
End Sub
Private Sub BTT_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_OPEN.Click
GlobalOpenPath(Job.Host.SavedPostsPath)
GlobalOpenPath(If(Job.HostCollection.FirstOrDefault(Function(h) h.DownloadSavedPosts), Job.HostCollection.Default).SavedPostsPath)
End Sub
#End Region
#Region "Start, Stop"
@@ -173,13 +173,13 @@ Namespace DownloadObjects
Try
btte.Invoke(BTT_START, False)
btte.Invoke(BTT_STOP, True)
Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading started"
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading started"
Job.Start()
Instance.Download(Job.Token, _IsMultiple)
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.Host.Name} posts is completed")
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.HostCollection.Name} posts is completed")
Catch ex As Exception
Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading error"
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Job.Host.Name} saved posts downloading error", "Saved posts"})
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading error"
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Job.HostCollection.Name} saved posts downloading error", "Saved posts"})
Finally
_IsMultiple = False
btte.Invoke(BTT_START, True)

View File

@@ -25,7 +25,7 @@ Friend Class DownloadSavedPostsForm
If Settings.Plugins.Count > 0 Then
Dim j As TDownloader.Job
For Each p As PluginHost In Settings.Plugins
If p.Settings.IsSavedPostsCompatible Then
If p.Settings.Default.IsSavedPostsCompatible Then
j = New TDownloader.Job(Plugin.ISiteSettings.Download.SavedPosts)
j.AddHost(p.Settings)
JobsList.Add(New DownloadProgress(j))

View File

@@ -26,12 +26,23 @@ Namespace DownloadObjects
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_VIEW As System.Windows.Forms.ToolStripDropDownButton
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadFeedForm))
Dim MENU_LOAD_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim MENU_LOAD_SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim MENU_LOAD_SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim MENU_LOAD_SEP_4 As System.Windows.Forms.ToolStripSeparator
Me.OPT_DEFAULT = New System.Windows.Forms.ToolStripMenuItem()
Me.OPT_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem()
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
Me.MENU_LOAD_SESSION = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_LOAD_SESSION_CURRENT = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_SESSION_LAST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_SESSION_CHOOSE = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_LOAD_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_REMOVE_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_ADD_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_REMOVE_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_0 = New System.Windows.Forms.ToolStripSeparator()
Me.MENU_DOWN = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_DOWN_ALL = New System.Windows.Forms.ToolStripMenuItem()
@@ -39,10 +50,18 @@ Namespace DownloadObjects
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
Me.BTT_CLEAR = New System.Windows.Forms.ToolStripButton()
Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel()
Me.BTT_LOAD_SESSION_CURRENT = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_CLEAR_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_CLEAR_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_DELETE_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_DELETE_DAILY_LIST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_DELETE_DAILY_DATE = New System.Windows.Forms.ToolStripMenuItem()
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
MENU_LOAD_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
MENU_LOAD_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
MENU_LOAD_SEP_3 = New System.Windows.Forms.ToolStripSeparator()
MENU_LOAD_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
Me.ToolbarTOP.SuspendLayout()
Me.SuspendLayout()
'
@@ -78,6 +97,21 @@ Namespace DownloadObjects
Me.OPT_SUBSCRIPTIONS.Size = New System.Drawing.Size(145, 22)
Me.OPT_SUBSCRIPTIONS.Text = "Subscriptions"
'
'MENU_LOAD_SEP_1
'
MENU_LOAD_SEP_1.Name = "MENU_LOAD_SEP_1"
MENU_LOAD_SEP_1.Size = New System.Drawing.Size(264, 6)
'
'MENU_LOAD_SEP_2
'
MENU_LOAD_SEP_2.Name = "MENU_LOAD_SEP_2"
MENU_LOAD_SEP_2.Size = New System.Drawing.Size(264, 6)
'
'MENU_LOAD_SEP_3
'
MENU_LOAD_SEP_3.Name = "MENU_LOAD_SEP_3"
MENU_LOAD_SEP_3.Size = New System.Drawing.Size(264, 6)
'
'ToolbarTOP
'
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
@@ -90,27 +124,76 @@ Namespace DownloadObjects
'MENU_LOAD_SESSION
'
Me.MENU_LOAD_SESSION.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE})
Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_1, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_2, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_4, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE})
Me.MENU_LOAD_SESSION.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.MENU_LOAD_SESSION.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_LOAD_SESSION.Name = "MENU_LOAD_SESSION"
Me.MENU_LOAD_SESSION.Size = New System.Drawing.Size(29, 22)
Me.MENU_LOAD_SESSION.Text = "Load session"
'
'BTT_LOAD_SESSION_CURRENT
'
Me.BTT_LOAD_SESSION_CURRENT.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_LOAD_SESSION_CURRENT.Name = "BTT_LOAD_SESSION_CURRENT"
Me.BTT_LOAD_SESSION_CURRENT.Size = New System.Drawing.Size(267, 22)
Me.BTT_LOAD_SESSION_CURRENT.Text = "Load current session"
'
'BTT_LOAD_SESSION_LAST
'
Me.BTT_LOAD_SESSION_LAST.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_LOAD_SESSION_LAST.Name = "BTT_LOAD_SESSION_LAST"
Me.BTT_LOAD_SESSION_LAST.Size = New System.Drawing.Size(189, 22)
Me.BTT_LOAD_SESSION_LAST.Size = New System.Drawing.Size(267, 22)
Me.BTT_LOAD_SESSION_LAST.Text = "Load last session"
'
'BTT_LOAD_SESSION_CHOOSE
'
Me.BTT_LOAD_SESSION_CHOOSE.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_LOAD_SESSION_CHOOSE.Name = "BTT_LOAD_SESSION_CHOOSE"
Me.BTT_LOAD_SESSION_CHOOSE.Size = New System.Drawing.Size(189, 22)
Me.BTT_LOAD_SESSION_CHOOSE.Size = New System.Drawing.Size(267, 22)
Me.BTT_LOAD_SESSION_CHOOSE.Text = "Select loading session"
'
'BTT_LOAD_FAV
'
Me.BTT_LOAD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
Me.BTT_LOAD_FAV.Name = "BTT_LOAD_FAV"
Me.BTT_LOAD_FAV.Size = New System.Drawing.Size(267, 22)
Me.BTT_LOAD_FAV.Text = "Load Favorite"
'
'BTT_LOAD_SPEC
'
Me.BTT_LOAD_SPEC.Image = Global.SCrawler.My.Resources.Resources.RSSPic_512
Me.BTT_LOAD_SPEC.Name = "BTT_LOAD_SPEC"
Me.BTT_LOAD_SPEC.Size = New System.Drawing.Size(267, 22)
Me.BTT_LOAD_SPEC.Text = "Load special feed"
'
'BTT_FEED_ADD_FAV
'
Me.BTT_FEED_ADD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
Me.BTT_FEED_ADD_FAV.Name = "BTT_FEED_ADD_FAV"
Me.BTT_FEED_ADD_FAV.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_ADD_FAV.Text = "Add checked to Favorite"
'
'BTT_FEED_REMOVE_FAV
'
Me.BTT_FEED_REMOVE_FAV.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_REMOVE_FAV.Name = "BTT_FEED_REMOVE_FAV"
Me.BTT_FEED_REMOVE_FAV.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_REMOVE_FAV.Text = "Remove checked from Favorite"
'
'BTT_FEED_ADD_SPEC
'
Me.BTT_FEED_ADD_SPEC.Image = Global.SCrawler.My.Resources.Resources.RSSPic_512
Me.BTT_FEED_ADD_SPEC.Name = "BTT_FEED_ADD_SPEC"
Me.BTT_FEED_ADD_SPEC.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_ADD_SPEC.Text = "Add checked to special feed..."
'
'BTT_FEED_REMOVE_SPEC
'
Me.BTT_FEED_REMOVE_SPEC.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_REMOVE_SPEC.Name = "BTT_FEED_REMOVE_SPEC"
Me.BTT_FEED_REMOVE_SPEC.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_REMOVE_SPEC.Text = "Remove checked from special feed..."
'
'SEP_0
'
Me.SEP_0.Name = "SEP_0"
@@ -186,12 +269,45 @@ Namespace DownloadObjects
Me.TP_DATA.Size = New System.Drawing.Size(484, 436)
Me.TP_DATA.TabIndex = 1
'
'BTT_LOAD_SESSION_CURRENT
'MENU_LOAD_SEP_4
'
Me.BTT_LOAD_SESSION_CURRENT.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_LOAD_SESSION_CURRENT.Name = "BTT_LOAD_SESSION_CURRENT"
Me.BTT_LOAD_SESSION_CURRENT.Size = New System.Drawing.Size(189, 22)
Me.BTT_LOAD_SESSION_CURRENT.Text = "Load current session"
MENU_LOAD_SEP_4.Name = "MENU_LOAD_SEP_4"
MENU_LOAD_SEP_4.Size = New System.Drawing.Size(264, 6)
'
'BTT_FEED_CLEAR_FAV
'
Me.BTT_FEED_CLEAR_FAV.Image = Global.SCrawler.My.Resources.Resources.BrushToolPic_16
Me.BTT_FEED_CLEAR_FAV.Name = "BTT_FEED_CLEAR_FAV"
Me.BTT_FEED_CLEAR_FAV.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_CLEAR_FAV.Text = "Clear Favorite"
'
'BTT_FEED_CLEAR_SPEC
'
Me.BTT_FEED_CLEAR_SPEC.Image = Global.SCrawler.My.Resources.Resources.BrushToolPic_16
Me.BTT_FEED_CLEAR_SPEC.Name = "BTT_FEED_CLEAR_SPEC"
Me.BTT_FEED_CLEAR_SPEC.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_CLEAR_SPEC.Text = "Clear special feed..."
'
'BTT_FEED_DELETE_SPEC
'
Me.BTT_FEED_DELETE_SPEC.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_DELETE_SPEC.Name = "BTT_FEED_DELETE_SPEC"
Me.BTT_FEED_DELETE_SPEC.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_DELETE_SPEC.Text = "Delete special feed..."
'
'BTT_FEED_DELETE_DAILY_LIST
'
Me.BTT_FEED_DELETE_DAILY_LIST.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_DELETE_DAILY_LIST.Name = "BTT_FEED_DELETE_DAILY_LIST"
Me.BTT_FEED_DELETE_DAILY_LIST.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_DELETE_DAILY_LIST.Text = "Delete daily feed (by list)"
'
'BTT_FEED_DELETE_DAILY_DATE
'
Me.BTT_FEED_DELETE_DAILY_DATE.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_DELETE_DAILY_DATE.Name = "BTT_FEED_DELETE_DAILY_DATE"
Me.BTT_FEED_DELETE_DAILY_DATE.Size = New System.Drawing.Size(267, 22)
Me.BTT_FEED_DELETE_DAILY_DATE.Text = "Delete daily feed (by date)"
'
'DownloadFeedForm
'
@@ -227,5 +343,16 @@ Namespace DownloadObjects
Private WithEvents BTT_DOWN_ALL As ToolStripMenuItem
Private WithEvents BTT_DOWN_SELECTED As ToolStripMenuItem
Private WithEvents BTT_LOAD_SESSION_CURRENT As ToolStripMenuItem
Private WithEvents BTT_FEED_ADD_FAV As ToolStripMenuItem
Private WithEvents BTT_FEED_REMOVE_FAV As ToolStripMenuItem
Private WithEvents BTT_FEED_ADD_SPEC As ToolStripMenuItem
Private WithEvents BTT_FEED_REMOVE_SPEC As ToolStripMenuItem
Private WithEvents BTT_LOAD_FAV As ToolStripMenuItem
Private WithEvents BTT_LOAD_SPEC As ToolStripMenuItem
Private WithEvents BTT_FEED_CLEAR_FAV As ToolStripMenuItem
Private WithEvents BTT_FEED_CLEAR_SPEC As ToolStripMenuItem
Private WithEvents BTT_FEED_DELETE_SPEC As ToolStripMenuItem
Private WithEvents BTT_FEED_DELETE_DAILY_LIST As ToolStripMenuItem
Private WithEvents BTT_FEED_DELETE_DAILY_DATE As ToolStripMenuItem
End Class
End Namespace

View File

@@ -135,7 +135,19 @@
MeQCkYEBAD3tUdo+/cEPAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="MENU_LOAD_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_LOAD_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_LOAD_SEP_3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="MENU_LOAD_SEP_4.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -13,6 +13,7 @@ Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Tools
Imports RCI = PersonalUtilities.Forms.Toolbars.RangeSwitcherToolbar.ControlItem
Imports UserMediaD = SCrawler.DownloadObjects.TDownloader.UserMediaD
Imports DTSModes = PersonalUtilities.Forms.DateTimeSelectionForm.Modes
Namespace DownloadObjects
Friend Class DownloadFeedForm
#Region "Declarations"
@@ -26,6 +27,8 @@ Namespace DownloadObjects
Private ReadOnly FilterSubscriptions As New FPredicate(Of UserMediaD)(Function(d) If(d.User?.IsSubscription, False))
Private ReadOnly FilterUsers As New FPredicate(Of UserMediaD)(Function(d) Not FilterSubscriptions.Invoke(d))
Private ReadOnly FileNotExist As New FPredicate(Of UserMediaD)(Function(d) Not d.Data.File.Exists And Not FilterSubscriptions.Invoke(d))
Private ReadOnly SessionDateStringProvider As New CustomProvider(Function(v As SFile) AConvert(Of String)(AConvert(Of Date)(v.Name, SessionDateTimeProvider, v.Name),
DateTimeDefaultProvider, v.Name))
Private BttRefreshToolTipText As String = "Refresh data list"
Private CenterImage As Boolean = False
Private NumberOfVisibleImages As Integer = 1
@@ -66,6 +69,22 @@ Namespace DownloadObjects
End With
ToolbarTOP.Items.AddRange({New ToolStripSeparator, BTT_DELETE_SELECTED})
With Settings
With .Feeds
.Load()
AddHandler .FeedAdded, AddressOf Feed_FeedAdded
AddHandler .FeedRemoved, AddressOf Feed_FeedRemoved
If .Count > 0 Then
For Each feed As FeedSpecial In .Self
If Not feed.IsFavorite Then
AddNewFeedItem(BTT_LOAD_SPEC, feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_LOAD)
AddNewFeedItem(BTT_FEED_ADD_SPEC, feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_ADD)
AddNewFeedItem(BTT_FEED_REMOVE_SPEC, feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_REMOVE)
AddNewFeedItem(BTT_FEED_DELETE_SPEC, feed, My.Resources.DeletePic_24, AddressOf Feed_SPEC_DELETE)
AddNewFeedItem(BTT_FEED_CLEAR_SPEC, feed, My.Resources.BrushToolPic_16, AddressOf Feed_SPEC_CLEAR)
End If
Next
End If
End With
If .FeedOpenLastMode Then
If .FeedLastModeSubscriptions Then OPT_SUBSCRIPTIONS.Checked = True Else OPT_DEFAULT.Checked = True
Else
@@ -93,6 +112,94 @@ Namespace DownloadObjects
If e.KeyCode = Keys.F5 Then RefillList() : e.Handled = True
End Sub
#End Region
#Region "Feeds handlers"
Private Overloads Sub AddNewFeedItem(ByVal Destination As ToolStripMenuItem, ByVal Feed As FeedSpecial, ByVal Image As Image,
ByVal Handler As EventHandler, Optional ByVal Insert As Boolean = False)
AddNewFeedItem(Destination, ToolbarTOP, Feed, Image, Handler, Insert)
End Sub
Friend Overloads Shared Function AddNewFeedItem(ByVal Destination As ToolStripMenuItem, ByVal Toolbar As ToolStrip,
ByVal Feed As FeedSpecial, ByVal Image As Image,
ByVal Handler As EventHandler, Optional ByVal Insert As Boolean = False) As ToolStripMenuItem
Dim item As New ToolStripMenuItem(Feed.Name, Image) With {.Tag = Feed}
If Not Handler Is Nothing Then AddHandler item.Click, Handler
ControlInvokeFast(Toolbar, Destination, Sub()
If Destination.DropDownItems.Count > 0 And Insert Then
Destination.DropDownItems.Insert(0, item)
Else
Destination.DropDownItems.Add(item)
End If
End Sub, EDP.None)
Return item
End Function
Private Sub Feed_FeedAdded(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
AddNewFeedItem(BTT_LOAD_SPEC, Feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_LOAD, True)
AddNewFeedItem(BTT_FEED_ADD_SPEC, Feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_ADD, True)
AddNewFeedItem(BTT_FEED_REMOVE_SPEC, Feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_REMOVE, True)
AddNewFeedItem(BTT_FEED_DELETE_SPEC, Feed, My.Resources.DeletePic_24, AddressOf Feed_SPEC_DELETE, True)
AddNewFeedItem(BTT_FEED_CLEAR_SPEC, Feed, My.Resources.BrushToolPic_16, AddressOf Feed_SPEC_CLEAR, True)
End Sub
Private Overloads Sub Feed_FeedRemoved(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
Feed_FeedRemoved(BTT_LOAD_SPEC, Feed)
Feed_FeedRemoved(BTT_FEED_ADD_SPEC, Feed)
Feed_FeedRemoved(BTT_FEED_REMOVE_SPEC, Feed)
Feed_FeedRemoved(BTT_FEED_DELETE_SPEC, Feed)
Feed_FeedRemoved(BTT_FEED_CLEAR_SPEC, Feed)
End Sub
Private Overloads Sub Feed_FeedRemoved(ByVal Destination As ToolStripMenuItem, ByVal Feed As FeedSpecial)
Feed_FeedRemoved(Destination, ToolbarTOP, Feed)
End Sub
Friend Overloads Shared Sub Feed_FeedRemoved(ByVal Destination As ToolStripMenuItem, ByVal Toolbar As ToolStrip, ByVal Feed As FeedSpecial)
Try
With Destination
ControlInvokeFast(Toolbar, .Self,
Sub()
If .DropDownItems.Count > 0 Then
Dim item As Object
For i% = .DropDownItems.Count - 1 To 0 Step -1
item = .DropDownItems(i)
If TypeOf item Is ToolStripMenuItem AndAlso Feed.Equals(DirectCast(item, ToolStripMenuItem).Tag) Then
With DirectCast(item, ToolStripMenuItem) : .Tag = Nothing : .Dispose() : End With
'.DropDownItems.RemoveAt(i)
End If
Next
End If
End Sub, EDP.None)
End With
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "Feed removed")
MainFrameObj.UpdateLogButton()
End Try
End Sub
Private Sub Feed_SPEC_LOAD(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then
DataList.Clear()
If f.Count > 0 Then DataList.ListAddList(f) : CleanDataList()
RefillList(False)
End If
End Sub
Private Sub Feed_SPEC_ADD(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then f.Add(GetCheckedMedia())
End Sub
Private Sub Feed_SPEC_CLEAR(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then
If MsgBoxE({$"Are you sure you want to clear the '{f.Name}' feed?", "Clear feed"}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then f.Clear()
End If
End Sub
Private Sub Feed_SPEC_REMOVE(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then f.Remove(GetCheckedMedia())
End Sub
Private Sub Feed_SPEC_DELETE(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then
If MsgBoxE({$"Are you sure you want to delete the '{f.Name}' feed?", "Delete feed"}, vbExclamation,,, {"Process", "Cancel"}) = 0 AndAlso
f.Delete() Then Feed_FeedRemoved(Settings.Feeds, f)
End If
End Sub
#End Region
#Region "Settings"
Friend Sub UpdateSettings()
With Settings
@@ -151,13 +258,6 @@ Namespace DownloadObjects
End Sub
#End Region
#Region "Refill"
Friend Sub Downloader_FilesChanged(ByVal Added As Boolean)
ControlInvokeFast(ToolbarTOP, BTT_REFRESH, Sub() BTT_REFRESH.ToolTipText = If(Added, "New files found", "Some files have been removed"))
BTT_REFRESH.ControlChangeColor(ToolbarTOP, Added, False)
End Sub
Private Sub BTT_REFRESH_Click(sender As Object, e As EventArgs) Handles BTT_REFRESH.Click
RefillList()
End Sub
Private Sub RefillList(Optional ByVal RefillDataList As Boolean = True)
DataPopulated = False
If RefillDataList Then
@@ -176,11 +276,20 @@ Namespace DownloadObjects
MyRange_IndexChanged(MyRange, Nothing)
End If
End Sub
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
Downloader.Files.Clear()
ClearTable()
RefillList()
Private Sub CleanDataList()
If DataList.Count > 0 Then
If IsSubscription Then
DataList.RemoveAll(FilterUsers)
Else
DataList.RemoveAll(FilterSubscriptions)
DataList.RemoveAll(FileNotExist)
End If
End If
End Sub
#End Region
#Region "Toolbar controls"
#Region "Feed"
#Region "Load"
Private Sub BTT_LOAD_SESSION_CURRENT_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_SESSION_CURRENT.Click
RefillList()
End Sub
@@ -190,7 +299,8 @@ Namespace DownloadObjects
Private Sub BTT_LOAD_SESSION_CHOOSE_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_SESSION_CHOOSE.Click
SessionChooser(False)
End Sub
Private Sub SessionChooser(ByVal GetLast As Boolean)
Private Sub SessionChooser(ByVal GetLast As Boolean, Optional ByVal GetFilesOnly As Boolean = False,
Optional ByRef ResultFilesList As List(Of SFile) = Nothing)
Try
Downloader.ClearSessions()
Dim f As SFile = TDownloader.SessionsPath.CSFileP
@@ -198,16 +308,9 @@ Namespace DownloadObjects
Dim m As New MMessage("Saved sessions not selected", "Sessions",, vbExclamation)
Dim x As XmlFile
Dim lcr As New ListAddParams(LAP.NotContainsOnly + LAP.IgnoreICopier)
Dim __clearList As Action = Sub()
If IsSubscription Then
DataList.RemoveAll(FilterUsers)
Else
DataList.RemoveAll(FilterSubscriptions)
DataList.RemoveAll(FileNotExist)
End If
End Sub
Dim __getFiles As Func(Of Boolean) = Function() As Boolean
If f.Exists(SFO.Path, False) Then fList = SFile.GetFiles(f, "*.xml",, EDP.ReturnValue)
If fList.ListExists Then fList.RemoveAll(Settings.Feeds.FeedSpecialRemover)
If fList.ListExists Then
fList.Reverse()
Return True
@@ -216,27 +319,32 @@ Namespace DownloadObjects
End If
End Function
If Not GetLast Then __getFiles.Invoke
If Not GetLast AndAlso fList.ListExists Then
If Not GetLast And GetFilesOnly And Not fList.ListExists Then
MsgBoxE({"No session files found", "Get session files"}, vbExclamation)
ElseIf Not GetLast AndAlso fList.ListExists Then
Using chooser As New SimpleListForm(Of SFile)(fList, Settings.Design) With {
.FormText = "Sessions",
.Icon = My.Resources.ArrowDownIcon_Blue_24,
.Mode = SimpleListFormModes.CheckedItems,
.Provider = New CustomProvider(Function(v As SFile) AConvert(Of String)(AConvert(Of Date)(v.Name, SessionDateTimeProvider, v.Name),
DateTimeDefaultProvider, v.Name))
.Provider = SessionDateStringProvider
}
chooser.ClearButtons()
If chooser.ShowDialog = DialogResult.OK Then
fList = chooser.DataResult
If fList.ListExists Then
DataList.Clear()
For Each f In fList
x = New XmlFile(f,, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Count > 0 Then DataList.ListAddList(x, lcr)
x.Dispose()
Next
__clearList.Invoke
RefillList(False)
If GetFilesOnly Then
ResultFilesList.AddRange(fList)
Else
DataList.Clear()
For Each f In fList
x = New XmlFile(f,, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Count > 0 Then DataList.ListAddList(x, lcr)
x.Dispose()
Next
CleanDataList()
RefillList(False)
End If
Else
MsgBoxE(m)
End If
@@ -254,7 +362,7 @@ Namespace DownloadObjects
x.LoadData()
If x.Count > 0 Then DataList.Clear() : DataList.ListAddList(x, lcr)
x.Dispose()
__clearList.Invoke
CleanDataList()
RefillList(False)
Else
m.Text = "Saved sessions not found"
@@ -265,6 +373,147 @@ Namespace DownloadObjects
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"[DownloadObjects.DownloadFeedForm.SessionChooser({GetLast})]")
End Try
End Sub
#End Region
#Region "Load fav, spec"
Private Sub BTT_LOAD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_FAV.Click
DataList.Clear()
With Settings.Feeds.Favorite
.RemoveNotExist(FileNotExist)
If .Count > 0 Then DataList.AddRange(.Self) : CleanDataList() : RefillList(False)
End With
End Sub
Private Sub BTT_LOAD_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_LOAD_SPEC.Click
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then
DataList.Clear()
Dim d As New List(Of UserMediaD)
.ForEach(Sub(ByVal f As FeedSpecial)
f.RemoveNotExist(FileNotExist)
If f.Count > 0 Then d.AddRange(f)
End Sub)
If d.Count > 0 Then DataList.ListAddList(d.Distinct)
CleanDataList()
RefillList(False)
End If
End With
End Sub
#End Region
#Region "Add remove fav spec"
Private Sub BTT_FEED_ADD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_FEED_ADD_FAV.Click
Settings.Feeds.Favorite.Add(GetCheckedMedia())
End Sub
Private Sub BTT_FEED_REMOVE_FAV_Click(sender As Object, e As EventArgs) Handles BTT_FEED_REMOVE_FAV.Click
Settings.Feeds.Favorite.Remove(GetCheckedMedia())
End Sub
Private Sub BTT_FEED_ADD_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_ADD_SPEC.Click
Dim c As IEnumerable(Of UserMediaD) = GetCheckedMedia()
If c.ListExists Then
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then .ForEach(Sub(f) f.Add(c))
End With
Else
MsgBoxE({"You haven't selected media to add to your feed(s)", "Add to feed(s)"}, vbExclamation)
End If
End Sub
Private Sub BTT_FEED_REMOVE_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_REMOVE_SPEC.Click
Dim c As IEnumerable(Of UserMediaD) = GetCheckedMedia()
If c.ListExists Then
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then .ForEach(Sub(f) f.Remove(c))
End With
Else
MsgBoxE({"You haven't selected media to remove from your feed(s)", "Remove from feed(s)"}, vbExclamation)
End If
End Sub
Private Function GetCheckedMedia() As IEnumerable(Of UserMediaD)
Return ControlInvoke(Of IEnumerable(Of UserMediaD))(TP_DATA,
Function() As IEnumerable(Of UserMediaD)
If TP_DATA.Controls.Count > 0 Then
Return (From cnt As FeedMedia In TP_DATA.Controls Where cnt.Checked Select cnt.Media)
Else
Return New UserMediaD() {}
End If
End Function, New UserMediaD() {}, EDP.ReturnValue)
End Function
#End Region
#Region "Clear delete"
Private Sub BTT_FEED_CLEAR_FAV_Click(sender As Object, e As EventArgs) Handles BTT_FEED_CLEAR_FAV.Click
If MsgBoxE({"Are you sure you want to clear your Favorite feed?", "Clear feed"}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then _
Settings.Feeds.Favorite.Delete()
End Sub
Private Sub BTT_FEED_CLEAR_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_CLEAR_SPEC.Click
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then
If MsgBoxE({$"Are you sure you want to clear the following feeds?{vbCr}{vbCr}{ .ListToString(vbCr)}", "Clear feed"}, vbExclamation,,,
{"Process", "Cancel"}) = 0 Then .ForEach(Sub(f) f.Clear())
End If
End With
End Sub
Private Sub BTT_FEED_DELETE_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_DELETE_SPEC.Click
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then
If MsgBoxE({$"Are you sure you want to delete the following feeds?{vbCr}{vbCr}{ .ListToString(vbCr)}", "Delete feed"}, vbExclamation,,,
{"Process", "Cancel"}) = 0 Then .ForEach(Sub(f) f.Delete())
End If
End With
End Sub
Private Sub BTT_FEED_DELETE_DAILY_LIST_Click(sender As Object, e As EventArgs) Handles BTT_FEED_DELETE_DAILY_LIST.Click
Try
Dim l As New List(Of SFile)
SessionChooser(False, True, l)
If l.Count > 0 Then
If MsgBoxE({$"Are you sure you want to delete the following sessions?{vbCr}{vbCr}{l.ListToStringE(vbCr, SessionDateStringProvider)}", "Delete session"}, vbExclamation,,,
{"Process", "Cancel"}) = 0 Then
l.ForEach(Sub(f) f.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None))
MsgBoxE({"Sessions have been deleted", "Delete session"})
End If
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "Delete daily sessions (by list)")
MainFrameObj.UpdateLogButton()
End Try
End Sub
Private Sub BTT_FEED_DELETE_DAILY_DATE_Click(sender As Object, e As EventArgs) Handles BTT_FEED_DELETE_DAILY_DATE.Click
Try
Using f As New DateTimeSelectionForm(DTSModes.CheckBoxes + DTSModes.Date + DTSModes.Start + DTSModes.End, Settings.Design) With {
.DesignXMLNodeName = "SessionRemoverDateTimeForm"
}
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
Dim _dStart As Date? = f.MyDateStart
Dim _dEnd As Date? = f.MyDateEnd
If _dStart.HasValue Or _dEnd.HasValue Then
Dim dStart As Date = If(_dStart, Date.MinValue)
dStart = dStart.Date
Dim dEnd As Date = If(_dEnd, Date.MaxValue)
dEnd = dEnd.Date
Dim filesDir As SFile = TDownloader.SessionsPath.CSFileP
If filesDir.Exists(SFO.Path, False) Then
Dim files As List(Of SFile) = SFile.GetFiles(filesDir, "*.xml",, EDP.ReturnValue)
If files.ListExists Then files.RemoveAll(Settings.Feeds.FeedSpecialRemover)
If files.ListExists Then
Dim fd As IEnumerable(Of KeyValuePair(Of SFile, Date?)) =
files.Select(Function(ff) New KeyValuePair(Of SFile, Date?)(
ff, AConvert(Of Date)(ff.Name, SessionDateTimeProvider, AModes.Var, Nothing)))
If fd.ListExists Then
For Each optFile As KeyValuePair(Of SFile, Date?) In fd
If optFile.Value.HasValue AndAlso optFile.Value.Value.ValueBetween(dStart, dEnd) Then _
optFile.Key.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
Next
End If
End If
End If
End If
End If
End Using
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "Delete daily sessions (by date)")
MainFrameObj.UpdateLogButton()
End Try
End Sub
#End Region
#End Region
#Region "View modes"
Private Sub OPT_Click(ByVal Sender As ToolStripMenuItem, ByVal e As EventArgs) Handles OPT_DEFAULT.Click, OPT_SUBSCRIPTIONS.Click
Dim __refill As Boolean = False
ControlInvokeFast(ToolbarTOP, Sender,
@@ -283,6 +532,19 @@ Namespace DownloadObjects
End Sub, EDP.None)
If __refill Then RefillList()
End Sub
#End Region
Friend Sub Downloader_FilesChanged(ByVal Added As Boolean)
ControlInvokeFast(ToolbarTOP, BTT_REFRESH, Sub() BTT_REFRESH.ToolTipText = If(Added, "New files found", "Some files have been removed"))
BTT_REFRESH.ControlChangeColor(ToolbarTOP, Added, False)
End Sub
Private Sub BTT_REFRESH_Click(sender As Object, e As EventArgs) Handles BTT_REFRESH.Click
RefillList()
End Sub
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
Downloader.Files.Clear()
ClearTable()
RefillList()
End Sub
#End Region
#Region "Download"
Private Sub FeedMedia_Download(ByVal Sender As Object, ByVal e As EventArgs) Handles BTT_DOWN_ALL.Click, BTT_DOWN_SELECTED.Click
@@ -642,6 +904,9 @@ Namespace DownloadObjects
If TP_DATA.Controls.Count > 0 Then
For Each cnt As Control In TP_DATA.Controls : cnt.Dispose() : Next
TP_DATA.Controls.Clear()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.WaitForFullGCComplete()
End If
End Sub)
End Sub

View File

@@ -42,6 +42,11 @@ Namespace DownloadObjects
Me.ICON_SITE = New System.Windows.Forms.PictureBox()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.LBL_TITLE = New System.Windows.Forms.Label()
Me.CONTEXT_SEP_4 = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_ADD_SPEC = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_REMOVE_FAV = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_FEED_REMOVE_SPEC = New System.Windows.Forms.ToolStripMenuItem()
CONTEXT_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
CONTEXT_SEP_2 = New System.Windows.Forms.ToolStripSeparator()
TP_LBL = New System.Windows.Forms.TableLayoutPanel()
@@ -54,12 +59,12 @@ Namespace DownloadObjects
'CONTEXT_SEP_1
'
CONTEXT_SEP_1.Name = "CONTEXT_SEP_1"
CONTEXT_SEP_1.Size = New System.Drawing.Size(134, 6)
CONTEXT_SEP_1.Size = New System.Drawing.Size(217, 6)
'
'CONTEXT_SEP_2
'
CONTEXT_SEP_2.Name = "CONTEXT_SEP_2"
CONTEXT_SEP_2.Size = New System.Drawing.Size(134, 6)
CONTEXT_SEP_2.Size = New System.Drawing.Size(217, 6)
'
'TP_LBL
'
@@ -103,76 +108,76 @@ Namespace DownloadObjects
'
'CONTEXT_DATA
'
Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.CONTEXT_SEP_0, Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, CONTEXT_SEP_2, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, Me.CONTEXT_SEP_3, Me.BTT_CONTEXT_DELETE})
Me.CONTEXT_DATA.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_CONTEXT_DOWN, Me.CONTEXT_SEP_0, Me.BTT_CONTEXT_OPEN_MEDIA, Me.BTT_CONTEXT_OPEN_USER, CONTEXT_SEP_1, Me.BTT_CONTEXT_OPEN_USER_URL, Me.BTT_CONTEXT_OPEN_USER_POST, CONTEXT_SEP_2, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_REMOVE_FAV, Me.BTT_FEED_REMOVE_SPEC, Me.CONTEXT_SEP_3, Me.BTT_CONTEXT_FIND_USER, Me.BTT_CONTEXT_INFO, Me.CONTEXT_SEP_4, Me.BTT_CONTEXT_DELETE})
Me.CONTEXT_DATA.Name = "CONTEXT_PIC"
Me.CONTEXT_DATA.Size = New System.Drawing.Size(138, 204)
Me.CONTEXT_DATA.Size = New System.Drawing.Size(221, 320)
'
'BTT_CONTEXT_DOWN
'
Me.BTT_CONTEXT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_CONTEXT_DOWN.Name = "BTT_CONTEXT_DOWN"
Me.BTT_CONTEXT_DOWN.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_DOWN.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_DOWN.Text = "Download"
Me.BTT_CONTEXT_DOWN.Visible = False
'
'CONTEXT_SEP_0
'
Me.CONTEXT_SEP_0.Name = "CONTEXT_SEP_0"
Me.CONTEXT_SEP_0.Size = New System.Drawing.Size(134, 6)
Me.CONTEXT_SEP_0.Size = New System.Drawing.Size(217, 6)
Me.CONTEXT_SEP_0.Visible = False
'
'BTT_CONTEXT_OPEN_MEDIA
'
Me.BTT_CONTEXT_OPEN_MEDIA.Image = Global.SCrawler.My.Resources.Resources.FolderPic_32
Me.BTT_CONTEXT_OPEN_MEDIA.Name = "BTT_CONTEXT_OPEN_MEDIA"
Me.BTT_CONTEXT_OPEN_MEDIA.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_OPEN_MEDIA.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_OPEN_MEDIA.Text = "Open"
'
'BTT_CONTEXT_OPEN_USER
'
Me.BTT_CONTEXT_OPEN_USER.Image = Global.SCrawler.My.Resources.Resources.FolderPic_32
Me.BTT_CONTEXT_OPEN_USER.Name = "BTT_CONTEXT_OPEN_USER"
Me.BTT_CONTEXT_OPEN_USER.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_OPEN_USER.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_OPEN_USER.Text = "Open user"
'
'BTT_CONTEXT_OPEN_USER_URL
'
Me.BTT_CONTEXT_OPEN_USER_URL.Image = Global.SCrawler.My.Resources.Resources.GlobePic_32
Me.BTT_CONTEXT_OPEN_USER_URL.Name = "BTT_CONTEXT_OPEN_USER_URL"
Me.BTT_CONTEXT_OPEN_USER_URL.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_OPEN_USER_URL.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_OPEN_USER_URL.Text = "Open user"
'
'BTT_CONTEXT_OPEN_USER_POST
'
Me.BTT_CONTEXT_OPEN_USER_POST.Image = Global.SCrawler.My.Resources.Resources.GlobePic_32
Me.BTT_CONTEXT_OPEN_USER_POST.Name = "BTT_CONTEXT_OPEN_USER_POST"
Me.BTT_CONTEXT_OPEN_USER_POST.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_OPEN_USER_POST.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_OPEN_USER_POST.Text = "Open post"
'
'BTT_CONTEXT_FIND_USER
'
Me.BTT_CONTEXT_FIND_USER.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.BTT_CONTEXT_FIND_USER.Name = "BTT_CONTEXT_FIND_USER"
Me.BTT_CONTEXT_FIND_USER.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_FIND_USER.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_FIND_USER.Text = "Find user"
'
'BTT_CONTEXT_INFO
'
Me.BTT_CONTEXT_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.BTT_CONTEXT_INFO.Name = "BTT_CONTEXT_INFO"
Me.BTT_CONTEXT_INFO.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_INFO.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_INFO.Text = "Information"
'
'CONTEXT_SEP_3
'
Me.CONTEXT_SEP_3.Name = "CONTEXT_SEP_3"
Me.CONTEXT_SEP_3.Size = New System.Drawing.Size(134, 6)
Me.CONTEXT_SEP_3.Size = New System.Drawing.Size(217, 6)
'
'BTT_CONTEXT_DELETE
'
Me.BTT_CONTEXT_DELETE.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_CONTEXT_DELETE.Name = "BTT_CONTEXT_DELETE"
Me.BTT_CONTEXT_DELETE.Size = New System.Drawing.Size(137, 22)
Me.BTT_CONTEXT_DELETE.Size = New System.Drawing.Size(220, 22)
Me.BTT_CONTEXT_DELETE.Text = "Delete"
'
'ICON_SITE
@@ -212,6 +217,39 @@ Namespace DownloadObjects
Me.LBL_TITLE.Size = New System.Drawing.Size(140, 25)
Me.LBL_TITLE.TabIndex = 1
'
'CONTEXT_SEP_4
'
Me.CONTEXT_SEP_4.Name = "CONTEXT_SEP_4"
Me.CONTEXT_SEP_4.Size = New System.Drawing.Size(217, 6)
'
'BTT_FEED_ADD_FAV
'
Me.BTT_FEED_ADD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
Me.BTT_FEED_ADD_FAV.Name = "BTT_FEED_ADD_FAV"
Me.BTT_FEED_ADD_FAV.Size = New System.Drawing.Size(220, 22)
Me.BTT_FEED_ADD_FAV.Text = "Add to Favorite"
'
'BTT_FEED_ADD_SPEC
'
Me.BTT_FEED_ADD_SPEC.Image = Global.SCrawler.My.Resources.Resources.RSSPic_512
Me.BTT_FEED_ADD_SPEC.Name = "BTT_FEED_ADD_SPEC"
Me.BTT_FEED_ADD_SPEC.Size = New System.Drawing.Size(220, 22)
Me.BTT_FEED_ADD_SPEC.Text = "Add to special feed..."
'
'BTT_FEED_REMOVE_FAV
'
Me.BTT_FEED_REMOVE_FAV.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_REMOVE_FAV.Name = "BTT_FEED_REMOVE_FAV"
Me.BTT_FEED_REMOVE_FAV.Size = New System.Drawing.Size(220, 22)
Me.BTT_FEED_REMOVE_FAV.Text = "Remove from Favorite"
'
'BTT_FEED_REMOVE_SPEC
'
Me.BTT_FEED_REMOVE_SPEC.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
Me.BTT_FEED_REMOVE_SPEC.Name = "BTT_FEED_REMOVE_SPEC"
Me.BTT_FEED_REMOVE_SPEC.Size = New System.Drawing.Size(220, 22)
Me.BTT_FEED_REMOVE_SPEC.Text = "Remove from special feed..."
'
'FeedMedia
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
@@ -249,5 +287,10 @@ Namespace DownloadObjects
Private WithEvents BTT_CONTEXT_DOWN As ToolStripMenuItem
Private WithEvents CONTEXT_SEP_0 As ToolStripSeparator
Private WithEvents LBL_TITLE As Label
Private WithEvents BTT_FEED_ADD_FAV As ToolStripMenuItem
Private WithEvents BTT_FEED_ADD_SPEC As ToolStripMenuItem
Private WithEvents BTT_FEED_REMOVE_FAV As ToolStripMenuItem
Private WithEvents BTT_FEED_REMOVE_SPEC As ToolStripMenuItem
Private WithEvents CONTEXT_SEP_4 As ToolStripSeparator
End Class
End Namespace

View File

@@ -61,6 +61,7 @@ Namespace DownloadObjects
End Property
Private ReadOnly UserKey As String
Friend ReadOnly Post As UserMedia
Friend ReadOnly Media As UserMediaD
Friend Property Checked As Boolean
Get
Return CH_CHECKED.Checked
@@ -161,6 +162,7 @@ Namespace DownloadObjects
Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Height As Integer)
Try
InitializeComponent()
Me.Media = Media
IsSubscription = If(Media.User?.IsSubscription, False)
If IsSubscription Then
@@ -174,7 +176,7 @@ Namespace DownloadObjects
BTT_CONTEXT_DOWN.Visible = True
CONTEXT_SEP_0.Visible = True
BTT_CONTEXT_OPEN_USER.Visible = False
CONTEXT_SEP_3.Visible = False
CONTEXT_SEP_4.Visible = False
BTT_CONTEXT_DELETE.Visible = False
If Not Media.Data.URL.IsEmptyString Then
@@ -297,6 +299,22 @@ Namespace DownloadObjects
Else
Throw New ArgumentNullException With {.HelpLink = 1}
End If
If Settings.Feeds.FavoriteExists AndAlso Settings.Feeds.Favorite.Contains(Media) Then BTT_FEED_ADD_FAV.ControlChangeColor(True, False)
If Settings.FeedShowSpecialFeedsMediaItem Then
With Settings.Feeds
AddHandler .FeedAdded, AddressOf Feed_FeedAdded
AddHandler .FeedRemoved, AddressOf Feed_FeedRemoved
If .Count > 0 Then
For Each fItem As FeedSpecial In .Self
If Not fItem.IsFavorite Then
DownloadFeedForm.AddNewFeedItem(BTT_FEED_ADD_SPEC, CONTEXT_DATA, fItem, Nothing, AddressOf Feed_SPEC_ADD)
DownloadFeedForm.AddNewFeedItem(BTT_FEED_REMOVE_SPEC, CONTEXT_DATA, fItem, Nothing, AddressOf Feed_SPEC_REMOVE)
End If
Next
End If
End With
End If
Catch aex As ArgumentNullException When aex.HelpLink = 1
HasError = True
Catch tex As Threading.ThreadStateException
@@ -307,11 +325,38 @@ Namespace DownloadObjects
End Try
End Sub
#End Region
#Region "Feed handlers"
Private Sub Feed_FeedAdded(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
DownloadFeedForm.AddNewFeedItem(BTT_FEED_ADD_SPEC, CONTEXT_DATA, Feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_ADD, True)
DownloadFeedForm.AddNewFeedItem(BTT_FEED_REMOVE_SPEC, CONTEXT_DATA, Feed, My.Resources.RSSPic_512, AddressOf Feed_SPEC_REMOVE, True)
End Sub
Private Sub Feed_FeedRemoved(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
DownloadFeedForm.Feed_FeedRemoved(BTT_FEED_ADD_SPEC, CONTEXT_DATA, Feed)
DownloadFeedForm.Feed_FeedRemoved(BTT_FEED_REMOVE_SPEC, CONTEXT_DATA, Feed)
End Sub
Private Sub Feed_SPEC_ADD(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then f.Add(Media)
End Sub
Private Sub Feed_SPEC_REMOVE(ByVal Source As ToolStripMenuItem, ByVal e As EventArgs)
Dim f As FeedSpecial = Source.Tag
If Not f Is Nothing AndAlso Not f.Disposed Then f.Remove(Media)
End Sub
#End Region
#Region "Dispose"
Private Sub FeedImage_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
If Not MyImage Is Nothing Then MyImage.Dispose()
If Not MyPicture Is Nothing Then MyPicture.Dispose()
If Not MyPicture Is Nothing Then MyPicture.Dispose() : MyPicture = Nothing
If Not MyVideo Is Nothing Then MyVideo.Dispose()
Try
If Settings.FeedShowSpecialFeedsMediaItem Then
With Settings.Feeds
RemoveHandler .FeedAdded, AddressOf Feed_FeedAdded
RemoveHandler .FeedRemoved, AddressOf Feed_FeedRemoved
End With
End If
Catch
End Try
End Sub
#End Region
#Region "LBL"
@@ -336,9 +381,12 @@ Namespace DownloadObjects
End Sub
#End Region
#Region "Context"
#Region "Down"
Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click
RaiseEvent MediaDownload(Me, EventArgs.Empty)
End Sub
#End Region
#Region "Open media, folder"
Private Sub BTT_CONTEXT_OPEN_MEDIA_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_MEDIA.Click
File.Open()
End Sub
@@ -348,6 +396,8 @@ Namespace DownloadObjects
If Not u Is Nothing Then u.OpenFolder()
End If
End Sub
#End Region
#Region "Open URL"
Private Sub BTT_CONTEXT_OPEN_USER_URL_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER_URL.Click
If Not UserKey.IsEmptyString Then
Dim u As IUserData = Settings.GetUser(UserKey)
@@ -372,15 +422,44 @@ Namespace DownloadObjects
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, $"[FeedMedia.OpenPost({UserKey}, {Post.Post.ID})]")
End Try
End Sub
#End Region
#Region "Feed"
Private Sub BTT_FEED_ADD_FAV_Click(sender As Object, e As EventArgs) Handles BTT_FEED_ADD_FAV.Click
With Settings.Feeds.Favorite
If Not .Contains(Media) Then .Add(Media)
BTT_FEED_ADD_FAV.ControlChangeColor(True, False)
End With
End Sub
Private Sub BTT_FEED_ADD_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_ADD_SPEC.Click
With FeedSpecialCollection.ChooseFeeds(True)
If .ListExists Then .ForEach(Sub(f) f.Add(Media))
End With
End Sub
Private Sub BTT_FEED_REMOVE_FAV_Click(sender As Object, e As EventArgs) Handles BTT_FEED_REMOVE_FAV.Click
With Settings.Feeds.Favorite
If .Contains(Media) Then .Remove(Media)
BTT_FEED_ADD_FAV.ControlChangeColor(True)
End With
End Sub
Private Sub BTT_FEED_REMOVE_SPEC_Click(sender As Object, e As EventArgs) Handles BTT_FEED_REMOVE_SPEC.Click
With FeedSpecialCollection.ChooseFeeds(False)
If .ListExists Then .ForEach(Sub(f) f.Remove(Media))
End With
End Sub
#End Region
#Region "Info"
Private Sub BTT_CONTEXT_FIND_USER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_FIND_USER.Click
If Not UserKey.IsEmptyString Then MainFrameObj.FocusUser(UserKey, True)
End Sub
Private Sub BTT_CONTEXT_INFO_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_INFO.Click
MsgBoxE({Information, "Post information"})
End Sub
#End Region
#Region "Delete"
Private Sub BTT_CONTEXT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DELETE.Click
DeleteFile(False)
End Sub
#End Region
Friend Function DeleteFile(ByVal Silent As Boolean) As Boolean
Const msgTitle$ = "Deleting a file"
Try

View File

@@ -0,0 +1,252 @@
' 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.Tools
Imports PersonalUtilities.Functions.XML
Imports UserMediaD = SCrawler.DownloadObjects.TDownloader.UserMediaD
Namespace DownloadObjects
Friend Class FeedSpecial : Implements IEnumerable(Of UserMediaD), IMyEnumerator(Of UserMediaD), IDisposableSuspend
#Region "SEComparer"
Friend Class SEComparer : Implements IComparer(Of UserMediaD)
Friend Function Compare(ByVal x As UserMediaD, ByVal y As UserMediaD) As Integer Implements IComparer(Of UserMediaD).Compare
Dim v% = x.Date.Ticks.CompareTo(y.Date.Ticks) * -1
If v <> 0 Then Return v
v = If(x.User?.GetHashCode, 0).CompareTo(If(y.User?.GetHashCode, 0))
If v <> 0 Then Return v
Return 0
End Function
End Class
#End Region
#Region "Events"
Friend Event FeedDeleted As FeedSpecialCollection.FeedActionEventHandler
#End Region
#Region "Declarations"
Friend Const FavoriteName As String = "Favorite"
Friend Const SpecialName As String = "Special"
Private ReadOnly Items As List(Of UserMediaD)
Private _File As SFile
Friend ReadOnly Property File As SFile
Get
If _File.IsEmptyString AndAlso Not Name.IsEmptyString Then
If _IsFavorite Then
_File = $"{TDownloader.SessionsPath}{FavoriteName}.xml"
Else
_File = $"{TDownloader.SessionsPath}{SpecialName}_{Name}.xml"
End If
End If
Return _File
End Get
End Property
Private _IsFavorite As Boolean
Friend ReadOnly Property IsFavorite As Boolean
Get
Return _IsFavorite
End Get
End Property
Private _Name As String
Friend ReadOnly Property Name As String
Get
If _Name.IsEmptyString And IsFavorite Then
Return FavoriteName
Else
Return _Name
End If
End Get
End Property
#End Region
#Region "Initializers"
Private Sub New()
Items = New List(Of UserMediaD)
End Sub
Friend Sub New(ByVal f As SFile)
Me.New
_File = f
If Not File.Name.IsEmptyString Then
_IsFavorite = File.Name.StartsWith(FavoriteName)
If Not _IsFavorite Then _Name = File.Name.Split("_").ListTake(0, 100, EDP.ReturnValue).ListToString("").StringTrim.StringTrimStart("_")
End If
Load()
End Sub
Friend Shared Function CreateFavorite() As FeedSpecial
Return New FeedSpecial With {._IsFavorite = True}
End Function
Friend Shared Function CreateSpecial(ByVal Name As String) As FeedSpecial
Return New FeedSpecial With {._Name = Name}
End Function
Friend Sub Load()
If File.Exists Then
Using x As New XmlFile(File, Protector.Modes.All, False) With {.AllowSameNames = True}
x.LoadData()
If x.Count > 0 Then Items.ListAddList(x, LAP.IgnoreICopier)
End Using
End If
End Sub
#End Region
#Region "Data functions"
#Region "Item, Count"
Default Friend ReadOnly Property Item(ByVal Index As Integer) As UserMediaD Implements IMyEnumerator(Of UserMediaD).MyEnumeratorObject
Get
Return Items(Index)
End Get
End Property
Friend ReadOnly Property Count As Integer Implements IMyEnumerator(Of UserMediaD).MyEnumeratorCount
Get
Return Items.Count
End Get
End Property
#End Region
#Region "Clear, Sort, Save"
Friend Function Clear()
Dim result As Boolean = Count > 0
Items.Clear()
If result Then Save()
Return result
End Function
Friend Sub Sort()
If Count > 0 Then Items.Sort(Settings.Feeds.Comparer)
End Sub
Friend Sub Save()
If Not File.IsEmptyString Then
Sort()
Using x As New XmlFile With {.Name = "Feed", .AllowSameNames = True}
x.AddRange(Items)
x.Save(File, EDP.SendToLog)
End Using
End If
End Sub
#End Region
#Region "Add"
Friend Overloads Function Add(ByVal Item As UserMediaD, Optional ByVal AutoSave As Boolean = True) As Boolean
If Not Items.Contains(Item) Then
Items.Add(Item)
If AutoSave Then Save()
Return True
Else
Return False
End If
End Function
Friend Overloads Function Add(ByVal Items As IEnumerable(Of UserMediaD), Optional ByVal AutoSave As Boolean = True) As Integer
Dim ri% = 0
If Items.ListExists Then
For Each item As UserMediaD In Items : ri += Add(item, False).BoolToInteger : Next
If ri > 0 And AutoSave Then Save()
End If
Return ri
End Function
#End Region
#Region "Remove"
Friend Overloads Function Remove(ByVal Item As UserMediaD, Optional ByVal AutoSave As Boolean = True) As Boolean
If Count > 0 Then
Dim i% = Items.IndexOf(Item)
If i >= 0 Then
Items.RemoveAt(i)
If AutoSave Then Save()
Return True
End If
End If
Return False
End Function
Friend Overloads Function Remove(ByVal Items As IEnumerable(Of UserMediaD), Optional ByVal AutoSave As Boolean = True) As Integer
Dim ri% = 0
If Items.ListExists Then
For Each item As UserMediaD In Items : ri += Me.Items.Remove(item).BoolToInteger : Next
If ri > 0 And AutoSave Then Save()
End If
Return ri
End Function
Private _NotExistRemoved As Boolean = False
Friend Function RemoveNotExist(ByVal p As Predicate(Of UserMediaD)) As Integer
If Count > 0 And Not _NotExistRemoved Then
_NotExistRemoved = True
Dim ri% = Items.RemoveAll(p)
If ri > 0 Then Save()
Return ri
Else
Return 0
End If
End Function
#End Region
#Region "Delete"
Friend Overloads Function Delete() As Boolean
If File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.ReturnValue) Then
Items.Clear()
RaiseEvent FeedDeleted(Settings.Feeds, Me)
Return True
Else
Return False
End If
End Function
Friend Overloads Function Delete(ByVal Item As UserMediaD, Optional ByVal AutoSave As Boolean = True) As Boolean
Dim result As Boolean = False
If Item.Data.File.Exists Then result = Item.Data.File.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.ReturnValue)
If result And AutoSave Then Save()
Return result
End Function
#End Region
#Region "Contains"
Friend Function Contains(ByVal Item As UserMediaD) As Boolean
Return Items.Contains(Item)
End Function
#End Region
#End Region
#Region "Base Overrides"
Public Overrides Function ToString() As String
Return Name
End Function
Public Overrides Function GetHashCode() As Integer
Return Name.GetHashCode
End Function
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
If Not IsNothing(Obj) Then
If TypeOf Obj Is FeedSpecial Then
Return Name = DirectCast(Obj, FeedSpecial).Name
ElseIf TypeOf Obj Is String Then
Return Name = CStr(Obj)
End If
End If
Return False
End Function
#End Region
#Region "IEnumerable Support"
Private Function GetEnumerator() As IEnumerator(Of UserMediaD) Implements IEnumerable(Of UserMediaD).GetEnumerator
Return New MyEnumerator(Of UserMediaD)(Me)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
#End Region
#Region "IDisposable Support"
Friend Property DisposeSuspended As Boolean Implements IDisposableSuspend.DisposeSuspended
Get
Return IsFavorite
End Get
Private Set : End Set
End Property
Friend ReadOnly Property Disposed As Boolean Implements IDisposableSuspend.Disposed
Get
Return disposedValue
End Get
End Property
Private disposedValue As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not disposedValue Then
If disposing Then Items.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 Namespace

View File

@@ -0,0 +1,217 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms
Namespace DownloadObjects
Friend Class FeedSpecialCollection : Implements IEnumerable(Of FeedSpecial), IMyEnumerator(Of FeedSpecial)
#Region "Events"
Friend Delegate Sub FeedActionEventHandler(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
Private ReadOnly FeedAddedEventHandlers As List(Of FeedActionEventHandler)
Friend Custom Event FeedAdded As FeedActionEventHandler
AddHandler(ByVal h As FeedActionEventHandler)
If Not FeedAddedEventHandlers.Contains(h) Then FeedAddedEventHandlers.Add(h)
End AddHandler
RemoveHandler(ByVal h As FeedActionEventHandler)
FeedAddedEventHandlers.Remove(h)
End RemoveHandler
RaiseEvent(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
If FeedAddedEventHandlers.Count > 0 Then
Try
For i% = 0 To FeedAddedEventHandlers.Count - 1
Try : FeedAddedEventHandlers(i).Invoke(Source, Feed) : Catch : End Try
Next
Catch
End Try
End If
End RaiseEvent
End Event
Private ReadOnly FeedRemovedEventHandlers As List(Of FeedActionEventHandler)
Friend Custom Event FeedRemoved As FeedActionEventHandler
AddHandler(ByVal h As FeedActionEventHandler)
If Not FeedRemovedEventHandlers.Contains(h) Then FeedRemovedEventHandlers.Add(h)
End AddHandler
RemoveHandler(ByVal h As FeedActionEventHandler)
FeedRemovedEventHandlers.Remove(h)
End RemoveHandler
RaiseEvent(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
If FeedRemovedEventHandlers.Count > 0 Then
Try
For i% = 0 To FeedRemovedEventHandlers.Count - 1
Try : FeedRemovedEventHandlers(i).Invoke(Source, Feed) : Catch : End Try
Next
Catch
End Try
End If
End RaiseEvent
End Event
#End Region
#Region "FeedsComparer"
Private Class FeedsComparer : Implements IComparer(Of FeedSpecial)
Friend Function Compare(ByVal x As FeedSpecial, ByVal y As FeedSpecial) As Integer Implements IComparer(Of FeedSpecial).Compare
If x.IsFavorite Then
Return -1
Else
Return x.Name.CompareTo(y.Name)
End If
End Function
End Class
#End Region
#Region "Declarations"
Private ReadOnly Feeds As List(Of FeedSpecial)
Private _Favorite As FeedSpecial = Nothing
Friend ReadOnly Property Favorite As FeedSpecial
Get
If _Favorite Is Nothing Then
_Favorite = FeedSpecial.CreateFavorite
_Favorite.Load()
Feeds.Add(_Favorite)
Feeds.Sort(ComparerFeeds)
End If
Return _Favorite
End Get
End Property
Friend ReadOnly Property FavoriteExists As Boolean
Get
Return Not _Favorite Is Nothing
End Get
End Property
Private _Loaded As Boolean = False
Friend ReadOnly Property Comparer As New FeedSpecial.SEComparer
Private ReadOnly Property ComparerFeeds As New FeedsComparer
Friend ReadOnly Property FeedSpecialRemover As Predicate(Of SFile) = Function(f) f.Name.StartsWith(FeedSpecial.FavoriteName) Or f.Name.StartsWith(FeedSpecial.SpecialName)
#End Region
#Region "Initializer, loader, feeds handlers"
Friend Sub New()
FeedAddedEventHandlers = New List(Of FeedActionEventHandler)
FeedRemovedEventHandlers = New List(Of FeedActionEventHandler)
Feeds = New List(Of FeedSpecial)
End Sub
Friend Sub Load()
Try
If Not _Loaded Then
_Loaded = True
Dim files As List(Of SFile) = SFile.GetFiles(TDownloader.SessionsPath, $"{FeedSpecial.FavoriteName}.xml|{FeedSpecial.SpecialName}_*.xml",, EDP.ReturnValue)
If files.ListExists Then files.ForEach(Sub(ByVal f As SFile)
Feeds.Add(New FeedSpecial(f))
With Feeds.Last
If .IsFavorite Then _Favorite = .Self
AddHandler .FeedDeleted, AddressOf Feeds_FeedDeleted
End With
End Sub) : files.Clear()
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[FeedSpecialCollection.Load]")
MainFrameObj.UpdateLogButton()
End Try
End Sub
Private Sub Feeds_FeedDeleted(ByVal Source As FeedSpecialCollection, ByVal Feed As FeedSpecial)
RaiseEvent FeedRemoved(Me, Feed)
If Count > 0 Then Feeds.Remove(Feed)
End Sub
#End Region
#Region "ChooseFeeds"
Friend Shared Function ChooseFeeds(ByVal AllowAdd As Boolean) As List(Of FeedSpecial)
Try
Dim newFeed$ = String.Empty
Using f As New SimpleListForm(Of String)(Settings.Feeds.Select(Function(ff) ff.Name), Settings.Design) With {
.DesignXMLNodeName = "FeedsChooserForm",
.Icon = My.Resources.RSSIcon_32,
.FormText = "Feeds"
}
If AllowAdd Then f.AddFunction = Sub(ByVal sender As Object, ByVal e As SimpleListFormEventArgs)
If newFeed.IsEmptyString Then
Dim nf$ = InputBoxE("Enter a new feed name:", "New feed")
If Not nf.IsEmptyString Then
If Settings.Feeds.ListExists(Function(ff) ff.Name.StringToLower = nf.ToLower) Then
MsgBoxE({$"A feed named '{nf}' already exists", "New feed"}, vbCritical)
Else
newFeed = nf
e.Item = nf
End If
Else
MsgBoxE({"You can only create one feed at a time", "New feed"}, vbCritical)
End If
End If
End Sub
If f.ShowDialog = DialogResult.OK AndAlso f.DataResult.Count > 0 Then
If Not newFeed.IsEmptyString AndAlso f.DataResult.Contains(newFeed) Then Settings.Feeds.Add(newFeed)
Return Settings.Feeds.Where(Function(ff) f.DataResult.Contains(ff.Name)).ToList
End If
End Using
Return Nothing
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[FeedSpecialCollection.ChooseFeeds]")
End Try
End Function
#End Region
#Region "Item, Count"
Default Friend ReadOnly Property Item(ByVal Index As Integer) As FeedSpecial Implements IMyEnumerator(Of FeedSpecial).MyEnumeratorObject
Get
Return Feeds(Index)
End Get
End Property
Friend ReadOnly Property Count As Integer Implements IMyEnumerator(Of FeedSpecial).MyEnumeratorCount
Get
Return Feeds.Count
End Get
End Property
#End Region
#Region "Add, Delete"
Friend Function Add(ByVal Name As String) As Integer
Dim i% = -1
If Not Name.IsEmptyString Then
If Count = 0 Then
Feeds.Add(FeedSpecial.CreateSpecial(Name))
Feeds.Last.Save()
i = Count - 1
Else
i = Feeds.FindIndex(Function(f) f.Name = Name)
If i = -1 Then
Feeds.Add(FeedSpecial.CreateSpecial(Name))
Feeds.Last.Save()
i = Count - 1
End If
End If
End If
If i >= 0 Then
Feeds.Sort(ComparerFeeds)
i = Feeds.FindIndex(Function(f) f.Name = Name)
If i >= 0 Then RaiseEvent FeedAdded(Me, Feeds(i))
End If
Return i
End Function
Friend Function Delete(ByVal Item As FeedSpecial) As Boolean
Dim result As Boolean = False
Dim i% = Feeds.IndexOf(Item)
If i >= 0 Then
With Feeds(i)
If .IsFavorite Then
result = .Clear
Else
result = .Delete
If result Then
.Dispose()
Feeds.RemoveAt(i)
End If
End If
End With
End If
Return result
End Function
#End Region
#Region "IEnumerable Support"
Private Function GetEnumerator() As IEnumerator(Of FeedSpecial) Implements IEnumerable(Of FeedSpecial).GetEnumerator
Return New MyEnumerator(Of FeedSpecial)(Me)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
#End Region
End Class
End Namespace

View File

@@ -32,8 +32,10 @@ Namespace DownloadObjects.STDownloader
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.TXT_URL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_PATH = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.CMB_ACCOUNT = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
@@ -41,6 +43,7 @@ Namespace DownloadObjects.STDownloader
TP_MAIN.SuspendLayout()
CType(Me.TXT_URL, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'CONTAINER_MAIN
@@ -49,13 +52,13 @@ Namespace DownloadObjects.STDownloader
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(484, 84)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(484, 88)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
CONTAINER_MAIN.RightToolStripPanelVisible = False
CONTAINER_MAIN.Size = New System.Drawing.Size(484, 84)
CONTAINER_MAIN.Size = New System.Drawing.Size(484, 113)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
@@ -64,17 +67,18 @@ Namespace DownloadObjects.STDownloader
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Controls.Add(Me.TXT_URL, 0, 0)
TP_MAIN.Controls.Add(Me.TXT_PATH, 0, 1)
TP_MAIN.Controls.Add(Me.CMB_ACCOUNT, 0, 2)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowCount = 4
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Size = New System.Drawing.Size(484, 84)
TP_MAIN.Size = New System.Drawing.Size(484, 88)
TP_MAIN.TabIndex = 0
'
'TXT_URL
@@ -84,7 +88,7 @@ Namespace DownloadObjects.STDownloader
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_URL.Buttons.Add(ActionButton1)
Me.TXT_URL.CaptionText = "URL"
Me.TXT_URL.CaptionWidth = 40.0R
Me.TXT_URL.CaptionWidth = 50.0R
Me.TXT_URL.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_URL.Location = New System.Drawing.Point(4, 4)
Me.TXT_URL.Name = "TXT_URL"
@@ -116,7 +120,7 @@ Namespace DownloadObjects.STDownloader
Me.TXT_PATH.CaptionToolTipEnabled = True
Me.TXT_PATH.CaptionToolTipText = "Output path"
Me.TXT_PATH.CaptionVisible = True
Me.TXT_PATH.CaptionWidth = 40.0R
Me.TXT_PATH.CaptionWidth = 50.0R
ListColumn1.Name = "COL_NAME"
ListColumn1.Text = "Name"
ListColumn1.Width = -1
@@ -135,19 +139,38 @@ Namespace DownloadObjects.STDownloader
Me.TXT_PATH.TabIndex = 1
Me.TXT_PATH.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'CMB_ACCOUNT
'
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Name = "ArrowDown"
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_ACCOUNT.Buttons.Add(ActionButton6)
Me.CMB_ACCOUNT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.CMB_ACCOUNT.CaptionText = "Account"
Me.CMB_ACCOUNT.CaptionToolTipEnabled = True
Me.CMB_ACCOUNT.CaptionToolTipText = "Select an account to download this media"
Me.CMB_ACCOUNT.CaptionVisible = True
Me.CMB_ACCOUNT.CaptionWidth = 50.0R
Me.CMB_ACCOUNT.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_ACCOUNT.Location = New System.Drawing.Point(4, 62)
Me.CMB_ACCOUNT.Name = "CMB_ACCOUNT"
Me.CMB_ACCOUNT.Size = New System.Drawing.Size(476, 22)
Me.CMB_ACCOUNT.TabIndex = 2
Me.CMB_ACCOUNT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'DownloaderUrlForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(484, 84)
Me.ClientSize = New System.Drawing.Size(484, 113)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.Resources.ArrowDownIcon_Blue_24
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(500, 123)
Me.MaximumSize = New System.Drawing.Size(500, 152)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(500, 123)
Me.MinimumSize = New System.Drawing.Size(500, 152)
Me.Name = "DownloaderUrlForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
@@ -158,10 +181,12 @@ Namespace DownloadObjects.STDownloader
TP_MAIN.ResumeLayout(False)
CType(Me.TXT_URL, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_PATH, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_URL As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_PATH As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents CMB_ACCOUNT As PersonalUtilities.Forms.Controls.ComboBoxExtended
End Class
End Namespace

View File

@@ -261,6 +261,96 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
AAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
</root>

View File

@@ -14,6 +14,11 @@ Namespace DownloadObjects.STDownloader
Private WithEvents MyDefs As DefaultFormOptions
Friend Property URL As String
Friend Property OutputPath As SFile
Friend ReadOnly Property AccountName As String
Get
Return CMB_ACCOUNT.Text
End Get
End Property
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
@@ -26,6 +31,7 @@ Namespace DownloadObjects.STDownloader
Settings.DownloadLocations.PopulateComboBox(TXT_PATH)
TXT_PATH.Text = Settings.LatestSavingPath.Value
If TXT_PATH.Text.IsEmptyString Then TXT_PATH.Text = Application.StartupPath.CSFileP.PathWithSeparator
TXT_URL_ActionOnTextChanged()
.MyFieldsChecker = New FieldsChecker
With .MyFieldsCheckerE
.AddControl(Of String)(TXT_URL, TXT_URL.CaptionText)
@@ -54,6 +60,36 @@ Namespace DownloadObjects.STDownloader
MyDefs.CloseForm()
End If
End Sub
Friend Shared Function GetMediaPluginKey(ByVal URL As String) As String
If Not URL.IsEmptyString Then
Return Settings.Plugins.Select(Function(p) p.Settings.IsMyImageVideo(URL).HostKey).FirstOrDefault(Function(p) Not p.IsEmptyString)
Else
Return String.Empty
End If
End Function
Private Sub TXT_URL_ActionOnTextChanged() Handles TXT_URL.ActionOnTextChanged
Try
With CMB_ACCOUNT
.BeginUpdate()
.Items.Clear()
.Text = String.Empty
If Not TXT_URL.Text.IsEmptyString Then
Dim plugin$ = Settings.Plugins.Select(Function(p) p.Settings.IsMyImageVideo(TXT_URL.Text).HostKey).FirstOrDefault(Function(p) Not p.IsEmptyString)
If Not plugin.IsEmptyString Then _
CMB_ACCOUNT.Items.AddRange(Settings(plugin).Select(Function(p) New ListItem(p.AccountName.IfNullOrEmpty(
SCrawler.Plugin.Hosts.SettingsHost.NameAccountNameDefault))))
End If
.LeaveDefaultButtons = .Items.Count > 1
.Buttons.UpdateButtonsPositions()
.EndUpdate()
If .Items.Count > 0 Then .SelectedIndex = 0
.Enabled = .Items.Count > 1
End With
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[STDownloader.DownloaderUrlForm.TXT_URL_ActionOnTextChanged]")
MainFrameObj.UpdateLogButton()
End Try
End Sub
Private Sub TXT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_PATH.ActionOnButtonClick
If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _
Settings.DownloadLocations.ChooseNewLocation(TXT_PATH, Sender.DefaultButton = ADB.Add, Settings.STDownloader_OutputPathAskForName)

View File

@@ -32,8 +32,10 @@ Namespace DownloadObjects.STDownloader
Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim FRM_URLS As System.Windows.Forms.GroupBox
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.TXT_OUTPUT = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
Me.TXT_URLS = New System.Windows.Forms.RichTextBox()
Me.CMB_ACCOUNT = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
FRM_URLS = New System.Windows.Forms.GroupBox()
@@ -42,6 +44,7 @@ Namespace DownloadObjects.STDownloader
TP_MAIN.SuspendLayout()
CType(Me.TXT_OUTPUT, System.ComponentModel.ISupportInitialize).BeginInit()
FRM_URLS.SuspendLayout()
CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'CONTAINER_MAIN
@@ -50,7 +53,7 @@ Namespace DownloadObjects.STDownloader
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 261)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 236)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
@@ -64,16 +67,17 @@ Namespace DownloadObjects.STDownloader
'
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Controls.Add(Me.TXT_OUTPUT, 0, 0)
TP_MAIN.Controls.Add(FRM_URLS, 0, 1)
TP_MAIN.Controls.Add(FRM_URLS, 0, 2)
TP_MAIN.Controls.Add(Me.CMB_ACCOUNT, 0, 1)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 2
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Size = New System.Drawing.Size(384, 261)
TP_MAIN.Size = New System.Drawing.Size(384, 236)
TP_MAIN.TabIndex = 0
'
'TXT_OUTPUT
@@ -120,10 +124,10 @@ Namespace DownloadObjects.STDownloader
'
FRM_URLS.Controls.Add(Me.TXT_URLS)
FRM_URLS.Dock = System.Windows.Forms.DockStyle.Fill
FRM_URLS.Location = New System.Drawing.Point(3, 31)
FRM_URLS.Location = New System.Drawing.Point(3, 59)
FRM_URLS.Name = "FRM_URLS"
FRM_URLS.Size = New System.Drawing.Size(378, 227)
FRM_URLS.TabIndex = 1
FRM_URLS.Size = New System.Drawing.Size(378, 174)
FRM_URLS.TabIndex = 2
FRM_URLS.TabStop = False
FRM_URLS.Text = "URLs (new line as delimiter)"
'
@@ -133,10 +137,29 @@ Namespace DownloadObjects.STDownloader
Me.TXT_URLS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_URLS.Location = New System.Drawing.Point(3, 16)
Me.TXT_URLS.Name = "TXT_URLS"
Me.TXT_URLS.Size = New System.Drawing.Size(372, 208)
Me.TXT_URLS.Size = New System.Drawing.Size(372, 155)
Me.TXT_URLS.TabIndex = 0
Me.TXT_URLS.Text = ""
'
'CMB_ACCOUNT
'
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Name = "ArrowDown"
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_ACCOUNT.Buttons.Add(ActionButton5)
Me.CMB_ACCOUNT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.CMB_ACCOUNT.CaptionText = "Account"
Me.CMB_ACCOUNT.CaptionToolTipEnabled = True
Me.CMB_ACCOUNT.CaptionToolTipText = "Select an account to download media array"
Me.CMB_ACCOUNT.CaptionVisible = True
Me.CMB_ACCOUNT.CaptionWidth = 50.0R
Me.CMB_ACCOUNT.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_ACCOUNT.Location = New System.Drawing.Point(3, 31)
Me.CMB_ACCOUNT.Name = "CMB_ACCOUNT"
Me.CMB_ACCOUNT.Size = New System.Drawing.Size(378, 22)
Me.CMB_ACCOUNT.TabIndex = 1
Me.CMB_ACCOUNT.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
'
'DownloaderUrlsArrForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
@@ -155,10 +178,12 @@ Namespace DownloadObjects.STDownloader
TP_MAIN.ResumeLayout(False)
CType(Me.TXT_OUTPUT, System.ComponentModel.ISupportInitialize).EndInit()
FRM_URLS.ResumeLayout(False)
CType(Me.CMB_ACCOUNT, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_OUTPUT As PersonalUtilities.Forms.Controls.ComboBoxExtended
Private WithEvents TXT_URLS As RichTextBox
Private WithEvents CMB_ACCOUNT As PersonalUtilities.Forms.Controls.ComboBoxExtended
End Class
End Namespace

View File

@@ -258,4 +258,94 @@
<metadata name="FRM_URLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
</value>
</data>
</root>

View File

@@ -26,6 +26,17 @@ Namespace DownloadObjects.STDownloader
End If
End Get
End Property
Friend ReadOnly Property AccountName As String
Get
Return CMB_ACCOUNT.Text
End Get
End Property
Private _UseAccountName As Boolean = False
Friend ReadOnly Property UseAccountName As Boolean
Get
Return _UseAccountName
End Get
End Property
Friend Sub New(ByVal InitialList As IEnumerable(Of String))
InitializeComponent()
MyDefs = New DefaultFormOptions(Me, Settings.Design)
@@ -38,6 +49,7 @@ Namespace DownloadObjects.STDownloader
Settings.DownloadLocations.PopulateComboBox(TXT_OUTPUT)
TXT_OUTPUT.Text = Settings.LatestSavingPath.Value.PathWithSeparator
If TXT_OUTPUT.Text.IsEmptyString Then TXT_OUTPUT.Text = Application.StartupPath.CSFileP.PathWithSeparator
TXT_URLS_TextChanged()
.MyFieldsChecker = New FieldsChecker
With .MyFieldsCheckerE
.AddControl(Of String)(TXT_OUTPUT, TXT_OUTPUT.CaptionText)
@@ -65,5 +77,33 @@ Namespace DownloadObjects.STDownloader
If Sender.DefaultButton = ADB.Open Or Sender.DefaultButton = ADB.Add Then _
Settings.DownloadLocations.ChooseNewLocation(TXT_OUTPUT, Sender.DefaultButton = ADB.Add, Settings.STDownloader_OutputPathAskForName)
End Sub
Private Sub TXT_URLS_TextChanged() Handles TXT_URLS.TextChanged
Try
With CMB_ACCOUNT
.BeginUpdate()
.Items.Clear()
.Text = String.Empty
_UseAccountName = False
If Not TXT_URLS.Text.IsEmptyString Then
Dim plugins As IEnumerable(Of String) = TXT_URLS.Lines.Select(Function(u) DownloaderUrlForm.GetMediaPluginKey(u)).Distinct
Dim fpl As Func(Of String, Boolean) = Function(p) Not p.IsEmptyString
If plugins.ListExists AndAlso plugins.LongCount(fpl) = 1 Then
CMB_ACCOUNT.Items.AddRange(Settings(plugins.First(fpl)).Select(Function(p) New ListItem(p.AccountName.IfNullOrEmpty(
Plugin.Hosts.SettingsHost.NameAccountNameDefault))))
_UseAccountName = True
End If
End If
.LeaveDefaultButtons = .Items.Count > 1
.Buttons.UpdateButtonsPositions()
.EndUpdate()
If .Items.Count > 0 Then .SelectedIndex = 0
.Enabled = .Items.Count > 1
End With
Catch ex As Exception
_UseAccountName = True
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[STDownloader.DownloaderUrlsArrForm.TXT_URLS_TextChanged]")
MainFrameObj.UpdateLogButton()
End Try
End Sub
End Class
End Namespace

View File

@@ -68,6 +68,7 @@ Namespace DownloadObjects.STDownloader
If Not isExternal Then url = BufferText
Dim disableDown As Boolean = e.Shift
Dim output As SFile = Settings.LatestSavingPath
Dim acc$ = String.Empty
Dim isArr As Boolean = (__tag = UrlsArrTag Or (isExternal And ExternalUrlsTemp.Count > 1))
Dim formOpened As Boolean = False
Dim media As IYouTubeMediaContainer
@@ -79,6 +80,7 @@ Namespace DownloadObjects.STDownloader
If f.DialogResult = DialogResult.OK Then
url = f.URL
output = f.OutputPath
acc = f.AccountName
Settings.LatestSavingPath.Value = output
If Settings.STDownloader_UpdateYouTubeOutputPath Then _
API.YouTube.MyYouTubeSettings.OutputPath.Value = output
@@ -127,6 +129,7 @@ Namespace DownloadObjects.STDownloader
If fa.DialogResult = DialogResult.OK Then
urls = fa.URLs.ToList
output = fa.OutputPath
If fa.UseAccountName Then acc = fa.AccountName
If Settings.STDownloader_UpdateYouTubeOutputPath Then API.YouTube.MyYouTubeSettings.OutputPath.Value = output
If Settings.STDownloader_OutputPathAutoAddPaths Then Settings.DownloadLocations.Add(output, False)
Else
@@ -142,7 +145,7 @@ Namespace DownloadObjects.STDownloader
For Each url In urls
If Not TryYouTube.Invoke Then
media = FindSource(url, output)
If Not media Is Nothing Then ControlCreateAndAdd(media, disableDown)
If Not media Is Nothing Then media.AccountName = acc : ControlCreateAndAdd(media, disableDown)
End If
Next
urls.Clear()
@@ -173,6 +176,7 @@ Namespace DownloadObjects.STDownloader
If media Is Nothing Then
MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical)
Else
media.AccountName = acc
output.Exists(SFO.Path, True)
ControlCreateAndAdd(media, disableDown)
End If

View File

@@ -116,7 +116,11 @@ Namespace DownloadObjects
If Not _FilesSessionCleared Then
_FilesSessionCleared = True
Dim files As List(Of SFile) = SFile.GetFiles(SessionsPath.CSFileP, "*.xml",, EDP.ReturnValue)
If RenameOldFileNames(files) Then files = SFile.GetFiles(SessionsPath.CSFileP, "*.xml",, EDP.ReturnValue)
If files.ListExists Then files.RemoveAll(Settings.Feeds.FeedSpecialRemover)
If RenameOldFileNames(files) Then
files = SFile.GetFiles(SessionsPath.CSFileP, "*.xml",, EDP.ReturnValue)
If files.ListExists Then files.RemoveAll(Settings.Feeds.FeedSpecialRemover)
End If
Dim filesCount% = Settings.FeedStoredSessionsNumber
If files.ListExists And filesCount > 0 Then
Dim fe As New ErrorsDescriber(EDP.None)
@@ -152,9 +156,10 @@ Namespace DownloadObjects
Private ReadOnly NProv As IFormatProvider
#End Region
#Region "Working, Count"
Friend ReadOnly Property Working As Boolean
Friend ReadOnly Property Working(Optional ByVal CheckThread As Boolean = True) As Boolean
Get
Return Pool.Count > 0 AndAlso Pool.Exists(Function(j) j.Working)
Return _PoolReconfiguration Or (Pool.Count > 0 AndAlso Pool.Exists(Function(j) j.Working)) Or
(CheckThread AndAlso If(CheckerThread?.IsAlive, False))
End Get
End Property
Friend ReadOnly Property Count As Integer
@@ -180,13 +185,13 @@ Namespace DownloadObjects
#End Region
#Region "Jobs"
Friend Class Job : Inherits JobThread(Of IUserData)
Private ReadOnly Hosts As List(Of SettingsHost)
Private ReadOnly Hosts As List(Of SettingsHostCollection)
Private ReadOnly Keys As List(Of String)
Private ReadOnly RemovingKeys As List(Of String)
Friend ReadOnly Property [Type] As Download
Friend ReadOnly Property IsSeparated As Boolean
Get
Return Hosts.Count = 1 AndAlso Hosts(0).IsSeparatedTasks
Return Hosts.Count = 1 AndAlso Hosts(0).Default.IsSeparatedTasks
End Get
End Property
Friend ReadOnly Property Name As String
@@ -195,23 +200,28 @@ Namespace DownloadObjects
End Get
End Property
Friend ReadOnly Property GroupName As String
Friend ReadOnly Property TaskCount As Integer
Friend ReadOnly Property TaskCount(ByVal AccountName As String) As Integer
Get
Return Hosts(0).TaskCount
Return Hosts(0)(AccountName).TaskCount
End Get
End Property
Friend ReadOnly Property Host As SettingsHost
Friend ReadOnly Property HostCollection As SettingsHostCollection
Get
Return Hosts(0)
End Get
End Property
Friend ReadOnly Property Host(ByVal AccountName As String) As SettingsHost
Get
If Hosts.Count > 0 Then
Dim k$ = Hosts(0).Key
Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = k)
If i >= 0 Then Return Settings.Plugins(i).Settings
If i >= 0 Then Return Settings.Plugins(i).Settings(AccountName)
End If
Return Nothing
End Get
End Property
Friend Sub New(ByVal JobType As Download)
Hosts = New List(Of SettingsHost)
Hosts = New List(Of SettingsHostCollection)
RemovingKeys = New List(Of String)
Keys = New List(Of String)
[Type] = JobType
@@ -236,28 +246,41 @@ Namespace DownloadObjects
End With
Return False
End Function
Friend Sub AddHost(ByRef h As SettingsHost)
Friend Sub AddHost(ByRef h As SettingsHostCollection)
Hosts.Add(h)
Keys.Add(h.Key)
End Sub
Friend Function UserHost(ByVal User As IUserData) As SettingsHost
Dim i% = Keys.IndexOf(DirectCast(User, UserDataBase).User.Plugin)
If i >= 0 Then Return Hosts(i) Else Throw New KeyNotFoundException($"Plugin key [{DirectCast(User, UserDataBase).User.Plugin}] not found")
If i >= 0 Then Return Hosts(i)(User.AccountName) Else Throw New KeyNotFoundException($"Plugin key [{DirectCast(User, UserDataBase).User.Plugin}] not found")
End Function
Friend Function Available(ByVal Silent As Boolean) As Boolean
If Hosts.Count > 0 Then
Dim k$
Dim h As SettingsHostCollection
Dim hList As IEnumerable(Of String)
For i% = Hosts.Count - 1 To 0 Step -1
If Not Hosts(i).Available(Type, Silent) Then
k = Hosts(i).Key
If Not RemovingKeys.Contains(k) Then RemovingKeys.Add(k)
Hosts(i).DownloadDone(Type)
Hosts.RemoveAt(i)
Keys.RemoveAt(i)
If Items.Count > 0 Then Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k)
h = Hosts(i)
k = h.Key
hList = Nothing
If Items.Count > 0 Then
hList = (From u As UserDataBase In Items
Where u.HOST.Key = k
Select u.HOST.AccountName.IfNullOrEmpty(SettingsHost.NameAccountNameDefault)).Distinct
If Not h.Available(Type, Silent,, hList, True) Then
If Not RemovingKeys.Contains(k) Then RemovingKeys.Add(k)
h.DownloadDone(Type)
Hosts.RemoveAt(i)
Keys.RemoveAt(i)
If Items.Count > 0 Then Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k)
ElseIf h.CountUnavailable > 0 AndAlso Items.Count > 0 Then
Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k And Not h.AvailablePartial(u.AccountName))
End If
Else
Hosts.Clear()
End If
Next
Return Hosts.Count > 0
Return Hosts.Count > 0 And Items.Count > 0
Else
Return False
End If
@@ -303,7 +326,12 @@ Namespace DownloadObjects
End Sub
#End Region
#Region "Pool"
Friend Sub ReconfPool(Optional ByVal Round As Integer = 0)
Private _PoolReconfiguration As Boolean = False
Friend Overloads Sub ReconfPool()
_PoolReconfiguration = True
Try : ReconfPool(0) : Finally : _PoolReconfiguration = False : End Try
End Sub
Friend Overloads Sub ReconfPool(ByVal Round As Integer)
Try
If Pool.Count = 0 OrElse Not Pool.Exists(Function(j) j.Working Or j.Count > 0) Then
Dim i%
@@ -311,16 +339,16 @@ Namespace DownloadObjects
If Settings.Plugins.Count > 0 Then
Pool.Add(New Job(Download.Main))
For Each p As PluginHost In Settings.Plugins
If p.Settings.IsSeparatedTasks Then
If p.Settings.Default.IsSeparatedTasks Then
Pool.Add(New Job(Download.Main))
Pool.Last.AddHost(p.Settings)
ElseIf Not p.Settings.TaskGroupName.IsEmptyString Then
ElseIf Not p.Settings.Default.TaskGroupName.IsEmptyString Then
i = -1
If Pool.Count > 0 Then i = Pool.FindIndex(Function(pt) pt.GroupName = p.Settings.TaskGroupName)
If Pool.Count > 0 Then i = Pool.FindIndex(Function(pt) pt.GroupName = p.Settings.Default.TaskGroupName)
If i >= 0 Then
Pool(i).AddHost(p.Settings)
Else
Pool.Add(New Job(Download.Main, p.Settings.TaskGroupName))
Pool.Add(New Job(Download.Main, p.Settings.Default.TaskGroupName))
Pool.Last.AddHost(p.Settings)
End If
Else
@@ -331,11 +359,7 @@ Namespace DownloadObjects
RaiseEvent Reconfigured()
End If
Catch ex As Exception
If Round = 0 Then
ReconfPool(Round + 1)
Else
Throw ex
End If
If Round = 0 Then ReconfPool(Round + 1) Else Throw ex
End Try
End Sub
#End Region
@@ -429,28 +453,58 @@ Namespace DownloadObjects
Private Sub UpdateJobsLabel()
RaiseEvent JobsChange(Count)
End Sub
Friend Structure HostLimit
Friend Key As String
Friend Limit As Integer
Friend Value As Integer
Public Shared Widening Operator CType(ByVal Host As SettingsHost) As HostLimit
Return New HostLimit With {.Key = Host.KeyDownloader, .Limit = Host.TaskCount, .Value = 0}
End Operator
Friend Function [Next]() As HostLimit
Value += 1
Return Me
End Function
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
Return Key = CType(Obj, HostLimit).Key
End Function
End Structure
Private Sub DownloadData(ByRef _Job As Job, ByVal Token As CancellationToken)
Try
If _Job.Count > 0 Then
Const nf As ANumbers.Formats = ANumbers.Formats.Number
Dim t As New List(Of Task)
Dim i% = 0
Dim limit% = _Job.TaskCount
Dim limit As HostLimit
Dim limitIndex%
Dim limits As New List(Of HostLimit)
Dim Keys As New List(Of String)
Dim h As Boolean = False
Dim host As SettingsHost = Nothing
Dim hostAvailable As Boolean
For Each _Item As IUserData In _Job.Items
If Not _Item.Disposed Then
Keys.Add(_Item.Key)
host = _Job.UserHost(_Item)
If host.Source.ReadyToDownload(Download.Main) Then
host.BeforeStartDownload(_Item, Download.Main)
_Job.ThrowIfCancellationRequested()
DirectCast(_Item, UserDataBase).Progress = _Job.Progress
t.Add(Task.Run(Sub() _Item.DownloadData(Token)))
RaiseEvent UserDownloadStateChanged(_Item, True)
i += 1
If i >= limit Then Exit For
hostAvailable = DirectCast(_Item, UserDataBase).HostCollection.AvailablePartial(_Item.AccountName)
Keys.Add(_Item.Key)
If hostAvailable Then
limit = host
If Not limits.Contains(limit) Then
limits.Add(limit)
limitIndex = limits.Count - 1
Else
limitIndex = limits.IndexOf(limit)
limit = limits(limitIndex)
End If
If host.Source.ReadyToDownload(Download.Main) Then
host.BeforeStartDownload(_Item, Download.Main)
_Job.ThrowIfCancellationRequested()
DirectCast(_Item, UserDataBase).Progress = _Job.Progress
t.Add(Task.Run(Sub() _Item.DownloadData(Token)))
RaiseEvent UserDownloadStateChanged(_Item, True)
limit = limit.Next
limits(limitIndex) = limit
If limit.Value >= limit.Limit Then Exit For
End If
End If
End If
Next
@@ -470,6 +524,7 @@ Namespace DownloadObjects
With _Job.Items(i)
If DirectCast(.Self, UserDataBase).ContentMissingExists Then MissingPostsDetected = True
RaiseEvent UserDownloadStateChanged(.Self, False)
host = _Job.UserHost(.Self)
host.AfterDownload(.Self, Download.Main)
If Not .Disposed AndAlso Not .IsCollection AndAlso .DownloadedTotal(False) > 0 Then
If Not Downloaded.Contains(.Self) Then Downloaded.Add(Settings.GetUser(.Self))

View File

@@ -24,16 +24,16 @@ Namespace Editors
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim TP_BASIS As System.Windows.Forms.TableLayoutPanel
Dim ActionButton55 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(GlobalSettingsForm))
Dim ActionButton56 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TP_IMAGES As System.Windows.Forms.TableLayoutPanel
Dim ActionButton57 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton58 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton59 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton60 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton61 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton62 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel
Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel
Dim LBL_DATE_POS As System.Windows.Forms.Label
@@ -46,14 +46,14 @@ Namespace Editors
Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel
Dim TAB_BEHAVIOR As System.Windows.Forms.TabPage
Dim TP_BEHAVIOR As System.Windows.Forms.TableLayoutPanel
Dim ActionButton63 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton64 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TP_OPEN_INFO As System.Windows.Forms.TableLayoutPanel
Dim TP_OPEN_PROGRESS As System.Windows.Forms.TableLayoutPanel
Dim TAB_DOWN As System.Windows.Forms.TabPage
Dim TP_DOWNLOADING As System.Windows.Forms.TableLayoutPanel
Dim ActionButton65 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton66 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton11 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton12 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TP_MISSING_DATA As System.Windows.Forms.TableLayoutPanel
Dim TAB_FEED As System.Windows.Forms.TabPage
Dim TP_FEED As System.Windows.Forms.TableLayoutPanel
@@ -61,27 +61,27 @@ Namespace Editors
Dim TAB_NOTIFY As System.Windows.Forms.TabPage
Dim TP_NOTIFY_MAIN As System.Windows.Forms.TableLayoutPanel
Dim TP_ENVIR As System.Windows.Forms.TableLayoutPanel
Dim ActionButton67 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton68 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton69 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton70 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton71 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton72 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton73 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton74 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton75 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton76 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton15 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton16 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton17 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton18 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton19 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton20 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton21 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton22 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TAB_STD As System.Windows.Forms.TabPage
Dim TP_STD As System.Windows.Forms.TableLayoutPanel
Dim ActionButton77 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ListColumn5 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ListColumn6 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ActionButton23 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ListColumn1 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim ListColumn2 As PersonalUtilities.Forms.Controls.Base.ListColumn = New PersonalUtilities.Forms.Controls.Base.ListColumn()
Dim TAB_DESIGN As System.Windows.Forms.TabPage
Dim TP_DESIGN As System.Windows.Forms.TableLayoutPanel
Dim ActionButton78 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton79 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton80 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton81 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton24 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton25 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton26 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton27 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
@@ -131,6 +131,8 @@ Namespace Editors
Me.BTT_RESET_DOWNLOAD_LOCATIONS = New System.Windows.Forms.Button()
Me.CH_STD_SNAP_KEEP_WITH_FILES = New System.Windows.Forms.CheckBox()
Me.CH_STD_SNAP_CACHE_PERMANENT = New System.Windows.Forms.CheckBox()
Me.CH_STD_YT_CREATE_URL = New System.Windows.Forms.CheckBox()
Me.CH_USE_DEF_ACC = New System.Windows.Forms.CheckBox()
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox()
@@ -175,7 +177,7 @@ Namespace Editors
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
Me.TAB_ENVIR = New System.Windows.Forms.TabPage()
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
Me.CH_STD_YT_CREATE_URL = New System.Windows.Forms.CheckBox()
Me.CH_FEED_SHOW_SPEC_MEDIAITEM = New System.Windows.Forms.CheckBox()
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
@@ -302,17 +304,17 @@ Namespace Editors
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BASIS.Size = New System.Drawing.Size(570, 368)
TP_BASIS.Size = New System.Drawing.Size(570, 393)
TP_BASIS.TabIndex = 0
'
'TXT_GLOBAL_PATH
'
ActionButton55.BackgroundImage = CType(resources.GetObject("ActionButton55.BackgroundImage"), System.Drawing.Image)
ActionButton55.Name = "Open"
ActionButton56.BackgroundImage = CType(resources.GetObject("ActionButton56.BackgroundImage"), System.Drawing.Image)
ActionButton56.Name = "Clear"
Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton55)
Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton56)
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Open"
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Clear"
Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton1)
Me.TXT_GLOBAL_PATH.Buttons.Add(ActionButton2)
Me.TXT_GLOBAL_PATH.CaptionText = "Data Path"
Me.TXT_GLOBAL_PATH.CaptionToolTipEnabled = True
Me.TXT_GLOBAL_PATH.CaptionToolTipText = "Root path for storing users' data"
@@ -373,9 +375,9 @@ Namespace Editors
'
'TXT_COLLECTIONS_PATH
'
ActionButton57.BackgroundImage = CType(resources.GetObject("ActionButton57.BackgroundImage"), System.Drawing.Image)
ActionButton57.Name = "Clear"
Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton57)
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "Clear"
Me.TXT_COLLECTIONS_PATH.Buttons.Add(ActionButton3)
Me.TXT_COLLECTIONS_PATH.CaptionText = "Collections folder"
Me.TXT_COLLECTIONS_PATH.CaptionToolTipEnabled = True
Me.TXT_COLLECTIONS_PATH.CaptionToolTipText = "Set collections folder name (name only)"
@@ -387,10 +389,10 @@ Namespace Editors
'
'TXT_MAX_JOBS_USERS
'
ActionButton58.BackgroundImage = CType(resources.GetObject("ActionButton58.BackgroundImage"), System.Drawing.Image)
ActionButton58.Name = "Refresh"
ActionButton58.ToolTipText = "Set to default"
Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton58)
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Name = "Refresh"
ActionButton4.ToolTipText = "Set to default"
Me.TXT_MAX_JOBS_USERS.Buttons.Add(ActionButton4)
Me.TXT_MAX_JOBS_USERS.CaptionSizeType = System.Windows.Forms.SizeType.Percent
Me.TXT_MAX_JOBS_USERS.CaptionText = "Maximum downloading tasks of users"
Me.TXT_MAX_JOBS_USERS.CaptionWidth = 50.0R
@@ -406,10 +408,10 @@ Namespace Editors
'
'TXT_MAX_JOBS_CHANNELS
'
ActionButton59.BackgroundImage = CType(resources.GetObject("ActionButton59.BackgroundImage"), System.Drawing.Image)
ActionButton59.Name = "Refresh"
ActionButton59.ToolTipText = "Set to default"
Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton59)
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Name = "Refresh"
ActionButton5.ToolTipText = "Set to default"
Me.TXT_MAX_JOBS_CHANNELS.Buttons.Add(ActionButton5)
Me.TXT_MAX_JOBS_CHANNELS.CaptionSizeType = System.Windows.Forms.SizeType.Percent
Me.TXT_MAX_JOBS_CHANNELS.CaptionText = "Maximum downloading tasks of channels"
Me.TXT_MAX_JOBS_CHANNELS.CaptionWidth = 50.0R
@@ -436,9 +438,9 @@ Namespace Editors
'
'TXT_IMGUR_CLIENT_ID
'
ActionButton60.BackgroundImage = CType(resources.GetObject("ActionButton60.BackgroundImage"), System.Drawing.Image)
ActionButton60.Name = "Clear"
Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton60)
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Name = "Clear"
Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton6)
Me.TXT_IMGUR_CLIENT_ID.CaptionText = "Imgur Client ID"
Me.TXT_IMGUR_CLIENT_ID.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 204)
@@ -472,14 +474,14 @@ Namespace Editors
'
'TXT_USER_AGENT
'
ActionButton61.BackgroundImage = CType(resources.GetObject("ActionButton61.BackgroundImage"), System.Drawing.Image)
ActionButton61.Name = "Refresh"
ActionButton61.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton62.BackgroundImage = CType(resources.GetObject("ActionButton62.BackgroundImage"), System.Drawing.Image)
ActionButton62.Name = "Clear"
ActionButton62.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_USER_AGENT.Buttons.Add(ActionButton61)
Me.TXT_USER_AGENT.Buttons.Add(ActionButton62)
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Name = "Refresh"
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Name = "Clear"
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_USER_AGENT.Buttons.Add(ActionButton7)
Me.TXT_USER_AGENT.Buttons.Add(ActionButton8)
Me.TXT_USER_AGENT.CaptionText = "UserAgent"
Me.TXT_USER_AGENT.CaptionToolTipEnabled = True
Me.TXT_USER_AGENT.CaptionToolTipText = "Default user agent to use in requests"
@@ -1009,6 +1011,31 @@ Namespace Editors
"with 'Create video thumbnail' and 'Keep video thumbnail with files'.")
Me.CH_STD_SNAP_CACHE_PERMANENT.UseVisualStyleBackColor = True
'
'CH_STD_YT_CREATE_URL
'
Me.CH_STD_YT_CREATE_URL.AutoSize = True
Me.CH_STD_YT_CREATE_URL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_CREATE_URL.Location = New System.Drawing.Point(4, 322)
Me.CH_STD_YT_CREATE_URL.Name = "CH_STD_YT_CREATE_URL"
Me.CH_STD_YT_CREATE_URL.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_CREATE_URL.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_CREATE_URL.TabIndex = 12
Me.CH_STD_YT_CREATE_URL.Text = "Create URL files"
TT_MAIN.SetToolTip(Me.CH_STD_YT_CREATE_URL, "Create local URL files to link to the original page")
Me.CH_STD_YT_CREATE_URL.UseVisualStyleBackColor = True
'
'CH_USE_DEF_ACC
'
Me.CH_USE_DEF_ACC.AutoSize = True
Me.CH_USE_DEF_ACC.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_USE_DEF_ACC.Location = New System.Drawing.Point(4, 254)
Me.CH_USE_DEF_ACC.Name = "CH_USE_DEF_ACC"
Me.CH_USE_DEF_ACC.Size = New System.Drawing.Size(568, 19)
Me.CH_USE_DEF_ACC.TabIndex = 9
Me.CH_USE_DEF_ACC.Text = "Use the default account if the selected account does not exist"
TT_MAIN.SetToolTip(Me.CH_USE_DEF_ACC, "Use the default account if you deleted an account that you used for some users")
Me.CH_USE_DEF_ACC.UseVisualStyleBackColor = True
'
'TP_CHANNELS_IMGS
'
TP_CHANNELS_IMGS.ColumnCount = 2
@@ -1060,7 +1087,7 @@ Namespace Editors
TAB_BASIS.Location = New System.Drawing.Point(4, 22)
TAB_BASIS.Name = "TAB_BASIS"
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
TAB_BASIS.Size = New System.Drawing.Size(576, 374)
TAB_BASIS.Size = New System.Drawing.Size(576, 399)
TAB_BASIS.TabIndex = 0
TAB_BASIS.Text = "Basis"
'
@@ -1070,7 +1097,7 @@ Namespace Editors
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
TAB_DEFAULTS.Name = "TAB_DEFAULTS"
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 374)
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 399)
TAB_DEFAULTS.TabIndex = 1
TAB_DEFAULTS.Text = "Defaults"
'
@@ -1096,7 +1123,7 @@ Namespace Editors
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DEFS.Size = New System.Drawing.Size(570, 368)
TP_DEFS.Size = New System.Drawing.Size(570, 393)
TP_DEFS.TabIndex = 0
'
'CH_DOWN_IMAGES_NATIVE
@@ -1116,7 +1143,7 @@ Namespace Editors
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 374)
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 399)
TAB_DEFS_CHANNELS.TabIndex = 4
TAB_DEFS_CHANNELS.Text = "Channels"
'
@@ -1140,7 +1167,7 @@ Namespace Editors
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_CHANNELS.Size = New System.Drawing.Size(570, 368)
TP_CHANNELS.Size = New System.Drawing.Size(570, 393)
TP_CHANNELS.TabIndex = 0
'
'TXT_CHANNEL_USER_POST_LIMIT
@@ -1168,7 +1195,7 @@ Namespace Editors
TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR)
TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22)
TAB_BEHAVIOR.Name = "TAB_BEHAVIOR"
TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 374)
TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 399)
TAB_BEHAVIOR.TabIndex = 5
TAB_BEHAVIOR.Text = "Behavior"
'
@@ -1199,17 +1226,17 @@ Namespace Editors
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 374)
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 399)
TP_BEHAVIOR.TabIndex = 0
'
'TXT_FOLDER_CMD
'
Me.TXT_FOLDER_CMD.AutoShowClearButton = True
ActionButton63.BackgroundImage = CType(resources.GetObject("ActionButton63.BackgroundImage"), System.Drawing.Image)
ActionButton63.Enabled = False
ActionButton63.Name = "Clear"
ActionButton63.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton63)
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Enabled = False
ActionButton9.Name = "Clear"
ActionButton9.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton9)
Me.TXT_FOLDER_CMD.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_FOLDER_CMD.CaptionText = "Folder cmd"
Me.TXT_FOLDER_CMD.CaptionToolTipEnabled = True
@@ -1248,11 +1275,11 @@ Namespace Editors
'TXT_CLOSE_SCRIPT
'
Me.TXT_CLOSE_SCRIPT.AutoShowClearButton = True
ActionButton64.BackgroundImage = CType(resources.GetObject("ActionButton64.BackgroundImage"), System.Drawing.Image)
ActionButton64.Enabled = False
ActionButton64.Name = "Clear"
ActionButton64.Visible = False
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton64)
ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image)
ActionButton10.Enabled = False
ActionButton10.Name = "Clear"
ActionButton10.Visible = False
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton10)
Me.TXT_CLOSE_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_CLOSE_SCRIPT.CaptionText = "Close cmd"
Me.TXT_CLOSE_SCRIPT.CaptionToolTipEnabled = True
@@ -1340,7 +1367,7 @@ Namespace Editors
TAB_DOWN.Controls.Add(TP_DOWNLOADING)
TAB_DOWN.Location = New System.Drawing.Point(4, 22)
TAB_DOWN.Name = "TAB_DOWN"
TAB_DOWN.Size = New System.Drawing.Size(576, 374)
TAB_DOWN.Size = New System.Drawing.Size(576, 399)
TAB_DOWN.TabIndex = 6
TAB_DOWN.Text = "Downloading"
'
@@ -1358,10 +1385,11 @@ Namespace Editors
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_UICON_UP, 0, 2)
TP_DOWNLOADING.Controls.Add(Me.CH_USE_DEF_ACC, 0, 9)
TP_DOWNLOADING.Dock = System.Windows.Forms.DockStyle.Fill
TP_DOWNLOADING.Location = New System.Drawing.Point(0, 0)
TP_DOWNLOADING.Name = "TP_DOWNLOADING"
TP_DOWNLOADING.RowCount = 10
TP_DOWNLOADING.RowCount = 11
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!))
@@ -1371,18 +1399,19 @@ Namespace Editors
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.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.Percent, 100.0!))
TP_DOWNLOADING.Size = New System.Drawing.Size(576, 374)
TP_DOWNLOADING.Size = New System.Drawing.Size(576, 399)
TP_DOWNLOADING.TabIndex = 1
'
'TXT_SCRIPT
'
ActionButton65.BackgroundImage = CType(resources.GetObject("ActionButton65.BackgroundImage"), System.Drawing.Image)
ActionButton65.Name = "Open"
ActionButton66.BackgroundImage = CType(resources.GetObject("ActionButton66.BackgroundImage"), System.Drawing.Image)
ActionButton66.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton65)
Me.TXT_SCRIPT.Buttons.Add(ActionButton66)
ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image)
ActionButton11.Name = "Open"
ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image)
ActionButton12.Name = "Clear"
Me.TXT_SCRIPT.Buttons.Add(ActionButton11)
Me.TXT_SCRIPT.Buttons.Add(ActionButton12)
Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SCRIPT.CaptionText = "Script"
Me.TXT_SCRIPT.CaptionToolTipEnabled = True
@@ -1458,7 +1487,7 @@ Namespace Editors
TAB_FEED.Controls.Add(TP_FEED)
TAB_FEED.Location = New System.Drawing.Point(4, 22)
TAB_FEED.Name = "TAB_FEED"
TAB_FEED.Size = New System.Drawing.Size(576, 374)
TAB_FEED.Size = New System.Drawing.Size(576, 399)
TAB_FEED.TabIndex = 7
TAB_FEED.Text = "Feed"
'
@@ -1476,10 +1505,11 @@ Namespace Editors
TP_FEED.Controls.Add(Me.COLORS_FEED, 0, 2)
TP_FEED.Controls.Add(Me.CH_FEED_OPEN_LAST_MODE, 0, 7)
TP_FEED.Controls.Add(Me.CH_FEED_SHOW_FRIENDLY, 0, 8)
TP_FEED.Controls.Add(Me.CH_FEED_SHOW_SPEC_MEDIAITEM, 0, 9)
TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill
TP_FEED.Location = New System.Drawing.Point(0, 0)
TP_FEED.Name = "TP_FEED"
TP_FEED.RowCount = 10
TP_FEED.RowCount = 11
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
@@ -1489,8 +1519,9 @@ Namespace Editors
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FEED.Size = New System.Drawing.Size(576, 374)
TP_FEED.Size = New System.Drawing.Size(576, 399)
TP_FEED.TabIndex = 0
'
'TP_FEED_IMG_COUNT
@@ -1644,7 +1675,7 @@ Namespace Editors
TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN)
TAB_NOTIFY.Location = New System.Drawing.Point(4, 22)
TAB_NOTIFY.Name = "TAB_NOTIFY"
TAB_NOTIFY.Size = New System.Drawing.Size(576, 374)
TAB_NOTIFY.Size = New System.Drawing.Size(576, 399)
TAB_NOTIFY.TabIndex = 8
TAB_NOTIFY.Text = "Notifications"
'
@@ -1674,7 +1705,7 @@ Namespace Editors
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 374)
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 399)
TP_NOTIFY_MAIN.TabIndex = 0
'
'TP_ENVIR
@@ -1697,19 +1728,19 @@ Namespace Editors
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_ENVIR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_ENVIR.Size = New System.Drawing.Size(576, 374)
TP_ENVIR.Size = New System.Drawing.Size(576, 399)
TP_ENVIR.TabIndex = 0
'
'TXT_YTDLP
'
ActionButton67.BackgroundImage = CType(resources.GetObject("ActionButton67.BackgroundImage"), System.Drawing.Image)
ActionButton67.Name = "Open"
ActionButton67.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton68.BackgroundImage = CType(resources.GetObject("ActionButton68.BackgroundImage"), System.Drawing.Image)
ActionButton68.Name = "Clear"
ActionButton68.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_YTDLP.Buttons.Add(ActionButton67)
Me.TXT_YTDLP.Buttons.Add(ActionButton68)
ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image)
ActionButton13.Name = "Open"
ActionButton13.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image)
ActionButton14.Name = "Clear"
ActionButton14.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_YTDLP.Buttons.Add(ActionButton13)
Me.TXT_YTDLP.Buttons.Add(ActionButton14)
Me.TXT_YTDLP.CaptionText = "yt-dlp"
Me.TXT_YTDLP.CaptionToolTipEnabled = True
Me.TXT_YTDLP.CaptionToolTipText = "Path to yt-dlp.exe file"
@@ -1723,14 +1754,14 @@ Namespace Editors
'
'TXT_FFMPEG
'
ActionButton69.BackgroundImage = CType(resources.GetObject("ActionButton69.BackgroundImage"), System.Drawing.Image)
ActionButton69.Name = "Open"
ActionButton69.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton70.BackgroundImage = CType(resources.GetObject("ActionButton70.BackgroundImage"), System.Drawing.Image)
ActionButton70.Name = "Clear"
ActionButton70.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_FFMPEG.Buttons.Add(ActionButton69)
Me.TXT_FFMPEG.Buttons.Add(ActionButton70)
ActionButton15.BackgroundImage = CType(resources.GetObject("ActionButton15.BackgroundImage"), System.Drawing.Image)
ActionButton15.Name = "Open"
ActionButton15.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton16.BackgroundImage = CType(resources.GetObject("ActionButton16.BackgroundImage"), System.Drawing.Image)
ActionButton16.Name = "Clear"
ActionButton16.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_FFMPEG.Buttons.Add(ActionButton15)
Me.TXT_FFMPEG.Buttons.Add(ActionButton16)
Me.TXT_FFMPEG.CaptionText = "ffmpeg"
Me.TXT_FFMPEG.CaptionToolTipEnabled = True
Me.TXT_FFMPEG.CaptionToolTipText = "Path to ffmpeg.exe file"
@@ -1744,14 +1775,14 @@ Namespace Editors
'
'TXT_CURL
'
ActionButton71.BackgroundImage = CType(resources.GetObject("ActionButton71.BackgroundImage"), System.Drawing.Image)
ActionButton71.Name = "Open"
ActionButton71.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton72.BackgroundImage = CType(resources.GetObject("ActionButton72.BackgroundImage"), System.Drawing.Image)
ActionButton72.Name = "Clear"
ActionButton72.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CURL.Buttons.Add(ActionButton71)
Me.TXT_CURL.Buttons.Add(ActionButton72)
ActionButton17.BackgroundImage = CType(resources.GetObject("ActionButton17.BackgroundImage"), System.Drawing.Image)
ActionButton17.Name = "Open"
ActionButton17.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton18.BackgroundImage = CType(resources.GetObject("ActionButton18.BackgroundImage"), System.Drawing.Image)
ActionButton18.Name = "Clear"
ActionButton18.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CURL.Buttons.Add(ActionButton17)
Me.TXT_CURL.Buttons.Add(ActionButton18)
Me.TXT_CURL.CaptionText = "cURL"
Me.TXT_CURL.CaptionToolTipEnabled = True
Me.TXT_CURL.CaptionToolTipText = "Path to curl.exe file"
@@ -1765,14 +1796,14 @@ Namespace Editors
'
'TXT_GALLERYDL
'
ActionButton73.BackgroundImage = CType(resources.GetObject("ActionButton73.BackgroundImage"), System.Drawing.Image)
ActionButton73.Name = "Open"
ActionButton73.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton74.BackgroundImage = CType(resources.GetObject("ActionButton74.BackgroundImage"), System.Drawing.Image)
ActionButton74.Name = "Clear"
ActionButton74.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_GALLERYDL.Buttons.Add(ActionButton73)
Me.TXT_GALLERYDL.Buttons.Add(ActionButton74)
ActionButton19.BackgroundImage = CType(resources.GetObject("ActionButton19.BackgroundImage"), System.Drawing.Image)
ActionButton19.Name = "Open"
ActionButton19.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton20.BackgroundImage = CType(resources.GetObject("ActionButton20.BackgroundImage"), System.Drawing.Image)
ActionButton20.Name = "Clear"
ActionButton20.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_GALLERYDL.Buttons.Add(ActionButton19)
Me.TXT_GALLERYDL.Buttons.Add(ActionButton20)
Me.TXT_GALLERYDL.CaptionText = "gallery-dl"
Me.TXT_GALLERYDL.CaptionToolTipText = "Path to gallery-dl.exe file"
Me.TXT_GALLERYDL.CaptionWidth = 80.0R
@@ -1785,14 +1816,14 @@ Namespace Editors
'
'TXT_CMD_ENCODING
'
ActionButton75.BackgroundImage = CType(resources.GetObject("ActionButton75.BackgroundImage"), System.Drawing.Image)
ActionButton75.Name = "Refresh"
ActionButton75.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton76.BackgroundImage = CType(resources.GetObject("ActionButton76.BackgroundImage"), System.Drawing.Image)
ActionButton76.Name = "Clear"
ActionButton76.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton75)
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton76)
ActionButton21.BackgroundImage = CType(resources.GetObject("ActionButton21.BackgroundImage"), System.Drawing.Image)
ActionButton21.Name = "Refresh"
ActionButton21.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton22.BackgroundImage = CType(resources.GetObject("ActionButton22.BackgroundImage"), System.Drawing.Image)
ActionButton22.Name = "Clear"
ActionButton22.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton21)
Me.TXT_CMD_ENCODING.Buttons.Add(ActionButton22)
Me.TXT_CMD_ENCODING.CaptionText = "CMD Encoding"
Me.TXT_CMD_ENCODING.CaptionToolTipEnabled = True
Me.TXT_CMD_ENCODING.CaptionToolTipText = "Command line encoding"
@@ -1808,7 +1839,7 @@ Namespace Editors
TAB_STD.Controls.Add(TP_STD)
TAB_STD.Location = New System.Drawing.Point(4, 22)
TAB_STD.Name = "TAB_STD"
TAB_STD.Size = New System.Drawing.Size(576, 374)
TAB_STD.Size = New System.Drawing.Size(576, 399)
TAB_STD.TabIndex = 10
TAB_STD.Text = "Downloader"
'
@@ -1850,7 +1881,7 @@ Namespace Editors
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_STD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_STD.Size = New System.Drawing.Size(576, 374)
TP_STD.Size = New System.Drawing.Size(576, 399)
TP_STD.TabIndex = 0
'
'TXT_STD_MAX_JOBS_COUNT
@@ -1895,24 +1926,24 @@ Namespace Editors
'
'CMB_STD_OPEN_DBL
'
ActionButton77.BackgroundImage = CType(resources.GetObject("ActionButton77.BackgroundImage"), System.Drawing.Image)
ActionButton77.Name = "ArrowDown"
ActionButton77.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton77)
ActionButton23.BackgroundImage = CType(resources.GetObject("ActionButton23.BackgroundImage"), System.Drawing.Image)
ActionButton23.Name = "ArrowDown"
ActionButton23.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
Me.CMB_STD_OPEN_DBL.Buttons.Add(ActionButton23)
Me.CMB_STD_OPEN_DBL.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
Me.CMB_STD_OPEN_DBL.CaptionText = "DoubleClick opens"
Me.CMB_STD_OPEN_DBL.CaptionToolTipEnabled = True
Me.CMB_STD_OPEN_DBL.CaptionToolTipText = "What do you want to open when you double click on an item"
Me.CMB_STD_OPEN_DBL.CaptionVisible = True
ListColumn5.DisplayMember = True
ListColumn5.Name = "STD_CMB_COL_TEXT"
ListColumn5.Text = "Text"
ListColumn6.Name = "STD_CMB_COL_VALUE"
ListColumn6.Text = "Value"
ListColumn6.ValueMember = True
ListColumn6.Visible = False
Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn5)
Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn6)
ListColumn1.DisplayMember = True
ListColumn1.Name = "STD_CMB_COL_TEXT"
ListColumn1.Text = "Text"
ListColumn2.Name = "STD_CMB_COL_VALUE"
ListColumn2.Text = "Value"
ListColumn2.ValueMember = True
ListColumn2.Visible = False
Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn1)
Me.CMB_STD_OPEN_DBL.Columns.Add(ListColumn2)
Me.CMB_STD_OPEN_DBL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_STD_OPEN_DBL.Location = New System.Drawing.Point(4, 85)
Me.CMB_STD_OPEN_DBL.Name = "CMB_STD_OPEN_DBL"
@@ -1949,7 +1980,7 @@ Namespace Editors
TAB_DESIGN.Controls.Add(TP_DESIGN)
TAB_DESIGN.Location = New System.Drawing.Point(4, 22)
TAB_DESIGN.Name = "TAB_DESIGN"
TAB_DESIGN.Size = New System.Drawing.Size(576, 374)
TAB_DESIGN.Size = New System.Drawing.Size(576, 399)
TAB_DESIGN.TabIndex = 11
TAB_DESIGN.Text = "Design"
'
@@ -1975,15 +2006,15 @@ Namespace Editors
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DESIGN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DESIGN.Size = New System.Drawing.Size(576, 374)
TP_DESIGN.Size = New System.Drawing.Size(576, 399)
TP_DESIGN.TabIndex = 0
'
'TXT_PRG_TITLE
'
ActionButton78.BackgroundImage = CType(resources.GetObject("ActionButton78.BackgroundImage"), System.Drawing.Image)
ActionButton78.Name = "Clear"
ActionButton78.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_TITLE.Buttons.Add(ActionButton78)
ActionButton24.BackgroundImage = CType(resources.GetObject("ActionButton24.BackgroundImage"), System.Drawing.Image)
ActionButton24.Name = "Clear"
ActionButton24.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_TITLE.Buttons.Add(ActionButton24)
Me.TXT_PRG_TITLE.CaptionText = "Program title"
Me.TXT_PRG_TITLE.CaptionToolTipEnabled = True
Me.TXT_PRG_TITLE.CaptionToolTipText = "Change the title of the main window if you need to"
@@ -1995,10 +2026,10 @@ Namespace Editors
'
'TXT_PRG_DESCR
'
ActionButton79.BackgroundImage = CType(resources.GetObject("ActionButton79.BackgroundImage"), System.Drawing.Image)
ActionButton79.Name = "Clear"
ActionButton79.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_DESCR.Buttons.Add(ActionButton79)
ActionButton25.BackgroundImage = CType(resources.GetObject("ActionButton25.BackgroundImage"), System.Drawing.Image)
ActionButton25.Name = "Clear"
ActionButton25.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_PRG_DESCR.Buttons.Add(ActionButton25)
Me.TXT_PRG_DESCR.CaptionText = "Program description"
Me.TXT_PRG_DESCR.CaptionToolTipEnabled = True
Me.TXT_PRG_DESCR.CaptionToolTipText = "Add some additional info to the program info if you need"
@@ -2010,14 +2041,14 @@ Namespace Editors
'
'TXT_USER_LIST_IMAGE
'
ActionButton80.BackgroundImage = CType(resources.GetObject("ActionButton80.BackgroundImage"), System.Drawing.Image)
ActionButton80.Name = "Open"
ActionButton80.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton81.BackgroundImage = CType(resources.GetObject("ActionButton81.BackgroundImage"), System.Drawing.Image)
ActionButton81.Name = "Clear"
ActionButton81.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton80)
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton81)
ActionButton26.BackgroundImage = CType(resources.GetObject("ActionButton26.BackgroundImage"), System.Drawing.Image)
ActionButton26.Name = "Open"
ActionButton26.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton27.BackgroundImage = CType(resources.GetObject("ActionButton27.BackgroundImage"), System.Drawing.Image)
ActionButton27.Name = "Clear"
ActionButton27.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton26)
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton27)
Me.TXT_USER_LIST_IMAGE.CaptionText = "Userlist image"
Me.TXT_USER_LIST_IMAGE.CaptionToolTipEnabled = True
Me.TXT_USER_LIST_IMAGE.CaptionToolTipText = "Background image for user list"
@@ -2081,7 +2112,7 @@ Namespace Editors
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TAB_MAIN.Name = "TAB_MAIN"
Me.TAB_MAIN.SelectedIndex = 0
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 400)
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 425)
Me.TAB_MAIN.TabIndex = 1
'
'TAB_ENVIR
@@ -2089,7 +2120,7 @@ Namespace Editors
Me.TAB_ENVIR.Controls.Add(TP_ENVIR)
Me.TAB_ENVIR.Location = New System.Drawing.Point(4, 22)
Me.TAB_ENVIR.Name = "TAB_ENVIR"
Me.TAB_ENVIR.Size = New System.Drawing.Size(576, 374)
Me.TAB_ENVIR.Size = New System.Drawing.Size(576, 399)
Me.TAB_ENVIR.TabIndex = 9
Me.TAB_ENVIR.Text = "Environment"
'
@@ -2099,7 +2130,7 @@ Namespace Editors
'CONTAINER_MAIN.ContentPanel
'
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 400)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 425)
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
@@ -2109,18 +2140,16 @@ Namespace Editors
Me.CONTAINER_MAIN.TabIndex = 0
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'CH_STD_YT_CREATE_URL
'CH_FEED_SHOW_SPEC_MEDIAITEM
'
Me.CH_STD_YT_CREATE_URL.AutoSize = True
Me.CH_STD_YT_CREATE_URL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_STD_YT_CREATE_URL.Location = New System.Drawing.Point(4, 322)
Me.CH_STD_YT_CREATE_URL.Name = "CH_STD_YT_CREATE_URL"
Me.CH_STD_YT_CREATE_URL.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
Me.CH_STD_YT_CREATE_URL.Size = New System.Drawing.Size(568, 19)
Me.CH_STD_YT_CREATE_URL.TabIndex = 12
Me.CH_STD_YT_CREATE_URL.Text = "Create URL files"
TT_MAIN.SetToolTip(Me.CH_STD_YT_CREATE_URL, "Create local URL files to link to the original page")
Me.CH_STD_YT_CREATE_URL.UseVisualStyleBackColor = True
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.AutoSize = True
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Location = New System.Drawing.Point(4, 247)
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Name = "CH_FEED_SHOW_SPEC_MEDIAITEM"
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Size = New System.Drawing.Size(568, 19)
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.TabIndex = 9
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.Text = "Show special feeds in media items"
Me.CH_FEED_SHOW_SPEC_MEDIAITEM.UseVisualStyleBackColor = True
'
'GlobalSettingsForm
'
@@ -2310,5 +2339,7 @@ Namespace Editors
Private WithEvents CH_FEED_SHOW_FRIENDLY As CheckBox
Private WithEvents COLORS_SUBSCRIPTIONS_USERS As ColorPicker
Private WithEvents CH_STD_YT_CREATE_URL As CheckBox
Private WithEvents CH_USE_DEF_ACC As CheckBox
Private WithEvents CH_FEED_SHOW_SPEC_MEDIAITEM As CheckBox
End Class
End Namespace

Some files were not shown because too many files have changed in this diff Show More