Compare commits

..

15 Commits

Author SHA1 Message Date
Andy
60b459e217 3.0.0.10
Added downloading groups
Added downloading Twitter saved posts
Added scripts when closing and completing the download
Opening Info and Progress forms when downloads start
Disabling the opening of forms Info and Progress at the start of downloads if it was once closed
Added focusing the main window when opening Info or Progress forms
Fixed downloading Instagram tagged data
Fixed forbidden characters Instagram stories
Updated form field checkers
Fixed downloading Imgur and Gfycat if they were posted on Reddit
Fixed separate Instagram posts were not downloading via the Video Downloader form.
Date time filenames
Twitter 4K images
2022-05-23 15:51:08 +03:00
Andy
f491e03812 Merge pull request #37 from unknown81311/main
Update MainFrame.vb
2022-05-02 08:11:35 +03:00
unknown81311
418f44edfd Update MainFrame.vb 2022-04-27 19:24:37 -06:00
Andy
075a2b9b80 3.0.0.9
Updated labels class
Moved some settings from SettingsCLS to LabelsKeeper
Excluded labels
Disable user grouping
Show groups of user sites when filtering by labels
Removed adding 'No Parsed' internal label
Fixed redownloading Instagram Stories
Changed global settings form
Updated Labels form
Fixed text separator in UserCreatorForm
Add target user if hidden
2022-04-24 20:35:30 +03:00
Andy
20c74ec8f1 Update ProgramsComparison.md 2022-04-20 18:48:06 +03:00
Andy
0594e77e0b 3.0.0.8
Script mode command
Disabled Instagram error 403
Fixed script does not run
2022-04-19 14:58:56 +03:00
Andy
a5fa935e76 3.0.0.7
Added script usage
Fixed  downloading of LPSG images
Fixed Instagram Stories
Fixed date/time file pattern
2022-04-14 18:12:01 +03:00
Andy
c90dd5637e Update Plugins.md 2022-04-12 05:41:03 +03:00
Andy
9a301ebc5e 3.0.0.6
Added GoTo Start/End channels buttons
Fixed saved Reddit posts downloading
Fixed Reddit accessibility check
Disabled main progress bar progress when downloading saved posts
Added Date and Time for Stories and Tagged Photos
2022-04-04 03:00:22 +03:00
Andy
11a590f14e 3.0.0.5
Added options for Reddit channel and user
Fixed minor bugs and typos
2022-04-02 04:36:38 +03:00
Andy
975d46715c 3.0.0.4
Changed XVIDEOS.M3U8 errors
Added TryCatch to XVIDEOS.UserData.Download
Removed old declarations in UserDataBase
Changed description replacement in UserDataHost
2022-03-26 20:00:55 +03:00
Andy
726fc486ce 3.0.0.3
Added additional 'download all' options
Fixed ListImagesLoader (User.FitToAddParams)
Fixed Instagram default value of SleepTimerOnPostsLimit
Fixed XVIDEOS typo
2022-03-24 19:14:58 +03:00
Andy
ede81f9d05 Update HowToSupport.md 2022-03-23 00:41:18 +03:00
Andy
fccb786e55 3.0.0.2
Added plugins: LPSG, XVIDEOS
Updated hosts
Deleted IResponserContainer
Updated SiteSettingsForm (properties, responser, button, cookies, offset)
Updated plugin dependencies
Fixed Instagram algo typo
2022-03-22 20:14:17 +03:00
Andy
2be52c7c56 Update README.md
Added additional authorization info
2022-03-20 16:00:10 +03:00
122 changed files with 7215 additions and 744 deletions

View File

@@ -26,8 +26,10 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Release information (please complete the following information):** **Release information (please complete the following information):**
- OS [e.g. Windows 10, Windows 11]
- Architecture [e.g. x86, x64] - Architecture [e.g. x86, x64]
- Version [e.g. 2.0.0.0] - Version [e.g. 2.0.0.0]
- NET.Framework version
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View File

@@ -1,3 +1,95 @@
# 3.0.0.10
- Added
- **Downloading groups**
- **Download saved Twitter posts** (bookmarks)
- Ability to enable/disable progress form opening at the start of downloading
- Ability to enable/disable Info form opening at the start of downloading
- The ability to disable the opening of forms Info and Progress at the start of downloads if it was once closed
- Focusing the main window when opening Info or Progress forms
- Ability to execute a script/command when closing SCrawler
- Ability to execute a script/command after all downloads are completed
- Minor improvements
- Fixed
- Instagram tagged data not downloading (now requires one more parameter **x-csrftoken** to download tagged data)
- In some cases, Instagram Stories cannot be downloaded due to forbidden Windows characters
- Separate Instagram posts were not downloading via the Video Downloader form.
- In some cases, an Imgur video hosted on Reddit won't download
- Gfycat data not downloading from saved Reddit posts
- In some cases, the date and time are not added to the filename
- Unable to download photos from Twitter in full resolution (4K)
# 3.0.0.9
- Added
- Excluded labels
- Ability to disable user grouping
- Ability to show groups of user sites when filtering by labels
- Fixed
- Removed adding "No Parsed" internal label when not needed
- Redownloading Instagram Stories
# 3.0.0.8
- Added
- Script mode ```command```
- Disabled Instagram error 403 (Forbidden) logging for downloading tagged data
- Fixed
- The script does not run after the user download is complete
# 3.0.0.7
- Added
- Ability to run a script after the user download is complete
- Hotkey ```F2``` for additional options in the user creation form
- Fixed
- (Issue #32) In some cases, Date and Time are still not added for Stories and Tagged Photos
- (Issue #33) Instagram Stories downloading error
- LPSG downloader does not download all content
# 3.0.0.6
- Added
- ```GoTo Start``` channels button
- ```GoTo End``` channels button
- Fixed
- In some cases, saved Reddit posts didn't fully download
- Incorrect Reddit accessibility check algorithm
- Incorrect behavior of the main progress bar when downloading saved posts
- (Issue #25) Date and Time not added for Stories and Tagged Photos
# 3.0.0.5
- Added
- ```New```, ```Hot```, ```Top``` Reddit channel and user download modes
# 3.0.0.4
- Fixed
- External plugins do not save information about downloaded files
- The user cannot be added to the collection if a special path has been specified.
# 3.0.0.3
- Added
- Download all by specific sites
- Download all, ignoring the ```Ready for download``` option
- Download all by specific sites, ignoring the ```Ready for download``` option
- Fixed
- (Issue #19) Typo in default Instagram settings (Post limit timer)
- Typo when applying "Download UHD" in XVIDEOS plugin
- The sites filter does not work unless the "Fast profiles loading" option is enabled.
# 3.0.0.2
- Added
- **LPSG** site plugin
- **XVIDEOS** site plugin
- Updated
- Plugin provider
- Fixed
- Minor bugs
# 3.0.0.1 # 3.0.0.1
- Added - Added

34
FAQ.md
View File

@@ -2,6 +2,8 @@
**Please read the [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) Before asking a question!** **Please read the [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) Before asking a question!**
**Also read [here](README.md) for basic information.**
Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide. Most of your questions are already answered. All settings, functions, buttons and everything else described in the guide.
Any other questions I will keep in this file. Any other questions I will keep in this file.
@@ -44,6 +46,30 @@ A: Check your credentials. Both of these sites require cookies. Check your [Twit
---- ----
#### Q: **I have set credentials but still nothing is downloading**
A: Click the ```Start downloading``` button
----
#### Q: **Where can I find the release?**
A: https://github.com/AAndyProgram/SCrawler/releases/latest
----
#### Q: **How to run the program?**
A: Double-click ```SCrawler.exe```
----
#### Q: **Where to find binaries?**
A: https://github.com/AAndyProgram/SCrawler/releases/latest
----
#### Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?** #### Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?**
A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**! A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
@@ -64,4 +90,10 @@ A: There is no functionality to remove an individual label. You can open the ```
#### Q: **How to remove a user from the blacklist** #### Q: **How to remove a user from the blacklist**
A: Just add that user back to the program. In the dialog box that opens, click on the ```Add and remove from blacklist```` button. A: Just add that user back to the program. In the dialog box that opens, click on the ```Add and remove from blacklist``` button.
----
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
A: **NO**! I will not do it. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.

View File

@@ -2,7 +2,7 @@ Your support is very valuable to me. Any support is greatly appreciated. Your su
You can support the program by: You can support the program by:
- **Bitcoin**: bitcoin:BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET - **Bitcoin**: bitcoin:BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
- :heavy_dollar_sign: making donaion making donations on this site: https://ko-fi.com/andyprogram - :heavy_dollar_sign: make a donation on this site: https://ko-fi.com/andyprogram
- :repeat: make a post about my program on your profile (Reddit, Twitter, Instagram and any other social networks) - :repeat: make a post about my program on your profile (Reddit, Twitter, Instagram and any other social networks)
- :speech_balloon: tell your friends about the program - :speech_balloon: tell your friends about the program
- :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/ - :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/

View File

@@ -1 +1,6 @@
List of available plugins List of available plugins:
- LPSG
- XVIDEOS
Tools:
- [image2post](https://github.com/unknown81311/SCrawler-image2post) by @unknown81311: **get reddit post URL from file.**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 KiB

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -19,7 +19,7 @@ https://www.4kdownload.com/products/product-stogram
| See Others Instagram Feed As Your Own | No | **Yes** | | See Others Instagram Feed As Your Own | No | **Yes** |
| Download Instagram Video Posts | Yes | Yes | | Download Instagram Video Posts | Yes | Yes |
| Backup Your Instagram Account | Yes | Yes | | Backup Your Instagram Account | Yes | Yes |
| Save Instagram Posts by Date | No (only limited download) | **Yes** | | Save Instagram Posts by Date | Yes | Yes |
| Download Instagram Saved Posts | Yes | Yes | | Download Instagram Saved Posts | Yes | Yes |
| Download Instagram Tagged Posts | Yes | Yes | | Download Instagram Tagged Posts | Yes | Yes |
| Export and import subscriptions | No | **Yes** | | Export and import subscriptions | No | **Yes** |

View File

@@ -1,7 +1,7 @@
# Social networks crawler # Social networks crawler
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/AAndyProgram/SCrawler)](https://github.com/AAndyProgram/SCrawler/releases/latest) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/AAndyProgram/SCrawler)](https://github.com/AAndyProgram/SCrawler/releases/latest)
[![GitHub](https://img.shields.io/github/license/AAndyProgram/SCrawler)](https://github.com/AAndyProgram/SCrawler/) [![GitHub license](https://img.shields.io/github/license/AAndyProgram/SCrawler)](https://github.com/AAndyProgram/SCrawler/blob/main/LICENSE)
[![FAQ](https://img.shields.io/badge/FAQ-green)](FAQ.md) [![FAQ](https://img.shields.io/badge/FAQ-green)](FAQ.md)
[![GUIDE](https://img.shields.io/badge/GUIDE-green)](https://github.com/AAndyProgram/SCrawler/wiki) [![GUIDE](https://img.shields.io/badge/GUIDE-green)](https://github.com/AAndyProgram/SCrawler/wiki)
[![How to support](https://img.shields.io/badge/HowToSupport-green)](HowToSupport.md) [![How to support](https://img.shields.io/badge/HowToSupport-green)](HowToSupport.md)
@@ -51,6 +51,8 @@ Do you like this program? Consider adding to my coffee fund by making a donation
- RedGifs - RedGifs
- Imgur - Imgur
- Gfycat - Gfycat
- LPSG
- XVIDEOS
- [Other sites](Plugins.md) - [Other sites](Plugins.md)
# How does it works: # How does it works:
@@ -73,9 +75,9 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
# Requirements # Requirements
- Windows 7, 8, 9, 10, 11 with NET Framework 4.6.1 or higher - Windows 7, 8, 9, 10, 11 with NET Framework 4.6.1 or higher (v4.6.1 must be installed). You can check version compatibility with this [tool](Tools/NET.FrameworkVersion.ps1).
- Authorization cookies and tokens for Twitter (if you want to download data from Twitter) - Authorization [cookies](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies) and [tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) for Twitter (if you want to download data from Twitter)
- Authorization cookies Instagram (if you want to download data from Instagram) - Authorization [cookies](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies) and [Hash](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram) for Instagram (if you want to download data from Instagram), [Hash 2](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-instagram-hash-2) for saved Instagram posts, Instagram [stories authorization headers](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-instagram-stories-authorization-headers) for Stories and Tagged data
- ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip)). **ffmpeg only works with the x64 version of the program.** - ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip)). **ffmpeg only works with the x64 version of the program.**
# Guide # Guide
@@ -110,7 +112,11 @@ Read more about how to support the program [here](HowToSupport.md).
The program has an intuitive interface. The program has an intuitive interface.
Just add a user profile and click the ```Start downloading``` button. You need to set up authorization for Twitter and Instagram:
- Authorization [cookies](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies) and [tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) for **Twitter** (if you want to download data from Twitter)
- Authorization [cookies](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies) and [Hash](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram) for **Instagram** (if you want to download data from Instagram), [Hash 2](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-instagram-hash-2) for **saved Instagram posts**, Instagram [stories authorization headers](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-instagram-stories-authorization-headers) for **Stories** and **Tagged data**
Just add a user profile and **click the ```Start downloading``` button**.
You can add users by patterns: You can add users by patterns:
- https://www.instagram.com/SomeUserName - https://www.instagram.com/SomeUserName

View File

@@ -0,0 +1,3 @@
[*.vb]
# Modifier preferences
file_header_template = Copyright (C) 2022 Andy\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

@@ -0,0 +1,48 @@
' Copyright (C) 2022 Andy
' 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.Functions.RegularExpressions
Friend Module Declarations
Friend ReadOnly Property PhotoRegEx As RParams = RParams.DM("(https://www.lpsg.com/attachments)(.+?)(?="")", 0, RegexReturn.List)
Friend ReadOnly Property PhotoRegExExt As New RParams("img.data.src=""(/proxy[^""]+?)""", Nothing, 1, RegexReturn.List) With {
.Converter = Function(Input) $"https://www.lpsg.com/{SymbolsConverter.HTML.Decode(Input)}"}
Friend ReadOnly Property NextPageRegex As RParams = RParams.DMS("<link rel=""next"" href=""(.+?/page-(\d+))""", 2)
Private Const FileUrlRegexDefault As String = "([^/]+?)(jpg|jpeg|gif|png|webm)"
Private ReadOnly InputFReplacer As New ErrorsDescriber(EDP.ReturnValue)
Private ReadOnly InputForbidRemover As Func(Of String, String) = Function(Input) If(Input.IsEmptyString, Input, Input.StringRemoveWinForbiddenSymbols(, InputFReplacer))
Friend ReadOnly Property FileRegEx As New RParams(FileUrlRegexDefault, Nothing, 0) With {
.Converter = Function(ByVal Input As String) As String
Input = InputForbidRemover.Invoke(Input)
If Not Input.IsEmptyString Then
Dim lv$ = Input.Split("-").LastOrDefault
If Not lv.IsEmptyString Then
Input = Input.Replace($"-{lv}", String.Empty)
Input &= $".{lv}"
End If
End If
Return Input
End Function}
Friend ReadOnly Property FileRegExExt As New RParams(FileUrlRegexDefault, 0, Nothing, InputForbidRemover)
Friend ReadOnly Property FileRegExExt2 As New RParams("([^/]+?)(?=(\Z|&))", 0, Nothing, InputForbidRemover)
Friend ReadOnly Property FileExistsRegEx As RParams = RParams.DMS(FileUrlRegexDefault, 2)
Private Class PUMComparer : Implements IEqualityComparer, IEqualityComparer(Of PluginUserMedia)
Private Overloads Function Equals(ByVal x As PluginUserMedia, ByVal y As PluginUserMedia) As Boolean Implements IEqualityComparer(Of PluginUserMedia).Equals
Return x.URL = y.URL
End Function
Private Function IEqualityComparer_Equals(ByVal x As Object, ByVal y As Object) As Boolean Implements IEqualityComparer.Equals
Return DirectCast(x, PluginUserMedia).URL = DirectCast(y, PluginUserMedia).URL
End Function
Private Overloads Function GetHashCode(ByVal Obj As Object) As Integer Implements IEqualityComparer.GetHashCode
Throw New NotImplementedException()
End Function
Private Overloads Function GetHashCode(ByVal Obj As PluginUserMedia) As Integer Implements IEqualityComparer(Of PluginUserMedia).GetHashCode
Throw New NotImplementedException()
End Function
End Class
Friend ReadOnly TempListAddParams As New ListAddParams(LAP.NotContainsOnly) With {.Comparer = New PUMComparer}
End Module

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,37 @@
Imports System.Resources
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
' Review the values of the assembly attributes
<Assembly: AssemblyTitle("LPSG")>
<Assembly: AssemblyDescription("LPSG plugin for SCrawler")>
<Assembly: AssemblyCompany("AndyProgram")>
<Assembly: AssemblyProduct("LPSG")>
<Assembly: AssemblyCopyright("Copyright © 2022")>
<Assembly: AssemblyTrademark("AndyProgram")>
<Assembly: ComVisible(False)>
'The following GUID is for the ID of the typelib if this project is exposed to COM
<Assembly: Guid("4beaf92d-0566-4331-ad29-034d09a7326f")>
' Version information for an assembly consists of the following four values:
'
' Major Version
' Minor Version
' Build Number
' Revision
'
' You can specify all the values or you can default the Build and Revision Numbers
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.2")>
<Assembly: AssemblyFileVersion("1.0.0.2")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -0,0 +1,83 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("LPSG.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
'''<summary>
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
'''</summary>
Friend ReadOnly Property Icon32() As System.Drawing.Icon
Get
Dim obj As Object = ResourceManager.GetObject("Icon32", resourceCulture)
Return CType(obj,System.Drawing.Icon)
End Get
End Property
'''<summary>
''' Looks up a localized resource of type System.Drawing.Bitmap.
'''</summary>
Friend ReadOnly Property IconPic_32() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("IconPic_32", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,127 @@
<?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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Icon32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Icons\Icon32.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="IconPic_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Pictures\IconPic_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@@ -0,0 +1,73 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.LPSG.My.MySettings
Get
Return Global.LPSG.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>LPSG</RootNamespace>
<AssemblyName>SCrawler.Plugin.LPSG</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x64\Debug\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x64\Release\</OutputPath>
<Optimize>true</Optimize>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x86\Debug\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x86\Release\</OutputPath>
<Optimize>true</Optimize>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="PersonalUtilities.Functions" />
<Import Include="PersonalUtilities.Tools.WEB" />
<Import Include="SCrawler.Plugin" />
<Import Include="SCrawler.Plugin.Attributes" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="Declarations.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="SiteSettings.vb" />
<Compile Include="UserData.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj">
<Project>{8405896b-2685-4916-bc93-1fb514c323a9}</Project>
<Name>PersonalUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\SCrawler.PluginProvider\SCrawler.PluginProvider.vbproj">
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
<Name>SCrawler.PluginProvider</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Content\Icons\Icon32.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Content\Pictures\IconPic_32.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@@ -0,0 +1,100 @@
' Copyright (C) 2022 Andy
' 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.Drawing
Imports PersonalUtilities.Functions.RegularExpressions
<Manifest("AndyProgram_LPSG")>
Public Class SiteSettings : Implements ISiteSettings
Public ReadOnly Property Icon As Icon Implements ISiteSettings.Icon
Get
Return My.Resources.Icon32
End Get
End Property
Public ReadOnly Property Image As Image Implements ISiteSettings.Image
Get
Return My.Resources.IconPic_32
End Get
End Property
Public ReadOnly Property Site As String = "LPSG" Implements ISiteSettings.Site
Public Property Logger As ILogProvider Implements ISiteSettings.Logger
Friend ReadOnly Property Responser As Response
Public Sub New()
Responser = New Response($"Settings\Responser_LPSG.xml")
With Responser
If .File.Exists Then
.LoadSettings()
Else
.CookiesDomain = "www.lpsg.com"
.Cookies = New CookieKeeper("www.lpsg.com")
End If
End With
End Sub
Public Sub BeginInit() Implements ISiteSettings.BeginInit
End Sub
Public Sub EndInit() Implements ISiteSettings.EndInit
End Sub
Public Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider Implements ISiteSettings.GetInstance
Return New UserData
End Function
Public Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Implements ISiteSettings.Load
End Sub
#Region "Download functions"
Public Sub DownloadStarted(ByVal What As ISiteSettings.Download) Implements ISiteSettings.DownloadStarted
End Sub
Public Sub BeforeStartDownload(ByVal User As Object, ByVal What As ISiteSettings.Download) Implements ISiteSettings.BeforeStartDownload
End Sub
Public Sub AfterDownload(ByVal User As Object, ByVal What As ISiteSettings.Download) Implements ISiteSettings.AfterDownload
End Sub
Public Sub DownloadDone(ByVal What As ISiteSettings.Download) Implements ISiteSettings.DownloadDone
End Sub
#End Region
#Region "Update"
Public Sub BeginUpdate() Implements ISiteSettings.BeginUpdate
End Sub
Public Sub EndUpdate() Implements ISiteSettings.EndUpdate
End Sub
Public Sub Update() Implements ISiteSettings.Update
Responser.SaveSettings()
End Sub
#End Region
Public Sub Reset() Implements ISiteSettings.Reset
End Sub
Public Sub OpenSettingsForm() Implements ISiteSettings.OpenSettingsForm
End Sub
Public Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
Options = Nothing
End Sub
Public Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String Implements ISiteSettings.GetUserUrl
Return $"https://www.lpsg.com/threads/{UserName}/"
End Function
Private ReadOnly UserRegEx As RParams = RParams.DMS(".+?lpsg.com/threads/([^/]+)", 1)
Public Function IsMyUser(ByVal UserURL As String) As ExchangeOptions Implements ISiteSettings.IsMyUser
Try
Dim r$ = RegexReplace(UserURL, UserRegEx)
If Not r.IsEmptyString Then
Return New ExchangeOptions(Site, r)
Else
Return Nothing
End If
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions Implements ISiteSettings.IsMyImageVideo
Return Nothing
End Function
Public Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable(Of PluginUserMedia) Implements ISiteSettings.GetSpecialData
Return Nothing
End Function
Public Function Available(ByVal What As ISiteSettings.Download) As Boolean Implements ISiteSettings.Available
Return True
End Function
Public Function ReadyToDownload(ByVal What As ISiteSettings.Download) As Boolean Implements ISiteSettings.ReadyToDownload
Return True
End Function
End Class

View File

@@ -0,0 +1,190 @@
' Copyright (C) 2022 Andy
' 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.Functions.RegularExpressions
Imports UStates = SCrawler.Plugin.PluginUserMedia.States
Imports UTypes = SCrawler.Plugin.PluginUserMedia.Types
Imports Converters = PersonalUtilities.Functions.SymbolsConverter.Converters
Public Class UserData : Implements IPluginContentProvider
#Region "XML names"
Private Const Name_LatestPage As String = "LatestPage"
#End Region
#Region "Interface declarations"
Public Event ProgressChanged(ByVal Count As Integer) Implements IPluginContentProvider.ProgressChanged
Public Event TotalCountChanged(ByVal Count As Integer) Implements IPluginContentProvider.TotalCountChanged
Public Property Thrower As IThrower Implements IPluginContentProvider.Thrower
Public Property LogProvider As ILogProvider Implements IPluginContentProvider.LogProvider
Public Property ESettings As ISiteSettings Implements IPluginContentProvider.Settings
Private ReadOnly Property Settings As SiteSettings
Get
Return DirectCast(ESettings, SiteSettings)
End Get
End Property
Public Property Name As String Implements IPluginContentProvider.Name
Public Property ID As String Implements IPluginContentProvider.ID
Public Property ParseUserMediaOnly As Boolean Implements IPluginContentProvider.ParseUserMediaOnly
Public Property UserDescription As String Implements IPluginContentProvider.UserDescription
Public Property ExistingContentList As List(Of PluginUserMedia) Implements IPluginContentProvider.ExistingContentList
Public Property TempPostsList As List(Of String) Implements IPluginContentProvider.TempPostsList
Public Property TempMediaList As List(Of PluginUserMedia) Implements IPluginContentProvider.TempMediaList
Public Property UserExists As Boolean Implements IPluginContentProvider.UserExists
Public Property UserSuspended As Boolean Implements IPluginContentProvider.UserSuspended
Public Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
Public Property SeparateVideoFolder As Boolean Implements IPluginContentProvider.SeparateVideoFolder
Public Property DataPath As String Implements IPluginContentProvider.DataPath
Public Property PostsNumberLimit As Integer? Implements IPluginContentProvider.PostsNumberLimit
Public Property PostsDateLimit As Date? Implements IPluginContentProvider.PostsDateLimit
#End Region
#Region "Interface exchange options"
Public Sub ExchangeOptionsSet(ByVal Obj As Object) Implements IPluginContentProvider.ExchangeOptionsSet
End Sub
Public Function ExchangeOptionsGet() As Object Implements IPluginContentProvider.ExchangeOptionsGet
Return Nothing
End Function
#End Region
#Region "Interface XML"
Public Sub XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String))) Implements IPluginContentProvider.XmlFieldsSet
If Fields.ListExists Then
For Each f As KeyValuePair(Of String, String) In Fields
If f.Key = Name_LatestPage Then LatestPage = f.Value
Next
End If
End Sub
Public Function XmlFieldsGet() As List(Of KeyValuePair(Of String, String)) Implements IPluginContentProvider.XmlFieldsGet
Return New List(Of KeyValuePair(Of String, String)) From {New KeyValuePair(Of String, String)(Name_LatestPage, LatestPage)}
End Function
#End Region
Private Property LatestPage As String = String.Empty
Private Property Responser As Response = Nothing
Private Enum Mode : Internal : External : End Enum
Public Sub GetMedia() Implements IPluginContentProvider.GetMedia
Try
If Not Responser Is Nothing Then Responser.Dispose()
Responser = New Response
With Responser : .Copy(Settings.Responser) : .Error = EDP.ThrowException : End With
Dim NextPage$
Dim r$
Dim _LPage As Func(Of String) = Function() If(LatestPage.IsEmptyString, String.Empty, $"page-{LatestPage}")
Do
r = Responser.GetResponse($"https://www.lpsg.com/threads/{Name}/{_LPage.Invoke}")
UserExists = True
UserSuspended = False
Thrower.ThrowAny()
If Not r.IsEmptyString Then
NextPage = RegexReplace(r, NextPageRegex)
UpdateMediaList(RegexReplace(r, PhotoRegEx), Mode.Internal)
UpdateMediaList(RegexReplace(r, PhotoRegExExt), Mode.External)
If NextPage = LatestPage Or NextPage.IsEmptyString Then Exit Do Else LatestPage = NextPage
Else
Exit Do
End If
Loop
If TempMediaList.ListExists And ExistingContentList.ListExists Then _
TempMediaList.RemoveAll(Function(m) ExistingContentList.Exists(Function(mm) mm.URL = m.URL))
Catch oex As OperationCanceledException
Catch dex As ObjectDisposedException
Catch ex As Exception
If Responser.StatusCode = Net.HttpStatusCode.ServiceUnavailable Then
LogProvider.Add("LPSG not available")
Else
LogProvider.Add(ex, "[LPSG.UserData.GetMedia]")
End If
End Try
End Sub
Private Sub UpdateMediaList(ByVal l As List(Of String), ByVal m As Mode)
If l.ListExists Then
Dim f As SFile
Dim u$
Dim exists As Boolean
Dim r As RParams
Dim ude As New ErrorsDescriber(EDP.ReturnValue)
For Each url$ In l
If Not url.IsEmptyString Then u = SymbolsConverter.Decode(url, {Converters.HTML, Converters.ASCII}, ude) Else u = String.Empty
If Not u.IsEmptyString Then
exists = Not IsEmptyString(RegexReplace(u, FileExistsRegEx))
If m = Mode.Internal Then
r = FileRegEx
Else
r = FileRegExExt
If Not exists Then
r = FileRegExExt2
exists = Not IsEmptyString(RegexReplace(u, FileRegExExt2))
End If
End If
If exists Then
f = CStr(RegexReplace(u, r))
f.Path = DataPath.CSFilePSN
f.Separator = "\"
If f.Extension.IsEmptyString Then f.Extension = "jpg"
TempMediaList.ListAddValue(New PluginUserMedia With {.ContentType = UTypes.Picture, .URL = url, .File = f}, TempListAddParams)
End If
End If
Next
End If
End Sub
Public Sub Download() Implements IPluginContentProvider.Download
Try
With Responser : .UseWebClient = True : .UseWebClientCookies = True : .ResetError() : End With
If TempMediaList.ListExists Then
Dim m As PluginUserMedia
Dim eweb As ErrorsDescriber = EDP.ThrowException
RaiseEvent TotalCountChanged(TempMediaList.Count)
For i% = 0 To TempMediaList.Count - 1
Thrower.ThrowAny()
m = TempMediaList(i)
m.DownloadState = UStates.Tried
Try
If Not m.URL.IsEmptyString And Not m.File.IsEmptyString Then
Responser.DownloadFile(m.URL, m.File, eweb)
m.DownloadState = UStates.Downloaded
Else
m.DownloadState = UStates.Skipped
End If
Catch wex As Exception
If Responser.Client.StatusCode = Net.HttpStatusCode.ServiceUnavailable Then
LogProvider.Add("LPSG not available")
Else
m.DownloadState = UStates.Skipped
End If
End Try
RaiseEvent ProgressChanged(1)
TempMediaList(i) = m
Next
End If
Catch oex As OperationCanceledException
Catch dex As ObjectDisposedException
Catch ex As Exception
LogProvider.Add(ex, "[LPSG.UserData.Download]")
End Try
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
If Not Responser Is Nothing Then Responser.Dispose()
If ExistingContentList.ListExists Then ExistingContentList.Clear()
If TempPostsList.ListExists Then TempPostsList.Clear()
If TempMediaList.ListExists Then TempMediaList.Clear()
End If
disposedValue = True
End If
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class

View File

@@ -0,0 +1,3 @@
[*.vb]
# Modifier preferences
file_header_template = Copyright (C) 2022 Andy\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

View File

@@ -0,0 +1,16 @@
' Copyright (C) 2022 Andy
' 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.Functions.RegularExpressions
Friend Module Declarations
Friend ReadOnly Property M3U8Regex As RParams = RParams.DM("http.+?.m3u8.*?(?=')", 0)
Friend ReadOnly Property VideoTitleRegex As RParams = RParams.DMS("html5player.setVideoTitle\('(.+)(?='\);)", 1)
Friend ReadOnly Property VideoID As RParams = RParams.DMS(".*?www.xvideos.com/(video\d+).*", 1)
Friend ReadOnly Property M3U8Reparse As RParams = RParams.DM("NAME=""(\d+).*?""[\r\n]*?(.+)(?=(|[\r\n]+?))", 0, RegexReturn.List)
Friend ReadOnly Property M3U8Appender As RParams = RParams.DM("(.+)(?=/.+?\.m3u8.*?)", 0)
End Module

View File

@@ -0,0 +1,69 @@
' Copyright (C) 2022 Andy
' 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.Net
Imports PersonalUtilities.Tools.WEB
Friend NotInheritable Class M3U8
Private Sub New()
End Sub
Private Shared Function Save(ByVal URLs As List(Of String), ByVal ffmpegFile As SFile, ByVal f As SFile, ByRef Logger As ILogProvider) As SFile
Dim CachePath As SFile = Nothing
Try
If URLs.ListExists Then
Dim ConcatFile As SFile = f
If ConcatFile.Name.IsEmptyString Then ConcatFile.Name = "PlayListFile"
ConcatFile.Extension = "mp4"
CachePath = $"{f.PathWithSeparator}_Cache\{SFile.GetDirectories($"{f.PathWithSeparator}_Cache\",,, EDP.ReturnValue).ListIfNothing.Count + 1}\"
If CachePath.Exists(SFO.Path) Then
Dim p As New SFileNumbers(ConcatFile.Name,,, New ANumbers With {.Format = ANumbers.Formats.General})
ConcatFile = SFile.Indexed_IndexFile(ConcatFile,, p, EDP.ReturnValue)
Dim i%
Dim eFiles As New List(Of SFile)
Dim dFile As SFile = CachePath
dFile.Extension = "ts"
Using w As New WebClient
For i = 0 To URLs.Count - 1
dFile.Name = $"ConPart_{i}"
w.DownloadFile(URLs(i), dFile)
eFiles.Add(dFile)
Next
End Using
f = FFMPEG.ConcatenateFiles(eFiles, ffmpegFile, ConcatFile, p, EDP.ThrowException)
eFiles.Clear()
Return f
End If
End If
Return Nothing
Catch ex As Exception
Logger.Add(ex, "[M3U8.Save]")
ex.HelpLink = 1
Throw ex
Finally
CachePath.Delete(SFO.Path, SFODelete.None, EDP.None)
End Try
End Function
Friend Shared Function Download(ByVal URL As String, ByVal Appender As String, ByVal ffmpegFile As SFile, ByVal f As SFile,
ByRef Logger As ILogProvider) As SFile
Try
If Not URL.IsEmptyString Then
Using w As New WebClient
Dim r$ = w.DownloadString(URL)
If Not r.IsEmptyString Then
Dim l As List(Of String) = ListAddList(Nothing, r.StringFormatLines.StringToList(Of String)(vbNewLine).ListWithRemove(Function(v) v.Trim.StartsWith("#")),
New ListAddParams With {.Converter = Function(Input) $"{Appender}/{Input.ToString.Trim}"})
If l.ListExists Then Return Save(l, ffmpegFile, f, Logger)
End If
End Using
End If
Return Nothing
Catch ex As Exception
If Not ex.HelpLink = 1 Then Logger.Add(ex, "[M3U8.Download]")
Throw ex
End Try
End Function
End Class

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,37 @@
Imports System.Resources
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
' Review the values of the assembly attributes
<Assembly: AssemblyTitle("XVIDEOS")>
<Assembly: AssemblyDescription("XVIDEOS plugin for SCrawler")>
<Assembly: AssemblyCompany("AndyProgram")>
<Assembly: AssemblyProduct("XVIDEOS")>
<Assembly: AssemblyCopyright("Copyright © 2022")>
<Assembly: AssemblyTrademark("AndyProgram")>
<Assembly: ComVisible(False)>
'The following GUID is for the ID of the typelib if this project is exposed to COM
<Assembly: Guid("d31a0e3b-081d-4155-9a41-4c0a641c87b6")>
' Version information for an assembly consists of the following four values:
'
' Major Version
' Minor Version
' Build Number
' Revision
'
' You can specify all the values or you can default the Build and Revision Numbers
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.2")>
<Assembly: AssemblyFileVersion("1.0.0.2")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -0,0 +1,83 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("XVIDEOS.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
'''<summary>
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
'''</summary>
Friend ReadOnly Property Icon32() As System.Drawing.Icon
Get
Dim obj As Object = ResourceManager.GetObject("Icon32", resourceCulture)
Return CType(obj,System.Drawing.Icon)
End Get
End Property
'''<summary>
''' Looks up a localized resource of type System.Drawing.Bitmap.
'''</summary>
Friend ReadOnly Property IconPic32() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("IconPic32", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,127 @@
<?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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Icon32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Icons\Icon32.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="IconPic32" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Content\Pictures\IconPic32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@@ -0,0 +1,73 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.XVIDEOS.My.MySettings
Get
Return Global.XVIDEOS.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>XVIDEOS</RootNamespace>
<AssemblyName>SCrawler.Plugin.XVIDEOS</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>
</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x64\Debug\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x64\Release\</OutputPath>
<Optimize>true</Optimize>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x86\Debug\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<DefineTrace>true</DefineTrace>
<OutputPath>bin\x86\Release\</OutputPath>
<Optimize>true</Optimize>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="PersonalUtilities.Functions" />
<Import Include="SCrawler.Plugin" />
<Import Include="SCrawler.Plugin.Attributes" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="Declarations.vb" />
<Compile Include="M3U8.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="SettingsForm.Designer.vb">
<DependentUpon>SettingsForm.vb</DependentUpon>
</Compile>
<Compile Include="SettingsForm.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="SiteSettings.vb" />
<Compile Include="UserData.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="SettingsForm.resx">
<DependentUpon>SettingsForm.vb</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj">
<Project>{8405896b-2685-4916-bc93-1fb514c323a9}</Project>
<Name>PersonalUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\SCrawler.PluginProvider\SCrawler.PluginProvider.vbproj">
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
<Name>SCrawler.PluginProvider</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Content\Pictures\IconPic32.png" />
</ItemGroup>
<ItemGroup>
<None Include="Content\Icons\Icon32.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@@ -0,0 +1,129 @@
' Copyright (C) 2022 Andy
' 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
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Public 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 resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SettingsForm))
Me.LIST_DOMAINS = New System.Windows.Forms.ListBox()
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
Me.BTT_ADD = New System.Windows.Forms.ToolStripButton()
Me.BTT_DELETE = New System.Windows.Forms.ToolStripButton()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.TopToolStripPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
Me.ToolbarTOP.SuspendLayout()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.LIST_DOMAINS)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 266)
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, 291)
CONTAINER_MAIN.TabIndex = 0
'
'CONTAINER_MAIN.TopToolStripPanel
'
CONTAINER_MAIN.TopToolStripPanel.Controls.Add(Me.ToolbarTOP)
'
'LIST_DOMAINS
'
Me.LIST_DOMAINS.Dock = System.Windows.Forms.DockStyle.Fill
Me.LIST_DOMAINS.FormattingEnabled = True
Me.LIST_DOMAINS.Location = New System.Drawing.Point(0, 0)
Me.LIST_DOMAINS.Name = "LIST_DOMAINS"
Me.LIST_DOMAINS.Size = New System.Drawing.Size(384, 266)
Me.LIST_DOMAINS.TabIndex = 0
'
'ToolbarTOP
'
Me.ToolbarTOP.Dock = System.Windows.Forms.DockStyle.None
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_ADD, Me.BTT_DELETE})
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
Me.ToolbarTOP.Name = "ToolbarTOP"
Me.ToolbarTOP.Size = New System.Drawing.Size(384, 25)
Me.ToolbarTOP.Stretch = True
Me.ToolbarTOP.TabIndex = 0
'
'BTT_ADD
'
Me.BTT_ADD.AutoToolTip = False
Me.BTT_ADD.BackColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer))
Me.BTT_ADD.ForeColor = System.Drawing.Color.DarkGreen
Me.BTT_ADD.Image = CType(resources.GetObject("BTT_ADD.Image"), System.Drawing.Image)
Me.BTT_ADD.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_ADD.Name = "BTT_ADD"
Me.BTT_ADD.Size = New System.Drawing.Size(49, 22)
Me.BTT_ADD.Text = "Add"
'
'BTT_DELETE
'
Me.BTT_DELETE.AutoToolTip = False
Me.BTT_DELETE.BackColor = System.Drawing.Color.FromArgb(CType(CType(255, Byte), Integer), CType(CType(192, Byte), Integer), CType(CType(192, Byte), Integer))
Me.BTT_DELETE.ForeColor = System.Drawing.Color.Maroon
Me.BTT_DELETE.Image = CType(resources.GetObject("BTT_DELETE.Image"), System.Drawing.Image)
Me.BTT_DELETE.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DELETE.Name = "BTT_DELETE"
Me.BTT_DELETE.Size = New System.Drawing.Size(60, 22)
Me.BTT_DELETE.Text = "Delete"
'
'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, 291)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(400, 330)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(400, 330)
Me.Name = "SettingsForm"
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "Settings"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.TopToolStripPanel.ResumeLayout(False)
CONTAINER_MAIN.TopToolStripPanel.PerformLayout()
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
Me.ToolbarTOP.ResumeLayout(False)
Me.ToolbarTOP.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents LIST_DOMAINS As Windows.Forms.ListBox
Private WithEvents ToolbarTOP As Windows.Forms.ToolStrip
Private WithEvents BTT_ADD As Windows.Forms.ToolStripButton
Private WithEvents BTT_DELETE As Windows.Forms.ToolStripButton
End Class

View File

@@ -0,0 +1,477 @@
<?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="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN+SURBVEhLrZVZSFRRGMdvKa6oE5Y1bpTtRY2pJYk3ayyd
xgrvaDXlQotLKVqSo7QR2QIREUX0EgUSET1V9NTyYBHt6ZTOqNPY7DomWNbriX/fuYzkg2jY/eAPM5zD
//+d7/7OvcJkFXIlqDX0ahDGE18LbJt6cSOtWWTaDhGbPonQdZEsIrY7cuWQwLapFzfZ9FlkES8ERL8W
EPteQMLHYFR69coFUNcs5o2AWe+nYW5HKFK7otHkL1IuoKBbZLzzFHMo0qwxWN8zG2eHSpULkGxalmIO
w2qrCvm2eJr/AlwZrlIuYN9XHcuwqKC3JWC3czGqXKm4OVKvXMARTyHTfUlEmWspatxp9D8Ld0ZM/xYw
EeejMnkMv0tdS1DnzkBzv4jT/jy0fm/EzLvhE0p9P7JV7jB3lHHiu6BHhMGmRbkjH3WebTjq245z/nL6
nYFjvnVo8efjzKAOrcONuD1skoNuDNfj8lAFWgZL0OQrphEWoMa1E+oHkZADuHn0K2L8rYDEjhBoCENO
itSXgr2u5TjkycTx/g1koMP5Qb0ccHogj8xEVLlTsaNvIXJ750BjiUZSewhU5LPTIv0N4J1zc76osUTR
ZjWKAuaHvZk44dPijF9HAXk4OaCFyZdNzyIde5zLUGifh5yeOKzoikJ8RzBU7wSE06Us+jQmoMAqIpnM
U6mDXJtaxrDSrUGDdw2O9a/HCTI96suByZuNw57VqKa1MtcybLXPxTo6qWzeHgx+Gbn5tCcCpHdjAnbZ
NmKtNZYwTESJYwnq6WE2EinNZMhNj3izZDXQqKppJJymLfZkZHfHYWlnJNQfghBFIw5rEyA8Jj2ggJdj
Ag769cw0ZGAtP8rYhZH97NLPanbpVxW7/PMAu/atlnSQzNeg0qWB0bkIensSmj3lqHUaf1d4ilipU2LG
LxIzWCUmfSZ9JL2VmBzAMR0PsVHxTbeGmlmleyWMjoXYTKfMpNPWuI3y2oTimE5WfOP1bw1sBz2X/N4E
pNONnm8Oxx6HQTYJbJt6cZOLAzUsrzdeftHxt2kskbLbFpjx/xY3OeWtYKssMUgkUmYQzvzbUDzK+f8W
N6l3lbCk9lCoCMOI5wKCnhIlZgUD9tkNjJuHUefTOYaPKOCNggEl3RILp84FukDCQ9I9CnihYEBxpySP
hNiWL5DURnqmVACxzI3G1aScC8If1IGynvf45pQAAAAASUVORK5CYII=
</value>
</data>
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVFSURBVEhLjZVrTJNXGMcLQmdHO6Sdt6ygAyYgN+1bS+uE
4ASlxVfSUkFkRMyouILinShGYzTRKCZL9mH7sH3YMj+YzUSXZXNeQOcEFkFhysbVQWlL6dsLvMwtWaBn
/1OKl1A2nuSX8p7znP/z5znnPa+ARntubkRjXNxnd5Ys6b2xbNmn+XL5WxgO80/+T/SoVOo/YmLu9S9d
+uhqfLwRQxEgxD9J44nZLH6Qm/tNT20tGbh4kTw9dMh3Q6NpyJBI3sF0+FRW8OhimHX2kpJB/vx5Ml5f
TwaKitwfJyZWxURGRmF6qkhDXNwn3QcOkKenTpGBkyeJFcmWI0fIdbX6XppEsgIpQYv0aTTvQdzCX7hA
eKzl6+rI+IkTpJdlPd/K5R8hRQrCBHdkMisVh3MyeOwYsSJp+OxZYq2t9d1QqX5OlUgSkPhKEbRlo724
2EqdU/FxiPOHD5NxGPOWlZHGxYs7kaYGEsGt6OhLvRUVZAAFLMB69CixY8HImTPEjnbdVqubU8TiRCT7
i/QoFBuHi4qsY+fOER5mxmGKx7rx/fvJ6O7dpEGl4splsq+RqgNSgWH58mXXlcp7/Tt3+oaQZAPDcDOC
PXGhZc6DB8kdFFktFic9ZJhcm9FoHzt92t8SHo55tJevqSFjEL+rUrkTRKIvIWwCaYBuuCCckckSUaTZ
smMHse/ZQxzV1WRk3z7CoZiH/jfV1b4WjaZjsKDAyh8/7nfMY45HLl9VNSWuVLqTRKJL0KsAyQHxUOAP
4WqpNOlHhaJpqLTU56isJE7gMpuJGwJeFPPu3UvG4HaMCuOZx7NfHO1t0mg86WIxFafOV4L54MVRDYRQ
JZWuvJWe3mzfupU4y8uJC3hMJuKFw1EUHMUGjhYUEO/69cSr0RA3aMrI8K6WSC5j/S5AnYvADPHpEK6J
ikpuSEtrtrHshHvbNuLSaomLYQgnlxNOIiFceDjh5s0jI2Kx73ZsrEcdFUU3tBKkgNfBrOLT4W/Xg/T0
9mEIOqgYcAIq7CcsjPzOMH8bExO/R/6HIBXMSdwf9rIys33dOotDJJopDuiYNT5+opFl+5OiowuwJBLM
TdxrMh3kNmzgHHA/m7gNDAJLcjJ5VFjYuX3t2lVY+p/Xij9cJlMdt2mTyxERMUPcid7TdlHxAdAbGkqe
gO5Vq3zthYW/GdVq2qbZi3h27TrG5eW5gzl3ymRkKC/vH3tCgo+K9wTE20ATeMwwk+1GY+f22YrgKNZx
Wq3HIRb7hV9py6JFpEun+/N0VlZL2+bNw5akJPIYoq3gPvgJNIL2NWsmW43Gjg1pafSCfHHVuysqajmd
zoNjN1N84ULSk5//rIphbiG1Oi8l5f1Ovb6/C72fFm8AN8F10KpSTbYUFrZ9wbJ044UgROA2GKwjCxYE
dU7FKxWKm0g0A7qR0n3Z2e92GAx9Hampz8V/AN+Ba6A9K2ui1WDoRu5yIBQ4jcYud0xMUOdmhrmNpKqA
+PSXSrg/J0eNje1rS031vSx+JSSEtGZmTtxlWRvyckGUoKW0tGSYZV0uiL7k/K89wcWnQ1iTnZ2Bje3F
C0muBsRxbUxe1mqHdCtWfI6cqQKI+TeLio5bt2zxONVqX49O96xGqWzA+Gzi0yE0ZWYqaDtase4XjWby
ilZre0MkqsecHky1CBHCxMZGPjQYvnqq1zsv5+Tg9IXWYJwBYjpPk2YJ4bXi4g9+1ett91mW0yYk0G+B
AcgBPa7P19I/FgAlyA/8zvX1fw3Qo0lPzmbwNgj6ws0D1DH9WNNf+jyXoCbo/f9mAFowYEwg+Bc5Ntw7
FHW1qQAAAABJRU5ErkJggg==
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAIAKgIAABGDgAAMDAAAAEA
IACoJQAA7hYAACAgAAABAAgAqAgAAJY8AAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAA
AAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAIO/wADF/8AAxb/AAEJ/wAAAP8AAAD/AAAA/wAAAP8AAQb/AAMV/wAD
F/8AAhL/AAAC/wAAAP8AAAD/AAAA/wAHMv8AFoz/ABiW/wAQaf8AAQz/AAAA/wAAAP8AAAT/AAxU/wAY
lP8AGJP/AAtJ/wAAAv8AAAD/AAAA/wAAAP8AAQ3/ABOQ/wAh3v8AH9T/AAtb/wAAAf8AAAD/AAc7/wAc
x/8AIeD/ABis/wADHv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAFK/8AG73/ACLk/wAbvf8ABSr/AAIV/wAW
o/8AIuP/AB7P/wAIRv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAH/AAtZ/wAf1v8AIeH/ABSU/wAQ
e/8AINz/ACDe/wAPdv8AAAX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wABC/8AE4z/ACHg/wAg
2/8AINn/ACHi/wAXpf8AAhn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAQm/wAa
t/8AIeH/ACHh/wAdyP8ABzr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAB
C/8AFZj/ACHi/wAh4f8AG7r/AAQh/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AClH/AB7S/wAh4P8AIeD/ACHe/wAQfP8AAAb/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8ABCX/ABq2/wAi4/8AGrn/ABag/wAh4P8AHtD/AAlH/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAQr/ABKI/wAh4f8AH9X/AApQ/wAEKP8AG7v/ACLk/wAYrv8AAx7/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/Ag1W/wIi1/8CJOP/ABOL/wABCv8AAAD/AAxc/wIi2f8CJOL/AhN//wABB/8AAAD/AAAA/wAA
AP8AAAD/CQ0h/ylBsv8vTt7/Iz67/wMJKv8AAAD/AAAA/wACEP8aMJr/L07e/y1Iyv8RGD//AAAA/wAA
AP8AAAD/AAAA/wUHEP8RFzL/Ehg0/wwQI/8BAQL/AAAA/wAAAP8AAAD/CAsY/xIYM/8SGDT/CAsZ/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAoAAAAGAAAADAAAAABACAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAEM/wADG/8AAxr/AAMa/wADFv8AAQT/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAB/wACEf8AAxv/AAMa/wADG/8AAhT/AAAC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAQk/wAT
dv8AF4b/ABeF/wAVgP8ACT7/AAAC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAQl/wATdP8AF4X/ABeF/wAW
gf8ACUD/AAAD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAI/wAOav8AHcX/AB/K/wAfyv8AGaz/AAQv/wAA
AP8AAAD/AAAA/wAAAP8AART/ABKL/wAeyf8AH8r/AB/L/wAVkv8AAhr/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wADJP8AF6v/ACHi/wAh4P8AIeD/ABKR/wABE/8AAAD/AAAA/wAAA/8ADGH/AB/W/wAh
4f8AIuL/ABzJ/wAISf8AAAH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AB0b/AB3K/wAh
4P8AIeD/AB7U/wALYP8AAAT/AAAA/wAFN/8AGr3/ACHi/wAh4P8AINr/AA5y/wAAB/8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAf/AA53/wAg2v8AIeD/ACHh/wAauv8ABTL/AAIT/wAT
k/8AId//ACHf/wAh4P8AFaD/AAIb/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAIg/wAVpP8AIeH/ACHg/wAh3v8AE5X/AA1z/wAf1P8AIeD/ACHh/wAbwf8ABjz/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAHQf8AHMX/ACHh/wAh
3/8AINr/AB/W/wAh4P8AIeD/AB/W/wAMZ/8AAAb/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAACP8ADXD/ACDZ/wAh4P8AId//ACHg/wAh3/8AId//ABSU/wAB
Fv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAhj/ABWe/wAh3/8AId//ACHf/wAh4P8AGrz/AAUx/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAT/AAxr/wAg3P8AId//ACHf/wAh
4f8AFqP/AAIT/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAyX/ABiv/wAh4P8AId//ACHf/wAh4P8AH9L/AApb/wAAAv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wABDf8AEYL/ACDd/wAh
3/8AIeD/ACHg/wAh3/8AIeH/ABm3/wAFL/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAC/wAKU/8AHs7/ACHh/wAh4P8AHMX/ABeo/wAg3P8AIeD/ACHf/wAS
jv8AARL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAQq/wAY
sP8AIeH/ACHg/wAf1/8ADGj/AAQy/wAYtP8AIeH/ACHg/wAe0v8AC1v/AAAD/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAQv/ABGG/wAg3f8AIeD/ACHh/wAVnf8AAhr/AAAB/wAL
XP8AH9P/ACHg/wAh4P8AGrn/AAQu/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
Av8ACVX/AB3R/wAg4P8AIOH/ABvE/wAHPv8AAAD/AAAA/wABE/8AE5L/ACDf/wAg3/8AIN//ABGO/wAB
Ef8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wULLv8NKbj/DjHn/w4x5f8MLt//ARFz/wAA
CP8AAAD/AAAA/wAAAP8ABTT/ByXD/w4x5v8OMeb/Di7Y/wgWYf8BAQT/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/BAYN/yg5hf9BXuH/QF7i/0Ff4/8tRa7/Awgd/wAAAP8AAAD/AAAA/wAAAP8AAQX/GChx/z9b
3f9BX+L/QV/k/zZOt/8MECj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgMJ/w8VMf8VHT//FRw9/xUc
Pv8KDiH/AAEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/BQcP/xMZOP8VHD7/FRw+/xMbPP8FBxL/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAA
AABAAAAAAQAIAAAAAAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAIDigAFBxBABMbPwADBhQADRMxABQb
QAASGj0AAQEGABsnWgBSbewAVXHyAFRx8QBVcvQANUqlAAABAwANFz8ATmjiAFVy8gA+U7UAAQIKAAAA
AgAULJcAG0LsABtB6gAZP+QAAQ1bAAAACAALKawAHELtABtB6wAbPtgABg46AAABHgAAGb0AACDhAAAg
3wAAIeEAABq/AAABIAAACGcAACDeAAAKcAAABlEAACDYAAAh4AAAId8AACHiAAARjQAAAAEAAAIpAAAc
xwAAIuIAABWoAAAACgAAEIsAAAZPAAAAAwAAE5cAAB7OAAADNgAAARsAABq7AAAZugAAARkAAAZXAAAg
2wAAC3AAAAVNAAAg1wAADoMAAAEiAAAavQAAEIcAAB/TAAAYtAAAARgAABm4AAAFSQAAH9YAAA6CAAAe
zAAAAzUAAAIzAAAQiAAAEIkAAAZSAAAg2gAAEpIAACDcAAAbwgAAASUAAAZbAAATmwAAB2EAABOZAAAA
BQAAAScAABvEAAACKgAAEY4AACHdAAAIZAAAAAQAAAhjAAABHwAAGr4AABzKAAACMQAACGIAACHcAAAT
nAAABlMAACDZAAAVpgAAAi0AABzIAAALcgAAAAYAABSgAAAe0AAAAzwAAAdOAAAcsQAAHLMAAB61AAAR
gQAABUcAABuvAAActAAAE4cAAAEVAAAUdQAAGIEAABeAAAAXgQAAE3MAAAtTAAAHQwAAAAcAAAIaAAAC
GQAAAQ4AAAEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAi4yNjY2MjgAAAAAAAAAAAAA5jY2NjYyPAAAAAAAAAACDhIWGhoeIgwAA
AAAAAAAAMYmFhoaGhYoAAAAAAAAAAAB6e3x8fH1+ZwAAAAAAAAB/gIF8fH2CGwAAAAAAAAAAAHZ3Ly4u
LlleAAAAAAAAaUglLi4teHkAAAAAAAAAAAAAAHN0JS4uJTNjAAAAABVkLy4uLi51AAAAAAAAAAAAAAAA
AG1uLi4uL29gAAAAcHEtLi40cjYAAAAAAAAAAAAAAAAAZ18vLi4uZWgAAGlqJS4uJWtsAAAAAAAAAAAA
AAAAAAAAYWIlLi4lM2MxZC8uLi5lZgAAAAAAAAAAAAAAAAAAAAAAXEItLi40XV4sLS4uL19gAAAAAAAA
AAAAAAAAAAAAAAAVWC8uLi5ZTy0uLiVaWwAAAAAAAAAAAAAAAAAAAAAAAAAnJiUuLi4tLi4tV0EAAAAA
AAAAAAAAAAAAAAAAAAAAAABWLC0uLi4uLiUwFQAAAAAAAAAAAAAAAAAAAAAAAAAAADFVLS4uLi4lTT0A
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNKLS4uLjRUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxUC4uLi4u
LVFSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PLS4uLi4uNDU2AAAAAAAAAAAAAAAAAAAAAAAAAABMTS8u
Li0lLi4uLkMAAAAAAAAAAAAAAAAAAAAAAAAAMUklLi4tSksuLi4tOzwAAAAAAAAAAAAAAAAAAAAAAABE
RS0uLiVGR0glLi40NTYAAAAAAAAAAAAAAAAAAAAAPT4lLi4lP0AAQUIuLi4uQwAAAAAAAAAAAAAAAAAA
ADE3JS4uLSw4AAA5OjQuLi07PAAAAAAAAAAAAAAAAAAAKywtLi4vMDEAAAAyMyUuLjQ1NgAAAAAAAAAA
AAAAACEiIyQkJSYnAAAAAAAoKSQkJCQqAAAAAAAAAAAAAAAVFhcYGBgZGgAAAAAAABscHRgYHh8gAAAA
AAAAAAAAAAkKCwwMDQ4PAAAAAAAAABAREgwMDRMUAAAAAAAAAAAAAQIDAwMDBAAAAAAAAAAAAAUGAwMD
BwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAMAAAAGAA
AAABACAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAC/wAAB/8AAAr/AAAJ/wAA
Cf8AAAn/AAAJ/wAACf8AAAj/AAAF/wAAAv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAH/AAAH/wAACf8AAAn/AAAJ/wAACf8AAAn/AAAJ/wAA
Cf8AAAf/AAAB/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAH/AAAI/wAD
Gv8ABSr/AAYq/wAGKv8ABSr/AAUq/wAGK/8ABSn/AAQh/wACEP8AAAL/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wABB/8AAhT/AAUm/wAGK/8ABSr/AAUq/wAF
Kv8ABir/AAYr/wAEJf8AAhj/AAAF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAP/AAEP/wAJPf8AEmj/ABRv/wAUb/8AE2//ABNv/wAUcP8AE27/ABFl/wAIOf8AAQ3/AAAC/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAEIf8AC03/ABJp/wAU
cP8AE2//ABNv/wATb/8AFG//ABRw/wANWP8ABTH/AAEK/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAH/AAAJ/wAHOP8AEXH/ABmV/wAbnv8AGpv/ABqc/wAanP8AGpz/ABmY/wAR
cv8ABzz/AAEM/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAX/AAEa/wAK
Uf8AFYf/ABmZ/wAbnf8AGpz/ABqc/wAbnf8AG5v/ABiO/wANWv8AAyD/AAAG/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wACHf8ACVT/ABed/wAduf8AHbv/AB27/wAd
u/8AHbv/AB68/wAaq/8AEHz/AAQo/wAABf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AARL/AAdM/wATjP8AHLn/AB28/wAdu/8AHbv/AB27/wAevf8AHLH/ABOG/wAIP/8AAAT/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAABP8ABCr/ABKL/wAc
xP8AINv/ACDZ/wAg2P8AINj/ACHY/wAg1/8AGrn/AApm/wACJP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAACP8ABDH/ABOR/wAcxv8AINn/ACDZ/wAg2P8AINj/ACDZ/wAg1/8AGrf/AApf/wAC
IP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAhH/AAlV/wAVpP8AINz/ACHh/wAh4f8AIeH/ACHg/wAi5P8AH9b/ABSk/wAIUv8AAA3/AAAC/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAEJv8ADGv/ABu//wAg3/8AIeL/ACHh/wAh4P8AIeH/ACLj/wAc
yf8AEY7/AAQy/wAACf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAX/AAEe/wANbv8AGr//ACDb/wAh4f8AId//ACHf/wAh4f8AId7/AB7R/wAR
hv8ABDL/AAEJ/wAAAP8AAAD/AAAA/wAAAP8AAAH/AAEL/wAKU/8AFqj/AB/X/wAh4/8AId//ACHf/wAh
4P8AId//ACDZ/wAUnv8AB0//AAEP/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAF/wAFOv8AD4b/AB7M/wAi4v8AId//ACHf/wAh
3/8AIeD/ACHf/wAZuP8ADXL/AAMZ/wAAAP8AAAD/AAAA/wAAAP8AAQv/AAQ4/wARi/8AHtH/ACHe/wAh
4P8AId//ACHf/wAi4v8AINv/ABm6/wAMZf8AARX/AAAD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wABE/8AB0j/ABem/wAf
1f8AIeH/ACHg/wAh3/8AIeD/ACHh/wAf1v8AF6j/AAdJ/wABE/8AAAD/AAAA/wAAAf8AAyD/AA10/wAZ
uf8AIeD/ACHg/wAh3/8AId//ACHg/wAh4f8AHMj/AA9+/wAFM/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAxj/AA1v/wAZtv8AIN//ACHg/wAh3/8AId//ACHf/wAi4v8AHs3/AA+H/wAFOv8AAAT/AAAA/wAB
E/8ACEr/ABes/wAf2P8AIeH/ACHf/wAh3/8AIeD/ACHh/wAe0v8AFaH/AAVA/wAAD/8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAn/AAMv/wAQg/8AHc//ACDe/wAh4f8AId//ACHf/wAh4f8AINv/ABq//wAN
bP8AARv/AAAE/wAGOf8AEYz/AB3N/wAh4f8AId//ACHf/wAh3/8AIeD/ACHf/wAXrv8ACWL/AAIZ/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAL/AAAM/wAITv8AE6D/AB7U/wAi4/8AId//ACHf/wAh
4P8AIeD/ACDa/wAVnv8ACVf/AAQ0/wANbv8AG7//ACDc/wAh4v8AId//ACHf/wAh4f8AIN3/ABzG/wAP
ef8AAyj/AAAH/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wACIf8ACWL/ABq6/wAg
3f8AIeD/ACHf/wAh3/8AIeD/ACLi/wAcxv8AE53/AA18/wAVpv8AIdv/ACHg/wAh4P8AId//ACHf/wAh
4f8AHtD/ABOV/wAHQv8AAAL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
A/8ABCj/ABGH/wAbxf8AIeL/ACHg/wAh3/8AId//ACHg/wAg2f8AHc//ABvF/wAe0f8AId//ACHf/wAh
3/8AId//ACHh/wAf2f8AGLD/AAhQ/wABF/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAQ7/AAdI/wAUmf8AH9f/ACHf/wAh4P8AId//ACHf/wAh3/8AIeD/ACHf/wAh
3/8AIeD/ACHf/wAh3/8AIeD/ACHh/wAZvP8ADnj/AAMj/wAAA/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAP/AAAV/wALY/8AGbf/AB/Z/wAh4f8AId//ACHf/wAh
3/8AId//ACHg/wAh3/8AId//ACHf/wAh4P8AId7/AB7S/wARjf8ABDv/AAEL/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAD/wAEMf8ADXn/ABzH/wAh
4f8AIeD/ACHf/wAh3/8AId//ACHf/wAh3/8AId//ACHf/wAh4v8AH9b/ABan/wAKU/8AAQz/AAAC/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
Dv8ABj3/ABWb/wAez/8AIeH/ACHg/wAh3/8AId//ACHf/wAh3/8AId//ACHg/wAg2/8AGrr/AAxn/wAE
Jf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAhT/AAtl/wAYsP8AId//ACHg/wAh3/8AId//ACHf/wAh3/8AIeD/ACHh/wAd
zv8AE5X/AAQv/wAABf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAr/AAM1/wASjf8AINj/ACHf/wAh4P8AId//ACHf/wAh
3/8AIeD/ACLi/wAavv8ADnf/AAMa/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAQ3/AAZG/wAUmf8AINv/ACHf/wAh
4P8AId//ACHf/wAh3/8AIeD/ACLh/wAdyf8AE4//AAQu/wAABv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAv8AAyL/AA56/wAa
vP8AIeD/ACHg/wAh3/8AId//ACHf/wAh3/8AId//ACHg/wAh3f8AG7r/AApf/wACIP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAB
Gf8ACFT/ABix/wAf2f8AIeD/ACHf/wAh3/8AId//ACHf/wAh3/8AId//ACHf/wAi4v8AH9P/ABWi/wAI
TP8AAAX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAG/wAHQv8AEpL/AB7Q/wAh4/8AId//ACHf/wAh3/8AIeD/ACHh/wAh4P8AId//ACHf/wAi
4f8AId7/AB3N/wAQgv8ABC//AAEJ/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAb/AAMi/wAPdf8AHMb/ACDd/wAh4f8AId//ACHf/wAh3/8AId7/ACDb/wAg
3f8AId//ACHf/wAh3/8AIeD/ACHg/wAYtP8ADGz/AAMc/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAhP/AAtg/wAXq/8AINz/ACHg/wAh3/8AId//ACHg/wAg
3P8AHtH/ABvA/wAdzf8AId//ACHf/wAh3/8AId//ACHg/wAf1f8AF6b/AAZF/wAAEf8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAADf8ABjv/ABWa/wAez/8AIeL/ACHg/wAh
3/8AIeD/ACHi/wAcy/8AFaL/AA51/wAVm/8AH9X/ACHf/wAh4P8AId//ACHf/wAi4f8AHcr/AA+C/wAF
NP8AAAH/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAC/wADLv8ADXX/ABzF/wAh
4f8AIeD/ACHf/wAh3/8AIeD/ACDd/wAWqf8ACmH/AAIo/wALX/8AGbb/AB/Z/wAh4v8AId//ACHf/wAi
4v8AINv/ABm7/wAMZf8AARX/AAAD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAP/AAAR/wAL
Xv8AGLP/AB/Y/wAh4f8AId//ACHf/wAh4f8AIN3/ABzI/wAPdv8AAiL/AAAJ/wAEMf8ADXz/ABzK/wAh
4v8AId//ACHf/wAh4P8AId//ACDZ/wAUnf8AB07/AAEP/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAQ3/AAZD/wATlP8AH9X/ACHf/wAh4P8AId//ACHf/wAi4v8AHtH/ABKW/wAHRf8AAAb/AAAA/wAA
D/8ABkL/ABak/wAf1P8AIuH/ACHg/wAh3/8AIeD/ACHh/wAcx/8AEYr/AAQu/wAAB/8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAv8ABCT/ABCB/wAbwv8AIeH/ACHg/wAh3/8AId//ACHg/wAg2/8AGbX/AAlZ/wAC
HP8AAAD/AAAA/wAAAP8AAxf/AA1u/wAZtv8AId//ACHg/wAh3/8AId//ACHg/wAh3v8AG7v/AApg/wAC
IP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wACHf8ACVr/ABm1/wAg2/8AIeD/ACHf/wAh3/8AIeD/ACHi/wAb
w/8AEIL/AAQk/wAAAv8AAAD/AAAA/wAAAP8AAQn/AAQw/wARhf8AHtH/ACHe/wAh4f8AId//ACHf/wAi
4v8AH9T/ABWi/wAITP8AAAX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAH/AAAI/wAHR/8AEZf/AB3R/wAg4v8AH9//AB/f/wAg
4P8AIN//AB7X/wATl/8AB0b/AAEN/wAAAP8AAAD/AAAA/wAAAP8AAAL/AAAN/wAJU/8AFab/AB7W/wAg
4v8AH97/AB/f/wAg4f8AH97/ABvM/wAOgf8AAy//AAAJ/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAQf/AgYp/wQUfP8EIcv/BCTf/wQl
4/8EJeH/BCXh/wQm4/8DJNr/ARq4/wAMY/8AABX/AAAD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAC
J/8AC2z/Ah3C/wMk4P8EJeH/BCXh/wQl4f8EJeL/BCXi/wQctv8EEG3/AQQc/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8DBhb/DR5s/xQx
uP8WO+b/Fjvp/xY76P8WO+j/Fjvo/xY86v8RM9H/BBaB/wAGNP8AAAP/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAABv8BBzH/CCGa/xAz1f8XPOv/Fjvp/xY76P8WO+n/Fjvp/xc63v8TLq7/CBJJ/wIE
Ev8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wYI
Ev8VH0r/L0ey/zpZ5/87Xvf/O131/ztd9P87XfX/O172/zRV5f8jPa//BxFG/wABEP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8CBRP/Chti/yM+tv85WvD/O130/zte9f87XfT/O131/zxe
9v84Vt7/KDqS/xEZPv8AAQT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/woPJf8gLmj/QFa8/0tk1/9KY9T/SmPU/0pj1P9KZNX/SmTW/z1Ttv8lNHX/BwsZ/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAwj/CQ8q/yc3ff9FXMj/SmPT/0pk
1f9KY9T/SmPU/0tk1/9IYM//O0+s/xslVP8AAQf/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wUIF/8PFzn/HCZX/x8rYP8fKl3/Hipd/x4qXf8fKl7/Hype/xYe
Rv8KDiT/AgMH/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAH/AgMI/w0T
LP8aI1L/Hilc/x8qXv8eKl3/Hipd/x8qXv8eKV3/GyVV/w0TLP8BAQX/AAAB/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIDCf8EBxT/BwoZ/wgLGv8HCxn/BwsZ/wcL
Gf8HCxn/BwsZ/wQGD/8AAAT/AAAB/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wIDCf8FBxT/BwoZ/wgLGv8HCxn/BwsZ/wcKGf8HCxr/Bwsa/wQGD/8AAAL/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAIAAAAAAAABAAAAAAAAAAA
AAAAAQAAAAEAAAAAAAAIDigAFBxBABMbPwADBhQADRMxABQbQAASGj0AAQEGABsnWgBSbewAVXHyAFRx
8QBVcvQANUqlAAABAwANFz8ATmjiAFVy8gA+U7UAAQIKAAAAAgAULJcAG0LsABtB6gAZP+QAAQ1bAAAA
CAALKawAHELtABtB6wAbPtgABg46AAABHgAAGb0AACDhAAAg3wAAIeEAABq/AAABIAAACGcAACDeAAAK
cAAABlEAACDYAAAh4AAAId8AACHiAAARjQAAAAEAAAIpAAAcxwAAIuIAABWoAAAACgAAEIsAAAZPAAAA
AwAAE5cAAB7OAAADNgAAARsAABq7AAAZugAAARkAAAZXAAAg2wAAC3AAAAVNAAAg1wAADoMAAAEiAAAa
vQAAEIcAAB/TAAAYtAAAARgAABm4AAAFSQAAH9YAAA6CAAAezAAAAzUAAAIzAAAQiAAAEIkAAAZSAAAg
2gAAEpIAACDcAAAbwgAAASUAAAZbAAATmwAAB2EAABOZAAAABQAAAScAABvEAAACKgAAEY4AACHdAAAI
ZAAAAAQAAAhjAAABHwAAGr4AABzKAAACMQAACGIAACHcAAATnAAABlMAACDZAAAVpgAAAi0AABzIAAAL
cgAAAAYAABSgAAAe0AAAAzwAAAdOAAAcsQAAHLMAAB61AAARgQAABUcAABuvAAActAAAE4cAAAEVAAAU
dQAAGIEAABeAAAAXgQAAE3MAAAtTAAAHQwAAAAcAAAIaAAACGQAAAQ4AAAEUAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi4yNjY2M
jgAAAAAAAAAAAAA5jY2NjYyPAAAAAAAAAACDhIWGhoeIgwAAAAAAAAAAMYmFhoaGhYoAAAAAAAAAAAB6
e3x8fH1+ZwAAAAAAAAB/gIF8fH2CGwAAAAAAAAAAAHZ3Ly4uLlleAAAAAAAAaUglLi4teHkAAAAAAAAA
AAAAAHN0JS4uJTNjAAAAABVkLy4uLi51AAAAAAAAAAAAAAAAAG1uLi4uL29gAAAAcHEtLi40cjYAAAAA
AAAAAAAAAAAAZ18vLi4uZWgAAGlqJS4uJWtsAAAAAAAAAAAAAAAAAAAAYWIlLi4lM2MxZC8uLi5lZgAA
AAAAAAAAAAAAAAAAAAAAXEItLi40XV4sLS4uL19gAAAAAAAAAAAAAAAAAAAAAAAVWC8uLi5ZTy0uLiVa
WwAAAAAAAAAAAAAAAAAAAAAAAAAnJiUuLi4tLi4tV0EAAAAAAAAAAAAAAAAAAAAAAAAAAABWLC0uLi4u
LiUwFQAAAAAAAAAAAAAAAAAAAAAAAAAAADFVLS4uLi4lTT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFNK
LS4uLjRUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxUC4uLi4uLVFSAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AE5PLS4uLi4uNDU2AAAAAAAAAAAAAAAAAAAAAAAAAABMTS8uLi0lLi4uLkMAAAAAAAAAAAAAAAAAAAAA
AAAAMUklLi4tSksuLi4tOzwAAAAAAAAAAAAAAAAAAAAAAABERS0uLiVGR0glLi40NTYAAAAAAAAAAAAA
AAAAAAAAPT4lLi4lP0AAQUIuLi4uQwAAAAAAAAAAAAAAAAAAADE3JS4uLSw4AAA5OjQuLi07PAAAAAAA
AAAAAAAAAAAAKywtLi4vMDEAAAAyMyUuLjQ1NgAAAAAAAAAAAAAAACEiIyQkJSYnAAAAAAAoKSQkJCQq
AAAAAAAAAAAAAAAVFhcYGBgZGgAAAAAAABscHRgYHh8gAAAAAAAAAAAAAAkKCwwMDQ4PAAAAAAAAABAR
EgwMDRMUAAAAAAAAAAAAAQIDAwMDBAAAAAAAAAAAAAUGAwMDBwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
</value>
</data>
</root>

View File

@@ -0,0 +1,73 @@
' Copyright (C) 2022 Andy
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Forms
Public Class SettingsForm : Implements IOkCancelToolbar
Private ReadOnly MyDefs As DefaultFormProps
Private ReadOnly Property Settings As SiteSettings
Friend Sub New(ByRef s As SiteSettings)
InitializeComponent()
MyDefs = New DefaultFormProps
Settings = s
End Sub
Private Sub SettingsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
With MyDefs
.MyViewInitialize(Me, Settings.Design, True)
.AddOkCancelToolbar()
.DelegateClosingChecker()
If Settings.Domains.Count > 0 Then Settings.Domains.ForEach(Sub(d) LIST_DOMAINS.Items.Add(d))
.EndLoaderOperations()
End With
Catch ex As Exception
MyDefs.InvokeLoaderError(ex)
End Try
End Sub
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
Settings.Domains.Clear()
With LIST_DOMAINS
If .Items.Count > 0 Then
For Each i In .Items : Settings.Domains.Add(i.ToString) : Next
End If
End With
Settings.UpdateDomains()
MyDefs.CloseForm()
End Sub
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
MyDefs.CloseForm(Windows.Forms.DialogResult.Cancel)
End Sub
Private Sub BTT_ADD_Click(sender As Object, e As EventArgs) Handles BTT_ADD.Click
Dim nd$ = InputBoxE("Enter a new domain using the pattern [xvideos.com]:", "New domain")
If Not nd.IsEmptyString Then
If Not LIST_DOMAINS.Items.Contains(nd) Then
LIST_DOMAINS.Items.Add(nd)
Else
MsgBoxE($"The domain [{nd}] already added")
End If
End If
End Sub
Private Sub BTT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE.Click
If _LatestSelected.ValueBetween(0, LIST_DOMAINS.Items.Count - 1) Then
Dim n$ = LIST_DOMAINS.Items(_LatestSelected)
If MsgBoxE({$"Are you sure you want to delete the [{n}] domain?",
"Removing domains"}, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
LIST_DOMAINS.Items.RemoveAt(_LatestSelected)
MsgBoxE($"Domain [{n}] removed")
Else
MsgBoxE("Operation canceled")
End If
Else
MsgBoxE("No domain selected", vbExclamation)
End If
End Sub
Private _LatestSelected As Integer = -1
Private Sub LIST_DOMENS_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_DOMAINS.SelectedIndexChanged
_LatestSelected = LIST_DOMAINS.SelectedIndex
End Sub
End Class

View File

@@ -0,0 +1,185 @@
' Copyright (C) 2022 Andy
' 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.Drawing
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.WEB
<Manifest("AndyProgram_XVIDEOS"), SpecialForm(True)>
Public Class SiteSettings : Implements ISiteSettings
Public ReadOnly Property Icon As Icon Implements ISiteSettings.Icon
Get
Return My.Resources.Icon32
End Get
End Property
Public ReadOnly Property Image As Image Implements ISiteSettings.Image
Get
Return My.Resources.IconPic32
End Get
End Property
Public ReadOnly Property Site As String = "XVIDEOS" Implements ISiteSettings.Site
Public Property Logger As ILogProvider Implements ISiteSettings.Logger
#Region "M3U8"
Private ReadOnly OS64 As Boolean
Private ReadOnly FfmpegExists As Boolean
Friend ReadOnly FfmpegFile As SFile
Friend ReadOnly Property UseM3U8 As Boolean
Get
Return OS64 And FfmpegExists
End Get
End Property
#End Region
<PXML("Domains")> Private Property SiteDomains As PropertyValue
<PropertyOption(ControlText:="Download UHD", ControlToolTip:="Download UHD (4K) content"), PXML>
Public Property DownloadUHD As PropertyValue
Friend ReadOnly Property Domains As List(Of String)
Public ReadOnly Property Responser As Response
Private Const DomainsDefault As String = "xvideos.com|xnxx.com"
Private _Initialized As Boolean = False
Friend Design As XmlFile
Public Sub New()
Responser = New Response($"Settings\Responser_{Site}.xml")
With Responser
If .File.Exists Then
.LoadSettings()
Else
.CookiesDomain = "www.xvideos.com"
.SaveSettings()
End If
End With
OS64 = Environment.Is64BitOperatingSystem
FfmpegFile = "ffmpeg.exe"
FfmpegExists = FfmpegFile.Exists
Domains = New List(Of String)
SiteDomains = New PropertyValue(DomainsDefault, GetType(String), Sub(s) UpdateDomains())
DownloadUHD = New PropertyValue(False)
End Sub
Public Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider Implements ISiteSettings.GetInstance
Return New UserData
End Function
Public Sub BeginInit() Implements ISiteSettings.BeginInit
End Sub
Public Sub EndInit() Implements ISiteSettings.EndInit
_Initialized = True
UpdateDomains()
End Sub
Public Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Implements ISiteSettings.Load
End Sub
Private _DomainsUpdateInProgress As Boolean = False
Friend Sub UpdateDomains()
If Not _Initialized Then Exit Sub
If Not _DomainsUpdateInProgress Then
_DomainsUpdateInProgress = True
If Not ACheck(SiteDomains.Value) Then SiteDomains.Value = DomainsDefault
Domains.ListAddList(CStr(SiteDomains.Value).Split("|"), LAP.NotContainsOnly, LAP.ClearBeforeAdd)
Domains.ListAddList(DomainsDefault.Split("|"), LAP.NotContainsOnly)
SiteDomains.Value = Domains.ListToString("|")
_DomainsUpdateInProgress = False
End If
End Sub
#Region "Downloading"
Public Function Available(ByVal What As ISiteSettings.Download) As Boolean Implements ISiteSettings.Available
Return UseM3U8
End Function
Public Function ReadyToDownload(ByVal What As ISiteSettings.Download) As Boolean Implements ISiteSettings.ReadyToDownload
Return UseM3U8
End Function
Public Sub DownloadStarted(ByVal What As ISiteSettings.Download) Implements ISiteSettings.DownloadStarted
End Sub
Public Sub BeforeStartDownload(ByVal User As Object, ByVal What As ISiteSettings.Download) Implements ISiteSettings.BeforeStartDownload
End Sub
Public Sub AfterDownload(ByVal User As Object, ByVal What As ISiteSettings.Download) Implements ISiteSettings.AfterDownload
End Sub
Public Sub DownloadDone(ByVal What As ISiteSettings.Download) Implements ISiteSettings.DownloadDone
End Sub
#End Region
Public Sub BeginUpdate() Implements ISiteSettings.BeginUpdate
End Sub
Public Sub EndUpdate() Implements ISiteSettings.EndUpdate
End Sub
Public Sub Update() Implements ISiteSettings.Update
UpdateDomains()
Responser.SaveSettings()
End Sub
Public Sub Reset() Implements ISiteSettings.Reset
End Sub
Public Sub OpenSettingsForm() Implements ISiteSettings.OpenSettingsForm
Using f As New SettingsForm(Me)
Design = New XmlFile("Settings\Design_XVIDEOS.xml")
f.ShowDialog()
Design.Dispose()
End Using
End Sub
Public Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
Options = Nothing
End Sub
Public Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String Implements ISiteSettings.GetUserUrl
Dim user$ = UserName.Split("_").FirstOrDefault
user &= $"/{UserName.Replace($"{user}_", String.Empty)}"
Return user
End Function
Private Const UserRegexDefault As String = "/(profiles|[\w]*?[-]{0,1}channels)/([^/]+)(\Z|.*?)"
Private Const URD As String = ".*?{0}{1}"
Public Function IsMyUser(ByVal UserURL As String) As ExchangeOptions Implements ISiteSettings.IsMyUser
If Not UserURL.IsEmptyString Then
If Domains.Count > 0 Then
Dim uName$, uOpt$, fStr$
For i% = 0 To Domains.Count - 1
fStr = String.Format(URD, Domains(i), UserRegexDefault)
uName = RegexReplace(UserURL, RParams.DMS(fStr, 2))
If Not uName.IsEmptyString Then
uOpt = RegexReplace(UserURL, RParams.DMS(fStr, 1))
If Not uOpt.IsEmptyString Then Return New ExchangeOptions(Site, $"{uOpt}_{uName}")
End If
Next
End If
End If
Return Nothing
End Function
Public Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions Implements ISiteSettings.IsMyImageVideo
If Not URL.IsEmptyString And Domains.Count > 0 Then
If Domains.Exists(Function(d) URL.Contains(d)) Then Return New ExchangeOptions With {.UserName = URL, .Exists = True}
End If
Return Nothing
End Function
Private Class TempThrower : Implements IThrower
Private Sub ThrowAny() Implements IThrower.ThrowAny
End Sub
End Class
Public Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable(Of PluginUserMedia) Implements ISiteSettings.GetSpecialData
If Not URL.IsEmptyString And UseM3U8 Then
Dim f As SFile = Path.CSFileP
f.Name = "video"
f.Extension = "mp4"
#Disable Warning BC40000
If AskForPath Then f = SFile.SaveAs(f,, True, "mp4")
#Enable Warning
If Not f.IsEmptyString Then
Using user As New UserData With {
.LogProvider = Logger,
.Thrower = New TempThrower,
.ESettings = Me,
.DataPath = f.Path
}
With user
.TempMediaList = New List(Of PluginUserMedia) From {UserData.GetVideoData(URL, Responser.Copy, DownloadUHD.Value, String.Empty, Logger)}
If Not .TempMediaList(0).URL.IsEmptyString Then
.Download()
If .TempMediaList(0).DownloadState = PluginUserMedia.States.Downloaded Then
Dim p As PluginUserMedia = .TempMediaList(0)
p.SpecialFolder = p.File
Return {p}
End If
End If
End With
End Using
End If
End If
Return Nothing
End Function
End Class

View File

@@ -0,0 +1,240 @@
' Copyright (C) 2022 Andy
' 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.Functions.RegularExpressions
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Tools.WEB
Imports PersonalUtilities.Tools.WebDocuments.JSON
Imports UStates = SCrawler.Plugin.PluginUserMedia.States
Imports UTypes = SCrawler.Plugin.PluginUserMedia.Types
Public Class UserData : Implements IPluginContentProvider
#Region "Interface declarations"
Public Event ProgressChanged(Count As Integer) Implements IPluginContentProvider.ProgressChanged
Public Event TotalCountChanged(Count As Integer) Implements IPluginContentProvider.TotalCountChanged
Public Property Thrower As IThrower Implements IPluginContentProvider.Thrower
Public Property LogProvider As ILogProvider Implements IPluginContentProvider.LogProvider
Public Property ESettings As ISiteSettings Implements IPluginContentProvider.Settings
Private ReadOnly Property Settings As SiteSettings
Get
Return DirectCast(ESettings, SiteSettings)
End Get
End Property
Public Property Name As String Implements IPluginContentProvider.Name
Public Property ID As String Implements IPluginContentProvider.ID
Public Property ParseUserMediaOnly As Boolean Implements IPluginContentProvider.ParseUserMediaOnly
Public Property UserDescription As String Implements IPluginContentProvider.UserDescription
Public Property ExistingContentList As List(Of PluginUserMedia) Implements IPluginContentProvider.ExistingContentList
Public Property TempPostsList As List(Of String) Implements IPluginContentProvider.TempPostsList
Public Property TempMediaList As List(Of PluginUserMedia) Implements IPluginContentProvider.TempMediaList
Public Property UserExists As Boolean Implements IPluginContentProvider.UserExists
Public Property UserSuspended As Boolean Implements IPluginContentProvider.UserSuspended
Public Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
Public Property SeparateVideoFolder As Boolean Implements IPluginContentProvider.SeparateVideoFolder
Public Property DataPath As String Implements IPluginContentProvider.DataPath
Public Property PostsNumberLimit As Integer? Implements IPluginContentProvider.PostsNumberLimit
Public Property PostsDateLimit As Date? Implements IPluginContentProvider.PostsDateLimit
#End Region
#Region "Interface exchange options"
Public Sub ExchangeOptionsSet(ByVal Obj As Object) Implements IPluginContentProvider.ExchangeOptionsSet
End Sub
Public Function ExchangeOptionsGet() As Object Implements IPluginContentProvider.ExchangeOptionsGet
Return Nothing
End Function
#End Region
#Region "Interface XML"
Public Sub XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String))) Implements IPluginContentProvider.XmlFieldsSet
End Sub
Public Function XmlFieldsGet() As List(Of KeyValuePair(Of String, String)) Implements IPluginContentProvider.XmlFieldsGet
Return Nothing
End Function
#End Region
Private Property Responser As Response
Public Sub GetMedia() Implements IPluginContentProvider.GetMedia
Try
If Not Settings.UseM3U8 Then LogProvider.Add("File [ffmpeg.exe] not found") : Exit Sub
If Not Responser Is Nothing Then Responser.Dispose()
Responser = New Response
Responser.Copy(Settings.Responser)
Dim NextPage% = 0
Dim r$
Dim j As EContainer, jj As EContainer
Dim e As ErrorsDescriber = EDP.ThrowException
Dim user$ = Settings.GetUserUrl(Name, False)
Dim p As PluginUserMedia
Dim EnvirSet As Boolean = False
Do
Thrower.ThrowAny()
r = Responser.GetResponse($"https://www.xvideos.com/{user}/videos/new/{If(NextPage = 0, String.Empty, NextPage)}",, e)
If Not r.IsEmptyString Then
If Not EnvirSet Then UserExists = True : UserSuspended = False : EnvirSet = True
j = JsonDocument.Parse(r).XmlIfNothing
With j
If .Contains("videos") Then
With .Item("videos")
If .Count > 0 Then
NextPage += 1
For Each jj In .Self
p = New PluginUserMedia With {
.PostID = jj.Value("id"),
.URL = $"https://www.xvideos.com{jj.Value("u")}"
}
If Not p.PostID.IsEmptyString And Not jj.Value("u").IsEmptyString Then
If Not TempPostsList.Contains(p.PostID) Then TempPostsList.Add(p.PostID) : TempMediaList.Add(p) Else Exit Do
End If
Next
End If
End With
Else
.Dispose()
Exit Do
End If
.Dispose()
End With
Else
Exit Do
End If
Loop
If TempMediaList.Count > 0 Then
For i% = 0 To TempMediaList.Count - 1
Thrower.ThrowAny()
With TempMediaList(i)
TempMediaList(i) = GetVideoData(.URL, Responser, Settings.DownloadUHD.Value, .PostID, LogProvider)
End With
Next
TempMediaList.RemoveAll(Function(m) m.URL.IsEmptyString)
End If
Catch oex As OperationCanceledException
Catch dex As ObjectDisposedException
Catch ex As Exception
If Responser.StatusCode = Net.HttpStatusCode.NotFound Then
UserExists = False
Else
LogProvider.Add(ex, "[XVIDEOS.UserData.GetMedia]")
End If
Finally
If TempMediaList.ListExists Then TempMediaList.RemoveAll(Function(m) m.URL.IsEmptyString)
End Try
End Sub
Private Structure VSize : Implements IRegExCreator, IComparable(Of VSize)
Friend Size As Integer
Friend Value As String
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
If ParamsArray.ListExists(2) Then
Size = AConvert(Of Integer)(ParamsArray(0), 0)
Value = ParamsArray(1)
End If
Return Me
End Function
Private Function CompareTo(ByVal Other As VSize) As Integer Implements IComparable(Of VSize).CompareTo
Return Size.CompareTo(Other.Size) * -1
End Function
End Structure
Friend Shared Function GetVideoData(ByVal URL As String, ByVal resp As Response, ByVal DownloadUHD As Boolean,
ByVal ID As String, ByRef Logger As ILogProvider) As PluginUserMedia
Try
If Not URL.IsEmptyString Then
Dim r$ = resp.GetResponse(URL,, EDP.ThrowException)
If Not r.IsEmptyString Then
Dim m$ = RegexReplace(r, M3U8Regex)
If Not m.IsEmptyString Then
Dim appender$ = RegexReplace(m, M3U8Appender)
Dim t$ = RegexReplace(r, VideoTitleRegex)
r = resp.GetResponse(m,, EDP.ThrowException)
If Not r.IsEmptyString Then
Dim ls As List(Of VSize) = FNF.RegexFields(Of VSize)(r, {M3U8Reparse}, {1, 2})
If ls.ListExists And Not DownloadUHD Then ls.RemoveAll(Function(v) v.Size > 1080)
If ls.ListExists Then
ls.Sort()
m = $"{appender}/{ls(0).Value}"
ls.Clear()
Dim pID$ = ID
If pID.IsEmptyString Then pID = RegexReplace(r, VideoID)
If pID.IsEmptyString Then pID = "0"
If Not t.IsEmptyString Then t = t.StringRemoveWinForbiddenSymbols(" ")
If t.IsEmptyString Then
t = pID
Else
If t.Length > 100 Then t = Left(t, 100)
End If
If Not m.IsEmptyString Then
Return New PluginUserMedia With {
.ContentType = UTypes.m3u8,
.PostID = pID,
.URL = m,
.File = $"{t}.mp4",
.SpecialFolder = appender
}
End If
End If
End If
End If
End If
End If
Return Nothing
Catch ex As Exception
Logger.Add(ex, $"[XVIDEOS.UserData.GetVideoData({URL})]")
Return Nothing
End Try
End Function
Public Sub Download() Implements IPluginContentProvider.Download
Try
If TempMediaList.Count > 0 Then
RaiseEvent TotalCountChanged(TempMediaList.Count - 1)
Dim m As PluginUserMedia
Dim f As SFile
Dim DefPath As String = DataPath.CSFilePSN
For i% = 0 To TempMediaList.Count - 1
Thrower.ThrowAny()
m = TempMediaList(i)
f = m.File
f.Path = DefPath
m.DownloadState = UStates.Tried
Try
f = M3U8.Download(m.URL, m.SpecialFolder, Settings.FfmpegFile, f, LogProvider)
m.File = f
m.DownloadState = UStates.Downloaded
Catch ex As Exception
m.DownloadState = UStates.Skipped
End Try
TempMediaList(i) = m
RaiseEvent ProgressChanged(1)
Next
End If
Catch oex As OperationCanceledException
Catch dex As ObjectDisposedException
Catch ex As Exception
LogProvider.Add(ex, $"[XVIDEOS.UserData.Download]")
End Try
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
If Not Responser Is Nothing Then Responser.Dispose()
If TempMediaList.ListExists Then TempMediaList.Clear()
If TempPostsList.ListExists Then TempPostsList.Clear()
If ExistingContentList.ListExists Then ExistingContentList.Clear()
End If
disposedValue = True
End If
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class

View File

@@ -7,7 +7,7 @@
' This program is distributed in the hope that it will be useful, ' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY ' but WITHOUT ANY WARRANTY
Namespace Plugin Namespace Plugin
Public Interface IPluginContentProvider Public Interface IPluginContentProvider : Inherits IDisposable
Event ProgressChanged(ByVal Count As Integer) Event ProgressChanged(ByVal Count As Integer)
Event TotalCountChanged(ByVal Count As Integer) Event TotalCountChanged(ByVal Count As Integer)
Property Thrower As IThrower Property Thrower As IThrower
@@ -19,7 +19,7 @@ Namespace Plugin
Property UserDescription As String Property UserDescription As String
Property ExistingContentList As List(Of PluginUserMedia) Property ExistingContentList As List(Of PluginUserMedia)
Property TempPostsList As List(Of String) Property TempPostsList As List(Of String)
Property TempMediaList As List(Of IPluginUserMedia) Property TempMediaList As List(Of PluginUserMedia)
Property UserExists As Boolean Property UserExists As Boolean
Property UserSuspended As Boolean Property UserSuspended As Boolean
Property IsSavedPosts As Boolean Property IsSavedPosts As Boolean

View File

@@ -17,10 +17,11 @@ Namespace Plugin
ReadOnly Property Icon As Icon ReadOnly Property Icon As Icon
ReadOnly Property Image As Image ReadOnly Property Image As Image
ReadOnly Property Site As String ReadOnly Property Site As String
Property Logger As ILogProvider
Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String
Function IsMyUser(ByVal UserURL As String) As ExchangeOptions Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
Function GetSpecialData(ByVal URL As String) As IEnumerable(Of IPluginUserMedia) Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable(Of PluginUserMedia)
Function GetInstance(ByVal What As Download) As IPluginContentProvider Function GetInstance(ByVal What As Download) As IPluginContentProvider
#Region "XML Support" #Region "XML Support"
Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String)))

View File

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

View File

@@ -1,40 +0,0 @@
' Copyright (C) 2022 Andy
' 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 Plugin
Public Structure PluginUserMedia : Implements IPluginUserMedia
Public Property ContentType As Integer Implements IPluginUserMedia.ContentType
Public Property URL As String Implements IPluginUserMedia.URL
Public Property MD5 As String Implements IPluginUserMedia.MD5
Public Property File As String Implements IPluginUserMedia.File
Public Property DownloadState As Integer Implements IPluginUserMedia.DownloadState
Public Property PostID As String Implements IPluginUserMedia.PostID
Public Property PostDate As Date? Implements IPluginUserMedia.PostDate
Public Property SpecialFolder As String Implements IPluginUserMedia.SpecialFolder
End Structure
Public Interface IPluginUserMedia
Enum Types As Integer
Undefined = 0
[Picture] = 1
[Video] = 2
[Text] = 3
VideoPre = 10
GIF = 50
m3u8 = 100
End Enum
Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : End Enum
Property ContentType As Integer
Property URL As String
Property MD5 As String
Property File As String
Property DownloadState As Integer
Property PostID As String
Property PostDate As Date?
Property SpecialFolder As String
End Interface
End Namespace

View File

@@ -0,0 +1,30 @@
' Copyright (C) 2022 Andy
' 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 Plugin
Public Structure PluginUserMedia
Enum Types As Integer
Undefined = 0
[Picture] = 1
[Video] = 2
[Text] = 3
VideoPre = 10
GIF = 50
m3u8 = 100
End Enum
Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : End Enum
Public ContentType As Integer
Public URL As String
Public MD5 As String
Public File As String
Public DownloadState As Integer
Public PostID As String
Public PostDate As Date?
Public SpecialFolder As String
End Structure
End Namespace

View File

@@ -105,7 +105,7 @@
<Compile Include="Objects\ExchangeOptions.vb" /> <Compile Include="Objects\ExchangeOptions.vb" />
<Compile Include="ObjectInterfaces\ILogProvider.vb" /> <Compile Include="ObjectInterfaces\ILogProvider.vb" />
<Compile Include="Interfaces\IPluginContentProvider.vb" /> <Compile Include="Interfaces\IPluginContentProvider.vb" />
<Compile Include="ObjectInterfaces\IPluginUserMedia.vb" /> <Compile Include="Objects\PluginUserMedia.vb" />
<Compile Include="Interfaces\ISiteSettings.vb" /> <Compile Include="Interfaces\ISiteSettings.vb" />
<Compile Include="ObjectInterfaces\IThrower.vb" /> <Compile Include="ObjectInterfaces\IThrower.vb" />
<Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\AssemblyInfo.vb" />

View File

@@ -17,6 +17,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.PluginProvider", "SCrawler.PluginProvider\SCrawler.PluginProvider.vbproj", "{D4650F6B-5A54-44B6-999B-6C675B7116B1}" Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.PluginProvider", "SCrawler.PluginProvider\SCrawler.PluginProvider.vbproj", "{D4650F6B-5A54-44B6-999B-6C675B7116B1}"
EndProject EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Plugin.LPSG", "SCrawler.Plugin.LPSG\SCrawler.Plugin.LPSG.vbproj", "{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}"
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Plugin.XVIDEOS", "SCrawler.Plugin.XVIDEOS\SCrawler.Plugin.XVIDEOS.vbproj", "{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -63,6 +67,30 @@ Global
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x64.Build.0 = Release|x64 {D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x64.Build.0 = Release|x64
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.ActiveCfg = Release|x86 {D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.ActiveCfg = Release|x86
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.Build.0 = Release|x86 {D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.Build.0 = Release|x86
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|x64.ActiveCfg = Debug|x64
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|x64.Build.0 = Debug|x64
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|x86.ActiveCfg = Debug|x86
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Debug|x86.Build.0 = Debug|x86
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|Any CPU.Build.0 = Release|Any CPU
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|x64.ActiveCfg = Release|x64
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|x64.Build.0 = Release|x64
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|x86.ActiveCfg = Release|x86
{22A130B2-DDF4-4FB5-BA38-E5DB4CF1B8A2}.Release|x86.Build.0 = Release|x86
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|x64.ActiveCfg = Debug|x64
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|x64.Build.0 = Debug|x64
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|x86.ActiveCfg = Debug|x86
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Debug|x86.Build.0 = Debug|x86
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|Any CPU.Build.0 = Release|Any CPU
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|x64.ActiveCfg = Release|x64
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|x64.Build.0 = Release|x64
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|x86.ActiveCfg = Release|x86
{CCCF47F4-C97C-4193-AC4B-C56DF2F9AA8A}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -33,25 +33,32 @@ Namespace API.Base
Friend Shared Function GetData(ByVal Site As String) As List(Of Data) Friend Shared Function GetData(ByVal Site As String) As List(Of Data)
Try Try
Dim l As List(Of Data) = Nothing Dim l As List(Of Data) = Nothing
Dim l2 As List(Of Data) = Nothing
Using w As New WebClient Using w As New WebClient
Dim r$ = w.DownloadString($"https://downdetector.co.uk/status/{Site}/") Dim r$ = w.DownloadString($"https://downdetector.co.uk/status/{Site}/")
If Not r.IsEmptyString Then If Not r.IsEmptyString Then
l = FNF.RegexFields(Of Data)(r, {Params}, {1, 2}) l = FNF.RegexFields(Of Data)(r, {Params}, {1, 2})
If l.ListExists(2) Then If l.ListExists(2) Then
Dim lDate As Date = l(0).Date
Dim i%
Dim indx% = -1
For i = 1 To l.Count - 1
If l(i).Date < lDate Then indx = i : Exit For Else lDate = l(i).Date
Next
If indx >= 0 Then
For i = indx To 0 Step -1 : l.RemoveAt(i) : Next
End If
l.Sort() l.Sort()
l2 = New List(Of Data)
Dim d As Data
Dim eDates As New List(Of Date)
Dim MaxValue As Func(Of Date, Integer) = Function(dd) (From ddd In l Where ddd.Date = dd Select ddd.Value).DefaultIfEmpty(0).Max
For i% = 0 To l.Count - 1
If Not eDates.Contains(l(i).Date) Then
d = l(i)
d.Value = MaxValue(d.Date)
l2.Add(d)
eDates.Add(d.Date)
End If
Next
eDates.Clear()
l.Clear()
l2.Sort()
End If End If
End If End If
End Using End Using
Return l Return l2
Catch ex As Exception Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, $"[DownDetector.GetData({Site})]") Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, $"[DownDetector.GetData({Site})]")
End Try End Try

View File

@@ -11,11 +11,12 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.WEB Imports PersonalUtilities.Tools.WEB
Imports Download = SCrawler.Plugin.ISiteSettings.Download Imports Download = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Base Namespace API.Base
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings
Friend ReadOnly Property Site As String Implements ISiteSettings.Site Friend ReadOnly Property Site As String Implements ISiteSettings.Site
Friend Overridable ReadOnly Property Icon As Icon = Nothing Implements ISiteSettings.Icon Friend Overridable ReadOnly Property Icon As Icon = Nothing Implements ISiteSettings.Icon
Friend Overridable ReadOnly Property Image As Image = Nothing Implements ISiteSettings.Image Friend Overridable ReadOnly Property Image As Image = Nothing Implements ISiteSettings.Image
Friend Overridable ReadOnly Property Responser As Response Implements IResponserContainer.Responser Private Property Logger As ILogProvider = LogConnector Implements ISiteSettings.Logger
Friend Overridable ReadOnly Property Responser As Response
Friend MustOverride Function GetInstance(ByVal What As Download) As IPluginContentProvider Implements ISiteSettings.GetInstance Friend MustOverride Function GetInstance(ByVal What As Download) As IPluginContentProvider Implements ISiteSettings.GetInstance
Friend Sub New(ByVal SiteName As String) Friend Sub New(ByVal SiteName As String)
Site = SiteName Site = SiteName
@@ -82,7 +83,7 @@ Namespace API.Base
Return Nothing Return Nothing
End If End If
End Function End Function
Friend Overridable Function GetSpecialData(ByVal URL As String) As IEnumerable(Of IPluginUserMedia) Implements ISiteSettings.GetSpecialData Friend Overridable Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable(Of PluginUserMedia) Implements ISiteSettings.GetSpecialData
Return Nothing Return Nothing
End Function End Function
Friend Overridable Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia) Friend Overridable Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)

View File

@@ -42,7 +42,7 @@ Namespace API.Base
Me.New(_URL) Me.New(_URL)
[Type] = _Type [Type] = _Type
End Sub End Sub
Friend Sub New(ByVal m As Plugin.IPluginUserMedia) Friend Sub New(ByVal m As Plugin.PluginUserMedia)
If Not IsNothing(m) Then If Not IsNothing(m) Then
[Type] = m.ContentType [Type] = m.ContentType
URL = m.URL URL = m.URL

View File

@@ -9,6 +9,8 @@
Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Forms.Toolbars Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Tools.WEB
Imports PersonalUtilities.Tools
Imports System.IO Imports System.IO
Imports System.Net Imports System.Net
Imports System.Threading Imports System.Threading
@@ -114,6 +116,9 @@ Namespace API.Base
Private Const Name_PicturesCount As String = "PicturesCount" Private Const Name_PicturesCount As String = "PicturesCount"
Private Const Name_LastUpdated As String = "LastUpdated" Private Const Name_LastUpdated As String = "LastUpdated"
Private Const Name_ScriptUse As String = "ScriptUse"
Private Const Name_ScriptData As String = "ScriptData"
Private Const Name_DataMerging As String = "DataMerging" Private Const Name_DataMerging As String = "DataMerging"
#Region "Downloaded data" #Region "Downloaded data"
Private Const Name_MediaType As String = "Type" Private Const Name_MediaType As String = "Type"
@@ -247,7 +252,7 @@ BlockPictureFolder:
End If End If
BlockPictureScan: BlockPictureScan:
On Error GoTo BlockDeletePictureFolder On Error GoTo BlockDeletePictureFolder
Dim NewPicFile As SFile = SFile.GetFiles(MyFile.CutPath, "*.jpg|*.png",, Dim NewPicFile As SFile = SFile.GetFiles(MyFile.CutPath, "*.jpg|*.jpeg|*.png",,
New ErrorsDescriber(EDP.ReturnValue) With { New ErrorsDescriber(EDP.ReturnValue) With {
.ReturnValue = New List(Of SFile), .ReturnValue = New List(Of SFile),
.ReturnValueExists = True}).FirstOrDefault .ReturnValueExists = True}).FirstOrDefault
@@ -404,6 +409,10 @@ BlockNullPicture:
End Get End Get
End Property End Property
#End Region #End Region
#Region "Script"
Friend Overridable Property ScriptUse As Boolean = False Implements IUserData.ScriptUse
Friend Overridable Property ScriptData As String Implements IUserData.ScriptData
#End Region
#End Region #End Region
#Region "Plugins Support" #Region "Plugins Support"
Protected Event ProgressChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressChanged Protected Event ProgressChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressChanged
@@ -421,7 +430,7 @@ BlockNullPicture:
Friend Property ExternalPlugin As IPluginContentProvider Friend Property ExternalPlugin As IPluginContentProvider
Private Property IPluginContentProvider_ExistingContentList As List(Of PluginUserMedia) Implements IPluginContentProvider.ExistingContentList Private Property IPluginContentProvider_ExistingContentList As List(Of PluginUserMedia) Implements IPluginContentProvider.ExistingContentList
Private Property IPluginContentProvider_TempPostsList As List(Of String) Implements IPluginContentProvider.TempPostsList Private Property IPluginContentProvider_TempPostsList As List(Of String) Implements IPluginContentProvider.TempPostsList
Private Property IPluginContentProvider_TempMediaList As List(Of IPluginUserMedia) Implements IPluginContentProvider.TempMediaList Private Property IPluginContentProvider_TempMediaList As List(Of PluginUserMedia) Implements IPluginContentProvider.TempMediaList
Private Property IPluginContentProvider_SeparateVideoFolder As Boolean Implements IPluginContentProvider.SeparateVideoFolder Private Property IPluginContentProvider_SeparateVideoFolder As Boolean Implements IPluginContentProvider.SeparateVideoFolder
Private Property IPluginContentProvider_DataPath As String Implements IPluginContentProvider.DataPath Private Property IPluginContentProvider_DataPath As String Implements IPluginContentProvider.DataPath
Private Sub IPluginContentProvider_XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String))) Implements IPluginContentProvider.XmlFieldsSet Private Sub IPluginContentProvider_XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String))) Implements IPluginContentProvider.XmlFieldsSet
@@ -468,6 +477,7 @@ BlockNullPicture:
Get Get
If Settings.LastUpdatedDate.HasValue AndAlso LastUpdated.HasValue AndAlso If Settings.LastUpdatedDate.HasValue AndAlso LastUpdated.HasValue AndAlso
LastUpdated.Value.Date > Settings.LastUpdatedDate.Value.Date Then Return False LastUpdated.Value.Date > Settings.LastUpdatedDate.Value.Date Then Return False
If Not Settings.Labels.ExcludedIgnore AndAlso Settings.Labels.Excluded.ValuesList.ListContains(Labels) Then Return False
If Settings.SelectedSites.Count = 0 OrElse Settings.SelectedSites.Contains(Site) Then If Settings.SelectedSites.Count = 0 OrElse Settings.SelectedSites.Contains(Site) Then
Select Case Settings.ShowingMode.Value Select Case Settings.ShowingMode.Value
Case ShowingModes.Regular : Return Not Temporary And Not Favorite Case ShowingModes.Regular : Return Not Temporary And Not Favorite
@@ -475,7 +485,7 @@ BlockNullPicture:
Case ShowingModes.Favorite : Return Favorite Case ShowingModes.Favorite : Return Favorite
Case ShowingModes.Deleted : Return Not UserExists Case ShowingModes.Deleted : Return Not UserExists
Case ShowingModes.Suspended : Return UserSuspended Case ShowingModes.Suspended : Return UserSuspended
Case ShowingModes.Labels : Return Settings.Labels.CurrentSelection.ListContains(Labels) Case ShowingModes.Labels : Return Settings.Labels.Current.ValuesList.ListContains(Labels)
Case ShowingModes.NoLabels : Return Labels.Count = 0 Case ShowingModes.NoLabels : Return Labels.Count = 0
Case Else : Return True Case Else : Return True
End Select End Select
@@ -486,16 +496,16 @@ BlockNullPicture:
End Property End Property
Friend Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup Implements IUserData.GetLVIGroup Friend Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup Implements IUserData.GetLVIGroup
Try Try
If Settings.ShowingMode.Value = ShowingModes.Labels Then If Settings.ShowingMode.Value = ShowingModes.Labels And Not Settings.ShowGroupsInsteadLabels Then
If Labels.Count > 0 And Settings.Labels.CurrentSelection.Count > 0 Then If Labels.Count > 0 And Settings.Labels.Current.Count > 0 Then
For i% = 0 To Labels.Count - 1 For i% = 0 To Labels.Count - 1
If Settings.Labels.CurrentSelection.Contains(Labels(i)) Then Return Destination.Groups.Item(Labels(i)) If Settings.Labels.Current.Contains(Labels(i)) Then Return Destination.Groups.Item(Labels(i))
Next Next
End If End If
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName) ElseIf Settings.ShowGroups Then
Else
Return Destination.Groups.Item(GetLviGroupName(HOST, Temporary, Favorite, IsCollection, IsChannel)) Return Destination.Groups.Item(GetLviGroupName(HOST, Temporary, Favorite, IsCollection, IsChannel))
End If End If
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
Catch ex As Exception Catch ex As Exception
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName) Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
End Try End Try
@@ -558,7 +568,7 @@ BlockNullPicture:
If MyFile.Exists Then If MyFile.Exists Then
FileExists = True FileExists = True
Using x As New XmlFile(MyFile) With {.XmlReadOnly = True} Using x As New XmlFile(MyFile) With {.XmlReadOnly = True}
User.Name = x.Value(Name_UserName) If User.Name.IsEmptyString Then User.Name = x.Value(Name_UserName)
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True) UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False) UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
ID = x.Value(Name_UserID) ID = x.Value(Name_UserID)
@@ -575,6 +585,8 @@ BlockNullPicture:
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0) DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0) DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing) LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
ScriptUse = x.Value(Name_ScriptUse).FromXML(Of Boolean)(False)
ScriptData = x.Value(Name_ScriptData)
DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False) DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False)
ChangeCollectionName(x.Value(Name_CollectionName), False) ChangeCollectionName(x.Value(Name_CollectionName), False)
Labels.ListAddList(x.Value(Name_LabelsName).StringToList(Of String, List(Of String))("|", EDP.ReturnValue), LAP.NotContainsOnly, LAP.ClearBeforeAdd) Labels.ListAddList(x.Value(Name_LabelsName).StringToList(Of String, List(Of String))("|", EDP.ReturnValue), LAP.NotContainsOnly, LAP.ClearBeforeAdd)
@@ -614,8 +626,10 @@ BlockNullPicture:
x.Add(Name_VideoCount, DownloadedVideos(True)) x.Add(Name_VideoCount, DownloadedVideos(True))
x.Add(Name_PicturesCount, DownloadedPictures(True)) x.Add(Name_PicturesCount, DownloadedPictures(True))
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty)) x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
x.Add(Name_ScriptUse, ScriptUse.BoolToInteger)
x.Add(Name_ScriptData, ScriptData)
x.Add(Name_CollectionName, CollectionName) x.Add(Name_CollectionName, CollectionName)
x.Add(Name_LabelsName, Labels.ListToString(, "|", EDP.ReturnValue)) x.Add(Name_LabelsName, Labels.ListToString("|", EDP.ReturnValue))
x.Add(Name_DataMerging, DataMerging.BoolToInteger) x.Add(Name_DataMerging, DataMerging.BoolToInteger)
LoadUserInformation_OptionalFields(x, False) LoadUserInformation_OptionalFields(x, False)
@@ -712,7 +726,7 @@ BlockNullPicture:
#Region "Download functions and options" #Region "Download functions and options"
Friend Overridable Property DownloadTopCount As Integer? = Nothing Implements IUserData.DownloadTopCount, IPluginContentProvider.PostsNumberLimit Friend Overridable Property DownloadTopCount As Integer? = Nothing Implements IUserData.DownloadTopCount, IPluginContentProvider.PostsNumberLimit
Friend Overridable Property DownloadToDate As Date? = Nothing Implements IUserData.DownloadToDate, IPluginContentProvider.PostsDateLimit Friend Overridable Property DownloadToDate As Date? = Nothing Implements IUserData.DownloadToDate, IPluginContentProvider.PostsDateLimit
Protected Responser As PersonalUtilities.Tools.WEB.Response Protected Responser As Response
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
Dim Canceled As Boolean = False Dim Canceled As Boolean = False
_ExternalCompatibilityToken = Token _ExternalCompatibilityToken = Token
@@ -720,12 +734,8 @@ BlockNullPicture:
UpdateDataFiles() UpdateDataFiles()
UserDescriptionReset() UserDescriptionReset()
If Not Responser Is Nothing Then Responser.Dispose() If Not Responser Is Nothing Then Responser.Dispose()
Responser = New PersonalUtilities.Tools.WEB.Response Responser = New Response
If TypeOf HOST.Source Is IResponserContainer Then If Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser)
With DirectCast(HOST.Source, IResponserContainer)
If Not .Responser Is Nothing Then Responser.Copy(.Responser)
End With
End If
Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(False) Is Nothing Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(False) Is Nothing
Dim sEnvir() As Boolean = {UserExists, UserSuspended} Dim sEnvir() As Boolean = {UserExists, UserSuspended}
@@ -755,7 +765,7 @@ BlockNullPicture:
ReparseVideo(Token) ReparseVideo(Token)
ThrowAny(Token) ThrowAny(Token)
If _TempPostsList.Count > 0 And __SaveData Then TextSaver.SaveTextToFile(_TempPostsList.ListToString(, Environment.NewLine), MyFilePosts, True,, EDP.None) If _TempPostsList.Count > 0 And __SaveData Then TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None)
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd) _ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
DownloadContent(Token) DownloadContent(Token)
ThrowIfDisposed() ThrowIfDisposed()
@@ -763,6 +773,7 @@ BlockNullPicture:
If DownloadedTotal(False) > 0 Or EnvirChanged.Invoke Then If DownloadedTotal(False) > 0 Or EnvirChanged.Invoke Then
If __SaveData Then If __SaveData Then
LastUpdated = Now LastUpdated = Now
RunScript()
DownloadedPictures(True) = SFile.GetFiles(User.File.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count DownloadedPictures(True) = SFile.GetFiles(User.File.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count
DownloadedVideos(True) = SFile.GetFiles(User.File.CutPath, "*.mp4|*.mkv|*.mov", SearchOption.AllDirectories, EDP.ReturnValue).Count DownloadedVideos(True) = SFile.GetFiles(User.File.CutPath, "*.mp4|*.mkv|*.mov", SearchOption.AllDirectories, EDP.ReturnValue).Count
If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser) If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser)
@@ -902,6 +913,7 @@ BlockNullPicture:
End Using End Using
End If End If
End If End If
Catch iex As IndexOutOfRangeException When Disposed
Catch oex As OperationCanceledException When Token.IsCancellationRequested Catch oex As OperationCanceledException When Token.IsCancellationRequested
Catch dex As ObjectDisposedException When Disposed Catch dex As ObjectDisposedException When Disposed
Catch ex As Exception Catch ex As Exception
@@ -922,16 +934,10 @@ BlockNullPicture:
Dim ff As SFile = Nothing Dim ff As SFile = Nothing
Try Try
If Not f.IsEmptyString AndAlso f.Exists Then If Not f.IsEmptyString AndAlso f.Exists Then
Dim d As Date? = m.Post.Date If Settings.FileReplaceNameByDate Or Settings.FileAddTimeToFileName Then
If Settings.FileReplaceNameByDate Then
Dim dd$ = AConvert(Of String)(If(d, Now), FileDateAppenderProvider, String.Empty)
ff = f ff = f
ff.Name = dd ff.Name = String.Format(FileDateAppenderPattern, f.Name, CStr(AConvert(Of String)(If(m.Post.Date, Now), FileDateAppenderProvider, String.Empty)))
ff = SFile.Indexed_IndexFile(ff,, New NumberedFile(ff)) ff = SFile.Indexed_IndexFile(ff,, New NumberedFile(ff))
ElseIf d.HasValue AndAlso (Settings.FileAddDateToFileName Or Settings.FileAddTimeToFileName) AndAlso
(Not FileDateAppenderProvider Is Nothing And Not FileDateAppenderPattern.IsEmptyString) Then
ff = f
ff.Name = String.Format(FileDateAppenderPattern, f.Name, CStr(AConvert(Of String)(d.Value, FileDateAppenderProvider, String.Empty)))
End If End If
If Not ff.Name.IsEmptyString Then My.Computer.FileSystem.RenameFile(f, ff.File) : Return ff If Not ff.Name.IsEmptyString Then My.Computer.FileSystem.RenameFile(f, ff.File) : Return ff
End If End If
@@ -941,19 +947,38 @@ BlockNullPicture:
Return f Return f
End Try End Try
End Function End Function
Private Sub RunScript()
Try
Const spa$ = "{0}"
If ScriptUse Then
Dim ScriptPattern$
If Not ScriptData.IsEmptyString Then
ScriptPattern = ScriptData
Else
ScriptPattern = Settings.ScriptData.Value
End If
If Not ScriptPattern.IsEmptyString Then
If Not ScriptPattern.Contains(spa) Then ScriptPattern &= $" ""{spa}"""
Using b As New BatchExecutor With {.RedirectStandardError = True}
b.Execute({String.Format(ScriptPattern, MyFile.CutPath(1).PathNoSeparator)}, EDP.SendInLog + EDP.ThrowException)
If b.HasError Or Not b.ErrorOutput.IsEmptyString Then Throw New Exception(b.ErrorOutput, b.ErrorException)
End Using
End If
End If
Catch ex As Exception
LogError(ex, "script execution error")
End Try
End Sub
#End Region #End Region
#Region "Delete, Move, Merge" #Region "Delete, Move, Merge"
Friend Overridable Function Delete() As Integer Implements IUserData.Delete Friend Overridable Function Delete() As Integer Implements IUserData.Delete
Return DeleteF(Me)
End Function
Friend Function DeleteF(ByVal Instance As IUserData) As Integer
Dim f As SFile = SFile.GetPath(MyFile.CutPath.Path) Dim f As SFile = SFile.GetPath(MyFile.CutPath.Path)
If f.Exists(SFO.Path, False) AndAlso (User.Merged OrElse f.Delete(SFO.Path, Settings.DeleteMode)) Then If f.Exists(SFO.Path, False) AndAlso (User.Merged OrElse f.Delete(SFO.Path, Settings.DeleteMode)) Then
ImageHandler(Me, False) ImageHandler(Me, False)
Settings.UsersList.Remove(User) Settings.UsersList.Remove(User)
Settings.UpdateUsersList() Settings.UpdateUsersList()
Settings.Users.Remove(Instance) Settings.Users.Remove(Me)
Downloader.UserRemove(Instance) Downloader.UserRemove(Me)
Dispose(True) Dispose(True)
Return 1 Return 1
Else Else
@@ -961,24 +986,22 @@ BlockNullPicture:
End If End If
End Function End Function
Friend Overridable Function MoveFiles(ByVal __CollectionName As String) As Boolean Implements IUserData.MoveFiles Friend Overridable Function MoveFiles(ByVal __CollectionName As String) As Boolean Implements IUserData.MoveFiles
Return MoveFilesF(Me, __CollectionName)
End Function
Friend Function MoveFilesF(ByRef Instance As IUserData, ByVal __CollectionName As String) As Boolean
Dim UserBefore As UserInfo = User Dim UserBefore As UserInfo = User
Dim Removed As Boolean = True Dim Removed As Boolean = True
Dim _TurnBack As Boolean = False Dim _TurnBack As Boolean = False
Try Try
Dim f As SFile Dim f As SFile
If IncludedInCollection Then If IncludedInCollection Then
Settings.Users.Add(Instance) Settings.Users.Add(Me)
Removed = False Removed = False
User.CollectionName = String.Empty User.CollectionName = String.Empty
User.IncludedInCollection = False User.IncludedInCollection = False
Else Else
Settings.Users.Remove(Instance) Settings.Users.Remove(Me)
Removed = True Removed = True
User.CollectionName = __CollectionName User.CollectionName = __CollectionName
User.IncludedInCollection = True User.IncludedInCollection = True
User.SpecialPath = Nothing
End If End If
_TurnBack = True _TurnBack = True
User.UpdateUserFile() User.UpdateUserFile()
@@ -990,7 +1013,7 @@ BlockNullPicture:
"Destination directory is not empty!"}, MsgBoxStyle.Exclamation,,, {"Delete", "Cancel"}) = 1 Then "Destination directory is not empty!"}, MsgBoxStyle.Exclamation,,, {"Delete", "Cancel"}) = 1 Then
MsgBoxE("Operation canceled", MsgBoxStyle.Exclamation) MsgBoxE("Operation canceled", MsgBoxStyle.Exclamation)
User = UserBefore User = UserBefore
If Removed Then Settings.Users.Add(Instance) Else Settings.Users.Remove(Instance) If Removed Then Settings.Users.Add(Me) Else Settings.Users.Remove(Me)
_TurnBack = False _TurnBack = False
Return False Return False
End If End If
@@ -998,6 +1021,8 @@ BlockNullPicture:
End If End If
f.CutPath.Exists(SFO.Path) f.CutPath.Exists(SFO.Path)
Directory.Move(UserBefore.File.CutPath(, EDP.ThrowException).Path, f.Path) Directory.Move(UserBefore.File.CutPath(, EDP.ThrowException).Path, f.Path)
If Not ScriptData.IsEmptyString AndAlso ScriptData.Contains(UserBefore.File.PathNoSeparator) Then _
ScriptData = ScriptData.Replace(UserBefore.File.PathNoSeparator, MyFile.PathNoSeparator)
Settings.UsersList.Remove(UserBefore) Settings.UsersList.Remove(UserBefore)
Settings.UpdateUsersList(User) Settings.UpdateUsersList(User)
UpdateUserInformation() UpdateUserInformation()
@@ -1006,7 +1031,7 @@ BlockNullPicture:
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Files moving error") ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Files moving error")
User = UserBefore User = UserBefore
If _TurnBack Then If _TurnBack Then
If Removed Then Settings.Users.Add(Instance) Else Settings.Users.Remove(Instance) If Removed Then Settings.Users.Add(Me) Else Settings.Users.Remove(Me)
End If End If
Return False Return False
End Try End Try
@@ -1051,6 +1076,8 @@ BlockNullPicture:
New ErrorsDescriber(False, False, False, New List(Of SFile))).Count = 0 Then New ErrorsDescriber(False, False, False, New List(Of SFile))).Count = 0 Then
UserBefore.File.CutPath.Delete(SFO.Path, Settings.DeleteMode, EDP.SendInLog) UserBefore.File.CutPath.Delete(SFO.Path, Settings.DeleteMode, EDP.SendInLog)
End If End If
If Not ScriptData.IsEmptyString AndAlso ScriptData.Contains(UserBefore.File.PathNoSeparator) Then _
ScriptData = ScriptData.Replace(UserBefore.File.PathNoSeparator, MyFile.PathNoSeparator)
UpdateUserInformation() UpdateUserInformation()
End If End If
Catch ioex As InvalidOperationException When ioex.HelpLink = 1 Catch ioex As InvalidOperationException When ioex.HelpLink = 1
@@ -1096,25 +1123,6 @@ BlockNullPicture:
Else Else
Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName) Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName)
End If End If
'If Settings.ViewModeIsPicture Then
' If IsCollection Then
' Return CollectionName
' Else
' Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName)
' End If
'Else
' Dim t$ = String.Empty
' If Temporary Then
' t = " (T)"
' ElseIf Favorite Then
' t = " (F)"
' End If
' If IsCollection Then
' Return $"Collection [{CollectionName}]{t}"
' Else
' Return $"[{Site}]{t} {IIf(FriendlyName.IsEmptyString, Name, FriendlyName)}"
' End If
'End If
End Function End Function
#Region "Buttons actions" #Region "Buttons actions"
Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click
@@ -1234,6 +1242,8 @@ BlockNullPicture:
ReadOnly Property Key As String ReadOnly Property Key As String
Property DownloadImages As Boolean Property DownloadImages As Boolean
Property DownloadVideos As Boolean Property DownloadVideos As Boolean
Property ScriptUse As Boolean
Property ScriptData As String
Function GetLVI(ByVal Destination As ListView) As ListViewItem Function GetLVI(ByVal Destination As ListView) As ListViewItem
Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup Function GetLVIGroup(ByVal Destination As ListView) As ListViewGroup
Sub LoadUserInformation() Sub LoadUserInformation()

View File

@@ -9,6 +9,7 @@
Imports SCrawler.API.Base Imports SCrawler.API.Base
Imports SCrawler.Plugin Imports SCrawler.Plugin
Imports SCrawler.Plugin.Attributes Imports SCrawler.Plugin.Attributes
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Tools Imports PersonalUtilities.Tools
Imports PersonalUtilities.Functions.XML Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base Imports PersonalUtilities.Functions.XML.Base
@@ -30,18 +31,27 @@ Namespace API.Instagram
End Property End Property
#End Region #End Region
#Region "Providers" #Region "Providers"
Private Class TimersChecker : Implements ICustomProvider Private Class TimersChecker : Implements IFieldsCheckerProvider
Private Property ErrorMessage As String Implements IFieldsCheckerProvider.ErrorMessage
Private Property Name As String Implements IFieldsCheckerProvider.Name
Private Property TypeError As Boolean Implements IFieldsCheckerProvider.TypeError
Private ReadOnly LVProvider As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
Private ReadOnly _LowestValue As Integer Private ReadOnly _LowestValue As Integer
Friend Sub New(ByVal LowestValue As Integer) Friend Sub New(ByVal LowestValue As Integer)
_LowestValue = LowestValue _LowestValue = LowestValue
End Sub End Sub
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider, Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
If ACheck(Of Integer)(Value) AndAlso CInt(Value) >= _LowestValue Then TypeError = False
Return Value ErrorMessage = String.Empty
If Not ACheck(Of Integer)(Value) Then
TypeError = True
ElseIf CInt(Value) < _LowestValue Then
ErrorMessage = $"The value of [{Name}] field must be greater than or equal to {_LowestValue.NumToString(LVProvider)}"
Else Else
Return Nothing Return Value
End If End If
Return Nothing
End Function End Function
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
Throw New NotImplementedException() Throw New NotImplementedException()
@@ -53,35 +63,37 @@ Namespace API.Instagram
Friend ReadOnly Property Hash As PropertyValue Friend ReadOnly Property Hash As PropertyValue
<PropertyOption(ControlText:="Hash 2", ControlToolTip:="Instagram session hash for saved posts", IsAuth:=True), PXML("InstaHashSavedPosts"), ControlNumber(1)> <PropertyOption(ControlText:="Hash 2", ControlToolTip:="Instagram session hash for saved posts", IsAuth:=True), PXML("InstaHashSavedPosts"), ControlNumber(1)>
Friend ReadOnly Property HashSavedPosts As PropertyValue Friend ReadOnly Property HashSavedPosts As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True), ControlNumber(2)> <PropertyOption(ControlText:="x-csrftoken", ControlToolTip:="Instagram token for tagged data", IsAuth:=True), ControlNumber(2)>
Friend ReadOnly Property CSRF_TOKEN As PropertyValue
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True), ControlNumber(3)>
Friend Property IG_APP_ID As PropertyValue Friend Property IG_APP_ID As PropertyValue
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True), ControlNumber(3)> <PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True), ControlNumber(4)>
Friend Property IG_WWW_CLAIM As PropertyValue Friend Property IG_WWW_CLAIM As PropertyValue
<PropertyOption(ControlText:="Saved posts user", IsAuth:=True), PXML("SavedPostsUserName"), ControlNumber(4)> <PropertyOption(ControlText:="Saved posts user", IsAuth:=True), PXML("SavedPostsUserName"), ControlNumber(5)>
Friend ReadOnly Property SavedPostsUserName As PropertyValue Friend ReadOnly Property SavedPostsUserName As PropertyValue
Friend ReadOnly Property StoriesAndTaggedReady As Boolean Friend ReadOnly Property StoriesAndTaggedReady As Boolean
Get Get
Return ACheck(IG_APP_ID.Value) And ACheck(IG_WWW_CLAIM.Value) Return ACheck(IG_APP_ID.Value) And ACheck(IG_WWW_CLAIM.Value) And ACheck(CSRF_TOKEN.Value)
End Get End Get
End Property End Property
#End Region #End Region
#Region "Download properties" #Region "Download properties"
Friend ReadOnly Property HashUpdateRequired As XMLValue(Of Boolean) Friend ReadOnly Property HashUpdateRequired As XMLValue(Of Boolean)
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(5)> <PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(6)>
Friend ReadOnly Property RequestsWaitTimer As PropertyValue Friend ReadOnly Property RequestsWaitTimer As PropertyValue
<Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)> <Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(6)> <PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(7)>
Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue
<Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)> <Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)>
Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider
<PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(7)> <PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(8)>
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)> <Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
<PropertyOption(ControlText:="Get stories"), PXML, ControlNumber(8)> <PropertyOption(ControlText:="Get stories"), PXML, ControlNumber(9)>
Friend ReadOnly Property GetStories As PropertyValue Friend ReadOnly Property GetStories As PropertyValue
<PropertyOption(ControlText:="Get tagged photos"), PXML, ControlNumber(9)> <PropertyOption(ControlText:="Get tagged photos"), PXML, ControlNumber(10)>
Friend ReadOnly Property GetTagged As PropertyValue Friend ReadOnly Property GetTagged As PropertyValue
#End Region #End Region
#Region "429 bypass" #Region "429 bypass"
@@ -136,11 +148,13 @@ Namespace API.Instagram
Dim app_id$ = String.Empty Dim app_id$ = String.Empty
Dim www_claim$ = String.Empty Dim www_claim$ = String.Empty
Dim token$ = String.Empty
With Responser With Responser
If .File.Exists Then If .File.Exists Then
.LoadSettings() .LoadSettings()
With .Headers With .Headers
If .ContainsKey(Header_CSRF_TOKEN) Then token = .Item(Header_CSRF_TOKEN)
If .ContainsKey(Header_IG_APP_ID) Then app_id = .Item(Header_IG_APP_ID) If .ContainsKey(Header_IG_APP_ID) Then app_id = .Item(Header_IG_APP_ID)
If .ContainsKey(Header_IG_WWW_CLAIM) Then www_claim = .Item(Header_IG_WWW_CLAIM) If .ContainsKey(Header_IG_WWW_CLAIM) Then www_claim = .Item(Header_IG_WWW_CLAIM)
End With End With
@@ -157,6 +171,7 @@ Namespace API.Instagram
HashUpdateRequired = New XMLValue(Of Boolean)("InstaHashUpdateRequired", True, _XML, n) HashUpdateRequired = New XMLValue(Of Boolean)("InstaHashUpdateRequired", True, _XML, n)
Hash = New PropertyValue(String.Empty, GetType(String)) Hash = New PropertyValue(String.Empty, GetType(String))
HashSavedPosts = New PropertyValue(String.Empty, GetType(String)) HashSavedPosts = New PropertyValue(String.Empty, GetType(String))
CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(CSRF_TOKEN), v))
IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_APP_ID), v)) IG_APP_ID = New PropertyValue(app_id, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_APP_ID), v))
IG_WWW_CLAIM = New PropertyValue(www_claim, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v)) IG_WWW_CLAIM = New PropertyValue(www_claim, GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v))
@@ -164,7 +179,7 @@ Namespace API.Instagram
RequestsWaitTimerProvider = New TimersChecker(100) RequestsWaitTimerProvider = New TimersChecker(100)
RequestsWaitTimerTaskCount = New PropertyValue(1) RequestsWaitTimerTaskCount = New PropertyValue(1)
RequestsWaitTimerTaskCountProvider = New TimersChecker(1) RequestsWaitTimerTaskCountProvider = New TimersChecker(1)
SleepTimerOnPostsLimit = New PropertyValue(6000) SleepTimerOnPostsLimit = New PropertyValue(60000)
SleepTimerOnPostsLimitProvider = New TimersChecker(10000) SleepTimerOnPostsLimitProvider = New TimersChecker(10000)
GetStories = New PropertyValue(False) GetStories = New PropertyValue(False)
@@ -192,12 +207,14 @@ Namespace API.Instagram
End Function End Function
Private Const Header_IG_APP_ID As String = "x-ig-app-id" Private Const Header_IG_APP_ID As String = "x-ig-app-id"
Private Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim" Private Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
Private Const Header_CSRF_TOKEN As String = "x-csrftoken"
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object) Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
If Not PropName.IsEmptyString Then If Not PropName.IsEmptyString Then
Dim f$ = String.Empty Dim f$ = String.Empty
Select Case PropName Select Case PropName
Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID
Case NameOf(IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM Case NameOf(IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM
Case NameOf(CSRF_TOKEN) : f = Header_CSRF_TOKEN
End Select End Select
If Not f.IsEmptyString Then If Not f.IsEmptyString Then
If Responser.Headers.Count > 0 AndAlso Responser.Headers.ContainsKey(f) Then Responser.Headers.Remove(f) If Responser.Headers.Count > 0 AndAlso Responser.Headers.ContainsKey(f) Then Responser.Headers.Remove(f)
@@ -303,7 +320,7 @@ Namespace API.Instagram
End Try End Try
End Function End Function
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia) Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
Return UserData.GetVideoInfo(URL, Responser) Return UserData.GetVideoInfo(URL, Responser, Me)
End Function End Function
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
If Options Is Nothing OrElse Not TypeOf Options Is EditorExchangeOptions Then Options = New EditorExchangeOptions(Me) If Options Is Nothing OrElse Not TypeOf Options Is EditorExchangeOptions Then Options = New EditorExchangeOptions(Me)

View File

@@ -14,6 +14,7 @@ Imports PersonalUtilities.Tools.WebDocuments.JSON
Imports SCrawler.API.Base Imports SCrawler.API.Base
Imports System.Threading Imports System.Threading
Imports System.Net Imports System.Net
Imports System.Reflection
Imports UTypes = SCrawler.API.Base.UserMedia.Types Imports UTypes = SCrawler.API.Base.UserMedia.Types
Namespace API.Instagram Namespace API.Instagram
Friend Class UserData : Inherits UserDataBase Friend Class UserData : Inherits UserDataBase
@@ -138,7 +139,7 @@ Namespace API.Instagram
End Function End Function
Private Sub ReconfigureAwaiter() Private Sub ReconfigureAwaiter()
If WaitNotificationMode = WNM.SkipTemp Then WaitNotificationMode = WNM.Notify If WaitNotificationMode = WNM.SkipTemp Then WaitNotificationMode = WNM.Notify
If Caught429 Then Caught429 = False ': RequestsCount = 0 If Caught429 Then Caught429 = False
ProgressTempSet = False ProgressTempSet = False
End Sub End Sub
Private Sub NextRequest(ByVal StartWait As Boolean) Private Sub NextRequest(ByVal StartWait As Boolean)
@@ -193,6 +194,7 @@ Namespace API.Instagram
Case Sections.Stories Case Sections.Stories
If Not StoriesRequested Then If Not StoriesRequested Then
StoriesList = GetStoriesList() StoriesList = GetStoriesList()
StoriesRequested = True
MySiteSettings.TooManyRequests(False) MySiteSettings.TooManyRequests(False)
RequestsCount += 1 RequestsCount += 1
ThrowAny(Token) ThrowAny(Token)
@@ -260,9 +262,9 @@ Namespace API.Instagram
If Not TaggedChecked Then If Not TaggedChecked Then
TaggedCount = j.Value("total_count").FromXML(Of Integer)(0) TaggedCount = j.Value("total_count").FromXML(Of Integer)(0)
TaggedChecked = True TaggedChecked = True
If TaggedChecked > 200 Then If TaggedCount > 200 Then
Dim a% = MsgBoxE({$"The number of tagged posts is {TaggedCount.NumToString(New ANumbers With { Dim a% = MsgBoxE({$"The number of tagged posts by user [{ToString()}] is { _
.FormatOptions = ANumbers.Options.GroupIntegral})}" & vbCr & TaggedCount.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral})}" & vbCr &
"The tagged data download operation can take a long time.", "Too much tagged data"}, vbExclamation,,, "The tagged data download operation can take a long time.", "Too much tagged data"}, vbExclamation,,,
{"Continue", {"Continue",
New MsgBoxButton("Disable and cancel") With { New MsgBoxButton("Disable and cancel") With {
@@ -276,11 +278,9 @@ Namespace API.Instagram
End If End If
End Select End Select
Else Else
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso _TempMediaList.Count = 0 Then If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso
MySiteSettings.HashUpdateRequired.Value = True _TempMediaList.Count = 0 AndAlso Section = Sections.Timeline Then _
UserExists = False UserExists = False : Throw New ExitException(_DownloadComplete)
Throw New ExitException(_DownloadComplete)
End If
End If End If
End Using End Using
Else Else
@@ -298,7 +298,7 @@ Namespace API.Instagram
Catch dex As ObjectDisposedException When Disposed Catch dex As ObjectDisposedException When Disposed
Exit Do Exit Do
Catch ex As Exception Catch ex As Exception
If DownloadingException(ex, $"data downloading error [{URL}]") = 1 Then Continue Do Else Exit Do If DownloadingException(ex, $"data downloading error [{URL}]", Section, False) = 1 Then Continue Do Else Exit Do
End Try End Try
Loop Loop
Catch eex2 As ExitException Catch eex2 As ExitException
@@ -390,11 +390,30 @@ Namespace API.Instagram
CreateMedia(node) CreateMedia(node)
End If End If
End Sub End Sub
Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String, Optional ByVal SpecialFolder As String = Nothing) Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String, Optional ByVal SpecialFolder As String = Nothing,
Optional ByVal DateObj As String = Nothing)
Try Try
Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0 Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0
Dim vid As Predicate(Of EContainer) = Function(_vid) Not _vid.Name.IsEmptyString AndAlso _vid.Name.StartsWith("video_versions") AndAlso _vid.Count > 0 Dim vid As Predicate(Of EContainer) = Function(_vid) Not _vid.Name.IsEmptyString AndAlso _vid.Name.StartsWith("video_versions") AndAlso _vid.Count > 0
Dim ss As Func(Of EContainer, Sizes) = Function(_ss) New Sizes(_ss.Value("width"), _ss.Value("url")) Dim ss As Func(Of EContainer, Sizes) = Function(_ss) New Sizes(_ss.Value("width"), _ss.Value("url"))
Dim mDate As Func(Of EContainer, String) = Function(ByVal elem As EContainer) As String
If elem.Contains("taken_at") Then
Return elem.Value("taken_at")
ElseIf elem.Contains("imported_taken_at") Then
Return elem.Value("imported_taken_at")
Else
Dim ev$ = elem.Value("device_timestamp")
If Not ev.IsEmptyString Then
If ev.Length > 10 Then
Return elem.Value("device_timestamp").Substring(0, 10)
Else
Return ev
End If
Else
Return String.Empty
End If
End If
End Function
If n.Count > 0 Then If n.Count > 0 Then
Dim l As New List(Of Sizes) Dim l As New List(Of Sizes)
Dim d As EContainer Dim d As EContainer
@@ -408,6 +427,7 @@ Namespace API.Instagram
Case 1 Case 1
If n.Contains(img) Then If n.Contains(img) Then
t = n.Value("media_type").FromXML(Of Integer)(-1) t = n.Value("media_type").FromXML(Of Integer)(-1)
DateObj = mDate(n)
If t >= 0 Then If t >= 0 Then
With n.ItemF({img, "candidates"}).XmlIfNothing With n.ItemF({img, "candidates"}).XmlIfNothing
If .Count > 0 Then If .Count > 0 Then
@@ -415,7 +435,7 @@ Namespace API.Instagram
l.ListAddList(.Select(ss), LNC) l.ListAddList(.Select(ss), LNC)
If l.Count > 0 Then If l.Count > 0 Then
l.Sort() l.Sort()
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, Nothing, SpecialFolder), LNC) _TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, DateObj, SpecialFolder), LNC)
l.Clear() l.Clear()
End If End If
End If End If
@@ -424,22 +444,24 @@ Namespace API.Instagram
End If End If
Case 2 Case 2
If n.Contains(vid) Then If n.Contains(vid) Then
DateObj = mDate(n)
With n.ItemF({vid}).XmlIfNothing With n.ItemF({vid}).XmlIfNothing
If .Count > 0 Then If .Count > 0 Then
l.Clear() l.Clear()
l.ListAddList(.Select(ss), LNC) l.ListAddList(.Select(ss), LNC)
If l.Count > 0 Then If l.Count > 0 Then
l.Sort() l.Sort()
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, Nothing, SpecialFolder), LNC) _TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, DateObj, SpecialFolder), LNC)
l.Clear() l.Clear()
End If End If
End If End If
End With End With
End If End If
Case 8 Case 8
DateObj = mDate(n)
With n("carousel_media").XmlIfNothing With n("carousel_media").XmlIfNothing
If .Count > 0 Then If .Count > 0 Then
For Each d In .Self : ObtainMedia2(d, PostID, SpecialFolder) : Next For Each d In .Self : ObtainMedia2(d, PostID, SpecialFolder, DateObj) : Next
End If End If
End With End With
End Select End Select
@@ -471,14 +493,14 @@ Namespace API.Instagram
Private Sub GetStoriesData(ByRef StoriesList As List(Of String), ByVal Token As CancellationToken) Private Sub GetStoriesData(ByRef StoriesList As List(Of String), ByVal Token As CancellationToken)
Const ReqUrl$ = "https://i.instagram.com/api/v1/feed/reels_media/?{0}" Const ReqUrl$ = "https://i.instagram.com/api/v1/feed/reels_media/?{0}"
Dim tmpList As IEnumerable(Of String) Dim tmpList As IEnumerable(Of String)
Dim qStr$, r$, sFolder$, storyID$ Dim qStr$, r$, sFolder$, storyID$, pid$
Dim i% = -1 Dim i% = -1
Dim jj As EContainer, s As EContainer Dim jj As EContainer, s As EContainer
ThrowAny(Token) ThrowAny(Token)
If StoriesList.ListExists Then If StoriesList.ListExists Then
tmpList = StoriesList.Take(5) tmpList = StoriesList.Take(5)
If tmpList.ListExists Then If tmpList.ListExists Then
qStr = String.Format(ReqUrl, tmpList.Select(Function(q) $"reel_ids=highlight:{q}").ListToString(, "&")) qStr = String.Format(ReqUrl, tmpList.Select(Function(q) $"reel_ids=highlight:{q}").ListToString("&"))
r = Responser.GetResponse(qStr,, EDP.ThrowException) r = Responser.GetResponse(qStr,, EDP.ThrowException)
ThrowAny(Token) ThrowAny(Token)
If Not r.IsEmptyString Then If Not r.IsEmptyString Then
@@ -486,7 +508,7 @@ Namespace API.Instagram
If j.Contains("reels") Then If j.Contains("reels") Then
For Each jj In j("reels") For Each jj In j("reels")
i += 1 i += 1
sFolder = jj.Value("title") sFolder = jj.Value("title").StringRemoveWinForbiddenSymbols
storyID = jj.Value("id").Replace("highlight:", String.Empty) storyID = jj.Value("id").Replace("highlight:", String.Empty)
If sFolder.IsEmptyString Then sFolder = $"Story_{storyID}" If sFolder.IsEmptyString Then sFolder = $"Story_{storyID}"
If sFolder.IsEmptyString Then sFolder = $"Story_{i}" If sFolder.IsEmptyString Then sFolder = $"Story_{i}"
@@ -494,7 +516,14 @@ Namespace API.Instagram
If Not storyID.IsEmptyString Then storyID &= ":" If Not storyID.IsEmptyString Then storyID &= ":"
With jj("items").XmlIfNothing With jj("items").XmlIfNothing
If .Count > 0 Then If .Count > 0 Then
For Each s In .Self : ThrowAny(Token) : ObtainMedia2(s, storyID & s.Value("id"), sFolder) : Next For Each s In .Self
pid = storyID & s.Value("id")
If Not _TempPostsList.Contains(pid) Then
ThrowAny(Token)
ObtainMedia2(s, pid, sFolder)
_TempPostsList.Add(pid)
End If
Next
End If End If
End With End With
Next Next
@@ -515,7 +544,7 @@ Namespace API.Instagram
End If End If
Return Nothing Return Nothing
Catch ex As Exception Catch ex As Exception
DownloadingException(ex, "API.Instagram.GetStoriesList") DownloadingException(ex, "API.Instagram.GetStoriesList", Sections.Stories, False)
Return Nothing Return Nothing
End Try End Try
End Function End Function
@@ -529,13 +558,18 @@ Namespace API.Instagram
''' <inheritdoc cref="UserDataBase.DownloadingException(Exception, String)"/><br/> ''' <inheritdoc cref="UserDataBase.DownloadingException(Exception, String)"/><br/>
''' 1 - continue ''' 1 - continue
''' </summary> ''' </summary>
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer Protected Overloads Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False) As Integer
Return DownloadingException(ex, Message, Sections.Timeline, FromPE)
End Function
Private Overloads Function DownloadingException(ByVal ex As Exception, ByVal Message As String, ByVal s As Sections, ByVal FromPE As Boolean) As Integer
If Responser.StatusCode = HttpStatusCode.NotFound Then If Responser.StatusCode = HttpStatusCode.NotFound Then
UserExists = False UserExists = False
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
HasError = True HasError = True
MyMainLOG = "Instagram credentials have expired" MyMainLOG = $"Instagram credentials have expired: {ToString()} [{s}]"
MySiteSettings.HashUpdateRequired.Value = True MySiteSettings.HashUpdateRequired.Value = True
ElseIf Responser.StatusCode = HttpStatusCode.Forbidden And s = Sections.Tagged Then
Return 3
ElseIf Responser.StatusCode = 429 Then ElseIf Responser.StatusCode = 429 Then
With MySiteSettings With MySiteSettings
Dim WaiterExists As Boolean = .LastApplyingValue.HasValue Dim WaiterExists As Boolean = .LastApplyingValue.HasValue
@@ -547,6 +581,7 @@ Namespace API.Instagram
Return 1 Return 1
Else Else
MySiteSettings.HashUpdateRequired.Value = True MySiteSettings.HashUpdateRequired.Value = True
MyMainLOG = $"Instagram hash requested: {ToString()} [{s}]"
If Not FromPE Then LogError(ex, Message) : HasError = True If Not FromPE Then LogError(ex, Message) : HasError = True
Return 0 Return 0
End If End If
@@ -561,12 +596,13 @@ Namespace API.Instagram
m.SpecialFolder = SpecialFolder m.SpecialFolder = SpecialFolder
Return m Return m
End Function End Function
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal r As Response) As IEnumerable(Of UserMedia) Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal r As Response, ByVal _Settings As SiteSettings) As IEnumerable(Of UserMedia)
Try Try
If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then
Dim PID$ = RegexReplace(URL, RParams.DMS(".*?instagram.com/p/([_\w\d]+)", 1)) Dim PID$ = RegexReplace(URL, RParams.DMS(".*?instagram.com/p/([_\w\d]+)", 1))
If Not PID.IsEmptyString Then If Not PID.IsEmptyString Then
Using t As New UserData Using t As New UserData
t.SetEnvironment(Settings(_Settings.GetType.GetCustomAttribute(Of Plugin.Attributes.Manifest)().GUID), Nothing, False, False)
t.Responser = New Response t.Responser = New Response
t.Responser.Copy(r) t.Responser.Copy(r)
t._SavedPostsIDs.Add(PID) t._SavedPostsIDs.Add(PID)

View File

@@ -12,9 +12,12 @@ Imports PersonalUtilities.Functions.XML
Imports SCrawler.API.Base Imports SCrawler.API.Base
Imports SCrawler.Plugin.Hosts Imports SCrawler.Plugin.Hosts
Imports System.Threading Imports System.Threading
Imports SCrawler.API.Reddit.RedditViewExchange
Imports View = SCrawler.API.Reddit.IRedditView.View
Imports Period = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit Namespace API.Reddit
Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel), Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel),
IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IDisposable IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IRedditView, IDisposable
#Region "XML Nodes' Names" #Region "XML Nodes' Names"
Private Const Name_Name As String = "Name" Private Const Name_Name As String = "Name"
Private Const Name_ID As String = "ID" Private Const Name_ID As String = "ID"
@@ -35,6 +38,7 @@ Namespace API.Reddit
End Property End Property
Friend ReadOnly Property PostsLatest As List(Of UserPost) Friend ReadOnly Property PostsLatest As List(Of UserPost)
Friend ReadOnly Property Posts As List(Of UserPost) Friend ReadOnly Property Posts As List(Of UserPost)
Friend ReadOnly Property PostsNames As List(Of String)
Friend ReadOnly Property PostsAll As List(Of UserPost) Friend ReadOnly Property PostsAll As List(Of UserPost)
Get Get
Return ListAddList(Nothing, Posts).ListAddList(PostsLatest).ListSort Return ListAddList(Nothing, Posts).ListAddList(PostsLatest).ListSort
@@ -57,6 +61,14 @@ Namespace API.Reddit
Return $"{ChannelsCollection.ChannelsPath.PathWithSeparator}{ID}.xml" Return $"{ChannelsCollection.ChannelsPath.PathWithSeparator}{ID}.xml"
End Get End Get
End Property End Property
Private ReadOnly Property FilePosts As SFile
Get
Dim f As SFile = File
f.Name &= "_Posts"
f.Extension = "txt"
Return f
End Get
End Property
Friend ReadOnly Property CachePath As SFile Friend ReadOnly Property CachePath As SFile
Get Get
Return $"{ChannelsCollection.ChannelsPathCache.PathWithSeparator}{ID}\" Return $"{ChannelsCollection.ChannelsPathCache.PathWithSeparator}{ID}\"
@@ -72,7 +84,14 @@ Namespace API.Reddit
Return Posts(Index) Return Posts(Index)
End Get End Get
End Property End Property
Private ReadOnly Property Range As RangeSwitcher(Of UserPost) Friend Property ViewMode As View = View.New Implements IRedditView.ViewMode
Friend Property ViewPeriod As Period = Period.All Implements IRedditView.ViewPeriod
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
End If
End Sub
#Region "Statistics support" #Region "Statistics support"
Private ReadOnly CountOfAddedUsers As List(Of Integer) Private ReadOnly CountOfAddedUsers As List(Of Integer)
Private ReadOnly CountOfLoadedPostsPerSession As List(Of Integer) Private ReadOnly CountOfLoadedPostsPerSession As List(Of Integer)
@@ -118,6 +137,9 @@ Namespace API.Reddit
Private _DownloadLimitCount As Integer? = Nothing Private _DownloadLimitCount As Integer? = Nothing
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
Get Get
If Not ViewMode = View.New And AutoGetLimits Then
Return _DownloadLimitCount
Else
If AutoGetLimits Then If AutoGetLimits Then
If LatestParsedDate.HasValue OrElse Not DownloadLimitPost.IsEmptyString Then If LatestParsedDate.HasValue OrElse Not DownloadLimitPost.IsEmptyString Then
Return Nothing Return Nothing
@@ -129,6 +151,7 @@ Namespace API.Reddit
Else Else
Return _DownloadLimitCount Return _DownloadLimitCount
End If End If
End If
End Get End Get
Set(ByVal NewLimit As Integer?) Set(ByVal NewLimit As Integer?)
_DownloadLimitCount = NewLimit _DownloadLimitCount = NewLimit
@@ -137,12 +160,16 @@ Namespace API.Reddit
Private _DownloadLimitPost As String = String.Empty Private _DownloadLimitPost As String = String.Empty
Friend Property DownloadLimitPost As String Implements IChannelLimits.DownloadLimitPost Friend Property DownloadLimitPost As String Implements IChannelLimits.DownloadLimitPost
Get Get
If Not ViewMode = View.New And AutoGetLimits Then
Return _DownloadLimitPost
Else
Dim PID$ = ListAddList(Nothing, Posts, LAP.NotContainsOnly).ListAddList(PostsLatest, LAP.NotContainsOnly).ListSort.FirstOrDefault.ID Dim PID$ = ListAddList(Nothing, Posts, LAP.NotContainsOnly).ListAddList(PostsLatest, LAP.NotContainsOnly).ListSort.FirstOrDefault.ID
If AutoGetLimits And Not PID.IsEmptyString Then If AutoGetLimits And Not PID.IsEmptyString Then
Return PID Return PID
Else Else
Return _DownloadLimitPost Return _DownloadLimitPost
End If End If
End If
End Get End Get
Set(ByVal NewLimit As String) Set(ByVal NewLimit As String)
_DownloadLimitPost = NewLimit _DownloadLimitPost = NewLimit
@@ -151,11 +178,15 @@ Namespace API.Reddit
Private _DownloadLimitDate As Date? = Nothing Private _DownloadLimitDate As Date? = Nothing
Friend Property DownloadLimitDate As Date? Implements IChannelLimits.DownloadLimitDate Friend Property DownloadLimitDate As Date? Implements IChannelLimits.DownloadLimitDate
Get Get
If Not ViewMode = View.New And AutoGetLimits Then
Return _DownloadLimitDate
Else
If AutoGetLimits And LatestParsedDate.HasValue Then If AutoGetLimits And LatestParsedDate.HasValue Then
Return LatestParsedDate Return LatestParsedDate
Else Else
Return _DownloadLimitDate Return _DownloadLimitDate
End If End If
End If
End Get End Get
Set(ByVal NewLimit As Date?) Set(ByVal NewLimit As Date?)
_DownloadLimitDate = NewLimit _DownloadLimitDate = NewLimit
@@ -174,6 +205,11 @@ Namespace API.Reddit
DownloadLimitDate = .DownloadLimitDate DownloadLimitDate = .DownloadLimitDate
AutoGetLimits = .AutoGetLimits AutoGetLimits = .AutoGetLimits
End With End With
If Not ViewMode = View.New And AutoGetLimits Then
DownloadLimitDate = Nothing
DownloadLimitCount = Nothing
DownloadLimitPost = String.Empty
End If
End Sub End Sub
Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits
#End Region #End Region
@@ -181,7 +217,7 @@ Namespace API.Reddit
Friend Sub New() Friend Sub New()
Posts = New List(Of UserPost) Posts = New List(Of UserPost)
PostsLatest = New List(Of UserPost) PostsLatest = New List(Of UserPost)
Range = New RangeSwitcher(Of UserPost)(Me) PostsNames = New List(Of String)
CountOfAddedUsers = New List(Of Integer) CountOfAddedUsers = New List(Of Integer)
CountOfLoadedPostsPerSession = New List(Of Integer) CountOfLoadedPostsPerSession = New List(Of Integer)
ChannelExistentUserNames = New List(Of String) ChannelExistentUserNames = New List(Of String)
@@ -203,6 +239,7 @@ Namespace API.Reddit
End Function End Function
Friend Sub Delete() Friend Sub Delete()
File.Delete(, SFODelete.DeleteToRecycleBin) File.Delete(, SFODelete.DeleteToRecycleBin)
FilePosts.Delete(, SFODelete.DeleteToRecycleBin)
End Sub End Sub
Friend Sub DownloadData(ByVal Token As CancellationToken, Optional ByVal SkipExists As Boolean = True, Friend Sub DownloadData(ByVal Token As CancellationToken, Optional ByVal SkipExists As Boolean = True,
Optional ByVal p As MyProgress = Nothing) Optional ByVal p As MyProgress = Nothing)
@@ -214,10 +251,13 @@ Namespace API.Reddit
.SkipExistsUsers = SkipExists, .SkipExistsUsers = SkipExists,
.ChannelInfo = Me .ChannelInfo = Me
} }
d.SetEnvironment(HOST, CUser, False) With d
d.RemoveUpdateHandlers() .SetEnvironment(HOST, CUser, False)
d.SetLimit(Me) .RemoveUpdateHandlers()
d.DownloadData(Token) .SetLimit(Me)
.SetView(Me)
.DownloadData(Token)
End With
Dim b% = Posts.Count Dim b% = Posts.Count
Posts.ListAddList(d.GetNewChannelPosts(), LAP.NotContainsOnly) Posts.ListAddList(d.GetNewChannelPosts(), LAP.NotContainsOnly)
If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b) If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b)
@@ -298,6 +338,9 @@ Namespace API.Reddit
Dim lc As New ListAddParams(LAP.ClearBeforeAdd) Dim lc As New ListAddParams(LAP.ClearBeforeAdd)
Name = x.Value(Name_Name) Name = x.Value(Name_Name)
ID = x.Value(Name_ID) ID = x.Value(Name_ID)
ViewMode = x.Value(Name_ViewMode).FromXML(Of Integer)(CInt(View.[New]))
ViewPeriod = x.Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(Period.All))
If FilePosts.Exists Then PostsNames.ListAddList(FilePosts.GetText.StringToList(Of String)("|"), LNC)
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing) LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing)
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc) CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc)
CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), lc) CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), lc)
@@ -317,9 +360,20 @@ Namespace API.Reddit
Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime) Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
UpdateUsersStats() UpdateUsersStats()
If Not ViewMode = View.New Then
Dim l As New List(Of String)
If Posts.Count > 0 Or PostsLatest.Count > 0 Then l.ListAddList((From p In PostsAll Where Not p.ID.IsEmptyString Select p.ID), LAP.NotContainsOnly)
l.ListAddList(PostsNames, LAP.NotContainsOnly)
If l.Count > 0 Then TextSaver.SaveTextToFile(l.ListToString("|"), FilePosts, True,, EDP.SendInLog)
End If
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"} Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"}
x.Add(Name_Name, Name) x.Add(Name_Name, Name)
x.Add(Name_ID, ID) x.Add(Name_ID, ID)
x.Add(Name_ViewMode, CInt(ViewMode))
x.Add(Name_ViewPeriod, CInt(ViewPeriod))
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString("|"))
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString("|"))
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString("|"))
If Posts.Count > 0 Or PostsLatest.Count > 0 Then If Posts.Count > 0 Or PostsLatest.Count > 0 Then
Dim tmpPostList As List(Of UserPost) = Nothing Dim tmpPostList As List(Of UserPost) = Nothing
tmpPostList.ListAddList(Posts).ListAddList(PostsLatest) tmpPostList.ListAddList(Posts).ListAddList(PostsLatest)
@@ -327,9 +381,6 @@ Namespace API.Reddit
LatestParsedDate = tmpPostList.FirstOrDefault(Function(pd) pd.Date.HasValue).Date LatestParsedDate = tmpPostList.FirstOrDefault(Function(pd) pd.Date.HasValue).Date
x.Add(Name_Date, AConvert(Of String)(LatestParsedDate, XMLDateProvider, String.Empty)) x.Add(Name_Date, AConvert(Of String)(LatestParsedDate, XMLDateProvider, String.Empty))
x.Add(Name_PostsNode, String.Empty) x.Add(Name_PostsNode, String.Empty)
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString(, "|"))
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString(, "|"))
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString(, "|"))
With x(Name_PostsNode) With x(Name_PostsNode)
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post", tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
String.Empty, String.Empty,
@@ -354,9 +405,9 @@ Namespace API.Reddit
If disposing Then If disposing Then
Posts.Clear() Posts.Clear()
PostsLatest.Clear() PostsLatest.Clear()
PostsNames.Clear()
CountOfAddedUsers.Clear() CountOfAddedUsers.Clear()
CountOfLoadedPostsPerSession.Clear() CountOfLoadedPostsPerSession.Clear()
Range.Dispose()
ChannelExistentUserNames.Clear() ChannelExistentUserNames.Clear()
CachePath.Delete(SFO.Path, SFODelete.None, EDP.SendInLog) CachePath.Delete(SFO.Path, SFODelete.None, EDP.SendInLog)
End If End If

View File

@@ -0,0 +1,40 @@
' Copyright (C) 2022 Andy
' 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.Reddit
Friend Interface IRedditView
Enum View As Integer
[New] = 0
Hot = 1
Top = 2
End Enum
Enum Period As Integer
All = 0
Hour = 1
Day = 2
Week = 3
Month = 4
Year = 5
End Enum
Property ViewMode As View
Property ViewPeriod As Period
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 Property ViewMode As IRedditView.View Implements IRedditView.ViewMode
Friend Property ViewPeriod As IRedditView.Period Implements IRedditView.ViewPeriod
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
End If
End Sub
End Class
End Namespace

View File

@@ -52,7 +52,7 @@ Namespace API.Reddit
If Not r.IsEmptyString Then If Not r.IsEmptyString Then
Dim lp As New ListAddParams(LAP.NotContainsOnly) With { Dim lp As New ListAddParams(LAP.NotContainsOnly) With {
.Converter = Function(input) $"{BaseUrl}/{input}", .Converter = Function(input) $"{BaseUrl}/{input}",
.e = New ErrorsDescriber(False, False, True, New List(Of String))} .Error = New ErrorsDescriber(False, False, True, New List(Of String))}
Return ListAddList(Of String, List(Of String))(Nothing, DirectCast(RegexReplace(r, PlayListRegEx_2), List(Of String)), lp).ListIfNothing Return ListAddList(Of String, List(Of String))(Nothing, DirectCast(RegexReplace(r, PlayListRegEx_2), List(Of String)), lp).ListIfNothing
End If End If
End If End If

View File

@@ -0,0 +1,301 @@
' Copyright (C) 2022 Andy
' 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.Reddit
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class RedditViewSettingsForm : 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 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 resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(RedditViewSettingsForm))
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()
Me.TP_PERIOD = New System.Windows.Forms.TableLayoutPanel()
Me.OPT_PERIOD_ALL = New System.Windows.Forms.RadioButton()
Me.OPT_PERIOD_HOUR = New System.Windows.Forms.RadioButton()
Me.OPT_PERIOD_DAY = New System.Windows.Forms.RadioButton()
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()
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()
TP_VIEW_MODE.SuspendLayout()
Me.TP_PERIOD.SuspendLayout()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 87)
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.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
'
'TP_VIEW_MODE
'
TP_VIEW_MODE.ColumnCount = 4
TP_VIEW_MODE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
TP_VIEW_MODE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
TP_VIEW_MODE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
TP_VIEW_MODE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
TP_VIEW_MODE.Controls.Add(LBL_VIEW_MODE, 0, 0)
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_NEW, 1, 0)
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_HOT, 2, 0)
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_TOP, 3, 0)
TP_VIEW_MODE.Dock = System.Windows.Forms.DockStyle.Fill
TP_VIEW_MODE.Location = New System.Drawing.Point(1, 1)
TP_VIEW_MODE.Margin = New System.Windows.Forms.Padding(0)
TP_VIEW_MODE.Name = "TP_VIEW_MODE"
TP_VIEW_MODE.RowCount = 1
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_VIEW_MODE.Size = New System.Drawing.Size(475, 28)
TP_VIEW_MODE.TabIndex = 0
'
'LBL_VIEW_MODE
'
LBL_VIEW_MODE.AutoSize = True
LBL_VIEW_MODE.Dock = System.Windows.Forms.DockStyle.Fill
LBL_VIEW_MODE.Location = New System.Drawing.Point(3, 0)
LBL_VIEW_MODE.Name = "LBL_VIEW_MODE"
LBL_VIEW_MODE.Size = New System.Drawing.Size(112, 28)
LBL_VIEW_MODE.TabIndex = 0
LBL_VIEW_MODE.Text = "View"
LBL_VIEW_MODE.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'OPT_VIEW_MODE_NEW
'
Me.OPT_VIEW_MODE_NEW.AutoSize = True
Me.OPT_VIEW_MODE_NEW.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_VIEW_MODE_NEW.Location = New System.Drawing.Point(121, 3)
Me.OPT_VIEW_MODE_NEW.Name = "OPT_VIEW_MODE_NEW"
Me.OPT_VIEW_MODE_NEW.Size = New System.Drawing.Size(112, 22)
Me.OPT_VIEW_MODE_NEW.TabIndex = 1
Me.OPT_VIEW_MODE_NEW.TabStop = True
Me.OPT_VIEW_MODE_NEW.Text = "New"
Me.OPT_VIEW_MODE_NEW.UseVisualStyleBackColor = True
'
'OPT_VIEW_MODE_HOT
'
Me.OPT_VIEW_MODE_HOT.AutoSize = True
Me.OPT_VIEW_MODE_HOT.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_VIEW_MODE_HOT.Location = New System.Drawing.Point(239, 3)
Me.OPT_VIEW_MODE_HOT.Name = "OPT_VIEW_MODE_HOT"
Me.OPT_VIEW_MODE_HOT.Size = New System.Drawing.Size(112, 22)
Me.OPT_VIEW_MODE_HOT.TabIndex = 2
Me.OPT_VIEW_MODE_HOT.TabStop = True
Me.OPT_VIEW_MODE_HOT.Text = "Hot"
Me.OPT_VIEW_MODE_HOT.UseVisualStyleBackColor = True
'
'OPT_VIEW_MODE_TOP
'
Me.OPT_VIEW_MODE_TOP.AutoSize = True
Me.OPT_VIEW_MODE_TOP.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_VIEW_MODE_TOP.Location = New System.Drawing.Point(357, 3)
Me.OPT_VIEW_MODE_TOP.Name = "OPT_VIEW_MODE_TOP"
Me.OPT_VIEW_MODE_TOP.Size = New System.Drawing.Size(115, 22)
Me.OPT_VIEW_MODE_TOP.TabIndex = 3
Me.OPT_VIEW_MODE_TOP.TabStop = True
Me.OPT_VIEW_MODE_TOP.Text = "Top"
Me.OPT_VIEW_MODE_TOP.UseVisualStyleBackColor = True
'
'TP_PERIOD
'
Me.TP_PERIOD.ColumnCount = 4
Me.TP_PERIOD.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
Me.TP_PERIOD.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
Me.TP_PERIOD.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
Me.TP_PERIOD.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
Me.TP_PERIOD.Controls.Add(LBL_PERIOD, 0, 0)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_ALL, 1, 0)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_HOUR, 2, 0)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_DAY, 3, 0)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_WEEK, 1, 1)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_MONTH, 2, 1)
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_YEAR, 3, 1)
Me.TP_PERIOD.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_PERIOD.Location = New System.Drawing.Point(1, 30)
Me.TP_PERIOD.Margin = New System.Windows.Forms.Padding(0)
Me.TP_PERIOD.Name = "TP_PERIOD"
Me.TP_PERIOD.RowCount = 2
Me.TP_PERIOD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TP_PERIOD.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TP_PERIOD.Size = New System.Drawing.Size(475, 56)
Me.TP_PERIOD.TabIndex = 2
'
'LBL_PERIOD
'
LBL_PERIOD.AutoSize = True
LBL_PERIOD.Dock = System.Windows.Forms.DockStyle.Fill
LBL_PERIOD.Location = New System.Drawing.Point(3, 0)
LBL_PERIOD.Name = "LBL_PERIOD"
LBL_PERIOD.Size = New System.Drawing.Size(112, 28)
LBL_PERIOD.TabIndex = 0
LBL_PERIOD.Text = "Period"
LBL_PERIOD.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'OPT_PERIOD_ALL
'
Me.OPT_PERIOD_ALL.AutoSize = True
Me.OPT_PERIOD_ALL.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_ALL.Location = New System.Drawing.Point(121, 3)
Me.OPT_PERIOD_ALL.Name = "OPT_PERIOD_ALL"
Me.OPT_PERIOD_ALL.Size = New System.Drawing.Size(112, 22)
Me.OPT_PERIOD_ALL.TabIndex = 1
Me.OPT_PERIOD_ALL.TabStop = True
Me.OPT_PERIOD_ALL.Text = "All"
Me.OPT_PERIOD_ALL.UseVisualStyleBackColor = True
'
'OPT_PERIOD_HOUR
'
Me.OPT_PERIOD_HOUR.AutoSize = True
Me.OPT_PERIOD_HOUR.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_HOUR.Location = New System.Drawing.Point(239, 3)
Me.OPT_PERIOD_HOUR.Name = "OPT_PERIOD_HOUR"
Me.OPT_PERIOD_HOUR.Size = New System.Drawing.Size(112, 22)
Me.OPT_PERIOD_HOUR.TabIndex = 2
Me.OPT_PERIOD_HOUR.TabStop = True
Me.OPT_PERIOD_HOUR.Text = "Hour"
Me.OPT_PERIOD_HOUR.UseVisualStyleBackColor = True
'
'OPT_PERIOD_DAY
'
Me.OPT_PERIOD_DAY.AutoSize = True
Me.OPT_PERIOD_DAY.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_DAY.Location = New System.Drawing.Point(357, 3)
Me.OPT_PERIOD_DAY.Name = "OPT_PERIOD_DAY"
Me.OPT_PERIOD_DAY.Size = New System.Drawing.Size(115, 22)
Me.OPT_PERIOD_DAY.TabIndex = 3
Me.OPT_PERIOD_DAY.TabStop = True
Me.OPT_PERIOD_DAY.Text = "Day"
Me.OPT_PERIOD_DAY.UseVisualStyleBackColor = True
'
'OPT_PERIOD_WEEK
'
Me.OPT_PERIOD_WEEK.AutoSize = True
Me.OPT_PERIOD_WEEK.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_WEEK.Location = New System.Drawing.Point(121, 31)
Me.OPT_PERIOD_WEEK.Name = "OPT_PERIOD_WEEK"
Me.OPT_PERIOD_WEEK.Size = New System.Drawing.Size(112, 22)
Me.OPT_PERIOD_WEEK.TabIndex = 4
Me.OPT_PERIOD_WEEK.TabStop = True
Me.OPT_PERIOD_WEEK.Text = "Week"
Me.OPT_PERIOD_WEEK.UseVisualStyleBackColor = True
'
'OPT_PERIOD_MONTH
'
Me.OPT_PERIOD_MONTH.AutoSize = True
Me.OPT_PERIOD_MONTH.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_MONTH.Location = New System.Drawing.Point(239, 31)
Me.OPT_PERIOD_MONTH.Name = "OPT_PERIOD_MONTH"
Me.OPT_PERIOD_MONTH.Size = New System.Drawing.Size(112, 22)
Me.OPT_PERIOD_MONTH.TabIndex = 5
Me.OPT_PERIOD_MONTH.TabStop = True
Me.OPT_PERIOD_MONTH.Text = "Month"
Me.OPT_PERIOD_MONTH.UseVisualStyleBackColor = True
'
'OPT_PERIOD_YEAR
'
Me.OPT_PERIOD_YEAR.AutoSize = True
Me.OPT_PERIOD_YEAR.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_PERIOD_YEAR.Location = New System.Drawing.Point(357, 31)
Me.OPT_PERIOD_YEAR.Name = "OPT_PERIOD_YEAR"
Me.OPT_PERIOD_YEAR.Size = New System.Drawing.Size(115, 22)
Me.OPT_PERIOD_YEAR.TabIndex = 6
Me.OPT_PERIOD_YEAR.TabStop = True
Me.OPT_PERIOD_YEAR.Text = "Year"
Me.OPT_PERIOD_YEAR.UseVisualStyleBackColor = True
'
'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.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(493, 151)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(493, 151)
Me.Name = "RedditViewSettingsForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "Options"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
TP_VIEW_MODE.ResumeLayout(False)
TP_VIEW_MODE.PerformLayout()
Me.TP_PERIOD.ResumeLayout(False)
Me.TP_PERIOD.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents OPT_VIEW_MODE_NEW As RadioButton
Private WithEvents OPT_VIEW_MODE_HOT As RadioButton
Private WithEvents OPT_VIEW_MODE_TOP As RadioButton
Private WithEvents OPT_PERIOD_ALL As RadioButton
Private WithEvents OPT_PERIOD_HOUR As RadioButton
Private WithEvents OPT_PERIOD_DAY As RadioButton
Private WithEvents OPT_PERIOD_WEEK As RadioButton
Private WithEvents OPT_PERIOD_MONTH As RadioButton
Private WithEvents OPT_PERIOD_YEAR As RadioButton
Private WithEvents TP_PERIOD As TableLayoutPanel
End Class
End Namespace

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
' Copyright (C) 2022 Andy
' 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.Toolbars
Imports CView = SCrawler.API.Reddit.IRedditView.View
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit
Friend Class RedditViewSettingsForm : Implements IOkCancelToolbar
Private ReadOnly MyDefs As DefaultFormProps
Private ReadOnly Property MyOptions As IRedditView
Friend Sub New(ByRef opt As IRedditView)
InitializeComponent()
MyOptions = opt
MyDefs = New DefaultFormProps
End Sub
Private Sub ChannelSettingsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
Dim n$ = String.Empty
If TypeOf MyOptions Is Channel Then
n = $"Channel [{DirectCast(MyOptions, Channel).Name}]"
ElseIf TypeOf MyOptions Is Base.IUserData Then
n = $"User [{DirectCast(MyOptions, Base.IUserData).Name}]"
End If
If Not n.IsEmptyString Then Text = n
With MyDefs
.MyViewInitialize(Me, Settings.Design, True)
.AddOkCancelToolbar()
.AppendDetectors()
.DelegateClosingChecker()
Select Case MyOptions.ViewMode
Case CView.Hot : OPT_VIEW_MODE_HOT.Checked = True
Case CView.Top : OPT_VIEW_MODE_TOP.Checked = True
Case Else : OPT_VIEW_MODE_NEW.Checked = True
End Select
Select Case MyOptions.ViewPeriod
Case CPeriod.Hour : OPT_PERIOD_HOUR.Checked = True
Case CPeriod.Day : OPT_PERIOD_DAY.Checked = True
Case CPeriod.Week : OPT_PERIOD_WEEK.Checked = True
Case CPeriod.Month : OPT_PERIOD_MONTH.Checked = True
Case CPeriod.Year : OPT_PERIOD_YEAR.Checked = True
Case Else : OPT_PERIOD_ALL.Checked = True
End Select
ChangePeriodEnabled()
.EndLoaderOperations()
End With
Catch ex As Exception
MyDefs.InvokeLoaderError(ex)
End Try
End Sub
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
With MyOptions
Select Case True
Case OPT_VIEW_MODE_HOT.Checked : .ViewMode = CView.Hot
Case OPT_VIEW_MODE_TOP.Checked : .ViewMode = CView.Top
Case Else : .ViewMode = CView.New
End Select
Select Case True
Case OPT_PERIOD_HOUR.Checked : .ViewPeriod = CPeriod.Hour
Case OPT_PERIOD_DAY.Checked : .ViewPeriod = CPeriod.Day
Case OPT_PERIOD_WEEK.Checked : .ViewPeriod = CPeriod.Week
Case OPT_PERIOD_MONTH.Checked : .ViewPeriod = CPeriod.Month
Case OPT_PERIOD_YEAR.Checked : .ViewPeriod = CPeriod.Year
Case Else : .ViewPeriod = CPeriod.All
End Select
End With
MyDefs.CloseForm()
End Sub
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
MyDefs.CloseForm(DialogResult.Cancel)
End Sub
Private Sub OPT_VIEW_MODE_NEW_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_VIEW_MODE_NEW.CheckedChanged
ChangePeriodEnabled()
End Sub
Private Sub OPT_VIEW_MODE_HOT_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_VIEW_MODE_HOT.CheckedChanged
ChangePeriodEnabled()
End Sub
Private Sub OPT_VIEW_MODE_TOP_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_VIEW_MODE_TOP.CheckedChanged
ChangePeriodEnabled()
End Sub
Private Sub ChangePeriodEnabled()
TP_PERIOD.Enabled = OPT_VIEW_MODE_TOP.Checked
End Sub
End Class
End Namespace

View File

@@ -14,7 +14,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports DownDetector = SCrawler.API.Base.DownDetector Imports DownDetector = SCrawler.API.Base.DownDetector
Imports Download = SCrawler.Plugin.ISiteSettings.Download Imports Download = SCrawler.Plugin.ISiteSettings.Download
Namespace API.Reddit Namespace API.Reddit
<Manifest(RedditSiteKey), UseClassAsIs, SavedPosts> <Manifest(RedditSiteKey), UseClassAsIs, SavedPosts, SpecialForm(False)>
Friend Class SiteSettings : Inherits SiteSettingsBase Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Overrides ReadOnly Property Icon As Icon Friend Overrides ReadOnly Property Icon As Icon
Get Get
@@ -53,7 +53,10 @@ Namespace API.Reddit
Case Download.Channel : Return New UserData With {.SaveToCache = False, .SkipExistsUsers = False, .AutoGetLimits = True} Case Download.Channel : Return New UserData With {.SaveToCache = False, .SkipExistsUsers = False, .AutoGetLimits = True}
Case Download.SavedPosts Case Download.SavedPosts
Dim u As New UserData With {.IsSavedPosts = True} Dim u As New UserData With {.IsSavedPosts = True}
DirectCast(u, UserDataBase).User = New UserInfo With {.Name = CStr(AConvert(Of String)(SavedPostsUserName.Value, String.Empty))} DirectCast(u, UserDataBase).User = New UserInfo With {
.Name = CStr(AConvert(Of String)(SavedPostsUserName.Value, String.Empty)),
.IsChannel = True
}
Return u Return u
End Select End Select
Return Nothing Return Nothing
@@ -81,7 +84,7 @@ Namespace API.Reddit
If avg > 100 Then If avg > 100 Then
Return MsgBoxE({"Over the past hour, Reddit has received an average of " & Return MsgBoxE({"Over the past hour, Reddit has received an average of " &
avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr & avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr &
dl.ListToString(, vbCr) & vbCr & vbCr & dl.ListToString(vbCr) & vbCr & vbCr &
"Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes "Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes
End If End If
End If End If
@@ -93,5 +96,11 @@ Namespace API.Reddit
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia) Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
Return UserData.GetVideoInfo(URL, Responser) Return UserData.GetVideoInfo(URL, Responser)
End Function End Function
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
End If
End Sub
End Class End Class
End Namespace End Namespace

View File

@@ -14,10 +14,13 @@ Imports PersonalUtilities.Tools.WebDocuments.JSON
Imports System.Net Imports System.Net
Imports System.Threading Imports System.Threading
Imports SCrawler.API.Base Imports SCrawler.API.Base
Imports SCrawler.API.Reddit.RedditViewExchange
Imports UStates = SCrawler.API.Base.UserMedia.States Imports UStates = SCrawler.API.Base.UserMedia.States
Imports UTypes = SCrawler.API.Base.UserMedia.Types Imports UTypes = SCrawler.API.Base.UserMedia.Types
Imports CView = SCrawler.API.Reddit.IRedditView.View
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
Namespace API.Reddit Namespace API.Reddit
Friend Class UserData : Inherits UserDataBase : Implements IChannelData Friend Class UserData : Inherits UserDataBase : Implements IChannelData, IRedditView
Private ReadOnly Property MySiteSettings As SiteSettings Private ReadOnly Property MySiteSettings As SiteSettings
Get Get
Return DirectCast(HOST.Source, SiteSettings) Return DirectCast(HOST.Source, SiteSettings)
@@ -60,6 +63,41 @@ Namespace API.Reddit
Select c.Post) Else Return Nothing Select c.Post) Else Return Nothing
End Function End Function
#End Region #End Region
#Region "IRedditView Support"
Friend Property ViewMode As CView Implements IRedditView.ViewMode
Friend Property ViewPeriod As CPeriod Implements IRedditView.ViewPeriod
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
If Not Options Is Nothing Then
ViewMode = Options.ViewMode
ViewPeriod = Options.ViewPeriod
End If
End Sub
Private ReadOnly Property View As String
Get
Select Case ViewMode
Case CView.Hot : Return "hot"
Case CView.Top : Return "top"
Case Else : Return "new"
End Select
End Get
End Property
Private ReadOnly Property Period As String
Get
If ViewMode = CView.Top Then
Select Case ViewPeriod
Case CPeriod.Hour : Return "hour"
Case CPeriod.Day : Return "day"
Case CPeriod.Week : Return "week"
Case CPeriod.Month : Return "month"
Case CPeriod.Year : Return "year"
Case Else : Return "all"
End Select
Else
Return "all"
End If
End Get
End Property
#End Region
#Region "Initializer" #Region "Initializer"
Friend Sub New() Friend Sub New()
ChannelPostsNames = New List(Of String) ChannelPostsNames = New List(Of String)
@@ -69,6 +107,21 @@ Namespace API.Reddit
#End Region #End Region
#Region "Load and Update user info" #Region "Load and Update user info"
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean) Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
With Container
If Loading Then
ViewMode = .Value(Name_ViewMode).FromXML(Of Integer)(CInt(CView.New))
ViewPeriod = .Value(Name_ViewPeriod).FromXML(Of Integer)(CInt(CPeriod.All))
Else
.Add(Name_ViewMode, CInt(ViewMode))
.Add(Name_ViewPeriod, CInt(ViewPeriod))
End If
End With
End Sub
Friend Overrides Function ExchangeOptionsGet() As Object
Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod}
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))
End Sub End Sub
#End Region #End Region
#Region "Download Overrides" #Region "Download Overrides"
@@ -80,6 +133,7 @@ Namespace API.Reddit
Responser = New Response Responser = New Response
Responser.Copy(MySiteSettings.Responser) Responser.Copy(MySiteSettings.Responser)
ChannelPostsNames.ListAddList(ChannelInfo.PostsAll.Select(Function(p) p.ID), LNC) ChannelPostsNames.ListAddList(ChannelInfo.PostsAll.Select(Function(p) p.ID), LNC)
If Not ViewMode = CView.New Then ChannelPostsNames.ListAddList(ChannelInfo.PostsNames, LNC)
If SkipExistsUsers Then _ExistsUsersNames.ListAddList(Settings.UsersList.Select(Function(p) p.Name), LNC) If SkipExistsUsers Then _ExistsUsersNames.ListAddList(Settings.UsersList.Select(Function(p) p.Name), LNC)
DownloadDataF(Token) DownloadDataF(Token)
ReparseVideo(Token) ReparseVideo(Token)
@@ -133,7 +187,7 @@ Namespace API.Reddit
Dim UPicType As Func(Of String, UTypes) = Function(input) IIf(input = "image", UTypes.Picture, UTypes.GIF) Dim UPicType As Func(Of String, UTypes) = Function(input) IIf(input = "image", UTypes.Picture, UTypes.GIF)
Dim _PostID As Func(Of String) = Function() IIf(PostTmp.IsEmptyString, PostID, PostTmp) Dim _PostID As Func(Of String) = Function() IIf(PostTmp.IsEmptyString, PostID, PostTmp)
URL = $"https://gateway.reddit.com/desktopapi/v1/user/{Name}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort=new&t=all&layout=classic" URL = $"https://gateway.reddit.com/desktopapi/v1/user/{Name}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
ThrowAny(Token) ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException) Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
If Not r.IsEmptyString Then If Not r.IsEmptyString Then
@@ -241,7 +295,7 @@ Namespace API.Reddit
If IsSavedPosts Then If IsSavedPosts Then
URL = $"https://www.reddit.com/user/{Name}/saved.json?after={POST}" URL = $"https://www.reddit.com/user/{Name}/saved.json?after={POST}"
Else Else
URL = $"https://reddit.com/r/{Name}/new.json?allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort=new&t=all&layout=classic" URL = $"https://reddit.com/r/{Name}/{View}.json?allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
End If End If
ThrowAny(Token) ThrowAny(Token)
@@ -258,10 +312,13 @@ Namespace API.Reddit
PostID = s.Value("name") PostID = s.Value("name")
If PostID.IsEmptyString AndAlso s.Contains("id") Then PostID = s("id").Value If PostID.IsEmptyString AndAlso s.Contains("id") Then PostID = s("id").Value
If ChannelPostsNames.Contains(PostID) Then ExistsDetected = True : Continue For 'Exit Sub If ChannelPostsNames.Contains(PostID) Then
If ViewMode = CView.New Then ExistsDetected = True Else NewPostDetected = True 'bypass
Continue For 'Exit Sub
End If
If DownloadLimitCount.HasValue AndAlso _TotalPostsDownloaded >= DownloadLimitCount.Value Then Exit Sub If DownloadLimitCount.HasValue AndAlso _TotalPostsDownloaded >= DownloadLimitCount.Value Then Exit Sub
If Not DownloadLimitPost.IsEmptyString AndAlso DownloadLimitPost = PostID Then Exit Sub If Not DownloadLimitPost.IsEmptyString AndAlso DownloadLimitPost = PostID Then Exit Sub
If DownloadLimitDate.HasValue AndAlso _TempMediaList.Count > 0 Then If ViewMode = CView.New AndAlso DownloadLimitDate.HasValue AndAlso _TempMediaList.Count > 0 Then
With (From __u In _TempMediaList Where __u.Post.Date.HasValue Select __u.Post.Date.Value) With (From __u In _TempMediaList Where __u.Post.Date.HasValue Select __u.Post.Date.Value)
If .Count > 0 Then lDate = .Min Else lDate = Nothing If .Count > 0 Then lDate = .Min Else lDate = Nothing
End With End With
@@ -283,7 +340,7 @@ Namespace API.Reddit
If s.Contains("created") Then PostDate = s("created").Value Else PostDate = String.Empty If s.Contains("created") Then PostDate = s("created").Value Else PostDate = String.Empty
_UserID = s.Value("author") _UserID = s.Value("author")
If SkipExistsUsers AndAlso _ExistsUsersNames.Count > 0 AndAlso If Not IsSavedPosts AndAlso SkipExistsUsers AndAlso _ExistsUsersNames.Count > 0 AndAlso
Not _UserID.IsEmptyString AndAlso _ExistsUsersNames.Contains(_UserID) Then Not _UserID.IsEmptyString AndAlso _ExistsUsersNames.Contains(_UserID) Then
If Not IsSavedPosts AndAlso Not ChannelInfo Is Nothing Then _ If Not IsSavedPosts AndAlso Not ChannelInfo Is Nothing Then _
ChannelInfo.ChannelExistentUserNames.ListAddValue(_UserID, LNC) ChannelInfo.ChannelExistentUserNames.ListAddValue(_UserID, LNC)
@@ -291,7 +348,7 @@ Namespace API.Reddit
End If End If
tmpUrl = s.Value("url") tmpUrl = s.Value("url")
If Not tmpUrl.IsEmptyString AndAlso tmpUrl.Contains("redgifs.com") Then If Not tmpUrl.IsEmptyString AndAlso tmpUrl.StringContains({"redgifs.com", "gfycat.com"}) Then
If SaveToCache Then If SaveToCache Then
tmpUrl = s.Value({"media", "oembed"}, "thumbnail_url") tmpUrl = s.Value({"media", "oembed"}, "thumbnail_url")
If Not tmpUrl.IsEmptyString Then If Not tmpUrl.IsEmptyString Then
@@ -366,6 +423,8 @@ Namespace API.Reddit
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL.Replace(".gifv", ".mp4"), _TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL.Replace(".gifv", ".mp4"),
PostID, PostDate, _UserID, IsChannel), LNC) PostID, PostDate, _UserID, IsChannel), LNC)
End If End If
ElseIf _URL.Contains(".mp4") Then
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL, PostID, PostDate, _UserID, IsChannel), LNC)
ElseIf _URL.Contains(".gif") Then ElseIf _URL.Contains(".gif") Then
_TempMediaList.ListAddValue(MediaFromData(UTypes.GIF, _URL, PostID, PostDate, _UserID, IsChannel), LNC) _TempMediaList.ListAddValue(MediaFromData(UTypes.GIF, _URL, PostID, PostDate, _UserID, IsChannel), LNC)
Else Else
@@ -643,6 +702,7 @@ Namespace API.Reddit
End Using End Using
End If End If
End If End If
Catch iex As IndexOutOfRangeException When Disposed
Catch oex As OperationCanceledException When Token.IsCancellationRequested Catch oex As OperationCanceledException When Token.IsCancellationRequested
Catch dex As ObjectDisposedException When Disposed Catch dex As ObjectDisposedException When Disposed
Catch ex As Exception Catch ex As Exception

View File

@@ -12,7 +12,7 @@ Imports PersonalUtilities.Tools
Imports PersonalUtilities.Functions.RegularExpressions Imports PersonalUtilities.Functions.RegularExpressions
Imports SCrawler.API.Base Imports SCrawler.API.Base
Namespace API.Twitter Namespace API.Twitter
<Manifest("AndyProgram_Twitter"), UseClassAsIs> <Manifest("AndyProgram_Twitter"), SavedPosts, UseClassAsIs>
Friend Class SiteSettings : Inherits SiteSettingsBase Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Const Header_Authorization As String = "authorization" Friend Const Header_Authorization As String = "authorization"
Friend Const Header_Token As String = "x-csrf-token" Friend Const Header_Token As String = "x-csrf-token"
@@ -31,6 +31,8 @@ Namespace API.Twitter
Private ReadOnly Property Auth As PropertyValue Private ReadOnly Property Auth As PropertyValue
<PropertyOption(AllowNull:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")> <PropertyOption(AllowNull:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
Private ReadOnly Property Token As PropertyValue Private ReadOnly Property Token As PropertyValue
<PropertyOption(ControlText:="Saved posts user name", ControlToolTip:="Personal profile username", LeftOffset:=120), PXML>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
Friend Overrides ReadOnly Property Responser As WEB.Response Friend Overrides ReadOnly Property Responser As WEB.Response
Friend Sub New() Friend Sub New()
MyBase.New(TwitterSite) MyBase.New(TwitterSite)
@@ -70,6 +72,7 @@ Namespace API.Twitter
Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v)) Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v)) Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1) UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
UrlPatternUser = "https://twitter.com/{0}" UrlPatternUser = "https://twitter.com/{0}"
@@ -90,7 +93,11 @@ Namespace API.Twitter
End If End If
End Sub End Sub
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
If What = ISiteSettings.Download.SavedPosts Then
Return New UserData With {.IsSavedPosts = True, .User = New UserInfo With {.Name = CStr(AConvert(Of String)(SavedPostsUserName.Value, String.Empty))}}
Else
Return New UserData Return New UserData
End If
End Function End Function
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia) Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
Return UserData.GetVideoInfo(URL, Responser) Return UserData.GetVideoInfo(URL, Responser)

View File

@@ -27,12 +27,19 @@ Namespace API.Twitter
End Sub End Sub
#Region "Download functions" #Region "Download functions"
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken) Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
If IsSavedPosts Then
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.Post.ID), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData(String.Empty, Token)
Else
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly) If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
DownloadData(String.Empty, Token) DownloadData(String.Empty, Token)
End If
End Sub End Sub
Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken) Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken)
Dim URL$ = String.Empty Dim URL$ = String.Empty
Try Try
Dim NextCursor$ = String.Empty
Dim __NextCursor As Predicate(Of EContainer) = Function(e) e.Value({"content", "operation", "cursor"}, "cursorType") = "Bottom"
Dim PostID$ = String.Empty Dim PostID$ = String.Empty
Dim PostDate$, dName$ Dim PostDate$, dName$
Dim m As EContainer, nn As EContainer, s As EContainer Dim m As EContainer, nn As EContainer, s As EContainer
@@ -42,24 +49,37 @@ Namespace API.Twitter
Dim PicNode As Predicate(Of EContainer) = Function(e) e.Count > 0 AndAlso e.Contains("media_url") Dim PicNode As Predicate(Of EContainer) = Function(e) e.Count > 0 AndAlso e.Contains("media_url")
Dim UID As Func(Of EContainer, String) = Function(e) e.XmlIfNothing.Item({"user", "id"}).XmlIfNothingValue Dim UID As Func(Of EContainer, String) = Function(e) e.XmlIfNothing.Item({"user", "id"}).XmlIfNothingValue
If IsSavedPosts Then
If Name.IsEmptyString Then Throw New ArgumentNullException With {.HelpLink = 1}
URL = $"https://api.twitter.com/2/timeline/bookmark.json?screen_name={Name}&count=200" &
"&tweet_mode=extended&include_entities=true&include_user_entities=true&include_ext_media_availability=true"
If Not POST.IsEmptyString Then URL &= $"&cursor={SymbolsConverter.ASCII.EncodeSymbolsOnly(POST)}"
Else
URL = $"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={Name}&count=200&exclude_replies=false&include_rts=1&tweet_mode=extended" URL = $"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={Name}&count=200&exclude_replies=false&include_rts=1&tweet_mode=extended"
If Not POST.IsEmptyString Then URL &= $"&max_id={POST}" If Not POST.IsEmptyString Then URL &= $"&max_id={POST}"
End If
ThrowAny(Token) ThrowAny(Token)
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException) Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
If Not r.IsEmptyString Then If Not r.IsEmptyString Then
Using w As EContainer = JsonDocument.Parse(r) Using w As EContainer = JsonDocument.Parse(r)
If Not w Is Nothing AndAlso w.Count > 0 Then If Not w Is Nothing AndAlso w.Count > 0 Then
For Each nn In w For Each nn In If(IsSavedPosts, w({"globalObjects", "tweets"}).XmlIfNothing, w)
ThrowAny(Token) ThrowAny(Token)
If nn.Count > 0 Then If nn.Count > 0 Then
If IsSavedPosts Then
PostID = nn.Value
If PostID.IsEmptyString Then PostID = nn.Value("id_str")
Else
PostID = nn.Value("id") PostID = nn.Value("id")
If ID.IsEmptyString Then If ID.IsEmptyString Then
ID = UID(nn) ID = UID(nn)
If Not ID.IsEmptyString Then UpdateUserInformation() If Not ID.IsEmptyString Then UpdateUserInformation()
End If End If
End If
If UserDescriptionNeedToUpdate() AndAlso nn.Value({"user"}, "screen_name") = Name Then UserDescriptionUpdate(nn.Value({"user"}, "description")) If Not IsSavedPosts AndAlso UserDescriptionNeedToUpdate() AndAlso nn.Value({"user"}, "screen_name") = Name Then _
UserDescriptionUpdate(nn.Value({"user"}, "description"))
'Date Pattern: 'Date Pattern:
'Sat Jan 01 01:10:15 +0000 2000 'Sat Jan 01 01:10:15 +0000 2000
@@ -74,7 +94,7 @@ Namespace API.Twitter
Continue For Continue For
End If End If
If Not ParseUserMediaOnly OrElse (Not nn.Contains("retweeted_status") OrElse If IsSavedPosts OrElse Not ParseUserMediaOnly OrElse (Not nn.Contains("retweeted_status") OrElse
(Not ID.IsEmptyString AndAlso UID(nn("retweeted_status")) = ID)) Then (Not ID.IsEmptyString AndAlso UID(nn("retweeted_status")) = ID)) Then
If Not CheckVideoNode(nn, PostID, PostDate) Then If Not CheckVideoNode(nn, PostID, PostDate) Then
s = nn.ItemF({"extended_entities", "media"}) s = nn.ItemF({"extended_entities", "media"})
@@ -95,13 +115,25 @@ Namespace API.Twitter
End If End If
End If End If
Next Next
If IsSavedPosts Then
s = w.ItemF({"timeline", "instructions", 0, "addEntries", "entries"}).XmlIfNothing
If s.Count > 0 Then NextCursor = If(s.ItemF({__NextCursor})?.Value({"content", "operation", "cursor"}, "value"), String.Empty)
End If
End If End If
End Using End Using
If IsSavedPosts Then
If Not NextCursor.IsEmptyString And Not NextCursor = POST Then DownloadData(NextCursor, Token)
Else
If POST.IsEmptyString And ExistsDetected Then Exit Sub If POST.IsEmptyString And ExistsDetected Then Exit Sub
If Not PostID.IsEmptyString And NewPostDetected Then DownloadData(PostID, Token) If Not PostID.IsEmptyString And NewPostDetected Then DownloadData(PostID, Token)
End If End If
End If
Catch ane As ArgumentNullException When ane.HelpLink = 1
MyMainLOG = "Username not set for saved Twitter posts"
Catch ex As Exception Catch ex As Exception
ProcessException(ex, Token, $"data downloading error [{URL}]") ProcessException(ex, Token, $"data downloading error{IIf(IsSavedPosts, " (Saved Posts)", String.Empty)} [{URL}]")
End Try End Try
End Sub End Sub
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Response) As IEnumerable(Of UserMedia) Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Response) As IEnumerable(Of UserMedia)
@@ -128,20 +160,34 @@ Namespace API.Twitter
End Function End Function
#Region "Picture options" #Region "Picture options"
Private Function GetPictureOption(ByVal w As EContainer) As String Private Function GetPictureOption(ByVal w As EContainer) As String
Const P4K As String = "4096x4096"
Try Try
Dim ww As EContainer = w("sizes") Dim ww As EContainer = w("sizes")
If Not ww Is Nothing AndAlso ww.Count > 0 Then If Not ww Is Nothing AndAlso ww.Count > 0 Then
Dim l As New List(Of Sizes) Dim l As New List(Of Sizes)
Dim Orig As Sizes? = New Sizes(w.Value({"original_info"}, "height").FromXML(Of Integer)(-1), P4K)
If Orig.Value.Value = -1 Then Orig = Nothing
Dim LargeContained As Boolean = ww.Contains("large") Dim LargeContained As Boolean = ww.Contains("large")
For Each v As EContainer In ww For Each v As EContainer In ww
If v.Count > 0 AndAlso v.Contains("h") Then l.Add(New Sizes(v.Value("h"), v.Name)) If v.Count > 0 AndAlso v.Contains("h") Then l.Add(New Sizes(v.Value("h"), v.Name))
Next Next
If l.Count > 0 Then If l.Count > 0 Then
l.Sort() l.Sort()
If l(0).Data.IsEmptyString And LargeContained Then Return "large" Else Return l(0).Data If Orig.HasValue AndAlso l(0).Value < Orig.Value.Value Then
Return P4K
ElseIf l(0).Data.IsEmptyString Then
If LargeContained Then Return "large" Else Return P4K
Else
Return l(0).Data
End If End If
Else
Return P4K
End If End If
ElseIf Not w.Value({"original_info"}, "height").IsEmptyString Then
Return P4K
Else
Return String.Empty Return String.Empty
End If
Catch ex As Exception Catch ex As Exception
LogError(ex, "[API.Twitter.UserData.GetPictureOption]") LogError(ex, "[API.Twitter.UserData.GetPictureOption]")
Return String.Empty Return String.Empty

View File

@@ -207,6 +207,18 @@ Namespace API
Return Count > 0 AndAlso Collections.Exists(Function(c) c.FitToAddParams) Return Count > 0 AndAlso Collections.Exists(Function(c) c.FitToAddParams)
End Get End Get
End Property End Property
Friend Overrides Property ScriptUse As Boolean
Get
Return Count > 0 AndAlso Collections.Exists(Function(c) c.ScriptUse)
End Get
Set(ByVal u As Boolean)
If Count > 0 Then Collections.ForEach(Sub(ByVal c As IUserData)
Dim b As Boolean = c.ScriptUse = u
c.ScriptUse = u
If Not b Then c.UpdateUserInformation()
End Sub)
End Set
End Property
#Region "Context buttons" #Region "Context buttons"
Friend ReadOnly Property ContextDown As ToolStripMenuItem() Friend ReadOnly Property ContextDown As ToolStripMenuItem()
Get Get
@@ -336,6 +348,7 @@ Namespace API
.Favorite = Favorite .Favorite = Favorite
.ReadyForDownload = ReadyForDownload .ReadyForDownload = ReadyForDownload
ConsolidateLabels() ConsolidateLabels()
ConsolidateScripts()
.UpdateUserInformation() .UpdateUserInformation()
End If End If
ImageHandler(_Item, False) ImageHandler(_Item, False)
@@ -381,6 +394,9 @@ Namespace API
Collections.ForEach(Sub(c) c.Labels.ListAddList(l, lp)) Collections.ForEach(Sub(c) c.Labels.ListAddList(l, lp))
End If End If
End Sub End Sub
Private Sub ConsolidateScripts()
If Count > 1 AndAlso ScriptUse Then Collections.ForEach(Sub(c) c.ScriptUse = True)
End Sub
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData)) Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
If Not _Items Is Nothing AndAlso _Items.Count > 0 Then If Not _Items Is Nothing AndAlso _Items.Count > 0 Then
For i% = 0 To _Items.Count - 1 : Add(_Items(i)) : Next For i% = 0 To _Items.Count - 1 : Add(_Items(i)) : Next

View File

@@ -160,7 +160,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
CMB_CHANNELS.Buttons.AddRange({CmbDefaultButtons.Refresh, CmbDefaultButtons.Add, CmbDefaultButtons.Delete, CMB_CHANNELS.Buttons.AddRange({CmbDefaultButtons.Refresh, CmbDefaultButtons.Add, CmbDefaultButtons.Delete,
New ActionButton(CmbDefaultButtons.Up) With {.ToolTipText = "Previous item (F1)"}, New ActionButton(CmbDefaultButtons.Up) With {.ToolTipText = "Previous item (F1)"},
New ActionButton(CmbDefaultButtons.Down) With {.ToolTipText = "Next item (F4)"}, New ActionButton(CmbDefaultButtons.Down) With {.ToolTipText = "Next item (F4)"},
CmbDefaultButtons.Info}) CmbDefaultButtons.Edit, CmbDefaultButtons.Info})
TXT_LIMIT = New TextBoxExtended With { TXT_LIMIT = New TextBoxExtended With {
.CaptionText = "Limit", .CaptionText = "Limit",
.Margin = New Padding(2), .Margin = New Padding(2),
@@ -201,11 +201,12 @@ Friend Class ChannelViewForm : Implements IChannelLimits
MyRange = New RangeSwitcher(Of UserPost) With {.Selector = SelectorExpression} MyRange = New RangeSwitcher(Of UserPost) With {.Selector = SelectorExpression}
With MyRange With MyRange
.Limit = ImagesInRow * ImagesRows .Limit = ImagesInRow * ImagesRows
.InsertButtons(ToolbarTOP, {RButton.Previous, RButton.Next}, 5) .InsertButtons(ToolbarTOP,, 5)
.SetButtonKey(RButton.Previous, Keys.F2) .SetButtonKey(RButton.Previous, Keys.F2)
.SetButtonKey(RButton.Next, Keys.F3) .SetButtonKey(RButton.Next, Keys.F3)
.BindForm(Me) .BindForm(Me)
.LabelNumbersProvider = CProvider .LabelNumbersProvider = CProvider
.LabelShowAbsolutIndexes = False
.UpdateControls() .UpdateControls()
End With End With
AddHandler Settings.ChannelsImagesColumns.OnValueChanged, AddressOf ImagesCountChanged AddHandler Settings.ChannelsImagesColumns.OnValueChanged, AddressOf ImagesCountChanged
@@ -215,6 +216,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
MyDefs.MyViewInitialize(Me, Settings.Design) MyDefs.MyViewInitialize(Me, Settings.Design)
RefillChannels(Settings.LatestSelectedChannel.Value) RefillChannels(Settings.LatestSelectedChannel.Value)
ChangeComboIndex(0) ChangeComboIndex(0)
MyRange.LabelText = String.Empty
CMB_CHANNELS_ActionOnCheckedChange(CMB_CHANNELS.Checked) CMB_CHANNELS_ActionOnCheckedChange(CMB_CHANNELS.Checked)
With LIST_POSTS With LIST_POSTS
Dim s As Size = GetImageSize() Dim s As Size = GetImageSize()
@@ -279,11 +281,10 @@ Friend Class ChannelViewForm : Implements IChannelLimits
End With End With
CMB_CHANNELS.EndUpdate() CMB_CHANNELS.EndUpdate()
End Sub End Sub
#Region "Images refill methods"
Private Sub AppendPendingUsers() Private Sub AppendPendingUsers()
If LIST_POSTS.CheckedIndices.Count > 0 Then If LIST_POSTS.CheckedIndices.Count > 0 Then
Dim c As Channel = GetCurrentChannel(False) Dim c As Channel = GetCurrentChannel(False)
Dim lp As New ListAddParams(LAP.NotContainsOnly) With {.OnAddAction = Sub(ByVal u As PendingUser) u.ChannelUserAdded()} Dim lp As New ListAddParams(LAP.NotContainsOnly) With {.OnProcessAction = Sub(ByVal u As PendingUser) u.ChannelUserAdded()}
PendingUsers.ListAddList((From p As ListViewItem In LIST_POSTS.Items PendingUsers.ListAddList((From p As ListViewItem In LIST_POSTS.Items
Where p.Checked Where p.Checked
Select New PendingUser(p.Text, c, GetPostBySelected(CStr(p.Tag)).CachedFile)), lp) Select New PendingUser(p.Text, c, GetPostBySelected(CStr(p.Tag)).CachedFile)), lp)
@@ -311,7 +312,6 @@ Friend Class ChannelViewForm : Implements IChannelLimits
End With End With
Return s Return s
End Function End Function
#End Region
#Region "Toolbar controls" #Region "Toolbar controls"
#Region "Downloader" #Region "Downloader"
Private TokenSource As CancellationTokenSource Private TokenSource As CancellationTokenSource
@@ -543,10 +543,12 @@ Friend Class ChannelViewForm : Implements IChannelLimits
LBL_LIMIT_TEXT.Text = String.Empty LBL_LIMIT_TEXT.Text = String.Empty
If Not c Is Nothing Then If Not c Is Nothing Then
Settings.LatestSelectedChannel.Value = c.ID Settings.LatestSelectedChannel.Value = c.ID
Dim d As Date?
If c.ViewMode = IRedditView.View.New Then
With c.PostsAll With c.PostsAll
If .Count > 0 Then If .Count > 0 Then
OPT_LIMITS_DEFAULT.Checked = True OPT_LIMITS_DEFAULT.Checked = True
Dim d As Date? = .FirstOrDefault(Function(p) p.Date.HasValue).Date d = .FirstOrDefault(Function(p) p.Date.HasValue).Date
If d.HasValue Then If d.HasValue Then
LBL_LIMIT_TEXT.Text = $"to date {AConvert(Of String)(d, ADateTime.Formats.BaseDateTime, String.Empty)}" LBL_LIMIT_TEXT.Text = $"to date {AConvert(Of String)(d, ADateTime.Formats.BaseDateTime, String.Empty)}"
Else Else
@@ -558,6 +560,13 @@ Friend Class ChannelViewForm : Implements IChannelLimits
LBL_LIMIT_TEXT.Text = $"first {TXT_LIMIT.Text} posts" LBL_LIMIT_TEXT.Text = $"first {TXT_LIMIT.Text} posts"
End If End If
End With End With
Else
OPT_LIMITS_DEFAULT.Checked = True
d = c.LatestParsedDate
Dim per$ = IIf(c.ViewMode = IRedditView.View.Top, c.ViewPeriod.ToString, String.Empty)
If Not per.IsEmptyString Then per = $" ({per})"
LBL_LIMIT_TEXT.Text = $"[{c.ViewMode}{per}] to date {AConvert(Of String)(d, ADateTime.Formats.BaseDateTime, String.Empty)}"
End If
End If End If
End Sub End Sub
Private Sub CMB_CHANNELS_ActionSelectedItemChanged(ByVal _Item As ListViewItem) Handles CMB_CHANNELS.ActionSelectedItemChanged Private Sub CMB_CHANNELS_ActionSelectedItemChanged(ByVal _Item As ListViewItem) Handles CMB_CHANNELS.ActionSelectedItemChanged
@@ -582,6 +591,18 @@ Friend Class ChannelViewForm : Implements IChannelLimits
End Try End Try
Case CmbDefaultButtons.Up : ChangeComboIndex(-1) Case CmbDefaultButtons.Up : ChangeComboIndex(-1)
Case CmbDefaultButtons.Down : ChangeComboIndex(1) Case CmbDefaultButtons.Down : ChangeComboIndex(1)
Case CmbDefaultButtons.Edit
Try
c = GetCurrentChannel()
If Not c Is Nothing Then
Using f As New RedditViewSettingsForm(c)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then c.Save()
End Using
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Error on trying to edit channel")
End Try
Case CmbDefaultButtons.Info Case CmbDefaultButtons.Info
Try Try
c = GetCurrentChannel() c = GetCurrentChannel()

View File

@@ -57,9 +57,9 @@ Friend Class ChannelsStatsForm : Implements IOkCancelDeleteToolbar
Try Try
Dim c As List(Of String) = CMB_CHANNELS.Items.CheckedItems.Select(Function(cc) CStr(cc.Value(1))).ListIfNothing Dim c As List(Of String) = CMB_CHANNELS.Items.CheckedItems.Select(Function(cc) CStr(cc.Value(1))).ListIfNothing
If c.ListExists Then If c.ListExists Then
If MsgBoxE({$"The following channels will be deleted:{vbCr}{c.ListToString(, vbCr)}", "Deleting channels"}, vbExclamation,,, {"Confirm", "Cancel"}) = 0 Then If MsgBoxE({$"The following channels will be deleted:{vbCr}{c.ListToString(vbCr)}", "Deleting channels"}, vbExclamation,,, {"Confirm", "Cancel"}) = 0 Then
For Each CID$ In c : Settings.Channels.Remove(Settings.Channels.Find(CID)) : Next For Each CID$ In c : Settings.Channels.Remove(Settings.Channels.Find(CID)) : Next
MyMainLOG = $"Deleted channels:{vbNewLine}{c.ListToString(, vbNewLine)}" MyMainLOG = $"Deleted channels:{vbNewLine}{c.ListToString(vbNewLine)}"
MsgBoxE("Channels deleted") MsgBoxE("Channels deleted")
DeletedChannels += c.Count DeletedChannels += c.Count
c.Clear() c.Clear()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

View File

@@ -12,7 +12,12 @@ Namespace DownloadObjects
Friend Class ActiveDownloadingProgress Friend Class ActiveDownloadingProgress
Private Const MinWidth As Integer = 450 Private Const MinWidth As Integer = 450
Private MyView As FormsView Private MyView As FormsView
Friend Property Opened As Boolean = False Private Opened As Boolean = False
Friend ReadOnly Property ReadyToOpen As Boolean
Get
Return Settings.DownloadOpenProgress And (Not Opened Or Settings.DownloadOpenProgress.Attribute) And Not Visible
End Get
End Property
Private ReadOnly JobsList As List(Of DownloadProgress) Private ReadOnly JobsList As List(Of DownloadProgress)
Friend Property DisableProgressChange As Boolean = False Friend Property DisableProgressChange As Boolean = False
Friend Sub New() Friend Sub New()

View File

@@ -156,7 +156,7 @@ Namespace DownloadObjects
RaiseEvent OnTotalCountChange() RaiseEvent OnTotalCountChange()
End Sub End Sub
Private Sub JobProgress_OnProgressChange(ByVal Source As IMyProgress, ByVal Index As Integer) Private Sub JobProgress_OnProgressChange(ByVal Source As IMyProgress, ByVal Index As Integer)
MainProgress.Perform() If Not Job.Type = Download.SavedPosts Then MainProgress.Perform()
End Sub End Sub
#End Region #End Region
#Region "IDisposable Support" #Region "IDisposable Support"

View File

@@ -13,7 +13,13 @@ Namespace DownloadObjects
Friend Class DownloadedInfoForm Friend Class DownloadedInfoForm
Friend Event OnUserLooking(ByVal Key As String) Friend Event OnUserLooking(ByVal Key As String)
Private MyView As FormsView Private MyView As FormsView
Private ReadOnly LParams As New ListAddParams(LAP.IgnoreICopier) With {.e = EDP.None} Private ReadOnly LParams As New ListAddParams(LAP.IgnoreICopier) With {.Error = EDP.None}
Private Opened As Boolean = False
Friend ReadOnly Property ReadyToOpen As Boolean
Get
Return Settings.DownloadOpenInfo And (Not Opened Or Settings.DownloadOpenInfo.Attribute) And Not Visible
End Get
End Property
Friend Enum ViewModes As Integer Friend Enum ViewModes As Integer
Session = 0 Session = 0
All = 1 All = 1
@@ -50,6 +56,8 @@ Namespace DownloadObjects
BTT_CLEAR.Visible = ViewMode = ViewModes.Session BTT_CLEAR.Visible = ViewMode = ViewModes.Session
RefillList() RefillList()
Catch ex As Exception Catch ex As Exception
Finally
Opened = True
End Try End Try
End Sub End Sub
Private Sub DownloadedInfoForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing Private Sub DownloadedInfoForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing

View File

@@ -0,0 +1,211 @@
' Copyright (C) 2022 Andy
' 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.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports SCrawler.API
Imports SCrawler.API.Base
Namespace DownloadObjects.Groups
Friend Class DownloadGroup : Implements IIndexable, IEContainerProvider, IDisposable
Friend Delegate Sub GroupEventHandler(ByVal Sender As DownloadGroup)
Friend Event Deleted As GroupEventHandler
Friend Event Updated As GroupEventHandler
#Region "XML Names"
Private Const Name_Name As String = "Name"
Private Const Name_Temporary As String = "Temporary"
Private Const Name_Favorite As String = "Favorite"
Private Const Name_ReadyForDownload As String = "RFD"
Private Const Name_ReadyForDownloadIgnore As String = "RFDI"
#End Region
Private WithEvents BTT_EDIT As ToolStripMenuItem
Private WithEvents BTT_DELETE As ToolStripMenuItem
Private WithEvents BTT_DOWNLOAD As ToolStripMenuItem
Private WithEvents BTT_DOWNLOAD_FULL As ToolStripMenuItem
Private ReadOnly SEP_1 As ToolStripSeparator
Private WithEvents BTT_MENU As ToolStripMenuItem
Friend Property Temporary As CheckState = CheckState.Indeterminate
Friend Property Favorite As CheckState = CheckState.Indeterminate
Friend Property ReadyForDownload As Boolean = True
Friend Property ReadyForDownloadIgnore As Boolean = False
Friend Property Name As String
Private _Key As String = String.Empty
Friend ReadOnly Property Key As String
Get
If _Key.IsEmptyString Then _Key = $"{Name}{Index}"
Return _Key
End Get
End Property
Private _Index As Integer = 0
Friend Property Index As Integer Implements IIndexable.Index
Get
Return _Index
End Get
Set(ByVal NewIndex As Integer)
Dim b As Boolean = Not _Index = NewIndex
_Index = NewIndex
If b Then RaiseEvent Updated(Me)
End Set
End Property
Friend ReadOnly Property Labels As List(Of String)
Friend ReadOnly Property Count As Integer
Get
Return Labels.Count
End Get
End Property
Friend Sub New()
Labels = New List(Of String)
BTT_MENU = New ToolStripMenuItem With {
.ToolTipText = "Download users of this group",
.AutoToolTip = True,
.Image = My.Resources.GroupBy_284.ToBitmap
}
BTT_DELETE = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.DeletePic_02_Red_24,
.BackColor = ColorBttDeleteBack,
.ForeColor = ColorBttDeleteFore,
.Text = "Delete",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
BTT_EDIT = New ToolStripMenuItem With {
.Image = PersonalUtilities.My.Resources.PencilPic_01_48,
.BackColor = ColorBttEditBack,
.ForeColor = ColorBttEditFore,
.Text = "Edit",
.ToolTipText = String.Empty,
.AutoToolTip = False
}
SEP_1 = New ToolStripSeparator
BTT_DOWNLOAD = New ToolStripMenuItem With {
.Image = My.Resources.StartPic_01_Green_16,
.Text = "Download",
.ToolTipText = "Download users of this group (respect the 'Ready for download' parameter)",
.AutoToolTip = True
}
BTT_DOWNLOAD_FULL = New ToolStripMenuItem With {
.Image = My.Resources.StartPic_01_Green_16,
.Text = "Download FULL",
.ToolTipText = "Download users of this group (ignore the 'Ready for download' parameter)",
.AutoToolTip = True
}
BTT_MENU.DropDownItems.AddRange({BTT_EDIT, BTT_DELETE, SEP_1, BTT_DOWNLOAD, BTT_DOWNLOAD_FULL})
End Sub
Friend Sub New(ByVal e As EContainer)
Me.New
Name = e.Attribute(Name_Name)
Temporary = e.Attribute(Name_Temporary).Value.FromXML(Of Integer)(CInt(CheckState.Indeterminate))
Favorite = e.Attribute(Name_Favorite).Value.FromXML(Of Integer)(CInt(CheckState.Indeterminate))
ReadyForDownload = e.Attribute(Name_ReadyForDownload).Value.FromXML(Of Boolean)(True)
ReadyForDownloadIgnore = e.Attribute(Name_ReadyForDownloadIgnore).Value.FromXML(Of Boolean)(False)
If Not e.Value.IsEmptyString Then Labels.ListAddList(e.Value.Split("|"), LAP.NotContainsOnly)
End Sub
Public Overrides Function ToString() As String
Return $"{IIf(Index >= 0 And Index <= 8, $"#{Index + 1}: ", String.Empty)}{Name}"
End Function
Private _ControlSent As Boolean = False
Friend Function GetControl() As ToolStripMenuItem
If Not _ControlSent Then
BTT_MENU.Text = ToString()
BTT_MENU.Tag = Key
_ControlSent = True
End If
Return BTT_MENU
End Function
Private Function SetIndex(ByVal Obj As Object, ByVal _Index As Integer) As Object Implements IIndexable.SetIndex
DirectCast(Obj, DownloadGroup).Index = _Index
Return Obj
End Function
#Region "Buttons"
Private Sub BTT_MENU_Click(sender As Object, e As EventArgs) Handles BTT_MENU.Click
DownloadUsers(True)
End Sub
Private Sub BTT_EDIT_Click(sender As Object, e As EventArgs) Handles BTT_EDIT.Click
Using f As New GroupEditorForm(Me)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then RaiseEvent Updated(Me)
End Using
End Sub
Private Sub BTT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE.Click
If MsgBoxE({$"Are you sure you want to delete the [{Name}] group?", "Deleting a group"}, vbExclamation + vbYesNo) = vbYes Then
RaiseEvent Deleted(Me)
MsgBoxE({$"Group [{Name}] deleted", "Deleting a group"})
End If
End Sub
Private Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click
DownloadUsers(True)
End Sub
Private Sub BTT_DOWNLOAD_FULL_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD_FULL.Click
DownloadUsers(False)
End Sub
Friend Sub DownloadUsers(ByVal UseReadyOption As Boolean)
Try
If Settings.Users.Count > 0 Then
Dim CheckParams As Predicate(Of IUserData) = Function(user) _
(Temporary = CheckState.Indeterminate Or user.Temporary = CBool(Temporary)) And
(Favorite = CheckState.Indeterminate Or (user.Favorite = CBool(Favorite))) And
(Not UseReadyOption Or ReadyForDownloadIgnore Or user.ReadyForDownload = ReadyForDownload)
Dim f As Func(Of IUserData, IEnumerable(Of IUserData)) = Function(ByVal user As IUserData) As IEnumerable(Of IUserData)
If user.IsCollection Then
With DirectCast(user, UserDataBind)
If Count > 0 Then Return .Collections.SelectMany(f)
End With
Else
If Labels.Count = 0 OrElse user.Labels.ListContains(Labels) Then
If CheckParams.Invoke(user) Then Return {user}
End If
End If
Return New IUserData() {}
End Function
Dim u As IEnumerable(Of IUserData) = Settings.Users.SelectMany(f)
If u.ListExists Then
Downloader.AddRange(u)
Else
MsgBoxE({$"No users found for group [{Name}].", "No users found"}, vbExclamation)
End If
End If
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[DownloadGroup.DownloadUsers]")
End Try
End Sub
#End Region
#Region "IEContainerProvider Support"
Public Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
Return New EContainer("Group", Labels.ListToString("|"), {New EAttribute(Name_Name, Name),
New EAttribute(Name_Temporary, CInt(Temporary)),
New EAttribute(Name_Favorite, CInt(Favorite)),
New EAttribute(Name_ReadyForDownload, ReadyForDownload.BoolToInteger),
New EAttribute(Name_ReadyForDownloadIgnore, ReadyForDownloadIgnore.BoolToInteger)})
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
Labels.Clear()
BTT_DELETE.Dispose()
BTT_EDIT.Dispose()
BTT_MENU.Dispose()
SEP_1.Dispose()
BTT_DOWNLOAD.Dispose()
BTT_DOWNLOAD_FULL.Dispose()
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

@@ -0,0 +1,90 @@
' Copyright (C) 2022 Andy
' 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.Functions.XML
Imports PersonalUtilities.Tools
Namespace DownloadObjects.Groups
Friend Class DownloadGroupCollection : Implements IEnumerable(Of DownloadGroup), IMyEnumerator(Of DownloadGroup)
Friend Event Deleted As DownloadGroup.GroupEventHandler
Friend Event Added As DownloadGroup.GroupEventHandler
Friend Event Updated As DownloadGroup.GroupEventHandler
Private ReadOnly GroupsList As List(Of DownloadGroup)
Private ReadOnly GroupFile As SFile = "Settings\Groups.xml"
Friend Sub New()
GroupsList = New List(Of DownloadGroup)
If GroupFile.Exists Then
Using x As New XmlFile(GroupFile,, False) With {.XmlReadOnly = True, .AllowSameNames = True}
x.LoadData()
If x.Count > 0 Then GroupsList.ListAddList(x, LAP.IgnoreICopier)
End Using
If GroupsList.Count > 0 Then GroupsList.ForEach(Sub(ByVal g As DownloadGroup)
AddHandler g.Deleted, AddressOf OnGroupDeleted
AddHandler g.Updated, AddressOf OnGroupUpdated
End Sub)
End If
GroupsList.ListReindex
End Sub
Friend Function GetLabels() As List(Of String)
Return ListAddList(Nothing, GroupsList.SelectMany(Function(g) g.Labels), LAP.NotContainsOnly)
End Function
Default Friend ReadOnly Property Item(ByVal Index As Integer) As DownloadGroup Implements IMyEnumerator(Of DownloadGroup).MyEnumeratorObject
Get
Return GroupsList(Index)
End Get
End Property
Friend ReadOnly Property Count As Integer Implements IMyEnumerator(Of DownloadGroup).MyEnumeratorCount
Get
Return GroupsList.Count
End Get
End Property
Friend Sub Update()
If Count > 0 Then
Using x As New XmlFile With {.Name = "Groups", .AllowSameNames = True}
x.AddRange(GroupsList)
x.Save(GroupFile)
End Using
Else
GroupFile.Delete()
End If
End Sub
Private Sub OnGroupUpdated(ByVal Sender As DownloadGroup)
Update()
RaiseEvent Updated(Sender)
End Sub
Private Sub OnGroupDeleted(ByVal Sender As DownloadGroup)
RaiseEvent Deleted(Sender)
Dim i% = GroupsList.FindIndex(Function(g) g.Key = Sender.Key)
If i >= 0 Then
GroupsList(i).Dispose()
GroupsList.RemoveAt(i)
GroupsList.ListReindex
Update()
End If
End Sub
Friend Sub Add()
Using f As New GroupEditorForm(Nothing)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
GroupsList.Add(f.MyGroup)
GroupsList.ListReindex
RaiseEvent Added(GroupsList.Last)
Update()
End If
End Using
End Sub
Friend Function DownloadGroupIfExists(ByVal Index As Integer) As Boolean
If Index.ValueBetween(0, Count - 1) Then Item(Index).DownloadUsers(True) : Return True Else Return False
End Function
Private Function GetEnumerator() As IEnumerator(Of DownloadGroup) Implements IEnumerable(Of DownloadGroup).GetEnumerator
Return New MyEnumerator(Of DownloadGroup)(Me)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
End Class
End Namespace

View File

@@ -0,0 +1,253 @@
' Copyright (C) 2022 Andy
' 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 DownloadObjects.Groups
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class GroupEditorForm : 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 ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(GroupEditorForm))
Dim ActionButton8 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 TP_TEMP_FAV As System.Windows.Forms.TableLayoutPanel
Dim TP_READY_FOR_DOWN As System.Windows.Forms.TableLayoutPanel
Me.TXT_NAME = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_LABELS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_TEMPORARY = New System.Windows.Forms.CheckBox()
Me.CH_FAV = New System.Windows.Forms.CheckBox()
Me.CH_READY_FOR_DOWN = New System.Windows.Forms.CheckBox()
Me.CH_READY_FOR_DOWN_IGNORE = New System.Windows.Forms.CheckBox()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_TEMP_FAV = New System.Windows.Forms.TableLayoutPanel()
TP_READY_FOR_DOWN = New System.Windows.Forms.TableLayoutPanel()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
TP_MAIN.SuspendLayout()
CType(Me.TXT_NAME, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_LABELS, System.ComponentModel.ISupportInitialize).BeginInit()
TP_TEMP_FAV.SuspendLayout()
TP_READY_FOR_DOWN.SuspendLayout()
Me.SuspendLayout()
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(476, 111)
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(476, 136)
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_READY_FOR_DOWN, 0, 2)
TP_MAIN.Controls.Add(Me.TXT_NAME, 0, 0)
TP_MAIN.Controls.Add(Me.TXT_LABELS, 0, 3)
TP_MAIN.Controls.Add(TP_TEMP_FAV, 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 = 5
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, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.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.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Size = New System.Drawing.Size(476, 111)
TP_MAIN.TabIndex = 0
'
'TXT_NAME
'
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Index = 0
ActionButton7.Name = "BTT_CLEAR"
Me.TXT_NAME.Buttons.Add(ActionButton7)
Me.TXT_NAME.CaptionText = "Name"
Me.TXT_NAME.CaptionToolTipEnabled = True
Me.TXT_NAME.CaptionToolTipText = "Group name"
Me.TXT_NAME.CaptionWidth = 50.0R
Me.TXT_NAME.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_NAME.Location = New System.Drawing.Point(4, 4)
Me.TXT_NAME.Name = "TXT_NAME"
Me.TXT_NAME.Size = New System.Drawing.Size(468, 22)
Me.TXT_NAME.TabIndex = 0
'
'TXT_LABELS
'
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Index = 0
ActionButton8.Name = "BTT_EDIT"
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Index = 1
ActionButton9.Name = "BTT_CLEAR"
Me.TXT_LABELS.Buttons.Add(ActionButton8)
Me.TXT_LABELS.Buttons.Add(ActionButton9)
Me.TXT_LABELS.CaptionText = "Labels"
Me.TXT_LABELS.CaptionToolTipEnabled = True
Me.TXT_LABELS.CaptionToolTipText = "Group labels"
Me.TXT_LABELS.CaptionWidth = 50.0R
Me.TXT_LABELS.ClearTextByButtonClear = False
Me.TXT_LABELS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_LABELS.Location = New System.Drawing.Point(4, 85)
Me.TXT_LABELS.Name = "TXT_LABELS"
Me.TXT_LABELS.Size = New System.Drawing.Size(468, 22)
Me.TXT_LABELS.TabIndex = 1
'
'TP_TEMP_FAV
'
TP_TEMP_FAV.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_TEMP_FAV.ColumnCount = 2
TP_TEMP_FAV.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_TEMP_FAV.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_TEMP_FAV.Controls.Add(Me.CH_TEMPORARY, 0, 0)
TP_TEMP_FAV.Controls.Add(Me.CH_FAV, 1, 0)
TP_TEMP_FAV.Dock = System.Windows.Forms.DockStyle.Fill
TP_TEMP_FAV.Location = New System.Drawing.Point(1, 30)
TP_TEMP_FAV.Margin = New System.Windows.Forms.Padding(0)
TP_TEMP_FAV.Name = "TP_TEMP_FAV"
TP_TEMP_FAV.RowCount = 1
TP_TEMP_FAV.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_TEMP_FAV.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_TEMP_FAV.Size = New System.Drawing.Size(474, 25)
TP_TEMP_FAV.TabIndex = 2
'
'TP_READY_FOR_DOWN
'
TP_READY_FOR_DOWN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_READY_FOR_DOWN.ColumnCount = 2
TP_READY_FOR_DOWN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_READY_FOR_DOWN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_READY_FOR_DOWN.Controls.Add(Me.CH_READY_FOR_DOWN, 0, 0)
TP_READY_FOR_DOWN.Controls.Add(Me.CH_READY_FOR_DOWN_IGNORE, 1, 0)
TP_READY_FOR_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
TP_READY_FOR_DOWN.Location = New System.Drawing.Point(1, 56)
TP_READY_FOR_DOWN.Margin = New System.Windows.Forms.Padding(0)
TP_READY_FOR_DOWN.Name = "TP_READY_FOR_DOWN"
TP_READY_FOR_DOWN.RowCount = 1
TP_READY_FOR_DOWN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_READY_FOR_DOWN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_READY_FOR_DOWN.Size = New System.Drawing.Size(474, 25)
TP_READY_FOR_DOWN.TabIndex = 3
'
'CH_TEMPORARY
'
Me.CH_TEMPORARY.AutoSize = True
Me.CH_TEMPORARY.Checked = True
Me.CH_TEMPORARY.CheckState = System.Windows.Forms.CheckState.Indeterminate
Me.CH_TEMPORARY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_TEMPORARY.Location = New System.Drawing.Point(4, 4)
Me.CH_TEMPORARY.Name = "CH_TEMPORARY"
Me.CH_TEMPORARY.Size = New System.Drawing.Size(229, 17)
Me.CH_TEMPORARY.TabIndex = 0
Me.CH_TEMPORARY.Text = "Temporary"
Me.CH_TEMPORARY.ThreeState = True
Me.CH_TEMPORARY.UseVisualStyleBackColor = True
'
'CH_FAV
'
Me.CH_FAV.AutoSize = True
Me.CH_FAV.Checked = True
Me.CH_FAV.CheckState = System.Windows.Forms.CheckState.Indeterminate
Me.CH_FAV.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FAV.Location = New System.Drawing.Point(240, 4)
Me.CH_FAV.Name = "CH_FAV"
Me.CH_FAV.Size = New System.Drawing.Size(230, 17)
Me.CH_FAV.TabIndex = 1
Me.CH_FAV.Text = "Favorite"
Me.CH_FAV.ThreeState = True
Me.CH_FAV.UseVisualStyleBackColor = True
'
'CH_READY_FOR_DOWN
'
Me.CH_READY_FOR_DOWN.AutoSize = True
Me.CH_READY_FOR_DOWN.Checked = True
Me.CH_READY_FOR_DOWN.CheckState = System.Windows.Forms.CheckState.Checked
Me.CH_READY_FOR_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_READY_FOR_DOWN.Location = New System.Drawing.Point(4, 4)
Me.CH_READY_FOR_DOWN.Name = "CH_READY_FOR_DOWN"
Me.CH_READY_FOR_DOWN.Size = New System.Drawing.Size(229, 17)
Me.CH_READY_FOR_DOWN.TabIndex = 0
Me.CH_READY_FOR_DOWN.Text = "Ready for download"
Me.CH_READY_FOR_DOWN.UseVisualStyleBackColor = True
'
'CH_READY_FOR_DOWN_IGNORE
'
Me.CH_READY_FOR_DOWN_IGNORE.AutoSize = True
Me.CH_READY_FOR_DOWN_IGNORE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_READY_FOR_DOWN_IGNORE.Location = New System.Drawing.Point(240, 4)
Me.CH_READY_FOR_DOWN_IGNORE.Name = "CH_READY_FOR_DOWN_IGNORE"
Me.CH_READY_FOR_DOWN_IGNORE.Size = New System.Drawing.Size(230, 17)
Me.CH_READY_FOR_DOWN_IGNORE.TabIndex = 1
Me.CH_READY_FOR_DOWN_IGNORE.Text = "Ignore ready for download"
Me.CH_READY_FOR_DOWN_IGNORE.UseVisualStyleBackColor = True
'
'GroupEditorForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(476, 136)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(492, 175)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(492, 175)
Me.Name = "GroupEditorForm"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "Group"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
CType(Me.TXT_NAME, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_LABELS, System.ComponentModel.ISupportInitialize).EndInit()
TP_TEMP_FAV.ResumeLayout(False)
TP_TEMP_FAV.PerformLayout()
TP_READY_FOR_DOWN.ResumeLayout(False)
TP_READY_FOR_DOWN.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_NAME As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_LABELS As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_READY_FOR_DOWN As CheckBox
Private WithEvents CH_READY_FOR_DOWN_IGNORE As CheckBox
Private WithEvents CH_TEMPORARY As CheckBox
Private WithEvents CH_FAV As CheckBox
End Class
End Namespace

View File

@@ -0,0 +1,207 @@
<?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>
<metadata name="TP_READY_FOR_DOWN.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="ActionButton7.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="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
DwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKOWlDQ1BQaG90b3Nob3AgSUNDIHByb2Zp
bGUAAEjHnZZ3VFTXFofPvXd6oc0w0hl6ky4wgPQuIB0EURhmBhjKAMMMTWyIqEBEEREBRZCggAGjoUis
iGIhKKhgD0gQUGIwiqioZEbWSnx5ee/l5ffHvd/aZ+9z99l7n7UuACRPHy4vBZYCIJkn4Ad6ONNXhUfQ
sf0ABniAAaYAMFnpqb5B7sFAJC83F3q6yAn8i94MAUj8vmXo6U+ng/9P0qxUvgAAyF/E5mxOOkvE+SJO
yhSkiu0zIqbGJIoZRomZL0pQxHJijlvkpZ99FtlRzOxkHlvE4pxT2clsMfeIeHuGkCNixEfEBRlcTqaI
b4tYM0mYzBXxW3FsMoeZDgCKJLYLOKx4EZuImMQPDnQR8XIAcKS4LzjmCxZwsgTiQ7mkpGbzuXHxArou
S49uam3NoHtyMpM4AoGhP5OVyOSz6S4pyalMXjYAi2f+LBlxbemiIluaWltaGpoZmX5RqP+6+Dcl7u0i
vQr43DOI1veH7a/8UuoAYMyKarPrD1vMfgA6tgIgd/8Pm+YhACRFfWu/8cV5aOJ5iRcIUm2MjTMzM424
HJaRuKC/6386/A198T0j8Xa/l4fuyollCpMEdHHdWClJKUI+PT2VyeLQDf88xP848K/zWBrIieXwOTxR
RKhoyri8OFG7eWyugJvCo3N5/6mJ/zDsT1qca5Eo9Z8ANcoISN2gAuTnPoCiEAESeVDc9d/75oMPBeKb
F6Y6sTj3nwX9+65wifiRzo37HOcSGExnCfkZi2viawnQgAAkARXIAxWgAXSBITADVsAWOAI3sAL4gWAQ
DtYCFogHyYAPMkEu2AwKQBHYBfaCSlAD6kEjaAEnQAc4DS6Ay+A6uAnugAdgBIyD52AGvAHzEARhITJE
geQhVUgLMoDMIAZkD7lBPlAgFA5FQ3EQDxJCudAWqAgqhSqhWqgR+hY6BV2ArkID0D1oFJqCfoXewwhM
gqmwMqwNG8MM2An2hoPhNXAcnAbnwPnwTrgCroOPwe3wBfg6fAcegZ/DswhAiAgNUUMMEQbigvghEUgs
wkc2IIVIOVKHtCBdSC9yCxlBppF3KAyKgqKjDFG2KE9UCIqFSkNtQBWjKlFHUe2oHtQt1ChqBvUJTUYr
oQ3QNmgv9Cp0HDoTXYAuRzeg29CX0HfQ4+g3GAyGhtHBWGE8MeGYBMw6TDHmAKYVcx4zgBnDzGKxWHms
AdYO64dlYgXYAux+7DHsOewgdhz7FkfEqeLMcO64CBwPl4crxzXhzuIGcRO4ebwUXgtvg/fDs/HZ+BJ8
Pb4LfwM/jp8nSBN0CHaEYEICYTOhgtBCuER4SHhFJBLVidbEACKXuIlYQTxOvEIcJb4jyZD0SS6kSJKQ
tJN0hHSedI/0ikwma5MdyRFkAXknuZF8kfyY/FaCImEk4SXBltgoUSXRLjEo8UISL6kl6SS5VjJHslzy
pOQNyWkpvJS2lIsUU2qDVJXUKalhqVlpirSptJ90snSxdJP0VelJGayMtoybDFsmX+awzEWZMQpC0aC4
UFiULZR6yiXKOBVD1aF6UROoRdRvqP3UGVkZ2WWyobJZslWyZ2RHaAhNm+ZFS6KV0E7QhmjvlygvcVrC
WbJjScuSwSVzcopyjnIcuUK5Vrk7cu/l6fJu8onyu+U75B8poBT0FQIUMhUOKlxSmFakKtoqshQLFU8o
3leClfSVApXWKR1W6lOaVVZR9lBOVd6vfFF5WoWm4qiSoFKmclZlSpWiaq/KVS1TPaf6jC5Ld6In0Svo
PfQZNSU1TzWhWq1av9q8uo56iHqeeqv6Iw2CBkMjVqNMo1tjRlNV01czV7NZ874WXouhFa+1T6tXa05b
RztMe5t2h/akjpyOl06OTrPOQ12yroNumm6d7m09jB5DL1HvgN5NfVjfQj9ev0r/hgFsYGnANThgMLAU
vdR6KW9p3dJhQ5Khk2GGYbPhqBHNyMcoz6jD6IWxpnGE8W7jXuNPJhYmSSb1Jg9MZUxXmOaZdpn+aqZv
xjKrMrttTjZ3N99o3mn+cpnBMs6yg8vuWlAsfC22WXRbfLS0suRbtlhOWWlaRVtVWw0zqAx/RjHjijXa
2tl6o/Vp63c2ljYCmxM2v9ga2ibaNtlOLtdZzllev3zMTt2OaVdrN2JPt4+2P2Q/4qDmwHSoc3jiqOHI
dmxwnHDSc0pwOub0wtnEme/c5jznYuOy3uW8K+Lq4Vro2u8m4xbiVun22F3dPc692X3Gw8Jjncd5T7Sn
t+duz2EvZS+WV6PXzAqrFetX9HiTvIO8K72f+Oj78H26fGHfFb57fB+u1FrJW9nhB/y8/Pb4PfLX8U/z
/z4AE+AfUBXwNNA0MDewN4gSFBXUFPQm2Dm4JPhBiG6IMKQ7VDI0MrQxdC7MNaw0bGSV8ar1q66HK4Rz
wzsjsBGhEQ0Rs6vdVu9dPR5pEVkQObRGZ03WmqtrFdYmrT0TJRnFjDoZjY4Oi26K/sD0Y9YxZ2O8Yqpj
ZlgurH2s52xHdhl7imPHKeVMxNrFlsZOxtnF7YmbineIL4+f5rpwK7kvEzwTahLmEv0SjyQuJIUltSbj
kqOTT/FkeIm8nhSVlKyUgVSD1ILUkTSbtL1pM3xvfkM6lL4mvVNAFf1M9Ql1hVuFoxn2GVUZbzNDM09m
SWfxsvqy9bN3ZE/kuOd8vQ61jrWuO1ctd3Pu6Hqn9bUboA0xG7o3amzM3zi+yWPT0c2EzYmbf8gzySvN
e70lbEtXvnL+pvyxrR5bmwskCvgFw9tst9VsR23nbu/fYb5j/45PhezCa0UmReVFH4pZxde+Mv2q4quF
nbE7+0ssSw7uwuzi7Rra7bD7aKl0aU7p2B7fPe1l9LLCstd7o/ZeLV9WXrOPsE+4b6TCp6Jzv+b+Xfs/
VMZX3qlyrmqtVqreUT13gH1g8KDjwZYa5ZqimveHuIfu1nrUttdp15UfxhzOOPy0PrS+92vG140NCg1F
DR+P8I6MHA082tNo1djYpNRU0gw3C5unjkUeu/mN6zedLYYtta201qLj4Ljw+LNvo78dOuF9ovsk42TL
d1rfVbdR2grbofbs9pmO+I6RzvDOgVMrTnV32Xa1fW/0/ZHTaqerzsieKTlLOJt/duFczrnZ86nnpy/E
XRjrjup+cHHVxds9AT39l7wvXbnsfvlir1PvuSt2V05ftbl66hrjWsd1y+vtfRZ9bT9Y/NDWb9nffsPq
RudN65tdA8sHzg46DF645Xrr8m2v29fvrLwzMBQydHc4cnjkLvvu5L2key/vZ9yff7DpIfph4SOpR+WP
lR7X/aj3Y+uI5ciZUdfRvidBTx6Mscae/5T+04fx/Kfkp+UTqhONk2aTp6fcp24+W/1s/Hnq8/npgp+l
f65+ofviu18cf+mbWTUz/pL/cuHX4lfyr468Xva6e9Z/9vGb5Dfzc4Vv5d8efcd41/s+7P3EfOYH7IeK
j3ofuz55f3q4kLyw8Bv3hPP74uYdwgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAahJREFUOE9j+P//P8l4
vaOjPYyNIYkPO1lZsa1wdNy42sHh3Hxb22KQGFaF2LC4qjjroUP7n97s6vx/Ny/3/ypn54+LbGwisSpG
x+aaouwZren/u5f2/3/18tX/qzNn/l/i4XGSgYFBFasGZKwjzcJ6YVnU152blvw3LHH53zCl/ufatWu+
T+1vDALJY9UEwxrijExHZgd+/Xy1Hcg98BNkCMglMM0gjKEJhuX5GVh2TvD+/O5c0///P9b///qo819P
lgmKZhBG0QTDMjwMzJs7XT+9OVHz///XFf+/PWj7j00zCKNwQFiah4FtXbPjp8d78////7bo/4/79Tg1
gzAKR1mUg3lOocXbe9uz/v9/M/H/1zuVeDWDMJwhJcDBvK4p4tb1DQn//r/u+f/zRh5BzSAMZyyrdVh9
c33B9//32159vZr2hxjNIAwm1GUE3e+ur/n9/+Ls/592Nf9fUun3khjNIMzAysTAv6g6+OT/E33/j09N
+zWpMuImsZpBmMHIQK9x19T8/03x1ufE+TkqsCnChxmUlFWuyEpJtAHTtT42BfjxfwYAtlm0ShMkSB4A
AAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton9.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>
<metadata name="TP_TEMP_FAV.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,111 @@
' Copyright (C) 2022 Andy
' 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
Imports PersonalUtilities.Forms.Toolbars
Namespace DownloadObjects.Groups
Friend Class GroupEditorForm : Implements IOkCancelToolbar
Private ReadOnly MyDefs As DefaultFormProps
Friend Property MyGroup As DownloadGroup
Private ReadOnly MyLabels As List(Of String)
Friend Sub New(ByRef g As DownloadGroup)
InitializeComponent()
MyGroup = g
MyLabels = New List(Of String)
If Not MyGroup Is Nothing Then MyLabels.ListAddList(MyGroup.Labels)
MyDefs = New DefaultFormProps
End Sub
Private Class NameChecker : Implements IFieldsCheckerProvider
Private Property ErrorMessage As String Implements IFieldsCheckerProvider.ErrorMessage
Private Property Name As String Implements IFieldsCheckerProvider.Name
Private Property TypeError As Boolean Implements IFieldsCheckerProvider.TypeError
Private ReadOnly ExistingGroupName As String
Friend Sub New(ByVal _ExistingGroupName As String)
ExistingGroupName = _ExistingGroupName
End Sub
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
If Not ACheck(Value) Then
ErrorMessage = "Group name cannot be empty"
ElseIf Not ExistingGroupName.IsEmptyString AndAlso CStr(Value) = ExistingGroupName Then
Return Value
ElseIf Settings.Groups.Count > 0 AndAlso Settings.Groups.LongCount(Function(g) g.Name = CStr(Value)) > 0 Then
ErrorMessage = "A group with the same name already exists"
Else
Return Value
End If
Return Nothing
End Function
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
Throw New NotImplementedException("GetFormat is not available in this context")
End Function
End Class
Private Sub GroupEditorForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize(Me, Settings.Design, True)
.AddOkCancelToolbar()
.DelegateClosingChecker()
If Not MyGroup Is Nothing Then
With MyGroup
TXT_NAME.Text = .Name
CH_TEMPORARY.CheckState = .Temporary
CH_FAV.CheckState = .Favorite
CH_READY_FOR_DOWN.Checked = .ReadyForDownload
CH_READY_FOR_DOWN_IGNORE.Checked = .ReadyForDownloadIgnore
TXT_LABELS.Text = MyLabels.ListToString
Text &= $" { .Name}"
End With
Else
Text = "New Group"
End If
.MyFieldsChecker = New FieldsChecker
DirectCast(.MyFieldsChecker, FieldsChecker).AddControl(Of String)(TXT_NAME, TXT_NAME.CaptionText,, New NameChecker(If(MyGroup?.Name, String.Empty)))
.MyFieldsChecker.EndLoaderOperations()
.AppendDetectors()
.EndLoaderOperations()
End With
End Sub
Private Sub GroupEditorForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyLabels.Clear()
End Sub
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
If MyDefs.MyFieldsChecker.AllParamsOK Then
If MyGroup Is Nothing Then MyGroup = New DownloadGroup
With MyGroup
.Name = TXT_NAME.Text
.Temporary = CH_TEMPORARY.CheckState
.Favorite = CH_FAV.CheckState
.ReadyForDownload = CH_READY_FOR_DOWN.Checked
.ReadyForDownloadIgnore = CH_READY_FOR_DOWN_IGNORE.Checked
.Labels.ListAddList(MyLabels, LAP.ClearBeforeAdd, LAP.NotContainsOnly)
End With
MyDefs.CloseForm()
End If
End Sub
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
MyDefs.CloseForm(DialogResult.Cancel)
End Sub
Private Sub TXT_LABELS_ActionOnButtonClick(ByVal Sender As ActionButton) Handles TXT_LABELS.ActionOnButtonClick
Select Case Sender.DefaultButton
Case ActionButton.DefaultButtons.Edit
Using f As New LabelsForm(MyLabels)
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
MyLabels.ListAddList(f.LabelsList, LAP.NotContainsOnly, LAP.ClearBeforeAdd)
TXT_LABELS.Clear()
TXT_LABELS.Text = MyLabels.ListToString
End If
End Using
Case ActionButton.DefaultButtons.Clear
MyLabels.Clear()
TXT_LABELS.Clear()
End Select
End Sub
End Class
End Namespace

View File

@@ -206,9 +206,10 @@ Namespace DownloadObjects
End Sub End Sub
Private CheckerThread As Thread Private CheckerThread As Thread
Private Sub [Start]() Private Sub [Start]()
If Not MyProgressForm.Opened AndAlso Pool.LongCount(Function(p) p.Count > 0) > 1 Then MyProgressForm.Show() If MyProgressForm.ReadyToOpen AndAlso Pool.LongCount(Function(p) p.Count > 0) > 1 Then MyProgressForm.Show() : MainFrameObj.Focus()
If Not If(CheckerThread?.IsAlive, False) Then If Not If(CheckerThread?.IsAlive, False) Then
MainProgress.Enabled = True MainProgress.Enabled = True
If InfoForm.ReadyToOpen Then InfoForm.Show() : MainFrameObj.Focus()
CheckerThread = New Thread(New ThreadStart(AddressOf JobsChecker)) CheckerThread = New Thread(New ThreadStart(AddressOf JobsChecker))
CheckerThread.SetApartmentState(ApartmentState.MTA) CheckerThread.SetApartmentState(ApartmentState.MTA)
CheckerThread.Start() CheckerThread.Start()
@@ -235,6 +236,7 @@ Namespace DownloadObjects
End With End With
MyProgressForm.DisableProgressChange = True MyProgressForm.DisableProgressChange = True
If Pool.Count > 0 Then Pool.ForEach(Sub(p) If Not p.Progress Is Nothing Then p.Progress.TotalCount = 0) If Pool.Count > 0 Then Pool.ForEach(Sub(p) If Not p.Progress Is Nothing Then p.Progress.TotalCount = 0)
ExecuteCommand(Settings.DownloadsCompleteCommand)
End Try End Try
End Sub End Sub
Private Sub StartDownloading(ByRef _Job As Job) Private Sub StartDownloading(ByRef _Job As Job)
@@ -254,9 +256,7 @@ Namespace DownloadObjects
Dim SiteChecked As Boolean = False Dim SiteChecked As Boolean = False
Do While _Job.Count > 0 Do While _Job.Count > 0
_Job.ThrowIfCancellationRequested() _Job.ThrowIfCancellationRequested()
If Not SiteChecked Then If Not SiteChecked Then _Job.Available() : SiteChecked = True : Continue Do
If Not _Job.Available Then Exit Sub Else SiteChecked = True : Continue Do
End If
UpdateJobsLabel() UpdateJobsLabel()
DownloadData(_Job, _Job.Token) DownloadData(_Job, _Job.Token)
_Job.ThrowIfCancellationRequested() _Job.ThrowIfCancellationRequested()

View File

@@ -63,7 +63,7 @@ Namespace DownloadObjects
End Sub End Sub
Private Sub UpdateUrlsFile() Private Sub UpdateUrlsFile()
If UrlList.Count > 0 Then If UrlList.Count > 0 Then
TextSaver.SaveTextToFile(UrlList.ListToString(, Environment.NewLine), DownloadingUrlsFile, True,, EDP.SendInLog) TextSaver.SaveTextToFile(UrlList.ListToString(Environment.NewLine), DownloadingUrlsFile, True,, EDP.SendInLog)
Else Else
DownloadingUrlsFile.Delete(, Settings.DeleteMode, EDP.SendInLog) DownloadingUrlsFile.Delete(, Settings.DeleteMode, EDP.SendInLog)
End If End If
@@ -129,7 +129,7 @@ Namespace DownloadObjects
With Settings.LatestSavingPath With Settings.LatestSavingPath
If Not .Value.IsEmptyString Then If Not .Value.IsEmptyString Then
If .Value.Exists(SFO.Path, False) Then If .Value.Exists(SFO.Path, False) Then
.Value.Open(SFO.Path, EDP.ShowMainMsg) GlobalOpenPath(.Value, EDP.ShowMainMsg)
Else Else
MsgBoxE($"Path [{ .Value}] does not exists!", MsgBoxStyle.Exclamation) MsgBoxE($"Path [{ .Value}] does not exists!", MsgBoxStyle.Exclamation)
End If End If

View File

@@ -27,7 +27,6 @@
Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel
Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel
Dim LBL_DATE_POS As System.Windows.Forms.Label Dim LBL_DATE_POS As System.Windows.Forms.Label
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TT_MAIN As System.Windows.Forms.ToolTip Dim TT_MAIN As System.Windows.Forms.ToolTip
Dim TP_CHANNELS_IMGS As System.Windows.Forms.TableLayoutPanel Dim TP_CHANNELS_IMGS As System.Windows.Forms.TableLayoutPanel
Dim TAB_BASIS As System.Windows.Forms.TabPage Dim TAB_BASIS As System.Windows.Forms.TabPage
@@ -35,6 +34,15 @@
Dim TP_DEFS As System.Windows.Forms.TableLayoutPanel Dim TP_DEFS As System.Windows.Forms.TableLayoutPanel
Dim TAB_DEFS_CHANNELS As System.Windows.Forms.TabPage Dim TAB_DEFS_CHANNELS As System.Windows.Forms.TabPage
Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel 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 ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TAB_DOWN As System.Windows.Forms.TabPage
Dim TP_DOWNLOADING As System.Windows.Forms.TableLayoutPanel
Dim ActionButton8 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 TP_OPEN_INFO As System.Windows.Forms.TableLayoutPanel
Dim TP_OPEN_PROGRESS As System.Windows.Forms.TableLayoutPanel
Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
@@ -43,6 +51,8 @@
Me.TXT_MAX_JOBS_CHANNELS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_MAX_JOBS_CHANNELS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_CHECK_VER_START = New System.Windows.Forms.CheckBox() Me.CH_CHECK_VER_START = New System.Windows.Forms.CheckBox()
Me.TXT_IMGUR_CLIENT_ID = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_IMGUR_CLIENT_ID = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_SHOW_GROUPS = New System.Windows.Forms.CheckBox()
Me.CH_USERS_GROUPING = New System.Windows.Forms.CheckBox()
Me.OPT_FILE_NAME_REPLACE = New System.Windows.Forms.RadioButton() Me.OPT_FILE_NAME_REPLACE = New System.Windows.Forms.RadioButton()
Me.OPT_FILE_NAME_ADD_DATE = New System.Windows.Forms.RadioButton() Me.OPT_FILE_NAME_ADD_DATE = New System.Windows.Forms.RadioButton()
Me.CH_FILE_NAME_CHANGE = New System.Windows.Forms.CheckBox() Me.CH_FILE_NAME_CHANGE = New System.Windows.Forms.CheckBox()
@@ -50,12 +60,7 @@
Me.CH_FILE_TIME = New System.Windows.Forms.CheckBox() Me.CH_FILE_TIME = New System.Windows.Forms.CheckBox()
Me.OPT_FILE_DATE_START = New System.Windows.Forms.RadioButton() Me.OPT_FILE_DATE_START = New System.Windows.Forms.RadioButton()
Me.OPT_FILE_DATE_END = New System.Windows.Forms.RadioButton() Me.OPT_FILE_DATE_END = New System.Windows.Forms.RadioButton()
Me.CH_EXIT_CONFIRM = New System.Windows.Forms.CheckBox()
Me.CH_CLOSE_TO_TRAY = New System.Windows.Forms.CheckBox()
Me.CH_SHOW_NOTIFY = New System.Windows.Forms.CheckBox()
Me.CH_FAST_LOAD = New System.Windows.Forms.CheckBox() Me.CH_FAST_LOAD = New System.Windows.Forms.CheckBox()
Me.TXT_FOLDER_CMD = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_RECYCLE_DEL = New System.Windows.Forms.CheckBox()
Me.CH_COPY_CHANNEL_USER_IMAGE = New System.Windows.Forms.CheckBox() Me.CH_COPY_CHANNEL_USER_IMAGE = New System.Windows.Forms.CheckBox()
Me.CH_DEF_TEMP = New System.Windows.Forms.CheckBox() Me.CH_DEF_TEMP = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_IMAGES = New System.Windows.Forms.CheckBox() Me.CH_DOWN_IMAGES = New System.Windows.Forms.CheckBox()
@@ -67,8 +72,20 @@
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_CHANNEL_USER_POST_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended() Me.TXT_CHANNEL_USER_POST_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_FOLDER_CMD = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_EXIT_CONFIRM = New System.Windows.Forms.CheckBox()
Me.CH_CLOSE_TO_TRAY = New System.Windows.Forms.CheckBox()
Me.CH_SHOW_NOTIFY = New System.Windows.Forms.CheckBox()
Me.CH_RECYCLE_DEL = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_OPEN_INFO = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_OPEN_PROGRESS = New System.Windows.Forms.CheckBox()
Me.TXT_CLOSE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TAB_MAIN = New System.Windows.Forms.TabControl() Me.TAB_MAIN = New System.Windows.Forms.TabControl()
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer() Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
Me.CH_DOWN_OPEN_INFO_SUSPEND = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND = New System.Windows.Forms.CheckBox()
TP_BASIS = New System.Windows.Forms.TableLayoutPanel() TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel() TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel() TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
@@ -81,6 +98,12 @@
TP_DEFS = New System.Windows.Forms.TableLayoutPanel() TP_DEFS = New System.Windows.Forms.TableLayoutPanel()
TAB_DEFS_CHANNELS = New System.Windows.Forms.TabPage() TAB_DEFS_CHANNELS = New System.Windows.Forms.TabPage()
TP_CHANNELS = New System.Windows.Forms.TableLayoutPanel() TP_CHANNELS = New System.Windows.Forms.TableLayoutPanel()
TAB_BEHAVIOR = New System.Windows.Forms.TabPage()
TP_BEHAVIOR = New System.Windows.Forms.TableLayoutPanel()
TAB_DOWN = New System.Windows.Forms.TabPage()
TP_DOWNLOADING = New System.Windows.Forms.TableLayoutPanel()
TP_OPEN_INFO = New System.Windows.Forms.TableLayoutPanel()
TP_OPEN_PROGRESS = New System.Windows.Forms.TableLayoutPanel()
TP_BASIS.SuspendLayout() TP_BASIS.SuspendLayout()
CType(Me.TXT_GLOBAL_PATH, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_GLOBAL_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
TP_IMAGES.SuspendLayout() TP_IMAGES.SuspendLayout()
@@ -92,7 +115,6 @@
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit()
TP_FILE_NAME.SuspendLayout() TP_FILE_NAME.SuspendLayout()
TP_FILE_PATTERNS.SuspendLayout() TP_FILE_PATTERNS.SuspendLayout()
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).BeginInit()
TP_CHANNELS_IMGS.SuspendLayout() TP_CHANNELS_IMGS.SuspendLayout()
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit()
@@ -102,9 +124,19 @@
TAB_DEFS_CHANNELS.SuspendLayout() TAB_DEFS_CHANNELS.SuspendLayout()
TP_CHANNELS.SuspendLayout() TP_CHANNELS.SuspendLayout()
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit()
TAB_BEHAVIOR.SuspendLayout()
TP_BEHAVIOR.SuspendLayout()
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_CLOSE_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit()
TAB_DOWN.SuspendLayout()
TP_DOWNLOADING.SuspendLayout()
CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_DOWN_COMPLETE_SCRIPT, System.ComponentModel.ISupportInitialize).BeginInit()
Me.TAB_MAIN.SuspendLayout() Me.TAB_MAIN.SuspendLayout()
Me.CONTAINER_MAIN.ContentPanel.SuspendLayout() Me.CONTAINER_MAIN.ContentPanel.SuspendLayout()
Me.CONTAINER_MAIN.SuspendLayout() Me.CONTAINER_MAIN.SuspendLayout()
TP_OPEN_INFO.SuspendLayout()
TP_OPEN_PROGRESS.SuspendLayout()
Me.SuspendLayout() Me.SuspendLayout()
' '
'TP_BASIS 'TP_BASIS
@@ -119,18 +151,12 @@
TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_CHANNELS, 0, 4) TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_CHANNELS, 0, 4)
TP_BASIS.Controls.Add(Me.CH_CHECK_VER_START, 0, 5) TP_BASIS.Controls.Add(Me.CH_CHECK_VER_START, 0, 5)
TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 6) TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 6)
TP_BASIS.Controls.Add(TP_FILE_NAME, 0, 7) TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 7)
TP_BASIS.Controls.Add(TP_FILE_PATTERNS, 0, 8) TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 8)
TP_BASIS.Controls.Add(Me.CH_EXIT_CONFIRM, 0, 9)
TP_BASIS.Controls.Add(Me.CH_CLOSE_TO_TRAY, 0, 10)
TP_BASIS.Controls.Add(Me.CH_SHOW_NOTIFY, 0, 11)
TP_BASIS.Controls.Add(Me.CH_FAST_LOAD, 0, 12)
TP_BASIS.Controls.Add(Me.TXT_FOLDER_CMD, 0, 13)
TP_BASIS.Controls.Add(Me.CH_RECYCLE_DEL, 0, 14)
TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill
TP_BASIS.Location = New System.Drawing.Point(3, 3) TP_BASIS.Location = New System.Drawing.Point(3, 3)
TP_BASIS.Name = "TP_BASIS" TP_BASIS.Name = "TP_BASIS"
TP_BASIS.RowCount = 16 TP_BASIS.RowCount = 10
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
@@ -138,16 +164,10 @@
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BASIS.Size = New System.Drawing.Size(570, 447) TP_BASIS.Size = New System.Drawing.Size(570, 253)
TP_BASIS.TabIndex = 0 TP_BASIS.TabIndex = 0
' '
'TXT_GLOBAL_PATH 'TXT_GLOBAL_PATH
@@ -297,6 +317,30 @@
Me.TXT_IMGUR_CLIENT_ID.Size = New System.Drawing.Size(562, 22) Me.TXT_IMGUR_CLIENT_ID.Size = New System.Drawing.Size(562, 22)
Me.TXT_IMGUR_CLIENT_ID.TabIndex = 6 Me.TXT_IMGUR_CLIENT_ID.TabIndex = 6
' '
'CH_SHOW_GROUPS
'
Me.CH_SHOW_GROUPS.AutoSize = True
Me.CH_SHOW_GROUPS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_SHOW_GROUPS.Location = New System.Drawing.Point(4, 204)
Me.CH_SHOW_GROUPS.Name = "CH_SHOW_GROUPS"
Me.CH_SHOW_GROUPS.Size = New System.Drawing.Size(562, 19)
Me.CH_SHOW_GROUPS.TabIndex = 7
Me.CH_SHOW_GROUPS.Text = "Show groups"
TT_MAIN.SetToolTip(Me.CH_SHOW_GROUPS, "Grouping users by site")
Me.CH_SHOW_GROUPS.UseVisualStyleBackColor = True
'
'CH_USERS_GROUPING
'
Me.CH_USERS_GROUPING.AutoSize = True
Me.CH_USERS_GROUPING.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_USERS_GROUPING.Location = New System.Drawing.Point(4, 230)
Me.CH_USERS_GROUPING.Name = "CH_USERS_GROUPING"
Me.CH_USERS_GROUPING.Size = New System.Drawing.Size(562, 19)
Me.CH_USERS_GROUPING.TabIndex = 8
Me.CH_USERS_GROUPING.Text = "Use user grouping"
TT_MAIN.SetToolTip(Me.CH_USERS_GROUPING, "Group users by groups and/or labels")
Me.CH_USERS_GROUPING.UseVisualStyleBackColor = True
'
'TP_FILE_NAME 'TP_FILE_NAME
' '
TP_FILE_NAME.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single] TP_FILE_NAME.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
@@ -308,21 +352,21 @@
TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0) TP_FILE_NAME.Controls.Add(Me.OPT_FILE_NAME_ADD_DATE, 2, 0)
TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0) TP_FILE_NAME.Controls.Add(Me.CH_FILE_NAME_CHANGE, 0, 0)
TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill TP_FILE_NAME.Dock = System.Windows.Forms.DockStyle.Fill
TP_FILE_NAME.Location = New System.Drawing.Point(1, 201) TP_FILE_NAME.Location = New System.Drawing.Point(1, 27)
TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0) TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0)
TP_FILE_NAME.Name = "TP_FILE_NAME" TP_FILE_NAME.Name = "TP_FILE_NAME"
TP_FILE_NAME.RowCount = 1 TP_FILE_NAME.RowCount = 1
TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_NAME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FILE_NAME.Size = New System.Drawing.Size(568, 30) TP_FILE_NAME.Size = New System.Drawing.Size(574, 30)
TP_FILE_NAME.TabIndex = 7 TP_FILE_NAME.TabIndex = 1
' '
'OPT_FILE_NAME_REPLACE 'OPT_FILE_NAME_REPLACE
' '
Me.OPT_FILE_NAME_REPLACE.AutoSize = True Me.OPT_FILE_NAME_REPLACE.AutoSize = True
Me.OPT_FILE_NAME_REPLACE.Dock = System.Windows.Forms.DockStyle.Fill Me.OPT_FILE_NAME_REPLACE.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_FILE_NAME_REPLACE.Location = New System.Drawing.Point(193, 4) Me.OPT_FILE_NAME_REPLACE.Location = New System.Drawing.Point(195, 4)
Me.OPT_FILE_NAME_REPLACE.Name = "OPT_FILE_NAME_REPLACE" Me.OPT_FILE_NAME_REPLACE.Name = "OPT_FILE_NAME_REPLACE"
Me.OPT_FILE_NAME_REPLACE.Size = New System.Drawing.Size(182, 22) Me.OPT_FILE_NAME_REPLACE.Size = New System.Drawing.Size(184, 22)
Me.OPT_FILE_NAME_REPLACE.TabIndex = 1 Me.OPT_FILE_NAME_REPLACE.TabIndex = 1
Me.OPT_FILE_NAME_REPLACE.TabStop = True Me.OPT_FILE_NAME_REPLACE.TabStop = True
Me.OPT_FILE_NAME_REPLACE.Text = "Replace file name by date" Me.OPT_FILE_NAME_REPLACE.Text = "Replace file name by date"
@@ -332,9 +376,9 @@
' '
Me.OPT_FILE_NAME_ADD_DATE.AutoSize = True Me.OPT_FILE_NAME_ADD_DATE.AutoSize = True
Me.OPT_FILE_NAME_ADD_DATE.Dock = System.Windows.Forms.DockStyle.Fill Me.OPT_FILE_NAME_ADD_DATE.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_FILE_NAME_ADD_DATE.Location = New System.Drawing.Point(382, 4) Me.OPT_FILE_NAME_ADD_DATE.Location = New System.Drawing.Point(386, 4)
Me.OPT_FILE_NAME_ADD_DATE.Name = "OPT_FILE_NAME_ADD_DATE" Me.OPT_FILE_NAME_ADD_DATE.Name = "OPT_FILE_NAME_ADD_DATE"
Me.OPT_FILE_NAME_ADD_DATE.Size = New System.Drawing.Size(182, 22) Me.OPT_FILE_NAME_ADD_DATE.Size = New System.Drawing.Size(184, 22)
Me.OPT_FILE_NAME_ADD_DATE.TabIndex = 2 Me.OPT_FILE_NAME_ADD_DATE.TabIndex = 2
Me.OPT_FILE_NAME_ADD_DATE.TabStop = True Me.OPT_FILE_NAME_ADD_DATE.TabStop = True
Me.OPT_FILE_NAME_ADD_DATE.Text = "Add date/time to file name" Me.OPT_FILE_NAME_ADD_DATE.Text = "Add date/time to file name"
@@ -346,7 +390,7 @@
Me.CH_FILE_NAME_CHANGE.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_FILE_NAME_CHANGE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FILE_NAME_CHANGE.Location = New System.Drawing.Point(4, 4) Me.CH_FILE_NAME_CHANGE.Location = New System.Drawing.Point(4, 4)
Me.CH_FILE_NAME_CHANGE.Name = "CH_FILE_NAME_CHANGE" Me.CH_FILE_NAME_CHANGE.Name = "CH_FILE_NAME_CHANGE"
Me.CH_FILE_NAME_CHANGE.Size = New System.Drawing.Size(182, 22) Me.CH_FILE_NAME_CHANGE.Size = New System.Drawing.Size(184, 22)
Me.CH_FILE_NAME_CHANGE.TabIndex = 0 Me.CH_FILE_NAME_CHANGE.TabIndex = 0
Me.CH_FILE_NAME_CHANGE.Text = "Change file names" Me.CH_FILE_NAME_CHANGE.Text = "Change file names"
Me.CH_FILE_NAME_CHANGE.UseVisualStyleBackColor = True Me.CH_FILE_NAME_CHANGE.UseVisualStyleBackColor = True
@@ -366,14 +410,14 @@
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0) TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_START, 3, 0)
TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0) TP_FILE_PATTERNS.Controls.Add(Me.OPT_FILE_DATE_END, 4, 0)
TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill TP_FILE_PATTERNS.Dock = System.Windows.Forms.DockStyle.Fill
TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 232) TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 58)
TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0) TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0)
TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS" TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS"
TP_FILE_PATTERNS.RowCount = 1 TP_FILE_PATTERNS.RowCount = 1
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!)) TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!)) TP_FILE_PATTERNS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29.0!))
TP_FILE_PATTERNS.Size = New System.Drawing.Size(568, 30) TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30)
TP_FILE_PATTERNS.TabIndex = 8 TP_FILE_PATTERNS.TabIndex = 2
' '
'CH_FILE_DATE 'CH_FILE_DATE
' '
@@ -381,7 +425,7 @@
Me.CH_FILE_DATE.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_FILE_DATE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FILE_DATE.Location = New System.Drawing.Point(4, 4) Me.CH_FILE_DATE.Location = New System.Drawing.Point(4, 4)
Me.CH_FILE_DATE.Name = "CH_FILE_DATE" Me.CH_FILE_DATE.Name = "CH_FILE_DATE"
Me.CH_FILE_DATE.Size = New System.Drawing.Size(106, 22) Me.CH_FILE_DATE.Size = New System.Drawing.Size(107, 22)
Me.CH_FILE_DATE.TabIndex = 0 Me.CH_FILE_DATE.TabIndex = 0
Me.CH_FILE_DATE.Text = "Date" Me.CH_FILE_DATE.Text = "Date"
Me.CH_FILE_DATE.UseVisualStyleBackColor = True Me.CH_FILE_DATE.UseVisualStyleBackColor = True
@@ -390,9 +434,9 @@
' '
Me.CH_FILE_TIME.AutoSize = True Me.CH_FILE_TIME.AutoSize = True
Me.CH_FILE_TIME.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_FILE_TIME.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FILE_TIME.Location = New System.Drawing.Point(117, 4) Me.CH_FILE_TIME.Location = New System.Drawing.Point(118, 4)
Me.CH_FILE_TIME.Name = "CH_FILE_TIME" Me.CH_FILE_TIME.Name = "CH_FILE_TIME"
Me.CH_FILE_TIME.Size = New System.Drawing.Size(106, 22) Me.CH_FILE_TIME.Size = New System.Drawing.Size(107, 22)
Me.CH_FILE_TIME.TabIndex = 1 Me.CH_FILE_TIME.TabIndex = 1
Me.CH_FILE_TIME.Text = "Time" Me.CH_FILE_TIME.Text = "Time"
Me.CH_FILE_TIME.UseVisualStyleBackColor = True Me.CH_FILE_TIME.UseVisualStyleBackColor = True
@@ -401,9 +445,9 @@
' '
LBL_DATE_POS.AutoSize = True LBL_DATE_POS.AutoSize = True
LBL_DATE_POS.Dock = System.Windows.Forms.DockStyle.Fill LBL_DATE_POS.Dock = System.Windows.Forms.DockStyle.Fill
LBL_DATE_POS.Location = New System.Drawing.Point(230, 1) LBL_DATE_POS.Location = New System.Drawing.Point(232, 1)
LBL_DATE_POS.Name = "LBL_DATE_POS" LBL_DATE_POS.Name = "LBL_DATE_POS"
LBL_DATE_POS.Size = New System.Drawing.Size(106, 28) LBL_DATE_POS.Size = New System.Drawing.Size(107, 28)
LBL_DATE_POS.TabIndex = 2 LBL_DATE_POS.TabIndex = 2
LBL_DATE_POS.Text = "Date position:" LBL_DATE_POS.Text = "Date position:"
LBL_DATE_POS.TextAlign = System.Drawing.ContentAlignment.MiddleRight LBL_DATE_POS.TextAlign = System.Drawing.ContentAlignment.MiddleRight
@@ -412,9 +456,9 @@
' '
Me.OPT_FILE_DATE_START.AutoSize = True Me.OPT_FILE_DATE_START.AutoSize = True
Me.OPT_FILE_DATE_START.Dock = System.Windows.Forms.DockStyle.Fill Me.OPT_FILE_DATE_START.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_FILE_DATE_START.Location = New System.Drawing.Point(343, 4) Me.OPT_FILE_DATE_START.Location = New System.Drawing.Point(346, 4)
Me.OPT_FILE_DATE_START.Name = "OPT_FILE_DATE_START" Me.OPT_FILE_DATE_START.Name = "OPT_FILE_DATE_START"
Me.OPT_FILE_DATE_START.Size = New System.Drawing.Size(106, 22) Me.OPT_FILE_DATE_START.Size = New System.Drawing.Size(107, 22)
Me.OPT_FILE_DATE_START.TabIndex = 3 Me.OPT_FILE_DATE_START.TabIndex = 3
Me.OPT_FILE_DATE_START.TabStop = True Me.OPT_FILE_DATE_START.TabStop = True
Me.OPT_FILE_DATE_START.Text = "Start" Me.OPT_FILE_DATE_START.Text = "Start"
@@ -424,92 +468,26 @@
' '
Me.OPT_FILE_DATE_END.AutoSize = True Me.OPT_FILE_DATE_END.AutoSize = True
Me.OPT_FILE_DATE_END.Dock = System.Windows.Forms.DockStyle.Fill Me.OPT_FILE_DATE_END.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_FILE_DATE_END.Location = New System.Drawing.Point(456, 4) Me.OPT_FILE_DATE_END.Location = New System.Drawing.Point(460, 4)
Me.OPT_FILE_DATE_END.Name = "OPT_FILE_DATE_END" Me.OPT_FILE_DATE_END.Name = "OPT_FILE_DATE_END"
Me.OPT_FILE_DATE_END.Size = New System.Drawing.Size(108, 22) Me.OPT_FILE_DATE_END.Size = New System.Drawing.Size(110, 22)
Me.OPT_FILE_DATE_END.TabIndex = 4 Me.OPT_FILE_DATE_END.TabIndex = 4
Me.OPT_FILE_DATE_END.TabStop = True Me.OPT_FILE_DATE_END.TabStop = True
Me.OPT_FILE_DATE_END.Text = "End" Me.OPT_FILE_DATE_END.Text = "End"
Me.OPT_FILE_DATE_END.UseVisualStyleBackColor = True Me.OPT_FILE_DATE_END.UseVisualStyleBackColor = True
' '
'CH_EXIT_CONFIRM
'
Me.CH_EXIT_CONFIRM.AutoSize = True
Me.CH_EXIT_CONFIRM.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_EXIT_CONFIRM.Location = New System.Drawing.Point(4, 266)
Me.CH_EXIT_CONFIRM.Name = "CH_EXIT_CONFIRM"
Me.CH_EXIT_CONFIRM.Size = New System.Drawing.Size(562, 19)
Me.CH_EXIT_CONFIRM.TabIndex = 9
Me.CH_EXIT_CONFIRM.Text = "Exit confirm"
Me.CH_EXIT_CONFIRM.UseVisualStyleBackColor = True
'
'CH_CLOSE_TO_TRAY
'
Me.CH_CLOSE_TO_TRAY.AutoSize = True
Me.CH_CLOSE_TO_TRAY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_CLOSE_TO_TRAY.Location = New System.Drawing.Point(4, 292)
Me.CH_CLOSE_TO_TRAY.Name = "CH_CLOSE_TO_TRAY"
Me.CH_CLOSE_TO_TRAY.Size = New System.Drawing.Size(562, 19)
Me.CH_CLOSE_TO_TRAY.TabIndex = 10
Me.CH_CLOSE_TO_TRAY.Text = "Close to tray"
Me.CH_CLOSE_TO_TRAY.UseVisualStyleBackColor = True
'
'CH_SHOW_NOTIFY
'
Me.CH_SHOW_NOTIFY.AutoSize = True
Me.CH_SHOW_NOTIFY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_SHOW_NOTIFY.Location = New System.Drawing.Point(4, 318)
Me.CH_SHOW_NOTIFY.Name = "CH_SHOW_NOTIFY"
Me.CH_SHOW_NOTIFY.Size = New System.Drawing.Size(562, 19)
Me.CH_SHOW_NOTIFY.TabIndex = 11
Me.CH_SHOW_NOTIFY.Text = "Show notifications"
Me.CH_SHOW_NOTIFY.UseVisualStyleBackColor = True
'
'CH_FAST_LOAD 'CH_FAST_LOAD
' '
Me.CH_FAST_LOAD.AutoSize = True Me.CH_FAST_LOAD.AutoSize = True
Me.CH_FAST_LOAD.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_FAST_LOAD.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_FAST_LOAD.Location = New System.Drawing.Point(4, 344) Me.CH_FAST_LOAD.Location = New System.Drawing.Point(4, 82)
Me.CH_FAST_LOAD.Name = "CH_FAST_LOAD" Me.CH_FAST_LOAD.Name = "CH_FAST_LOAD"
Me.CH_FAST_LOAD.Size = New System.Drawing.Size(562, 19) Me.CH_FAST_LOAD.Size = New System.Drawing.Size(568, 19)
Me.CH_FAST_LOAD.TabIndex = 12 Me.CH_FAST_LOAD.TabIndex = 3
Me.CH_FAST_LOAD.Text = "Fast profiles loading" Me.CH_FAST_LOAD.Text = "Fast profiles loading"
TT_MAIN.SetToolTip(Me.CH_FAST_LOAD, "Fast loading of profiles in the main window") TT_MAIN.SetToolTip(Me.CH_FAST_LOAD, "Fast loading of profiles in the main window")
Me.CH_FAST_LOAD.UseVisualStyleBackColor = True Me.CH_FAST_LOAD.UseVisualStyleBackColor = True
' '
'TXT_FOLDER_CMD
'
Me.TXT_FOLDER_CMD.AutoShowClearButton = True
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Enabled = False
ActionButton7.Index = 0
ActionButton7.Name = "BTT_CLEAR"
ActionButton7.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton7)
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
Me.TXT_FOLDER_CMD.CaptionToolTipText = "The command to open a folder."
Me.TXT_FOLDER_CMD.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FOLDER_CMD.LeaveDefaultButtons = True
Me.TXT_FOLDER_CMD.Location = New System.Drawing.Point(4, 370)
Me.TXT_FOLDER_CMD.Name = "TXT_FOLDER_CMD"
Me.TXT_FOLDER_CMD.PlaceholderEnabled = True
Me.TXT_FOLDER_CMD.PlaceholderText = "MyCommand /arg {0}"
Me.TXT_FOLDER_CMD.Size = New System.Drawing.Size(562, 22)
Me.TXT_FOLDER_CMD.TabIndex = 13
'
'CH_RECYCLE_DEL
'
Me.CH_RECYCLE_DEL.AutoSize = True
Me.CH_RECYCLE_DEL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_RECYCLE_DEL.Location = New System.Drawing.Point(4, 399)
Me.CH_RECYCLE_DEL.Name = "CH_RECYCLE_DEL"
Me.CH_RECYCLE_DEL.Size = New System.Drawing.Size(562, 19)
Me.CH_RECYCLE_DEL.TabIndex = 14
Me.CH_RECYCLE_DEL.Text = "Delete data to recycle bin"
Me.CH_RECYCLE_DEL.UseVisualStyleBackColor = True
'
'CH_COPY_CHANNEL_USER_IMAGE 'CH_COPY_CHANNEL_USER_IMAGE
' '
Me.CH_COPY_CHANNEL_USER_IMAGE.AutoSize = True Me.CH_COPY_CHANNEL_USER_IMAGE.AutoSize = True
@@ -599,10 +577,10 @@
' '
Me.CH_UDESCR_UP.AutoSize = True Me.CH_UDESCR_UP.AutoSize = True
Me.CH_UDESCR_UP.Dock = System.Windows.Forms.DockStyle.Fill Me.CH_UDESCR_UP.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_UDESCR_UP.Location = New System.Drawing.Point(4, 108) Me.CH_UDESCR_UP.Location = New System.Drawing.Point(4, 4)
Me.CH_UDESCR_UP.Name = "CH_UDESCR_UP" Me.CH_UDESCR_UP.Name = "CH_UDESCR_UP"
Me.CH_UDESCR_UP.Size = New System.Drawing.Size(562, 19) Me.CH_UDESCR_UP.Size = New System.Drawing.Size(568, 19)
Me.CH_UDESCR_UP.TabIndex = 4 Me.CH_UDESCR_UP.TabIndex = 0
Me.CH_UDESCR_UP.Text = "Update user description every time" Me.CH_UDESCR_UP.Text = "Update user description every time"
TT_MAIN.SetToolTip(Me.CH_UDESCR_UP, "If the user description does not contain a new user description, then the new one" & TT_MAIN.SetToolTip(Me.CH_UDESCR_UP, "If the user description does not contain a new user description, then the new one" &
" will be added via a new line") " will be added via a new line")
@@ -659,7 +637,7 @@
TAB_BASIS.Location = New System.Drawing.Point(4, 22) TAB_BASIS.Location = New System.Drawing.Point(4, 22)
TAB_BASIS.Name = "TAB_BASIS" TAB_BASIS.Name = "TAB_BASIS"
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3) TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
TAB_BASIS.Size = New System.Drawing.Size(576, 453) TAB_BASIS.Size = New System.Drawing.Size(576, 259)
TAB_BASIS.TabIndex = 0 TAB_BASIS.TabIndex = 0
TAB_BASIS.Text = "Basis" TAB_BASIS.Text = "Basis"
' '
@@ -669,7 +647,7 @@
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22) TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
TAB_DEFAULTS.Name = "TAB_DEFAULTS" TAB_DEFAULTS.Name = "TAB_DEFAULTS"
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3) TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 453) TAB_DEFAULTS.Size = New System.Drawing.Size(576, 284)
TAB_DEFAULTS.TabIndex = 1 TAB_DEFAULTS.TabIndex = 1
TAB_DEFAULTS.Text = "Defaults" TAB_DEFAULTS.Text = "Defaults"
' '
@@ -682,18 +660,17 @@
TP_DEFS.Controls.Add(Me.CH_DOWN_VIDEOS, 0, 3) TP_DEFS.Controls.Add(Me.CH_DOWN_VIDEOS, 0, 3)
TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES, 0, 2) TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES, 0, 2)
TP_DEFS.Controls.Add(Me.CH_DEF_TEMP, 0, 1) TP_DEFS.Controls.Add(Me.CH_DEF_TEMP, 0, 1)
TP_DEFS.Controls.Add(Me.CH_UDESCR_UP, 0, 4)
TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill
TP_DEFS.Location = New System.Drawing.Point(3, 3) TP_DEFS.Location = New System.Drawing.Point(3, 3)
TP_DEFS.Name = "TP_DEFS" TP_DEFS.Name = "TP_DEFS"
TP_DEFS.RowCount = 6 TP_DEFS.RowCount = 5
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.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.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.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.Absolute, 25.0!))
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.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, 447) TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_DEFS.Size = New System.Drawing.Size(570, 278)
TP_DEFS.TabIndex = 0 TP_DEFS.TabIndex = 0
' '
'TAB_DEFS_CHANNELS 'TAB_DEFS_CHANNELS
@@ -702,7 +679,7 @@
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22) TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS" TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3) TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 453) TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 284)
TAB_DEFS_CHANNELS.TabIndex = 4 TAB_DEFS_CHANNELS.TabIndex = 4
TAB_DEFS_CHANNELS.Text = "Channels" TAB_DEFS_CHANNELS.Text = "Channels"
' '
@@ -726,7 +703,7 @@
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.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.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_CHANNELS.Size = New System.Drawing.Size(570, 447) TP_CHANNELS.Size = New System.Drawing.Size(570, 278)
TP_CHANNELS.TabIndex = 0 TP_CHANNELS.TabIndex = 0
' '
'TXT_CHANNEL_USER_POST_LIMIT 'TXT_CHANNEL_USER_POST_LIMIT
@@ -749,16 +726,232 @@
Me.TXT_CHANNEL_USER_POST_LIMIT.Text = "1" Me.TXT_CHANNEL_USER_POST_LIMIT.Text = "1"
Me.TXT_CHANNEL_USER_POST_LIMIT.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center Me.TXT_CHANNEL_USER_POST_LIMIT.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center
' '
'TAB_BEHAVIOR
'
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, 284)
TAB_BEHAVIOR.TabIndex = 5
TAB_BEHAVIOR.Text = "Behavior"
'
'TP_BEHAVIOR
'
TP_BEHAVIOR.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_BEHAVIOR.ColumnCount = 1
TP_BEHAVIOR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BEHAVIOR.Controls.Add(Me.TXT_FOLDER_CMD, 0, 7)
TP_BEHAVIOR.Controls.Add(Me.CH_EXIT_CONFIRM, 0, 0)
TP_BEHAVIOR.Controls.Add(Me.CH_CLOSE_TO_TRAY, 0, 1)
TP_BEHAVIOR.Controls.Add(Me.CH_SHOW_NOTIFY, 0, 2)
TP_BEHAVIOR.Controls.Add(Me.CH_FAST_LOAD, 0, 3)
TP_BEHAVIOR.Controls.Add(Me.TXT_CLOSE_SCRIPT, 0, 8)
TP_BEHAVIOR.Controls.Add(TP_OPEN_INFO, 0, 5)
TP_BEHAVIOR.Controls.Add(Me.CH_RECYCLE_DEL, 0, 4)
TP_BEHAVIOR.Controls.Add(TP_OPEN_PROGRESS, 0, 6)
TP_BEHAVIOR.Dock = System.Windows.Forms.DockStyle.Fill
TP_BEHAVIOR.Location = New System.Drawing.Point(0, 0)
TP_BEHAVIOR.Name = "TP_BEHAVIOR"
TP_BEHAVIOR.RowCount = 11
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
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.Absolute, 28.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 284)
TP_BEHAVIOR.TabIndex = 0
'
'TXT_FOLDER_CMD
'
Me.TXT_FOLDER_CMD.AutoShowClearButton = True
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Enabled = False
ActionButton7.Index = 0
ActionButton7.Name = "BTT_CLEAR"
ActionButton7.Visible = False
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton7)
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
Me.TXT_FOLDER_CMD.CaptionToolTipText = "The command to open a folder."
Me.TXT_FOLDER_CMD.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FOLDER_CMD.LeaveDefaultButtons = True
Me.TXT_FOLDER_CMD.Location = New System.Drawing.Point(4, 186)
Me.TXT_FOLDER_CMD.Name = "TXT_FOLDER_CMD"
Me.TXT_FOLDER_CMD.PlaceholderEnabled = True
Me.TXT_FOLDER_CMD.PlaceholderText = "MyCommand /arg {0}"
Me.TXT_FOLDER_CMD.Size = New System.Drawing.Size(568, 22)
Me.TXT_FOLDER_CMD.TabIndex = 7
'
'CH_EXIT_CONFIRM
'
Me.CH_EXIT_CONFIRM.AutoSize = True
Me.CH_EXIT_CONFIRM.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_EXIT_CONFIRM.Location = New System.Drawing.Point(4, 4)
Me.CH_EXIT_CONFIRM.Name = "CH_EXIT_CONFIRM"
Me.CH_EXIT_CONFIRM.Size = New System.Drawing.Size(568, 19)
Me.CH_EXIT_CONFIRM.TabIndex = 0
Me.CH_EXIT_CONFIRM.Text = "Exit confirm"
Me.CH_EXIT_CONFIRM.UseVisualStyleBackColor = True
'
'CH_CLOSE_TO_TRAY
'
Me.CH_CLOSE_TO_TRAY.AutoSize = True
Me.CH_CLOSE_TO_TRAY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_CLOSE_TO_TRAY.Location = New System.Drawing.Point(4, 30)
Me.CH_CLOSE_TO_TRAY.Name = "CH_CLOSE_TO_TRAY"
Me.CH_CLOSE_TO_TRAY.Size = New System.Drawing.Size(568, 19)
Me.CH_CLOSE_TO_TRAY.TabIndex = 1
Me.CH_CLOSE_TO_TRAY.Text = "Close to tray"
Me.CH_CLOSE_TO_TRAY.UseVisualStyleBackColor = True
'
'CH_SHOW_NOTIFY
'
Me.CH_SHOW_NOTIFY.AutoSize = True
Me.CH_SHOW_NOTIFY.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_SHOW_NOTIFY.Location = New System.Drawing.Point(4, 56)
Me.CH_SHOW_NOTIFY.Name = "CH_SHOW_NOTIFY"
Me.CH_SHOW_NOTIFY.Size = New System.Drawing.Size(568, 19)
Me.CH_SHOW_NOTIFY.TabIndex = 2
Me.CH_SHOW_NOTIFY.Text = "Show notifications"
Me.CH_SHOW_NOTIFY.UseVisualStyleBackColor = True
'
'CH_RECYCLE_DEL
'
Me.CH_RECYCLE_DEL.AutoSize = True
Me.CH_RECYCLE_DEL.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_RECYCLE_DEL.Location = New System.Drawing.Point(4, 108)
Me.CH_RECYCLE_DEL.Name = "CH_RECYCLE_DEL"
Me.CH_RECYCLE_DEL.Size = New System.Drawing.Size(568, 19)
Me.CH_RECYCLE_DEL.TabIndex = 4
Me.CH_RECYCLE_DEL.Text = "Delete data to recycle bin"
Me.CH_RECYCLE_DEL.UseVisualStyleBackColor = True
'
'CH_DOWN_OPEN_INFO
'
Me.CH_DOWN_OPEN_INFO.AutoSize = True
Me.CH_DOWN_OPEN_INFO.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_OPEN_INFO.Location = New System.Drawing.Point(4, 4)
Me.CH_DOWN_OPEN_INFO.Name = "CH_DOWN_OPEN_INFO"
Me.CH_DOWN_OPEN_INFO.Size = New System.Drawing.Size(279, 17)
Me.CH_DOWN_OPEN_INFO.TabIndex = 0
Me.CH_DOWN_OPEN_INFO.Text = "Open the 'Info' form when the download starts"
Me.CH_DOWN_OPEN_INFO.UseVisualStyleBackColor = True
'
'CH_DOWN_OPEN_PROGRESS
'
Me.CH_DOWN_OPEN_PROGRESS.AutoSize = True
Me.CH_DOWN_OPEN_PROGRESS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_OPEN_PROGRESS.Location = New System.Drawing.Point(4, 4)
Me.CH_DOWN_OPEN_PROGRESS.Name = "CH_DOWN_OPEN_PROGRESS"
Me.CH_DOWN_OPEN_PROGRESS.Size = New System.Drawing.Size(279, 17)
Me.CH_DOWN_OPEN_PROGRESS.TabIndex = 0
Me.CH_DOWN_OPEN_PROGRESS.Text = "Open the 'Progress' form when the download starts"
Me.CH_DOWN_OPEN_PROGRESS.UseVisualStyleBackColor = True
'
'TXT_CLOSE_SCRIPT
'
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
Me.TXT_CLOSE_SCRIPT.CaptionToolTipText = "This command will be executed when SCrawler is closed"
Me.TXT_CLOSE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_CLOSE_SCRIPT.Location = New System.Drawing.Point(4, 215)
Me.TXT_CLOSE_SCRIPT.Name = "TXT_CLOSE_SCRIPT"
Me.TXT_CLOSE_SCRIPT.PlaceholderEnabled = True
Me.TXT_CLOSE_SCRIPT.PlaceholderText = "Enter command here..."
Me.TXT_CLOSE_SCRIPT.Size = New System.Drawing.Size(568, 22)
Me.TXT_CLOSE_SCRIPT.TabIndex = 8
'
'TAB_DOWN
'
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, 284)
TAB_DOWN.TabIndex = 6
TAB_DOWN.Text = "Downloading"
'
'TP_DOWNLOADING
'
TP_DOWNLOADING.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_DOWNLOADING.ColumnCount = 1
TP_DOWNLOADING.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DOWNLOADING.Controls.Add(TP_FILE_NAME, 0, 1)
TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 2)
TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 3)
TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0)
TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 4)
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 = 6
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
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, 28.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, 284)
TP_DOWNLOADING.TabIndex = 0
'
'TXT_SCRIPT
'
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Index = 0
ActionButton8.Name = "BTT_OPEN"
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Index = 1
ActionButton9.Name = "BTT_CLEAR"
Me.TXT_SCRIPT.Buttons.Add(ActionButton8)
Me.TXT_SCRIPT.Buttons.Add(ActionButton9)
Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SCRIPT.CaptionText = "Script"
Me.TXT_SCRIPT.CaptionToolTipEnabled = True
Me.TXT_SCRIPT.CaptionToolTipText = "Default script. If the checkbox is checked, newly created users will be created u" &
"sing the script option."
Me.TXT_SCRIPT.ChangeControlsEnableOnCheckedChange = False
Me.TXT_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SCRIPT.Location = New System.Drawing.Point(4, 92)
Me.TXT_SCRIPT.Name = "TXT_SCRIPT"
Me.TXT_SCRIPT.PlaceholderEnabled = True
Me.TXT_SCRIPT.PlaceholderText = "Enter script path here..."
Me.TXT_SCRIPT.Size = New System.Drawing.Size(568, 22)
Me.TXT_SCRIPT.TabIndex = 3
'
'TXT_DOWN_COMPLETE_SCRIPT
'
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionText = "After download cmd"
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipEnabled = True
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionToolTipText = "This command will be executed after all downloads are completed"
Me.TXT_DOWN_COMPLETE_SCRIPT.CaptionWidth = 120.0R
Me.TXT_DOWN_COMPLETE_SCRIPT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_DOWN_COMPLETE_SCRIPT.Location = New System.Drawing.Point(4, 121)
Me.TXT_DOWN_COMPLETE_SCRIPT.Name = "TXT_DOWN_COMPLETE_SCRIPT"
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderEnabled = True
Me.TXT_DOWN_COMPLETE_SCRIPT.PlaceholderText = "Enter command here..."
Me.TXT_DOWN_COMPLETE_SCRIPT.Size = New System.Drawing.Size(568, 22)
Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 4
'
'TAB_MAIN 'TAB_MAIN
' '
Me.TAB_MAIN.Controls.Add(TAB_BASIS) Me.TAB_MAIN.Controls.Add(TAB_BASIS)
Me.TAB_MAIN.Controls.Add(TAB_BEHAVIOR)
Me.TAB_MAIN.Controls.Add(TAB_DEFAULTS) Me.TAB_MAIN.Controls.Add(TAB_DEFAULTS)
Me.TAB_MAIN.Controls.Add(TAB_DOWN)
Me.TAB_MAIN.Controls.Add(TAB_DEFS_CHANNELS) Me.TAB_MAIN.Controls.Add(TAB_DEFS_CHANNELS)
Me.TAB_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.TAB_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0) Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TAB_MAIN.Name = "TAB_MAIN" Me.TAB_MAIN.Name = "TAB_MAIN"
Me.TAB_MAIN.SelectedIndex = 0 Me.TAB_MAIN.SelectedIndex = 0
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 479) Me.TAB_MAIN.Size = New System.Drawing.Size(584, 310)
Me.TAB_MAIN.TabIndex = 1 Me.TAB_MAIN.TabIndex = 1
' '
'CONTAINER_MAIN 'CONTAINER_MAIN
@@ -767,29 +960,89 @@
'CONTAINER_MAIN.ContentPanel 'CONTAINER_MAIN.ContentPanel
' '
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN) Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 479) Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 310)
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0) Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN" Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 479) Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 310)
Me.CONTAINER_MAIN.TabIndex = 0 Me.CONTAINER_MAIN.TabIndex = 0
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
' '
'TP_OPEN_INFO
'
TP_OPEN_INFO.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_OPEN_INFO.ColumnCount = 2
TP_OPEN_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_OPEN_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_OPEN_INFO.Controls.Add(Me.CH_DOWN_OPEN_INFO, 0, 0)
TP_OPEN_INFO.Controls.Add(Me.CH_DOWN_OPEN_INFO_SUSPEND, 1, 0)
TP_OPEN_INFO.Dock = System.Windows.Forms.DockStyle.Fill
TP_OPEN_INFO.Location = New System.Drawing.Point(1, 131)
TP_OPEN_INFO.Margin = New System.Windows.Forms.Padding(0)
TP_OPEN_INFO.Name = "TP_OPEN_INFO"
TP_OPEN_INFO.RowCount = 1
TP_OPEN_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_OPEN_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_OPEN_INFO.Size = New System.Drawing.Size(574, 25)
TP_OPEN_INFO.TabIndex = 5
'
'TP_OPEN_PROGRESS
'
TP_OPEN_PROGRESS.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_OPEN_PROGRESS.ColumnCount = 2
TP_OPEN_PROGRESS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_OPEN_PROGRESS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_OPEN_PROGRESS.Controls.Add(Me.CH_DOWN_OPEN_PROGRESS, 0, 0)
TP_OPEN_PROGRESS.Controls.Add(Me.CH_DOWN_OPEN_PROGRESS_SUSPEND, 1, 0)
TP_OPEN_PROGRESS.Dock = System.Windows.Forms.DockStyle.Fill
TP_OPEN_PROGRESS.Location = New System.Drawing.Point(1, 157)
TP_OPEN_PROGRESS.Margin = New System.Windows.Forms.Padding(0)
TP_OPEN_PROGRESS.Name = "TP_OPEN_PROGRESS"
TP_OPEN_PROGRESS.RowCount = 1
TP_OPEN_PROGRESS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_OPEN_PROGRESS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_OPEN_PROGRESS.Size = New System.Drawing.Size(574, 25)
TP_OPEN_PROGRESS.TabIndex = 6
'
'CH_DOWN_OPEN_INFO_SUSPEND
'
Me.CH_DOWN_OPEN_INFO_SUSPEND.AutoSize = True
Me.CH_DOWN_OPEN_INFO_SUSPEND.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_OPEN_INFO_SUSPEND.Location = New System.Drawing.Point(290, 4)
Me.CH_DOWN_OPEN_INFO_SUSPEND.Name = "CH_DOWN_OPEN_INFO_SUSPEND"
Me.CH_DOWN_OPEN_INFO_SUSPEND.Size = New System.Drawing.Size(280, 17)
Me.CH_DOWN_OPEN_INFO_SUSPEND.TabIndex = 1
Me.CH_DOWN_OPEN_INFO_SUSPEND.Text = "Don't open again"
TT_MAIN.SetToolTip(Me.CH_DOWN_OPEN_INFO_SUSPEND, "Do not open the form automatically if it was once closed")
Me.CH_DOWN_OPEN_INFO_SUSPEND.UseVisualStyleBackColor = True
'
'CH_DOWN_OPEN_PROGRESS_SUSPEND
'
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.AutoSize = True
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.Location = New System.Drawing.Point(290, 4)
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.Name = "CH_DOWN_OPEN_PROGRESS_SUSPEND"
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.Size = New System.Drawing.Size(280, 17)
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.TabIndex = 1
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.Text = "Don't open again"
TT_MAIN.SetToolTip(Me.CH_DOWN_OPEN_PROGRESS_SUSPEND, "Do not open the form automatically if it was once closed")
Me.CH_DOWN_OPEN_PROGRESS_SUSPEND.UseVisualStyleBackColor = True
'
'GlobalSettingsForm 'GlobalSettingsForm
' '
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(584, 479) Me.ClientSize = New System.Drawing.Size(584, 310)
Me.Controls.Add(Me.CONTAINER_MAIN) Me.Controls.Add(Me.CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.KeyPreview = True Me.KeyPreview = True
Me.MaximizeBox = False Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(600, 518) Me.MaximumSize = New System.Drawing.Size(600, 349)
Me.MinimizeBox = False Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(600, 518) Me.MinimumSize = New System.Drawing.Size(600, 349)
Me.Name = "GlobalSettingsForm" Me.Name = "GlobalSettingsForm"
Me.ShowInTaskbar = False Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
@@ -808,7 +1061,6 @@
TP_FILE_NAME.PerformLayout() TP_FILE_NAME.PerformLayout()
TP_FILE_PATTERNS.ResumeLayout(False) TP_FILE_PATTERNS.ResumeLayout(False)
TP_FILE_PATTERNS.PerformLayout() TP_FILE_PATTERNS.PerformLayout()
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).EndInit()
TP_CHANNELS_IMGS.ResumeLayout(False) TP_CHANNELS_IMGS.ResumeLayout(False)
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit()
@@ -820,10 +1072,24 @@
TP_CHANNELS.ResumeLayout(False) TP_CHANNELS.ResumeLayout(False)
TP_CHANNELS.PerformLayout() TP_CHANNELS.PerformLayout()
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).EndInit()
TAB_BEHAVIOR.ResumeLayout(False)
TP_BEHAVIOR.ResumeLayout(False)
TP_BEHAVIOR.PerformLayout()
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_CLOSE_SCRIPT, System.ComponentModel.ISupportInitialize).EndInit()
TAB_DOWN.ResumeLayout(False)
TP_DOWNLOADING.ResumeLayout(False)
TP_DOWNLOADING.PerformLayout()
CType(Me.TXT_SCRIPT, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_DOWN_COMPLETE_SCRIPT, System.ComponentModel.ISupportInitialize).EndInit()
Me.TAB_MAIN.ResumeLayout(False) Me.TAB_MAIN.ResumeLayout(False)
Me.CONTAINER_MAIN.ContentPanel.ResumeLayout(False) Me.CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
Me.CONTAINER_MAIN.ResumeLayout(False) Me.CONTAINER_MAIN.ResumeLayout(False)
Me.CONTAINER_MAIN.PerformLayout() Me.CONTAINER_MAIN.PerformLayout()
TP_OPEN_INFO.ResumeLayout(False)
TP_OPEN_INFO.PerformLayout()
TP_OPEN_PROGRESS.ResumeLayout(False)
TP_OPEN_PROGRESS.PerformLayout()
Me.ResumeLayout(False) Me.ResumeLayout(False)
End Sub End Sub
@@ -862,5 +1128,14 @@
Private WithEvents CH_FAST_LOAD As CheckBox Private WithEvents CH_FAST_LOAD As CheckBox
Private WithEvents TXT_FOLDER_CMD As PersonalUtilities.Forms.Controls.TextBoxExtended Private WithEvents TXT_FOLDER_CMD As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_RECYCLE_DEL As CheckBox Private WithEvents CH_RECYCLE_DEL As CheckBox
Private WithEvents TXT_SCRIPT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_SHOW_GROUPS As CheckBox
Private WithEvents CH_USERS_GROUPING As CheckBox
Private WithEvents CH_DOWN_OPEN_INFO As CheckBox
Private WithEvents CH_DOWN_OPEN_PROGRESS As CheckBox
Private WithEvents TXT_CLOSE_SCRIPT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_DOWN_COMPLETE_SCRIPT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CH_DOWN_OPEN_INFO_SUSPEND As CheckBox
Private WithEvents CH_DOWN_OPEN_PROGRESS_SUSPEND As CheckBox
End Class End Class
End Namespace End Namespace

View File

@@ -191,6 +191,12 @@
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value> </value>
</data> </data>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="TP_FILE_NAME.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="TP_FILE_NAME.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
@@ -200,20 +206,6 @@
<metadata name="LBL_DATE_POS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="LBL_DATE_POS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="ActionButton7.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="CH_SEPARATE_VIDEO_FOLDER.ToolTip" xml:space="preserve"> <data name="CH_SEPARATE_VIDEO_FOLDER.ToolTip" xml:space="preserve">
<value>This is a global setting for newly added users only. <value>This is a global setting for newly added users only.
This parameter specifies how the video will be stored in the users' download path. This parameter specifies how the video will be stored in the users' download path.
@@ -237,6 +229,51 @@ If checked, videos will be stored in separate folder; otherwise, videos will be
<metadata name="TP_CHANNELS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="TP_CHANNELS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="TAB_BEHAVIOR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_BEHAVIOR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton7.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>
<metadata name="TP_OPEN_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_OPEN_PROGRESS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TAB_DOWN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_DOWNLOADING.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton9.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="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
AAABAA8AAAAQAAEABAAwOgAA9gAAADAwEAABAAQAaAYAACg7AAAgIBAAAQAEAOgCAACQQQAAGBgQAAEA AAABAA8AAAAQAAEABAAwOgAA9gAAADAwEAABAAQAaAYAACg7AAAgIBAAAQAEAOgCAACQQQAAGBgQAAEA

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