Compare commits
17 Commits
2022.11.16
...
2023.3.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85d8df96ca | ||
|
|
6ca90f0489 | ||
|
|
2a780a3acf | ||
|
|
290b5c4586 | ||
|
|
f5e68a7032 | ||
|
|
ece573dd40 | ||
|
|
1f1148020c | ||
|
|
fc226d549a | ||
|
|
602771d982 | ||
|
|
3e472b4f2b | ||
|
|
30c3fe3b68 | ||
|
|
38c81b7a0b | ||
|
|
0fb6add751 | ||
|
|
5d64b8c7ce | ||
|
|
aabf6d62ab | ||
|
|
03487185c5 | ||
|
|
f0686bbc8e |
@@ -8,14 +8,16 @@ I welcome requests! Follow these steps to contribute:
|
||||
1. If you have a code change suggestion, you can post a replacement code block. I also accept pull requests.
|
||||
|
||||
# How to build from source
|
||||
1. Delete the "PersonalUtilities" project from the solution.
|
||||
1. Delete the "PersonalUtilities.Notifications" project from the solution.
|
||||
1. Delete the ```PersonalUtilities``` project from the solution.
|
||||
1. Delete the ```PersonalUtilities.Notifications``` project from the solution.
|
||||
1. Delete the ```cURL``` folder from the solution.
|
||||
1. Delete the ```ffmpeg.exe``` from the solution.
|
||||
1. The following libraries must be added to project references with the '**Copy to output folder**' option:
|
||||
- ```PersonalUtilities.dll```
|
||||
- ```PersonalUtilities.Notifications.dll```
|
||||
- ```Microsoft.Toolkit.Uwp.Notifications.dll```
|
||||
- ```System.ValueTuple.dll```
|
||||
1. Import PersonalUtilities.Functions for the whole project.
|
||||
- ```PersonalUtilities.dll```
|
||||
- ```PersonalUtilities.Notifications.dll```
|
||||
- ```Microsoft.Toolkit.Uwp.Notifications.dll```
|
||||
- ```System.ValueTuple.dll```
|
||||
1. Import ```PersonalUtilities.Functions``` for the whole project.
|
||||
|
||||
**Always use the correct libraries. You must download libraries from the same release date as the code commit date.**
|
||||
|
||||
|
||||
110
Changelog.md
@@ -1,3 +1,113 @@
|
||||
# 2023.3.1.0
|
||||
|
||||
*2023-03-01*
|
||||
|
||||
- Added
|
||||
- **Path plugin.** Now you can add paths. *This may be suitable if you want to add a collection of media data to a specific user collection.*
|
||||
- MainWindow: setting a background image
|
||||
- MainWindow: setting background color and font color
|
||||
- Feed: setting background color and font color
|
||||
- Feed: (Request #108) center the image in the feed grid
|
||||
- Users: the ability to use user site name (if it exists) as a friendly name (on supported sites: Reddit, Twitter, Instagram)
|
||||
- Users: the ability to update user site name every time
|
||||
- Twitter: ability to download images using MD5 comparison to protect against duplicate downloads *(this may be suitable for the users who post the same image many times)*
|
||||
- Twitter: one-time duplicate image removal option
|
||||
- XHamster: (Request #107) added channels downloading
|
||||
- Updated
|
||||
- Updated ffmpeg to version [5.1.2](https://github.com/GyanD/codexffmpeg/releases/tag/5.1.2)
|
||||
- Fixed
|
||||
- PornHub: (Issue #106) unicode titles
|
||||
- (Issue #106) problem with non-Latin characters
|
||||
- ffmpeg: maximum input length error when merging parts of files
|
||||
|
||||
# 2023.2.5.0
|
||||
|
||||
*2023-02-05*
|
||||
|
||||
- Added
|
||||
- The ability to configure UserAgent
|
||||
- Fixed
|
||||
- (Issue #101) Failed download Gfycat video in some cases
|
||||
|
||||
# 2023.1.27.0
|
||||
|
||||
*2023-01-27*
|
||||
|
||||
- Added
|
||||
- Advanced Twitter options for GIFs
|
||||
- Changing the icon of the user creation form based on the selected site
|
||||
- Fixed
|
||||
- Pinned Instagram posts reload every time
|
||||
- Plugins
|
||||
- Added
|
||||
- `Interaction` option to the `Provider` attribute
|
||||
- `IPropertyProvider` interface
|
||||
|
||||
# 2023.1.24.1
|
||||
|
||||
*2023-01-24*
|
||||
|
||||
- Added
|
||||
- Icon for standalone downloader
|
||||
- Fixed
|
||||
- (Issue #100) some Imgur albums won't download
|
||||
|
||||
# 2023.1.24.0
|
||||
|
||||
*2023-01-24*
|
||||
|
||||
- Fixed
|
||||
- (Issue #100) Imgur albums not downloading
|
||||
- When deleting a collection with the 'ban' option, users in the collection are not banned
|
||||
|
||||
# 2023.1.2.0
|
||||
|
||||
*2023-01-02*
|
||||
|
||||
- Added
|
||||
- RedGifs: an ability to customize token refresh interval
|
||||
- RedGifs: token refresh interval changed from 24 hours to 12 hours
|
||||
- Updated labels collection
|
||||
- Fixed
|
||||
- PornHub: bug in the downloader
|
||||
- PornHub: download additional non-user videos
|
||||
- Reddit: bug in standalone downloader
|
||||
- Fixed a bug in the user list loading algorithm
|
||||
- Notifications: pressing any button opens SCrawler
|
||||
|
||||
# 2022.12.27.0
|
||||
|
||||
*2022-12-27*
|
||||
|
||||
- Added
|
||||
- XVideos: added downloading 'Quickies'
|
||||
- Instagram: added more enable/disable options
|
||||
- Fixed
|
||||
- XVideos not downloading (sorry, I broke it in a previous release)
|
||||
|
||||
# 2022.12.26.0
|
||||
|
||||
*2022-12-26*
|
||||
|
||||
**ATTENTION!**
|
||||
|
||||
**Instagram requirements changed. Headers and cookies are now required to download Timeline, Stories and Saved posts; hash to download tagged posts. Please update your credentials.**
|
||||
|
||||
**Instagram tagged posts no longer provide the total amount of tagged posts. I've corrected the tagged posts notification, but now I can't tell how many requests will be spent on downloading tagged posts. And from now on, one request will be spent on downloading each tagged post, because Instagram doesn't provide complete information about the tagged post with the site's response. In this case, if the number of tagged posts is 1000, 1000 requests will be spent. Be careful when downloading them. I highly recommend that you forcefully disable the downloading of tagged posts for a while.**
|
||||
|
||||
- Added
|
||||
- Updated user loading algorithm
|
||||
- Channels button to tray context menu
|
||||
- (Request #96) Add FFmpeg to x86 version
|
||||
- Fixed
|
||||
- PornHub wrong behavior when downloading images
|
||||
- Unable open XVideos user profile
|
||||
- Cannot delete multiple collections at once
|
||||
- Can't focus user from the download info form
|
||||
- Instagram downloader not working
|
||||
- (Issue #69) **RedGifs data is not downloading**. Again.
|
||||
- Minor bugs
|
||||
|
||||
# 2022.11.16.0
|
||||
|
||||
*2022-11-16*
|
||||
|
||||
2
FAQ.md
@@ -42,7 +42,7 @@ A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-
|
||||
|
||||
#### Q: **Twitter/Instagram download failed.**
|
||||
|
||||
A: Check your credentials. Both of these sites require cookies. Check your [Twitter tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) and [Instagram settings](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram-settings). If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
|
||||
A: Check your credentials. Both of these sites require cookies. Check your [Twitter tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) and [Instagram settings](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram). If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
|
||||
|
||||
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ You can support the program by:
|
||||
- :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
|
||||
- :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/
|
||||
- :heart: like the program on this site: https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml
|
||||
- suggest my program as an alternative ([on this site](https://alternativeto.net/software/scrawler/about/)) to any program you have used before
|
||||
|
||||
I would be very grateful for any support! :blush:
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.4 KiB |
BIN
ProgramScreenshots/SettingsTwitterUser.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.3 KiB |
43
README.md
@@ -2,13 +2,14 @@
|
||||
|
||||
[](https://github.com/AAndyProgram/SCrawler/releases/latest)
|
||||
[](https://github.com/AAndyProgram/SCrawler/blob/main/LICENSE)
|
||||
[](https://github.com/AAndyProgram/SCrawler/releases)
|
||||
[](FAQ.md)
|
||||
[](https://github.com/AAndyProgram/SCrawler/wiki)
|
||||
[](HowToSupport.md)
|
||||
|
||||
A program to download photo and video from [any site](#supported-sites) (e.g. Reddit, Twitter, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, LPSG).
|
||||
|
||||
**If you like SCrawler, please like the program on [this site]( https://alternativeto.net/software/scrawler/about/)**
|
||||
**If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)**
|
||||
|
||||
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
|
||||
|
||||
@@ -21,7 +22,7 @@ Do you like this program? Consider adding to my coffee fund by making a donation
|
||||
|
||||
# What can program do:
|
||||
- Download pictures and videos from users' profiles and subreddits:
|
||||
- Reddit images, galleries of images, videos (downloading Reddit hosted video is going through ffmpeg (**ffmpeg only works with the x64 program**)), saved posts;
|
||||
- Reddit images, galleries of images, videos, saved posts;
|
||||
- Redgifs videos (https://www.redgifs.com/);
|
||||
- Twitter images and videos, saved (bookmarked) posts;
|
||||
- Instagram images and videos, tagged posts, stories, saved posts;
|
||||
@@ -36,18 +37,18 @@ Do you like this program? Consider adding to my coffee fund by making a donation
|
||||
- Download [saved Reddit, Twitter and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
|
||||
- Add users from parsed channel
|
||||
- **Advanced user management**
|
||||
- **Automation** (downloading data automatically every ```X``` minutes)
|
||||
- **Feed** (feed of downloaded media files)
|
||||
- **Automation** ([downloading data automatically](https://github.com/AAndyProgram/SCrawler/wiki/Settings#automation) every ```X``` minutes)
|
||||
- **Feed** ([feed](https://github.com/AAndyProgram/SCrawler/wiki#feed) of downloaded media files)
|
||||
- Labeling users
|
||||
- Create download groups
|
||||
- Create [download groups](https://github.com/AAndyProgram/SCrawler/wiki/Settings#download-groups)
|
||||
- Adding users to favorites and temporary
|
||||
- Filter exists users by label or group
|
||||
- [Filter exists users](https://github.com/AAndyProgram/SCrawler/wiki#view) by label or group
|
||||
- Selection of media types you want to download (images only, videos only, both)
|
||||
- Download a special video, image or gallery
|
||||
- Making collections (grouping users into collections)
|
||||
- [Download a special video](https://github.com/AAndyProgram/SCrawler/wiki#download-separate-video), image or gallery
|
||||
- Making [collections](https://github.com/AAndyProgram/SCrawler/wiki#collections) (grouping users into collections)
|
||||
- Specifying a user folder (for downloading data to another location)
|
||||
- Changing user icons
|
||||
- Changing view modes
|
||||
- Changing [view modes](https://github.com/AAndyProgram/SCrawler/wiki#view)
|
||||
- ...and many others...
|
||||
|
||||
# Supported sites
|
||||
@@ -73,11 +74,11 @@ First, the program downloads the full profile. After the program downloads only
|
||||
|
||||
## Reddit
|
||||
|
||||
The program parses all user posts, obtain MD5 images hash and compares them with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
The program parses user posts, obtain MD5 images hash and compares them with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
|
||||
## Other sites
|
||||
|
||||
The program parses all user posts and compares file names with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
The program parses user posts and compares file names with existing ones to remove duplicates. Then the media will be downloaded.
|
||||
|
||||
## How to request a new site
|
||||
|
||||
@@ -119,7 +120,7 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
|
||||
|
||||
# Installation
|
||||
|
||||
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder, copy the file ```ffmpeg.exe``` into it and enjoy.** :blush:
|
||||
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
|
||||
|
||||
**Don't put program in the ```Program Files``` system folder (this is portable program and program settings are stored in the program folder)**
|
||||
|
||||
@@ -127,17 +128,11 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
|
||||
|
||||
Just download [latest](https://github.com/AAndyProgram/SCrawler/releases/latest) version and unpack it into the program folder. **Before starting a new version, I recommend making a backup copy of the program settings folder.**
|
||||
|
||||
# How to build from source
|
||||
# [How to build from source](CONTRIBUTING.md#how-to-build-from-source)
|
||||
|
||||
Read about how to build from source [here](CONTRIBUTING.md#how-to-build-from-source)
|
||||
# [How to make a plugin](https://github.com/AAndyProgram/SCrawler/wiki/Plugins)
|
||||
|
||||
# How to make a plugin
|
||||
|
||||
Read about how to make plugin [here](https://github.com/AAndyProgram/SCrawler/wiki/Plugins).
|
||||
|
||||
# How to support
|
||||
|
||||
Read more about how to support the program [here](HowToSupport.md).
|
||||
# [How to support](HowToSupport.md)
|
||||
|
||||
# Settings and usage
|
||||
|
||||
@@ -158,3 +153,9 @@ Create a shortcut for the program. Open shortcut properties. In the ```Shortcut`
|
||||
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
|
||||
|
||||

|
||||
|
||||
# Contact me
|
||||
|
||||
[](https://matrix.to/#/@andyprogram:matrix.org)
|
||||
|
||||
[](https://discordapp.com/users/1012768226679206009) AndyProgram#3804
|
||||
@@ -100,6 +100,8 @@ Namespace Plugin.Attributes
|
||||
''' <see langword="False"/> - only for conversion
|
||||
''' </summary>
|
||||
Public FieldsChecker As Boolean = False
|
||||
''' <summary>Interaction with changing text field. Default: <see langword="False"/></summary>
|
||||
Public Interaction As Boolean = False
|
||||
''' <summary>Initialize a new Provider attribute. <see cref="IFormatProvider"/> is only allowed</summary>
|
||||
''' <param name="PropertyName">The name of the property for which this provider is used</param>
|
||||
Public Sub New(ByVal PropertyName As String)
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2022.11.16.0")>
|
||||
<Assembly: AssemblyFileVersion("2022.11.16.0")>
|
||||
<Assembly: AssemblyVersion("2023.2.5.0")>
|
||||
<Assembly: AssemblyFileVersion("2023.2.5.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Plugin
|
||||
Public Interface IPropertyProvider : Inherits IFormatProvider
|
||||
Property PropertyName As String
|
||||
End Interface
|
||||
End Namespace
|
||||
@@ -34,6 +34,7 @@ Namespace Plugin
|
||||
Public Property PostDate As Date? Implements IUserMedia.PostDate
|
||||
Public Property SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||
Public Property Attempts As Integer Implements IUserMedia.Attempts
|
||||
Public Property [Object] As Object Implements IUserMedia.Object
|
||||
End Structure
|
||||
Public Interface IUserMedia
|
||||
Property ContentType As Integer
|
||||
@@ -46,5 +47,6 @@ Namespace Plugin
|
||||
Property PostDate As Date?
|
||||
Property SpecialFolder As String
|
||||
Property Attempts As Integer
|
||||
Property [Object] As Object
|
||||
End Interface
|
||||
End Namespace
|
||||
@@ -102,6 +102,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Attributes\Attributes.vb" />
|
||||
<Compile Include="ObjectInterfaces\IPropertyProvider.vb" />
|
||||
<Compile Include="Objects\ExchangeOptions.vb" />
|
||||
<Compile Include="ObjectInterfaces\ILogProvider.vb" />
|
||||
<Compile Include="Interfaces\IPluginContentProvider.vb" />
|
||||
|
||||
@@ -9,5 +9,8 @@
|
||||
Namespace API.Base
|
||||
Friend Module Declarations
|
||||
Friend ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly)
|
||||
Friend ReadOnly TitleHtmlConverter As Func(Of String, String) =
|
||||
Function(Input) SymbolsConverter.HTML.Decode(SymbolsConverter.Convert(Input, EDP.ReturnValue), EDP.ReturnValue).
|
||||
StringRemoveWinForbiddenSymbols().StringTrim()
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -28,7 +28,7 @@ Namespace API.Base
|
||||
Return $"{Appender.StringTrimEnd("/")}/{File}"
|
||||
End If
|
||||
End Function
|
||||
Friend Shared Function Download(ByVal URLs As List(Of String), ByVal DestinationFile As SFile, Optional ByVal Responser As Response = Nothing) As SFile
|
||||
Friend Shared Function Download(ByVal URLs As List(Of String), ByVal DestinationFile As SFile, Optional ByVal Responser As Responser = Nothing) As SFile
|
||||
Dim CachePath As SFile = Nothing
|
||||
Try
|
||||
If URLs.ListExists Then
|
||||
|
||||
@@ -17,8 +17,8 @@ Namespace API.Base
|
||||
Friend Overridable ReadOnly Property Icon As Icon Implements ISiteSettings.Icon
|
||||
Friend Overridable ReadOnly Property Image As Image Implements ISiteSettings.Image
|
||||
Private Property Logger As ILogProvider = LogConnector Implements ISiteSettings.Logger
|
||||
Friend Overridable ReadOnly Property Responser As Response
|
||||
Private Property IResponserContainer_Responser As Response Implements IResponserContainer.Responser
|
||||
Friend Overridable ReadOnly Property Responser As Responser
|
||||
Private Property IResponserContainer_Responser As Responser Implements IResponserContainer.Responser
|
||||
Get
|
||||
Return Responser
|
||||
End Get
|
||||
@@ -30,14 +30,13 @@ Namespace API.Base
|
||||
End Sub
|
||||
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String)
|
||||
Site = SiteName
|
||||
Responser = New Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||
Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||
With Responser
|
||||
If .File.Exists Then
|
||||
If EncryptCookies.CookiesEncrypted Then .CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
||||
.LoadSettings()
|
||||
Else
|
||||
.CookiesDomain = CookiesDomain
|
||||
.Cookies = New CookieKeeper(.CookiesDomain) With {.EncryptKey = SettingsCLS.CookieEncryptKey}
|
||||
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
||||
.SaveSettings()
|
||||
End If
|
||||
@@ -53,6 +52,7 @@ Namespace API.Base
|
||||
End Sub
|
||||
Friend Overridable Sub EndInit() Implements ISiteSettings.EndInit
|
||||
EncryptCookies.ValidateCookiesEncrypt(Responser)
|
||||
If Not DefaultUserAgent.IsEmptyString And Not Responser Is Nothing Then Responser.UserAgent = DefaultUserAgent
|
||||
End Sub
|
||||
Friend Overridable Sub BeginUpdate() Implements ISiteSettings.BeginUpdate
|
||||
End Sub
|
||||
|
||||
@@ -104,7 +104,7 @@ Namespace API.Base
|
||||
Return Post.ID
|
||||
End Get
|
||||
Set(ByVal PostID As String)
|
||||
Post.ID = PostID
|
||||
Post = New UserPost(PostID, Post.Date)
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_PostDate As Date? Implements IUserMedia.PostDate
|
||||
@@ -112,7 +112,7 @@ Namespace API.Base
|
||||
Return Post.Date
|
||||
End Get
|
||||
Set(ByVal PostDate As Date?)
|
||||
Post.Date = PostDate
|
||||
Post = New UserPost(Post.ID, PostDate)
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||
@@ -131,6 +131,14 @@ Namespace API.Base
|
||||
Me.Attempts = Attempts
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_Object As Object Implements IUserMedia.Object
|
||||
Get
|
||||
Return Me.Object
|
||||
End Get
|
||||
Set(ByVal Obj As Object)
|
||||
Me.Object = Obj
|
||||
End Set
|
||||
End Property
|
||||
#End Region
|
||||
Friend Sub New(ByVal URL As String)
|
||||
Me.URL = URL
|
||||
@@ -142,7 +150,7 @@ Namespace API.Base
|
||||
Me.New(URL)
|
||||
Me.Type = Type
|
||||
End Sub
|
||||
Friend Sub New(ByVal m As Plugin.IUserMedia)
|
||||
Friend Sub New(ByVal m As IUserMedia)
|
||||
[Type] = m.ContentType
|
||||
URL = m.URL
|
||||
URL_BASE = m.URL_BASE
|
||||
@@ -152,6 +160,7 @@ Namespace API.Base
|
||||
State = m.DownloadState
|
||||
SpecialFolder = m.SpecialFolder
|
||||
Attempts = m.Attempts
|
||||
Me.Object = m.Object
|
||||
End Sub
|
||||
Friend Sub New(ByVal e As EContainer, ByVal UserInstance As IUserData)
|
||||
Type = e.Attribute(Name_MediaType).Value.FromXML(Of Integer)(CInt(Types.Undefined))
|
||||
@@ -178,7 +187,7 @@ Namespace API.Base
|
||||
|
||||
Post = New UserPost With {
|
||||
.ID = e.Attribute(Name_MediaPostID).Value,
|
||||
.[Date] = AConvert(Of Date)(e.Attribute(Name_MediaPostDate).Value, ParsersDataDateProvider, Nothing)
|
||||
.[Date] = AConvert(Of Date)(e.Attribute(Name_MediaPostDate).Value, DateTimeDefaultProvider, Nothing)
|
||||
}
|
||||
End Sub
|
||||
Public Shared Widening Operator CType(ByVal _URL As String) As UserMedia
|
||||
@@ -216,7 +225,7 @@ Namespace API.Base
|
||||
New EAttribute(Name_MediaFile, File.File),
|
||||
New EAttribute(Name_SpecialFolder, SpecialFolder),
|
||||
New EAttribute(Name_MediaPostID, Post.ID),
|
||||
New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, ParsersDataDateProvider, String.Empty))
|
||||
New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, DateTimeDefaultProvider, String.Empty))
|
||||
}
|
||||
)
|
||||
End Function
|
||||
|
||||
@@ -6,16 +6,18 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.IO
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports System.Runtime.CompilerServices
|
||||
Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Hosts
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Objects
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports System.IO
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Hosts
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.Base
|
||||
@@ -107,6 +109,7 @@ Namespace API.Base
|
||||
Private Const Name_UserExists As String = "UserExists"
|
||||
Private Const Name_UserSuspended As String = "UserSuspended"
|
||||
Private Const Name_FriendlyName As String = "FriendlyName"
|
||||
Private Const Name_UserSiteName As String = "UserSiteName"
|
||||
Private Const Name_UserID As String = "UserID"
|
||||
Private Const Name_Description As String = "Description"
|
||||
Private Const Name_ParseUserMediaOnly As String = "ParseUserMediaOnly"
|
||||
@@ -140,17 +143,30 @@ Namespace API.Base
|
||||
End Get
|
||||
End Property
|
||||
Friend Property Progress As MyProgress
|
||||
Friend ReadOnly Property Self As IUserData Implements IUserData.Self
|
||||
Get
|
||||
Return Me
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
#Region "User name, ID, exist, suspend"
|
||||
Friend User As UserInfo
|
||||
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
|
||||
Friend Overridable Property UserExists As Boolean = True Implements IUserData.Exists, IPluginContentProvider.UserExists
|
||||
Friend Overridable Property UserSuspended As Boolean = False Implements IUserData.Suspended, IPluginContentProvider.UserSuspended
|
||||
Private _UserExists As Boolean = True
|
||||
Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists
|
||||
Get
|
||||
Return _UserExists
|
||||
End Get
|
||||
Set(ByVal _UserExists As Boolean)
|
||||
If Not Me._UserExists = _UserExists Then EnvirChanged(_UserExists)
|
||||
Me._UserExists = _UserExists
|
||||
End Set
|
||||
End Property
|
||||
Private _UserSuspended As Boolean = False
|
||||
Friend Overridable Property UserSuspended As Boolean Implements IUserData.Suspended, IPluginContentProvider.UserSuspended
|
||||
Get
|
||||
Return _UserSuspended
|
||||
End Get
|
||||
Set(ByVal _UserSuspended As Boolean)
|
||||
If Not Me._UserSuspended = _UserSuspended Then EnvirChanged(_UserSuspended)
|
||||
Me._UserSuspended = _UserSuspended
|
||||
End Set
|
||||
End Property
|
||||
Friend Overridable Property Name As String Implements IContentProvider.Name, IPluginContentProvider.Name
|
||||
Get
|
||||
Return User.Name
|
||||
@@ -162,7 +178,46 @@ Namespace API.Base
|
||||
End Set
|
||||
End Property
|
||||
Friend Overridable Property ID As String = String.Empty Implements IContentProvider.ID, IPluginContentProvider.ID
|
||||
Friend Overridable Property FriendlyName As String = String.Empty Implements IContentProvider.FriendlyName
|
||||
Protected _FriendlyName As String = String.Empty
|
||||
Friend Overridable Property FriendlyName As String Implements IContentProvider.FriendlyName
|
||||
Get
|
||||
If Settings.UserSiteNameAsFriendly Then
|
||||
Return _FriendlyName.IfNullOrEmpty(UserSiteName)
|
||||
Else
|
||||
Return _FriendlyName
|
||||
End If
|
||||
End Get
|
||||
Set(ByVal n As String)
|
||||
_FriendlyName = n
|
||||
End Set
|
||||
End Property
|
||||
Friend ReadOnly Property FriendlyNameOrig As String
|
||||
Get
|
||||
Return _FriendlyName
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property FriendlyNameIsSiteName As Boolean
|
||||
Get
|
||||
If Settings.UserSiteNameAsFriendly Then
|
||||
Return Not FriendlyName.IsEmptyString And Not _FriendlyName = UserSiteName And FriendlyName = UserSiteName
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Private _UserSiteName As String = String.Empty
|
||||
Friend Property UserSiteName As String
|
||||
Get
|
||||
Return _UserSiteName
|
||||
End Get
|
||||
Set(ByVal _UserSiteName As String)
|
||||
If Not Me._UserSiteName = _UserSiteName Then EnvirChanged(_UserSiteName)
|
||||
Me._UserSiteName = _UserSiteName
|
||||
End Set
|
||||
End Property
|
||||
Protected Sub UserSiteNameUpdate(ByVal NewName As String)
|
||||
If Not NewName.IsEmptyString And (UserSiteName.IsEmptyString Or Settings.UserSiteNameUpdateEveryTime) Then UserSiteName = NewName
|
||||
End Sub
|
||||
Friend ReadOnly Property UserModel As UsageModel Implements IUserData.UserModel
|
||||
Get
|
||||
Return User.UserModel
|
||||
@@ -196,10 +251,6 @@ Namespace API.Base
|
||||
_DescriptionChecked = True
|
||||
End If
|
||||
End Sub
|
||||
Protected Sub UserDescriptionReset()
|
||||
_DescriptionChecked = False
|
||||
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Favorite, Temporary"
|
||||
Protected _Favorite As Boolean = False
|
||||
@@ -245,12 +296,12 @@ Namespace API.Base
|
||||
Friend Overridable Sub SetPicture(ByVal f As SFile) Implements IUserData.SetPicture
|
||||
Try
|
||||
If f.Exists Then
|
||||
Using p As New UserImage(f, User.File) : p.Save() : End Using
|
||||
Using p As New UserImage(f, MyFile) : p.Save() : End Using
|
||||
End If
|
||||
Catch
|
||||
End Try
|
||||
End Sub
|
||||
Protected Function GetNullPicture(ByVal MaxHeigh As XML.Base.XMLValue(Of Integer)) As Bitmap
|
||||
Protected Function GetNullPicture(ByVal MaxHeigh As XMLValue(Of Integer)) As Bitmap
|
||||
Return New Bitmap(CInt(DivideWithZeroChecking(MaxHeigh.Value, 100) * 75), MaxHeigh.Value)
|
||||
End Function
|
||||
Friend Function GetPicture(Of T)(Optional ByVal ReturnNullImageOnNothing As Boolean = True, Optional ByVal GetToast As Boolean = False) As T
|
||||
@@ -408,13 +459,18 @@ BlockNullPicture:
|
||||
#Region "Files"
|
||||
Friend Overridable Property MyFile As SFile Implements IUserData.File
|
||||
Get
|
||||
Return User.File
|
||||
If IsSavedPosts Then
|
||||
Return MyFileSettings
|
||||
Else
|
||||
Return User.File
|
||||
End If
|
||||
End Get
|
||||
Set(ByVal f As SFile)
|
||||
User.File = f
|
||||
Settings.UpdateUsersList(User)
|
||||
End Set
|
||||
End Property
|
||||
Protected MyFileSettings As SFile
|
||||
Protected MyFileData As SFile
|
||||
Protected MyFilePosts As SFile
|
||||
Friend Overridable Property FileExists As Boolean = False Implements IUserData.FileExists
|
||||
@@ -660,14 +716,16 @@ BlockNullPicture:
|
||||
Private _UserInformationLoaded As Boolean = False
|
||||
Friend Overridable Sub LoadUserInformation() Implements IUserData.LoadUserInformation
|
||||
Try
|
||||
If MyFile.Exists Then
|
||||
UpdateDataFiles(, True)
|
||||
If MyFileSettings.Exists Then
|
||||
FileExists = True
|
||||
Using x As New XmlFile(MyFile) With {.XmlReadOnly = True}
|
||||
Using x As New XmlFile(MyFileSettings) With {.XmlReadOnly = True}
|
||||
If User.Name.IsEmptyString Then User.Name = x.Value(Name_UserName)
|
||||
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
|
||||
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
|
||||
ID = x.Value(Name_UserID)
|
||||
FriendlyName = x.Value(Name_FriendlyName)
|
||||
_FriendlyName = x.Value(Name_FriendlyName)
|
||||
UserSiteName = x.Value(Name_UserSiteName)
|
||||
UserDescription = x.Value(Name_Description)
|
||||
ParseUserMediaOnly = x.Value(Name_ParseUserMediaOnly).FromXML(Of Boolean)(False)
|
||||
Temporary = x.Value(Name_Temporary).FromXML(Of Boolean)(False)
|
||||
@@ -682,6 +740,7 @@ BlockNullPicture:
|
||||
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)
|
||||
'TODELETE: UserDataBase remove old 'merge' constant
|
||||
#Disable Warning BC40000
|
||||
If x.Contains(Name_DataMerging) Then
|
||||
DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False)
|
||||
@@ -703,7 +762,8 @@ BlockNullPicture:
|
||||
End Sub
|
||||
Friend Overridable Sub UpdateUserInformation() Implements IUserData.UpdateUserInformation
|
||||
Try
|
||||
MyFile.Exists(SFO.Path)
|
||||
UpdateDataFiles(True)
|
||||
MyFileSettings.Exists(SFO.Path)
|
||||
Using x As New XmlFile With {.Name = "User"}
|
||||
x.Add(Name_Site, Site)
|
||||
x.Add(Name_Plugin, HOST.Key)
|
||||
@@ -716,7 +776,8 @@ BlockNullPicture:
|
||||
x.Add(Name_UserExists, UserExists.BoolToInteger)
|
||||
x.Add(Name_UserSuspended, UserSuspended.BoolToInteger)
|
||||
x.Add(Name_UserID, ID)
|
||||
x.Add(Name_FriendlyName, FriendlyName)
|
||||
x.Add(Name_FriendlyName, _FriendlyName)
|
||||
x.Add(Name_UserSiteName, UserSiteName)
|
||||
x.Add(Name_Description, UserDescription)
|
||||
x.Add(Name_ParseUserMediaOnly, ParseUserMediaOnly.BoolToInteger)
|
||||
x.Add(Name_Temporary, Temporary.BoolToInteger)
|
||||
@@ -741,7 +802,7 @@ BlockNullPicture:
|
||||
|
||||
LoadUserInformation_OptionalFields(x, False)
|
||||
|
||||
x.Save(MyFile)
|
||||
x.Save(MyFileSettings)
|
||||
End Using
|
||||
If Not IsSavedPosts Then Settings.UpdateUsersList(User)
|
||||
Catch ex As Exception
|
||||
@@ -754,7 +815,7 @@ BlockNullPicture:
|
||||
#Region "User data"
|
||||
Friend Overridable Overloads Sub LoadContentInformation(Optional ByVal Force As Boolean = False)
|
||||
Try
|
||||
UpdateDataFiles()
|
||||
UpdateDataFiles(, True)
|
||||
If Not MyFileData.Exists Or (_DataLoaded And Not Force) Then Exit Sub
|
||||
Using x As New XmlFile(MyFileData, Protector.Modes.All, False) With {.XmlReadOnly = True, .AllowSameNames = True}
|
||||
x.LoadData()
|
||||
@@ -769,7 +830,7 @@ BlockNullPicture:
|
||||
End Sub
|
||||
Friend Sub UpdateContentInformation()
|
||||
Try
|
||||
UpdateDataFiles()
|
||||
UpdateDataFiles(True, True)
|
||||
If MyFileData.IsEmptyString Then Exit Sub
|
||||
MyFileData.Exists(SFO.Path)
|
||||
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Data"}
|
||||
@@ -843,29 +904,55 @@ BlockNullPicture:
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Download functions and options"
|
||||
Protected Responser As Response
|
||||
Protected Responser As Responser
|
||||
Protected UseResponserClient As Boolean = False
|
||||
Protected _ForceSaveUserData As Boolean = False
|
||||
Protected _ForceSaveUserInfo As Boolean = False
|
||||
Private _DownloadInProgress As Boolean = False
|
||||
Private _EnvirUserExists As Boolean
|
||||
Private _EnvirUserSuspended As Boolean
|
||||
Private _EnvirChanged As Boolean = False
|
||||
Private _PictureExists As Boolean
|
||||
Private _EnvirInvokeUserUpdated As Boolean = False
|
||||
Protected Sub EnvirDownloadSet()
|
||||
UpdateDataFiles(, True)
|
||||
_DownloadInProgress = True
|
||||
_DescriptionChecked = False
|
||||
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
|
||||
_ForceSaveUserData = False
|
||||
_ForceSaveUserInfo = False
|
||||
_EnvirUserExists = UserExists
|
||||
_EnvirUserSuspended = UserSuspended
|
||||
_EnvirChanged = False
|
||||
UserExists = True
|
||||
UserSuspended = False
|
||||
DownloadedPictures(False) = 0
|
||||
DownloadedVideos(False) = 0
|
||||
_PictureExists = Settings.ViewModeIsPicture AndAlso Not GetPicture(Of Image)(False) Is Nothing
|
||||
_EnvirInvokeUserUpdated = False
|
||||
End Sub
|
||||
Private Sub EnvirChanged(ByVal NewValue As Object, <CallerMemberName> Optional ByVal Caller As String = Nothing)
|
||||
If _DownloadInProgress Then
|
||||
Select Case Caller
|
||||
Case NameOf(UserExists) : If Not _EnvirUserExists = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
||||
Case NameOf(UserSuspended) : If Not _EnvirUserSuspended = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
||||
Case Else : _EnvirChanged = True
|
||||
End Select
|
||||
End If
|
||||
End Sub
|
||||
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
|
||||
Dim Canceled As Boolean = False
|
||||
_ExternalCompatibilityToken = Token
|
||||
Try
|
||||
UpdateDataFiles()
|
||||
UserDescriptionReset()
|
||||
EnvirDownloadSet()
|
||||
If Not Responser Is Nothing Then Responser.Dispose()
|
||||
Responser = New Response
|
||||
Responser = New Responser
|
||||
If Not HOST.Responser Is Nothing Then Responser.Copy(HOST.Responser)
|
||||
'TODO: UserDataBase remove [Responser.DecodersError]
|
||||
Responser.DecodersError = New ErrorsDescriber(EDP.SendInLog + EDP.ReturnValue) With {
|
||||
.DeclaredMessage = New MMessage($"SymbolsConverter error: [{ToStringForLog()}]", ToStringForLog())}
|
||||
|
||||
Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(Of Image)(False) Is Nothing
|
||||
Dim sEnvir() As Boolean = {UserExists, UserSuspended}
|
||||
Dim EnvirChanged As Func(Of Boolean) = Function() Not sEnvir(0) = UserExists Or Not sEnvir(1) = UserSuspended
|
||||
Dim _downContent As Func(Of UserMedia, Boolean) = Function(c) c.State = UStates.Downloaded
|
||||
UserExists = True
|
||||
UserSuspended = False
|
||||
DownloadedPictures(False) = 0
|
||||
DownloadedVideos(False) = 0
|
||||
_TempMediaList.Clear()
|
||||
_TempPostsList.Clear()
|
||||
LatestData.Clear()
|
||||
@@ -894,6 +981,7 @@ BlockNullPicture:
|
||||
|
||||
ReparseVideo(Token)
|
||||
ThrowAny(Token)
|
||||
If IsSavedPosts Then UpdateDataFiles(True)
|
||||
If _TempPostsList.Count > 0 And Not DownloadMissingOnly And __SaveData Then _
|
||||
TextSaver.SaveTextToFile(_TempPostsList.ListToString(Environment.NewLine), MyFilePosts, True,, EDP.None)
|
||||
_ContentNew.ListAddList(_TempMediaList, LAP.ClearBeforeAdd)
|
||||
@@ -904,12 +992,12 @@ BlockNullPicture:
|
||||
Dim mcb& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0)
|
||||
_ContentList.ListAddList(_ContentNew.Where(Function(c) _downContent(c) Or MissingFinder(c)), LNC)
|
||||
Dim mca& = If(ContentMissingExists, _ContentList.LongCount(Function(c) MissingFinder(c)), 0)
|
||||
If DownloadedTotal(False) > 0 Or EnvirChanged.Invoke Or Not mcb = mca Then
|
||||
If DownloadedTotal(False) > 0 Or _EnvirChanged Or Not mcb = mca Or _ForceSaveUserData Then
|
||||
If __SaveData Then
|
||||
LastUpdated = Now
|
||||
RunScript()
|
||||
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
|
||||
DownloadedPictures(True) = SFile.GetFiles(MyFile.CutPath, "*.jpg|*.jpeg|*.png|*.gif|*.webm",, EDP.ReturnValue).Count
|
||||
DownloadedVideos(True) = SFile.GetFiles(MyFile.CutPath, "*.mp4|*.mkv|*.mov", SearchOption.AllDirectories, EDP.ReturnValue).Count
|
||||
If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser)
|
||||
UpdateContentInformation()
|
||||
Else
|
||||
@@ -920,10 +1008,12 @@ BlockNullPicture:
|
||||
End If
|
||||
If Not UserExists Then ReadyForDownload = False
|
||||
UpdateUserInformation()
|
||||
If _CollectionButtonsExists AndAlso EnvirChanged.Invoke Then UpdateButtonsColor()
|
||||
If _CollectionButtonsExists AndAlso _EnvirChanged Then UpdateButtonsColor()
|
||||
ElseIf _ForceSaveUserInfo Then
|
||||
UpdateUserInformation()
|
||||
End If
|
||||
ThrowIfDisposed()
|
||||
If UpPic Or EnvirChanged.Invoke Then OnUserUpdated()
|
||||
If Not _PictureExists Or _EnvirInvokeUserUpdated Then OnUserUpdated()
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
MyMainLOG = $"{ToStringForLog()}: downloading canceled"
|
||||
Canceled = True
|
||||
@@ -936,17 +1026,32 @@ BlockNullPicture:
|
||||
If Not Responser Is Nothing Then Responser.Dispose() : Responser = Nothing
|
||||
If Not Canceled Then _DataParsed = True
|
||||
_ContentNew.Clear()
|
||||
_DownloadInProgress = False
|
||||
DownloadTopCount = Nothing
|
||||
DownloadDateFrom = Nothing
|
||||
DownloadDateTo = Nothing
|
||||
DownloadMissingOnly = False
|
||||
_ForceSaveUserData = False
|
||||
_ForceSaveUserInfo = False
|
||||
End Try
|
||||
End Sub
|
||||
Protected Sub UpdateDataFiles()
|
||||
Protected Sub UpdateDataFiles(Optional ByVal ForceSaved As Boolean = False, Optional ByVal ValidateContetnt As Boolean = False)
|
||||
'TODELETE: saved posts name compatibility 2023.2.5.0
|
||||
Dim __validateSaved As Func(Of Boolean) = Function() MyFileData.Exists Or MyFilePosts.Exists
|
||||
If Not User.File.IsEmptyString Then
|
||||
MyFileData = User.File
|
||||
MyFileSettings = Nothing
|
||||
If IsSavedPosts Then
|
||||
Dim u As UserInfo = User
|
||||
u.Name = "SavedPosts"
|
||||
u.UpdateUserFile()
|
||||
Dim mfp As SFile = u.File
|
||||
mfp.Name &= "_Posts"
|
||||
If (ValidateContetnt AndAlso mfp.Exists) Or (Not ValidateContetnt AndAlso u.File.Exists) Or ForceSaved Then MyFileSettings = u.File
|
||||
End If
|
||||
If MyFileSettings.IsEmptyString Then MyFileSettings = User.File
|
||||
MyFileData = MyFileSettings
|
||||
MyFileData.Name &= "_Data"
|
||||
MyFilePosts = User.File
|
||||
MyFilePosts = MyFileSettings
|
||||
MyFilePosts.Name &= "_Posts"
|
||||
MyFilePosts.Extension = "txt"
|
||||
Else
|
||||
@@ -1022,12 +1127,14 @@ BlockNullPicture:
|
||||
End If
|
||||
|
||||
If Not v.SpecialFolder.IsEmptyString Then
|
||||
f.Path = $"{f.PathWithSeparator}{v.SpecialFolder}\".CSFileP.Path
|
||||
f.Path = $"{f.PathWithSeparator}{v.SpecialFolder.StringTrimEnd("*")}\".CSFileP.Path
|
||||
f.Exists(SFO.Path)
|
||||
End If
|
||||
If __isVideo And vsf Then
|
||||
f.Path = $"{f.PathWithSeparator}Video"
|
||||
If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
|
||||
If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then
|
||||
f.Path = $"{f.PathWithSeparator}Video"
|
||||
If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
|
||||
End If
|
||||
End If
|
||||
|
||||
If v.Type = UTypes.m3u8 And UseInternalM3U8Function Then
|
||||
@@ -1094,7 +1201,6 @@ BlockNullPicture:
|
||||
Return v
|
||||
End If
|
||||
Else
|
||||
'URGENT: UserDataBase.ProcessException [Throw ex]
|
||||
If ThrowEx Then Throw ex Else Return EXCEPTION_OPERATION_CANCELED
|
||||
End If
|
||||
Return 0
|
||||
@@ -1289,7 +1395,7 @@ BlockNullPicture:
|
||||
Else
|
||||
pOffset = 1
|
||||
End If
|
||||
fSource = User.File.CutPath(pOffset).Path.CSFileP
|
||||
fSource = MyFile.CutPath(pOffset).Path.CSFileP
|
||||
|
||||
Dim OptPath$ = String.Empty
|
||||
If IncludedInCollection Then
|
||||
@@ -1497,7 +1603,6 @@ BlockNullPicture:
|
||||
Function MoveFiles(ByVal CollectionName As String, ByVal SpecialCollectionPath As SFile) As Boolean
|
||||
Function CopyFiles(ByVal DestinationPath As SFile, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
|
||||
Sub OpenFolder()
|
||||
ReadOnly Property Self As IUserData
|
||||
Property DownloadTopCount As Integer?
|
||||
Property DownloadDateFrom As Date?
|
||||
Property DownloadDateTo As Date?
|
||||
|
||||
@@ -71,7 +71,7 @@ Namespace API.BaseObjects
|
||||
.Icon = s.Icon,
|
||||
.LocationOnly = True,
|
||||
.Size = New Size(400, 330),
|
||||
.DesignXMLNode = s.Site
|
||||
.DesignXMLNodeName = s.Site
|
||||
}
|
||||
AddHandler f.AddClick, __add
|
||||
AddHandler f.DeleteClick, __delete
|
||||
|
||||
@@ -17,7 +17,18 @@ Namespace API.Gfycat
|
||||
Try
|
||||
Dim r$
|
||||
Using w As New WebClient : r = w.DownloadString(URL) : End Using
|
||||
If Not r.IsEmptyString Then Return RegexReplace(r, RParams.DMS("contentUrl.:.(http.?://[^""]+?\.mp4)", 1)) Else Return String.Empty
|
||||
If Not r.IsEmptyString Then
|
||||
Dim _url$ = RegexReplace(r, RParams.DMS("contentUrl.:.(http.?://[^""]+?\.mp4)", 1, EDP.ReturnValue))
|
||||
If Not _url.IsEmptyString Then
|
||||
If _url.Contains("redgifs.com") Then
|
||||
_url = RegexReplace(_url, RParams.DMS("([^/-]+)[-\w]*\.mp4", 1, EDP.ReturnValue))
|
||||
If Not _url.IsEmptyString Then Return $"https://www.redgifs.com/watch/{_url}"
|
||||
Else
|
||||
Return _url
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Return String.Empty
|
||||
Catch ex As Exception
|
||||
Dim e As EDP = EDP.ReturnValue
|
||||
If TypeOf ex Is WebException Then
|
||||
|
||||
@@ -15,7 +15,7 @@ Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Namespace API.Imgur
|
||||
Namespace Declarations
|
||||
Friend Module Imgur_Declarations
|
||||
Friend ReadOnly PostRegex As RParams = RParams.DMS("/([\w\d]+?)(|\.[\w]{0,4})\Z", 1)
|
||||
Friend ReadOnly PostRegex As RParams = RParams.DMS("/([^/]+?)(|#.*?|\.[\w]{0,4})(|\?.*?)\Z", 1)
|
||||
End Module
|
||||
End Namespace
|
||||
Friend NotInheritable Class Envir
|
||||
@@ -70,11 +70,12 @@ Namespace API.Imgur
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, Optional ByVal e As ErrorsDescriber = Nothing) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If Not URL.IsEmptyString AndAlso URL.ToLower.Contains("imgur") AndAlso Not Settings.ImgurClientID.IsEmptyString Then
|
||||
Dim img$ = GetImage(URL, EDP.ReturnValue)
|
||||
If Not img.IsEmptyString Then
|
||||
Return {New UserMedia(img)}
|
||||
Dim imgList As List(Of String) = GetGallery(URL, EDP.ReturnValue)
|
||||
If imgList.ListExists Then
|
||||
Return imgList.Select(Function(u) New UserMedia(u))
|
||||
Else
|
||||
Return GetGallery(URL, EDP.ReturnValue).ListIfNothing.Select(Function(u) New UserMedia(u))
|
||||
Dim img$ = GetImage(URL, EDP.ReturnValue)
|
||||
If Not img.IsEmptyString Then Return {New UserMedia(img)}
|
||||
End If
|
||||
End If
|
||||
Return Nothing
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.Instagram
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class AdditionalSettingsForm : 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
|
||||
Me.CH_DOWN_TIME = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_DOWN_TAG = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_DOWN_SAVED = New System.Windows.Forms.CheckBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(234, 78)
|
||||
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(234, 103)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_MAIN.Controls.Add(Me.CH_DOWN_TIME, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.CH_DOWN_TAG, 0, 1)
|
||||
TP_MAIN.Controls.Add(Me.CH_DOWN_SAVED, 0, 2)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 4
|
||||
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, 25.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(234, 78)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'CH_DOWN_TIME
|
||||
'
|
||||
Me.CH_DOWN_TIME.AutoSize = True
|
||||
Me.CH_DOWN_TIME.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_TIME.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_DOWN_TIME.Name = "CH_DOWN_TIME"
|
||||
Me.CH_DOWN_TIME.Size = New System.Drawing.Size(226, 19)
|
||||
Me.CH_DOWN_TIME.TabIndex = 0
|
||||
Me.CH_DOWN_TIME.Text = "Download Timeline"
|
||||
Me.CH_DOWN_TIME.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_DOWN_TAG
|
||||
'
|
||||
Me.CH_DOWN_TAG.AutoSize = True
|
||||
Me.CH_DOWN_TAG.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_TAG.Location = New System.Drawing.Point(4, 30)
|
||||
Me.CH_DOWN_TAG.Name = "CH_DOWN_TAG"
|
||||
Me.CH_DOWN_TAG.Size = New System.Drawing.Size(226, 19)
|
||||
Me.CH_DOWN_TAG.TabIndex = 1
|
||||
Me.CH_DOWN_TAG.Text = "Download Stories and Tagged data"
|
||||
Me.CH_DOWN_TAG.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_DOWN_SAVED
|
||||
'
|
||||
Me.CH_DOWN_SAVED.AutoSize = True
|
||||
Me.CH_DOWN_SAVED.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_SAVED.Location = New System.Drawing.Point(4, 56)
|
||||
Me.CH_DOWN_SAVED.Name = "CH_DOWN_SAVED"
|
||||
Me.CH_DOWN_SAVED.Size = New System.Drawing.Size(226, 19)
|
||||
Me.CH_DOWN_SAVED.TabIndex = 2
|
||||
Me.CH_DOWN_SAVED.Text = "Download saved posts"
|
||||
Me.CH_DOWN_SAVED.UseVisualStyleBackColor = True
|
||||
'
|
||||
'AdditionalSettingsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(234, 103)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteResources.InstagramIcon_32
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(250, 142)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(250, 142)
|
||||
Me.Name = "AdditionalSettingsForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.Text = "Additional settings"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_MAIN.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents CH_DOWN_TIME As CheckBox
|
||||
Private WithEvents CH_DOWN_TAG As CheckBox
|
||||
Private WithEvents CH_DOWN_SAVED As CheckBox
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -1,41 +0,0 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Namespace API.Instagram
|
||||
Friend Class AdditionalSettingsForm
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Friend Property MyParameters As SettingsExchangeOptions
|
||||
Friend Sub New(ByVal Parameters As SettingsExchangeOptions)
|
||||
InitializeComponent()
|
||||
MyParameters = Parameters
|
||||
MyDefs = New DefaultFormOptions(Me, Settings.Design)
|
||||
End Sub
|
||||
Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize(True)
|
||||
.AddOkCancelToolbar()
|
||||
With MyParameters
|
||||
CH_DOWN_TIME.Checked = .DownloadTimeline
|
||||
CH_DOWN_TAG.Checked = .DownloadStoriesTagged
|
||||
CH_DOWN_SAVED.Checked = .DownloadSaved
|
||||
End With
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
MyParameters = New SettingsExchangeOptions With {
|
||||
.DownloadTimeline = CH_DOWN_TIME.Checked,
|
||||
.DownloadStoriesTagged = CH_DOWN_TAG.Checked,
|
||||
.DownloadSaved = CH_DOWN_SAVED.Checked,
|
||||
.Changed = True
|
||||
}
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -7,11 +7,49 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Clients.EventArguments
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Namespace API.Instagram
|
||||
Friend Module Declarations
|
||||
Friend Const InstagramSite As String = "Instagram"
|
||||
Friend Const InstagramSiteKey As String = "AndyProgram_Instagram"
|
||||
Friend ReadOnly FilesPattern As RParams = RParams.DMS(".+?([^/\?]+?\.[\w\d]{3,4})(?=(\?|\Z))", 1, EDP.ReturnValue)
|
||||
Friend ReadOnly Property DateProvider As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnicode(v))
|
||||
Friend Sub UpdateResponser(ByVal Source As IResponse, ByRef Destination As Responser)
|
||||
Const r_wwwClaimName$ = "x-ig-set-www-claim"
|
||||
Const r_tokenName$ = "csrftoken"
|
||||
If Not Source Is Nothing Then
|
||||
Dim isInternal As Boolean = TypeOf Source Is WebDataResponse
|
||||
Dim wwwClaimName$, tokenName$
|
||||
If isInternal Then
|
||||
wwwClaimName = r_wwwClaimName
|
||||
tokenName = r_tokenName
|
||||
Else
|
||||
wwwClaimName = SiteSettings.Header_IG_WWW_CLAIM
|
||||
tokenName = SiteSettings.Header_CSRF_TOKEN
|
||||
End If
|
||||
Dim wwwClaim$ = String.Empty
|
||||
Dim token$ = String.Empty
|
||||
With Source
|
||||
If isInternal Then
|
||||
If .HeadersExists Then wwwClaim = .Headers.Value(wwwClaimName)
|
||||
If .CookiesExists Then token = If(.Cookies.FirstOrDefault(Function(c) c.Name = tokenName)?.Value, String.Empty)
|
||||
Else
|
||||
If .HeadersExists Then
|
||||
wwwClaim = .Headers.Value(wwwClaimName)
|
||||
token = .Headers.Value(tokenName)
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
|
||||
If Not wwwClaim.IsEmptyString Then Destination.Headers.Add(SiteSettings.Header_IG_WWW_CLAIM, wwwClaim)
|
||||
If Not token.IsEmptyString Then Destination.Headers.Add(SiteSettings.Header_CSRF_TOKEN, token)
|
||||
If Not isInternal Then
|
||||
Destination.Cookies.Update(Source.Cookies, CookieKeeper.UpdateModes.ReplaceByNameAll, False, EDP.SendInLog)
|
||||
Destination.SaveSettings()
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -9,10 +9,12 @@
|
||||
Imports SCrawler.Plugin
|
||||
Namespace API.Instagram
|
||||
Friend Class EditorExchangeOptions
|
||||
Friend Property GetTimeline As Boolean
|
||||
Friend Property GetStories As Boolean
|
||||
Friend Property GetTagged As Boolean
|
||||
Friend Sub New(ByVal h As ISiteSettings)
|
||||
With DirectCast(h, SiteSettings)
|
||||
GetTimeline = CBool(.GetTimeline.Value)
|
||||
GetStories = CBool(.GetStories.Value)
|
||||
GetTagged = CBool(.GetTagged.Value)
|
||||
End With
|
||||
|
||||
41
SCrawler/API/Instagram/OptionsForm.Designer.vb
generated
@@ -26,6 +26,7 @@ Namespace API.Instagram
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Me.CH_GET_STORIES = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_GET_TAGGED = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_GET_TIMELINE = New System.Windows.Forms.CheckBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
@@ -39,13 +40,13 @@ Namespace API.Instagram
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(260, 53)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(260, 79)
|
||||
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(260, 78)
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(260, 104)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
@@ -54,26 +55,28 @@ Namespace API.Instagram
|
||||
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(Me.CH_GET_STORIES, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.CH_GET_TAGGED, 0, 1)
|
||||
TP_MAIN.Controls.Add(Me.CH_GET_STORIES, 0, 1)
|
||||
TP_MAIN.Controls.Add(Me.CH_GET_TAGGED, 0, 2)
|
||||
TP_MAIN.Controls.Add(Me.CH_GET_TIMELINE, 0, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 3
|
||||
TP_MAIN.RowCount = 4
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 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, 25.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(260, 53)
|
||||
TP_MAIN.Size = New System.Drawing.Size(260, 79)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'CH_GET_STORIES
|
||||
'
|
||||
Me.CH_GET_STORIES.AutoSize = True
|
||||
Me.CH_GET_STORIES.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_GET_STORIES.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_GET_STORIES.Location = New System.Drawing.Point(4, 30)
|
||||
Me.CH_GET_STORIES.Name = "CH_GET_STORIES"
|
||||
Me.CH_GET_STORIES.Size = New System.Drawing.Size(252, 19)
|
||||
Me.CH_GET_STORIES.TabIndex = 0
|
||||
Me.CH_GET_STORIES.TabIndex = 1
|
||||
Me.CH_GET_STORIES.Text = "Get stories"
|
||||
Me.CH_GET_STORIES.UseVisualStyleBackColor = True
|
||||
'
|
||||
@@ -81,26 +84,37 @@ Namespace API.Instagram
|
||||
'
|
||||
Me.CH_GET_TAGGED.AutoSize = True
|
||||
Me.CH_GET_TAGGED.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_GET_TAGGED.Location = New System.Drawing.Point(4, 30)
|
||||
Me.CH_GET_TAGGED.Location = New System.Drawing.Point(4, 56)
|
||||
Me.CH_GET_TAGGED.Name = "CH_GET_TAGGED"
|
||||
Me.CH_GET_TAGGED.Size = New System.Drawing.Size(252, 19)
|
||||
Me.CH_GET_TAGGED.TabIndex = 1
|
||||
Me.CH_GET_TAGGED.TabIndex = 2
|
||||
Me.CH_GET_TAGGED.Text = "Get tagged data"
|
||||
Me.CH_GET_TAGGED.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_GET_TIMELINE
|
||||
'
|
||||
Me.CH_GET_TIMELINE.AutoSize = True
|
||||
Me.CH_GET_TIMELINE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_GET_TIMELINE.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_GET_TIMELINE.Name = "CH_GET_TIMELINE"
|
||||
Me.CH_GET_TIMELINE.Size = New System.Drawing.Size(252, 19)
|
||||
Me.CH_GET_TIMELINE.TabIndex = 0
|
||||
Me.CH_GET_TIMELINE.Text = "Get Timeline"
|
||||
Me.CH_GET_TIMELINE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OptionsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(260, 78)
|
||||
Me.ClientSize = New System.Drawing.Size(260, 104)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteResources.InstagramIcon_32
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(276, 117)
|
||||
Me.MaximumSize = New System.Drawing.Size(276, 143)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(276, 117)
|
||||
Me.MinimumSize = New System.Drawing.Size(276, 143)
|
||||
Me.Name = "OptionsForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
@@ -116,5 +130,6 @@ Namespace API.Instagram
|
||||
|
||||
Private WithEvents CH_GET_STORIES As CheckBox
|
||||
Private WithEvents CH_GET_TAGGED As CheckBox
|
||||
Private WithEvents CH_GET_TIMELINE As CheckBox
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -21,6 +21,7 @@ Namespace API.Instagram
|
||||
.MyViewInitialize(True)
|
||||
.AddOkCancelToolbar()
|
||||
With MyExchangeOptions
|
||||
CH_GET_TIMELINE.Checked = .GetTimeline
|
||||
CH_GET_STORIES.Checked = .GetStories
|
||||
CH_GET_TAGGED.Checked = .GetTagged
|
||||
End With
|
||||
@@ -29,6 +30,7 @@ Namespace API.Instagram
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
With MyExchangeOptions
|
||||
.GetTimeline = CH_GET_TIMELINE.Checked
|
||||
.GetStories = CH_GET_STORIES.Checked
|
||||
.GetTagged = CH_GET_TAGGED.Checked
|
||||
End With
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.Instagram
|
||||
Friend Structure SettingsExchangeOptions
|
||||
Friend DownloadTimeline As Boolean
|
||||
Friend DownloadStoriesTagged As Boolean
|
||||
Friend DownloadSaved As Boolean
|
||||
Friend Changed As Boolean
|
||||
Friend Sub New(ByVal Source As SiteSettings)
|
||||
With Source
|
||||
DownloadTimeline = .DownloadTimeline
|
||||
DownloadStoriesTagged = .DownloadStoriesTagged
|
||||
DownloadSaved = .DownloadSaved
|
||||
End With
|
||||
End Sub
|
||||
End Structure
|
||||
End Namespace
|
||||
@@ -11,11 +11,14 @@ Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Objects
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||
Namespace API.Instagram
|
||||
<Manifest(InstagramSiteKey), SeparatedTasks(1), SavedPosts, SpecialForm(False), SpecialForm(True)>
|
||||
<Manifest(InstagramSiteKey), SeparatedTasks(1), SavedPosts, SpecialForm(False)>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||
#Region "Declarations"
|
||||
#Region "Images"
|
||||
@@ -77,28 +80,23 @@ Namespace API.Instagram
|
||||
End Class
|
||||
#End Region
|
||||
#Region "Authorization properties"
|
||||
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash", IsAuth:=True, AllowNull:=False), PXML("InstaHash"), ControlNumber(0)>
|
||||
Friend ReadOnly Property Hash As PropertyValue
|
||||
Private Const HashSavedPosts_Text As String = "Hash 2"
|
||||
<PropertyOption(ControlText:=HashSavedPosts_Text, ControlToolTip:="Instagram session hash for saved posts", IsAuth:=True), PXML("InstaHashSavedPosts"), ControlNumber(1)>
|
||||
Friend ReadOnly Property HashSavedPosts As PropertyValue
|
||||
<PropertyOption(ControlText:="x-csrftoken", ControlToolTip:="Instagram token for tagged data", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
|
||||
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash for tagged posts", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
|
||||
Friend ReadOnly Property HashTagged As PropertyValue
|
||||
<PropertyOption(ControlText:="x-csrftoken", IsAuth:=True, AllowNull:=False), ControlNumber(2)>
|
||||
Friend ReadOnly Property CSRF_TOKEN As PropertyValue
|
||||
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True, AllowNull:=False), ControlNumber(3)>
|
||||
Friend Property IG_APP_ID As PropertyValue
|
||||
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=False), ControlNumber(4)>
|
||||
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True, AllowNull:=True), ControlNumber(4)>
|
||||
Friend Property IG_WWW_CLAIM As PropertyValue
|
||||
Private Const SavedPostsUserName_Text As String = "Saved posts user"
|
||||
<PropertyOption(ControlText:=SavedPostsUserName_Text, ControlToolTip:="Personal profile username", IsAuth:=True), PXML("SavedPostsUserName"), ControlNumber(5)>
|
||||
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||
Friend Overrides Function BaseAuthExists() As Boolean
|
||||
Return If(Responser.Cookies?.Count, 0) > 0 And ACheck(IG_APP_ID.Value) And ACheck(IG_WWW_CLAIM.Value) And ACheck(CSRF_TOKEN.Value)
|
||||
Return Responser.CookiesExists And ACheck(IG_APP_ID.Value) And ACheck(CSRF_TOKEN.Value)
|
||||
End Function
|
||||
Private Const Header_IG_APP_ID As String = "x-ig-app-id"
|
||||
Private Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
|
||||
Private Const Header_CSRF_TOKEN As String = "x-csrftoken"
|
||||
Friend Const Header_IG_WWW_CLAIM As String = "x-ig-www-claim"
|
||||
Friend Const Header_CSRF_TOKEN As String = "x-csrftoken"
|
||||
Private _FieldsChangerSuspended As Boolean = False
|
||||
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
||||
If Not PropName.IsEmptyString Then
|
||||
If Not _FieldsChangerSuspended And Not PropName.IsEmptyString Then
|
||||
Dim f$ = String.Empty
|
||||
Select Case PropName
|
||||
Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID
|
||||
@@ -106,41 +104,46 @@ Namespace API.Instagram
|
||||
Case NameOf(CSRF_TOKEN) : f = Header_CSRF_TOKEN
|
||||
End Select
|
||||
If Not f.IsEmptyString Then
|
||||
Responser.HeadersRemove(f)
|
||||
If Not CStr(Value).IsEmptyString Then Responser.HeadersAdd(f, CStr(Value))
|
||||
Responser.Headers.Remove(f)
|
||||
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||
Responser.SaveSettings()
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download properties"
|
||||
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(6)>
|
||||
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(20)>
|
||||
Friend ReadOnly Property RequestsWaitTimer As PropertyValue
|
||||
<Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)>
|
||||
Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider
|
||||
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(7)>
|
||||
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False, LeftOffset:=120), PXML("RequestsWaitTimerTaskCount"), ControlNumber(21)>
|
||||
Friend ReadOnly Property RequestsWaitTimerTaskCount As PropertyValue
|
||||
<Provider(NameOf(RequestsWaitTimerTaskCount), FieldsChecker:=True)>
|
||||
Private ReadOnly Property RequestsWaitTimerTaskCountProvider As IFormatProvider
|
||||
<PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(8)>
|
||||
<PropertyOption(ControlText:="Posts limit timer", AllowNull:=False), PXML("SleepTimerOnPostsLimit"), ControlNumber(22)>
|
||||
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
|
||||
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
|
||||
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
|
||||
<PropertyOption(ControlText:="Get stories"), PXML, ControlNumber(9)>
|
||||
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users"), PXML, ControlNumber(23)>
|
||||
Friend ReadOnly Property GetTimeline As PropertyValue
|
||||
<PropertyOption(ControlText:="Get stories", ControlToolTip:="Default value for new users"), PXML, ControlNumber(24)>
|
||||
Friend ReadOnly Property GetStories As PropertyValue
|
||||
<PropertyOption(ControlText:="Get tagged photos"), PXML, ControlNumber(10)>
|
||||
<PropertyOption(ControlText:="Get tagged photos", ControlToolTip:="Default value for new users"), PXML, ControlNumber(25)>
|
||||
Friend ReadOnly Property GetTagged As PropertyValue
|
||||
<PropertyOption(ControlText:="Tagged notify limit",
|
||||
ControlToolTip:="If the number of tagged posts exceeds this number you will be notified." & vbCr &
|
||||
"-1 to disable"), PXML, ControlNumber(11)>
|
||||
"-1 to disable"), PXML, ControlNumber(26)>
|
||||
Friend ReadOnly Property TaggedNotifyLimit As PropertyValue
|
||||
<Provider(NameOf(TaggedNotifyLimit), FieldsChecker:=True)>
|
||||
Private ReadOnly Property TaggedNotifyLimitProvider As IFormatProvider
|
||||
#End Region
|
||||
#Region "Download ready"
|
||||
Friend ReadOnly Property DownloadTimeline As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property DownloadStoriesTagged As XMLValue(Of Boolean)
|
||||
Friend ReadOnly Property DownloadSaved As XMLValue(Of Boolean)
|
||||
<PropertyOption(ControlText:="Download timeline", ControlToolTip:="Download timeline"), PXML, ControlNumber(10)>
|
||||
Friend ReadOnly Property DownloadTimeline As PropertyValue
|
||||
<PropertyOption(ControlText:="Download stories", ControlToolTip:="Download stories"), PXML, ControlNumber(11)>
|
||||
Friend ReadOnly Property DownloadStories As PropertyValue
|
||||
<PropertyOption(ControlText:="Download tagged", ControlToolTip:="Download tagged posts"), PXML, ControlNumber(12)>
|
||||
Friend ReadOnly Property DownloadTagged As PropertyValue
|
||||
#End Region
|
||||
#Region "429 bypass"
|
||||
Private ReadOnly Property DownloadingErrorDate As XMLValue(Of Date)
|
||||
@@ -202,29 +205,25 @@ Namespace API.Instagram
|
||||
|
||||
With Responser
|
||||
If .Headers.Count > 0 Then
|
||||
token = .HeadersValue(Header_CSRF_TOKEN)
|
||||
app_id = .HeadersValue(Header_IG_APP_ID)
|
||||
www_claim = .HeadersValue(Header_IG_WWW_CLAIM)
|
||||
End If
|
||||
If Not .Cookies Is Nothing Then
|
||||
.Cookies.ChangedAllowInternalDrop = False
|
||||
.Cookies.Changed = False
|
||||
token = .Headers.Value(Header_CSRF_TOKEN)
|
||||
app_id = .Headers.Value(Header_IG_APP_ID)
|
||||
www_claim = .Headers.Value(Header_IG_WWW_CLAIM)
|
||||
End If
|
||||
.CookiesExtractMode = Responser.CookiesExtractModes.Response
|
||||
.CookiesUpdateMode = CookieKeeper.UpdateModes.ReplaceByNameAll
|
||||
.CookiesExtractedAutoSave = False
|
||||
End With
|
||||
|
||||
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
|
||||
|
||||
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
|
||||
|
||||
Hash = New PropertyValue(String.Empty, GetType(String))
|
||||
HashSavedPosts = New PropertyValue(String.Empty, GetType(String))
|
||||
HashTagged = New PropertyValue(String.Empty, GetType(String))
|
||||
CSRF_TOKEN = New PropertyValue(token, GetType(String), Sub(v) ChangeResponserFields(NameOf(CSRF_TOKEN), v))
|
||||
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.IfNullOrEmpty(0), GetType(String), Sub(v) ChangeResponserFields(NameOf(IG_WWW_CLAIM), v))
|
||||
|
||||
DownloadTimeline = New XMLValue(Of Boolean)("DownloadTimeline", True, _XML, n)
|
||||
DownloadStoriesTagged = New XMLValue(Of Boolean)("DownloadStoriesTagged", True, _XML, n)
|
||||
DownloadSaved = New XMLValue(Of Boolean)("DownloadSaved", True, _XML, n)
|
||||
DownloadTimeline = New PropertyValue(True)
|
||||
DownloadStories = New PropertyValue(True)
|
||||
DownloadTagged = New PropertyValue(False)
|
||||
|
||||
RequestsWaitTimer = New PropertyValue(1000)
|
||||
RequestsWaitTimerProvider = New TimersChecker(100)
|
||||
@@ -233,106 +232,25 @@ Namespace API.Instagram
|
||||
SleepTimerOnPostsLimit = New PropertyValue(60000)
|
||||
SleepTimerOnPostsLimitProvider = New TimersChecker(10000)
|
||||
|
||||
GetTimeline = New PropertyValue(True)
|
||||
GetStories = New PropertyValue(False)
|
||||
GetTagged = New PropertyValue(False)
|
||||
TaggedNotifyLimit = New PropertyValue(200)
|
||||
TaggedNotifyLimitProvider = New TaggedNotifyLimitChecker
|
||||
|
||||
DownloadingErrorDate = New XMLValue(Of Date) With {.Provider = New XMLValueConversionProvider(Function(ss, vv) AConvert(Of String)(vv, AModes.Var, Nothing))}
|
||||
DownloadingErrorDate = New XMLValue(Of Date) With {.Provider = New XMLValueConversionProvider(Function(ss, nn, vv, dd) AConvert(Of String)(vv, AModes.Var, Nothing))}
|
||||
DownloadingErrorDate.SetExtended("InstagramDownloadingErrorDate", Now.AddYears(-10), _XML, n)
|
||||
LastDownloadDate = New XMLValue(Of Date)("LastDownloadDate", Now.AddDays(-1), _XML, n)
|
||||
LastRequestsCount = New XMLValue(Of Integer)("LastRequestsCount", 0, _XML, n)
|
||||
LastRequestsCountLabel = New PropertyValue(LastRequestsCountLabelStr.Invoke(LastRequestsCount.Value))
|
||||
AddHandler LastRequestsCount.OnValueChanged, Sub(sender, __name, __value) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(DirectCast(__value, Existable(Of Integer)).Value)
|
||||
AddHandler LastRequestsCount.ValueChanged, Sub(sender, e) LastRequestsCountLabel.Value = LastRequestsCountLabelStr.Invoke(DirectCast(sender, XMLValue(Of Integer)).ValueF.Value)
|
||||
|
||||
UrlPatternUser = "https://www.instagram.com/{0}/"
|
||||
UserRegex = RParams.DMS("[htps:/]{7,8}.*?instagram.com/([^/]+)", 1)
|
||||
ImageVideoContains = "instagram.com"
|
||||
End Sub
|
||||
Private Structure LatestValues
|
||||
Friend Hash As String
|
||||
Friend Hash2 As String
|
||||
Friend Token As String
|
||||
Friend AppID As String
|
||||
Friend WwwClaim As String
|
||||
Friend Exists As Boolean
|
||||
Friend Sub New(ByVal Source As SiteSettings)
|
||||
Exists = True
|
||||
With Source
|
||||
Hash = AConvert(Of String)(.Hash.Value, String.Empty)
|
||||
Hash2 = AConvert(Of String)(.HashSavedPosts.Value, String.Empty)
|
||||
With .Responser
|
||||
Token = .HeadersValue(Header_CSRF_TOKEN)
|
||||
AppID = .HeadersValue(Header_IG_APP_ID)
|
||||
WwwClaim = .HeadersValue(Header_IG_WWW_CLAIM)
|
||||
End With
|
||||
End With
|
||||
End Sub
|
||||
End Structure
|
||||
Private LV As LatestValues = Nothing
|
||||
Private ASO As SettingsExchangeOptions = Nothing
|
||||
Friend Overrides Sub BeginEdit()
|
||||
LV = New LatestValues(Me)
|
||||
ASO = Nothing
|
||||
MyBase.BeginEdit()
|
||||
End Sub
|
||||
Friend Overrides Sub EndEdit()
|
||||
LV = Nothing
|
||||
ASO = Nothing
|
||||
MyBase.EndEdit()
|
||||
End Sub
|
||||
Friend Overrides Sub Update()
|
||||
If LV.Exists Then
|
||||
Dim __lv As New LatestValues(Me)
|
||||
If If(Responser.Cookies?.Count, 0) > 0 Then
|
||||
Dim _cookiesChanged As Boolean = If(Responser.Cookies?.Changed, False)
|
||||
If Not DownloadTimeline AndAlso (_cookiesChanged Or
|
||||
(Not LV.Hash = __lv.Hash And Not __lv.Hash.IsEmptyString)) Then DownloadTimeline.Value = True
|
||||
If Not DownloadSaved AndAlso (_cookiesChanged Or (Not LV.Hash2 = __lv.Hash2 And Not __lv.Hash2.IsEmptyString)) Then DownloadSaved.Value = True
|
||||
If Not DownloadStoriesTagged AndAlso (
|
||||
_cookiesChanged Or (
|
||||
(Not LV.Hash = __lv.Hash Or Not LV.Token = __lv.Token Or Not LV.AppID = __lv.AppID Or Not LV.WwwClaim = __lv.WwwClaim) And
|
||||
(Not __lv.Hash.IsEmptyString And Not __lv.Token.IsEmptyString And Not __lv.AppID.IsEmptyString And Not __lv.WwwClaim.IsEmptyString)
|
||||
)) Then DownloadStoriesTagged.Value = True
|
||||
End If
|
||||
End If
|
||||
If ASO.Changed Then
|
||||
DownloadTimeline.Value = ASO.DownloadTimeline
|
||||
DownloadStoriesTagged.Value = ASO.DownloadStoriesTagged
|
||||
DownloadSaved.Value = ASO.DownloadSaved
|
||||
End If
|
||||
LV = Nothing
|
||||
ASO = Nothing
|
||||
If Not Responser.Cookies Is Nothing Then Responser.Cookies.Changed = False
|
||||
MyBase.Update()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "PropertiesDataChecker"
|
||||
<PropertiesDataChecker({NameOf(Hash), NameOf(HashSavedPosts)})>
|
||||
Private Function CheckHashControls(ByVal p As IEnumerable(Of PropertyData)) As Boolean
|
||||
If p.ListExists(2) Then
|
||||
Dim h$ = String.Empty
|
||||
Dim hsp$ = String.Empty
|
||||
For Each pp As PropertyData In p
|
||||
Select Case pp.Name
|
||||
Case NameOf(Hash) : h = AConvert(Of String)(pp.Value, String.Empty)
|
||||
Case NameOf(HashSavedPosts) : hsp = AConvert(Of String)(pp.Value, String.Empty)
|
||||
End Select
|
||||
Next
|
||||
If h.IsEmptyString And hsp.IsEmptyString Then
|
||||
Return True
|
||||
Else
|
||||
If h = hsp Then
|
||||
MsgBoxE({"InstaHash for saved posts must be different from InstaHash!", "InstaHash are equal"}, vbCritical)
|
||||
Return False
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End If
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
<PropertiesDataChecker({NameOf(TaggedNotifyLimit)})>
|
||||
Private Function CheckNotifyLimit(ByVal p As IEnumerable(Of PropertyData)) As Boolean
|
||||
If p.ListExists Then
|
||||
@@ -351,37 +269,6 @@ Namespace API.Instagram
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
<PropertiesDataChecker({NameOf(HashSavedPosts), NameOf(SavedPostsUserName)})>
|
||||
Private Function CheckSavedOptions(ByVal p As IEnumerable(Of PropertyData)) As Boolean
|
||||
If p.ListExists Then
|
||||
Const MsgTitle$ = "Saved posts credentials"
|
||||
Dim __hash$ = String.Empty
|
||||
Dim __name$ = String.Empty
|
||||
Dim _OptionlErrorText$ = $"For download saved posts, you must to set both [{HashSavedPosts_Text}] and [{SavedPostsUserName_Text}]."
|
||||
For i% = 0 To p.Count - 1
|
||||
Select Case p(i).Name
|
||||
Case NameOf(HashSavedPosts) : __hash = p(i).Value
|
||||
Case NameOf(SavedPostsUserName) : __name = p(i).Value
|
||||
End Select
|
||||
Next
|
||||
If __hash = __name Then
|
||||
If __hash.IsEmptyString Then
|
||||
Return True
|
||||
Else
|
||||
MsgBoxE({$"[{HashSavedPosts_Text}] and [{SavedPostsUserName_Text}] for saved posts cannot be equal!", MsgTitle}, vbCritical)
|
||||
End If
|
||||
Else
|
||||
If __hash.IsEmptyString Then
|
||||
MsgBoxE({$"[{HashSavedPosts_Text}] not set.{vbCr}{_OptionlErrorText}", MsgTitle}, vbCritical)
|
||||
ElseIf __name.IsEmptyString Then
|
||||
MsgBoxE({$"[{SavedPostsUserName_Text}] not set.{vbCr}{_OptionlErrorText}", MsgTitle}, vbCritical)
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Plugin functions"
|
||||
Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider
|
||||
@@ -389,7 +276,7 @@ Namespace API.Instagram
|
||||
Case Download.Main : Return New UserData
|
||||
Case Download.SavedPosts
|
||||
Dim u As New UserData
|
||||
DirectCast(u, UserDataBase).User = New UserInfo With {.Name = CStr(AConvert(Of String)(SavedPostsUserName.Value, String.Empty))}
|
||||
DirectCast(u, UserDataBase).User = New UserInfo With {.Name = Site}
|
||||
Return u
|
||||
End Select
|
||||
Return Nothing
|
||||
@@ -397,19 +284,14 @@ Namespace API.Instagram
|
||||
#Region "Downloading"
|
||||
Friend Property SkipUntilNextSession As Boolean = False
|
||||
Friend Overrides Function ReadyToDownload(ByVal What As Download) As Boolean
|
||||
If ActiveJobs < 2 AndAlso Not SkipUntilNextSession AndAlso ReadyForDownload AndAlso BaseAuthExists() Then
|
||||
Select Case What
|
||||
Case Download.Main : Return ACheck(Hash.Value) And DownloadTimeline
|
||||
Case Download.SavedPosts : Return ACheck(HashSavedPosts.Value) And DownloadSaved
|
||||
End Select
|
||||
End If
|
||||
Return False
|
||||
Return ActiveJobs < 2 AndAlso Not SkipUntilNextSession AndAlso ReadyForDownload AndAlso BaseAuthExists() AndAlso DownloadTimeline.Value
|
||||
End Function
|
||||
Private ActiveJobs As Integer = 0
|
||||
Private _NextWNM As UserData.WNM = UserData.WNM.Notify
|
||||
Private _NextTagged As Boolean = True
|
||||
Friend Overrides Sub DownloadStarted(ByVal What As Download)
|
||||
ActiveJobs += 1
|
||||
If LastDownloadDate.Value.AddMinutes(120) < Now Or Not ACheck(IG_WWW_CLAIM.Value) Then IG_WWW_CLAIM.Value = "0"
|
||||
End Sub
|
||||
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
|
||||
With DirectCast(User, UserData)
|
||||
@@ -432,6 +314,10 @@ Namespace API.Instagram
|
||||
_NextTagged = .TaggedCheckSession
|
||||
LastDownloadDate.Value = Now
|
||||
LastRequestsCount.Value = .RequestsCount
|
||||
_FieldsChangerSuspended = True
|
||||
IG_WWW_CLAIM.Value = Responser.Headers.Value(Header_IG_WWW_CLAIM)
|
||||
CSRF_TOKEN.Value = Responser.Headers.Value(Header_CSRF_TOKEN)
|
||||
_FieldsChangerSuspended = False
|
||||
End With
|
||||
End Sub
|
||||
Friend Overrides Sub DownloadDone(ByVal What As Download)
|
||||
@@ -451,12 +337,14 @@ Namespace API.Instagram
|
||||
Using f As New OptionsForm(Options) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
Friend Overrides Sub OpenSettingsForm()
|
||||
Using f As New AdditionalSettingsForm(If(ASO.Changed, ASO, New SettingsExchangeOptions(Me)))
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Then ASO = f.MyParameters
|
||||
End Using
|
||||
End Sub
|
||||
Friend Overrides Function GetUserPostUrl(ByVal User As UserDataBase, ByVal Media As UserMedia) As String
|
||||
Try
|
||||
Dim code$ = DirectCast(User, UserData).GetPostCodeById(Media.Post.ID)
|
||||
If Not code.IsEmptyString Then Return $"https://instagram.com/p/{code}/" Else Return String.Empty
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.SendInLog, ex, "Can't open user's post", String.Empty)
|
||||
End Try
|
||||
End Function
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -9,6 +9,7 @@
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports PersonalUtilities.Functions.Messaging
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
@@ -20,29 +21,68 @@ Namespace API.Instagram
|
||||
#Region "XML Names"
|
||||
Private Const Name_LastCursor As String = "LastCursor"
|
||||
Private Const Name_FirstLoadingDone As String = "FirstLoadingDone"
|
||||
Private Const Name_GetTimeline As String = "GetTimeline"
|
||||
Private Const Name_GetStories As String = "GetStories"
|
||||
Private Const Name_GetTagged As String = "GetTaggedData"
|
||||
Private Const Name_TaggedChecked As String = "TaggedChecked"
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
Private Structure PostKV : Implements IEContainerProvider
|
||||
Private Const Name_Code As String = "Code"
|
||||
Private Const Name_Section As String = "Section"
|
||||
Friend Code As String
|
||||
Friend ID As String
|
||||
Friend Section As Sections
|
||||
Friend Sub New(ByVal _Section As Sections)
|
||||
Section = _Section
|
||||
End Sub
|
||||
Friend Sub New(ByVal _Code As String, ByVal _ID As String, ByVal _Section As Sections)
|
||||
Code = _Code
|
||||
ID = _ID
|
||||
Section = _Section
|
||||
End Sub
|
||||
Private Sub New(ByVal e As EContainer)
|
||||
Code = e.Attribute(Name_Code)
|
||||
Section = e.Attribute(Name_Section)
|
||||
ID = e.Value
|
||||
End Sub
|
||||
Public Shared Widening Operator CType(ByVal e As EContainer) As PostKV
|
||||
Return New PostKV(e)
|
||||
End Operator
|
||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||
If Not IsNothing(Obj) AndAlso TypeOf Obj Is PostKV Then
|
||||
With DirectCast(Obj, PostKV)
|
||||
Return Code = .Code And ID = .ID And Section = .Section
|
||||
End With
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
Private Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
|
||||
Return New EContainer("Post", ID, {New EAttribute(Name_Section, CInt(Section)), New EAttribute(Name_Code, Code)})
|
||||
End Function
|
||||
End Structure
|
||||
Private ReadOnly Property MySiteSettings As SiteSettings
|
||||
Get
|
||||
Return DirectCast(HOST.Source, SiteSettings)
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly _SavedPostsIDs As New List(Of String)
|
||||
Private ReadOnly PostsKVIDs As List(Of PostKV)
|
||||
Private ReadOnly PostsToReparse As List(Of PostKV)
|
||||
Private LastCursor As String = String.Empty
|
||||
Private FirstLoadingDone As Boolean = False
|
||||
Friend Property GetTimeline As Boolean = True
|
||||
Friend Property GetStories As Boolean
|
||||
Friend Property GetTaggedData As Boolean
|
||||
#End Region
|
||||
#Region "Exchange options"
|
||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||
Return New EditorExchangeOptions(HOST.Source) With {.GetStories = GetStories, .GetTagged = GetTaggedData}
|
||||
Return New EditorExchangeOptions(HOST.Source) With {.GetTimeline = GetTimeline, .GetStories = GetStories, .GetTagged = GetTaggedData}
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptions Then
|
||||
With DirectCast(Obj, EditorExchangeOptions)
|
||||
GetTimeline = .GetTimeline
|
||||
GetStories = .GetStories
|
||||
GetTaggedData = .GetTagged
|
||||
End With
|
||||
@@ -51,17 +91,21 @@ Namespace API.Instagram
|
||||
#End Region
|
||||
#Region "Initializer, loader"
|
||||
Friend Sub New()
|
||||
PostsKVIDs = New List(Of PostKV)
|
||||
PostsToReparse = New List(Of PostKV)
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
If Loading Then
|
||||
LastCursor = Container.Value(Name_LastCursor)
|
||||
FirstLoadingDone = Container.Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
|
||||
GetTimeline = Container.Value(Name_GetTimeline).FromXML(Of Boolean)(CBool(MySiteSettings.GetTimeline.Value))
|
||||
GetStories = Container.Value(Name_GetStories).FromXML(Of Boolean)(CBool(MySiteSettings.GetStories.Value))
|
||||
GetTaggedData = Container.Value(Name_GetTagged).FromXML(Of Boolean)(CBool(MySiteSettings.GetTagged.Value))
|
||||
TaggedChecked = Container.Value(Name_TaggedChecked).FromXML(Of Boolean)(False)
|
||||
Else
|
||||
Container.Add(Name_LastCursor, LastCursor)
|
||||
Container.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
|
||||
Container.Add(Name_GetTimeline, GetTimeline.BoolToInteger)
|
||||
Container.Add(Name_GetStories, GetStories.BoolToInteger)
|
||||
Container.Add(Name_GetTagged, GetTaggedData.BoolToInteger)
|
||||
Container.Add(Name_TaggedChecked, TaggedChecked.BoolToInteger)
|
||||
@@ -78,48 +122,128 @@ Namespace API.Instagram
|
||||
End If
|
||||
Throw New ExitException
|
||||
End Sub
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
Friend Sub New(ByRef CompleteArg As Boolean)
|
||||
CompleteArg = True
|
||||
End Sub
|
||||
End Class
|
||||
Private Sub LoadSavePostsKV(ByVal Load As Boolean)
|
||||
Dim x As XmlFile
|
||||
Dim f As SFile = MyFilePosts
|
||||
If Not f.IsEmptyString Then
|
||||
f.Name &= "_KV"
|
||||
f.Extension = "xml"
|
||||
If Load Then
|
||||
PostsKVIDs.Clear()
|
||||
x = New XmlFile(f, Protector.Modes.All, False) With {.AllowSameNames = True, .XmlReadOnly = True}
|
||||
x.LoadData()
|
||||
If x.Count > 0 Then PostsKVIDs.ListAddList(x, LAP.IgnoreICopier)
|
||||
x.Dispose()
|
||||
Else
|
||||
x = New XmlFile With {.AllowSameNames = True}
|
||||
x.AddRange(PostsKVIDs)
|
||||
x.Name = "Posts"
|
||||
x.Save(f, EDP.SendInLog)
|
||||
x.Dispose()
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
Private Overloads Function PostKvExists(ByVal pkv As PostKV) As Boolean
|
||||
Return PostKvExists(pkv.ID, False, pkv.Section) OrElse PostKvExists(pkv.Code, True, pkv.Section)
|
||||
End Function
|
||||
Private Overloads Function PostKvExists(ByVal PostCodeId As String, ByVal IsCode As Boolean, ByVal Section As Sections) As Boolean
|
||||
If Not PostCodeId.IsEmptyString And PostsKVIDs.Count > 0 Then
|
||||
If PostsKVIDs.FindIndex(Function(p) p.Section = Section AndAlso If(IsCode, p.Code = PostCodeId, p.ID = PostCodeId)) >= 0 Then
|
||||
Return True
|
||||
ElseIf Not IsCode Then
|
||||
Return _TempPostsList.Contains(GetPostIdBySection(PostCodeId, Section)) Or
|
||||
_TempPostsList.Contains(PostCodeId.Replace($"_{ID}", String.Empty)) Or
|
||||
_TempPostsList.Contains(GetPostIdBySection(PostCodeId.Replace($"_{ID}", String.Empty), Section))
|
||||
End If
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
Friend Function GetPostCodeById(ByVal PostID As String) As String
|
||||
Try
|
||||
If Not PostID.IsEmptyString Then
|
||||
Dim f As SFile = MyFilePosts
|
||||
If Not f.IsEmptyString Then
|
||||
f.Name &= "_KV"
|
||||
f.Extension = "xml"
|
||||
Dim l As List(Of PostKV) = Nothing
|
||||
Using x As New XmlFile(f, Protector.Modes.All, False) With {.AllowSameNames = True, .XmlReadOnly = True}
|
||||
x.LoadData()
|
||||
l.ListAddList(x, LAP.IgnoreICopier)
|
||||
End Using
|
||||
Dim code$ = String.Empty
|
||||
If l.ListExists Then
|
||||
Dim i% = l.FindIndex(Function(p) p.ID = PostID)
|
||||
If i >= 0 Then code = l(i).Code
|
||||
l.Clear()
|
||||
End If
|
||||
Return code
|
||||
End If
|
||||
End If
|
||||
Return String.Empty
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.SendInLog, ex, $"{ToStringForLog()}: Cannot find post code by ID ({PostID})", String.Empty)
|
||||
End Try
|
||||
End Function
|
||||
Private Function GetPostIdBySection(ByVal ID As String, ByVal Section As Sections) As String
|
||||
If Section = Sections.Timeline Then
|
||||
Return ID
|
||||
Else
|
||||
Return $"{Section}_{ID}"
|
||||
End If
|
||||
End Function
|
||||
Private _DownloadingInProgress As Boolean = False
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
Dim s As Sections = Sections.Timeline
|
||||
Dim errorFound As Boolean = False
|
||||
Try
|
||||
LoadSavePostsKV(True)
|
||||
_DownloadingInProgress = True
|
||||
AddHandler Responser.ResponseReceived, AddressOf Responser_ResponseReceived
|
||||
ThrowAny(Token)
|
||||
_InstaHash = String.Empty
|
||||
HasError = False
|
||||
Dim fc As Boolean = IIf(IsSavedPosts, MySiteSettings.DownloadSaved.Value, MySiteSettings.DownloadTimeline.Value)
|
||||
If fc And Not LastCursor.IsEmptyString Then
|
||||
Dim dt As Func(Of Boolean) = Function() (CBool(MySiteSettings.DownloadTimeline.Value) And GetTimeline) Or IsSavedPosts
|
||||
If dt.Invoke And Not LastCursor.IsEmptyString Then
|
||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||
DownloadData(LastCursor, s, Token)
|
||||
ThrowAny(Token)
|
||||
If Not HasError Then FirstLoadingDone = True
|
||||
End If
|
||||
If fc And Not HasError Then
|
||||
If dt.Invoke And Not HasError Then
|
||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||
DownloadData(String.Empty, s, Token)
|
||||
ThrowAny(Token)
|
||||
If Not HasError Then FirstLoadingDone = True
|
||||
End If
|
||||
If FirstLoadingDone Then LastCursor = String.Empty
|
||||
If IsSavedPosts Then
|
||||
If MySiteSettings.DownloadSaved Then s = Sections.SavedPosts : DownloadPosts(Token)
|
||||
ElseIf MySiteSettings.BaseAuthExists() Then
|
||||
DownloadedTags = 0
|
||||
If MySiteSettings.DownloadStoriesTagged And GetStories Then s = Sections.Stories : DownloadData(String.Empty, s, Token)
|
||||
If MySiteSettings.DownloadStoriesTagged And GetTaggedData Then s = Sections.Tagged : DownloadData(String.Empty, s, Token)
|
||||
If Not IsSavedPosts AndAlso MySiteSettings.BaseAuthExists() Then
|
||||
If CBool(MySiteSettings.DownloadStories.Value) And GetStories Then s = Sections.Stories : DownloadData(String.Empty, s, Token)
|
||||
If CBool(MySiteSettings.DownloadTagged.Value) And ACheck(MySiteSettings.HashTagged.Value) And GetTaggedData Then s = Sections.Tagged : DownloadData(String.Empty, s, Token)
|
||||
End If
|
||||
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
||||
Catch eex As ExitException
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, "[API.Instagram.UserData.DownloadDataF]", False, s)
|
||||
errorFound = True
|
||||
Throw ex
|
||||
Finally
|
||||
E560Thrown = False
|
||||
UpdateResponser()
|
||||
If Not errorFound Then LoadSavePostsKV(False)
|
||||
End Try
|
||||
End Sub
|
||||
Private _InstaHash As String = String.Empty
|
||||
Private Sub UpdateResponser()
|
||||
Try
|
||||
If _DownloadingInProgress AndAlso Not Responser Is Nothing AndAlso Not Responser.Disposed Then
|
||||
_DownloadingInProgress = False
|
||||
RemoveHandler Responser.ResponseReceived, AddressOf Responser_ResponseReceived
|
||||
Declarations.UpdateResponser(Responser, MySiteSettings.Responser)
|
||||
End If
|
||||
Catch
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub Responser_ResponseReceived(ByVal Sender As Object, ByVal e As EventArguments.WebDataResponse)
|
||||
Declarations.UpdateResponser(e, Responser)
|
||||
End Sub
|
||||
Private Enum Sections : Timeline : Tagged : Stories : SavedPosts : End Enum
|
||||
Private Const StoriesFolder As String = "Stories"
|
||||
Private Const TaggedFolder As String = "Tagged"
|
||||
@@ -145,7 +269,7 @@ Namespace API.Instagram
|
||||
"What do you want to do?", "Waiting for Instagram download...",
|
||||
{
|
||||
New MsgBoxButton("Wait") With {.ToolTip = "Wait and ask again when the error is found."},
|
||||
New MsgBoxButton("Wait (disable current") With {.ToolTip = "Wait and skip future prompts while downloading the current profile."},
|
||||
New MsgBoxButton("Wait (disable current)") With {.ToolTip = "Wait and skip future prompts while downloading the current profile."},
|
||||
New MsgBoxButton("Abort") With {.ToolTip = "Abort operation"},
|
||||
New MsgBoxButton("Wait (disable all)") With {.ToolTip = "Wait and skip future prompts while downloading the current session."}
|
||||
},
|
||||
@@ -157,7 +281,7 @@ Namespace API.Instagram
|
||||
Case Else : WaitNotificationMode = WNM.SkipTemp
|
||||
End Select
|
||||
End If
|
||||
If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until { .GetWaitDate().ToString(ParsersDataDateProvider)}"
|
||||
If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until { .GetWaitDate().ToString(DateTimeDefaultProvider)}"
|
||||
ProgressTempSet = True
|
||||
Return False
|
||||
Else
|
||||
@@ -180,13 +304,11 @@ Namespace API.Instagram
|
||||
#Region "Tags"
|
||||
Private TaggedChecked As Boolean = False
|
||||
Friend TaggedCheckSession As Boolean = True
|
||||
Private DownloadedTags As Integer = 0
|
||||
Private DownloadTagsLimit As Integer? = Nothing
|
||||
Private ReadOnly Property TaggedLimitsNotifications(Optional ByVal v As Integer? = Nothing) As Boolean
|
||||
Private ReadOnly Property TaggedLimitsNotifications(ByVal v As Integer) As Boolean
|
||||
Get
|
||||
Return Not TaggedChecked AndAlso TaggedCheckSession AndAlso
|
||||
CInt(MySiteSettings.TaggedNotifyLimit.Value) > 0 AndAlso
|
||||
(Not v.HasValue OrElse v.Value > CInt(MySiteSettings.TaggedNotifyLimit.Value))
|
||||
CInt(MySiteSettings.TaggedNotifyLimit.Value) > 0 AndAlso v > CInt(MySiteSettings.TaggedNotifyLimit.Value)
|
||||
End Get
|
||||
End Property
|
||||
Private Function SetTagsLimit(ByVal Max As Integer, ByVal p As ANumbers) As DialogResult
|
||||
@@ -219,8 +341,9 @@ Namespace API.Instagram
|
||||
End Function
|
||||
Private Function TaggedContinue(ByVal TaggedCount As Integer) As DialogResult
|
||||
Dim agi As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||
Dim msg As New MMessage($"The number of tagged posts by user [{ToString()}] is {TaggedCount.NumToString(agi)}" & vbCr &
|
||||
$"This is about {(TaggedCount / 12).RoundUp.NumToString(agi)} requests." & vbCr &
|
||||
Dim msg As New MMessage($"The number of already downloaded tagged posts by user [{ToString()}] is {TaggedCount.NumToString(agi)}" & vbCr &
|
||||
"There is currently no way to know how many posts exist." & vbCr &
|
||||
"One request will be spent per post." & vbCr &
|
||||
"The tagged data download operation can take a long time.",
|
||||
"Too much tagged data",
|
||||
{
|
||||
@@ -252,40 +375,45 @@ Namespace API.Instagram
|
||||
Dim URL$ = String.Empty
|
||||
Dim StoriesList As List(Of String) = Nothing
|
||||
Dim StoriesRequested As Boolean = False
|
||||
Dim _DownloadComplete As Boolean = False
|
||||
Dim dValue% = 1
|
||||
LastCursor = Cursor
|
||||
Try
|
||||
Do While Not _DownloadComplete
|
||||
Do While dValue = 1
|
||||
ThrowAny(Token)
|
||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||
ReconfigureAwaiter()
|
||||
|
||||
Try
|
||||
Dim n As EContainer, nn As EContainer, node As EContainer
|
||||
Dim n As EContainer, nn As EContainer
|
||||
Dim HasNextPage As Boolean = False
|
||||
Dim Pinned As Boolean
|
||||
Dim EndCursor$ = String.Empty
|
||||
Dim PostID$ = String.Empty, PostDate$ = String.Empty, SpecFolder$ = String.Empty
|
||||
Dim TaggedCount%
|
||||
Dim PostIDKV As PostKV
|
||||
Dim ENode() As Object = Nothing
|
||||
NextRequest(True)
|
||||
|
||||
'Check environment
|
||||
If Cursor.IsEmptyString And _InstaHash.IsEmptyString Then _
|
||||
_InstaHash = CStr(If(IsSavedPosts, MySiteSettings.HashSavedPosts, MySiteSettings.Hash).Value)
|
||||
If ID.IsEmptyString Then GetUserId()
|
||||
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
||||
If Not IsSavedPosts Then
|
||||
If ID.IsEmptyString Then GetUserId()
|
||||
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
||||
End If
|
||||
|
||||
'Create query
|
||||
Select Case Section
|
||||
Case Sections.Timeline, Sections.SavedPosts
|
||||
Case Sections.Timeline
|
||||
URL = $"https://www.instagram.com/api/v1/feed/user/{Name}/username/?count=50" &
|
||||
If(Cursor.IsEmptyString, String.Empty, $"&max_id={Cursor}")
|
||||
ENode = Nothing
|
||||
Case Sections.SavedPosts
|
||||
SavedPostsDownload(String.Empty, Token)
|
||||
Exit Sub
|
||||
Case Sections.Tagged
|
||||
Dim h$ = AConvert(Of String)(MySiteSettings.HashTagged.Value, String.Empty)
|
||||
If h.IsEmptyString Then Throw New ExitException
|
||||
Dim vars$ = "{""id"":" & ID & ",""first"":50,""after"":""" & Cursor & """}"
|
||||
vars = SymbolsConverter.ASCII.EncodeSymbolsOnly(vars)
|
||||
URL = $"https://www.instagram.com/graphql/query/?query_hash={_InstaHash}&variables={vars}"
|
||||
URL = $"https://www.instagram.com/graphql/query/?query_hash={h}&variables={vars}"
|
||||
ENode = {"data", "user", 0}
|
||||
Case Sections.Tagged
|
||||
URL = $"https://i.instagram.com/api/v1/usertags/{ID}/feed/?count=50&max_id={Cursor}"
|
||||
ENode = {"items"}
|
||||
SpecFolder = TaggedFolder
|
||||
Case Sections.Stories
|
||||
If Not StoriesRequested Then
|
||||
@@ -303,7 +431,7 @@ Namespace API.Instagram
|
||||
If StoriesList.ListExists Then
|
||||
Continue Do
|
||||
Else
|
||||
Throw New ExitException(_DownloadComplete)
|
||||
Throw New ExitException
|
||||
End If
|
||||
End Select
|
||||
|
||||
@@ -316,78 +444,74 @@ Namespace API.Instagram
|
||||
'Parsing
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
n = j.ItemF(ENode).XmlIfNothing
|
||||
n = If(ENode Is Nothing, j, j.ItemF(ENode)).XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
Select Case Section
|
||||
Case Sections.Timeline, Sections.SavedPosts
|
||||
If n.Contains("page_info") Then
|
||||
With n("page_info")
|
||||
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
||||
EndCursor = .Value("end_cursor")
|
||||
End With
|
||||
End If
|
||||
n = n("edges").XmlIfNothing
|
||||
If n.Count > 0 Then
|
||||
For Each nn In n
|
||||
ThrowAny(Token)
|
||||
node = nn(0).XmlIfNothing
|
||||
If IsSavedPosts Then
|
||||
PostID = node.Value("shortcode")
|
||||
If Not PostID.IsEmptyString AndAlso _TempPostsList.Contains(PostID) Then Throw New ExitException(_DownloadComplete)
|
||||
End If
|
||||
PostID = node.Value("id")
|
||||
Pinned = CBool(If(node("pinned_for_users")?.Count, 0))
|
||||
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) And Not Pinned Then Throw New ExitException(_DownloadComplete)
|
||||
_TempPostsList.Add(PostID)
|
||||
PostDate = node.Value("taken_at_timestamp")
|
||||
If IsSavedPosts Then
|
||||
_SavedPostsIDs.Add(PostID)
|
||||
Else
|
||||
Select Case CheckDatesLimit(PostDate, DateProvider)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : If Not Pinned Then Throw New ExitException(_DownloadComplete)
|
||||
End Select
|
||||
ObtainMedia(node, PostID, PostDate, SpecFolder)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Case Sections.Timeline
|
||||
With n
|
||||
HasNextPage = .Value("more_available").FromXML(Of Boolean)(False)
|
||||
EndCursor = .Value("next_max_id")
|
||||
If If(.Item("items")?.Count, 0) > 0 Then
|
||||
UserSiteNameUpdate(.ItemF({"items", 0, "user", "full_name"}).XmlIfNothingValue)
|
||||
If Not DefaultParser(.Item("items"), Section, Token) Then Throw New ExitException
|
||||
Else
|
||||
HasNextPage = False
|
||||
End If
|
||||
End With
|
||||
Case Sections.Tagged
|
||||
HasNextPage = j.Value("more_available").FromXML(Of Boolean)(False)
|
||||
EndCursor = j.Value("next_max_id")
|
||||
For Each nn In n
|
||||
PostID = $"Tagged_{nn.Value("id")}"
|
||||
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) Then Throw New ExitException(_DownloadComplete)
|
||||
_TempPostsList.Add(PostID)
|
||||
ObtainMedia2(nn, PostID, SpecFolder)
|
||||
DownloadedTags += 1
|
||||
If DownloadTagsLimit.HasValue AndAlso DownloadedTags >= DownloadTagsLimit.Value Then Throw New ExitException(_DownloadComplete)
|
||||
Next
|
||||
If TaggedLimitsNotifications Then
|
||||
TaggedCount = j.Value("total_count").FromXML(Of Integer)(0)
|
||||
With n
|
||||
If .Contains("page_info") Then
|
||||
With .Item("page_info")
|
||||
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
||||
EndCursor = .Value("end_cursor")
|
||||
End With
|
||||
Else
|
||||
HasNextPage = False
|
||||
End If
|
||||
If If(.Item("edges")?.Count, 0) > 0 Then
|
||||
For Each nn In .Item("edges")
|
||||
PostIDKV = New PostKV(Section)
|
||||
If nn.Count > 0 AndAlso nn(0).Count > 0 Then
|
||||
With nn(0)
|
||||
PostIDKV = New PostKV(.Value("shortcode"), .Value("id"), Section)
|
||||
If PostKvExists(PostIDKV) Then
|
||||
Throw New ExitException
|
||||
Else
|
||||
If Not DownloadTagsLimit.HasValue OrElse PostsToReparse.Count + 1 < DownloadTagsLimit.Value Then
|
||||
_TempPostsList.Add(GetPostIdBySection(PostIDKV.ID, Section))
|
||||
PostsKVIDs.ListAddValue(PostIDKV, LAP.NotContainsOnly)
|
||||
PostsToReparse.ListAddValue(PostIDKV, LNC)
|
||||
ElseIf DownloadTagsLimit.HasValue OrElse PostsToReparse.Count + 1 >= DownloadTagsLimit.Value Then
|
||||
Throw New ExitException
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
Next
|
||||
Else
|
||||
HasNextPage = False
|
||||
End If
|
||||
End With
|
||||
If TaggedLimitsNotifications(PostsToReparse.Count) Then
|
||||
TaggedChecked = True
|
||||
If TaggedLimitsNotifications(TaggedCount) AndAlso
|
||||
TaggedContinue(TaggedCount) = DialogResult.Cancel Then Throw New ExitException(_DownloadComplete)
|
||||
If TaggedContinue(PostsToReparse.Count) = DialogResult.Cancel Then Throw New ExitException
|
||||
End If
|
||||
End Select
|
||||
Else
|
||||
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso
|
||||
If j.Value("status") = "ok" AndAlso If(j("items")?.Count, 0) = 0 AndAlso
|
||||
_TempMediaList.Count = 0 AndAlso Section = Sections.Timeline Then _
|
||||
UserExists = False : Throw New ExitException(_DownloadComplete)
|
||||
UserExists = False : Throw New ExitException
|
||||
End If
|
||||
End Using
|
||||
Else
|
||||
Throw New ExitException(_DownloadComplete)
|
||||
Throw New ExitException
|
||||
End If
|
||||
_DownloadComplete = True
|
||||
dValue = 0
|
||||
If HasNextPage And Not EndCursor.IsEmptyString Then DownloadData(EndCursor, Section, Token)
|
||||
Catch eex As ExitException
|
||||
Throw eex
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Exit Do
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Exit Do
|
||||
Catch ex As Exception
|
||||
If DownloadingException(ex, $"data downloading error [{URL}]", False, Section) = 1 Then Continue Do Else Exit Do
|
||||
dValue = ProcessException(ex, Token, $"data downloading error [{URL}]",, Section, False)
|
||||
End Try
|
||||
Loop
|
||||
Catch eex2 As ExitException
|
||||
@@ -400,10 +524,10 @@ Namespace API.Instagram
|
||||
End Sub
|
||||
Private Sub DownloadPosts(ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Dim _DownloadComplete As Boolean = False
|
||||
Dim dValue% = 1
|
||||
Dim _Index% = 0
|
||||
Try
|
||||
Do While Not _DownloadComplete
|
||||
Do While dValue = 1
|
||||
ThrowAny(Token)
|
||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||
ReconfigureAwaiter()
|
||||
@@ -411,13 +535,11 @@ Namespace API.Instagram
|
||||
Try
|
||||
Dim r$
|
||||
Dim j As EContainer, jj As EContainer
|
||||
Dim _MediaObtained As Boolean
|
||||
If _SavedPostsIDs.Count > 0 And _Index <= _SavedPostsIDs.Count - 1 Then
|
||||
If PostsToReparse.Count > 0 And _Index <= PostsToReparse.Count - 1 Then
|
||||
Dim e As New ErrorsDescriber(EDP.ThrowException)
|
||||
For i% = _Index To _SavedPostsIDs.Count - 1
|
||||
For i% = _Index To PostsToReparse.Count - 1
|
||||
_Index = i
|
||||
'URL = $"https://instagram.com/p/{_SavedPostsIDs(i)}/?__a=1"
|
||||
URL = $"https://i.instagram.com/api/v1/media/{_SavedPostsIDs(i)}/info/"
|
||||
URL = $"https://www.instagram.com/api/v1/media/{PostsToReparse(i).ID}/info/"
|
||||
ThrowAny(Token)
|
||||
NextRequest(((i + 1) Mod 5) = 0)
|
||||
ThrowAny(Token)
|
||||
@@ -427,17 +549,9 @@ Namespace API.Instagram
|
||||
If Not r.IsEmptyString Then
|
||||
j = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing Then
|
||||
_MediaObtained = False
|
||||
If j.Contains({"graphql", "shortcode_media"}) Then
|
||||
With j({"graphql", "shortcode_media"}).XmlIfNothing
|
||||
If .Count > 0 Then ObtainMedia(.Self, _SavedPostsIDs(i), String.Empty, String.Empty) : _MediaObtained = True
|
||||
End With
|
||||
End If
|
||||
If Not _MediaObtained AndAlso j.Contains("items") Then
|
||||
If If(j("items")?.Count, 0) > 0 Then
|
||||
With j("items")
|
||||
If .Count > 0 Then
|
||||
For Each jj In .Self : ObtainMedia2(jj, _SavedPostsIDs(i)) : Next
|
||||
End If
|
||||
For Each jj In .Self : ObtainMedia(jj, PostsToReparse(i).ID) : Next
|
||||
End With
|
||||
End If
|
||||
j.Dispose()
|
||||
@@ -445,24 +559,82 @@ Namespace API.Instagram
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
_DownloadComplete = True
|
||||
dValue = 0
|
||||
Catch eex As ExitException
|
||||
Throw eex
|
||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||
Exit Do
|
||||
Catch dex As ObjectDisposedException When Disposed
|
||||
Exit Do
|
||||
Catch ex As Exception
|
||||
If DownloadingException(ex, $"downloading saved posts error [{URL}]", False, Sections.SavedPosts) = 1 Then Continue Do Else Exit Do
|
||||
dValue = ProcessException(ex, Token, $"downloading posts error [{URL}]",, Sections.Tagged, False)
|
||||
End Try
|
||||
Loop
|
||||
Catch eex2 As ExitException
|
||||
Catch oex2 As OperationCanceledException When Token.IsCancellationRequested Or oex2.HelpLink = InstAborted
|
||||
If oex2.HelpLink = InstAborted Then HasError = True
|
||||
Catch DoEx As Exception
|
||||
ProcessException(DoEx, Token, $"downloading saved posts error [{URL}]",, Sections.SavedPosts)
|
||||
ProcessException(DoEx, Token, $"downloading posts error [{URL}]",, Sections.Tagged)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub SavedPostsDownload(ByVal Cursor As String, ByVal Token As CancellationToken)
|
||||
Dim URL$ = $"https://www.instagram.com/api/v1/feed/saved/posts/?max_id={Cursor}"
|
||||
Dim HasNextPage As Boolean = False
|
||||
Dim NextCursor$ = String.Empty
|
||||
ThrowAny(Token)
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
Dim nodes As IEnumerable(Of EContainer) = Nothing
|
||||
If Not r.IsEmptyString Then
|
||||
Using e As EContainer = JsonDocument.Parse(r)
|
||||
If If(e?.Count, 0) > 0 Then
|
||||
With e
|
||||
HasNextPage = .Value("more_available").FromXML(Of Boolean)(False)
|
||||
NextCursor = .Value("next_max_id")
|
||||
If .Contains("items") Then nodes = (From ee As EContainer In .Item("items") Where ee.Count > 0 Select ee(0))
|
||||
End With
|
||||
If nodes.ListExists Then
|
||||
DefaultParser(nodes, Sections.SavedPosts, Token)
|
||||
If HasNextPage And Not NextCursor.IsEmptyString Then SavedPostsDownload(NextCursor, Token)
|
||||
End If
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
End Sub
|
||||
Private Function DefaultParser(ByVal Items As IEnumerable(Of EContainer), ByVal Section As Sections, ByVal Token As CancellationToken,
|
||||
Optional ByVal SpecFolder As String = Nothing) As Boolean
|
||||
ThrowAny(Token)
|
||||
If Items.Count > 0 Then
|
||||
Dim PostIDKV As PostKV
|
||||
Dim Pinned As Boolean
|
||||
Dim PostDate$
|
||||
If SpecFolder.IsEmptyString Then
|
||||
Select Case Section
|
||||
Case Sections.Tagged : SpecFolder = TaggedFolder
|
||||
Case Sections.Stories : SpecFolder = StoriesFolder
|
||||
Case Else : SpecFolder = String.Empty
|
||||
End Select
|
||||
End If
|
||||
For Each nn In Items
|
||||
With nn
|
||||
PostIDKV = New PostKV(.Value("code"), .Value("id"), Section)
|
||||
Pinned = .Contains("timeline_pinned_user_ids")
|
||||
If PostKvExists(PostIDKV) Then
|
||||
If Not Pinned Then Return False
|
||||
Else
|
||||
_TempPostsList.Add(PostIDKV.ID)
|
||||
PostsKVIDs.ListAddValue(PostIDKV, LNC)
|
||||
PostDate = .Value("taken_at")
|
||||
If Not IsSavedPosts Then
|
||||
Select Case CheckDatesLimit(PostDate, DateProvider)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : If Not Pinned Then Return False
|
||||
End Select
|
||||
End If
|
||||
ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate)
|
||||
End If
|
||||
End With
|
||||
Next
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Code ID converters"
|
||||
Private Shared Function CodeToID(ByVal Code As String) As String
|
||||
@@ -485,25 +657,7 @@ Namespace API.Instagram
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Obtain Media"
|
||||
Private Sub ObtainMedia(ByVal node As EContainer, ByVal PostID As String, ByVal PostDate As String, ByVal SpecFolder As String)
|
||||
Dim CreateMedia As Action(Of EContainer) =
|
||||
Sub(ByVal e As EContainer)
|
||||
Dim t As UTypes = If(e.Value("is_video").FromXML(Of Boolean)(False), UTypes.Video, UTypes.Picture)
|
||||
Dim tmpValue$
|
||||
If t = UTypes.Picture Then
|
||||
tmpValue = e.Value("display_url")
|
||||
Else
|
||||
tmpValue = e.Value("video_url")
|
||||
End If
|
||||
If Not tmpValue.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(t, tmpValue, PostID, PostDate, SpecFolder), LNC)
|
||||
End Sub
|
||||
If node.Contains({"edge_sidecar_to_children", "edges"}) Then
|
||||
For Each edge As EContainer In node({"edge_sidecar_to_children", "edges"}) : CreateMedia(edge("node").XmlIfNothing) : Next
|
||||
Else
|
||||
CreateMedia(node)
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String, Optional ByVal SpecialFolder As String = Nothing,
|
||||
Private Sub ObtainMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal SpecialFolder As String = Nothing,
|
||||
Optional ByVal DateObj As String = Nothing)
|
||||
Try
|
||||
Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0
|
||||
@@ -575,7 +729,7 @@ Namespace API.Instagram
|
||||
DateObj = mDate(n)
|
||||
With n("carousel_media").XmlIfNothing
|
||||
If .Count > 0 Then
|
||||
For Each d In .Self : ObtainMedia2(d, PostID, SpecialFolder, DateObj) : Next
|
||||
For Each d In .Self : ObtainMedia(d, PostID, SpecialFolder, DateObj) : Next
|
||||
End If
|
||||
End With
|
||||
End Select
|
||||
@@ -588,35 +742,41 @@ Namespace API.Instagram
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "GetUserId"
|
||||
<Obsolete> Private Sub GetUserId_Old()
|
||||
Try
|
||||
Dim r$ = Responser.GetResponse($"https://www.instagram.com/{Name}/?__a=1",, EDP.ThrowException)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
ID = j({"graphql", "user"}, "id").XmlIfNothingValue
|
||||
End Using
|
||||
End If
|
||||
Catch ex As Exception
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
Throw ex
|
||||
Else
|
||||
LogError(ex, "get Instagram user id")
|
||||
End If
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub GetUserId()
|
||||
Dim __idFound As Boolean = False
|
||||
Try
|
||||
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/users/web_profile_info/?username={Name}",, EDP.ThrowException)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
ID = j({"data", "user"}, "id").XmlIfNothingValue
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing AndAlso j.Contains({"data", "user"}) Then
|
||||
With j({"data", "user"})
|
||||
ID = .Value("id")
|
||||
__idFound = True
|
||||
UserSiteNameUpdate(.Value("full_name"))
|
||||
Dim descr$ = .Value("biography")
|
||||
If If(.Item("bio_links")?.Count, 0) > 0 Then descr.StringAppend(.Item("bio_links").Select(Function(bl) bl.Value("url")).ListToString(vbNewLine), vbNewLine)
|
||||
Dim eUrl$ = .Value("external_url")
|
||||
If Not eUrl.IsEmptyString AndAlso (descr.IsEmptyString OrElse Not descr.Contains(eUrl)) Then descr.StringAppendLine(eUrl)
|
||||
UserDescriptionUpdate(descr)
|
||||
Dim f As New SFile With {.Path = MyFile.CutPath.Path, .Name = "ProfilePicture", .Extension = "jpg"}
|
||||
If Not f.Exists Then
|
||||
Dim profilePicture$ = .Value("profile_pic_url_hd")
|
||||
If profilePicture.IsEmptyString OrElse Not GetWebFile(profilePicture, f, EDP.ReturnValue) Then
|
||||
profilePicture = .Value("profile_pic_url")
|
||||
If Not profilePicture.IsEmptyString Then GetWebFile(profilePicture, f, EDP.ReturnValue)
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
Catch ex As Exception
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
Throw ex
|
||||
Else
|
||||
LogError(ex, "get Instagram user id")
|
||||
If Not __idFound Then
|
||||
If Responser.StatusCode = HttpStatusCode.NotFound Or Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||
Throw ex
|
||||
Else
|
||||
LogError(ex, "get Instagram user id")
|
||||
End If
|
||||
End If
|
||||
End Try
|
||||
End Sub
|
||||
@@ -652,7 +812,7 @@ Namespace API.Instagram
|
||||
pid = storyID & s.Value("id")
|
||||
If Not _TempPostsList.Contains(pid) Then
|
||||
ThrowAny(Token)
|
||||
ObtainMedia2(s, pid, sFolder)
|
||||
ObtainMedia(s, pid, sFolder)
|
||||
_TempPostsList.Add(pid)
|
||||
End If
|
||||
Next
|
||||
@@ -731,8 +891,7 @@ Namespace API.Instagram
|
||||
Dim s As Sections = DirectCast(Section, Sections)
|
||||
Select Case s
|
||||
Case Sections.Timeline : MySiteSettings.DownloadTimeline.Value = False
|
||||
Case Sections.SavedPosts : MySiteSettings.DownloadSaved.Value = False
|
||||
Case Else : MySiteSettings.DownloadStoriesTagged.Value = False
|
||||
Case Else : MySiteSettings.DownloadTagged.Value = False
|
||||
End Select
|
||||
MyMainLOG = $"[{s}] downloading is disabled until you update your credentials".ToUpper
|
||||
End If
|
||||
@@ -750,7 +909,7 @@ Namespace API.Instagram
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Standalone downloader"
|
||||
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 Responser) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then
|
||||
Dim PID$ = RegexReplace(URL, RParams.DMS(".*?instagram.com/p/([_\w\d]+)", 1))
|
||||
@@ -758,9 +917,9 @@ Namespace API.Instagram
|
||||
If Not PID.IsEmptyString Then
|
||||
Using t As New UserData
|
||||
t.SetEnvironment(Settings(InstagramSiteKey), Nothing, False, False)
|
||||
t.Responser = New Response
|
||||
t.Responser = New Responser
|
||||
t.Responser.Copy(r)
|
||||
t._SavedPostsIDs.Add(PID)
|
||||
t.PostsToReparse.Add(New PostKV With {.ID = PID})
|
||||
t.DownloadPosts(Nothing)
|
||||
Return ListAddList(Nothing, t._TempMediaList)
|
||||
End Using
|
||||
@@ -774,7 +933,13 @@ Namespace API.Instagram
|
||||
#End Region
|
||||
#Region "IDisposable Support"
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then _SavedPostsIDs.Clear()
|
||||
If Not disposedValue Then
|
||||
UpdateResponser()
|
||||
If disposing Then
|
||||
PostsKVIDs.Clear()
|
||||
PostsToReparse.Clear()
|
||||
End If
|
||||
End If
|
||||
MyBase.Dispose(disposing)
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
@@ -31,7 +31,7 @@ Namespace API.LPSG
|
||||
Return New UserData
|
||||
End Function
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||
Return If(Responser.Cookies?.Count, 0) > 0
|
||||
Return Responser.CookiesExists
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -88,7 +88,7 @@ Namespace API.LPSG
|
||||
End If
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
With Responser : .Mode = Response.Modes.WebClient : .ResetStatus() : End With
|
||||
With Responser : .Mode = Responser.Modes.WebClient : .ResetStatus() : End With
|
||||
UseResponserClient = True
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
|
||||
14
SCrawler/API/PathPlugin/Declarations.vb
Normal file
@@ -0,0 +1,14 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.PathPlugin
|
||||
Friend Module Declarations
|
||||
Friend Const PluginKey As String = "AndyProgram_PathPlugin"
|
||||
Friend Const PluginName As String = "Path"
|
||||
End Module
|
||||
End Namespace
|
||||
49
SCrawler/API/PathPlugin/SiteSettings.vb
Normal file
@@ -0,0 +1,49 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.PathPlugin
|
||||
<Manifest(PluginKey)>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||
Friend Overrides ReadOnly Property Icon As Icon
|
||||
Get
|
||||
Return PersonalUtilities.Tools.ImageRenderer.GetIcon(PersonalUtilities.My.Resources.FolderOpenPic_Orange_16, EDP.ReturnValue)
|
||||
End Get
|
||||
End Property
|
||||
Friend Overrides ReadOnly Property Image As Image
|
||||
Get
|
||||
Return PersonalUtilities.My.Resources.FolderOpenPic_Orange_16
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub New()
|
||||
MyBase.New(PluginName)
|
||||
End Sub
|
||||
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
|
||||
Return New UserData
|
||||
End Function
|
||||
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||
Dim f As SFile = UserURL
|
||||
If Not f.IsEmptyString AndAlso f.PathNoSeparator = UserURL.StringTrimEnd("\") AndAlso (f.Location = SFOLocation.Local Or f.Location = SFOLocation.Network) Then
|
||||
Return New ExchangeOptions(Site, f)
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Function
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||
Return False
|
||||
End Function
|
||||
Friend Overrides Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
|
||||
Return Nothing
|
||||
End Function
|
||||
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String
|
||||
Return String.Empty
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
45
SCrawler/API/PathPlugin/UserData.vb
Normal file
@@ -0,0 +1,45 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Namespace API.PathPlugin
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Private Const DOWNLOAD_ERROR As String = "The path plugin only provides user paths."
|
||||
Friend Overrides Property UserExists As Boolean
|
||||
Get
|
||||
Return FileExists
|
||||
End Get
|
||||
Set(ByVal e As Boolean)
|
||||
MyBase.UserExists = e
|
||||
End Set
|
||||
End Property
|
||||
Friend Overrides Property UserSuspended As Boolean
|
||||
Get
|
||||
Return False
|
||||
End Get
|
||||
Set(ByVal s As Boolean)
|
||||
MyBase.UserSuspended = s
|
||||
End Set
|
||||
End Property
|
||||
Friend Overrides Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing)
|
||||
OpenFolder()
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XML.XmlFile, ByVal Loading As Boolean)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As Threading.CancellationToken)
|
||||
Throw New InvalidOperationException(DOWNLOAD_ERROR)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As Threading.CancellationToken)
|
||||
Throw New InvalidOperationException(DOWNLOAD_ERROR)
|
||||
End Sub
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
||||
Optional ByVal EObj As Object = Nothing) As Integer
|
||||
Throw New InvalidOperationException(DOWNLOAD_ERROR)
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -11,7 +11,6 @@ Namespace API.PornHub
|
||||
Friend Module Declarations
|
||||
#Region "Converters"
|
||||
Private ReadOnly UnicodeHexConverter As Func(Of String, String) = Function(Input) SymbolsConverter.UnicodeHex.Decode(Input, EDP.ReturnValue)
|
||||
Friend ReadOnly HtmlConverter As Func(Of String, String) = Function(Input) SymbolsConverter.HTML.Decode(Input, EDP.ReturnValue)
|
||||
#End Region
|
||||
#Region "Declarations video"
|
||||
Friend ReadOnly RegexVideo_FlashVarsBlock As RParams = RParams.DM("(?<=flashvars_\['[nN]ext[vV]ideo'\];[\r\n]*?)(.+?)(?=;flashvars_\d+?)", 0, EDP.ReturnValue)
|
||||
|
||||
@@ -14,7 +14,7 @@ Namespace API.PornHub
|
||||
Friend NotInheritable Class M3U8
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Private Shared Function GetUrlsList(ByVal URL As String, ByVal Responser As Response) As List(Of String)
|
||||
Private Shared Function GetUrlsList(ByVal URL As String, ByVal Responser As Responser) As List(Of String)
|
||||
Dim appender$ = RegexReplace(URL, Regex_M3U8_FileUrl)
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
If Not r.IsEmptyString Then
|
||||
@@ -35,7 +35,7 @@ Namespace API.PornHub
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
Friend Shared Function Download(ByVal URL As String, ByVal Responser As Response, ByVal Destination As SFile) As SFile
|
||||
Friend Shared Function Download(ByVal URL As String, ByVal Responser As Responser, ByVal Destination As SFile) As SFile
|
||||
Return M3U8Base.Download(GetUrlsList(URL, Responser), Destination, Responser)
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -41,6 +41,7 @@ Namespace API.PornHub
|
||||
Friend Sub New()
|
||||
MyBase.New("PornHub", "pornhub.com")
|
||||
Responser.CurlPath = $"cURL\curl.exe"
|
||||
Responser.CurlArgumentsRight = "--ssl-no-revoke"
|
||||
CurlPathExists = Responser.CurlPath.Exists
|
||||
Responser.DeclaredError = EDP.ThrowException
|
||||
|
||||
@@ -69,7 +70,7 @@ Namespace API.PornHub
|
||||
End Function
|
||||
Friend Overrides Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable
|
||||
If Available(ISiteSettings.Download.Main, True) Then
|
||||
Using resp As Response = Responser.Copy
|
||||
Using resp As Responser = Responser.Copy
|
||||
Dim spf$ = String.Empty
|
||||
Dim f As SFile = GetSpecialDataFile(Path, AskForPath, spf)
|
||||
Dim m As UserMedia = UserData.GetVideoInfo(URL, resp, f)
|
||||
@@ -105,17 +106,14 @@ Namespace API.PornHub
|
||||
With DirectCast(User, UserData) : Return String.Format(UrlPatternUser, .PersonType, .NameTrue) : End With
|
||||
End Function
|
||||
Friend Overrides Function GetUserPostUrl(ByVal User As UserDataBase, ByVal Media As UserMedia) As String
|
||||
'TODELETE: remove comment
|
||||
Return Media.URL_BASE '$"https://www.pornhub.com/view_video.php?viewkey={Media.Post.ID}"
|
||||
Return Media.URL_BASE
|
||||
End Function
|
||||
#End Region
|
||||
#Region "User options"
|
||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||
Dim e As UserExchangeOptions = Nothing
|
||||
If Not Options Is Nothing AndAlso TypeOf Options Is UserExchangeOptions Then e = Options
|
||||
If e Is Nothing Then e = New UserExchangeOptions(Me)
|
||||
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions(Me)
|
||||
If OpenForm Then
|
||||
Using f As New OptionsForm(e) : f.ShowDialog() : End Using
|
||||
Using f As New OptionsForm(Options) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
@@ -59,7 +59,7 @@ Namespace API.PornHub
|
||||
URL = ParamsArray(0)
|
||||
ID = RegexReplace(URL, RegexVideo_Video_VideoKey)
|
||||
URL = String.Format(UrlPattern, URL.TrimStart("/"))
|
||||
Title = HtmlConverter(ParamsArray(1)).StringRemoveWinForbiddenSymbols.StringTrim
|
||||
Title = TitleHtmlConverter(ParamsArray(1))
|
||||
End If
|
||||
Return Me
|
||||
End Function
|
||||
@@ -99,7 +99,6 @@ Namespace API.PornHub
|
||||
#Region "Person"
|
||||
Friend Property PersonType As String
|
||||
Friend Property NameTrue As String
|
||||
Private _FriendlyName As String = String.Empty
|
||||
Friend Overrides Property FriendlyName As String
|
||||
Get
|
||||
If _FriendlyName.IsEmptyString Then Return NameTrue Else Return _FriendlyName
|
||||
@@ -178,7 +177,7 @@ Namespace API.PornHub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
Try
|
||||
Responser.ResetStatus()
|
||||
If PersonType = PersonTypeUser Then Responser.Mode = Response.Modes.Curl
|
||||
If PersonType = PersonTypeUser Then Responser.Mode = Responser.Modes.Curl
|
||||
|
||||
If IsSavedPosts Then VideoPageModel = VideoPageModels.Favorite
|
||||
|
||||
@@ -187,7 +186,7 @@ Namespace API.PornHub
|
||||
Dim __videoDone As Boolean = False
|
||||
Dim d%
|
||||
If DownloadVideos Then
|
||||
If PersonType = PersonTypeUser Then Responser.Mode = Response.Modes.Curl : Responser.Method = "POST"
|
||||
If PersonType = PersonTypeUser Then Responser.Mode = Responser.Modes.Curl : Responser.Method = "POST"
|
||||
If VideoPageModel = VideoPageModels.Undefined Then
|
||||
__continue = False
|
||||
d = DownloadUserVideos(page, Token)
|
||||
@@ -210,13 +209,14 @@ Namespace API.PornHub
|
||||
If __continue And Not __videoDone Then
|
||||
Do While DownloadUserVideos(page, Token) = DataDownloaded And page < 100 : page += 1 : Loop
|
||||
End If
|
||||
If _TempMediaList.Count > 0 Then _TempMediaList.RemoveAll(Function(m) Not m.Type = UTypes.m3u8 And Not m.Type = UTypes.VideoPre)
|
||||
End If
|
||||
|
||||
Responser.Method = "GET"
|
||||
If DownloadGifs And Not IsSavedPosts Then DownloadUserGifs(Token)
|
||||
If DownloadImages Then DownloadUserPhotos(Token)
|
||||
Finally
|
||||
Responser.Mode = Response.Modes.Default
|
||||
Responser.Mode = Responser.Modes.Default
|
||||
Responser.Method = "GET"
|
||||
End Try
|
||||
End Sub
|
||||
@@ -256,7 +256,7 @@ Namespace API.PornHub
|
||||
If PersonType = PersonTypeUser And r.Contains(HtmlPageNotFoundVideo) Then Return DataDownloaded_NotFound
|
||||
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexVideo_Video_All}, {1, 2})
|
||||
Dim lw As List(Of UserVideo) = Nothing
|
||||
If Not PersonType = PersonTypeUser Then RegexFields(Of UserVideo)(r, {RegexVideo_Video_Wrong}, RegexVideo_Video_Wrong_Fields)
|
||||
If Not PersonType = PersonTypeUser Then lw = RegexFields(Of UserVideo)(r, {RegexVideo_Video_Wrong}, RegexVideo_Video_Wrong_Fields)
|
||||
If l.ListExists Then
|
||||
If lw.ListExists Then l.ListWithRemove(lw)
|
||||
If l.Count > 0 Then
|
||||
@@ -314,7 +314,7 @@ Namespace API.PornHub
|
||||
If l3.ListExists(3) Then
|
||||
m.URL = l3(2)
|
||||
m.File = m.URL
|
||||
n = HtmlConverter(l3(1)).StringRemoveWinForbiddenSymbols.StringTrim
|
||||
n = TitleHtmlConverter(l3(1))
|
||||
If MySettings.DownloadGifsAsMp4.Value Then m.File.Extension = "mp4"
|
||||
If Not n.IsEmptyString Then m.File.Name = n
|
||||
End If
|
||||
@@ -346,12 +346,12 @@ Namespace API.PornHub
|
||||
If PhotoPageModel = PhotoPageModels.Undefined Then
|
||||
If DownloadUserPhotos_ModelHub(Token) Then PhotoPageModel = PhotoPageModels.ModelHubPage
|
||||
ThrowAny(Token)
|
||||
If PhotoPageModel = PhotoPageModels.Undefined AndAlso DownloadPhotoOnlyFromModelHub AndAlso
|
||||
If PhotoPageModel = PhotoPageModels.Undefined AndAlso Not DownloadPhotoOnlyFromModelHub AndAlso
|
||||
DownloadUserPhotos_PornHub(Token) Then PhotoPageModel = PhotoPageModels.PornHubPage
|
||||
Else
|
||||
Select Case PhotoPageModel
|
||||
Case PhotoPageModels.ModelHubPage : DownloadUserPhotos_ModelHub(Token)
|
||||
Case PhotoPageModels.PornHubPage : If DownloadPhotoOnlyFromModelHub Then DownloadUserPhotos_PornHub(Token)
|
||||
Case PhotoPageModels.PornHubPage : If Not DownloadPhotoOnlyFromModelHub Then DownloadUserPhotos_PornHub(Token)
|
||||
End Select
|
||||
End If
|
||||
ElseIf Not DownloadPhotoOnlyFromModelHub Then
|
||||
@@ -359,7 +359,7 @@ Namespace API.PornHub
|
||||
End If
|
||||
ThrowAny(Token)
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"photos downloading error")
|
||||
ProcessException(ex, Token, "photos downloading error")
|
||||
End Try
|
||||
End Sub
|
||||
Private Function DownloadUserPhotos_ModelHub(ByVal Token As CancellationToken) As Boolean
|
||||
@@ -415,7 +415,7 @@ Namespace API.PornHub
|
||||
If albumName.IsEmptyString Then
|
||||
albumName = block.AlbumID.Split("/").LastOrDefault.StringTrim
|
||||
Else
|
||||
albumName = HtmlConverter(albumName).StringRemoveWinForbiddenSymbols.StringTrim
|
||||
albumName = TitleHtmlConverter(albumName)
|
||||
End If
|
||||
page = 1
|
||||
Do While DownloadUserPhotos_PornHub(page, block.AlbumID, albumName, Token) : page += 1 : Loop
|
||||
@@ -624,7 +624,7 @@ Namespace API.PornHub
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Standalone downloader"
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Response, ByVal Destination As SFile) As UserMedia
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Responser, ByVal Destination As SFile) As UserMedia
|
||||
Try
|
||||
Dim r$ = Responser.Curl(URL)
|
||||
If Not r.IsEmptyString Then
|
||||
|
||||
@@ -32,8 +32,9 @@ Namespace API.Reddit
|
||||
Friend Sub New()
|
||||
MyBase.New(RedditSite, "reddit.com")
|
||||
With Responser
|
||||
If .Decoders.Count = 0 OrElse Not .Decoders.Contains(SymbolsConverter.Converters.Unicode) Then _
|
||||
.Decoders.Add(SymbolsConverter.Converters.Unicode) : .SaveSettings()
|
||||
Dim d% = .Decoders.Count
|
||||
.Decoders.ListAddList({SymbolsConverter.Converters.Unicode, SymbolsConverter.Converters.HTML}, LAP.NotContainsOnly)
|
||||
If d <> .Decoders.Count Then .SaveSettings()
|
||||
End With
|
||||
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
|
||||
UseM3U8 = New PropertyValue(True)
|
||||
|
||||
@@ -132,11 +132,11 @@ Namespace API.Reddit
|
||||
#End Region
|
||||
#Region "Download Overrides"
|
||||
Friend Overrides Sub DownloadData(ByVal Token As CancellationToken)
|
||||
UserDescriptionReset()
|
||||
_CrossPosts.Clear()
|
||||
If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo Is Nothing) Then
|
||||
EnvirDownloadSet()
|
||||
If Not Responser Is Nothing Then Responser.Dispose()
|
||||
Responser = New Response
|
||||
Responser = New Responser
|
||||
Responser.Copy(MySiteSettings.Responser)
|
||||
ChannelPostsNames.ListAddList(ChannelInfo.PostsAll.Select(Function(p) p.ID), LNC)
|
||||
If Not ViewMode = CView.New Then ChannelPostsNames.ListAddList(ChannelInfo.PostsNames, LNC)
|
||||
@@ -165,12 +165,15 @@ Namespace API.Reddit
|
||||
End With
|
||||
End If
|
||||
If DownloadTopCount.HasValue Then DownloadLimitCount = DownloadTopCount
|
||||
Else
|
||||
GetUserInfo()
|
||||
End If
|
||||
If SaveToCache AndAlso Not Responser.Decoders.Contains(SymbolsConverter.Converters.HTML) Then _
|
||||
Responser.Decoders.Add(SymbolsConverter.Converters.HTML)
|
||||
DownloadDataChannel(String.Empty, Token)
|
||||
If ChannelInfo Is Nothing Then _TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC)
|
||||
Else
|
||||
GetUserInfo()
|
||||
DownloadDataUser(String.Empty, Token)
|
||||
End If
|
||||
End Sub
|
||||
@@ -205,7 +208,8 @@ Namespace API.Reddit
|
||||
If Not r.IsEmptyString Then
|
||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If w.Count > 0 Then
|
||||
If UserDescriptionNeedToUpdate() Then UserDescriptionUpdate(w.ItemF({"subredditAboutInfo", 0, "publicDescription"}).XmlIfNothingValue)
|
||||
'TODELETE: moved to 'GetUserInfo' 2023.2.5.0
|
||||
'If UserDescriptionNeedToUpdate() Then UserDescriptionUpdate(w.ItemF({"subredditAboutInfo", 0, "publicDescription"}).XmlIfNothingValue)
|
||||
n = w.GetNode(JsonNodesJson)
|
||||
If Not n Is Nothing AndAlso n.Count > 0 Then
|
||||
For Each nn In n
|
||||
@@ -416,6 +420,37 @@ Namespace API.Reddit
|
||||
ProcessException(ex, Token, $"channel data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub GetUserInfo()
|
||||
Try
|
||||
If Not IsSavedPosts And ChannelInfo Is Nothing Then
|
||||
Dim r$ = Responser.GetResponse($"https://reddit.com/{IIf(IsChannel, "r", "user")}/{Name}/about.json",, EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing AndAlso j.Contains({"data", "subreddit"}) Then
|
||||
With j({"data", "subreddit"})
|
||||
UserSiteNameUpdate(.Value("title"))
|
||||
UserDescriptionUpdate(.Value("public_description"))
|
||||
Dim dir As SFile = MyFile.CutPath
|
||||
Dim __getFile As Action(Of String) = Sub(ByVal img As String)
|
||||
If Not img.IsEmptyString Then
|
||||
Dim f As SFile = UrlToFile(img)
|
||||
If Not f.Name.IsEmptyString Then
|
||||
If f.Extension.IsEmptyString Then f.Extension = "jpg"
|
||||
f.Path = dir.Path
|
||||
If Not f.Exists Then GetWebFile(img, f, EDP.ReturnValue)
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
__getFile.Invoke(.Value("icon_img"))
|
||||
__getFile.Invoke(.Value("banner_img"))
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download Base Functions"
|
||||
Private Function CreateImgurMedia(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||
@@ -524,7 +559,7 @@ Namespace API.Reddit
|
||||
End Try
|
||||
End Function
|
||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||
Dim RedGifsResponser As Response = Nothing
|
||||
Dim RedGifsResponser As Responser = Nothing
|
||||
Try
|
||||
ThrowAny(Token)
|
||||
Const v2 As UTypes = UTypes.VideoPre + UTypes.m3u8
|
||||
@@ -533,31 +568,36 @@ Namespace API.Reddit
|
||||
Dim e As New ErrorsDescriber(EDP.ReturnValue)
|
||||
Dim m As UserMedia, m2 As UserMedia
|
||||
Dim RedGifsHost As SettingsHost = Settings(RedGifs.RedGifsSiteKey)
|
||||
Dim _repeatForRedgifs As Boolean
|
||||
RedGifsResponser = RedGifsHost.Responser.Copy
|
||||
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
||||
ThrowAny(Token)
|
||||
If _TempMediaList(i).Type = UTypes.VideoPre Or _TempMediaList(i).Type = v2 Then
|
||||
m = _TempMediaList(i)
|
||||
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||
If m.URL.Contains($"{SiteGfycatKey}.com") Then
|
||||
r = Gfycat.Envir.GetVideo(m.URL)
|
||||
ElseIf m.URL.Contains(SiteRedGifsKey) Then
|
||||
m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost)
|
||||
If m2.State = UStates.Missing Then
|
||||
m.State = UStates.Missing
|
||||
_ContentList.Add(m)
|
||||
_TempMediaList.RemoveAt(i)
|
||||
ElseIf m2.State = RedGifs.UserData.DataGone Then
|
||||
_TempMediaList.RemoveAt(i)
|
||||
Do
|
||||
_repeatForRedgifs = False
|
||||
If m.URL.Contains($"{SiteGfycatKey}.com") Then
|
||||
r = Gfycat.Envir.GetVideo(m.URL)
|
||||
If Not r.IsEmptyString AndAlso r.Contains("redgifs.com") Then m.URL = r : _repeatForRedgifs = True
|
||||
ElseIf m.URL.Contains(SiteRedGifsKey) Then
|
||||
m2 = RedGifs.UserData.GetDataFromUrlId(m.URL, False, RedGifsResponser, RedGifsHost)
|
||||
If m2.State = UStates.Missing Then
|
||||
m.State = UStates.Missing
|
||||
_ContentList.Add(m)
|
||||
_TempMediaList.RemoveAt(i)
|
||||
ElseIf m2.State = RedGifs.UserData.DataGone Then
|
||||
_TempMediaList.RemoveAt(i)
|
||||
Else
|
||||
m2.URL_BASE = m.URL
|
||||
m2.Post = m.Post
|
||||
_TempMediaList(i) = m2
|
||||
End If
|
||||
Continue For
|
||||
Else
|
||||
m2.URL_BASE = m.URL
|
||||
m2.Post = m.Post
|
||||
_TempMediaList(i) = m2
|
||||
r = Responser.GetResponse(m.URL,, e)
|
||||
End If
|
||||
Continue For
|
||||
Else
|
||||
r = Responser.GetResponse(m.URL,, e)
|
||||
End If
|
||||
Loop While _repeatForRedgifs
|
||||
Else
|
||||
r = m.URL
|
||||
End If
|
||||
@@ -581,7 +621,7 @@ Namespace API.Reddit
|
||||
End Sub
|
||||
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||
Dim rList As New List(Of Integer)
|
||||
Dim RedGifsResponser As Response = Nothing
|
||||
Dim RedGifsResponser As Responser = Nothing
|
||||
Try
|
||||
If Not ChannelInfo Is Nothing Or SaveToCache Then Exit Sub
|
||||
If ContentMissingExists Then
|
||||
@@ -658,11 +698,12 @@ Namespace API.Reddit
|
||||
Public Overrides Sub Perform(Optional ByVal Value As Double = 1)
|
||||
End Sub
|
||||
End Class
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Response, ByVal f As SFile, ByVal SpecialFolder As String) As IEnumerable(Of UserMedia)
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Responser, ByVal f As SFile, ByVal SpecialFolder As String) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If Not URL.IsEmptyString Then
|
||||
Using r As New UserData
|
||||
r.Responser = New Response
|
||||
r.SetEnvironment(Settings(RedditSiteKey), Nothing, False, False)
|
||||
r.Responser = New Responser
|
||||
r.Responser.Copy(resp)
|
||||
r.ParsePost(URL)
|
||||
If r._TempMediaList.Count > 0 Then
|
||||
@@ -713,7 +754,7 @@ Namespace API.Reddit
|
||||
End Function
|
||||
#End Region
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
Dim RedGifsResponser As Response = Nothing
|
||||
Dim RedGifsResponser As Responser = Nothing
|
||||
Try
|
||||
Const _RFN$ = "RedditVideo"
|
||||
Const RFN$ = _RFN & "{0}"
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
@@ -30,36 +30,53 @@ Namespace API.RedGifs
|
||||
Return My.Resources.SiteResources.RedGifsPic_32
|
||||
End Get
|
||||
End Property
|
||||
<PropertyOption(AllowNull:=False, ControlText:="Token", ControlToolTip:="Bearer token")>
|
||||
Friend Property Token As PropertyValue
|
||||
<PXML> Friend Property TokenLastDateUpdated As PropertyValue
|
||||
<DoNotUse> Friend ReadOnly Property NoCredentialsResponser As Response
|
||||
<PropertyOption(ControlToolTip:="Bearer token", AllowNull:=False), ControlNumber(1)>
|
||||
Friend ReadOnly Property Token As PropertyValue
|
||||
<PXML> Friend ReadOnly Property TokenLastDateUpdated As PropertyValue
|
||||
Private Const TokenName As String = "authorization"
|
||||
#Region "TokenUpdateInterval"
|
||||
<PropertyOption(ControlText:="Token refresh interval", ControlToolTip:="Interval (in minutes) to refresh the token", AllowNull:=False, LeftOffset:=120),
|
||||
PXML, ControlNumber(0)>
|
||||
Friend ReadOnly Property TokenUpdateInterval As PropertyValue
|
||||
Private Class TokenIntervalProvider : 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 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
|
||||
TypeError = False
|
||||
ErrorMessage = String.Empty
|
||||
If Not ACheck(Of Integer)(Value) Then
|
||||
TypeError = True
|
||||
ElseIf CInt(Value) > 0 Then
|
||||
Return Value
|
||||
Else
|
||||
ErrorMessage = $"The value of [{Name}] field must be greater than or equal to 1"
|
||||
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 the context of [TokenIntervalProvider]")
|
||||
End Function
|
||||
End Class
|
||||
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
|
||||
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New()
|
||||
MyBase.New(RedGifsSite, "redgifs.com")
|
||||
Dim t$ = String.Empty
|
||||
With Responser
|
||||
Dim b As Boolean = Not .Mode = Response.Modes.WebClient
|
||||
.Mode = Response.Modes.WebClient
|
||||
t = .HeadersValue(TokenName)
|
||||
Dim b As Boolean = Not .Mode = Responser.Modes.WebClient
|
||||
.Mode = Responser.Modes.WebClient
|
||||
t = .Headers.Value(TokenName)
|
||||
If b Then .SaveSettings()
|
||||
End With
|
||||
NoCredentialsResponser = New Response($"{SettingsFolderName}\Responser_{RedGifsSite}_NC.xml") With {
|
||||
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey,
|
||||
.CookiesDomain = "redgifs.com"
|
||||
}
|
||||
With NoCredentialsResponser
|
||||
If .File.Exists Then
|
||||
.LoadSettings()
|
||||
Else
|
||||
.Cookies = New CookieKeeper(.CookiesDomain) With {.EncryptKey = SettingsCLS.CookieEncryptKey}
|
||||
.SaveSettings()
|
||||
End If
|
||||
End With
|
||||
Token = New PropertyValue(t, GetType(String), Sub(v) UpdateResponse(v))
|
||||
TokenLastDateUpdated = New PropertyValue(Now.AddYears(-1), GetType(Date))
|
||||
TokenUpdateInterval = New PropertyValue(60 * 12, GetType(Integer))
|
||||
TokenUpdateIntervalProvider = New TokenIntervalProvider
|
||||
UrlPatternUser = "https://www.redgifs.com/users/{0}/"
|
||||
UserRegex = RParams.DMS("[htps:/]{7,8}.*?redgifs.com/users/([^/]+)", 1)
|
||||
ImageVideoContains = "redgifs"
|
||||
@@ -67,14 +84,14 @@ Namespace API.RedGifs
|
||||
#End Region
|
||||
#Region "Response updater"
|
||||
Private Sub UpdateResponse(ByVal Value As String)
|
||||
Responser.HeadersAdd(TokenName, Value)
|
||||
Responser.Headers.Add(TokenName, Value)
|
||||
Responser.SaveSettings()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Token updaters"
|
||||
Friend Function UpdateTokenIfRequired() As Boolean
|
||||
Dim d As Date? = AConvert(Of Date)(TokenLastDateUpdated.Value, AModes.Var, Nothing)
|
||||
If Not d.HasValue OrElse d.Value < Now.AddDays(-1) Then
|
||||
If Not d.HasValue OrElse d.Value < Now.AddMinutes(-CInt(TokenUpdateInterval.Value)) Then
|
||||
Return UpdateToken()
|
||||
Else
|
||||
Return True
|
||||
@@ -85,7 +102,7 @@ Namespace API.RedGifs
|
||||
Try
|
||||
Dim r$
|
||||
Dim NewToken$ = String.Empty
|
||||
Using resp As New Response : r = resp.GetResponse("https://api.redgifs.com/v2/auth/temporary",, EDP.ThrowException) : End Using
|
||||
Using resp As New Responser : r = resp.GetResponse("https://api.redgifs.com/v2/auth/temporary",, EDP.ThrowException) : End Using
|
||||
If Not r.IsEmptyString Then
|
||||
Dim j As EContainer = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing Then
|
||||
@@ -126,7 +143,7 @@ Namespace API.RedGifs
|
||||
End Function
|
||||
Friend Overrides Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable
|
||||
If BaseAuthExists() Then
|
||||
Using resp As Response = Responser.Copy
|
||||
Using resp As Responser = Responser.Copy
|
||||
Dim m As UserMedia = UserData.GetDataFromUrlId(URL, False, resp, Settings(RedGifsSiteKey))
|
||||
If Not m.State = UStates.Missing And Not m.State = UserData.DataGone And (m.Type = UTypes.Picture Or m.Type = UTypes.Video) Then
|
||||
Try
|
||||
|
||||
@@ -34,21 +34,15 @@ Namespace API.RedGifs
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download functions"
|
||||
Private NoCredentialsResponser As Response
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
Try
|
||||
NoCredentialsResponser = MySettings.NoCredentialsResponser.Copy
|
||||
DownloadData(1, Token)
|
||||
Finally
|
||||
NoCredentialsResponser.Dispose()
|
||||
End Try
|
||||
DownloadData(1, Token)
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
Dim _page As Func(Of String) = Function() If(Page = 1, String.Empty, $"&page={Page}")
|
||||
URL = $"https://api.redgifs.com/v2/users/{Name}/search?order=recent{_page.Invoke}"
|
||||
Dim r$ = NoCredentialsResponser.GetResponse(URL,, EDP.ThrowException)
|
||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||
Dim postDate$, postID$
|
||||
Dim pTotal% = 0
|
||||
If Not r.IsEmptyString Then
|
||||
@@ -70,7 +64,7 @@ Namespace API.RedGifs
|
||||
End If
|
||||
If pTotal > 0 And Page < pTotal Then DownloadData(Page + 1, Token)
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]",, True)
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
@@ -166,7 +160,7 @@ Namespace API.RedGifs
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
Friend Shared Function GetDataFromUrlId(ByVal Obj As String, ByVal ObjIsID As Boolean, ByVal Responser As Response,
|
||||
Friend Shared Function GetDataFromUrlId(ByVal Obj As String, ByVal ObjIsID As Boolean, ByVal Responser As Responser,
|
||||
ByVal Host As Plugin.Hosts.SettingsHost) As UserMedia
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
@@ -239,18 +233,8 @@ Namespace API.RedGifs
|
||||
#Region "Exception"
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
||||
Optional ByVal EObj As Object = Nothing) As Integer
|
||||
Dim IsNoCredentialsResponser As Boolean = AConvert(Of Boolean)(EObj, False)
|
||||
Dim s As WebExceptionStatus = -1
|
||||
Dim sc As HttpStatusCode = -1
|
||||
If IsNoCredentialsResponser Then
|
||||
If Not NoCredentialsResponser Is Nothing Then
|
||||
s = NoCredentialsResponser.Status
|
||||
sc = NoCredentialsResponser.StatusCode
|
||||
End If
|
||||
Else
|
||||
s = Responser.Client.Status
|
||||
sc = Responser.Client.StatusCode
|
||||
End If
|
||||
Dim s As WebExceptionStatus = Responser.Client.Status
|
||||
Dim sc As HttpStatusCode = Responser.Client.StatusCode
|
||||
If sc = HttpStatusCode.NotFound Or s = DataGone Then
|
||||
UserExists = False
|
||||
ElseIf sc = HttpStatusCode.Unauthorized Then
|
||||
|
||||
@@ -36,7 +36,7 @@ Namespace API.TikTok
|
||||
Return UserData.GetVideoInfo(URL, Responser)
|
||||
End Function
|
||||
Friend Overrides Function BaseAuthExists() As Boolean
|
||||
Return If(Responser.Cookies?.Count, 0) > 0
|
||||
Return Responser.CookiesExists
|
||||
End Function
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -52,7 +52,7 @@ Namespace API.TikTok
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Response, Optional ByVal e As ErrorsDescriber = Nothing) As IEnumerable(Of UserMedia)
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Responser, Optional ByVal e As ErrorsDescriber = Nothing) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If Not URL.IsEmptyString Then
|
||||
Dim PostId$ = String.Empty
|
||||
@@ -61,7 +61,7 @@ Namespace API.TikTok
|
||||
Dim r$
|
||||
PostId = RegexEnvir.ExtractPostID(URL)
|
||||
If Not PostId.IsEmptyString Then
|
||||
Using resp As Response = Responser.Copy() : r = resp.GetResponse(URL,, EDP.ThrowException) : End Using
|
||||
Using resp As Responser = Responser.Copy() : r = resp.GetResponse(URL,, EDP.ThrowException) : End Using
|
||||
If Not r.IsEmptyString Then
|
||||
If RegexEnvir.GetVideoData(r, PostId, PostURL, PostDate) Then Return {MediaFromData(PostURL, PostId, PostDate)}
|
||||
End If
|
||||
|
||||
@@ -12,6 +12,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.Twitter
|
||||
Friend Module Declarations
|
||||
Friend Const TwitterSite As String = "Twitter"
|
||||
Friend Const TwitterSiteKey As String = "AndyProgram_Twitter"
|
||||
Friend ReadOnly DateProvider As ADateTime = GetDateProvider()
|
||||
Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)}
|
||||
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
|
||||
|
||||
32
SCrawler/API/Twitter/EditorExchangeOptions.vb
Normal file
@@ -0,0 +1,32 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.Twitter
|
||||
Friend Class EditorExchangeOptions
|
||||
Friend Property GifsDownload As Boolean
|
||||
Friend Property GifsSpecialFolder As String
|
||||
Friend Property GifsPrefix As String
|
||||
Friend Property UseMD5Comparison As Boolean = False
|
||||
Friend Property RemoveExistingDuplicates As Boolean = False
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
GifsDownload = s.GifsDownload.Value
|
||||
GifsSpecialFolder = s.GifsSpecialFolder.Value
|
||||
GifsPrefix = s.GifsPrefix.Value
|
||||
UseMD5Comparison = s.UseMD5Comparison.Value
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
GifsDownload = u.GifsDownload
|
||||
GifsSpecialFolder = u.GifsSpecialFolder
|
||||
GifsPrefix = u.GifsPrefix
|
||||
UseMD5Comparison = u.UseMD5Comparison
|
||||
RemoveExistingDuplicates = u.RemoveExistingDuplicates
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
185
SCrawler/API/Twitter/OptionsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,185 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.Twitter
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class OptionsForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(OptionsForm))
|
||||
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.CH_DOWN_GIFS = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_GIF_FOLDER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_GIF_PREFIX = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CH_USE_MD5 = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_REMOVE_EXISTING_DUP = New System.Windows.Forms.CheckBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
CType(Me.TXT_GIF_FOLDER, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_GIF_PREFIX, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(304, 161)
|
||||
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(304, 161)
|
||||
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(Me.CH_DOWN_GIFS, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.TXT_GIF_FOLDER, 0, 1)
|
||||
TP_MAIN.Controls.Add(Me.TXT_GIF_PREFIX, 0, 2)
|
||||
TP_MAIN.Controls.Add(Me.CH_USE_MD5, 0, 3)
|
||||
TP_MAIN.Controls.Add(Me.CH_REMOVE_EXISTING_DUP, 0, 4)
|
||||
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 = 6
|
||||
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.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.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(304, 161)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'CH_DOWN_GIFS
|
||||
'
|
||||
Me.CH_DOWN_GIFS.AutoSize = True
|
||||
Me.CH_DOWN_GIFS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_GIFS.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_DOWN_GIFS.Name = "CH_DOWN_GIFS"
|
||||
Me.CH_DOWN_GIFS.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
|
||||
Me.CH_DOWN_GIFS.Size = New System.Drawing.Size(296, 19)
|
||||
Me.CH_DOWN_GIFS.TabIndex = 0
|
||||
Me.CH_DOWN_GIFS.Text = "Download GIFs"
|
||||
Me.CH_DOWN_GIFS.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TXT_GIF_FOLDER
|
||||
'
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Name = "Clear"
|
||||
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_GIF_FOLDER.Buttons.Add(ActionButton3)
|
||||
Me.TXT_GIF_FOLDER.CaptionText = "GIFs special folder"
|
||||
Me.TXT_GIF_FOLDER.CaptionToolTipText = "Put the GIFs in a special folder"
|
||||
Me.TXT_GIF_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_GIF_FOLDER.Location = New System.Drawing.Point(4, 30)
|
||||
Me.TXT_GIF_FOLDER.Name = "TXT_GIF_FOLDER"
|
||||
Me.TXT_GIF_FOLDER.Size = New System.Drawing.Size(296, 22)
|
||||
Me.TXT_GIF_FOLDER.TabIndex = 1
|
||||
'
|
||||
'TXT_GIF_PREFIX
|
||||
'
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Name = "Clear"
|
||||
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_GIF_PREFIX.Buttons.Add(ActionButton4)
|
||||
Me.TXT_GIF_PREFIX.CaptionText = "GIF prefix"
|
||||
Me.TXT_GIF_PREFIX.CaptionToolTipText = "This prefix will be added to the beginning of the filename"
|
||||
Me.TXT_GIF_PREFIX.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_GIF_PREFIX.Location = New System.Drawing.Point(4, 59)
|
||||
Me.TXT_GIF_PREFIX.Name = "TXT_GIF_PREFIX"
|
||||
Me.TXT_GIF_PREFIX.Size = New System.Drawing.Size(296, 22)
|
||||
Me.TXT_GIF_PREFIX.TabIndex = 2
|
||||
'
|
||||
'CH_USE_MD5
|
||||
'
|
||||
Me.CH_USE_MD5.AutoSize = True
|
||||
Me.CH_USE_MD5.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_USE_MD5.Location = New System.Drawing.Point(4, 88)
|
||||
Me.CH_USE_MD5.Name = "CH_USE_MD5"
|
||||
Me.CH_USE_MD5.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
|
||||
Me.CH_USE_MD5.Size = New System.Drawing.Size(296, 19)
|
||||
Me.CH_USE_MD5.TabIndex = 3
|
||||
Me.CH_USE_MD5.Text = "Use MD5 comparison"
|
||||
TT_MAIN.SetToolTip(Me.CH_USE_MD5, "Each image will be checked for existence using MD5")
|
||||
Me.CH_USE_MD5.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_REMOVE_EXISTING_DUP
|
||||
'
|
||||
Me.CH_REMOVE_EXISTING_DUP.AutoSize = True
|
||||
Me.CH_REMOVE_EXISTING_DUP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_REMOVE_EXISTING_DUP.Location = New System.Drawing.Point(4, 114)
|
||||
Me.CH_REMOVE_EXISTING_DUP.Name = "CH_REMOVE_EXISTING_DUP"
|
||||
Me.CH_REMOVE_EXISTING_DUP.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
|
||||
Me.CH_REMOVE_EXISTING_DUP.Size = New System.Drawing.Size(296, 19)
|
||||
Me.CH_REMOVE_EXISTING_DUP.TabIndex = 4
|
||||
Me.CH_REMOVE_EXISTING_DUP.Text = "Remove existing duplicates"
|
||||
TT_MAIN.SetToolTip(Me.CH_REMOVE_EXISTING_DUP, "Existing files will be checked for duplicates and duplicates removed." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Works only" &
|
||||
" on the first activation 'Use MD5 comparison'.")
|
||||
Me.CH_REMOVE_EXISTING_DUP.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OptionsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(304, 161)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteResources.TwitterIcon_32
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(320, 200)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(320, 200)
|
||||
Me.Name = "OptionsForm"
|
||||
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_MAIN.PerformLayout()
|
||||
CType(Me.TXT_GIF_FOLDER, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_GIF_PREFIX, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents CH_DOWN_GIFS As CheckBox
|
||||
Private WithEvents TXT_GIF_FOLDER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_GIF_PREFIX As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents CH_USE_MD5 As CheckBox
|
||||
Private WithEvents CH_REMOVE_EXISTING_DUP As CheckBox
|
||||
End Class
|
||||
End Namespace
|
||||
155
SCrawler/API/Twitter/OptionsForm.resx
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</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="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>
|
||||
</root>
|
||||
81
SCrawler/API/Twitter/OptionsForm.vb
Normal file
@@ -0,0 +1,81 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls
|
||||
Namespace API.Twitter
|
||||
Friend Class OptionsForm
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Private ReadOnly Property MyExchangeOptions As EditorExchangeOptions
|
||||
Private ReadOnly MyGifTextProvider As SiteSettings.GifStringProvider
|
||||
Friend Sub New(ByRef ExchangeOptions As EditorExchangeOptions)
|
||||
InitializeComponent()
|
||||
MyExchangeOptions = ExchangeOptions
|
||||
MyGifTextProvider = New SiteSettings.GifStringProvider
|
||||
MyDefs = New DefaultFormOptions(Me, Settings.Design)
|
||||
End Sub
|
||||
Private Sub OptionsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize(True)
|
||||
.AddOkCancelToolbar()
|
||||
With MyExchangeOptions
|
||||
CH_DOWN_GIFS.Checked = .GifsDownload
|
||||
TXT_GIF_FOLDER.Text = .GifsSpecialFolder
|
||||
TXT_GIF_FOLDER.Tag = NameOf(SiteSettings.GifsSpecialFolder)
|
||||
TXT_GIF_PREFIX.Text = .GifsPrefix
|
||||
TXT_GIF_PREFIX.Tag = NameOf(SiteSettings.GifsPrefix)
|
||||
CH_USE_MD5.Checked = .UseMD5Comparison
|
||||
CH_REMOVE_EXISTING_DUP.Checked = .RemoveExistingDuplicates
|
||||
|
||||
Try
|
||||
Dim p As PropertyOption
|
||||
With Settings(TwitterSiteKey)
|
||||
p = .PropList.Find(Function(pp) pp.Name = TXT_GIF_FOLDER.Tag).Options
|
||||
If Not p Is Nothing Then
|
||||
TXT_GIF_FOLDER.CaptionText = p.ControlText
|
||||
TXT_GIF_FOLDER.CaptionToolTipText = p.ControlToolTip
|
||||
TXT_GIF_FOLDER.CaptionToolTipEnabled = Not TXT_GIF_FOLDER.CaptionToolTipText.IsEmptyString
|
||||
End If
|
||||
|
||||
p = .PropList.Find(Function(pp) pp.Name = TXT_GIF_PREFIX.Tag).Options
|
||||
If Not p Is Nothing Then
|
||||
TXT_GIF_PREFIX.CaptionText = p.ControlText
|
||||
TXT_GIF_PREFIX.CaptionToolTipText = p.ControlToolTip
|
||||
TXT_GIF_PREFIX.CaptionToolTipEnabled = Not TXT_GIF_PREFIX.CaptionToolTipText.IsEmptyString
|
||||
End If
|
||||
End With
|
||||
Catch
|
||||
End Try
|
||||
End With
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
With MyExchangeOptions
|
||||
.GifsDownload = CH_DOWN_GIFS.Checked
|
||||
.GifsSpecialFolder = TXT_GIF_FOLDER.Text
|
||||
.GifsPrefix = TXT_GIF_PREFIX.Text
|
||||
.UseMD5Comparison = CH_USE_MD5.Checked
|
||||
.RemoveExistingDuplicates = CH_REMOVE_EXISTING_DUP.Checked
|
||||
End With
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
Private Sub TXT_ActionOnTextChanged(ByVal Sender As TextBoxExtended, ByVal e As EventArgs) Handles TXT_GIF_FOLDER.ActionOnTextChanged,
|
||||
TXT_GIF_PREFIX.ActionOnTextChanged
|
||||
If Not MyDefs.Initializing Then
|
||||
With Sender
|
||||
MyGifTextProvider.PropertyName = .Tag
|
||||
Dim s% = .SelectionStart
|
||||
Dim t$ = AConvert(Of String)(.Text, String.Empty, MyGifTextProvider)
|
||||
If Not .Text = t Then .Text = t : .Select(s, 0)
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -13,10 +13,11 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Namespace API.Twitter
|
||||
<Manifest("AndyProgram_Twitter"), SavedPosts>
|
||||
<Manifest(TwitterSiteKey), SavedPosts, SpecialForm(False)>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||
Friend Const Header_Authorization As String = "authorization"
|
||||
Friend Const Header_Token As String = "x-csrf-token"
|
||||
#Region "Declarations"
|
||||
Friend Overrides ReadOnly Property Icon As Icon
|
||||
Get
|
||||
Return My.Resources.SiteResources.TwitterIcon_32
|
||||
@@ -27,43 +28,83 @@ Namespace API.Twitter
|
||||
Return My.Resources.SiteResources.TwitterPic_400
|
||||
End Get
|
||||
End Property
|
||||
<PropertyOption(AllowNull:=False, ControlText:="Authorization",
|
||||
#Region "Auth"
|
||||
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Authorization",
|
||||
ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
|
||||
Private ReadOnly Property Auth As PropertyValue
|
||||
<PropertyOption(AllowNull:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
|
||||
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
|
||||
Private ReadOnly Property Token As PropertyValue
|
||||
<PropertyOption(ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
|
||||
<PropertyOption(IsAuth:=True, ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
|
||||
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||
Friend Overrides ReadOnly Property Responser As Response
|
||||
#End Region
|
||||
#Region "Other properties"
|
||||
<PropertyOption(IsAuth:=False, ControlText:="Download GIFs"), PXML>
|
||||
Friend ReadOnly Property GifsDownload As PropertyValue
|
||||
<PropertyOption(IsAuth:=False, ControlText:="GIFs special folder",
|
||||
ControlToolTip:="Put the GIFs in a special folder" & vbCr &
|
||||
"This is a folder name, not an absolute path." & vbCr &
|
||||
"This folder(s) will be created relative to the user's root folder." & vbCr &
|
||||
"Examples:" & vbCr & "SomeFolderName" & vbCr & "SomeFolderName\SomeFolderName2"), PXML>
|
||||
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
|
||||
<PropertyOption(IsAuth:=False, ControlText:="GIF prefix", ControlToolTip:="This prefix will be added to the beginning of the filename"), PXML>
|
||||
Friend ReadOnly Property GifsPrefix As PropertyValue
|
||||
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
|
||||
Private ReadOnly Property GifStringChecker As IFormatProvider
|
||||
Friend Class GifStringProvider : Implements ICustomProvider, IPropertyProvider
|
||||
Friend Property PropertyName As String Implements IPropertyProvider.PropertyName
|
||||
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
|
||||
Dim v$ = AConvert(Of String)(Value, String.Empty)
|
||||
If Not v.IsEmptyString Then
|
||||
If PropertyName = NameOf(GifsPrefix) Then
|
||||
v = v.StringRemoveWinForbiddenSymbols
|
||||
Else
|
||||
v = v.StringReplaceSymbols(GetWinForbiddenSymbols.ToList.ListWithRemove("\").ToArray, String.Empty, EDP.ReturnValue)
|
||||
v = v.StringTrim("\")
|
||||
End If
|
||||
End If
|
||||
Return v
|
||||
End Function
|
||||
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
|
||||
Throw New NotImplementedException("[GetFormat] is not available in the context of [TimersChecker]")
|
||||
End Function
|
||||
End Class
|
||||
<PropertyOption(IsAuth:=False, ControlText:="Use MD5 comparison", ControlToolTip:="Each image will be checked for existence using MD5"), PXML>
|
||||
Friend ReadOnly Property UseMD5Comparison As PropertyValue
|
||||
#End Region
|
||||
Friend Overrides ReadOnly Property Responser As Responser
|
||||
#End Region
|
||||
Friend Sub New()
|
||||
MyBase.New(TwitterSite)
|
||||
Responser = New Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||
Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||
|
||||
Dim a$ = String.Empty
|
||||
Dim t$ = String.Empty
|
||||
|
||||
With Responser
|
||||
If .File.Exists Then
|
||||
Dim b As Boolean = .CookiesDomain.IsEmptyString
|
||||
If EncryptCookies.CookiesEncrypted Then .CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
||||
.LoadSettings()
|
||||
a = .HeadersValue(Header_Authorization)
|
||||
t = .HeadersValue(Header_Token)
|
||||
a = .Headers.Value(Header_Authorization)
|
||||
t = .Headers.Value(Header_Token)
|
||||
.CookiesDomain = "twitter.com"
|
||||
If b Then .SaveSettings()
|
||||
Else
|
||||
.ContentType = "application/json"
|
||||
.Accept = "*/*"
|
||||
.CookiesDomain = "twitter.com"
|
||||
.Cookies = New CookieKeeper(.CookiesDomain) With {.EncryptKey = SettingsCLS.CookieEncryptKey}
|
||||
.CookiesEncryptKey = SettingsCLS.CookieEncryptKey
|
||||
.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
||||
.HeadersAdd("sec-ch-ua", " Not;A Brand"";v=""99"", ""Google Chrome"";v=""91"", ""Chromium"";v=""91""")
|
||||
.HeadersAdd("sec-ch-ua-mobile", "?0")
|
||||
.HeadersAdd("sec-fetch-dest", "empty")
|
||||
.HeadersAdd("sec-fetch-mode", "cors")
|
||||
.HeadersAdd("sec-fetch-site", "same-origin")
|
||||
.HeadersAdd(Header_Token, String.Empty)
|
||||
.HeadersAdd("x-twitter-active-user", "yes")
|
||||
.HeadersAdd("x-twitter-auth-type", "OAuth2Session")
|
||||
.HeadersAdd(Header_Authorization, String.Empty)
|
||||
.Headers.Add("sec-ch-ua", " Not;A Brand"";v=""99"", ""Google Chrome"";v=""91"", ""Chromium"";v=""91""")
|
||||
.Headers.Add("sec-ch-ua-mobile", "?0")
|
||||
.Headers.Add("sec-fetch-dest", "empty")
|
||||
.Headers.Add("sec-fetch-mode", "cors")
|
||||
.Headers.Add("sec-fetch-site", "same-origin")
|
||||
.Headers.Add(Header_Token, String.Empty)
|
||||
.Headers.Add("x-twitter-active-user", "yes")
|
||||
.Headers.Add("x-twitter-auth-type", "OAuth2Session")
|
||||
.Headers.Add(Header_Authorization, String.Empty)
|
||||
.SaveSettings()
|
||||
End If
|
||||
End With
|
||||
@@ -72,6 +113,12 @@ Namespace API.Twitter
|
||||
Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
|
||||
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
|
||||
|
||||
GifsDownload = New PropertyValue(True)
|
||||
GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
|
||||
GifsPrefix = New PropertyValue("GIF_")
|
||||
GifStringChecker = New GifStringProvider
|
||||
UseMD5Comparison = New PropertyValue(False)
|
||||
|
||||
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
|
||||
UrlPatternUser = "https://twitter.com/{0}"
|
||||
ImageVideoContains = "twitter"
|
||||
@@ -84,8 +131,8 @@ Namespace API.Twitter
|
||||
Case NameOf(Token) : f = Header_Token
|
||||
End Select
|
||||
If Not f.IsEmptyString Then
|
||||
Responser.HeadersRemove(f)
|
||||
If Not CStr(Value).IsEmptyString Then Responser.HeadersAdd(f, CStr(Value))
|
||||
Responser.Headers.Remove(f)
|
||||
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||
Responser.SaveSettings()
|
||||
End If
|
||||
End If
|
||||
@@ -104,7 +151,13 @@ Namespace API.Twitter
|
||||
Return $"https://twitter.com/{User.Name}/status/{Media.Post.ID}"
|
||||
End Function
|
||||
Friend Overrides Function BaseAuthExists() As Boolean
|
||||
Return If(Responser.Cookies?.Count, 0) > 0 And ACheck(Token.Value) And ACheck(Auth.Value)
|
||||
Return Responser.CookiesExists And ACheck(Token.Value) And ACheck(Auth.Value)
|
||||
End Function
|
||||
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 OpenForm Then
|
||||
Using f As New OptionsForm(Options) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -7,25 +7,77 @@
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Net
|
||||
Imports System.Drawing
|
||||
Imports System.Threading
|
||||
Imports SCrawler.API.Base
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports PersonalUtilities.Tools.ImageRenderer
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.Twitter
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Private Const SinglePostUrl As String = "https://api.twitter.com/1.1/statuses/show.json?id={0}&tweet_mode=extended"
|
||||
#Region "XML names"
|
||||
Private Const Name_GifsDownload As String = "GifsDownload"
|
||||
Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
|
||||
Private Const Name_GifsPrefix As String = "GifsPrefix"
|
||||
Private Const Name_UseMD5Comparison As String = "UseMD5Comparison"
|
||||
Private Const Name_RemoveExistingDuplicates As String = "RemoveExistingDuplicates"
|
||||
Private Const Name_StartMD5Checked As String = "StartMD5Checked"
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
Friend Property GifsDownload As Boolean
|
||||
Friend Property GifsSpecialFolder As String
|
||||
Friend Property GifsPrefix As String
|
||||
Private ReadOnly _DataNames As List(Of String)
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
Friend Property UseMD5Comparison As Boolean = False
|
||||
Private StartMD5Checked As Boolean = False
|
||||
Friend Property RemoveExistingDuplicates As Boolean = False
|
||||
#End Region
|
||||
#Region "Exchange options"
|
||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||
Return New EditorExchangeOptions(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptions Then
|
||||
With DirectCast(Obj, EditorExchangeOptions)
|
||||
GifsDownload = .GifsDownload
|
||||
GifsSpecialFolder = .GifsSpecialFolder
|
||||
GifsPrefix = .GifsPrefix
|
||||
UseMD5Comparison = .UseMD5Comparison
|
||||
RemoveExistingDuplicates = .RemoveExistingDuplicates
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
#Region "Initializer, loader"
|
||||
Friend Sub New()
|
||||
_DataNames = New List(Of String)
|
||||
End Sub
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
If Loading Then
|
||||
GifsDownload = Container.Value(Name_GifsDownload).FromXML(Of Boolean)(True)
|
||||
GifsSpecialFolder = Container.Value(Name_GifsSpecialFolder)
|
||||
If Not Container.Contains(Name_GifsPrefix) Then
|
||||
GifsPrefix = "GIF_"
|
||||
Else
|
||||
GifsPrefix = Container.Value(Name_GifsPrefix)
|
||||
End If
|
||||
UseMD5Comparison = Container.Value(Name_UseMD5Comparison).FromXML(Of Boolean)(False)
|
||||
RemoveExistingDuplicates = Container.Value(Name_RemoveExistingDuplicates).FromXML(Of Boolean)(False)
|
||||
StartMD5Checked = Container.Value(Name_StartMD5Checked).FromXML(Of Boolean)(False)
|
||||
Else
|
||||
Container.Add(Name_GifsDownload, GifsDownload.BoolToInteger)
|
||||
Container.Add(Name_GifsSpecialFolder, GifsSpecialFolder)
|
||||
Container.Add(Name_GifsPrefix, GifsPrefix)
|
||||
Container.Add(Name_UseMD5Comparison, UseMD5Comparison.BoolToInteger)
|
||||
Container.Add(Name_RemoveExistingDuplicates, RemoveExistingDuplicates.BoolToInteger)
|
||||
Container.Add(Name_StartMD5Checked, StartMD5Checked.BoolToInteger)
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Download functions"
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
@@ -35,6 +87,7 @@ Namespace API.Twitter
|
||||
Else
|
||||
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
DownloadData(String.Empty, Token)
|
||||
If UseMD5Comparison Then ValidateMD5(Token)
|
||||
End If
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken)
|
||||
@@ -65,6 +118,30 @@ Namespace API.Twitter
|
||||
If Not r.IsEmptyString Then
|
||||
Using w As EContainer = JsonDocument.Parse(r)
|
||||
If w.ListExists Then
|
||||
|
||||
If Not IsSavedPosts And POST.IsEmptyString And Not w.ItemF({0, "user"}) Is Nothing Then
|
||||
With w.ItemF({0, "user"})
|
||||
If .Value("screen_name").StringToLower = Name Then
|
||||
UserSiteNameUpdate(.Value("name"))
|
||||
UserDescriptionUpdate(.Value("description"))
|
||||
Dim __getImage As Action(Of String) = Sub(ByVal img As String)
|
||||
If Not img.IsEmptyString Then
|
||||
Dim __imgFile As SFile = UrlFile(img, True)
|
||||
If Not __imgFile.Name.IsEmptyString Then
|
||||
If __imgFile.Extension.IsEmptyString Then __imgFile.Extension = "jpg"
|
||||
__imgFile.Path = MyFile.CutPath.Path
|
||||
If Not __imgFile.Exists Then GetWebFile(img, __imgFile, EDP.None)
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
Dim icon$ = .Value("profile_image_url_https")
|
||||
If Not icon.IsEmptyString Then icon = icon.Replace("_normal", String.Empty)
|
||||
__getImage.Invoke(.Value("profile_banner_url"))
|
||||
__getImage.Invoke(icon)
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
|
||||
For Each nn In If(IsSavedPosts, w({"globalObjects", "tweets"}).XmlIfNothing, w)
|
||||
ThrowAny(Token)
|
||||
If nn.Count > 0 Then
|
||||
@@ -79,9 +156,6 @@ Namespace API.Twitter
|
||||
End If
|
||||
End If
|
||||
|
||||
If Not IsSavedPosts AndAlso UserDescriptionNeedToUpdate() AndAlso nn.Value({"user"}, "screen_name") = Name Then _
|
||||
UserDescriptionUpdate(nn.Value({"user"}, "description"))
|
||||
|
||||
'Date Pattern:
|
||||
'Sat Jan 01 01:10:15 +0000 2000
|
||||
If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty
|
||||
@@ -139,7 +213,7 @@ Namespace API.Twitter
|
||||
If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then
|
||||
_DataNames.Add(dName)
|
||||
_TempMediaList.ListAddValue(MediaFromData(m("media_url").Value,
|
||||
PostID, PostDate, GetPictureOption(m), State), LNC)
|
||||
PostID, PostDate, GetPictureOption(m), State, UTypes.Picture), LNC)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
@@ -155,7 +229,7 @@ Namespace API.Twitter
|
||||
Dim f$ = UrlFile(URL)
|
||||
If Not f.IsEmptyString AndAlso Not _DataNames.Contains(f) Then
|
||||
_DataNames.Add(f)
|
||||
_TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate,, State), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate,, State, UTypes.Video), LNC)
|
||||
End If
|
||||
Return True
|
||||
End If
|
||||
@@ -182,10 +256,11 @@ Namespace API.Twitter
|
||||
url = .Value("url")
|
||||
ff = UrlFile(url)
|
||||
If Not ff.IsEmptyString Then
|
||||
If Not _DataNames.Contains(ff) Then
|
||||
m = MediaFromData(url, PostID, PostDate,, State)
|
||||
If GifsDownload And Not _DataNames.Contains(ff) Then
|
||||
m = MediaFromData(url, PostID, PostDate,, State, UTypes.Video)
|
||||
f = m.File
|
||||
If Not f.IsEmptyString Then f.Name = $"GIF_{f.Name}" : m.File = f
|
||||
If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f
|
||||
If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*"
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
End If
|
||||
Return True
|
||||
@@ -262,19 +337,144 @@ Namespace API.Twitter
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "MD5 support"
|
||||
Private Const VALIDATE_MD5_ERROR As String = "VALIDATE_MD5_ERROR"
|
||||
Private Sub ValidateMD5(ByVal Token As CancellationToken)
|
||||
Try
|
||||
Dim missingMD5 As Predicate(Of UserMedia) = Function(d) (d.Type = UTypes.GIF Or d.Type = UTypes.Picture) And d.MD5.IsEmptyString
|
||||
If UseMD5Comparison And _TempMediaList.Exists(missingMD5) Then
|
||||
Dim i%
|
||||
Dim data As UserMedia = Nothing
|
||||
Dim hashList As New Dictionary(Of String, SFile)
|
||||
Dim f As SFile
|
||||
Dim ErrMD5 As New ErrorsDescriber(EDP.ReturnValue)
|
||||
Dim __getMD5 As Func(Of UserMedia, Boolean, String) =
|
||||
Function(ByVal __data As UserMedia, ByVal IsUrl As Boolean) As String
|
||||
Try
|
||||
Dim ImgFormat As Imaging.ImageFormat = Nothing
|
||||
Dim hash$ = String.Empty
|
||||
Dim __isGif As Boolean = False
|
||||
If __data.Type = UTypes.GIF Then
|
||||
ImgFormat = Imaging.ImageFormat.Gif
|
||||
__isGif = True
|
||||
ElseIf Not __data.File.IsEmptyString Then
|
||||
ImgFormat = GetImageFormat(__data.File)
|
||||
End If
|
||||
If ImgFormat Is Nothing Then ImgFormat = Imaging.ImageFormat.Jpeg
|
||||
If IsUrl Then
|
||||
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5))
|
||||
Else
|
||||
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
||||
End If
|
||||
If hash.IsEmptyString And Not __isGif Then
|
||||
If ImgFormat Is Imaging.ImageFormat.Jpeg Then ImgFormat = Imaging.ImageFormat.Png Else ImgFormat = Imaging.ImageFormat.Jpeg
|
||||
If IsUrl Then
|
||||
hash = ByteArrayToString(GetMD5(SFile.GetBytesFromNet(__data.URL_BASE.IfNullOrEmpty(__data.URL), ErrMD5), ImgFormat, ErrMD5))
|
||||
Else
|
||||
hash = ByteArrayToString(GetMD5(SFile.GetBytes(__data.File, ErrMD5), ImgFormat, ErrMD5))
|
||||
End If
|
||||
End If
|
||||
Return hash
|
||||
Catch
|
||||
Return String.Empty
|
||||
End Try
|
||||
End Function
|
||||
If Not StartMD5Checked Then
|
||||
StartMD5Checked = True
|
||||
If _ContentList.Exists(missingMD5) Then
|
||||
Dim existingFiles As List(Of SFile) = SFile.GetFiles(MyFileSettings.CutPath, "*.jpg|*.jpeg|*.png|*.gif",, EDP.ReturnValue).ListIfNothing
|
||||
Dim eIndx%
|
||||
Dim eFinder As Predicate(Of SFile) = Function(ff) ff.File = data.File.File
|
||||
If RemoveExistingDuplicates Then
|
||||
RemoveExistingDuplicates = False
|
||||
_ForceSaveUserInfo = True
|
||||
If existingFiles.Count > 0 Then
|
||||
Dim h$
|
||||
For i = existingFiles.Count - 1 To 0 Step -1
|
||||
h = __getMD5(New UserMedia With {.File = existingFiles(i)}, False)
|
||||
If Not h.IsEmptyString Then
|
||||
If hashList.ContainsKey(h) Then
|
||||
MyMainLOG = $"[{ToStringForLog()}]: Removed image [{existingFiles(i).File}] (duplicate of [{hashList(h).File}])"
|
||||
existingFiles(i).Delete(SFO.File, SFODelete.DeleteToRecycleBin, ErrMD5)
|
||||
existingFiles.RemoveAt(i)
|
||||
Else
|
||||
hashList.Add(h, existingFiles(i))
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
For i = 0 To _ContentList.Count - 1
|
||||
data = _ContentList(i)
|
||||
If (data.Type = UTypes.GIF Or data.Type = UTypes.Picture) Then
|
||||
If data.MD5.IsEmptyString Then
|
||||
ThrowAny(Token)
|
||||
eIndx = existingFiles.FindIndex(eFinder)
|
||||
If eIndx >= 0 Then
|
||||
data.MD5 = __getMD5(New UserMedia With {.File = existingFiles(eIndx)}, False)
|
||||
If Not data.MD5.IsEmptyString Then _ContentList(i) = data : _ForceSaveUserData = True
|
||||
End If
|
||||
End If
|
||||
existingFiles.RemoveAll(eFinder)
|
||||
End If
|
||||
Next
|
||||
If existingFiles.Count > 0 Then
|
||||
For i = 0 To existingFiles.Count - 1
|
||||
f = existingFiles(i)
|
||||
data = New UserMedia(f.File) With {
|
||||
.State = UStates.Downloaded,
|
||||
.Type = IIf(f.Extension = "gif", UTypes.GIF, UTypes.Picture),
|
||||
.File = f
|
||||
}
|
||||
ThrowAny(Token)
|
||||
data.MD5 = __getMD5(data, False)
|
||||
If Not data.MD5.IsEmptyString Then _ContentList.Add(data) : _ForceSaveUserData = True
|
||||
Next
|
||||
existingFiles.Clear()
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
If _ContentList.Count > 0 Then
|
||||
With _ContentList.Select(Function(d) d.MD5)
|
||||
If .ListExists Then .ToList.ForEach(Sub(md5value) If Not hashList.ContainsKey(md5value) Then hashList.Add(md5value, New SFile))
|
||||
End With
|
||||
End If
|
||||
|
||||
For i = _TempMediaList.Count - 1 To 0 Step -1
|
||||
data = _TempMediaList(i)
|
||||
If missingMD5(data) Then
|
||||
ThrowAny(Token)
|
||||
data.MD5 = __getMD5(data, True)
|
||||
If Not data.MD5.IsEmptyString Then
|
||||
If hashList.ContainsKey(data.MD5) Then
|
||||
_TempMediaList.RemoveAt(i)
|
||||
Else
|
||||
hashList.Add(data.MD5, New SFile)
|
||||
_TempMediaList(i) = data
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, "ValidateMD5",, VALIDATE_MD5_ERROR)
|
||||
End Try
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Get video static"
|
||||
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 Responser) As IEnumerable(Of UserMedia)
|
||||
Try
|
||||
If URL.Contains("twitter") Then
|
||||
Dim PostID$ = RegexReplace(URL, RParams.DM("(?<=/)\d+", 0))
|
||||
If Not PostID.IsEmptyString Then
|
||||
Dim r$
|
||||
Using rc As Response = resp.Copy() : r = rc.GetResponse(String.Format(SinglePostUrl, PostID),, EDP.ReturnValue) : End Using
|
||||
Using rc As Responser = resp.Copy() : r = rc.GetResponse(String.Format(SinglePostUrl, PostID),, EDP.ReturnValue) : End Using
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If j.ListExists Then
|
||||
Dim u$ = GetVideoNodeURL(j)
|
||||
If Not u.IsEmptyString Then Return {MediaFromData(u, PostID, String.Empty)}
|
||||
If Not u.IsEmptyString Then Return {MediaFromData(u, PostID, String.Empty,,, UTypes.Video)}
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
@@ -323,10 +523,17 @@ Namespace API.Twitter
|
||||
End Function
|
||||
#End Region
|
||||
#Region "UrlFile"
|
||||
Private Function UrlFile(ByVal URL As String) As String
|
||||
Private Function UrlFile(ByVal URL As String, Optional ByVal GetWithoutExtension As Boolean = False) As String
|
||||
Try
|
||||
Dim f As SFile = CStr(RegexReplace(LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern)), FilesPattern))
|
||||
If Not f.IsEmptyString Then Return f.File Else Return String.Empty
|
||||
If Not URL.IsEmptyString Then
|
||||
Dim f As SFile = CStr(RegexReplace(LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern)), FilesPattern))
|
||||
If f.IsEmptyString And GetWithoutExtension Then
|
||||
URL = LinkFormatterSecure(RegexReplace(URL.Replace("\", String.Empty), LinkPattern))
|
||||
If Not URL.IsEmptyString Then f = New SFile With {.Name = URL.Split("/").LastOrDefault}
|
||||
End If
|
||||
If Not f.IsEmptyString Then Return f.File
|
||||
End If
|
||||
Return String.Empty
|
||||
Catch ex As Exception
|
||||
Return String.Empty
|
||||
End Try
|
||||
@@ -335,9 +542,10 @@ Namespace API.Twitter
|
||||
#Region "Create media"
|
||||
Private Shared Function MediaFromData(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal _PictureOption As String = Nothing,
|
||||
Optional ByVal State As UStates = UStates.Unknown) As UserMedia
|
||||
Optional ByVal State As UStates = UStates.Unknown,
|
||||
Optional ByVal Type As UTypes = UTypes.Undefined) As UserMedia
|
||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||
Dim m As New UserMedia(_URL) With {.PictureOption = _PictureOption, .Post = New UserPost With {.ID = PostID}}
|
||||
Dim m As New UserMedia(_URL) With {.PictureOption = _PictureOption, .Post = New UserPost With {.ID = PostID}, .Type = Type}
|
||||
If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern))
|
||||
If Not m.PictureOption.IsEmptyString And Not m.File.IsEmptyString And Not m.URL.IsEmptyString Then
|
||||
m.URL = $"{m.URL.Replace($".{m.File.Extension}", String.Empty)}?format={m.File.Extension}&name={m.PictureOption}"
|
||||
@@ -355,20 +563,25 @@ Namespace API.Twitter
|
||||
#Region "Exception"
|
||||
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String, Optional ByVal FromPE As Boolean = False,
|
||||
Optional ByVal EObj As Object = Nothing) As Integer
|
||||
With Responser
|
||||
If .StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf .StatusCode = HttpStatusCode.Unauthorized Then
|
||||
UserSuspended = True
|
||||
ElseIf .StatusCode = HttpStatusCode.BadRequest Then
|
||||
MyMainLOG = "Twitter has invalid credentials"
|
||||
ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then
|
||||
MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})"
|
||||
Else
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
End With
|
||||
If AEquals(EObj, VALIDATE_MD5_ERROR) Then
|
||||
If Not FromPE Then LogError(ex, Message)
|
||||
Return 0
|
||||
Else
|
||||
With Responser
|
||||
If .StatusCode = HttpStatusCode.NotFound Then
|
||||
UserExists = False
|
||||
ElseIf .StatusCode = HttpStatusCode.Unauthorized Then
|
||||
UserSuspended = True
|
||||
ElseIf .StatusCode = HttpStatusCode.BadRequest Then
|
||||
MyMainLOG = "Twitter has invalid credentials"
|
||||
ElseIf .StatusCode = HttpStatusCode.ServiceUnavailable Or .StatusCode = HttpStatusCode.InternalServerError Then
|
||||
MyMainLOG = $"[{CInt(.StatusCode)}] Twitter is currently unavailable ({ToString()})"
|
||||
Else
|
||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||
Return 0
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
Return 1
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
@@ -98,7 +98,7 @@ Namespace API
|
||||
If Not img Is Nothing Then Return img
|
||||
Next
|
||||
End If
|
||||
Return GetNullPicture(Settings.MaxLargeImageHeight)
|
||||
Return GetNullPicture(If(Settings.ViewMode.Value = ViewModes.IconLarge, Settings.MaxLargeImageHeight, Settings.MaxSmallImageHeight))
|
||||
End Function
|
||||
#End Region
|
||||
Friend Overrides ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
|
||||
@@ -370,7 +370,7 @@ Namespace API
|
||||
If Not e.Exists Then e = New ErrorsDescriber(EDP.SendInLog)
|
||||
If Count > 0 Then Collections.ForEach(Sub(c) c.OpenSite(e))
|
||||
End Sub
|
||||
Private ReadOnly RealUser As Predicate(Of IUserData) = Function(u) u.UserModel = UsageModel.Default
|
||||
Private ReadOnly RealUser As Predicate(Of IUserData) = Function(u) u.UserModel = UsageModel.Default And Not u.HOST.Key = PathPlugin.PluginKey
|
||||
Friend Overrides Sub OpenFolder()
|
||||
Try
|
||||
If Count > 0 Then
|
||||
@@ -556,7 +556,11 @@ Namespace API
|
||||
"Cancel"}, vbExclamation)
|
||||
Dim v%
|
||||
If CollectionValue >= 0 Then
|
||||
v = CollectionValue
|
||||
Select Case CollectionValue
|
||||
Case 2 : v = 0
|
||||
Case 3 : v = 1
|
||||
Case Else : v = MsgBoxE(m)
|
||||
End Select
|
||||
ElseIf Multiple Then
|
||||
v = 0
|
||||
Else
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.XVIDEOS
|
||||
Friend Module Declarations
|
||||
Friend Const XvideosSiteKey As String = "AndyProgram_XVIDEOS"
|
||||
Private ReadOnly HtmlConverter As Func(Of String, String) = Function(Input) SymbolsConverter.HTML.Decode(Input, EDP.ReturnValue)
|
||||
Friend ReadOnly Regex_M3U8 As RParams = RParams.DM("http.+?.m3u8.*?(?=')", 0)
|
||||
Friend ReadOnly Regex_VideoTitle As RParams = RParams.DMS("html5player.setVideoTitle\('(.+)(?='\);)", 1, EDP.ReturnValue, HtmlConverter)
|
||||
Friend ReadOnly Regex_VideoTitle As RParams = RParams.DMS("html5player.setVideoTitle\('(.+)(?='\);)", 1, EDP.ReturnValue, TitleHtmlConverter)
|
||||
Friend ReadOnly Regex_VideoID As RParams = RParams.DMS(".*?www.xvideos.com/(video\d+).*", 1)
|
||||
Friend ReadOnly Regex_M3U8_Reparse As RParams = RParams.DM("NAME=""(\d+).*?""[\r\n]*?(.+)(?=(|[\r\n]+?))", 0, RegexReturn.List)
|
||||
Friend ReadOnly Regex_M3U8_Appender As RParams = RParams.DM("(.+)(?=/.+?\.m3u8.*?)", 0)
|
||||
Friend ReadOnly Regex_SavedVideosPlaylist As RParams = RParams.DM("<div id=""video.+?data-id=""(\d+).+?a href=""([^""]+)"".+?title=""([^""]*)""",
|
||||
0, RegexReturn.List, EDP.ReturnValue, HtmlConverter)
|
||||
0, RegexReturn.List, EDP.ReturnValue, TitleHtmlConverter)
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -57,11 +57,13 @@ Namespace API.XVIDEOS
|
||||
SiteDomains = New PropertyValue(DomainsDefault, GetType(String), Sub(s) UpdateDomains())
|
||||
DownloadUHD = New PropertyValue(False)
|
||||
SavedVideosPlaylist = New PropertyValue(String.Empty, GetType(String))
|
||||
UrlPatternUser = "https://xvideos.com/{0}"
|
||||
End Sub
|
||||
Friend Overrides Sub EndInit()
|
||||
Initialized = True
|
||||
DomainContainer.EndInit(Me)
|
||||
DomainsTemp.ListAddList(Domains)
|
||||
MyBase.EndInit()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Edit"
|
||||
@@ -93,7 +95,7 @@ Namespace API.XVIDEOS
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||
If Settings.UseM3U8 Then
|
||||
If What = ISiteSettings.Download.SavedPosts Then
|
||||
Return ACheck(SavedVideosPlaylist.Value) And If(Responser.Cookies?.Count, 0) > 0
|
||||
Return ACheck(SavedVideosPlaylist.Value) And Responser.CookiesExists
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
@@ -103,11 +105,14 @@ Namespace API.XVIDEOS
|
||||
End Function
|
||||
#End Region
|
||||
#Region "User: get, check"
|
||||
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String
|
||||
Friend Function GetUserUrlPart(ByVal User As UserData) As String
|
||||
Dim __user$ = User.Name.Split("_").FirstOrDefault
|
||||
__user &= $"/{User.Name.Replace($"{User}_", String.Empty)}"
|
||||
__user &= $"/{User.Name.Replace($"{__user}_", String.Empty)}"
|
||||
Return __user
|
||||
End Function
|
||||
Friend Overrides Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String
|
||||
Return String.Format(UrlPatternUser, GetUserUrlPart(User))
|
||||
End Function
|
||||
Private Const UserRegexDefault As String = "/(profiles|[\w]*?[-]{0,1}channels)/([^/]+)(\Z|.*?)"
|
||||
Private Const URD As String = ".*?{0}{1}"
|
||||
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||
@@ -141,7 +146,7 @@ Namespace API.XVIDEOS
|
||||
Dim f As SFile = GetSpecialDataFile(Path, AskForPath, spf)
|
||||
f.Name = "video"
|
||||
f.Extension = "mp4"
|
||||
Using resp As Response = Responser.Copy
|
||||
Using resp As Responser = Responser.Copy
|
||||
Using user As New UserData With {.HOST = Settings(XvideosSiteKey)}
|
||||
DirectCast(user, UserDataBase).User.File = f
|
||||
Dim p As UserMedia = user.Download(URL, resp, DownloadUHD.Value, String.Empty)
|
||||
|
||||
@@ -25,7 +25,7 @@ Namespace API.XVIDEOS
|
||||
ID = ParamsArray(0)
|
||||
URL = ParamsArray(1)
|
||||
If Not URL.IsEmptyString Then URL = $"https://www.xvideos.com/{URL.StringTrimStart("/")}"
|
||||
Title = ParamsArray(2).StringRemoveWinForbiddenSymbols.StringTrim
|
||||
Title = ParamsArray(2)
|
||||
End If
|
||||
Return Me
|
||||
End Function
|
||||
@@ -45,14 +45,7 @@ Namespace API.XVIDEOS
|
||||
UseInternalM3U8Function = True
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
If Not Settings.UseM3U8 Then
|
||||
If Not Settings.OS64 Then
|
||||
MyMainLOG = $"XVIDEOS [{ToStringForLog()}]: The plugin only works with x64 OS."
|
||||
Else
|
||||
MyMainLOG = $"{ToStringForLog()}: File [ffmpeg.exe] not found"
|
||||
End If
|
||||
Exit Sub
|
||||
End If
|
||||
If Not Settings.UseM3U8 Then MyMainLOG = $"{ToStringForLog()}: File [ffmpeg.exe] not found" : Exit Sub
|
||||
If IsSavedPosts Then
|
||||
If Not ACheck(MySettings.SavedVideosPlaylist.Value) Then Throw New ArgumentNullException("SavedVideosPlaylist", "Playlist of saved videos cannot be null")
|
||||
DownloadSavedVideos(Token)
|
||||
@@ -63,49 +56,63 @@ Namespace API.XVIDEOS
|
||||
Private Sub DownloadUserVideo(ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
Dim NextPage% = 0
|
||||
Dim r$
|
||||
Dim NextPage%, d%
|
||||
Dim limit% = If(DownloadTopCount, -1)
|
||||
Dim r$, n$
|
||||
Dim j As EContainer = Nothing
|
||||
Dim jj As EContainer
|
||||
Dim user$ = MySettings.GetUserUrl(Me, False)
|
||||
Dim user$ = MySettings.GetUserUrlPart(Me)
|
||||
Dim p As UserMedia
|
||||
Dim EnvirSet As Boolean = False
|
||||
|
||||
Do
|
||||
ThrowAny(Token)
|
||||
URL = $"https://www.xvideos.com/{user}/videos/new/{If(NextPage = 0, String.Empty, NextPage)}"
|
||||
r = Responser.GetResponse(URL)
|
||||
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 UserMedia With {
|
||||
.Post = jj.Value("id"),
|
||||
.URL = $"https://www.xvideos.com/{jj.Value("u").StringTrimStart("/")}"
|
||||
}
|
||||
If Not p.Post.ID.IsEmptyString And Not jj.Value("u").IsEmptyString Then
|
||||
If Not _TempPostsList.Contains(p.Post.ID) Then
|
||||
_TempPostsList.Add(p.Post.ID)
|
||||
_TempMediaList.Add(p)
|
||||
Else
|
||||
Exit Do
|
||||
If ID.IsEmptyString Then GetUserID()
|
||||
For i% = 0 To 1
|
||||
If i = 1 And ID.IsEmptyString Then Exit For
|
||||
NextPage = 0
|
||||
d = 0
|
||||
n = IIf(i = 0, "u", "url")
|
||||
Do
|
||||
ThrowAny(Token)
|
||||
If i = 0 Then
|
||||
URL = $"https://www.xvideos.com/{user}/videos/new/{If(NextPage = 0, String.Empty, NextPage)}"
|
||||
Else 'Quickies
|
||||
URL = $"https://www.xvideos.com/quickies-api/profilevideos/all/none/N/{ID}/{NextPage}"
|
||||
End If
|
||||
r = Responser.GetResponse(URL,, EDP.ReturnValue)
|
||||
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 UserMedia With {
|
||||
.Post = jj.Value("id"),
|
||||
.URL = $"https://www.xvideos.com/{jj.Value(n).StringTrimStart("/")}"
|
||||
}
|
||||
If Not p.Post.ID.IsEmptyString And Not jj.Value(n).IsEmptyString Then
|
||||
If Not _TempPostsList.Contains(p.Post.ID) Then
|
||||
_TempPostsList.Add(p.Post.ID)
|
||||
_TempMediaList.Add(p)
|
||||
d += 1
|
||||
If limit > 0 And d = limit Then Exit Do
|
||||
Else
|
||||
Exit Do
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
Continue Do
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
If Not j Is Nothing Then j.Dispose()
|
||||
Exit Do
|
||||
Loop While NextPage < 100
|
||||
Next
|
||||
Continue Do
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
If Not j Is Nothing Then j.Dispose()
|
||||
Exit Do
|
||||
Loop While NextPage < 100
|
||||
Next
|
||||
|
||||
If Not j Is Nothing Then j.Dispose()
|
||||
|
||||
@@ -128,6 +135,10 @@ Namespace API.XVIDEOS
|
||||
If _TempMediaList.ListExists Then _TempMediaList.RemoveAll(Function(m) m.URL.IsEmptyString)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub GetUserID()
|
||||
Dim r$ = Responser.GetResponse($"https://www.xvideos.com/{MySettings.GetUserUrlPart(Me)}",, EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then ID = RegexReplace(r, RParams.DMS("""id_user"":(\d+)", 1, EDP.ReturnValue))
|
||||
End Sub
|
||||
Private Sub DownloadSavedVideos(ByVal Token As CancellationToken)
|
||||
Dim URL$ = MySettings.SavedVideosPlaylist.Value
|
||||
Try
|
||||
@@ -171,7 +182,7 @@ Namespace API.XVIDEOS
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
End Sub
|
||||
Private Function GetVideoData(ByVal Media As UserMedia, ByVal resp As Response, ByVal DownloadUHD As Boolean) As UserMedia
|
||||
Private Function GetVideoData(ByVal Media As UserMedia, ByVal resp As Responser, ByVal DownloadUHD As Boolean) As UserMedia
|
||||
Try
|
||||
If Not Media.URL.IsEmptyString Then
|
||||
Dim r$ = resp.GetResponse(Media.URL)
|
||||
@@ -217,7 +228,7 @@ Namespace API.XVIDEOS
|
||||
Return Nothing
|
||||
End Try
|
||||
End Function
|
||||
Friend Function Download(ByVal URL As String, ByVal resp As Response, ByVal DownloadUHD As Boolean, ByVal ID As String)
|
||||
Friend Function Download(ByVal URL As String, ByVal resp As Responser, ByVal DownloadUHD As Boolean, ByVal ID As String)
|
||||
Dim m As UserMedia = GetVideoData(New UserMedia(URL, UTypes.VideoPre) With {.Post = ID}, resp, DownloadUHD)
|
||||
If Not m.URL.IsEmptyString Then
|
||||
Dim f As SFile = m.File
|
||||
|
||||
@@ -14,7 +14,7 @@ Namespace API.Xhamster
|
||||
Friend NotInheritable Class M3U8
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Private Shared Function ParseFirstM3U8(ByVal URL As String, ByVal Responser As Response, ByVal UHD As Boolean) As String
|
||||
Private Shared Function ParseFirstM3U8(ByVal URL As String, ByVal Responser As Responser, ByVal UHD As Boolean) As String
|
||||
Dim r$, d$
|
||||
Dim _DataObtained As Boolean = False
|
||||
For i% = 0 To 1
|
||||
@@ -38,7 +38,7 @@ Namespace API.Xhamster
|
||||
Next
|
||||
Return String.Empty
|
||||
End Function
|
||||
Private Shared Function ParseSecondM3U8(ByVal URL As String, ByVal Responser As Response, ByVal Appender As String) As List(Of String)
|
||||
Private Shared Function ParseSecondM3U8(ByVal URL As String, ByVal Responser As Responser, ByVal Appender As String) As List(Of String)
|
||||
Dim r$
|
||||
Dim l As List(Of String)
|
||||
For i% = 0 To 1
|
||||
@@ -57,7 +57,7 @@ Namespace API.Xhamster
|
||||
Next
|
||||
Return Nothing
|
||||
End Function
|
||||
Private Shared Function ObtainUrls(ByVal URL As String, ByVal Responser As Response, ByVal UHD As Boolean) As List(Of String)
|
||||
Private Shared Function ObtainUrls(ByVal URL As String, ByVal Responser As Responser, ByVal UHD As Boolean) As List(Of String)
|
||||
Try
|
||||
Dim file$ = ParseFirstM3U8(URL, Responser, UHD)
|
||||
If Not file.IsEmptyString Then
|
||||
@@ -72,7 +72,7 @@ Namespace API.Xhamster
|
||||
Responser.UseGZipStream = False
|
||||
End Try
|
||||
End Function
|
||||
Friend Shared Function Download(ByVal Media As UserMedia, ByVal Responser As Response, ByVal UHD As Boolean) As SFile
|
||||
Friend Shared Function Download(ByVal Media As UserMedia, ByVal Responser As Responser, ByVal UHD As Boolean) As SFile
|
||||
Return M3U8Base.Download(ObtainUrls(Media.URL, Responser, UHD), Media.File, Responser)
|
||||
End Function
|
||||
End Class
|
||||
|
||||
@@ -59,7 +59,8 @@ Namespace API.Xhamster
|
||||
DownloadUHD = New PropertyValue(False)
|
||||
|
||||
UrlPatternUser = "https://xhamster.com/users/{0}"
|
||||
UserRegex = RParams.DMS("xhamster.com/users/([^/]+).*?", 1)
|
||||
UrlPatternChannel = "https://xhamster.com/channels/{0}"
|
||||
UserRegex = RParams.DMS($"/({UserOption}|{ChannelOption})/([^/]+)(\Z|.*)", 0, RegexReturn.ListByMatch)
|
||||
ImageVideoContains = "xhamster"
|
||||
End Sub
|
||||
Friend Overrides Sub EndInit()
|
||||
@@ -102,7 +103,7 @@ Namespace API.Xhamster
|
||||
End Function
|
||||
Friend Overrides Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable
|
||||
If Available(ISiteSettings.Download.Main, True) Then
|
||||
Using resp As Response = Responser.Copy
|
||||
Using resp As Responser = Responser.Copy
|
||||
Dim spf$ = String.Empty
|
||||
Dim f As SFile = GetSpecialDataFile(Path, AskForPath, spf)
|
||||
Dim m As UserMedia = UserData.GetVideoInfo(URL, resp, f)
|
||||
@@ -114,10 +115,10 @@ Namespace API.Xhamster
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, Silent As Boolean) As Boolean
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||
If Settings.UseM3U8 AndAlso MyBase.Available(What, Silent) Then
|
||||
If What = ISiteSettings.Download.SavedPosts Then
|
||||
Return If(Responser.Cookies?.Count, 0) > 0
|
||||
Return Responser.CookiesExists
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
@@ -129,18 +130,12 @@ Namespace API.Xhamster
|
||||
Return Media.URL_BASE
|
||||
End Function
|
||||
#Region "Is my user/data"
|
||||
Private Const UserRegexDefault As String = "{0}/users/([^/]+).*?"
|
||||
Private Const ChannelOption As String = "channels"
|
||||
Private Const UserOption As String = "users"
|
||||
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||
Dim b As ExchangeOptions = MyBase.IsMyUser(UserURL)
|
||||
If b.Exists Then Return b
|
||||
If Not UserURL.IsEmptyString And Domains.Count > 0 Then
|
||||
Dim uName$, fStr$
|
||||
Dim uErr As New ErrorsDescriber(EDP.ReturnValue)
|
||||
For i% = 0 To Domains.Count - 1
|
||||
fStr = String.Format(UserRegexDefault, Domains(i))
|
||||
uName = RegexReplace(UserURL, RParams.DMS(fStr, 1, uErr))
|
||||
If Not uName.IsEmptyString Then Return New ExchangeOptions(Site, uName)
|
||||
Next
|
||||
If Not UserURL.IsEmptyString AndAlso Domains.Count > 0 AndAlso Domains.Exists(Function(d) UserURL.ToLower.Contains(d.ToLower)) Then
|
||||
Dim data As List(Of String) = RegexReplace(UserURL, UserRegex)
|
||||
If data.ListExists(3) AndAlso Not data(2).IsEmptyString Then Return New ExchangeOptions(Site, data(2), data(1) = ChannelOption)
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
|
||||
@@ -38,7 +38,7 @@ Namespace API.Xhamster
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
_TempPhotoData.Clear()
|
||||
If DownloadVideos Then DownloadData(1, True, Token)
|
||||
If DownloadImages Then
|
||||
If Not IsChannel And DownloadImages Then
|
||||
DownloadData(1, False, Token)
|
||||
ReparsePhoto(Token)
|
||||
End If
|
||||
@@ -50,11 +50,16 @@ Namespace API.Xhamster
|
||||
Dim Type As UTypes = IIf(IsVideo, UTypes.VideoPre, UTypes.Picture)
|
||||
Dim mPages$ = IIf(IsVideo, "maxVideoPages", "maxPhotoPages")
|
||||
Dim listNode$()
|
||||
Dim skipped As Boolean = False
|
||||
Dim cBefore% = _TempMediaList.Count
|
||||
Dim m As UserMedia
|
||||
|
||||
If IsSavedPosts Then
|
||||
URL = $"https://xhamster.com/my/favorites/{IIf(IsVideo, "videos", "photos-and-galleries")}{IIf(Page = 1, String.Empty, $"/{Page}")}"
|
||||
listNode = If(IsVideo, {"favoriteVideoListComponent", "models"}, {"favoritesGalleriesAndPhotosCollection"})
|
||||
ElseIf IsChannel Then
|
||||
URL = $"https://xhamster.com/channels/{Name}/newest{IIf(Page = 1, String.Empty, $"/{Page}")}"
|
||||
listNode = {"trendingVideoListComponent", "models"}
|
||||
Else
|
||||
URL = $"https://xhamster.com/users/{Name}/{IIf(IsVideo, "videos", "photos")}{IIf(Page = 1, String.Empty, $"/{Page}")}"
|
||||
listNode = {If(IsVideo, "userVideoCollection", "userGalleriesCollection")}
|
||||
@@ -80,7 +85,7 @@ Namespace API.Xhamster
|
||||
|
||||
If m.Post.Date.HasValue Then
|
||||
Select Case CheckDatesLimit(m.Post.Date.Value, Nothing)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Skip : skipped = True : Continue For
|
||||
Case DateResult.Exit : Exit Sub
|
||||
End Select
|
||||
End If
|
||||
@@ -108,7 +113,7 @@ Namespace API.Xhamster
|
||||
End Using
|
||||
End If
|
||||
|
||||
If MaxPage > 0 AndAlso Page < MaxPage Then DownloadData(Page + 1, IsVideo, Token)
|
||||
If (Not _TempMediaList.Count = cBefore Or skipped) And (IsChannel Or (MaxPage > 0 And Page < MaxPage)) Then DownloadData(Page + 1, IsVideo, Token)
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
@@ -219,7 +224,7 @@ Namespace API.Xhamster
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "GetM3U8"
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal URL As String, ByVal Responser As Response,
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal URL As String, ByVal Responser As Responser,
|
||||
Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
|
||||
Try
|
||||
If Not URL.IsEmptyString Then
|
||||
@@ -248,7 +253,7 @@ Namespace API.Xhamster
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Standalone downloader"
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Response, ByVal Path As SFile) As UserMedia
|
||||
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal Responser As Responser, ByVal Path As SFile) As UserMedia
|
||||
Try
|
||||
Using u As New UserData With {.Responser = Responser, .HOST = Settings(XhamsterSiteKey)}
|
||||
Dim m As UserMedia = Nothing
|
||||
@@ -286,7 +291,7 @@ Namespace API.Xhamster
|
||||
.ID = j.Value("id"),
|
||||
.Date = AConvert(Of Date)(j.Value("created"), DateProvider, Nothing)
|
||||
},
|
||||
.PictureOption = j.Value("title").StringRemoveWinForbiddenSymbols,
|
||||
.PictureOption = TitleHtmlConverter(j.Value("title")),
|
||||
.Object = New ExchObj
|
||||
}
|
||||
If PostDate.HasValue Then m.Post.Date = PostDate
|
||||
@@ -309,7 +314,7 @@ Namespace API.Xhamster
|
||||
End If
|
||||
If Not m.URL.IsEmptyString Then
|
||||
If m.Post.ID.IsEmptyString Then m.Post.ID = m.URL.Split("/").LastOrDefault
|
||||
If m.PictureOption.IsEmptyString Then m.PictureOption = j.Value("titleLocalized").StringRemoveWinForbiddenSymbols
|
||||
If m.PictureOption.IsEmptyString Then m.PictureOption = TitleHtmlConverter(j.Value("titleLocalized"))
|
||||
If m.PictureOption.IsEmptyString Then m.PictureOption = m.Post.ID
|
||||
If setSpecialFolder Then m.SpecialFolder = m.PictureOption
|
||||
|
||||
@@ -334,7 +339,7 @@ Namespace API.Xhamster
|
||||
Return If(Responser.Status = Net.WebExceptionStatus.ConnectionClosed, 1, 0)
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Idisposable support"
|
||||
#Region "IDisposable support"
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then _TempPhotoData.Clear()
|
||||
MyBase.Dispose(disposing)
|
||||
|
||||
@@ -211,8 +211,8 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
New ToolStripSeparator,
|
||||
New ToolStripControlHost(CH_HIDE_EXISTS_USERS),
|
||||
BTT_SHOW_STATS})
|
||||
AddHandler Settings.ChannelsImagesColumns.OnValueChanged, AddressOf ImagesCountChanged
|
||||
AddHandler Settings.ChannelsImagesRows.OnValueChanged, AddressOf ImagesCountChanged
|
||||
AddHandler Settings.ChannelsImagesColumns.ValueChanged, AddressOf ImagesCountChanged
|
||||
AddHandler Settings.ChannelsImagesRows.ValueChanged, AddressOf ImagesCountChanged
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form handlers"
|
||||
@@ -398,7 +398,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
||||
End With
|
||||
Return s
|
||||
End Function
|
||||
Private Sub ImagesCountChanged(ByVal Sender As Object, ByVal _Name As String, ByVal _Value As Object)
|
||||
Private Sub ImagesCountChanged(ByVal Sender As Object, ByVal e As EventArgs)
|
||||
AppendPendingUsers()
|
||||
MyRange.Limit = ImagesInRow * ImagesRows
|
||||
MyRange.GoTo(0)
|
||||
|
||||
BIN
SCrawler/Content/Pictures/TagPic_24.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@@ -143,7 +143,8 @@ Namespace DownloadObjects
|
||||
''' <returns>True to activate</returns>
|
||||
Friend Function Open(ByVal _Key As String) As Boolean
|
||||
If Not User Is Nothing Then
|
||||
If Key = _Key Then
|
||||
If KeyDismiss = _Key Then
|
||||
ElseIf Key = _Key Then
|
||||
Return True
|
||||
ElseIf KeyFolder = _Key Then
|
||||
User.OpenFolder()
|
||||
@@ -152,6 +153,8 @@ Namespace DownloadObjects
|
||||
ElseIf Images.ContainsKey(_Key) Then
|
||||
Images(_Key).Open(, EDP.None)
|
||||
End If
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
@@ -471,18 +474,25 @@ Namespace DownloadObjects
|
||||
Dim DownloadedUsersCount% = 0
|
||||
Dim simple As Boolean = ShowSimpleNotification And ShowNotifications
|
||||
Dim notify As Action = Sub()
|
||||
With Downloader.Downloaded
|
||||
If ShowNotifications And .Count > 0 Then .ForEach(Sub(ByVal u As IUserData)
|
||||
If Keys.Contains(u.Key) Then
|
||||
If simple Then
|
||||
DownloadedUsersCount += 1
|
||||
Else
|
||||
ShowNotification(u)
|
||||
End If
|
||||
Keys.Remove(u.Key)
|
||||
End If
|
||||
End Sub)
|
||||
End With
|
||||
Try
|
||||
With Downloader.Downloaded
|
||||
If ShowNotifications And .Count > 0 Then
|
||||
For indx% = 0 To .Count - 1
|
||||
With .Item(indx)
|
||||
If Keys.Contains(.Key) Then
|
||||
If simple Then
|
||||
DownloadedUsersCount += 1
|
||||
Else
|
||||
ShowNotification(.Self)
|
||||
End If
|
||||
Keys.Remove(.Key)
|
||||
End If
|
||||
End With
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
Catch n_ex As Exception
|
||||
End Try
|
||||
End Sub
|
||||
Select Case Mode
|
||||
Case Modes.All
|
||||
@@ -541,10 +551,12 @@ Namespace DownloadObjects
|
||||
UserKeys.Last.ShowNotification()
|
||||
End If
|
||||
End Sub
|
||||
Friend Function NotificationClicked(ByVal Key As String) As Boolean
|
||||
Friend Function NotificationClicked(ByVal Key As String, ByRef Found As Boolean, ByRef ActivateForm As Boolean) As Boolean
|
||||
Dim i% = UserKeys.IndexOf(Key)
|
||||
If i >= 0 Then
|
||||
MainFrameObj.FocusUser(UserKeys(i).IUserDataKey, UserKeys(i).Open(Key))
|
||||
Found = True
|
||||
ActivateForm = UserKeys(i).Open(Key)
|
||||
MainFrameObj.FocusUser(UserKeys(i).IUserDataKey, ActivateForm)
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
|
||||
@@ -52,8 +52,13 @@ Namespace DownloadObjects
|
||||
Return Plans.Count
|
||||
End Get
|
||||
End Property
|
||||
Friend Function NotificationClicked(ByVal Key As String) As Boolean
|
||||
Return Count > 0 AndAlso Plans.Exists(Function(p) p.NotificationClicked(Key))
|
||||
Friend Function NotificationClicked(ByVal Key As String, ByRef Found As Boolean, ByRef ActivateForm As Boolean) As Boolean
|
||||
If Count > 0 Then
|
||||
For Each plan As AutoDownloader In Plans
|
||||
If plan.NotificationClicked(Key, Found, ActivateForm) Then Return True
|
||||
Next
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
Friend Sub Add(ByVal Plan As AutoDownloader)
|
||||
Plan.Source = Me
|
||||
|
||||
@@ -150,8 +150,8 @@ Namespace DownloadObjects
|
||||
Private Sub BTT_FIND_Click(sender As Object, e As EventArgs) Handles BTT_FIND.Click
|
||||
Try
|
||||
If _LatestSelected.ValueBetween(0, LIST_DOWN.Items.Count - 1) AndAlso _LatestSelected.ValueBetween(0, Downloader.Downloaded.Count - 1) Then
|
||||
Dim i% = Settings.Users.IndexOf(_TempUsersList(_LatestSelected))
|
||||
If i >= 0 Then RaiseEvent UserFind(Settings.Users(i).Key)
|
||||
Dim u As IUserData = Settings.GetUser(_TempUsersList(_LatestSelected), True)
|
||||
If Not u Is Nothing Then RaiseEvent UserFind(u.Key)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
|
||||
@@ -25,6 +25,8 @@ Namespace DownloadObjects
|
||||
Private FeedEndless As Boolean = False
|
||||
Private ReadOnly FileNotExist As New FPredicate(Of UserMediaD)(Function(d) Not d.Data.File.Exists)
|
||||
Private BttRefreshToolTipText As String = "Refresh data list"
|
||||
Private CenterImage As Boolean = False
|
||||
Private NumberOfVisibleImages As Integer = 1
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New()
|
||||
@@ -81,6 +83,25 @@ Namespace DownloadObjects
|
||||
DataRows = .FeedDataRows
|
||||
DataColumns = .FeedDataColumns
|
||||
FeedEndless = .FeedEndless
|
||||
If .FeedCenterImage.Use Then
|
||||
CenterImage = True
|
||||
NumberOfVisibleImages = .FeedCenterImage
|
||||
Else
|
||||
CenterImage = False
|
||||
NumberOfVisibleImages = 1
|
||||
End If
|
||||
|
||||
If .FeedBackColor.Exists Then
|
||||
BackColor = .FeedBackColor
|
||||
Else
|
||||
BackColor = SystemColors.Window
|
||||
End If
|
||||
If .FeedForeColor.Exists Then
|
||||
ForeColor = .FeedForeColor
|
||||
Else
|
||||
ForeColor = SystemColors.WindowText
|
||||
End If
|
||||
|
||||
Dim fsd As Boolean = .FeedStoreSessionsData
|
||||
ControlInvoke(ToolbarTOP, MENU_LOAD_SESSION, Sub()
|
||||
MENU_LOAD_SESSION.Visible = fsd
|
||||
@@ -107,7 +128,7 @@ Namespace DownloadObjects
|
||||
MyRange.HandlersSuspended = True
|
||||
MyRange.Limit = c
|
||||
MyRange.HandlersSuspended = False
|
||||
If Not MyDefs.Initializing And rangeChanged Then RefillList()
|
||||
If Not MyDefs.Initializing Then RefillList(False)
|
||||
End With
|
||||
End Sub
|
||||
#End Region
|
||||
@@ -376,9 +397,10 @@ Namespace DownloadObjects
|
||||
If d2.Count > 0 Then d.InsertRange(0, d2) : d2.Clear()
|
||||
End If
|
||||
Dim w% = GetWidth()
|
||||
Dim h% = GetHeight()
|
||||
Dim p As New TPCELL(DataRows, DataColumns)
|
||||
Dim fmList As New List(Of FeedMedia)
|
||||
d.ForEach(Sub(de) fmList.Add(New FeedMedia(de, w, AddressOf FeedMedia_MediaDeleted)))
|
||||
d.ForEach(Sub(de) fmList.Add(New FeedMedia(de, w, h, AddressOf FeedMedia_MediaDeleted)))
|
||||
If fmList.Count > 0 Then fmList.ListDisposeRemoveAll(Function(fm) fm Is Nothing OrElse fm.HasError)
|
||||
If fmList.Count > 0 Then
|
||||
For i = 0 To fmList.Count - 1
|
||||
@@ -420,6 +442,13 @@ Namespace DownloadObjects
|
||||
Private Function GetWidth() As Integer
|
||||
Return (TP_DATA.Width - PaddingE.GetOf({Me, TP_DATA}).Horizontal(2)) / DataColumns
|
||||
End Function
|
||||
Private Function GetHeight() As Integer
|
||||
If CenterImage And DataColumns = 1 Then
|
||||
Return (TP_DATA.Height - PaddingE.GetOf({Me, TP_DATA}).Vertical(2)) / IIf(NumberOfVisibleImages > 0, NumberOfVisibleImages, 1)
|
||||
Else
|
||||
Return -1
|
||||
End If
|
||||
End Function
|
||||
Private Sub DownloadFeedForm_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
|
||||
ResizeGrid()
|
||||
End Sub
|
||||
@@ -431,10 +460,11 @@ Namespace DownloadObjects
|
||||
With TP_DATA
|
||||
If .Controls.Count > 0 Then
|
||||
Dim w% = GetWidth()
|
||||
Dim h% = GetHeight()
|
||||
Dim p As TableLayoutPanelCellPosition
|
||||
Dim rh As New Dictionary(Of Integer, List(Of Integer))
|
||||
For Each cnt As FeedMedia In .Controls
|
||||
cnt.Width = w
|
||||
cnt.RerenderObject(w, h)
|
||||
p = .GetCellPosition(cnt)
|
||||
If Not rh.ContainsKey(p.Row) Then rh.Add(p.Row, New List(Of Integer))
|
||||
rh(p.Row).Add(cnt.Height)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
'Imports System.Windows.Forms.PropertyGridInternal
|
||||
Imports System.ComponentModel
|
||||
Imports SCrawler.API.Base
|
||||
Imports PersonalUtilities.Forms
|
||||
@@ -30,19 +29,19 @@ Namespace DownloadObjects
|
||||
End Property
|
||||
Friend ReadOnly Property HasError As Boolean
|
||||
Friend ReadOnly File As SFile
|
||||
Public Shadows Property Width As Integer
|
||||
Public Shadows Property Width(Optional ByVal UpdateImage As Boolean = True) As Integer
|
||||
Get
|
||||
Return MyBase.Width
|
||||
End Get
|
||||
Set(ByVal w As Integer)
|
||||
If Size.Width <> w Then
|
||||
Dim s As New Size(w, If(MyImage Is Nothing, VideoHeight, MyImage.FitToWidthF(w).Height))
|
||||
Dim s As New Size(w, If(MyImage Is Nothing, VideoHeight, If(UpdateImage, MyImage.FitToWidthF(w).Height, MyPicture.Height)))
|
||||
Dim objSize As Size = s
|
||||
objSize.Height += (TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2))
|
||||
objSize.Height += ObjectsPaddingHeight
|
||||
MinimumSize = objSize
|
||||
MyBase.MaximumSize = objSize
|
||||
Size = objSize
|
||||
If Not MyImage Is Nothing Then
|
||||
If UpdateImage AndAlso Not MyImage Is Nothing Then
|
||||
With MyPicture
|
||||
.MinimumSize = Nothing
|
||||
.MaximumSize = Nothing
|
||||
@@ -54,6 +53,11 @@ Namespace DownloadObjects
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Private ReadOnly Property ObjectsPaddingHeight
|
||||
Get
|
||||
Return TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2)
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly UserKey As String
|
||||
Private ReadOnly Post As UserMedia
|
||||
Friend ReadOnly Property Checked As Boolean
|
||||
@@ -62,12 +66,56 @@ Namespace DownloadObjects
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property Information As String
|
||||
Private Function GetImageResize(ByVal Width As Integer, ByVal Height As Integer) As Size
|
||||
If Height > 0 Then
|
||||
Dim h% = Height = ObjectsPaddingHeight
|
||||
If h <= 0 Then h = Height
|
||||
Dim s As Size = MyImage.FitToHeightF(h)
|
||||
s = MyImage.FitToWidthF(s, Width, False)
|
||||
If s.Height > MyImage.Height Then s = MyImage.Size
|
||||
Return s
|
||||
Else
|
||||
Return MyImage.FitToWidthF(Width)
|
||||
End If
|
||||
End Function
|
||||
Friend Sub RerenderObject(ByVal Width As Integer, ByVal Height As Integer)
|
||||
If Not MyImage Is Nothing Then
|
||||
Dim s As Size
|
||||
If Height > 0 Then
|
||||
s = GetImageResize(Width, Height)
|
||||
With MyPicture
|
||||
.MinimumSize = Nothing
|
||||
.MaximumSize = Nothing
|
||||
.Size = s
|
||||
.MinimumSize = s
|
||||
.MaximumSize = s
|
||||
.Anchor = AnchorStyles.Top
|
||||
End With
|
||||
Me.Width(False) = Width
|
||||
Else
|
||||
Me.Width = Width
|
||||
MyPicture.Anchor = AnchorStyles.Left + AnchorStyles.Top
|
||||
End If
|
||||
Else
|
||||
Me.Width = Width
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ApplyColors()
|
||||
If Settings.FeedBackColor.Exists Then
|
||||
BackColor = Settings.FeedBackColor
|
||||
LBL_INFO.BackColor = Settings.FeedBackColor
|
||||
End If
|
||||
If Settings.FeedForeColor.Exists Then
|
||||
ForeColor = Settings.FeedForeColor
|
||||
LBL_INFO.ForeColor = Settings.FeedForeColor
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializers"
|
||||
Public Sub New()
|
||||
InitializeComponent()
|
||||
End Sub
|
||||
Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Handler As MediaDeletedEventHandler)
|
||||
Friend Sub New(ByVal Media As UserMediaD, ByVal Width As Integer, ByVal Height As Integer, ByVal Handler As MediaDeletedEventHandler)
|
||||
Try
|
||||
InitializeComponent()
|
||||
File = Media.Data.File
|
||||
@@ -93,14 +141,15 @@ Namespace DownloadObjects
|
||||
Select Case Media.Data.Type
|
||||
Case UserMedia.Types.Picture, UserMedia.Types.GIF
|
||||
MyImage = New ImageRenderer(File)
|
||||
s = MyImage.FitToWidthF(Width)
|
||||
Dim a As AnchorStyles = AnchorStyles.Top + If(Height > 0, 0, AnchorStyles.Left)
|
||||
s = GetImageResize(Width, Height)
|
||||
h = s.Height
|
||||
MyPicture = New PictureBox With {
|
||||
.SizeMode = PictureBoxSizeMode.Zoom,
|
||||
.Image = MyImage,
|
||||
.InitialImage = .Image,
|
||||
.Dock = DockStyle.None,
|
||||
.Anchor = AnchorStyles.Left + AnchorStyles.Top,
|
||||
.Anchor = a,
|
||||
.Size = s,
|
||||
.MinimumSize = s,
|
||||
.MaximumSize = s,
|
||||
@@ -115,6 +164,7 @@ Namespace DownloadObjects
|
||||
Case UserMedia.Types.Video, UserMedia.Types.m3u8
|
||||
infoType = UserMedia.Types.Video
|
||||
MyVideo = New FeedVideo(File) With {.Tag = File, .Dock = DockStyle.Fill, .ContextMenuStrip = CONTEXT_DATA}
|
||||
If MyVideo.HasError Then HasError = True
|
||||
TP_MAIN.Controls.Add(MyVideo, 0, 1)
|
||||
BTT_CONTEXT_OPEN_MEDIA.Text &= " video"
|
||||
BTT_CONTEXT_DELETE.Text &= " video"
|
||||
@@ -141,11 +191,11 @@ Namespace DownloadObjects
|
||||
If Settings.FeedAddDateToCaption Then info &= $" ({Media.Date.ToStringDate(ADateTime.Formats.BaseDateTime)})"
|
||||
LBL_INFO.Text = info
|
||||
|
||||
s = New Size(Width, h + TP_MAIN.RowStyles(0).Height + PaddingE.GetOf({TP_MAIN}).Vertical(2))
|
||||
s = New Size(Width, h + ObjectsPaddingHeight)
|
||||
Size = s
|
||||
MinimumSize = s
|
||||
MaximumSize = s
|
||||
|
||||
ApplyColors()
|
||||
If Not Handler Is Nothing Then AddHandler Me.MediaDeleted, Handler
|
||||
Else
|
||||
Throw New ArgumentNullException With {.HelpLink = 1}
|
||||
|
||||
@@ -38,6 +38,7 @@ Namespace DownloadObjects
|
||||
Private VideoLengthMs As Integer = 0
|
||||
Private VideoLengthStr As String
|
||||
Private MediaFile As SFile = Nothing
|
||||
Friend ReadOnly HasError As Boolean = False
|
||||
Public Sub New()
|
||||
InitializeComponent()
|
||||
End Sub
|
||||
@@ -63,7 +64,6 @@ Namespace DownloadObjects
|
||||
MyVideo.BackgroundImageLayout = ImageLayout.Zoom
|
||||
End If
|
||||
Catch img_set_ex As Exception
|
||||
'TODELETE: FeedVideo set BackgroundImage error
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, img_set_ex, "Error setting background image for media player." & vbCr &
|
||||
$"File: {File}{vbCr}Image: {f}")
|
||||
End Try
|
||||
@@ -71,8 +71,8 @@ Namespace DownloadObjects
|
||||
End If
|
||||
UpdateButtons()
|
||||
Catch ex As Exception
|
||||
'TODELETE: FeedVideo initialization error
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, $"Media player initialization error({File})")
|
||||
HasError = True
|
||||
End Try
|
||||
End Sub
|
||||
Private _Disposed As Boolean = False
|
||||
|
||||
@@ -90,18 +90,7 @@ Namespace DownloadObjects.Groups
|
||||
End Sub
|
||||
Friend Sub New(ByVal e As EContainer)
|
||||
Me.New
|
||||
If e.Attributes.Contains(New EAttribute(Name_Name)) Then
|
||||
'TODELETE: 2022.10.18.0
|
||||
NeedToSave = True
|
||||
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)
|
||||
Else
|
||||
Import(e)
|
||||
End If
|
||||
Import(e)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "ToString"
|
||||
|
||||
@@ -34,9 +34,6 @@ Namespace DownloadObjects.Groups
|
||||
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)
|
||||
|
||||
@@ -51,7 +51,7 @@ Namespace DownloadObjects
|
||||
If Not u.Name.IsEmptyString And Not u.Site.IsEmptyString Then User = Settings.GetUser(u)
|
||||
End If
|
||||
Data = New UserMedia(e(Name_Media), User)
|
||||
[Date] = AConvert(Of Date)(e.Value(Name_Date), ParsersDataDateProvider, Now)
|
||||
[Date] = AConvert(Of Date)(e.Value(Name_Date), DateTimeDefaultProvider, Now)
|
||||
Session = e.Value(Name_Session).FromXML(Of Integer)(0)
|
||||
Dim f As SFile = e.Value(Name_File)
|
||||
If f.Exists Then Data.File = f
|
||||
@@ -78,7 +78,7 @@ Namespace DownloadObjects
|
||||
Friend Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
|
||||
Return ListAddValue(New EContainer(Name_Data, String.Empty) From {
|
||||
Data.ToEContainer,
|
||||
New EContainer(Name_Date, AConvert(Of String)([Date], ParsersDataDateProvider, String.Empty)),
|
||||
New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)),
|
||||
New EContainer(Name_Session, Session),
|
||||
New EContainer(Name_File, Data.File)},
|
||||
If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing), LAP.IgnoreICopier)
|
||||
|
||||
@@ -151,10 +151,10 @@ Namespace DownloadObjects
|
||||
Me.Controls.Add(Me.LIST_VIDEOS)
|
||||
Me.Controls.Add(Me.ToolbarBOTTOM)
|
||||
Me.Controls.Add(Me.ToolbarTOP)
|
||||
Me.Icon = Global.SCrawler.My.Resources.Resources.ArrowDownIcon_Blue_24
|
||||
Me.KeyPreview = True
|
||||
Me.MinimumSize = New System.Drawing.Size(540, 400)
|
||||
Me.Name = "VideosDownloaderForm"
|
||||
Me.ShowIcon = False
|
||||
Me.Text = "Download videos"
|
||||
Me.ToolbarTOP.ResumeLayout(False)
|
||||
Me.ToolbarTOP.PerformLayout()
|
||||
|
||||
@@ -11,12 +11,12 @@ Imports PersonalUtilities.Tools.Web.Clients
|
||||
Namespace DownloadObjects
|
||||
Friend Class WebClient2 : Implements IDisposable
|
||||
Protected WC As WebClient
|
||||
Protected RC As Response
|
||||
Protected RC As Responser
|
||||
Private ReadOnly RCERROR As New ErrorsDescriber(EDP.ThrowException)
|
||||
Protected UseResponserClient As Boolean
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
Friend Sub New(ByVal Responser As Response)
|
||||
Friend Sub New(ByVal Responser As Responser)
|
||||
If Not Responser Is Nothing Then
|
||||
RC = Responser
|
||||
UseResponserClient = True
|
||||
|
||||
141
SCrawler/Editors/ColorPicker.Designer.vb
generated
Normal file
@@ -0,0 +1,141 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace Editors
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Public Class ColorPicker : Inherits System.Windows.Forms.UserControl
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ColorPicker))
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.LBL_CAPTION = New System.Windows.Forms.Label()
|
||||
Me.LBL_COLORS = New System.Windows.Forms.Label()
|
||||
Me.BTT_COLORS_FORE = New System.Windows.Forms.Button()
|
||||
Me.BTT_COLORS_BACK = New System.Windows.Forms.Button()
|
||||
Me.BTT_COLORS_CLEAR = New System.Windows.Forms.Button()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
Me.TP_MAIN.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
Me.TP_MAIN.ColumnCount = 5
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 105.0!))
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!))
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!))
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 22.0!))
|
||||
Me.TP_MAIN.Controls.Add(Me.LBL_CAPTION, 0, 0)
|
||||
Me.TP_MAIN.Controls.Add(Me.LBL_COLORS, 1, 0)
|
||||
Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_FORE, 2, 0)
|
||||
Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_BACK, 3, 0)
|
||||
Me.TP_MAIN.Controls.Add(Me.BTT_COLORS_CLEAR, 4, 0)
|
||||
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
Me.TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_MAIN.Name = "TP_MAIN"
|
||||
Me.TP_MAIN.RowCount = 1
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MAIN.Size = New System.Drawing.Size(340, 28)
|
||||
Me.TP_MAIN.TabIndex = 3
|
||||
'
|
||||
'LBL_CAPTION
|
||||
'
|
||||
Me.LBL_CAPTION.AutoSize = True
|
||||
Me.LBL_CAPTION.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_CAPTION.Location = New System.Drawing.Point(3, 0)
|
||||
Me.LBL_CAPTION.Name = "LBL_CAPTION"
|
||||
Me.LBL_CAPTION.Size = New System.Drawing.Size(99, 28)
|
||||
Me.LBL_CAPTION.TabIndex = 0
|
||||
Me.LBL_CAPTION.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
'
|
||||
'LBL_COLORS
|
||||
'
|
||||
Me.LBL_COLORS.AutoSize = True
|
||||
Me.LBL_COLORS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LBL_COLORS.Location = New System.Drawing.Point(108, 3)
|
||||
Me.LBL_COLORS.Margin = New System.Windows.Forms.Padding(3)
|
||||
Me.LBL_COLORS.Name = "LBL_COLORS"
|
||||
Me.LBL_COLORS.Size = New System.Drawing.Size(163, 22)
|
||||
Me.LBL_COLORS.TabIndex = 1
|
||||
Me.LBL_COLORS.Text = "Here's what it looks like."
|
||||
Me.LBL_COLORS.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||
'
|
||||
'BTT_COLORS_FORE
|
||||
'
|
||||
Me.BTT_COLORS_FORE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_COLORS_FORE.Location = New System.Drawing.Point(276, 2)
|
||||
Me.BTT_COLORS_FORE.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_COLORS_FORE.Name = "BTT_COLORS_FORE"
|
||||
Me.BTT_COLORS_FORE.Size = New System.Drawing.Size(18, 24)
|
||||
Me.BTT_COLORS_FORE.TabIndex = 2
|
||||
Me.BTT_COLORS_FORE.Tag = "F"
|
||||
Me.BTT_COLORS_FORE.Text = "F"
|
||||
TT_MAIN.SetToolTip(Me.BTT_COLORS_FORE, "Font color")
|
||||
Me.BTT_COLORS_FORE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_COLORS_BACK
|
||||
'
|
||||
Me.BTT_COLORS_BACK.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_COLORS_BACK.Location = New System.Drawing.Point(298, 2)
|
||||
Me.BTT_COLORS_BACK.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_COLORS_BACK.Name = "BTT_COLORS_BACK"
|
||||
Me.BTT_COLORS_BACK.Size = New System.Drawing.Size(18, 24)
|
||||
Me.BTT_COLORS_BACK.TabIndex = 3
|
||||
Me.BTT_COLORS_BACK.Tag = "C"
|
||||
Me.BTT_COLORS_BACK.Text = "C"
|
||||
TT_MAIN.SetToolTip(Me.BTT_COLORS_BACK, "Back color")
|
||||
Me.BTT_COLORS_BACK.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_COLORS_CLEAR
|
||||
'
|
||||
Me.BTT_COLORS_CLEAR.BackgroundImage = CType(resources.GetObject("BTT_COLORS_CLEAR.BackgroundImage"), System.Drawing.Image)
|
||||
Me.BTT_COLORS_CLEAR.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
||||
Me.BTT_COLORS_CLEAR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_COLORS_CLEAR.Location = New System.Drawing.Point(320, 2)
|
||||
Me.BTT_COLORS_CLEAR.Margin = New System.Windows.Forms.Padding(2)
|
||||
Me.BTT_COLORS_CLEAR.Name = "BTT_COLORS_CLEAR"
|
||||
Me.BTT_COLORS_CLEAR.Size = New System.Drawing.Size(18, 24)
|
||||
Me.BTT_COLORS_CLEAR.TabIndex = 4
|
||||
Me.BTT_COLORS_CLEAR.Tag = "D"
|
||||
TT_MAIN.SetToolTip(Me.BTT_COLORS_CLEAR, "Reset")
|
||||
Me.BTT_COLORS_CLEAR.UseVisualStyleBackColor = True
|
||||
'
|
||||
'ColorPicker
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.Controls.Add(Me.TP_MAIN)
|
||||
Me.Name = "ColorPicker"
|
||||
Me.Size = New System.Drawing.Size(340, 28)
|
||||
Me.TP_MAIN.ResumeLayout(False)
|
||||
Me.TP_MAIN.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
Private WithEvents LBL_COLORS As Label
|
||||
Private WithEvents BTT_COLORS_FORE As Button
|
||||
Private WithEvents BTT_COLORS_BACK As Button
|
||||
Private WithEvents BTT_COLORS_CLEAR As Button
|
||||
Private WithEvents TP_MAIN As TableLayoutPanel
|
||||
Private WithEvents LBL_CAPTION As Label
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -117,10 +117,19 @@
|
||||
<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">
|
||||
<metadata name="TT_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 name="TT_MAIN.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_COLORS_CLEAR.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
113
SCrawler/Editors/ColorPicker.vb
Normal file
@@ -0,0 +1,113 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.ComponentModel
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.XML.Objects
|
||||
Namespace Editors
|
||||
Public Class ColorPicker : Implements IChangeDetectorCompatible
|
||||
Private Event DataChanged As EventHandler Implements IChangeDetectorCompatible.DataChanged
|
||||
Public Sub New()
|
||||
InitializeComponent()
|
||||
End Sub
|
||||
#Region "Appearance"
|
||||
<Category("Appearance2"), DefaultValue(105)>
|
||||
Public Property CaptionWidth As Integer
|
||||
Get
|
||||
Return TP_MAIN.ColumnStyles(0).Width
|
||||
End Get
|
||||
Set(ByVal w As Integer)
|
||||
TP_MAIN.ColumnStyles(0).Width = w
|
||||
End Set
|
||||
End Property
|
||||
Private ReadOnly ButtonsMarginDefault As New Padding(2)
|
||||
<Category("Appearance2")>
|
||||
Public Property ButtonsMargin As Padding
|
||||
Get
|
||||
Return BTT_COLORS_CLEAR.Margin
|
||||
End Get
|
||||
Set(ByVal m As Padding)
|
||||
BTT_COLORS_BACK.Margin = m
|
||||
BTT_COLORS_FORE.Margin = m
|
||||
BTT_COLORS_CLEAR.Margin = m
|
||||
End Set
|
||||
End Property
|
||||
Private Function ShouldSerializeButtonsMargin() As Boolean
|
||||
Return Not ButtonsMargin.Equals(ButtonsMarginDefault)
|
||||
End Function
|
||||
Private Sub ResetButtonsMargin()
|
||||
ButtonsMargin = ButtonsMarginDefault
|
||||
End Sub
|
||||
<Category("Appearance2"), DefaultValue("")>
|
||||
Public Property CaptionText As String
|
||||
Get
|
||||
Return LBL_CAPTION.Text
|
||||
End Get
|
||||
Set(ByVal t As String)
|
||||
LBL_CAPTION.Text = t
|
||||
End Set
|
||||
End Property
|
||||
#End Region
|
||||
#Region "Colors"
|
||||
Private BackColorDefault As Color = DefaultBackColor
|
||||
Private _BackColorImpl As Color? = Nothing
|
||||
Private Property BackColorImpl As Color?
|
||||
Get
|
||||
Return _BackColorImpl
|
||||
End Get
|
||||
Set(ByVal c As Color?)
|
||||
_BackColorImpl = c
|
||||
If _BackColorImpl.HasValue Then LBL_COLORS.BackColor = _BackColorImpl.Value Else LBL_COLORS.BackColor = BackColorDefault
|
||||
End Set
|
||||
End Property
|
||||
Private ForeColorDefault As Color = DefaultForeColor
|
||||
Private _ForeColorImpl As Color? = Nothing
|
||||
Private Property ForeColorImpl As Color?
|
||||
Get
|
||||
Return _ForeColorImpl
|
||||
End Get
|
||||
Set(ByVal c As Color?)
|
||||
_ForeColorImpl = c
|
||||
If _ForeColorImpl.HasValue Then LBL_COLORS.ForeColor = _ForeColorImpl.Value Else LBL_COLORS.ForeColor = ForeColorDefault
|
||||
End Set
|
||||
End Property
|
||||
#End Region
|
||||
#Region "Get, Set"
|
||||
Friend Sub ColorsSet(ByVal b As XMLValue(Of Color), ByVal f As XMLValue(Of Color), ByVal bDefault As Color, ByVal fDefault As Color)
|
||||
BackColorDefault = bDefault
|
||||
If b.Exists Then
|
||||
BackColorImpl = b.Value
|
||||
Else
|
||||
BackColorImpl = Nothing
|
||||
End If
|
||||
ForeColorDefault = fDefault
|
||||
If f.Exists Then
|
||||
ForeColorImpl = f.Value
|
||||
Else
|
||||
ForeColorImpl = Nothing
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub ColorsGet(ByRef b As XMLValue(Of Color), ByRef f As XMLValue(Of Color))
|
||||
If BackColorImpl.HasValue Then b.Value = BackColorImpl.Value Else b.ValueF = Nothing
|
||||
If ForeColorImpl.HasValue Then f.Value = ForeColorImpl.Value Else f.ValueF = Nothing
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Buttons handlers"
|
||||
Private Sub COLOR_BUTTONS_Click(ByVal Sender As Button, ByVal e As EventArgs) Handles BTT_COLORS_BACK.Click,
|
||||
BTT_COLORS_FORE.Click,
|
||||
BTT_COLORS_CLEAR.Click
|
||||
Select Case CStr(Sender.Tag)
|
||||
Case "F" : ForeColorImpl = AFontColor.SelectNewColor(ForeColorImpl, EDP.ReturnValue)
|
||||
Case "C" : BackColorImpl = AFontColor.SelectNewColor(BackColorImpl, EDP.ReturnValue)
|
||||
Case "D" : BackColorImpl = Nothing : ForeColorImpl = Nothing
|
||||
End Select
|
||||
RaiseEvent DataChanged(Me, Nothing)
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
314
SCrawler/Editors/GlobalSettingsForm.Designer.vb
generated
@@ -32,6 +32,10 @@ Namespace Editors
|
||||
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim LBL_DATE_POS As System.Windows.Forms.Label
|
||||
@@ -44,14 +48,14 @@ Namespace Editors
|
||||
Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TAB_BEHAVIOR As System.Windows.Forms.TabPage
|
||||
Dim TP_BEHAVIOR As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton11 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton12 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TP_OPEN_INFO As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_OPEN_PROGRESS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TAB_DOWN As System.Windows.Forms.TabPage
|
||||
Dim TP_DOWNLOADING As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton10 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton13 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton14 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TP_MISSING_DATA As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TAB_FEED As System.Windows.Forms.TabPage
|
||||
Dim TP_FEED As System.Windows.Forms.TableLayoutPanel
|
||||
@@ -68,6 +72,9 @@ Namespace Editors
|
||||
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.TXT_USER_AGENT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_USER_LIST_IMAGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.COLORS_USERLIST = New SCrawler.Editors.ColorPicker()
|
||||
Me.OPT_FILE_NAME_REPLACE = 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()
|
||||
@@ -96,6 +103,7 @@ Namespace Editors
|
||||
Me.CH_NOTIFY_CHANNELS = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_NOTIFY_SAVED_POSTS = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_DOWN_REPARSE_MISSING = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_NAME_SITE_FRIENDLY = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CH_DOWN_IMAGES_NATIVE = New System.Windows.Forms.CheckBox()
|
||||
@@ -109,11 +117,14 @@ Namespace Editors
|
||||
Me.CH_DOWN_OPEN_PROGRESS = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_DOWN_COMPLETE_SCRIPT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CH_UNAME_UP = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_FEED_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_FEED_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.CH_FEED_ENDLESS = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FEED_ADD_SESSION = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FEED_ADD_DATE = New System.Windows.Forms.CheckBox()
|
||||
Me.TXT_FEED_CENTER_IMAGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.COLORS_FEED = New SCrawler.Editors.ColorPicker()
|
||||
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
|
||||
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
|
||||
@@ -149,6 +160,8 @@ Namespace Editors
|
||||
CType(Me.TXT_MAX_JOBS_USERS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_MAX_JOBS_CHANNELS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_FILE_NAME.SuspendLayout()
|
||||
TP_FILE_PATTERNS.SuspendLayout()
|
||||
TP_CHANNELS_IMGS.SuspendLayout()
|
||||
@@ -176,6 +189,7 @@ Namespace Editors
|
||||
TP_FEED_IMG_COUNT.SuspendLayout()
|
||||
CType(Me.TXT_FEED_ROWS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_FEED_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_FEED_CENTER_IMAGE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TAB_NOTIFY.SuspendLayout()
|
||||
TP_NOTIFY_MAIN.SuspendLayout()
|
||||
Me.TAB_MAIN.SuspendLayout()
|
||||
@@ -194,13 +208,16 @@ Namespace Editors
|
||||
TP_BASIS.Controls.Add(Me.TXT_MAX_JOBS_USERS, 0, 3)
|
||||
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.TXT_IMGUR_CLIENT_ID, 0, 6)
|
||||
TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 7)
|
||||
TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 8)
|
||||
TP_BASIS.Controls.Add(Me.TXT_IMGUR_CLIENT_ID, 0, 7)
|
||||
TP_BASIS.Controls.Add(Me.CH_SHOW_GROUPS, 0, 10)
|
||||
TP_BASIS.Controls.Add(Me.CH_USERS_GROUPING, 0, 11)
|
||||
TP_BASIS.Controls.Add(Me.TXT_USER_AGENT, 0, 6)
|
||||
TP_BASIS.Controls.Add(Me.TXT_USER_LIST_IMAGE, 0, 8)
|
||||
TP_BASIS.Controls.Add(Me.COLORS_USERLIST, 0, 9)
|
||||
TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_BASIS.Location = New System.Drawing.Point(3, 3)
|
||||
TP_BASIS.Name = "TP_BASIS"
|
||||
TP_BASIS.RowCount = 10
|
||||
TP_BASIS.RowCount = 13
|
||||
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!))
|
||||
@@ -208,10 +225,14 @@ Namespace Editors
|
||||
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, 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, 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.Percent, 100.0!))
|
||||
TP_BASIS.Size = New System.Drawing.Size(570, 278)
|
||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_BASIS.Size = New System.Drawing.Size(570, 337)
|
||||
TP_BASIS.TabIndex = 0
|
||||
'
|
||||
'TXT_GLOBAL_PATH
|
||||
@@ -350,19 +371,19 @@ Namespace Editors
|
||||
Me.TXT_IMGUR_CLIENT_ID.Buttons.Add(ActionButton6)
|
||||
Me.TXT_IMGUR_CLIENT_ID.CaptionText = "Imgur Client ID"
|
||||
Me.TXT_IMGUR_CLIENT_ID.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 175)
|
||||
Me.TXT_IMGUR_CLIENT_ID.Location = New System.Drawing.Point(4, 204)
|
||||
Me.TXT_IMGUR_CLIENT_ID.Name = "TXT_IMGUR_CLIENT_ID"
|
||||
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 = 7
|
||||
'
|
||||
'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.Location = New System.Drawing.Point(4, 288)
|
||||
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.TabIndex = 10
|
||||
Me.CH_SHOW_GROUPS.Text = "Show groups"
|
||||
TT_MAIN.SetToolTip(Me.CH_SHOW_GROUPS, "Grouping users by site")
|
||||
Me.CH_SHOW_GROUPS.UseVisualStyleBackColor = True
|
||||
@@ -371,14 +392,65 @@ Namespace Editors
|
||||
'
|
||||
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.Location = New System.Drawing.Point(4, 314)
|
||||
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.TabIndex = 11
|
||||
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
|
||||
'
|
||||
'TXT_USER_AGENT
|
||||
'
|
||||
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton7.Name = "Refresh"
|
||||
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
|
||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton8.Name = "Clear"
|
||||
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_USER_AGENT.Buttons.Add(ActionButton7)
|
||||
Me.TXT_USER_AGENT.Buttons.Add(ActionButton8)
|
||||
Me.TXT_USER_AGENT.CaptionText = "UserAgent"
|
||||
Me.TXT_USER_AGENT.CaptionToolTipEnabled = True
|
||||
Me.TXT_USER_AGENT.CaptionToolTipText = "Default user agent to use in requests"
|
||||
Me.TXT_USER_AGENT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_USER_AGENT.Location = New System.Drawing.Point(4, 175)
|
||||
Me.TXT_USER_AGENT.Name = "TXT_USER_AGENT"
|
||||
Me.TXT_USER_AGENT.Size = New System.Drawing.Size(562, 22)
|
||||
Me.TXT_USER_AGENT.TabIndex = 6
|
||||
'
|
||||
'TXT_USER_LIST_IMAGE
|
||||
'
|
||||
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton9.Name = "Open"
|
||||
ActionButton9.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton10.Name = "Clear"
|
||||
ActionButton10.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton9)
|
||||
Me.TXT_USER_LIST_IMAGE.Buttons.Add(ActionButton10)
|
||||
Me.TXT_USER_LIST_IMAGE.CaptionText = "Userlist image"
|
||||
Me.TXT_USER_LIST_IMAGE.CaptionToolTipEnabled = True
|
||||
Me.TXT_USER_LIST_IMAGE.CaptionToolTipText = "Background image for user list"
|
||||
Me.TXT_USER_LIST_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_USER_LIST_IMAGE.Location = New System.Drawing.Point(4, 233)
|
||||
Me.TXT_USER_LIST_IMAGE.Name = "TXT_USER_LIST_IMAGE"
|
||||
Me.TXT_USER_LIST_IMAGE.Size = New System.Drawing.Size(562, 22)
|
||||
Me.TXT_USER_LIST_IMAGE.TabIndex = 8
|
||||
'
|
||||
'COLORS_USERLIST
|
||||
'
|
||||
Me.COLORS_USERLIST.ButtonsMargin = New System.Windows.Forms.Padding(1, 2, 1, 2)
|
||||
Me.COLORS_USERLIST.CaptionText = "Userlist colors"
|
||||
Me.COLORS_USERLIST.CaptionWidth = 103
|
||||
Me.COLORS_USERLIST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.COLORS_USERLIST.Location = New System.Drawing.Point(1, 259)
|
||||
Me.COLORS_USERLIST.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.COLORS_USERLIST.Name = "COLORS_USERLIST"
|
||||
Me.COLORS_USERLIST.Padding = New System.Windows.Forms.Padding(0, 0, 2, 0)
|
||||
Me.COLORS_USERLIST.Size = New System.Drawing.Size(568, 25)
|
||||
Me.COLORS_USERLIST.TabIndex = 9
|
||||
'
|
||||
'TP_FILE_NAME
|
||||
'
|
||||
TP_FILE_NAME.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
@@ -390,13 +462,13 @@ Namespace Editors
|
||||
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.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_FILE_NAME.Location = New System.Drawing.Point(1, 27)
|
||||
TP_FILE_NAME.Location = New System.Drawing.Point(1, 53)
|
||||
TP_FILE_NAME.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_FILE_NAME.Name = "TP_FILE_NAME"
|
||||
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.Size = New System.Drawing.Size(574, 30)
|
||||
TP_FILE_NAME.TabIndex = 1
|
||||
TP_FILE_NAME.TabIndex = 2
|
||||
'
|
||||
'OPT_FILE_NAME_REPLACE
|
||||
'
|
||||
@@ -448,14 +520,14 @@ Namespace Editors
|
||||
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.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 58)
|
||||
TP_FILE_PATTERNS.Location = New System.Drawing.Point(1, 84)
|
||||
TP_FILE_PATTERNS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_FILE_PATTERNS.Name = "TP_FILE_PATTERNS"
|
||||
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.Absolute, 29.0!))
|
||||
TP_FILE_PATTERNS.Size = New System.Drawing.Size(574, 30)
|
||||
TP_FILE_PATTERNS.TabIndex = 2
|
||||
TP_FILE_PATTERNS.TabIndex = 3
|
||||
'
|
||||
'CH_FILE_DATE
|
||||
'
|
||||
@@ -676,10 +748,10 @@ Namespace Editors
|
||||
'
|
||||
Me.CH_FEED_STORE_SESSION_DATA.AutoSize = True
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Location = New System.Drawing.Point(4, 111)
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Location = New System.Drawing.Point(4, 166)
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Name = "CH_FEED_STORE_SESSION_DATA"
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_FEED_STORE_SESSION_DATA.TabIndex = 4
|
||||
Me.CH_FEED_STORE_SESSION_DATA.TabIndex = 6
|
||||
Me.CH_FEED_STORE_SESSION_DATA.Text = "Store session data"
|
||||
TT_MAIN.SetToolTip(Me.CH_FEED_STORE_SESSION_DATA, "If checked, session data will be stored in an xml file.")
|
||||
Me.CH_FEED_STORE_SESSION_DATA.UseVisualStyleBackColor = True
|
||||
@@ -762,15 +834,27 @@ Namespace Editors
|
||||
'
|
||||
Me.CH_DOWN_REPARSE_MISSING.AutoSize = True
|
||||
Me.CH_DOWN_REPARSE_MISSING.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 176)
|
||||
Me.CH_DOWN_REPARSE_MISSING.Location = New System.Drawing.Point(4, 202)
|
||||
Me.CH_DOWN_REPARSE_MISSING.Name = "CH_DOWN_REPARSE_MISSING"
|
||||
Me.CH_DOWN_REPARSE_MISSING.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_DOWN_REPARSE_MISSING.TabIndex = 6
|
||||
Me.CH_DOWN_REPARSE_MISSING.TabIndex = 7
|
||||
Me.CH_DOWN_REPARSE_MISSING.Text = "Trying to download missing posts using regular download"
|
||||
TT_MAIN.SetToolTip(Me.CH_DOWN_REPARSE_MISSING, "If missing posts exist, the missing posts will attempt to be downloaded via user " &
|
||||
"download")
|
||||
Me.CH_DOWN_REPARSE_MISSING.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_NAME_SITE_FRIENDLY
|
||||
'
|
||||
Me.CH_NAME_SITE_FRIENDLY.AutoSize = True
|
||||
Me.CH_NAME_SITE_FRIENDLY.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_NAME_SITE_FRIENDLY.Location = New System.Drawing.Point(4, 134)
|
||||
Me.CH_NAME_SITE_FRIENDLY.Name = "CH_NAME_SITE_FRIENDLY"
|
||||
Me.CH_NAME_SITE_FRIENDLY.Size = New System.Drawing.Size(562, 19)
|
||||
Me.CH_NAME_SITE_FRIENDLY.TabIndex = 5
|
||||
Me.CH_NAME_SITE_FRIENDLY.Text = "Use the site name as a friendly name"
|
||||
TT_MAIN.SetToolTip(Me.CH_NAME_SITE_FRIENDLY, "Use the user's site name as a friendly name")
|
||||
Me.CH_NAME_SITE_FRIENDLY.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_CHANNELS_IMGS
|
||||
'
|
||||
TP_CHANNELS_IMGS.ColumnCount = 2
|
||||
@@ -822,7 +906,7 @@ Namespace Editors
|
||||
TAB_BASIS.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_BASIS.Name = "TAB_BASIS"
|
||||
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
|
||||
TAB_BASIS.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_BASIS.Size = New System.Drawing.Size(576, 343)
|
||||
TAB_BASIS.TabIndex = 0
|
||||
TAB_BASIS.Text = "Basis"
|
||||
'
|
||||
@@ -832,7 +916,7 @@ Namespace Editors
|
||||
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_DEFAULTS.Name = "TAB_DEFAULTS"
|
||||
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
|
||||
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_DEFAULTS.TabIndex = 1
|
||||
TAB_DEFAULTS.Text = "Defaults"
|
||||
'
|
||||
@@ -846,17 +930,19 @@ Namespace Editors
|
||||
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_DOWN_IMAGES_NATIVE, 0, 4)
|
||||
TP_DEFS.Controls.Add(Me.CH_NAME_SITE_FRIENDLY, 0, 5)
|
||||
TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_DEFS.Location = New System.Drawing.Point(3, 3)
|
||||
TP_DEFS.Name = "TP_DEFS"
|
||||
TP_DEFS.RowCount = 6
|
||||
TP_DEFS.RowCount = 7
|
||||
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.Size = New System.Drawing.Size(570, 278)
|
||||
TP_DEFS.Size = New System.Drawing.Size(570, 480)
|
||||
TP_DEFS.TabIndex = 0
|
||||
'
|
||||
'CH_DOWN_IMAGES_NATIVE
|
||||
@@ -876,7 +962,7 @@ Namespace Editors
|
||||
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
|
||||
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
|
||||
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_DEFS_CHANNELS.TabIndex = 4
|
||||
TAB_DEFS_CHANNELS.Text = "Channels"
|
||||
'
|
||||
@@ -900,7 +986,7 @@ Namespace Editors
|
||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_CHANNELS.Size = New System.Drawing.Size(570, 278)
|
||||
TP_CHANNELS.Size = New System.Drawing.Size(570, 480)
|
||||
TP_CHANNELS.TabIndex = 0
|
||||
'
|
||||
'TXT_CHANNEL_USER_POST_LIMIT
|
||||
@@ -928,7 +1014,7 @@ Namespace Editors
|
||||
TAB_BEHAVIOR.Controls.Add(TP_BEHAVIOR)
|
||||
TAB_BEHAVIOR.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_BEHAVIOR.Name = "TAB_BEHAVIOR"
|
||||
TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_BEHAVIOR.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_BEHAVIOR.TabIndex = 5
|
||||
TAB_BEHAVIOR.Text = "Behavior"
|
||||
'
|
||||
@@ -959,17 +1045,17 @@ Namespace Editors
|
||||
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_BEHAVIOR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 284)
|
||||
TP_BEHAVIOR.Size = New System.Drawing.Size(576, 486)
|
||||
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.Name = "Clear"
|
||||
ActionButton7.Visible = False
|
||||
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton7)
|
||||
ActionButton11.BackgroundImage = CType(resources.GetObject("ActionButton11.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton11.Enabled = False
|
||||
ActionButton11.Name = "Clear"
|
||||
ActionButton11.Visible = False
|
||||
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton11)
|
||||
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
|
||||
@@ -1008,11 +1094,11 @@ Namespace Editors
|
||||
'TXT_CLOSE_SCRIPT
|
||||
'
|
||||
Me.TXT_CLOSE_SCRIPT.AutoShowClearButton = True
|
||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton8.Enabled = False
|
||||
ActionButton8.Name = "Clear"
|
||||
ActionButton8.Visible = False
|
||||
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton8)
|
||||
ActionButton12.BackgroundImage = CType(resources.GetObject("ActionButton12.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton12.Enabled = False
|
||||
ActionButton12.Name = "Clear"
|
||||
ActionButton12.Visible = False
|
||||
Me.TXT_CLOSE_SCRIPT.Buttons.Add(ActionButton12)
|
||||
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
|
||||
@@ -1100,7 +1186,7 @@ Namespace Editors
|
||||
TAB_DOWN.Controls.Add(TP_DOWNLOADING)
|
||||
TAB_DOWN.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_DOWN.Name = "TAB_DOWN"
|
||||
TAB_DOWN.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_DOWN.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_DOWN.TabIndex = 6
|
||||
TAB_DOWN.Text = "Downloading"
|
||||
'
|
||||
@@ -1109,17 +1195,19 @@ Namespace Editors
|
||||
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(TP_FILE_NAME, 0, 2)
|
||||
TP_DOWNLOADING.Controls.Add(TP_FILE_PATTERNS, 0, 3)
|
||||
TP_DOWNLOADING.Controls.Add(Me.TXT_SCRIPT, 0, 4)
|
||||
TP_DOWNLOADING.Controls.Add(Me.CH_UDESCR_UP, 0, 0)
|
||||
TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 4)
|
||||
TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 5)
|
||||
TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 6)
|
||||
TP_DOWNLOADING.Controls.Add(Me.TXT_DOWN_COMPLETE_SCRIPT, 0, 5)
|
||||
TP_DOWNLOADING.Controls.Add(TP_MISSING_DATA, 0, 6)
|
||||
TP_DOWNLOADING.Controls.Add(Me.CH_DOWN_REPARSE_MISSING, 0, 7)
|
||||
TP_DOWNLOADING.Controls.Add(Me.CH_UNAME_UP, 0, 1)
|
||||
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 = 8
|
||||
TP_DOWNLOADING.RowCount = 9
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
@@ -1128,17 +1216,17 @@ Namespace Editors
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_DOWNLOADING.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_DOWNLOADING.Size = New System.Drawing.Size(576, 284)
|
||||
TP_DOWNLOADING.TabIndex = 0
|
||||
TP_DOWNLOADING.Size = New System.Drawing.Size(576, 486)
|
||||
TP_DOWNLOADING.TabIndex = 1
|
||||
'
|
||||
'TXT_SCRIPT
|
||||
'
|
||||
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton9.Name = "Open"
|
||||
ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton10.Name = "Clear"
|
||||
Me.TXT_SCRIPT.Buttons.Add(ActionButton9)
|
||||
Me.TXT_SCRIPT.Buttons.Add(ActionButton10)
|
||||
ActionButton13.BackgroundImage = CType(resources.GetObject("ActionButton13.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton13.Name = "Open"
|
||||
ActionButton14.BackgroundImage = CType(resources.GetObject("ActionButton14.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton14.Name = "Clear"
|
||||
Me.TXT_SCRIPT.Buttons.Add(ActionButton13)
|
||||
Me.TXT_SCRIPT.Buttons.Add(ActionButton14)
|
||||
Me.TXT_SCRIPT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
|
||||
Me.TXT_SCRIPT.CaptionText = "Script"
|
||||
Me.TXT_SCRIPT.CaptionToolTipEnabled = True
|
||||
@@ -1146,12 +1234,12 @@ Namespace Editors
|
||||
"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.Location = New System.Drawing.Point(4, 118)
|
||||
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
|
||||
Me.TXT_SCRIPT.TabIndex = 4
|
||||
'
|
||||
'TXT_DOWN_COMPLETE_SCRIPT
|
||||
'
|
||||
@@ -1161,12 +1249,12 @@ Namespace Editors
|
||||
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.Location = New System.Drawing.Point(4, 147)
|
||||
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
|
||||
Me.TXT_DOWN_COMPLETE_SCRIPT.TabIndex = 5
|
||||
'
|
||||
'TP_MISSING_DATA
|
||||
'
|
||||
@@ -1177,21 +1265,32 @@ Namespace Editors
|
||||
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_TO_LOG, 0, 0)
|
||||
TP_MISSING_DATA.Controls.Add(Me.CH_ADD_MISSING_ERROS_TO_LOG, 1, 0)
|
||||
TP_MISSING_DATA.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MISSING_DATA.Location = New System.Drawing.Point(1, 147)
|
||||
TP_MISSING_DATA.Location = New System.Drawing.Point(1, 173)
|
||||
TP_MISSING_DATA.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_MISSING_DATA.Name = "TP_MISSING_DATA"
|
||||
TP_MISSING_DATA.RowCount = 1
|
||||
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MISSING_DATA.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24.0!))
|
||||
TP_MISSING_DATA.Size = New System.Drawing.Size(574, 25)
|
||||
TP_MISSING_DATA.TabIndex = 5
|
||||
TP_MISSING_DATA.TabIndex = 6
|
||||
'
|
||||
'CH_UNAME_UP
|
||||
'
|
||||
Me.CH_UNAME_UP.AutoSize = True
|
||||
Me.CH_UNAME_UP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_UNAME_UP.Location = New System.Drawing.Point(4, 30)
|
||||
Me.CH_UNAME_UP.Name = "CH_UNAME_UP"
|
||||
Me.CH_UNAME_UP.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_UNAME_UP.TabIndex = 7
|
||||
Me.CH_UNAME_UP.Text = "Update user site name every time"
|
||||
Me.CH_UNAME_UP.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TAB_FEED
|
||||
'
|
||||
TAB_FEED.Controls.Add(TP_FEED)
|
||||
TAB_FEED.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_FEED.Name = "TAB_FEED"
|
||||
TAB_FEED.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_FEED.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_FEED.TabIndex = 7
|
||||
TAB_FEED.Text = "Feed"
|
||||
'
|
||||
@@ -1201,21 +1300,26 @@ Namespace Editors
|
||||
TP_FEED.ColumnCount = 1
|
||||
TP_FEED.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_FEED.Controls.Add(TP_FEED_IMG_COUNT, 0, 0)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ENDLESS, 0, 1)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ADD_SESSION, 0, 2)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 3)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_STORE_SESSION_DATA, 0, 4)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ENDLESS, 0, 3)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ADD_SESSION, 0, 4)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_ADD_DATE, 0, 5)
|
||||
TP_FEED.Controls.Add(Me.CH_FEED_STORE_SESSION_DATA, 0, 6)
|
||||
TP_FEED.Controls.Add(Me.TXT_FEED_CENTER_IMAGE, 0, 1)
|
||||
TP_FEED.Controls.Add(Me.COLORS_FEED, 0, 2)
|
||||
TP_FEED.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_FEED.Location = New System.Drawing.Point(0, 0)
|
||||
TP_FEED.Name = "TP_FEED"
|
||||
TP_FEED.RowCount = 6
|
||||
TP_FEED.RowCount = 8
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_FEED.Size = New System.Drawing.Size(576, 284)
|
||||
TP_FEED.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_FEED.Size = New System.Drawing.Size(576, 486)
|
||||
TP_FEED.TabIndex = 0
|
||||
'
|
||||
'TP_FEED_IMG_COUNT
|
||||
@@ -1271,10 +1375,10 @@ Namespace Editors
|
||||
'
|
||||
Me.CH_FEED_ENDLESS.AutoSize = True
|
||||
Me.CH_FEED_ENDLESS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FEED_ENDLESS.Location = New System.Drawing.Point(4, 33)
|
||||
Me.CH_FEED_ENDLESS.Location = New System.Drawing.Point(4, 88)
|
||||
Me.CH_FEED_ENDLESS.Name = "CH_FEED_ENDLESS"
|
||||
Me.CH_FEED_ENDLESS.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_FEED_ENDLESS.TabIndex = 1
|
||||
Me.CH_FEED_ENDLESS.TabIndex = 3
|
||||
Me.CH_FEED_ENDLESS.Text = "Endless feed"
|
||||
Me.CH_FEED_ENDLESS.UseVisualStyleBackColor = True
|
||||
'
|
||||
@@ -1282,10 +1386,10 @@ Namespace Editors
|
||||
'
|
||||
Me.CH_FEED_ADD_SESSION.AutoSize = True
|
||||
Me.CH_FEED_ADD_SESSION.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FEED_ADD_SESSION.Location = New System.Drawing.Point(4, 59)
|
||||
Me.CH_FEED_ADD_SESSION.Location = New System.Drawing.Point(4, 114)
|
||||
Me.CH_FEED_ADD_SESSION.Name = "CH_FEED_ADD_SESSION"
|
||||
Me.CH_FEED_ADD_SESSION.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_FEED_ADD_SESSION.TabIndex = 2
|
||||
Me.CH_FEED_ADD_SESSION.TabIndex = 4
|
||||
Me.CH_FEED_ADD_SESSION.Text = "Add the session number to the post title"
|
||||
Me.CH_FEED_ADD_SESSION.UseVisualStyleBackColor = True
|
||||
'
|
||||
@@ -1293,19 +1397,51 @@ Namespace Editors
|
||||
'
|
||||
Me.CH_FEED_ADD_DATE.AutoSize = True
|
||||
Me.CH_FEED_ADD_DATE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 85)
|
||||
Me.CH_FEED_ADD_DATE.Location = New System.Drawing.Point(4, 140)
|
||||
Me.CH_FEED_ADD_DATE.Name = "CH_FEED_ADD_DATE"
|
||||
Me.CH_FEED_ADD_DATE.Size = New System.Drawing.Size(568, 19)
|
||||
Me.CH_FEED_ADD_DATE.TabIndex = 3
|
||||
Me.CH_FEED_ADD_DATE.TabIndex = 5
|
||||
Me.CH_FEED_ADD_DATE.Text = "Add the date to the post title"
|
||||
Me.CH_FEED_ADD_DATE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TXT_FEED_CENTER_IMAGE
|
||||
'
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionSizeType = System.Windows.Forms.SizeType.Percent
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionText = "Center images in grid (number of visible images)"
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionToolTipEnabled = True
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionToolTipText = "Don't fit images to the grid, but center them and set the number of visible image" &
|
||||
"s." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Only works when the number of columns is 1."
|
||||
Me.TXT_FEED_CENTER_IMAGE.CaptionWidth = 50.0R
|
||||
Me.TXT_FEED_CENTER_IMAGE.ControlMode = PersonalUtilities.Forms.Controls.TextBoxExtended.ControlModes.NumericUpDown
|
||||
Me.TXT_FEED_CENTER_IMAGE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_FEED_CENTER_IMAGE.Location = New System.Drawing.Point(4, 33)
|
||||
Me.TXT_FEED_CENTER_IMAGE.Margin = New System.Windows.Forms.Padding(3, 3, 2, 3)
|
||||
Me.TXT_FEED_CENTER_IMAGE.Name = "TXT_FEED_CENTER_IMAGE"
|
||||
Me.TXT_FEED_CENTER_IMAGE.NumberMaximum = New Decimal(New Integer() {50, 0, 0, 0})
|
||||
Me.TXT_FEED_CENTER_IMAGE.NumberMinimum = New Decimal(New Integer() {1, 0, 0, 0})
|
||||
Me.TXT_FEED_CENTER_IMAGE.Size = New System.Drawing.Size(569, 22)
|
||||
Me.TXT_FEED_CENTER_IMAGE.TabIndex = 1
|
||||
Me.TXT_FEED_CENTER_IMAGE.Text = "1"
|
||||
Me.TXT_FEED_CENTER_IMAGE.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center
|
||||
'
|
||||
'COLORS_FEED
|
||||
'
|
||||
Me.COLORS_FEED.ButtonsMargin = New System.Windows.Forms.Padding(1, 2, 1, 2)
|
||||
Me.COLORS_FEED.CaptionText = "Feed colors"
|
||||
Me.COLORS_FEED.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.COLORS_FEED.Location = New System.Drawing.Point(1, 59)
|
||||
Me.COLORS_FEED.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.COLORS_FEED.Name = "COLORS_FEED"
|
||||
Me.COLORS_FEED.Size = New System.Drawing.Size(574, 25)
|
||||
Me.COLORS_FEED.TabIndex = 2
|
||||
'
|
||||
'TAB_NOTIFY
|
||||
'
|
||||
TAB_NOTIFY.Controls.Add(TP_NOTIFY_MAIN)
|
||||
TAB_NOTIFY.Location = New System.Drawing.Point(4, 22)
|
||||
TAB_NOTIFY.Name = "TAB_NOTIFY"
|
||||
TAB_NOTIFY.Size = New System.Drawing.Size(576, 284)
|
||||
TAB_NOTIFY.Size = New System.Drawing.Size(576, 486)
|
||||
TAB_NOTIFY.TabIndex = 8
|
||||
TAB_NOTIFY.Text = "Notifications"
|
||||
'
|
||||
@@ -1332,7 +1468,7 @@ Namespace Editors
|
||||
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_NOTIFY_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 284)
|
||||
TP_NOTIFY_MAIN.Size = New System.Drawing.Size(576, 486)
|
||||
TP_NOTIFY_MAIN.TabIndex = 0
|
||||
'
|
||||
'TAB_MAIN
|
||||
@@ -1348,7 +1484,7 @@ Namespace Editors
|
||||
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
Me.TAB_MAIN.Name = "TAB_MAIN"
|
||||
Me.TAB_MAIN.SelectedIndex = 0
|
||||
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 310)
|
||||
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 369)
|
||||
Me.TAB_MAIN.TabIndex = 1
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
@@ -1357,13 +1493,13 @@ Namespace Editors
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
|
||||
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 310)
|
||||
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 369)
|
||||
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 310)
|
||||
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 394)
|
||||
Me.CONTAINER_MAIN.TabIndex = 0
|
||||
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
@@ -1371,15 +1507,15 @@ Namespace Editors
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(584, 310)
|
||||
Me.ClientSize = New System.Drawing.Size(584, 394)
|
||||
Me.Controls.Add(Me.CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.Resources.SettingsIcon_48
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(600, 349)
|
||||
Me.MaximumSize = New System.Drawing.Size(600, 433)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(600, 349)
|
||||
Me.MinimumSize = New System.Drawing.Size(600, 433)
|
||||
Me.Name = "GlobalSettingsForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
@@ -1394,6 +1530,8 @@ Namespace Editors
|
||||
CType(Me.TXT_MAX_JOBS_USERS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_MAX_JOBS_CHANNELS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_USER_AGENT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_USER_LIST_IMAGE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_FILE_NAME.ResumeLayout(False)
|
||||
TP_FILE_NAME.PerformLayout()
|
||||
TP_FILE_PATTERNS.ResumeLayout(False)
|
||||
@@ -1431,6 +1569,7 @@ Namespace Editors
|
||||
TP_FEED_IMG_COUNT.ResumeLayout(False)
|
||||
CType(Me.TXT_FEED_ROWS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_FEED_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_FEED_CENTER_IMAGE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TAB_NOTIFY.ResumeLayout(False)
|
||||
TP_NOTIFY_MAIN.ResumeLayout(False)
|
||||
TP_NOTIFY_MAIN.PerformLayout()
|
||||
@@ -1499,5 +1638,12 @@ Namespace Editors
|
||||
Private WithEvents CH_NOTIFY_AUTO_DOWN As CheckBox
|
||||
Private WithEvents CH_NOTIFY_CHANNELS As CheckBox
|
||||
Private WithEvents CH_DOWN_REPARSE_MISSING As CheckBox
|
||||
Private WithEvents TXT_USER_AGENT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_USER_LIST_IMAGE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_FEED_CENTER_IMAGE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents CH_NAME_SITE_FRIENDLY As CheckBox
|
||||
Private WithEvents CH_UNAME_UP As CheckBox
|
||||
Private WithEvents COLORS_USERLIST As ColorPicker
|
||||
Private WithEvents COLORS_FEED As ColorPicker
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -197,6 +197,49 @@
|
||||
<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/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
||||
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
||||
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
||||
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
||||
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
||||
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
||||
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
||||
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
||||
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
||||
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
||||
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton8.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="ActionButton9.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="ActionButton10.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_FILE_NAME.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
@@ -245,7 +288,7 @@ You can find more detailed information about the missing posts in the form that
|
||||
<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">
|
||||
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
@@ -253,7 +296,7 @@ You can find more detailed information about the missing posts in the form that
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton12.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
@@ -273,7 +316,7 @@ You can find more detailed information about the missing posts in the form that
|
||||
<metadata name="TP_DOWNLOADING.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
@@ -284,7 +327,7 @@ You can find more detailed information about the missing posts in the form that
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton10.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
|
||||
@@ -31,7 +31,10 @@ Namespace Editors
|
||||
TXT_MAX_JOBS_USERS.Value = .MaxUsersJobsCount.Value
|
||||
TXT_MAX_JOBS_CHANNELS.Value = .ChannelsMaxJobsCount.Value
|
||||
CH_CHECK_VER_START.Checked = .CheckUpdatesAtStart
|
||||
TXT_USER_AGENT.Text = .UserAgent
|
||||
TXT_IMGUR_CLIENT_ID.Text = .ImgurClientID
|
||||
TXT_USER_LIST_IMAGE.Text = .UserListImage.Value
|
||||
COLORS_USERLIST.ColorsSet(.UserListBackColor, .UserListForeColor, SystemColors.Window, SystemColors.WindowText)
|
||||
CH_SHOW_GROUPS.Checked = .ShowGroups
|
||||
CH_USERS_GROUPING.Checked = .UseGrouping
|
||||
'Behavior
|
||||
@@ -60,8 +63,10 @@ Namespace Editors
|
||||
CH_DOWN_IMAGES.Checked = .DefaultDownloadImages
|
||||
CH_DOWN_VIDEOS.Checked = .DefaultDownloadVideos
|
||||
CH_DOWN_IMAGES_NATIVE.Checked = .DownloadNativeImageFormat
|
||||
CH_NAME_SITE_FRIENDLY.Checked = .UserSiteNameAsFriendly
|
||||
'Downloading
|
||||
CH_UDESCR_UP.Checked = .UpdateUserDescriptionEveryTime
|
||||
CH_UNAME_UP.Checked = .UserSiteNameUpdateEveryTime
|
||||
TXT_SCRIPT.Checked = .ScriptData.Attribute
|
||||
TXT_SCRIPT.Text = .ScriptData.Value
|
||||
TXT_DOWN_COMPLETE_SCRIPT.Text = .DownloadsCompleteCommand
|
||||
@@ -89,6 +94,10 @@ Namespace Editors
|
||||
'Feed
|
||||
TXT_FEED_ROWS.Value = .FeedDataRows.Value
|
||||
TXT_FEED_COLUMNS.Value = .FeedDataColumns.Value
|
||||
TXT_FEED_CENTER_IMAGE.Checked = .FeedCenterImage.Use
|
||||
TXT_FEED_CENTER_IMAGE.Value = .FeedCenterImage.Value
|
||||
TXT_FEED_CENTER_IMAGE.Enabled = .FeedDataColumns = 1
|
||||
COLORS_FEED.ColorsSet(.FeedBackColor, .FeedForeColor, SystemColors.Window, SystemColors.WindowText)
|
||||
CH_FEED_ENDLESS.Checked = .FeedEndless
|
||||
CH_FEED_ADD_SESSION.Checked = .FeedAddSessionToCaption
|
||||
CH_FEED_ADD_DATE.Checked = .FeedAddDateToCaption
|
||||
@@ -147,7 +156,11 @@ Namespace Editors
|
||||
.MaxUsersJobsCount.Value = CInt(TXT_MAX_JOBS_USERS.Value)
|
||||
.ChannelsMaxJobsCount.Value = TXT_MAX_JOBS_CHANNELS.Value
|
||||
.CheckUpdatesAtStart.Value = CH_CHECK_VER_START.Checked
|
||||
.UserAgent.Value = TXT_USER_AGENT.Text
|
||||
DefaultUserAgent = TXT_USER_AGENT.Text
|
||||
.ImgurClientID.Value = TXT_IMGUR_CLIENT_ID.Text
|
||||
.UserListImage.Value = TXT_USER_LIST_IMAGE.Text
|
||||
COLORS_USERLIST.ColorsGet(.UserListBackColor, .UserListForeColor)
|
||||
.ShowGroups.Value = CH_SHOW_GROUPS.Checked
|
||||
.UseGrouping.Value = CH_USERS_GROUPING.Checked
|
||||
'Behavior
|
||||
@@ -176,8 +189,10 @@ Namespace Editors
|
||||
.DefaultDownloadImages.Value = CH_DOWN_IMAGES.Checked
|
||||
.DefaultDownloadVideos.Value = CH_DOWN_VIDEOS.Checked
|
||||
.DownloadNativeImageFormat.Value = CH_DOWN_IMAGES_NATIVE.Checked
|
||||
.UserSiteNameAsFriendly.Value = CH_NAME_SITE_FRIENDLY.Checked
|
||||
'Downloading
|
||||
.UpdateUserDescriptionEveryTime.Value = CH_UDESCR_UP.Checked
|
||||
.UserSiteNameUpdateEveryTime.Value = CH_UNAME_UP.Checked
|
||||
.ScriptData.Value = TXT_SCRIPT.Text
|
||||
.ScriptData.Attribute.Value = TXT_SCRIPT.Checked
|
||||
.DownloadsCompleteCommand.Value = TXT_DOWN_COMPLETE_SCRIPT.Text
|
||||
@@ -199,6 +214,8 @@ Namespace Editors
|
||||
'Channels
|
||||
.ChannelsImagesRows.Value = CInt(TXT_CHANNELS_ROWS.Value)
|
||||
.ChannelsImagesColumns.Value = CInt(TXT_CHANNELS_COLUMNS.Value)
|
||||
.FeedCenterImage.Use = TXT_FEED_CENTER_IMAGE.Checked
|
||||
.FeedCenterImage.Value = TXT_FEED_CENTER_IMAGE.Value
|
||||
.FromChannelDownloadTop.Value = CInt(TXT_CHANNEL_USER_POST_LIMIT.Value)
|
||||
.FromChannelDownloadTopUse.Value = TXT_CHANNEL_USER_POST_LIMIT.Checked
|
||||
.FromChannelCopyImageToUser.Value = CH_COPY_CHANNEL_USER_IMAGE.Checked
|
||||
@@ -207,12 +224,15 @@ Namespace Editors
|
||||
'Feed
|
||||
.FeedDataRows.Value = CInt(TXT_FEED_ROWS.Value)
|
||||
.FeedDataColumns.Value = CInt(TXT_FEED_COLUMNS.Value)
|
||||
COLORS_FEED.ColorsGet(.FeedBackColor, .FeedForeColor)
|
||||
.FeedEndless.Value = CH_FEED_ENDLESS.Checked
|
||||
.FeedAddSessionToCaption.Value = CH_FEED_ADD_SESSION.Checked
|
||||
.FeedAddDateToCaption.Value = CH_FEED_ADD_DATE.Checked
|
||||
.FeedStoreSessionsData.Value = CH_FEED_STORE_SESSION_DATA.Checked
|
||||
FeedParametersChanged = .FeedDataRows.ChangesDetected Or .FeedDataColumns.ChangesDetected Or
|
||||
.FeedEndless.ChangesDetected Or .FeedStoreSessionsData.ChangesDetected
|
||||
.FeedEndless.ChangesDetected Or .FeedStoreSessionsData.ChangesDetected Or
|
||||
.FeedBackColor.ChangesDetected Or .FeedForeColor.ChangesDetected Or
|
||||
.FeedCenterImage.ChangesDetected
|
||||
|
||||
.EndUpdate()
|
||||
End With
|
||||
@@ -231,6 +251,9 @@ Namespace Editors
|
||||
Private Sub TXT_MAX_JOBS_CHANNELS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As EventArgs) Handles TXT_MAX_JOBS_CHANNELS.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ADB.Refresh Then TXT_MAX_JOBS_CHANNELS.Value = SettingsCLS.DefaultMaxDownloadingTasks
|
||||
End Sub
|
||||
Private Sub TXT_USER_AGENT_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_USER_AGENT.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ADB.Refresh Then TXT_USER_AGENT.Text = Settings.UserAgent.Value
|
||||
End Sub
|
||||
Private Sub ChangePositionControlsEnabling() Handles OPT_FILE_NAME_REPLACE.CheckedChanged, OPT_FILE_NAME_ADD_DATE.CheckedChanged
|
||||
Dim b As Boolean = OPT_FILE_NAME_ADD_DATE.Checked And OPT_FILE_NAME_ADD_DATE.Enabled
|
||||
OPT_FILE_DATE_START.Enabled = b
|
||||
@@ -258,5 +281,14 @@ Namespace Editors
|
||||
CH_NOTIFY_CHANNELS.Enabled = b
|
||||
CH_NOTIFY_SAVED_POSTS.Enabled = b
|
||||
End Sub
|
||||
Private Sub TXT_USER_LIST_IMAGE_ActionOnButtonClick(ByVal Sender As ActionButton, e As ActionButtonEventArgs) Handles TXT_USER_LIST_IMAGE.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ADB.Open Then
|
||||
Dim f As SFile = SFile.SelectFiles(TXT_USER_LIST_IMAGE.Text, False, "Select a new image for the user list:", "Pictures|*.jpg;*.jpeg;*.png").FirstOrDefault
|
||||
If Not f.IsEmptyString Then TXT_USER_LIST_IMAGE.Text = f
|
||||
End If
|
||||
End Sub
|
||||
Private Sub TXT_FEED_COLUMNS_ActionOnValueChanged(sender As Object, e As EventArgs) Handles TXT_FEED_COLUMNS.ActionOnValueChanged
|
||||
TXT_FEED_CENTER_IMAGE.Enabled = TXT_FEED_COLUMNS.Value = 1
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -72,7 +72,7 @@ Friend Class LabelsForm
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
Try
|
||||
LabelsList.ListAddList(CMB_LABELS.Items.CheckedItems.Select(Function(l) CStr(l.Value(0))), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
If _AnyLabelAdd And _Source Is Nothing Then Settings.Labels.Update()
|
||||
If _Source Is Nothing Then Settings.Labels.Update()
|
||||
MyDefs.CloseForm()
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Label selection")
|
||||
|
||||
@@ -101,7 +101,7 @@ Namespace Editors
|
||||
SetChecker(CH.MyImagesDown, h.DownloadImages)
|
||||
SetChecker(CH.MyVideosDown, h.DownloadVideos)
|
||||
End Sub
|
||||
Private Overloads Shared Sub SetChecker(ByRef State As CheckState, ByVal Prop As XML.Base.XMLValue(Of Boolean))
|
||||
Private Overloads Shared Sub SetChecker(ByRef State As CheckState, ByVal Prop As XML.Objects.XMLValue(Of Boolean))
|
||||
If Prop.ValueF.Exists Then
|
||||
State = If(Prop.Value, CheckState.Checked, CheckState.Unchecked)
|
||||
Else
|
||||
@@ -113,7 +113,7 @@ Namespace Editors
|
||||
SetPropByChecker(CH.MyImagesDown, h.DownloadImages)
|
||||
SetPropByChecker(CH.MyVideosDown, h.DownloadVideos)
|
||||
End Sub
|
||||
Private Overloads Shared Sub SetPropByChecker(ByVal State As CheckState, ByRef Prop As XML.Base.XMLValue(Of Boolean))
|
||||
Private Overloads Shared Sub SetPropByChecker(ByVal State As CheckState, ByRef Prop As XML.Objects.XMLValue(Of Boolean))
|
||||
Select Case State
|
||||
Case CheckState.Checked : Prop.Value = True
|
||||
Case CheckState.Unchecked : Prop.Value = False
|
||||
|
||||
@@ -12,7 +12,6 @@ Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Controls
|
||||
Imports PersonalUtilities.Forms.Controls.Base
|
||||
Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Imports CookieControl = PersonalUtilities.Tools.Web.Cookies.CookieListForm.CookieControl
|
||||
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
|
||||
Namespace Editors
|
||||
Friend Class SiteEditorForm
|
||||
@@ -213,28 +212,26 @@ Namespace Editors
|
||||
Select Case Sender.DefaultButton
|
||||
Case ADB.Edit
|
||||
If Not Host.Responser Is Nothing Then
|
||||
Using f As New CookieListForm(Host.Responser) With {
|
||||
.MyDesignXML = Settings.Design,
|
||||
.DisableControls = CookieControl.AddFromInternal + CookieControl.AuthorizeProgram + CookieControl.OpenBrowser
|
||||
}
|
||||
Using f As New CookieListForm With {.DesignXML = Settings.Design, .ShowGrid = False}
|
||||
f.SetCollection(Host.Responser.Cookies)
|
||||
f.ShowDialog()
|
||||
MyDefs.MyOkCancel.EnableOK = True
|
||||
If f.DialogResult = DialogResult.OK Then
|
||||
f.GetCollection(Host.Responser)
|
||||
MyDefs.MyOkCancel.EnableOK = True
|
||||
End If
|
||||
End Using
|
||||
SetCookieText()
|
||||
End If
|
||||
Case ADB.Clear
|
||||
If Not Host.Responser Is Nothing Then
|
||||
With Host.Responser
|
||||
If Not .Cookies Is Nothing Then .Cookies.Dispose()
|
||||
.Cookies = New CookieKeeper(.CookiesDomain)
|
||||
MyDefs.MyOkCancel.EnableOK = True
|
||||
End With
|
||||
Host.Responser.Cookies.Clear()
|
||||
MyDefs.MyOkCancel.EnableOK = True
|
||||
SetCookieText()
|
||||
End If
|
||||
End Select
|
||||
End Sub
|
||||
Private Sub SetCookieText()
|
||||
If Not Host.Responser Is Nothing Then TXT_COOKIES.Text = $"{If(Host.Responser.Cookies?.Count, 0)} cookies"
|
||||
If Not Host.Responser Is Nothing Then TXT_COOKIES.Text = $"{Host.Responser.Cookies.Count} cookies"
|
||||
End Sub
|
||||
Private Sub SpecialButton_Click(sender As Object, e As EventArgs) Handles SpecialButton.Click
|
||||
MyDefs.Detector()
|
||||
|
||||
16
SCrawler/Editors/UserCreatorForm.Designer.vb
generated
@@ -106,10 +106,10 @@ Namespace Editors
|
||||
'BTT_OTHER_SETTINGS
|
||||
'
|
||||
Me.BTT_OTHER_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(330, 2)
|
||||
Me.BTT_OTHER_SETTINGS.Location = New System.Drawing.Point(329, 2)
|
||||
Me.BTT_OTHER_SETTINGS.Margin = New System.Windows.Forms.Padding(1)
|
||||
Me.BTT_OTHER_SETTINGS.Name = "BTT_OTHER_SETTINGS"
|
||||
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(120, 24)
|
||||
Me.BTT_OTHER_SETTINGS.Size = New System.Drawing.Size(121, 24)
|
||||
Me.BTT_OTHER_SETTINGS.TabIndex = 2
|
||||
Me.BTT_OTHER_SETTINGS.Text = "Options (F2)"
|
||||
TT_MAIN.SetToolTip(Me.BTT_OTHER_SETTINGS, "Other settings")
|
||||
@@ -121,7 +121,7 @@ Namespace Editors
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(454, 436)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(454, 461)
|
||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
@@ -162,7 +162,7 @@ Namespace Editors
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MAIN.Size = New System.Drawing.Size(454, 436)
|
||||
Me.TP_MAIN.Size = New System.Drawing.Size(454, 461)
|
||||
Me.TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TXT_USER
|
||||
@@ -182,7 +182,7 @@ Namespace Editors
|
||||
Me.TP_SITE.ColumnCount = 3
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 79.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 122.0!))
|
||||
Me.TP_SITE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 123.0!))
|
||||
Me.TP_SITE.Controls.Add(Me.CH_IS_CHANNEL, 0, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.CMB_SITE, 1, 0)
|
||||
Me.TP_SITE.Controls.Add(Me.BTT_OTHER_SETTINGS, 2, 0)
|
||||
@@ -225,7 +225,7 @@ Namespace Editors
|
||||
Me.CMB_SITE.Location = New System.Drawing.Point(84, 3)
|
||||
Me.CMB_SITE.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
|
||||
Me.CMB_SITE.Name = "CMB_SITE"
|
||||
Me.CMB_SITE.Size = New System.Drawing.Size(241, 22)
|
||||
Me.CMB_SITE.Size = New System.Drawing.Size(240, 22)
|
||||
Me.CMB_SITE.TabIndex = 1
|
||||
Me.CMB_SITE.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
|
||||
'
|
||||
@@ -302,7 +302,7 @@ Namespace Editors
|
||||
Me.TXT_DESCR.Location = New System.Drawing.Point(4, 290)
|
||||
Me.TXT_DESCR.Multiline = True
|
||||
Me.TXT_DESCR.Name = "TXT_DESCR"
|
||||
Me.TXT_DESCR.Size = New System.Drawing.Size(446, 142)
|
||||
Me.TXT_DESCR.Size = New System.Drawing.Size(446, 167)
|
||||
Me.TXT_DESCR.TabIndex = 10
|
||||
'
|
||||
'TXT_USER_FRIENDLY
|
||||
@@ -469,7 +469,7 @@ Namespace Editors
|
||||
Me.Name = "UserCreatorForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.Text = "Create User"
|
||||
Me.Text = "Create user"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
|
||||
@@ -80,6 +80,8 @@ Namespace Editors
|
||||
Return TXT_SCRIPT.Text
|
||||
End Get
|
||||
End Property
|
||||
Private FriendlyNameIsSiteName As Boolean = False
|
||||
Private FriendlyNameChanged As Boolean = False
|
||||
#End Region
|
||||
#Region "Exchange, Path, Labels"
|
||||
Friend Property MyExchangeOptions As Object = Nothing
|
||||
@@ -241,12 +243,25 @@ Namespace Editors
|
||||
CMB_SITE.Enabled = False
|
||||
CH_IS_CHANNEL.Checked = User.IsChannel
|
||||
If Not UserInstance Is Nothing Then
|
||||
Text = $"User: {UserInstance.Name}"
|
||||
If Not UserInstance.FriendlyName.IsEmptyString Then Text &= $" ({UserInstance.FriendlyName})"
|
||||
TXT_USER.Enabled = False
|
||||
TXT_SPEC_FOLDER.TextBoxReadOnly = True
|
||||
TXT_SPEC_FOLDER.Buttons.Clear()
|
||||
TXT_SPEC_FOLDER.Buttons.UpdateButtonsPositions()
|
||||
With UserInstance
|
||||
If .HOST.Key = PathPlugin.PluginKey Then TXT_SPEC_FOLDER.Enabled = False
|
||||
TXT_USER_FRIENDLY.Text = .FriendlyName
|
||||
FriendlyNameIsSiteName = DirectCast(.Self, UserDataBase).FriendlyNameIsSiteName
|
||||
If FriendlyNameIsSiteName Then
|
||||
With TXT_USER_FRIENDLY
|
||||
.ControlChangeColor(True, False)
|
||||
.Buttons.AddRange({New ActionButton With {.Text = "F", .ToolTipText = "Name set by you"},
|
||||
New ActionButton With {.Text = "S", .ToolTipText = "Name from site"},
|
||||
New ActionButton(ADB.Clear)})
|
||||
.ClearTextByButtonClear = False
|
||||
End With
|
||||
End If
|
||||
CH_FAV.Checked = .Favorite
|
||||
CH_TEMP.Checked = .Temporary
|
||||
CH_PARSE_USER_MEDIA.Checked = .ParseUserMediaOnly
|
||||
@@ -273,6 +288,7 @@ Namespace Editors
|
||||
.MyFieldsChecker.EndLoaderOperations()
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
FriendlyNameChanged = False
|
||||
Catch ex As Exception
|
||||
MyDef.InvokeLoaderError(ex)
|
||||
End Try
|
||||
@@ -334,7 +350,19 @@ Namespace Editors
|
||||
If Not UserInstance Is Nothing Then
|
||||
With DirectCast(UserInstance, UserDataBase)
|
||||
.User = User
|
||||
.FriendlyName = TXT_USER_FRIENDLY.Text
|
||||
Dim setFriendly As Boolean = True
|
||||
If FriendlyNameIsSiteName Then
|
||||
If Not FriendlyNameChanged Then
|
||||
setFriendly = False
|
||||
Else
|
||||
setFriendly = MsgBoxE({"Are you sure you want to set the site name as the friendly name?" & vbCr &
|
||||
$"Friendly name: { .FriendlyNameOrig}" & vbCr &
|
||||
$"Site name: { .UserSiteName}" & vbCr &
|
||||
$"Your choice: {TXT_USER_FRIENDLY.Text}", "Friendly name change"}, vbExclamation,,,
|
||||
{"Confirm", New Messaging.MsgBoxButton("Decline", "Friendly name will not be changed")}) = 0
|
||||
End If
|
||||
End If
|
||||
If setFriendly Then .FriendlyName = TXT_USER_FRIENDLY.Text
|
||||
.Favorite = CH_FAV.Checked
|
||||
.Temporary = CH_TEMP.Checked
|
||||
.ReadyForDownload = CH_READY_FOR_DOWN.Checked
|
||||
@@ -344,7 +372,7 @@ Namespace Editors
|
||||
If Not MyExchangeOptions Is Nothing Then .ExchangeOptionsSet(MyExchangeOptions)
|
||||
Dim l As New ListAddParams(LAP.NotContainsOnly + LAP.ClearBeforeAdd)
|
||||
If .IsCollection Then
|
||||
With DirectCast(UserInstance, API.UserDataBind)
|
||||
With DirectCast(UserInstance, UserDataBind)
|
||||
If .Count > 0 Then .Collections.ForEach(Sub(c) c.Labels.ListAddList(UserLabels, l))
|
||||
End With
|
||||
Else
|
||||
@@ -385,6 +413,10 @@ CloseForm:
|
||||
If Not s.UserName.IsEmptyString Then
|
||||
Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = s.HostKey)
|
||||
If i >= 0 Then
|
||||
If s.HostKey = PathPlugin.PluginKey Then
|
||||
TXT_SPEC_FOLDER.Text = s.UserName
|
||||
s.UserName = s.UserName.CSFileP.Segments.LastOrDefault
|
||||
End If
|
||||
CMB_SITE.SelectedIndex = i
|
||||
CH_IS_CHANNEL.Checked = s.IsChannel
|
||||
TXT_USER.Text = s.UserName
|
||||
@@ -395,6 +427,7 @@ CloseForm:
|
||||
CMB_SITE.SelectedIndex = -1
|
||||
CMB_SITE.Clear(ComboBoxExtended.ClearMode.Text)
|
||||
CH_IS_CHANNEL.Checked = False
|
||||
If Not UserIsCollection Then Icon = My.Resources.UsersIcon_32
|
||||
End If
|
||||
End If
|
||||
_TextChangeInvoked = False
|
||||
@@ -405,11 +438,38 @@ CloseForm:
|
||||
Private Sub TXT_USER_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_USER.ActionOnButtonClick
|
||||
If UserIsCollection AndAlso Sender.DefaultButton = ADB.Refresh Then TXT_USER.Text = UserInstance.CollectionName
|
||||
End Sub
|
||||
Private Sub TXT_USER_FRIENDLY_ActionOnTextChanged(sender As Object, e As EventArgs) Handles TXT_USER_FRIENDLY.ActionOnTextChanged
|
||||
If Not MyDef.Initializing Then FriendlyNameChanged = True
|
||||
End Sub
|
||||
Private Sub TXT_USER_FRIENDLY_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_USER_FRIENDLY.ActionOnButtonClick
|
||||
If Sender.DefaultButton = ADB.Clear Then
|
||||
TXT_USER_FRIENDLY.Clear()
|
||||
FriendlyNameIsSiteName = False
|
||||
FriendlyNameChanged = False
|
||||
TXT_USER_FRIENDLY.ControlChangeColor(SystemColors.Window, SystemColors.WindowText)
|
||||
Else
|
||||
Select Case Sender.Text
|
||||
Case "F"
|
||||
TXT_USER_FRIENDLY.Text = DirectCast(UserInstance, UserDataBase).FriendlyNameOrig
|
||||
FriendlyNameIsSiteName = False
|
||||
FriendlyNameChanged = False
|
||||
TXT_USER_FRIENDLY.ControlChangeColor(SystemColors.Window, SystemColors.WindowText)
|
||||
Case "S"
|
||||
TXT_USER_FRIENDLY.Text = DirectCast(UserInstance, UserDataBase).UserSiteName
|
||||
FriendlyNameIsSiteName = True
|
||||
FriendlyNameChanged = False
|
||||
TXT_USER_FRIENDLY.ControlChangeColor(True, False)
|
||||
End Select
|
||||
End If
|
||||
End Sub
|
||||
Private Sub CMB_SITE_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles CMB_SITE.ActionSelectedItemChanged
|
||||
CH_IS_CHANNEL.Checked = False
|
||||
MyExchangeOptions = Nothing
|
||||
SetParamsBySite()
|
||||
End Sub
|
||||
Private Sub CMB_SITE_ActionOnTextChanged(sender As Object, e As EventArgs) Handles CMB_SITE.ActionOnTextChanged
|
||||
If CMB_SITE.Text.IsEmptyString And Not UserIsCollection Then CMB_SITE.SelectedIndex = -1 : Icon = My.Resources.UsersIcon_32
|
||||
End Sub
|
||||
Private Sub BTT_OTHER_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_OTHER_SETTINGS.Click
|
||||
Dim s As SettingsHost = GetSiteByCheckers()
|
||||
If Not s Is Nothing Then
|
||||
@@ -602,9 +662,17 @@ CloseForm:
|
||||
Else
|
||||
BTT_OTHER_SETTINGS.Enabled = False
|
||||
End If
|
||||
If Not UserIsCollection Then
|
||||
If Not s.Source.Icon Is Nothing Then
|
||||
Icon = s.Source.Icon
|
||||
ElseIf Not s.Source.Image Is Nothing Then
|
||||
Icon = ImageRenderer.GetIcon(s.Source.Image, New ErrorsDescriber(False, False, False, My.Resources.UsersIcon_32))
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
Else
|
||||
BTT_OTHER_SETTINGS.Enabled = False
|
||||
If Not UserIsCollection Then Icon = My.Resources.UsersIcon_32
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ChangeLabels()
|
||||
|
||||
@@ -10,17 +10,10 @@ Imports PersonalUtilities.Tools.Web.Clients
|
||||
Namespace EncryptCookies
|
||||
Friend Module EncryptFunction
|
||||
Friend CookiesEncrypted As Boolean = False
|
||||
Friend Sub ValidateCookiesEncrypt(ByRef Responser As Response)
|
||||
Friend Sub ValidateCookiesEncrypt(ByRef Responser As Responser)
|
||||
If Not Responser Is Nothing Then
|
||||
Dim b As Boolean = False
|
||||
With Responser
|
||||
If Not .Cookies Is Nothing Then
|
||||
With .Cookies
|
||||
If .EncryptKey.IsEmptyString Then .EncryptKey = SettingsCLS.CookieEncryptKey : b = .Count > 0
|
||||
End With
|
||||
End If
|
||||
If .CookiesEncryptKey.IsEmptyString Then .CookiesEncryptKey = SettingsCLS.CookieEncryptKey : b = True
|
||||
If b Then .SaveSettings()
|
||||
If .CookiesEncryptKey.IsEmptyString Then .CookiesEncryptKey = SettingsCLS.CookieEncryptKey : .SaveSettings()
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
' 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 PersonalUtilities.Functions.XML.Objects
|
||||
Imports PersonalUtilities.Tools
|
||||
Friend Class LabelsKeeper : Implements ICollection(Of String), IMyEnumerator(Of String), IDisposable
|
||||
Friend Event NewLabelAdded()
|
||||
@@ -25,30 +25,16 @@ Friend Class LabelsKeeper : Implements ICollection(Of String), IMyEnumerator(Of
|
||||
Friend ReadOnly Property Current As XMLValuesCollection(Of String)
|
||||
Friend ReadOnly Property Excluded As XMLValuesCollection(Of String)
|
||||
Friend ReadOnly Property ExcludedIgnore As XMLValue(Of Boolean)
|
||||
Private ReadOnly Property SourceXML As XmlFile
|
||||
Friend Sub New(ByRef x As XmlFile)
|
||||
SourceXML = x
|
||||
LabelsList = New List(Of String)
|
||||
NewLabels = New List(Of String)
|
||||
If LabelsFile.Exists Then LabelsList.ListAddList(IO.File.ReadAllLines(LabelsFile), LAP.NotContainsOnly)
|
||||
Current = New XMLValuesCollection(Of String)(XMLValueBase.ListModes.String, "LatestSelectedLabels", x) With {.ListAddParameters = LAP.NotContainsOnly}
|
||||
Excluded = New XMLValuesCollection(Of String)(XMLValueBase.ListModes.String, "LatestExcludedLabels", x) With {.ListAddParameters = LAP.NotContainsOnly}
|
||||
Current = New XMLValuesCollection(Of String)(IXMLValuesCollection.Modes.String, "LatestSelectedLabels",, x) With {.ListAddParameters = LAP.NotContainsOnly}
|
||||
Excluded = New XMLValuesCollection(Of String)(IXMLValuesCollection.Modes.String, "LatestExcludedLabels",, x) With {.ListAddParameters = LAP.NotContainsOnly}
|
||||
ExcludedIgnore = New XMLValue(Of Boolean)("LatestExcludedLabelsIgnore", False, x)
|
||||
End Sub
|
||||
Friend Sub Verify()
|
||||
SourceXML.BeginUpdate()
|
||||
Dim r As Predicate(Of String) = Function(l) Not LabelsList.Contains(l)
|
||||
Dim c% = Current.Count
|
||||
If c > 0 Then
|
||||
Current.ValuesList.RemoveAll(r)
|
||||
If Not Current.Count = c Then Current.Update()
|
||||
End If
|
||||
c = Excluded.Count
|
||||
If c > 0 Then
|
||||
Excluded.ValuesList.RemoveAll(r)
|
||||
If Not c = Excluded.Count Then Excluded.Update()
|
||||
End If
|
||||
SourceXML.EndUpdate()
|
||||
Dim lp As New ListAddParams(LAP.NotContainsOnly + LAP.IgnoreICopier)
|
||||
If Current.Count > 0 Then LabelsList.ListAddList(Current, lp)
|
||||
If Excluded.Count > 0 Then LabelsList.ListAddList(Excluded, lp)
|
||||
End Sub
|
||||
Friend ReadOnly Property ToList As List(Of String)
|
||||
Get
|
||||
@@ -69,10 +55,14 @@ Friend Class LabelsKeeper : Implements ICollection(Of String), IMyEnumerator(Of
|
||||
LabelsList.Clear()
|
||||
NewLabels.Clear()
|
||||
End Sub
|
||||
Friend Sub Update()
|
||||
Friend Sub Update(Optional ByVal Force As Boolean = False)
|
||||
If LabelsList.Count > 0 Then
|
||||
LabelsList.Sort()
|
||||
TextSaver.SaveTextToFile(LabelsList.ListToString(vbNewLine), LabelsFile, True, False, EDP.SendInLog)
|
||||
If NewLabelsExists Or Force Then
|
||||
If LabelsList.Contains(NoParsedUser) Then LabelsList.Remove(NoParsedUser)
|
||||
LabelsList.Sort()
|
||||
TextSaver.SaveTextToFile(LabelsList.ListToString(vbNewLine), LabelsFile, True, False, EDP.SendInLog)
|
||||
If NewLabels.Count > 0 Then NewLabels.Clear()
|
||||
End If
|
||||
Else
|
||||
LabelsFile.Delete(, Settings.DeleteMode, EDP.SendInLog)
|
||||
End If
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Threading
|
||||
Imports SCrawler.API
|
||||
Imports SCrawler.API.Base
|
||||
Friend Class ListImagesLoader
|
||||
Private ReadOnly Property MyList As ListView
|
||||
Private Class UserOption : Implements IComparable(Of UserOption)
|
||||
Private Structure UserOption : Implements IComparable(Of UserOption)
|
||||
Friend ReadOnly User As IUserData
|
||||
Friend ReadOnly LVI As ListViewItem
|
||||
Friend Index As Integer
|
||||
@@ -19,95 +20,135 @@ Friend Class ListImagesLoader
|
||||
Return LVI.Name
|
||||
End Get
|
||||
End Property
|
||||
Friend [Image] As Image
|
||||
Friend Sub New(ByVal u As IUserData, ByVal l As ListView, ByVal GetImage As Boolean)
|
||||
Friend Sub New(ByVal u As IUserData, ByVal l As ListView)
|
||||
User = u
|
||||
LVI = u.GetLVI(l)
|
||||
Index = u.Index
|
||||
If GetImage Then Image = u.GetPicture
|
||||
End Sub
|
||||
Friend Sub UpdateImage()
|
||||
Image = User.GetPicture
|
||||
End Sub
|
||||
Friend Function CompareTo(ByVal Other As UserOption) As Integer Implements IComparable(Of UserOption).CompareTo
|
||||
Return Index.CompareTo(Other.Index)
|
||||
End Function
|
||||
End Class
|
||||
End Structure
|
||||
Friend Sub New(ByRef l As ListView)
|
||||
MyList = l
|
||||
End Sub
|
||||
Friend Sub Update()
|
||||
Dim a As Action = Sub()
|
||||
With MyList
|
||||
.Items.Clear()
|
||||
If Not .LargeImageList Is Nothing Then .LargeImageList.Images.Clear()
|
||||
.LargeImageList = New ImageList
|
||||
If Not .SmallImageList Is Nothing Then .SmallImageList.Images.Clear()
|
||||
.SmallImageList = New ImageList
|
||||
If Settings.ViewModeIsPicture Then
|
||||
.LargeImageList.ColorDepth = ColorDepth.Depth32Bit
|
||||
.SmallImageList.ColorDepth = ColorDepth.Depth32Bit
|
||||
.LargeImageList.ImageSize = New Size(DivideWithZeroChecking(Settings.MaxLargeImageHeight.Value, 100) * 75, Settings.MaxLargeImageHeight.Value)
|
||||
.SmallImageList.ImageSize = New Size(DivideWithZeroChecking(Settings.MaxSmallImageHeight.Value, 100) * 75, Settings.MaxSmallImageHeight.Value)
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
If MyList.InvokeRequired Then MyList.Invoke(a) Else a.Invoke
|
||||
If Settings.Users.Count > 0 Then
|
||||
Settings.Users.Sort()
|
||||
Dim v As View = Settings.ViewMode.Value
|
||||
Dim i%
|
||||
|
||||
With MyList
|
||||
MyList.BeginUpdate()
|
||||
|
||||
If Settings.FastProfilesLoading Then
|
||||
Settings.Users.ListReindex
|
||||
Dim UData As List(Of UserOption)
|
||||
|
||||
If Settings.ViewModeIsPicture Then
|
||||
UData = GetUsersWithImages()
|
||||
If UData.ListExists Then
|
||||
UData.Sort()
|
||||
Select Case v
|
||||
Case View.LargeIcon : .LargeImageList.Images.AddRange(UData.Select(Function(u) u.Image).ToArray)
|
||||
Case View.SmallIcon : .SmallImageList.Images.AddRange(UData.Select(Function(u) u.Image).ToArray)
|
||||
End Select
|
||||
End If
|
||||
Else
|
||||
UData = (From u As IUserData In Settings.Users Where u.FitToAddParams Select New UserOption(u, MyList, False)).ListIfNothing
|
||||
If UData.ListExists Then UData.Sort()
|
||||
End If
|
||||
|
||||
If UData.ListExists Then
|
||||
If Settings.ViewModeIsPicture Then
|
||||
For i = 0 To UData.Count - 1
|
||||
Select Case v
|
||||
Case View.LargeIcon : .LargeImageList.Images.SetKeyName(i, UData(i).Key)
|
||||
Case View.SmallIcon : .SmallImageList.Images.SetKeyName(i, UData(i).Key)
|
||||
End Select
|
||||
Next
|
||||
End If
|
||||
.Items.AddRange(UData.Select(Function(u) u.LVI).ToArray)
|
||||
UData.Clear()
|
||||
End If
|
||||
Else
|
||||
Dim t As New List(Of Task)
|
||||
For Each User As IUserData In Settings.Users
|
||||
If User.FitToAddParams Then
|
||||
If Settings.ViewModeIsPicture Then
|
||||
t.Add(Task.Run(Sub() UpdateUser(User, True)))
|
||||
Else
|
||||
UpdateUser(User, True)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
If t.Count > 0 Then Task.WhenAll(t.ToArray) : t.Clear()
|
||||
End If
|
||||
End With
|
||||
MyList.EndUpdate()
|
||||
Private UserDataList As List(Of UserOption)
|
||||
Private UpdateInProgress As Boolean = False
|
||||
Private ImageThread As Thread
|
||||
Private Sub UpdateImages()
|
||||
If UserDataList.ListExists And Not If(ImageThread?.IsAlive, False) Then
|
||||
ImageThread = New Thread(New ThreadStart(Sub()
|
||||
Dim ar As IAsyncResult = Nothing
|
||||
Dim a As Action = Sub()
|
||||
Try
|
||||
If UserDataList.ListExists Then
|
||||
For i% = 0 To UserDataList.Count - 1
|
||||
With UserDataList(i).User
|
||||
Select Case Settings.ViewMode.Value
|
||||
Case View.LargeIcon : MyList.LargeImageList.Images.Add(.Key, .GetPicture())
|
||||
Case View.SmallIcon : MyList.SmallImageList.Images.Add(.Key, .GetPicture())
|
||||
End Select
|
||||
End With
|
||||
Application.DoEvents()
|
||||
Next
|
||||
UserDataList.Clear()
|
||||
GC.Collect()
|
||||
End If
|
||||
Catch iex As ArgumentOutOfRangeException
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[ListImagesLoader.UpdateImages]")
|
||||
End Try
|
||||
If Not ar Is Nothing Then MyList.EndInvoke(ar)
|
||||
UpdateInProgress = False
|
||||
End Sub
|
||||
If MyList.InvokeRequired Then
|
||||
ar = MyList.BeginInvoke(a)
|
||||
Else
|
||||
a.Invoke
|
||||
End If
|
||||
End Sub)) With {.IsBackground = True}
|
||||
ImageThread.SetApartmentState(ApartmentState.MTA)
|
||||
ImageThread.Start()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub InterruptUpdate()
|
||||
Try
|
||||
If UserDataList.ListExists Then UserDataList.Clear() : Application.DoEvents()
|
||||
If If(ImageThread?.IsAlive, False) Then ImageThread.Abort() : Application.DoEvents()
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[ListImagesLoader.InterruptUpdate]")
|
||||
End Try
|
||||
End Sub
|
||||
Friend Sub Update()
|
||||
Try
|
||||
If UpdateInProgress Then InterruptUpdate()
|
||||
If Not UpdateInProgress Then
|
||||
UpdateInProgress = True
|
||||
Dim a As Action = Sub()
|
||||
With MyList
|
||||
.Items.Clear()
|
||||
If Not .LargeImageList Is Nothing Then .LargeImageList.Images.Clear()
|
||||
.LargeImageList = New ImageList
|
||||
If Not .SmallImageList Is Nothing Then .SmallImageList.Images.Clear()
|
||||
.SmallImageList = New ImageList
|
||||
If Settings.ViewModeIsPicture Then
|
||||
.LargeImageList.ColorDepth = ColorDepth.Depth32Bit
|
||||
.SmallImageList.ColorDepth = ColorDepth.Depth32Bit
|
||||
.LargeImageList.ImageSize = New Size(DivideWithZeroChecking(Settings.MaxLargeImageHeight.Value, 100) * 75, Settings.MaxLargeImageHeight.Value)
|
||||
.SmallImageList.ImageSize = New Size(DivideWithZeroChecking(Settings.MaxSmallImageHeight.Value, 100) * 75, Settings.MaxSmallImageHeight.Value)
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
If MyList.InvokeRequired Then MyList.Invoke(a) Else a.Invoke
|
||||
If Settings.Users.Count > 0 Then
|
||||
Settings.Users.Sort()
|
||||
Dim v As View = Settings.ViewMode.Value
|
||||
|
||||
With MyList
|
||||
MyList.BeginUpdate()
|
||||
|
||||
If Settings.FastProfilesLoading Then
|
||||
Settings.Users.ListReindex
|
||||
|
||||
UserDataList = (From u As IUserData In Settings.Users Where u.FitToAddParams Select New UserOption(u, MyList)).ListIfNothing
|
||||
If UserDataList.ListExists Then UserDataList.Sort()
|
||||
|
||||
If UserDataList.ListExists Then
|
||||
.Items.AddRange(UserDataList.Select(Function(u) u.LVI).ToArray)
|
||||
If Settings.ViewModeIsPicture Then
|
||||
MyList.EndUpdate()
|
||||
UpdateImages()
|
||||
Else
|
||||
UserDataList.Clear()
|
||||
UpdateInProgress = False
|
||||
End If
|
||||
End If
|
||||
Else
|
||||
Dim t As New List(Of Task)
|
||||
For Each User As IUserData In Settings.Users
|
||||
If User.FitToAddParams Then
|
||||
If Settings.ViewModeIsPicture Then
|
||||
t.Add(Task.Run(Sub() UpdateUser(User, True)))
|
||||
Else
|
||||
UpdateUser(User, True)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
If t.Count > 0 Then Task.WhenAll(t.ToArray) : t.Clear()
|
||||
UpdateInProgress = False
|
||||
End If
|
||||
End With
|
||||
MyList.EndUpdate()
|
||||
Else
|
||||
UpdateInProgress = False
|
||||
End If
|
||||
Else
|
||||
MsgBoxE({"User list update aborted. Click the 'Refresh' button to refresh the user list.", "Update user list"}, vbExclamation)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[ListImagesLoader.Update]")
|
||||
End Try
|
||||
End Sub
|
||||
Friend Sub UpdateUser(ByVal User As IUserData, ByVal Add As Boolean)
|
||||
Try
|
||||
Dim a As Action
|
||||
@@ -156,9 +197,9 @@ Friend Class ListImagesLoader
|
||||
ElseIf CheckUserCollection(User) Then
|
||||
.BackColor = Color.LightSkyBlue
|
||||
.ForeColor = Color.MidnightBlue
|
||||
ElseIf Not IsInit Then
|
||||
.BackColor = SystemColors.Window
|
||||
.ForeColor = SystemColors.WindowText
|
||||
Else 'If Not IsInit Then
|
||||
.BackColor = Settings.UserListBackColorF
|
||||
.ForeColor = Settings.UserListForeColorF
|
||||
End If
|
||||
End With
|
||||
Return LVI
|
||||
@@ -172,24 +213,4 @@ Friend Class ListImagesLoader
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
Private Function GetUsersWithImages() As List(Of UserOption)
|
||||
Try
|
||||
Dim t As New List(Of Task)
|
||||
Dim l As New List(Of UserOption)
|
||||
t.AddRange(From u As IUserData In Settings.Users Where u.FitToAddParams Select Task.Run(Sub() l.Add(New UserOption(u, MyList, True))))
|
||||
If t.Count > 0 Then Task.WaitAll(t.ToArray)
|
||||
If l.Count > 0 Then
|
||||
For i% = 0 To l.Count - 1
|
||||
If l(i) Is Nothing Then Throw New ArgumentNullException("UserOption", $"One of the UserOptions [{i} / {l.Count - 1}] is null.")
|
||||
If l(i).Image Is Nothing Then l(i).UpdateImage()
|
||||
Next
|
||||
End If
|
||||
Return l
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.LogMessageValue, ex,
|
||||
"Image fast loading error." & vbCr &
|
||||
"Click the ""Refresh"" button to manually refresh the user list." & vbCr &
|
||||
"[ListImagesLoader.GetUsersWithImages]")
|
||||
End Try
|
||||
End Function
|
||||
End Class
|
||||
16
SCrawler/MainFrame.Designer.vb
generated
@@ -121,6 +121,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
Me.BTT_TRAY_PAUSE_AUTOMATION = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_SILENT_MODE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_FEED_SHOW = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_CHANNELS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_SHOW_HIDE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_CLOSE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_TRAY_CLOSE_NO_SCRIPT = New System.Windows.Forms.ToolStripMenuItem()
|
||||
@@ -418,7 +419,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
'BTT_DOWN_VIDEO
|
||||
'
|
||||
Me.BTT_DOWN_VIDEO.AutoToolTip = True
|
||||
Me.BTT_DOWN_VIDEO.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
||||
Me.BTT_DOWN_VIDEO.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
|
||||
Me.BTT_DOWN_VIDEO.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
Me.BTT_DOWN_VIDEO.Name = "BTT_DOWN_VIDEO"
|
||||
Me.BTT_DOWN_VIDEO.Size = New System.Drawing.Size(231, 22)
|
||||
@@ -754,6 +755,7 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
'
|
||||
'BTT_CONTEXT_GROUPS
|
||||
'
|
||||
Me.BTT_CONTEXT_GROUPS.Image = Global.SCrawler.My.Resources.Resources.TagPic_24
|
||||
Me.BTT_CONTEXT_GROUPS.Name = "BTT_CONTEXT_GROUPS"
|
||||
Me.BTT_CONTEXT_GROUPS.Size = New System.Drawing.Size(221, 22)
|
||||
Me.BTT_CONTEXT_GROUPS.Text = "Change labels"
|
||||
@@ -824,9 +826,9 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
'
|
||||
'TRAY_CONTEXT
|
||||
'
|
||||
Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT})
|
||||
Me.TRAY_CONTEXT.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_TRAY_PAUSE_AUTOMATION, Me.BTT_TRAY_SILENT_MODE, Me.BTT_TRAY_FEED_SHOW, Me.BTT_TRAY_CHANNELS, TRAY_SEP_1, Me.BTT_TRAY_SHOW_HIDE, TRAY_SEP_2, Me.BTT_TRAY_CLOSE, Me.BTT_TRAY_CLOSE_NO_SCRIPT})
|
||||
Me.TRAY_CONTEXT.Name = "TRAY_CONTEXT"
|
||||
Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 148)
|
||||
Me.TRAY_CONTEXT.Size = New System.Drawing.Size(171, 170)
|
||||
'
|
||||
'BTT_TRAY_PAUSE_AUTOMATION
|
||||
'
|
||||
@@ -854,6 +856,13 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
Me.BTT_TRAY_FEED_SHOW.Text = "Feed"
|
||||
Me.BTT_TRAY_FEED_SHOW.ToolTipText = "Show feed of recently downloaded data." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+Click the tray icon to show the feed" &
|
||||
"."
|
||||
'
|
||||
'BTT_TRAY_CHANNELS
|
||||
'
|
||||
Me.BTT_TRAY_CHANNELS.Image = Global.SCrawler.My.Resources.SiteResources.RedditPic_512
|
||||
Me.BTT_TRAY_CHANNELS.Name = "BTT_TRAY_CHANNELS"
|
||||
Me.BTT_TRAY_CHANNELS.Size = New System.Drawing.Size(170, 22)
|
||||
Me.BTT_TRAY_CHANNELS.Text = "Channels"
|
||||
'
|
||||
'BTT_TRAY_SHOW_HIDE
|
||||
'
|
||||
@@ -986,4 +995,5 @@ Partial Public Class MainFrame : Inherits System.Windows.Forms.Form
|
||||
Friend WithEvents BTT_DOWN_AUTOMATION_PAUSE As ToolStripMenuItem
|
||||
Private WithEvents BTT_TRAY_FEED_SHOW As ToolStripMenuItem
|
||||
Friend WithEvents MENU_DOWN_ALL As ToolStripDropDownButton
|
||||
Private WithEvents BTT_TRAY_CHANNELS As ToolStripMenuItem
|
||||
End Class
|
||||
@@ -10,6 +10,7 @@ Imports System.Threading
|
||||
Imports System.ComponentModel
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Functions.Messaging
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports SCrawler.API
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Editors
|
||||
@@ -36,7 +37,8 @@ Public Class MainFrame
|
||||
With Settings.Plugins
|
||||
If .Count > 0 Then
|
||||
For i% = 0 To .Count - 1
|
||||
MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, .Item(i).Settings.GetSettingsButton)
|
||||
If Not .Item(i).Key = PathPlugin.PluginKey Then _
|
||||
MENU_SETTINGS.DropDownItems.Insert(MENU_SETTINGS.DropDownItems.Count - 2, .Item(i).Settings.GetSettingsButton)
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
@@ -88,33 +90,36 @@ Public Class MainFrame
|
||||
LIST_PROFILES.ShowGroups = .UseGrouping
|
||||
ApplyViewPattern(.ViewMode.Value)
|
||||
AddHandler .Labels.NewLabelAdded, AddressOf UpdateLabelsGroups
|
||||
UpdateImageColor()
|
||||
UserListLoader = New ListImagesLoader(LIST_PROFILES)
|
||||
RefillList()
|
||||
UpdateLabelsGroups()
|
||||
SetShowButtonsCheckers(.ShowingMode.Value)
|
||||
CheckVersion(False)
|
||||
BTT_SITE_ALL.Checked = .SelectedSites.Count = 0
|
||||
BTT_SITE_SPECIFIC.Checked = .SelectedSites.Count > 0
|
||||
BTT_SHOW_LIMIT_DATES_NOT.Tag = ShowingDates.Not
|
||||
BTT_SHOW_LIMIT_DATES_NOT.Checked = .ViewDateMode.Value = ShowingDates.Not
|
||||
BTT_SHOW_LIMIT_DATES_IN.Tag = ShowingDates.In
|
||||
BTT_SHOW_LIMIT_DATES_IN.Checked = .ViewDateMode.Value = ShowingDates.In
|
||||
With .Groups
|
||||
AddHandler .Added, AddressOf GROUPS_Added
|
||||
AddHandler .Deleted, AddressOf GROUPS_Deleted
|
||||
AddHandler .Updated, AddressOf GROUPS_Updated
|
||||
If .Count > 0 Then
|
||||
For Each ugroup As Groups.DownloadGroup In Settings.Groups : GROUPS_Added(ugroup) : Next
|
||||
End If
|
||||
End With
|
||||
.Automation = New Scheduler
|
||||
AddHandler .Groups.Updated, AddressOf .Automation.GROUPS_Updated
|
||||
AddHandler .Groups.Deleted, AddressOf .Automation.GROUPS_Deleted
|
||||
AddHandler .Automation.PauseDisabled, AddressOf MainFrameObj.PauseButtons.UpdatePauseButtons
|
||||
If .Automation.Count > 0 Then .Labels.AddRange(.Automation.GetGroupsLabels, False) : .Labels.Update()
|
||||
_UFinit = False
|
||||
Await .Automation.Start(True)
|
||||
End With
|
||||
UserListLoader = New ListImagesLoader(LIST_PROFILES)
|
||||
RefillList()
|
||||
UpdateLabelsGroups()
|
||||
SetShowButtonsCheckers(Settings.ShowingMode.Value)
|
||||
CheckVersion(False)
|
||||
BTT_SITE_ALL.Checked = Settings.SelectedSites.Count = 0
|
||||
BTT_SITE_SPECIFIC.Checked = Settings.SelectedSites.Count > 0
|
||||
BTT_SHOW_LIMIT_DATES_NOT.Tag = ShowingDates.Not
|
||||
BTT_SHOW_LIMIT_DATES_NOT.Checked = Settings.ViewDateMode.Value = ShowingDates.Not
|
||||
BTT_SHOW_LIMIT_DATES_IN.Tag = ShowingDates.In
|
||||
BTT_SHOW_LIMIT_DATES_IN.Checked = Settings.ViewDateMode.Value = ShowingDates.In
|
||||
With Settings.Groups
|
||||
AddHandler .Added, AddressOf GROUPS_Added
|
||||
AddHandler .Deleted, AddressOf GROUPS_Deleted
|
||||
AddHandler .Updated, AddressOf GROUPS_Updated
|
||||
If .Count > 0 Then
|
||||
For Each ugroup As Groups.DownloadGroup In Settings.Groups : GROUPS_Added(ugroup) : Next
|
||||
End If
|
||||
End With
|
||||
Settings.Automation = New Scheduler
|
||||
AddHandler Settings.Groups.Updated, AddressOf Settings.Automation.GROUPS_Updated
|
||||
AddHandler Settings.Groups.Deleted, AddressOf Settings.Automation.GROUPS_Deleted
|
||||
AddHandler Settings.Automation.PauseDisabled, AddressOf MainFrameObj.PauseButtons.UpdatePauseButtons
|
||||
_UFinit = False
|
||||
Await Settings.Automation.Start(True)
|
||||
UpdatePauseButtonsVisibility()
|
||||
MainFrameObj.UpdateLogButton()
|
||||
GoTo EndFunction
|
||||
FormClosingInvoker:
|
||||
Close()
|
||||
@@ -189,6 +194,25 @@ CloseResume:
|
||||
If Not _DisableClosingScript And Not _VideoDownloadingMode Then ExecuteCommand(Settings.ClosingCommand)
|
||||
If Not MyMainLOG.IsEmptyString Then SaveLogToFile()
|
||||
End Sub
|
||||
Private Sub MainFrame_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
|
||||
If Not _UFinit Then UpdateImageColor()
|
||||
End Sub
|
||||
Private Sub UpdateImageColor()
|
||||
Try
|
||||
If Settings.UserListImage.Value.Exists Then
|
||||
Using ir As New ImageRenderer(Settings.UserListImage) : LIST_PROFILES.BackgroundImage = ir.FitToWidth(LIST_PROFILES.Width) : End Using
|
||||
Else
|
||||
LIST_PROFILES.BackgroundImage = Nothing
|
||||
End If
|
||||
With Settings
|
||||
If Not .UserListBackColorF = LIST_PROFILES.BackColor Or Not .UserListForeColorF = LIST_PROFILES.ForeColor Then
|
||||
LIST_PROFILES.BackColor = .UserListBackColorF
|
||||
LIST_PROFILES.ForeColor = .UserListForeColorF
|
||||
End If
|
||||
End With
|
||||
Catch ex As Exception
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub MainFrame_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||
Dim b As Boolean = True
|
||||
Select Case e.KeyCode
|
||||
@@ -250,7 +274,6 @@ CloseResume:
|
||||
#Region "List refill, update"
|
||||
Friend Sub RefillList()
|
||||
UserListLoader.Update()
|
||||
GC.Collect()
|
||||
End Sub
|
||||
Private Sub UserListUpdate(ByVal User As IUserData, ByVal Add As Boolean)
|
||||
UserListLoader.UpdateUser(User, Add)
|
||||
@@ -272,6 +295,7 @@ CloseResume:
|
||||
LIST_PROFILES.ShowGroups = .UseGrouping
|
||||
If f.FeedParametersChanged And Not MyFeed Is Nothing Then MyFeed.UpdateSettings()
|
||||
UpdateSilentButtons()
|
||||
UpdateImageColor()
|
||||
End If
|
||||
End Using
|
||||
End With
|
||||
@@ -339,8 +363,11 @@ CloseResume:
|
||||
.ScriptUse = f.ScriptUse
|
||||
.ScriptData = f.ScriptData
|
||||
If Not f.MyExchangeOptions Is Nothing Then DirectCast(.Self, UserDataBase).ExchangeOptionsSet(f.MyExchangeOptions)
|
||||
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
|
||||
.Self.Labels.ListAddList(f.UserLabels.ListAddValue(LabelsKeeper.NoParsedUser), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
If Not .HOST.Key = PathPlugin.PluginKey Then
|
||||
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
|
||||
f.UserLabels.ListAddValue(LabelsKeeper.NoParsedUser)
|
||||
End If
|
||||
.Self.Labels.ListAddList(f.UserLabels, LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
.UpdateUserInformation()
|
||||
End If
|
||||
End With
|
||||
@@ -380,7 +407,7 @@ CloseResume:
|
||||
If MyFeed Is Nothing Then MyFeed = New DownloadFeedForm : AddHandler Downloader.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
|
||||
If MyFeed.Visible Then MyFeed.BringToFront() Else MyFeed.Show()
|
||||
End Sub
|
||||
Private Sub BTT_CHANNELS_Click(sender As Object, e As EventArgs) Handles BTT_CHANNELS.Click
|
||||
Private Sub BTT_CHANNELS_Click(sender As Object, e As EventArgs) Handles BTT_CHANNELS.Click, BTT_TRAY_CHANNELS.Click
|
||||
If MyChannels Is Nothing Then
|
||||
MyChannels = New ChannelViewForm
|
||||
AddHandler MyChannels.OnUsersAdded, AddressOf OnUsersAddedHandler
|
||||
@@ -613,7 +640,7 @@ CloseResume:
|
||||
BTT_SHOW_EXCLUDED_LABELS.Checked = Settings.Labels.Excluded.Count > 0
|
||||
BTT_SHOW_EXCLUDED_LABELS_IGNORE.Checked = Settings.Labels.ExcludedIgnore
|
||||
End Sub
|
||||
Private Function OpenLabelsForm(ByRef ll As XML.Base.XMLValuesCollection(Of String)) As Boolean
|
||||
Private Function OpenLabelsForm(ByRef ll As XML.Objects.XMLValuesCollection(Of String)) As Boolean
|
||||
Using f As New LabelsForm(ll) With {.WithDeleteButton = True}
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Then
|
||||
@@ -882,6 +909,23 @@ CloseResume:
|
||||
Else
|
||||
__ModelAskForDecision = True
|
||||
End If
|
||||
|
||||
If (users.Count = 1 AndAlso Not users(0).IsCollection AndAlso users(0).HOST.Key = PathPlugin.PluginKey) OrElse
|
||||
(users.Count = 2 AndAlso users.All(Function(u) u.IsCollection OrElse u.HOST.Key = PathPlugin.PluginKey)) Then
|
||||
__modelUser = UsageModel.Virtual
|
||||
If Added Then
|
||||
__modelCollection = UsageModel.Virtual
|
||||
Else
|
||||
i = users.FindIndex(_col_user)
|
||||
If i >= 0 Then
|
||||
__modelCollection = users(i).CollectionModel
|
||||
Else
|
||||
__modelCollection = UsageModel.Virtual
|
||||
End If
|
||||
End If
|
||||
__ModelAskForDecision = False
|
||||
End If
|
||||
|
||||
If __ModelAskForDecision Then
|
||||
Select Case MsgBoxE({"How do you want to add users to the collection?", MsgTitle}, vbQuestion,,,
|
||||
{
|
||||
@@ -909,7 +953,7 @@ CloseResume:
|
||||
For Each user As UserDataBase In users
|
||||
If Not user.IsCollection Then
|
||||
Try
|
||||
user.User.UserModel = __modelUser
|
||||
user.User.UserModel = IIf(user.HOST.Key = PathPlugin.PluginKey, UsageModel.Virtual, __modelUser)
|
||||
user.User.CollectionModel = __modelCollection
|
||||
userCollection.Add(user)
|
||||
RemoveUserFromList(user)
|
||||
@@ -1006,10 +1050,10 @@ CloseResume:
|
||||
Exit Sub
|
||||
End If
|
||||
CurrDir = CurrDir.CutPath(IIf(.DataMerging, 3, 2))
|
||||
colName = CurrDir.PathFolders.LastOrDefault
|
||||
Dim vu As IEnumerable(Of IUserData) = .Where(Function(vuu) vuu.UserModel = UsageModel.Virtual)
|
||||
colName = CurrDir.Segments.LastOrDefault
|
||||
Dim vu As IEnumerable(Of IUserData) = .Where(Function(vuu) vuu.UserModel = UsageModel.Virtual Or vuu.HOST.Key = PathPlugin.PluginKey)
|
||||
If vu.ListExists Then
|
||||
If MsgBoxE({"This collection contains virtual users." & vbCr &
|
||||
If MsgBoxE({"This collection contains virtual users and/or paths." & vbCr &
|
||||
"If you continue, the virtual user paths will not be changed." & vbCr &
|
||||
"The following users have been added to the collection in virtual mode:" & vbCr &
|
||||
vu.ListToStringE(vbCr, GetUserListProvider(False)), MsgTitle},
|
||||
@@ -1017,17 +1061,29 @@ CloseResume:
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
ElseIf .HOST.Key = PathPlugin.PluginKey Then
|
||||
MsgBoxE({"This is the path (not user). The paths cannot be changed.", MsgTitle}, vbCritical)
|
||||
Exit Sub
|
||||
Else
|
||||
CurrDir = .Self.File.CutPath(1)
|
||||
End If
|
||||
|
||||
Dim NewDest As SFile = SFile.SelectPath(CurrDir, $"Select a new destination for {IIf(_IsCollection, "collection", "user")} [{ .Self}]")
|
||||
Dim NewDest2 As SFile
|
||||
If Not NewDest.IsEmptyString Then
|
||||
NewDest = $"{NewDest.PathWithSeparator}{colName}\"
|
||||
If MsgBoxE({$"You are changing the user's [{ .Self}] destination" & vbCr &
|
||||
$"Current destination: {CurrDir.PathNoSeparator}" & vbCr &
|
||||
$"New destination: {NewDest.PathNoSeparator}",
|
||||
MsgTitle}, MsgBoxStyle.Exclamation,,, {"Confirm", "Cancel"}) = 0 Then
|
||||
NewDest2 = $"{NewDest.PathWithSeparator}{CurrDir.Segments.LastOrDefault().StringAppend("\", String.Empty)}"
|
||||
Dim choice% = MsgBoxE(New MMessage($"You are changing the user's [{ .Self}] destination" & vbCr &
|
||||
$"Current destination: {CurrDir.PathNoSeparator}" & vbCr &
|
||||
$"New destination [1]: {NewDest.PathNoSeparator}" & vbCr &
|
||||
$"New destination [2]: {NewDest2.PathWithSeparator}",
|
||||
MsgTitle,
|
||||
{New MsgBoxButton("Confirm [1] (Enter)", "Move the data to the destination [1]."),
|
||||
New MsgBoxButton("Confirm [2]", "Move the data to the destination [2].") With {.KeyCode = Keys.D2},
|
||||
"Cancel"},
|
||||
MsgBoxStyle.Exclamation) With {.AppendKeyCode = False})
|
||||
If choice < 2 Then
|
||||
If choice = 1 Then NewDest = NewDest2
|
||||
If Not NewDest.IsEmptyString AndAlso
|
||||
(Not NewDest.Exists(SFO.Path, False) OrElse
|
||||
(
|
||||
@@ -1396,6 +1452,7 @@ ResumeDownloadingOperation:
|
||||
If result < 6 Then
|
||||
Dim collectionResult% = -1
|
||||
Dim tmpResult%
|
||||
Dim tmpUserNames As New List(Of String)
|
||||
Dim IsMultiple As Boolean = users.Count > 1
|
||||
Dim removedUsers As New List(Of String)
|
||||
Dim keepData As Boolean = Not (result Mod 2) = 0
|
||||
@@ -1430,10 +1487,18 @@ ResumeDownloadingOperation:
|
||||
removedUsers.Add(ugn(user))
|
||||
user.Dispose()
|
||||
Else
|
||||
If banUser Then
|
||||
tmpUserNames.Clear()
|
||||
If user.IsCollection Then
|
||||
tmpUserNames.ListAddList(DirectCast(user, UserDataBind).Collections.Select(Function(u) u.Name), l)
|
||||
Else
|
||||
tmpUserNames.Add(user.Name)
|
||||
End If
|
||||
End If
|
||||
tmpResult = user.Delete(IsMultiple, collectionResult)
|
||||
If user.IsCollection And collectionResult = -1 Then collectionResult = tmpResult
|
||||
If tmpResult > 0 Then
|
||||
If banUser Then Settings.BlackList.ListAddValue(New UserBan(user.Name, reason), l) : b = True
|
||||
If banUser And tmpUserNames.Count > 0 Then Settings.BlackList.ListAddList(tmpUserNames.Select(Function(u) New UserBan(u, reason)), l) : b = True
|
||||
RemoveUserFromList(user)
|
||||
removedUsers.Add(ugn(user))
|
||||
Else
|
||||
@@ -1452,8 +1517,8 @@ ResumeDownloadingOperation:
|
||||
m.Text = "No one user deleted!"
|
||||
m.Style = MsgBoxStyle.Critical
|
||||
Else
|
||||
m.Text = $"The following users were deleted:{vbNewLine}{removedUsers.ListToStringE(vbNewLine, userProvider)}{vbNewLine.StringDup(2)}"
|
||||
m.Text &= $"The following users were NOT deleted:{vbNewLine}{leftUsers.ListToStringE(vbNewLine, userProvider)}"
|
||||
m.Text = $"The following users were deleted:{vbNewLine}{removedUsers.ListToString(vbNewLine)}{vbNewLine.StringDup(2)}"
|
||||
m.Text &= $"The following users were NOT deleted:{vbNewLine}{leftUsers.ListToString(vbNewLine)}"
|
||||
m.Style = MsgBoxStyle.Exclamation
|
||||
End If
|
||||
If b Then Settings.UpdateBlackList()
|
||||
@@ -1614,7 +1679,7 @@ ResumeDownloadingOperation:
|
||||
Private Sub Downloader_Downloading(ByVal Value As Boolean)
|
||||
Dim __isDownloading As Boolean = Value Or Downloader.Working
|
||||
ControlInvokeFast(Toolbar_TOP, BTT_DOWN_STOP, Sub() BTT_DOWN_STOP.Enabled = __isDownloading)
|
||||
ControlInvokeFast(Me, Sub() TrayIcon.Icon = If(__isDownloading, My.Resources.ArrowDownIcon_Blue_24, My.Resources.RainbowIcon_48))
|
||||
TrayIcon.Icon = If(__isDownloading, My.Resources.ArrowDownIcon_Blue_24, My.Resources.RainbowIcon_48)
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
@@ -74,14 +74,18 @@ Friend Class MainFrameObjects
|
||||
End Sub
|
||||
Private Sub Notificator_OnClicked(ByVal Key As String) Handles Notificator.OnClicked
|
||||
If Not Key.IsEmptyString Then
|
||||
Dim found As Boolean = False
|
||||
Dim activateForm As Boolean = False
|
||||
If Key.StartsWith(NotificationInternalKey) Then
|
||||
Select Case Key
|
||||
Case $"{NotificationInternalKey}_{NotifyObj.Channels}" : MF.MyChannels.FormShowS()
|
||||
Case $"{NotificationInternalKey}_{NotifyObj.SavedPosts}" : MF.MySavedPosts.FormShowS()
|
||||
Case Else : Focus(True)
|
||||
End Select
|
||||
ElseIf Settings.Automation Is Nothing OrElse Not Settings.Automation.NotificationClicked(Key) Then
|
||||
ElseIf Settings.Automation Is Nothing OrElse Not Settings.Automation.NotificationClicked(Key, found, activateForm) Then
|
||||
Focus(True)
|
||||
ElseIf found Then
|
||||
Focus(activateForm)
|
||||
Else
|
||||
Focus(True)
|
||||
End If
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports System.Runtime.CompilerServices
|
||||
Imports PersonalUtilities.Functions.XML.Objects
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports PersonalUtilities.Tools
|
||||
@@ -103,10 +104,11 @@ Friend Module MainMod
|
||||
Friend UserListLoader As ListImagesLoader
|
||||
Friend MyProgressForm As ActiveDownloadingProgress
|
||||
Friend MainFrameObj As MainFrameObjects
|
||||
Friend ReadOnly ParsersDataDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||
Friend ReadOnly DateTimeDefaultProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||
Friend ReadOnly FeedVideoLengthProvider As New ADateTime("hh\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
|
||||
Friend ReadOnly UserExistsPredicate As New FPredicate(Of IUserData)(Function(u) u.Exists)
|
||||
Friend ReadOnly LogConnector As New LogHost
|
||||
Friend DefaultUserAgent As String = String.Empty
|
||||
#Region "File name operations"
|
||||
Friend FileDateAppenderProvider As IFormatProvider
|
||||
''' <summary>File, Date</summary>
|
||||
@@ -147,6 +149,14 @@ Friend Module MainMod
|
||||
Return $"{If(Host?.Name, String.Empty)}{Opt}"
|
||||
End If
|
||||
End Function
|
||||
<Extension> Friend Function GetGroupsLabels(Of T As Groups.IGroup)(ByVal Groups As IEnumerable(Of T)) As List(Of String)
|
||||
If Groups.ListExists Then
|
||||
Return ListAddList(Nothing, Groups.SelectMany(Function(g) g.Labels), LAP.NotContainsOnly).
|
||||
ListAddList(Groups.SelectMany(Function(g) g.LabelsExcluded), LAP.NotContainsOnly)
|
||||
Else
|
||||
Return Nothing
|
||||
End If
|
||||
End Function
|
||||
#Region "Standalone video download functions"
|
||||
Friend Function GetCurrentBuffer() As String
|
||||
Dim b$ = BufferText
|
||||
@@ -178,6 +188,7 @@ Friend Module MainMod
|
||||
If Not found Then
|
||||
If URL.Contains("gfycat") Then
|
||||
um = Gfycat.Envir.GetVideoInfo(URL)
|
||||
If um.ListExists AndAlso um(0).URL.Contains("redgifs.com") Then Return DownloadVideoByURL(um(0).URL, AskForPath, Silent)
|
||||
ElseIf URL.Contains("imgur.com") Then
|
||||
um = Imgur.Envir.GetVideoInfo(URL)
|
||||
Else
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2022.11.16.0")>
|
||||
<Assembly: AssemblyFileVersion("2022.11.16.0")>
|
||||
<Assembly: AssemblyVersion("2023.3.1.0")>
|
||||
<Assembly: AssemblyFileVersion("2023.3.1.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
10
SCrawler/My Project/Resources.Designer.vb
generated
@@ -370,6 +370,16 @@ Namespace My.Resources
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
'''</summary>
|
||||
Friend ReadOnly Property TagPic_24() As System.Drawing.Bitmap
|
||||
Get
|
||||
Dim obj As Object = ResourceManager.GetObject("TagPic_24", resourceCulture)
|
||||
Return CType(obj,System.Drawing.Bitmap)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
'''</summary>
|
||||
|
||||