3.0.0.0
Parsing profiles descriptions (Reddit and Twitter) and updating it Filters: deleted, suspended, dates Collections containing deleted profiles are marked in blue Marked collection context elements Find profile in the main window from the info form New hotkeys in the info form: up, down, find, enter New hotkey in the main window: enter New list refill algo Added copying user pictures from all channels Changed view modes Changed comparer and ToString of UserDataBase New parameter added to channels stats (my users) Added view mode "details" Fixed twitter files overriding Fixed full parsing of reddit posts Fixed Insta timers and minors Fixed library fatal Removed UserDataBind comparer override Added GetUserMediaOnly for reddit users from channels Added Reddit availability check with DownDetector Added PLUGINS
2
.github/FUNDING.yml
vendored
@@ -10,4 +10,4 @@ liberapay: # Replace with a single Liberapay username
|
|||||||
issuehunt: # Replace with a single IssueHunt username
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
otechie: # Replace with a single Otechie username
|
otechie: # Replace with a single Otechie username
|
||||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
custom: ['https://blockchair.com/bitcoin/address/BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET']
|
||||||
|
|||||||
12
.github/ISSUE_TEMPLATE/plugin_add.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: Add plugin
|
||||||
|
about: Add plugin to plugin list
|
||||||
|
title: "[NEW PLUGIN]"
|
||||||
|
labels: 'New Plugin'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Plugin address:
|
||||||
|
Plugin name:
|
||||||
|
Plugin site:
|
||||||
40
Changelog.md
@@ -1,3 +1,43 @@
|
|||||||
|
# 3.0.0.0
|
||||||
|
|
||||||
|
**Attention! This version of the program makes changes user data file (Users.xml). Once you start using this version, you will not be able to use previous versions of the program. Therefore, it is highly recommended to archive the program settings folder and archive the users' data files (you can use the [```ArchiveSCrawlerUsersDataFiles.bat```](Tools/ArchiveSCrawlerUsersDataFiles.bat) tool to archive the data files of all users).**
|
||||||
|
|
||||||
|
- Added
|
||||||
|
- **PLUGINS SUPPORT**
|
||||||
|
- **Gfycat** site support
|
||||||
|
- Description of Twitter and Reddit user profiles
|
||||||
|
- Filter users by profile status "Suspended"
|
||||||
|
- Filter users by profile status "Deleted"
|
||||||
|
- Filter profiles that haven't downloaded new data since specific date
|
||||||
|
- Collections that contain non-existent profiles will be marked in blue
|
||||||
|
- Ability to find and activate a user in the main window from the Info form
|
||||||
|
- Ability to copy user images from all channels you have when adding a user from a channel
|
||||||
|
- Reddit default option "Get user media only" if now also used when creating new users from channels
|
||||||
|
- Ability to update user description every time
|
||||||
|
- ```Enter``` hotkey in the download info form to open the user's folder
|
||||||
|
- ```Enter``` hotkey in the main window to open the user's folder
|
||||||
|
- Channel statistics are supplemented by "existing users"
|
||||||
|
- ```Up``` and ```Down``` navigation buttons in the Info form
|
||||||
|
- ```Find``` button on the Info form to find the user in the main window
|
||||||
|
- "Details" view mode
|
||||||
|
- Fast loading of profiles in the main window. **Be careful with this setting. Fast loading leads to the highest CPU usage.**
|
||||||
|
- Reddit availability check with DownDetector
|
||||||
|
- Ability to [open folders with a specific program](https://github.com/AAndyProgram/SCrawler/wiki/Settings#folder-command)
|
||||||
|
- (Request #16) Ability to remove a user from the collection without deletion
|
||||||
|
- (Request #17) **Instagram Tagged** photos downloading
|
||||||
|
- (Request #17) **Instagram Stories** downloading
|
||||||
|
- Deleting data to recycle bin
|
||||||
|
- Updated
|
||||||
|
- "List" view mode
|
||||||
|
- Fixed
|
||||||
|
- Twitter reloads existing media
|
||||||
|
- Reddit saved posts downloader downloads all posts every time
|
||||||
|
- Minor bug that caused Instagram tasks timers to run longer
|
||||||
|
- A library error that in some cases leads to a fatal program error
|
||||||
|
- (Issue #16) Cannot delete a user that is in the collection.
|
||||||
|
|
||||||
|
At the requests of some users, I added [screenshots](ProgramScreenshots) of the program and added screenshots to [ReadMe](README.md) and the [guide](https://github.com/AAndyProgram/SCrawler/wiki).
|
||||||
|
|
||||||
# 2.0.0.4
|
# 2.0.0.4
|
||||||
|
|
||||||
**Removed compatibility of program settings with version 1.0.0.4 and lower.**
|
**Removed compatibility of program settings with version 1.0.0.4 and lower.**
|
||||||
|
|||||||
34
FAQ.md
@@ -8,42 +8,60 @@ Any other questions I will keep in this file.
|
|||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **HOW TO SETUP COOKIES**
|
#### Q: **HOW TO SETUP COOKIES**
|
||||||
|
|
||||||
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies
|
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **I can't copy cookies.**
|
#### Q: **I can't copy cookies.**
|
||||||
|
|
||||||
A: Use the mouse. Don't use ```Ctrl``` + ```A```!
|
A: Use the mouse. Don't use ```Ctrl``` + ```A```!
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **Does this program have GUI or CLI.**
|
#### Q: **Does this program have GUI or CLI.**
|
||||||
|
|
||||||
A: This is a GUI program.
|
A: This is a GUI program.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **Will CLI be added in the future?**
|
#### Q: **Will CLI be added in the future?**
|
||||||
|
|
||||||
A: I do not think so.
|
A: I do not think so.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **I want to add "...." site. How to request.**
|
#### Q: **I want to add "...." site. How to request.**
|
||||||
|
|
||||||
A: https://github.com/AAndyProgram/SCrawler/blob/main/CONTRIBUTING.md#how-to-request-a-new-site
|
A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-a-new-site)
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **Twitter/Instagram download failed.**
|
#### 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-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.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?**
|
#### Q: **Does the program remember the last download and check for new posts, downloading only new posts? Or does the program download the entire profile every time?**
|
||||||
|
|
||||||
A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
|
A: The program stored posts IDs in users' folders. For the first time, the program downloads the entire profile. All subsequent times the program will check for new posts and download **only new posts**!
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
#### Q: **How to redownload all data**
|
||||||
|
|
||||||
|
A: Double-click on the user you want to redownload. In the opened window open folder setting. Delete the files ending with ```_Data.xml``` and ```_Posts.txt```. Download this user again.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
#### Q: **How to remove the label**
|
||||||
|
|
||||||
|
A: There is no functionality to remove an individual label. You can open the ```Labels.txt``` file in the program settings folder and delete any label you want. You also can delete this file (```Labels.txt```). In this case, when the program starts, the list of labels list will be updated with only existing labels (from the user data files).
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
#### Q: **How to remove a user from the blacklist**
|
||||||
|
|
||||||
|
A: Just add that user back to the program. In the dialog box that opens, click on the ```Add and remove from blacklist```` button.
|
||||||
11
HowToSupport.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Your support is very valuable to me. Any support is greatly appreciated. Your support encourages me to make new features, update the program, add new sites, etc.
|
||||||
|
|
||||||
|
You can support the program by:
|
||||||
|
- **Bitcoin**: bitcoin:BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
|
||||||
|
- :heavy_dollar_sign: making donaion making donations on this site: https://ko-fi.com/andyprogram
|
||||||
|
- :repeat: make a post about my program on your profile (Reddit, Twitter, Instagram and any other social networks)
|
||||||
|
- :speech_balloon: tell your friends about the program
|
||||||
|
- :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/
|
||||||
|
- 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:
|
||||||
1
Plugins.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
List of available plugins
|
||||||
BIN
ProgramScreenshots/Channels.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
ProgramScreenshots/ChannelsStats.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
ProgramScreenshots/ChannelsStats2.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
ProgramScreenshots/CreateUser.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
ProgramScreenshots/CreateUserChannel.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
ProgramScreenshots/CreateUserClear.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
ProgramScreenshots/DownloadInfo.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
ProgramScreenshots/Labels.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
ProgramScreenshots/MainContext.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
ProgramScreenshots/MainContext2.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
ProgramScreenshots/MainWindow.png
Normal file
|
After Width: | Height: | Size: 369 KiB |
BIN
ProgramScreenshots/MainWindow2.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
ProgramScreenshots/SavedPosts.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
ProgramScreenshots/SeparateVideoDownloader.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
ProgramScreenshots/SettingDefaults.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
ProgramScreenshots/SettingsBasis.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
ProgramScreenshots/SettingsChannels.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
ProgramScreenshots/SettingsInstagram.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
ProgramScreenshots/SettingsReddit.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
ProgramScreenshots/SettingsTwitter.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
69
ProgramsComparison.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# 4K Stogram
|
||||||
|
|
||||||
|
https://www.4kdownload.com/products/product-stogram
|
||||||
|
|
||||||
|
| Option | SCrawler | 4K Stogram |
|
||||||
|
| ---- | ---- | ---- |
|
||||||
|
| User managament | **Advanced** | Primitive |
|
||||||
|
| Labeling users | **Yes** | No |
|
||||||
|
| Filtering | **Yes** | No |
|
||||||
|
| Collections | **Yes** | No |
|
||||||
|
| Specific user folders | **Yes** | No |
|
||||||
|
| Favorite / Temporary user options | **Yes** | No |
|
||||||
|
| Plugins support | **Yes** | No |
|
||||||
|
| Download posts by username | Yes | Yes |
|
||||||
|
| Download posts by hashtag | No | **Yes** |
|
||||||
|
| Download posts by location | No | **Yes** |
|
||||||
|
| Save Private Instagram Content with Permission| Yes | Yes |
|
||||||
|
| Download Instagram Stories and Highlights | Yes | Yes |
|
||||||
|
| See Others Instagram Feed As Your Own | No | **Yes** |
|
||||||
|
| Download Instagram Video Posts | Yes | Yes |
|
||||||
|
| Backup Your Instagram Account | Yes | Yes |
|
||||||
|
| Save Instagram Posts by Date | No (only limited download) | **Yes** |
|
||||||
|
| Download Instagram Saved Posts | Yes | Yes |
|
||||||
|
| Download Instagram Tagged Posts | Yes | Yes |
|
||||||
|
| Export and import subscriptions | No | **Yes** |
|
||||||
|
| **Paid** | **No** | Yes |
|
||||||
|
| **Free options** | **The program is completely free** | Only **ONE** profile downloading and only **200 posts** per day |
|
||||||
|
| Permitted Commercial Use | **Yes** | Starting from 43.56 EUR |
|
||||||
|
| Automatic Subscriptions Update | **Free** | Paid (43.56 EUR) |
|
||||||
|
| Posts and Captions Export | No | Paid (43.56 EUR) |
|
||||||
|
| Advertisements free | **No ADs at all for free** | Paid (14.52) |
|
||||||
|
| Operating Systems | Windows 7+ | Windows 7+, MacOS 10.13+, Ubuntu x64 |
|
||||||
|
| Select want content type to download | **Yes** | No |
|
||||||
|
| Instagram support | Yes | Yes |
|
||||||
|
| Twitter support | **Yes** | No |
|
||||||
|
| Reddit support | **Yes** | No |
|
||||||
|
| Other sites support | **Yes** | No |
|
||||||
|
| Still supported | Yes | Yes |
|
||||||
|
|
||||||
|
# RipMeApp
|
||||||
|
|
||||||
|
https://github.com/RipMeApp/ripme
|
||||||
|
|
||||||
|
| Option | SCrawler | 4K Stogram |
|
||||||
|
| ---- | ---- | ---- |
|
||||||
|
| User managament | **Advanced** | No |
|
||||||
|
| Labeling users | **Yes** | No |
|
||||||
|
| Filtering | **Yes** | No |
|
||||||
|
| Collections | **Yes** | No |
|
||||||
|
| Specific user folders | **Yes** | No |
|
||||||
|
| Favorite / Temporary user options | **Yes** | No |
|
||||||
|
| Plugins support | **Yes** | No |
|
||||||
|
| Download posts by username | Yes | Yes |
|
||||||
|
| Download posts by hashtag | No | No |
|
||||||
|
| Download posts by location | No | No |
|
||||||
|
| Save Private Instagram Content with Permission| Yes | Yes |
|
||||||
|
| Download Instagram Stories | Yes | Yes |
|
||||||
|
| Download Instagram Video Posts | Yes | Yes |
|
||||||
|
| Backup Your Instagram Account | Yes | Yes |
|
||||||
|
| Download Instagram Saved Posts | **Yes** | No |
|
||||||
|
| Download Instagram Tagged Posts | **Yes** | No |
|
||||||
|
| Export and import subscriptions | No | No |
|
||||||
|
| **Paid** | **No** | **No** |
|
||||||
|
| **Free options** | The program is completely free | The program is completely free, but site limits are not declared |
|
||||||
|
| Operating Systems | Windows 7+ | Windows, MacOS, Linux |
|
||||||
|
| Select want content type to download | Yes | Yes |
|
||||||
|
| Suported sites | 3 internal and any site using plugins | 86+ sites (declared) |
|
||||||
|
| Other sites support | **Yes** | No |
|
||||||
|
| Still supported | **Yes** | **No (last release date May 4, 2021)** |
|
||||||
67
README.md
@@ -4,13 +4,19 @@
|
|||||||
[](https://github.com/AAndyProgram/SCrawler/)
|
[](https://github.com/AAndyProgram/SCrawler/)
|
||||||
[](FAQ.md)
|
[](FAQ.md)
|
||||||
[](https://github.com/AAndyProgram/SCrawler/wiki)
|
[](https://github.com/AAndyProgram/SCrawler/wiki)
|
||||||
|
[](HowToSupport.md)
|
||||||
|
|
||||||
A program to download photo and video from Reddit, Twitter, Instagram, [etc](#supported-sites).
|
A program to download photo and video from [any site](#supported-sites) (e.g. Reddit, Twitter, Instagram).
|
||||||
|
|
||||||
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :)
|
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
|
||||||
|
|
||||||
[](https://ko-fi.com/andyprogram)
|
[](https://ko-fi.com/andyprogram)
|
||||||
|
|
||||||
|
**Bitcoin**: bitcoin:BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
# What can program do:
|
# What can program do:
|
||||||
- Download pictures and videos from users' profiles and subreddits:
|
- Download pictures and videos from users' profiles and subreddits:
|
||||||
- Reddit images;
|
- Reddit images;
|
||||||
@@ -19,20 +25,33 @@ Do you like this program? Consider adding to my coffee fund by making a donation
|
|||||||
- Reddit hosted videos (downloading Reddit hosted video is going through ffmpeg (**ffmpeg only works with the x64 program**));
|
- Reddit hosted videos (downloading Reddit hosted video is going through ffmpeg (**ffmpeg only works with the x64 program**));
|
||||||
- Twitter images and videos;
|
- Twitter images and videos;
|
||||||
- Instagram images and videos.
|
- Instagram images and videos.
|
||||||
|
- Imgur images, galleries and videos
|
||||||
|
- Gfycat videos
|
||||||
|
- [Other](#supported-sites) supported sites
|
||||||
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels).
|
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels).
|
||||||
- Download [saved Reddit and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts).
|
- Download [saved Reddit and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts).
|
||||||
- Add users from parsed channel.
|
- Add users from parsed channel.
|
||||||
|
- **Advanced user management.**
|
||||||
- Labeling users.
|
- Labeling users.
|
||||||
|
- Adding users to favorites and temporary.
|
||||||
- Filter exists users by label or group.
|
- Filter exists users by label or group.
|
||||||
- Selection of media types you want to download (images only, videos only, both)
|
- 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)
|
||||||
|
- Specifying a user folder (for downloading data to another location)
|
||||||
|
- Changing user icons
|
||||||
|
- Changing view modes
|
||||||
|
- ...and many others...
|
||||||
|
|
||||||
# Supported sites
|
# Supported sites
|
||||||
|
|
||||||
- Reddit
|
- **Reddit**
|
||||||
- Twitter
|
- **Twitter**
|
||||||
- Instagram
|
- **Instagram**
|
||||||
- RedGifs
|
- RedGifs
|
||||||
- Imgur
|
- Imgur
|
||||||
|
- Gfycat
|
||||||
|
- [Other sites](Plugins.md)
|
||||||
|
|
||||||
# How does it works:
|
# How does it works:
|
||||||
|
|
||||||
@@ -50,28 +69,42 @@ You can read about Instagram restrictions [here](https://github.com/AAndyProgram
|
|||||||
|
|
||||||
## How to request a new site
|
## How to request a new site
|
||||||
|
|
||||||
Read [here](https://github.com/AAndyProgram/SCrawler/blob/main/CONTRIBUTING.md#how-to-request-a-new-site) about
|
Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
|
||||||
|
|
||||||
# Requirements:
|
# Requirements
|
||||||
|
|
||||||
- Windows 7, 8, 9, 10, 11 with NET Framework 4.6.1 or higher
|
- Windows 7, 8, 9, 10, 11 with NET Framework 4.6.1 or higher
|
||||||
- Authorization cookies and tokens for Twitter (if you want to download data from Twitter)
|
- Authorization cookies and tokens for Twitter (if you want to download data from Twitter)
|
||||||
- Authorization cookies Instagram (if you want to download data from Instagram)
|
- Authorization cookies Instagram (if you want to download data from Instagram)
|
||||||
- ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip)). **ffmpeg only works with the x64 version of the program.**
|
- ffmpeg library for downloading videos hosted on Reddit (you can download it from the [official repo](https://github.com/GyanD/codexffmpeg/releases/tag/2021-01-12-git-ca21cb1e36) or [from my first release](https://github.com/AAndyProgram/SCrawler/releases/download/1.0.0.0/ffmpeg.zip)). **ffmpeg only works with the x64 version of the program.**
|
||||||
- **Don't put program in the ```Program Files``` system folder (this is portable program and program settings are stored in the program folder)**
|
|
||||||
- **Just unzip the program archive to any folder, copy the file ```ffmpeg.exe``` into it and enjoy. :)**
|
# Guide
|
||||||
|
|
||||||
|
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
**Just unzip the program archive to any folder, copy the file ```ffmpeg.exe``` into it 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)**
|
||||||
|
|
||||||
|
# Updating
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
1. Delete the "PersonalUtilities" project from the solution.
|
1. Delete the "PersonalUtilities" project from the solution.
|
||||||
2. Add the latest version of the "PersonalUtilities.dll" library (from the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest)).
|
1. Add the latest version of the "PersonalUtilities.dll" library (from the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest)).
|
||||||
3. Import PersonalUtilities.Functions for the whole project.
|
1. Import PersonalUtilities.Functions for the whole project.
|
||||||
|
|
||||||
# Updating
|
# How to make a plugin
|
||||||
|
|
||||||
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.
|
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).
|
||||||
|
|
||||||
# Settings and usage
|
# Settings and usage
|
||||||
|
|
||||||
@@ -92,16 +125,16 @@ You can add users by patterns:
|
|||||||
|
|
||||||
Read more about adding users and subreddits [here](https://github.com/AAndyProgram/SCrawler/wiki/Users)
|
Read more about adding users and subreddits [here](https://github.com/AAndyProgram/SCrawler/wiki/Users)
|
||||||
|
|
||||||
# Guide
|

|
||||||
|
|
||||||
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
|
# Using program as just video downloader
|
||||||
|
|
||||||
## Using program as just video downloader
|
|
||||||
|
|
||||||
Create a shortcut for the program. Open shortcut properties. In the ```Shortcut``` tab, in the ```Target``` field, just add the letter ```v``` at the end across the space.
|
Create a shortcut for the program. Open shortcut properties. In the ```Shortcut``` tab, in the ```Target``` field, just add the letter ```v``` at the end across the space.
|
||||||
|
|
||||||
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
|
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# Contact me
|
# Contact me
|
||||||
|
|
||||||
[](https://matrix.to/#/@andyprogram:matrix.org)
|
[](https://matrix.to/#/@andyprogram:matrix.org)
|
||||||
|
|||||||
3
SCrawler.PluginProvider/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[*.vb]
|
||||||
|
# Modifier preferences
|
||||||
|
file_header_template = Copyright (C) 2022 Andy\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
153
SCrawler.PluginProvider/Attributes/Attributes.vb
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Runtime.CompilerServices
|
||||||
|
Namespace Plugin.Attributes
|
||||||
|
''' <summary>Create a control for a property</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class PropertyOption : Inherits Attribute
|
||||||
|
''' <summary>Property name</summary>
|
||||||
|
Public ReadOnly Property Name As String
|
||||||
|
''' <summary>Property value type</summary>
|
||||||
|
Public Property [Type] As Type
|
||||||
|
Private _ControlText As String
|
||||||
|
''' <summary>This text will be displayed on the control information.<br/>Default: equals the name (property name)</summary>
|
||||||
|
Public Property ControlText As String
|
||||||
|
Get
|
||||||
|
Return If(String.IsNullOrEmpty(_ControlText), Name, _ControlText)
|
||||||
|
End Get
|
||||||
|
Set(ByVal NewText As String)
|
||||||
|
_ControlText = NewText
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
''' <summary>This tooltip will be displayed on the control.<br/>Default: <see langword="String.Empty"/></summary>
|
||||||
|
Public Property ControlToolTip As String
|
||||||
|
''' <summary>CheckBox ThreeStates mode</summary>
|
||||||
|
Public Property ThreeStates As Boolean = False
|
||||||
|
''' <summary>Property allows null values</summary>
|
||||||
|
Public Property AllowNull As Boolean = True
|
||||||
|
''' <summary>Offset the control from the left border of the form.<br/>Default: 100</summary>
|
||||||
|
Public Property LeftOffset As Integer = 100
|
||||||
|
''' <summary>This is an authorization property</summary>
|
||||||
|
Public Property IsAuth As Boolean = False
|
||||||
|
''' <summary>Initialize a new property option attribute</summary>
|
||||||
|
''' <param name="PropertyName">Property name</param>
|
||||||
|
Public Sub New(<CallerMemberName()> Optional ByVal PropertyName As String = Nothing)
|
||||||
|
Name = PropertyName
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Store property value in settings XML file</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class PXML : Inherits Attribute
|
||||||
|
Public ReadOnly ElementName As String
|
||||||
|
''' <summary>Initialize a new XML attribute</summary>
|
||||||
|
''' <param name="XMLElementName">XML element name</param>
|
||||||
|
Public Sub New(<CallerMemberName()> Optional ByVal XMLElementName As String = Nothing)
|
||||||
|
ElementName = XMLElementName
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Special property updater</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class PropertyUpdater : Inherits Attribute
|
||||||
|
Public ReadOnly Name As String
|
||||||
|
Public ReadOnly Dependencies As String()
|
||||||
|
''' <inheritdoc cref="PropertyUpdater.New(String, String())"/>
|
||||||
|
Public Sub New(ByVal UpdatingPropertyName As String)
|
||||||
|
Name = UpdatingPropertyName
|
||||||
|
End Sub
|
||||||
|
''' <summary>Initialize a new PropertyUpdater attribute</summary>
|
||||||
|
''' <param name="UpdatingPropertyName">The name of the property to be updated</param>
|
||||||
|
Public Sub New(ByVal UpdatingPropertyName As String, ByVal Dependent As String())
|
||||||
|
Name = UpdatingPropertyName
|
||||||
|
Dependencies = Dependent
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Plugin key</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class Manifest : Inherits Attribute
|
||||||
|
Public ReadOnly GUID As String
|
||||||
|
''' <summary>Initialize a new Manifest attribute</summary>
|
||||||
|
''' <param name="ClassGuid">Plugin key</param>
|
||||||
|
Public Sub New(ByVal ClassGuid As String)
|
||||||
|
GUID = ClassGuid
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Special form attribute for settings forms and user creator form</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class SpecialForm : Inherits Attribute
|
||||||
|
Public ReadOnly SettingsForm As Boolean
|
||||||
|
''' <summary>Initialize a new SpecialForm attribute</summary>
|
||||||
|
''' <param name="IsSettingsForm">
|
||||||
|
''' <see langword="True"/> - for setting form<br/>
|
||||||
|
''' <see langword="False"/> - for user creator form
|
||||||
|
''' </param>
|
||||||
|
Public Sub New(ByVal IsSettingsForm As Boolean)
|
||||||
|
SettingsForm = IsSettingsForm
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Property provider</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class Provider : Inherits Attribute
|
||||||
|
Public ReadOnly Name As String
|
||||||
|
''' <summary>
|
||||||
|
''' <see langword="True"/> - form field validation provider. Must return null if the value is invalid.<br/>
|
||||||
|
''' <see langword="False"/> - only for conversion
|
||||||
|
''' </summary>
|
||||||
|
Public FieldsChecker 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)
|
||||||
|
Name = PropertyName
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Sort attribute for settings form</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class ControlNumber : Inherits Attribute
|
||||||
|
Public ReadOnly PropertyNumber As String
|
||||||
|
''' <summary>Initialize a new sort attribute instance for the settings form</summary>
|
||||||
|
''' <param name="Number">Object position number in the settings form</param>
|
||||||
|
Public Sub New(ByVal Number As Integer)
|
||||||
|
PropertyNumber = Number
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>Attribute for properties values validation methods</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=True, Inherited:=False)> Public NotInheritable Class PropertiesDataChecker : Inherits Attribute
|
||||||
|
Public ReadOnly ComparableNames As String()
|
||||||
|
''' <summary>Initialize a new PropertiesDataChecker attribute.</summary>
|
||||||
|
''' <param name="Names">Array of the property names</param>
|
||||||
|
Public Sub New(ByVal Names As String())
|
||||||
|
ComparableNames = Names
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>This attribute specifies that users should be downloaded on a separate thread.</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class SeparatedTasks : Inherits Attribute
|
||||||
|
Public ReadOnly TasksCount As Integer
|
||||||
|
''' <summary>Initialize a new SeparatedTasks attribute.</summary>
|
||||||
|
''' <param name="JobsCount">
|
||||||
|
''' Predefined task counter.<br/>
|
||||||
|
''' <see cref="TaskCounter"/> will take precedence if it is defined.
|
||||||
|
''' </param>
|
||||||
|
Public Sub New(Optional ByVal JobsCount As Integer = -1)
|
||||||
|
TasksCount = JobsCount
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
''' <summary>A property attribute that specifies how many users should be downloaded at the same time in one thread</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class TaskCounter : Inherits Attribute
|
||||||
|
End Class
|
||||||
|
''' <summary>This attribute indicates that the plugin has a SavedPosts environment</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class SavedPosts : Inherits Attribute
|
||||||
|
End Class
|
||||||
|
''' <summary>This is an attribute of the UserData instance. Specifies that the default internal SCrawler downloader should be used.</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Class, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class UseInternalDownloader : Inherits Attribute
|
||||||
|
End Class
|
||||||
|
''' <summary>GitHub plugin info</summary>
|
||||||
|
<AttributeUsage(AttributeTargets.Assembly, AllowMultiple:=False, Inherited:=False)> Public NotInheritable Class Github : Inherits Attribute
|
||||||
|
Public ReadOnly UserName As String
|
||||||
|
Public ReadOnly Repository As String
|
||||||
|
''' <summary>Initialize a new Github attribute.</summary>
|
||||||
|
''' <param name="Name">Developer GitHub username</param>
|
||||||
|
''' <param name="RepoName">Plugin repository name</param>
|
||||||
|
Public Sub New(ByVal Name As String, ByVal RepoName As String)
|
||||||
|
UserName = Name
|
||||||
|
Repository = RepoName
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
36
SCrawler.PluginProvider/Interfaces/IPluginContentProvider.vb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Interface IPluginContentProvider
|
||||||
|
Event ProgressChanged(ByVal Count As Integer)
|
||||||
|
Event TotalCountChanged(ByVal Count As Integer)
|
||||||
|
Property Thrower As IThrower
|
||||||
|
Property LogProvider As ILogProvider
|
||||||
|
Property Settings As ISiteSettings
|
||||||
|
Property Name As String
|
||||||
|
Property ID As String
|
||||||
|
Property ParseUserMediaOnly As Boolean
|
||||||
|
Property UserDescription As String
|
||||||
|
Property ExistingContentList As List(Of PluginUserMedia)
|
||||||
|
Property TempPostsList As List(Of String)
|
||||||
|
Property TempMediaList As List(Of IPluginUserMedia)
|
||||||
|
Property UserExists As Boolean
|
||||||
|
Property UserSuspended As Boolean
|
||||||
|
Property IsSavedPosts As Boolean
|
||||||
|
Property SeparateVideoFolder As Boolean
|
||||||
|
Property DataPath As String
|
||||||
|
Property PostsNumberLimit As Integer?
|
||||||
|
Function ExchangeOptionsGet() As Object
|
||||||
|
Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||||
|
Sub XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String)))
|
||||||
|
Function XmlFieldsGet() As List(Of KeyValuePair(Of String, String))
|
||||||
|
Sub GetMedia()
|
||||||
|
Sub Download()
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
47
SCrawler.PluginProvider/Interfaces/ISiteSettings.vb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Drawing
|
||||||
|
Namespace Plugin
|
||||||
|
Public Interface ISiteSettings
|
||||||
|
Enum Download As Integer
|
||||||
|
Main = 0
|
||||||
|
SavedPosts = 1
|
||||||
|
Channel = 2
|
||||||
|
End Enum
|
||||||
|
ReadOnly Property Icon As Icon
|
||||||
|
ReadOnly Property Image As Image
|
||||||
|
ReadOnly Property Site As String
|
||||||
|
Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String
|
||||||
|
Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||||
|
Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
|
||||||
|
Function GetSpecialData(ByVal URL As String) As IEnumerable(Of IPluginUserMedia)
|
||||||
|
Function GetInstance(ByVal What As Download) As IPluginContentProvider
|
||||||
|
#Region "XML Support"
|
||||||
|
Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String)))
|
||||||
|
#End Region
|
||||||
|
#Region "Initialization"
|
||||||
|
Sub BeginInit()
|
||||||
|
Sub EndInit()
|
||||||
|
Sub BeginUpdate()
|
||||||
|
Sub EndUpdate()
|
||||||
|
#End Region
|
||||||
|
#Region "Site availability"
|
||||||
|
Function Available(ByVal What As Download) As Boolean
|
||||||
|
Function ReadyToDownload(ByVal What As Download) As Boolean
|
||||||
|
#End Region
|
||||||
|
#Region "Downloading"
|
||||||
|
Sub DownloadStarted(ByVal What As Download)
|
||||||
|
Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
|
||||||
|
Sub AfterDownload(ByVal User As Object, ByVal What As Download)
|
||||||
|
Sub DownloadDone(ByVal What As Download)
|
||||||
|
#End Region
|
||||||
|
Sub OpenSettingsForm()
|
||||||
|
Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
13
SCrawler.PluginProvider/My Project/Application.Designer.vb
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
10
SCrawler.PluginProvider/My Project/Application.myapp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<MySubMain>false</MySubMain>
|
||||||
|
<SingleInstance>false</SingleInstance>
|
||||||
|
<ShutdownMode>0</ShutdownMode>
|
||||||
|
<EnableVisualStyles>true</EnableVisualStyles>
|
||||||
|
<AuthenticationMode>0</AuthenticationMode>
|
||||||
|
<ApplicationType>1</ApplicationType>
|
||||||
|
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||||
|
</MyApplicationData>
|
||||||
37
SCrawler.PluginProvider/My Project/AssemblyInfo.vb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Imports System.Resources
|
||||||
|
Imports System
|
||||||
|
Imports System.Reflection
|
||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
' General Information about an assembly is controlled through the following
|
||||||
|
' set of attributes. Change these attribute values to modify the information
|
||||||
|
' associated with an assembly.
|
||||||
|
|
||||||
|
' Review the values of the assembly attributes
|
||||||
|
|
||||||
|
<Assembly: AssemblyTitle("SCrawler plugin provider")>
|
||||||
|
<Assembly: AssemblyDescription("Plugin provider for SCrawler")>
|
||||||
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
|
<Assembly: AssemblyProduct("SCrawler.PluginProvider")>
|
||||||
|
<Assembly: AssemblyCopyright("Copyright © 2022")>
|
||||||
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
|
<Assembly: ComVisible(False)>
|
||||||
|
|
||||||
|
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
<Assembly: Guid("1f6c9516-360e-4a2b-80d4-ae0d9a4e5cfd")>
|
||||||
|
|
||||||
|
' Version information for an assembly consists of the following four values:
|
||||||
|
'
|
||||||
|
' Major Version
|
||||||
|
' Minor Version
|
||||||
|
' Build Number
|
||||||
|
' Revision
|
||||||
|
'
|
||||||
|
' You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
' by using the '*' as shown below:
|
||||||
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
|
<Assembly: AssemblyVersion("3.0.0.0")>
|
||||||
|
<Assembly: AssemblyFileVersion("3.0.0.0")>
|
||||||
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
63
SCrawler.PluginProvider/My Project/Resources.Designer.vb
generated
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
Imports System
|
||||||
|
|
||||||
|
Namespace My.Resources
|
||||||
|
|
||||||
|
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
'class via a tool like ResGen or Visual Studio.
|
||||||
|
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
'with the /str option, or rebuild your VS project.
|
||||||
|
'''<summary>
|
||||||
|
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||||
|
Friend Module Resources
|
||||||
|
|
||||||
|
Private resourceMan As Global.System.Resources.ResourceManager
|
||||||
|
|
||||||
|
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||||
|
Get
|
||||||
|
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||||
|
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SCrawler.Resources", GetType(Resources).Assembly)
|
||||||
|
resourceMan = temp
|
||||||
|
End If
|
||||||
|
Return resourceMan
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Overrides the current thread's CurrentUICulture property for all
|
||||||
|
''' resource lookups using this strongly typed resource class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||||
|
Get
|
||||||
|
Return resourceCulture
|
||||||
|
End Get
|
||||||
|
Set
|
||||||
|
resourceCulture = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
117
SCrawler.PluginProvider/My Project/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?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.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: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" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</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" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
73
SCrawler.PluginProvider/My Project/Settings.Designer.vb
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
|
||||||
|
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Partial Friend NotInheritable Class MySettings
|
||||||
|
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||||
|
|
||||||
|
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||||
|
|
||||||
|
#Region "My.Settings Auto-Save Functionality"
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
Private Shared addedHandler As Boolean
|
||||||
|
|
||||||
|
Private Shared addedHandlerLockObject As New Object
|
||||||
|
|
||||||
|
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||||
|
If My.Application.SaveMySettingsOnExit Then
|
||||||
|
My.Settings.Save()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
#End If
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
Public Shared ReadOnly Property [Default]() As MySettings
|
||||||
|
Get
|
||||||
|
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
If Not addedHandler Then
|
||||||
|
SyncLock addedHandlerLockObject
|
||||||
|
If Not addedHandler Then
|
||||||
|
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||||
|
addedHandler = True
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
End If
|
||||||
|
#End If
|
||||||
|
Return defaultInstance
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||||
|
Friend Module MySettingsProperty
|
||||||
|
|
||||||
|
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||||
|
Friend ReadOnly Property Settings() As Global.SCrawler.My.MySettings
|
||||||
|
Get
|
||||||
|
Return Global.SCrawler.My.MySettings.Default
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
7
SCrawler.PluginProvider/My Project/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
16
SCrawler.PluginProvider/ObjectInterfaces/ILogProvider.vb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Interface ILogProvider
|
||||||
|
Overloads Sub Add(ByVal Message As String)
|
||||||
|
Overloads Sub Add(ByVal ex As Exception, ByVal Message As String,
|
||||||
|
Optional ByVal ShowMainMsg As Boolean = False, Optional ByVal ShowErrorMsg As Boolean = False,
|
||||||
|
Optional ByVal SendInLog As Boolean = True)
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
40
SCrawler.PluginProvider/ObjectInterfaces/IPluginUserMedia.vb
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Structure PluginUserMedia : Implements IPluginUserMedia
|
||||||
|
Public Property ContentType As Integer Implements IPluginUserMedia.ContentType
|
||||||
|
Public Property URL As String Implements IPluginUserMedia.URL
|
||||||
|
Public Property MD5 As String Implements IPluginUserMedia.MD5
|
||||||
|
Public Property File As String Implements IPluginUserMedia.File
|
||||||
|
Public Property DownloadState As Integer Implements IPluginUserMedia.DownloadState
|
||||||
|
Public Property PostID As String Implements IPluginUserMedia.PostID
|
||||||
|
Public Property PostDate As Date? Implements IPluginUserMedia.PostDate
|
||||||
|
Public Property SpecialFolder As String Implements IPluginUserMedia.SpecialFolder
|
||||||
|
End Structure
|
||||||
|
Public Interface IPluginUserMedia
|
||||||
|
Enum Types As Integer
|
||||||
|
Undefined = 0
|
||||||
|
[Picture] = 1
|
||||||
|
[Video] = 2
|
||||||
|
[Text] = 3
|
||||||
|
VideoPre = 10
|
||||||
|
GIF = 50
|
||||||
|
m3u8 = 100
|
||||||
|
End Enum
|
||||||
|
Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : End Enum
|
||||||
|
Property ContentType As Integer
|
||||||
|
Property URL As String
|
||||||
|
Property MD5 As String
|
||||||
|
Property File As String
|
||||||
|
Property DownloadState As Integer
|
||||||
|
Property PostID As String
|
||||||
|
Property PostDate As Date?
|
||||||
|
Property SpecialFolder As String
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
13
SCrawler.PluginProvider/ObjectInterfaces/IThrower.vb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Interface IThrower
|
||||||
|
Sub ThrowAny()
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
25
SCrawler.PluginProvider/Objects/ExchangeOptions.vb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Structure ExchangeOptions
|
||||||
|
Public UserName As String
|
||||||
|
Public SiteName As String
|
||||||
|
Public HostKey As String
|
||||||
|
Public IsChannel As Boolean
|
||||||
|
Public Exists As Boolean
|
||||||
|
Public Sub New(ByVal Site As String, ByVal _Name As String)
|
||||||
|
UserName = _Name
|
||||||
|
SiteName = Site
|
||||||
|
End Sub
|
||||||
|
Public Sub New(ByVal Site As String, ByVal _Name As String, ByVal _IsChannel As Boolean)
|
||||||
|
Me.New(Site, _Name)
|
||||||
|
IsChannel = _IsChannel
|
||||||
|
End Sub
|
||||||
|
End Structure
|
||||||
|
End Namespace
|
||||||
18
SCrawler.PluginProvider/Objects/PropertyData.vb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public Structure PropertyData
|
||||||
|
Public ReadOnly Name As String
|
||||||
|
Public ReadOnly Value As Object
|
||||||
|
Public Sub New(ByVal _Name As String, ByVal _Value As Object)
|
||||||
|
Name = _Name
|
||||||
|
Value = _Value
|
||||||
|
End Sub
|
||||||
|
End Structure
|
||||||
|
End Namespace
|
||||||
58
SCrawler.PluginProvider/Objects/PropertyValue.vb
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace Plugin
|
||||||
|
Public NotInheritable Class PropertyValue : Implements IPropertyValue
|
||||||
|
Public Event ValueChanged As IPropertyValue.ValueChangedEventHandler Implements IPropertyValue.ValueChanged
|
||||||
|
Public Property [Type] As Type Implements IPropertyValue.Type
|
||||||
|
Public Property OnChangeFunction As IPropertyValue.ValueChangedEventHandler
|
||||||
|
''' <inheritdoc cref="PropertyValue.New(Object, Type, ByRef IPropertyValue.ValueChangedEventHandler)"/>
|
||||||
|
''' <exception cref="ArgumentNullException"></exception>
|
||||||
|
Public Sub New(ByVal InitValue As Object)
|
||||||
|
_Value = InitValue
|
||||||
|
If IsNothing(InitValue) Then
|
||||||
|
Throw New ArgumentNullException("InitValue", "InitValue cannot be null")
|
||||||
|
Else
|
||||||
|
[Type] = _Value.GetType
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
''' <inheritdoc cref="PropertyValue.New(Object, Type, ByRef IPropertyValue.ValueChangedEventHandler)"/>
|
||||||
|
Public Sub New(ByVal InitValue As Object, ByVal T As Type)
|
||||||
|
_Value = InitValue
|
||||||
|
[Type] = T
|
||||||
|
End Sub
|
||||||
|
''' <summary>New property value instance</summary>
|
||||||
|
''' <param name="InitValue">Initialization value</param>
|
||||||
|
''' <param name="T">Value type</param>
|
||||||
|
''' <param name="RFunction">CallBack function on value change</param>
|
||||||
|
Public Sub New(ByVal InitValue As Object, ByVal T As Type, ByRef RFunction As IPropertyValue.ValueChangedEventHandler)
|
||||||
|
Me.New(InitValue, T)
|
||||||
|
OnChangeFunction = RFunction
|
||||||
|
End Sub
|
||||||
|
Private _Value As Object
|
||||||
|
Public Property Value As Object Implements IPropertyValue.Value
|
||||||
|
Get
|
||||||
|
Return _Value
|
||||||
|
End Get
|
||||||
|
Set(ByVal NewValue As Object)
|
||||||
|
_Value = NewValue
|
||||||
|
If Not OnChangeFunction Is Nothing Then OnChangeFunction.Invoke(Value)
|
||||||
|
RaiseEvent ValueChanged(_Value)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
|
Public Interface IPropertyValue
|
||||||
|
''' <summary>Event for internal exchange</summary>
|
||||||
|
''' <param name="Value">New value</param>
|
||||||
|
Event ValueChanged(ByVal Value As Object)
|
||||||
|
''' <summary>Value type</summary>
|
||||||
|
Property [Type] As Type
|
||||||
|
''' <summary>Property value</summary>
|
||||||
|
Property Value As Object
|
||||||
|
End Interface
|
||||||
|
End Namespace
|
||||||
151
SCrawler.PluginProvider/SCrawler.PluginProvider.vbproj
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{D4650F6B-5A54-44B6-999B-6C675B7116B1}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>SCrawler</RootNamespace>
|
||||||
|
<AssemblyName>SCrawler.PluginProvider</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<MyType>Windows</MyType>
|
||||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<DefineDebug>false</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionExplicit>On</OptionExplicit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionCompare>Binary</OptionCompare>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionStrict>Off</OptionStrict>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionInfer>On</OptionInfer>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
|
<Import Include="System" />
|
||||||
|
<Import Include="System.Collections" />
|
||||||
|
<Import Include="System.Collections.Generic" />
|
||||||
|
<Import Include="System.Data" />
|
||||||
|
<Import Include="System.Diagnostics" />
|
||||||
|
<Import Include="System.Linq" />
|
||||||
|
<Import Include="System.Xml.Linq" />
|
||||||
|
<Import Include="System.Threading.Tasks" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Attributes\Attributes.vb" />
|
||||||
|
<Compile Include="Objects\ExchangeOptions.vb" />
|
||||||
|
<Compile Include="ObjectInterfaces\ILogProvider.vb" />
|
||||||
|
<Compile Include="Interfaces\IPluginContentProvider.vb" />
|
||||||
|
<Compile Include="ObjectInterfaces\IPluginUserMedia.vb" />
|
||||||
|
<Compile Include="Interfaces\ISiteSettings.vb" />
|
||||||
|
<Compile Include="ObjectInterfaces\IThrower.vb" />
|
||||||
|
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||||
|
<Compile Include="My Project\Application.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Application.myapp</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Resources.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Settings.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Objects\PropertyData.vb" />
|
||||||
|
<Compile Include="Objects\PropertyValue.vb" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="My Project\Resources.resx">
|
||||||
|
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||||
|
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include=".editorconfig" />
|
||||||
|
<None Include="My Project\Application.myapp">
|
||||||
|
<Generator>MyApplicationCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<None Include="My Project\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<CustomToolNamespace>My</CustomToolNamespace>
|
||||||
|
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
|
</Project>
|
||||||
14
SCrawler.sln
@@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
ToDo.txt = ToDo.txt
|
ToDo.txt = ToDo.txt
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.PluginProvider", "SCrawler.PluginProvider\SCrawler.PluginProvider.vbproj", "{D4650F6B-5A54-44B6-999B-6C675B7116B1}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -49,6 +51,18 @@ Global
|
|||||||
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x64.Build.0 = Release|x64
|
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x64.Build.0 = Release|x64
|
||||||
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x86.ActiveCfg = Release|x86
|
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x86.ActiveCfg = Release|x86
|
||||||
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x86.Build.0 = Release|x86
|
{8405896B-2685-4916-BC93-1FB514C323A9}.Release|x86.Build.0 = Release|x86
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{D4650F6B-5A54-44B6-999B-6C675B7116B1}.Release|x86.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
60
SCrawler/API/Base/DownDetector.vb
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Net
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Namespace API.Base
|
||||||
|
Friend NotInheritable Class DownDetector
|
||||||
|
Private Shared ReadOnly Property Params As New RParams("x:.'([\S]+?)',.y:.(\d+)", -1, Nothing, RegexReturn.List)
|
||||||
|
Private Sub New()
|
||||||
|
End Sub
|
||||||
|
Friend Structure Data : Implements IRegExCreator, IComparable(Of Data)
|
||||||
|
Friend [Date] As Date
|
||||||
|
Friend Value As Integer
|
||||||
|
Friend Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
|
||||||
|
If ParamsArray.ListExists Then
|
||||||
|
Try : [Date] = Date.Parse(ParamsArray(0)) : Catch : End Try
|
||||||
|
If ParamsArray.Length > 1 Then Value = AConvert(Of Integer)(ParamsArray(1), 0)
|
||||||
|
End If
|
||||||
|
Return Me
|
||||||
|
End Function
|
||||||
|
Public Overrides Function ToString() As String
|
||||||
|
Return $"{AConvert(Of String)([Date], ADateTime.Formats.BaseDateTime, String.Empty)} [{Value}]"
|
||||||
|
End Function
|
||||||
|
Friend Function CompareTo(ByVal Other As Data) As Integer Implements IComparable(Of Data).CompareTo
|
||||||
|
Return [Date].CompareTo(Other.Date) * -1
|
||||||
|
End Function
|
||||||
|
End Structure
|
||||||
|
Friend Shared Function GetData(ByVal Site As String) As List(Of Data)
|
||||||
|
Try
|
||||||
|
Dim l As List(Of Data) = Nothing
|
||||||
|
Using w As New WebClient
|
||||||
|
Dim r$ = w.DownloadString($"https://downdetector.co.uk/status/{Site}/")
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
l = FNF.RegexFields(Of Data)(r, {Params}, {1, 2})
|
||||||
|
If l.ListExists(2) Then
|
||||||
|
Dim lDate As Date = l(0).Date
|
||||||
|
Dim i%
|
||||||
|
Dim indx% = -1
|
||||||
|
For i = 1 To l.Count - 1
|
||||||
|
If l(i).Date < lDate Then indx = i : Exit For Else lDate = l(i).Date
|
||||||
|
Next
|
||||||
|
If indx >= 0 Then
|
||||||
|
For i = indx To 0 Step -1 : l.RemoveAt(i) : Next
|
||||||
|
End If
|
||||||
|
l.Sort()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
Return l
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, $"[DownDetector.GetData({Site})]")
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
61
SCrawler/API/Base/ProfileSaved.vb
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
|
Imports System.Threading
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports PDownload = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Namespace API.Base
|
||||||
|
Friend NotInheritable Class ProfileSaved
|
||||||
|
Private ReadOnly Property HOST As SettingsHost
|
||||||
|
Private ReadOnly Property Progress As MyProgress
|
||||||
|
Friend Sub New(ByRef h As SettingsHost, ByRef Bar As MyProgress)
|
||||||
|
HOST = h
|
||||||
|
Progress = Bar
|
||||||
|
End Sub
|
||||||
|
Friend Sub Download(ByVal Token As CancellationToken)
|
||||||
|
Try
|
||||||
|
If HOST.Source.ReadyToDownload(PDownload.SavedPosts) Then
|
||||||
|
If HOST.Available(PDownload.SavedPosts) Then
|
||||||
|
HOST.DownloadStarted(PDownload.SavedPosts)
|
||||||
|
Dim u As New UserInfo With {.Plugin = HOST.Key, .Site = HOST.Name, .SpecialPath = HOST.SavedPostsPath}
|
||||||
|
Using user As IUserData = HOST.GetInstance(PDownload.SavedPosts, Nothing, False, False)
|
||||||
|
If Not user Is Nothing AndAlso (Not user.Name.IsEmptyString Or Not HOST.IsMyClass) Then
|
||||||
|
u.Name = user.Name
|
||||||
|
With DirectCast(user, UserDataBase).User
|
||||||
|
u.IsChannel = .IsChannel
|
||||||
|
u.UpdateUserFile()
|
||||||
|
End With
|
||||||
|
With DirectCast(user, UserDataBase)
|
||||||
|
.User = u
|
||||||
|
.LoadUserInformation()
|
||||||
|
.IsSavedPosts = True
|
||||||
|
.Progress = Progress
|
||||||
|
If Not .FileExists Then .UpdateUserInformation()
|
||||||
|
End With
|
||||||
|
HOST.BeforeStartDownload(user, PDownload.SavedPosts)
|
||||||
|
user.DownloadData(Token)
|
||||||
|
Progress.InformationTemporary = $"Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}"
|
||||||
|
HOST.AfterDownload(user, PDownload.SavedPosts)
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
Else
|
||||||
|
Progress.InformationTemporary = $"Host [{HOST.Name}] is unavailable"
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Progress.InformationTemporary = $"Host [{HOST.Name}] is nor ready"
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Progress.InformationTemporary = $"{HOST.Name} downloading error"
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, ex, $"[API.Base.ProfileSaved.Download({HOST.Key})]")
|
||||||
|
Finally
|
||||||
|
HOST.DownloadDone(PDownload.SavedPosts)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
Imports PersonalUtilities.Tools
|
|
||||||
Imports PersonalUtilities.Functions.XML
|
|
||||||
Imports PersonalUtilities.Functions.XML.Base
|
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
|
||||||
Namespace API.Base
|
|
||||||
Friend Class SiteSettings : Implements IDisposable
|
|
||||||
Friend Const Header_Twitter_Authorization As String = "authorization"
|
|
||||||
Friend Const Header_Twitter_Token As String = "x-csrf-token"
|
|
||||||
Friend ReadOnly Site As Sites
|
|
||||||
Friend ReadOnly Responser As WEB.Response
|
|
||||||
Private ReadOnly _Path As XMLValue(Of SFile)
|
|
||||||
Friend Property Path(Optional ByVal SetProp As Boolean = True) As SFile
|
|
||||||
Get
|
|
||||||
If _Path.IsEmptyString Then
|
|
||||||
Dim tmpPath As SFile = SFile.GetPath($"{Settings.GlobalPath.Value.PathWithSeparator}{Site}")
|
|
||||||
If SetProp Then _Path.Value = tmpPath Else Return tmpPath
|
|
||||||
End If
|
|
||||||
Return _Path.Value
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewPath As SFile)
|
|
||||||
_Path.Value = NewPath
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly _SavedPostsPath As XMLValue(Of SFile)
|
|
||||||
Friend Property SavedPostsPath(Optional ByVal GetAny As Boolean = True) As SFile
|
|
||||||
Get
|
|
||||||
If Not _SavedPostsPath.Value.IsEmptyString Then
|
|
||||||
Return _SavedPostsPath.Value
|
|
||||||
Else
|
|
||||||
If GetAny Then
|
|
||||||
Return $"{Path.PathNoSeparator}\!Saved\"
|
|
||||||
Else
|
|
||||||
Return Nothing
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewPath As SFile)
|
|
||||||
_SavedPostsPath.Value = NewPath
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
#Region "Instagram"
|
|
||||||
Friend ReadOnly Property InstaHash As XMLValue(Of String)
|
|
||||||
Friend ReadOnly Property InstaHash_SP As XMLValue(Of String)
|
|
||||||
Friend ReadOnly Property InstaHashUpdateRequired As XMLValue(Of Boolean)
|
|
||||||
Friend ReadOnly Property InstagramDownloadingErrorDate As XMLValue(Of Date)
|
|
||||||
Friend Property InstagramLastApplyingValue As Integer? = Nothing
|
|
||||||
Friend ReadOnly Property InstagramReadyForDownload As Boolean
|
|
||||||
Get
|
|
||||||
With InstagramDownloadingErrorDate
|
|
||||||
If .ValueF.Exists Then
|
|
||||||
Return .ValueF.Value.AddMinutes(If(InstagramLastApplyingValue, 10)) < Now
|
|
||||||
Else
|
|
||||||
Return True
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Friend ReadOnly Property InstagramLastDownloadDate As XMLValue(Of Date)
|
|
||||||
Friend ReadOnly Property InstagramLastRequestsCount As XMLValue(Of Integer)
|
|
||||||
Private InstagramTooManyRequestsReadyForCatch As Boolean = True
|
|
||||||
Friend Function GetInstaWaitDate() As Date
|
|
||||||
With InstagramDownloadingErrorDate
|
|
||||||
If .ValueF.Exists Then
|
|
||||||
Return .ValueF.Value.AddMinutes(If(InstagramLastApplyingValue, 10))
|
|
||||||
Else
|
|
||||||
Return Now
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
End Function
|
|
||||||
Friend Sub InstagramTooManyRequests(ByVal Catched As Boolean)
|
|
||||||
With InstagramDownloadingErrorDate
|
|
||||||
If Catched Then
|
|
||||||
If Not .ValueF.Exists Then
|
|
||||||
.Value = Now
|
|
||||||
If InstagramTooManyRequestsReadyForCatch Then
|
|
||||||
InstagramLastApplyingValue = If(InstagramLastApplyingValue, 0) + 10
|
|
||||||
InstagramTooManyRequestsReadyForCatch = False
|
|
||||||
MyMainLOG = $"Instagram downloading error: too many requests. Try again after {If(InstagramLastApplyingValue, 10)} minutes..."
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
.ValueF = Nothing
|
|
||||||
InstagramLastApplyingValue = Nothing
|
|
||||||
InstagramTooManyRequestsReadyForCatch = True
|
|
||||||
End If
|
|
||||||
End With
|
|
||||||
End Sub
|
|
||||||
Friend ReadOnly Property RequestsWaitTimer As XMLValue(Of Integer)
|
|
||||||
Friend ReadOnly Property RequestsWaitTimerTaskCount As XMLValue(Of Integer)
|
|
||||||
Friend ReadOnly Property SleepTimerOnPostsLimit As XMLValue(Of Integer)
|
|
||||||
#End Region
|
|
||||||
Friend ReadOnly Property Temporary As XMLValue(Of Boolean)
|
|
||||||
Friend ReadOnly Property DownloadImages As XMLValue(Of Boolean)
|
|
||||||
Friend ReadOnly Property DownloadVideos As XMLValue(Of Boolean)
|
|
||||||
Friend ReadOnly Property GetUserMediaOnly As XMLValue(Of Boolean)
|
|
||||||
Friend ReadOnly Property SavedPostsUserName As XMLValue(Of String)
|
|
||||||
Private ReadOnly SettingsFile As SFile
|
|
||||||
Friend Sub New(ByVal s As Sites, ByRef _XML As XmlFile, ByVal GlobalPath As SFile,
|
|
||||||
ByRef _Temp As XMLValue(Of Boolean), ByRef _Imgs As XMLValue(Of Boolean), ByRef _Vids As XMLValue(Of Boolean))
|
|
||||||
Site = s
|
|
||||||
SettingsFile = $"{SettingsFolderName}\Responser_{s}.xml"
|
|
||||||
Responser = New WEB.Response(SettingsFile)
|
|
||||||
|
|
||||||
If SettingsFile.Exists Then
|
|
||||||
Responser.LoadSettings()
|
|
||||||
Else
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Twitter
|
|
||||||
With Responser
|
|
||||||
.ContentType = "application/json"
|
|
||||||
.Accept = "*/*"
|
|
||||||
.CookiesDomain = "twitter.com"
|
|
||||||
.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
|
||||||
With .Headers
|
|
||||||
.Add("sec-ch-ua", " Not;A Brand" & Chr(34) & ";v=" & Chr(34) & "99" & Chr(34) & ", " & Chr(34) &
|
|
||||||
"Google Chrome" & Chr(34) & ";v=" & Chr(34) & "91" & Chr(34) & ", " & Chr(34) & "Chromium" &
|
|
||||||
Chr(34) & ";v=" & Chr(34) & "91" & Chr(34))
|
|
||||||
.Add("sec-ch-ua-mobile", "?0")
|
|
||||||
.Add("sec-fetch-dest", "empty")
|
|
||||||
.Add("sec-fetch-mode", "cors")
|
|
||||||
.Add("sec-fetch-site", "same-origin")
|
|
||||||
.Add(Header_Twitter_Token, String.Empty)
|
|
||||||
.Add("x-twitter-active-user", "yes")
|
|
||||||
.Add("x-twitter-auth-type", "OAuth2Session")
|
|
||||||
.Add(Header_Twitter_Authorization, String.Empty)
|
|
||||||
End With
|
|
||||||
End With
|
|
||||||
Case Sites.Reddit
|
|
||||||
Responser.CookiesDomain = "reddit.com"
|
|
||||||
Responser.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
|
||||||
Case Sites.Instagram : Responser.CookiesDomain = "instagram.com"
|
|
||||||
Case Sites.RedGifs : Responser.CookiesDomain = "redgifs.com"
|
|
||||||
End Select
|
|
||||||
Responser.SaveSettings()
|
|
||||||
End If
|
|
||||||
|
|
||||||
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
|
|
||||||
_Path = New XMLValue(Of SFile)("Path",, _XML, n, XMLValue(Of SFile).ToFilePath)
|
|
||||||
_XML.Remove(Site.ToString)
|
|
||||||
|
|
||||||
Temporary = New XMLValue(Of Boolean)
|
|
||||||
Temporary.SetExtended("Temporary", False, _XML, n)
|
|
||||||
Temporary.SetDefault(_Temp)
|
|
||||||
|
|
||||||
DownloadImages = New XMLValue(Of Boolean)
|
|
||||||
DownloadImages.SetExtended("DownloadImages", True, _XML, n)
|
|
||||||
DownloadImages.SetDefault(_Imgs)
|
|
||||||
|
|
||||||
DownloadVideos = New XMLValue(Of Boolean)
|
|
||||||
DownloadVideos.SetExtended("DownloadVideos", True, _XML, n)
|
|
||||||
DownloadVideos.SetDefault(_Vids)
|
|
||||||
|
|
||||||
GetUserMediaOnly = New XMLValue(Of Boolean)("GetUserMediaOnly", True, _XML, n)
|
|
||||||
_SavedPostsPath = New XMLValue(Of SFile)("SavedPostsPath",, _XML, n, XMLValue(Of SFile).ToFilePath)
|
|
||||||
|
|
||||||
CreateProp(InstaHashUpdateRequired, Sites.Instagram, "InstaHashUpdateRequired", True, _XML, n)
|
|
||||||
CreateProp(InstaHash, Sites.Instagram, "InstaHash", String.Empty, _XML, n)
|
|
||||||
If Site = Sites.Instagram AndAlso (InstaHash.IsEmptyString Or InstaHashUpdateRequired) AndAlso Responser.Cookies.ListExists Then GatherInstaHash()
|
|
||||||
CreateProp(InstaHash_SP, Sites.Instagram, "InstaHashSavedPosts", String.Empty, _XML, n)
|
|
||||||
CreateProp(InstagramLastDownloadDate, Sites.Instagram, "LastDownloadDate", Now.AddDays(-1), _XML, n)
|
|
||||||
CreateProp(InstagramLastRequestsCount, Sites.Instagram, "LastRequestsCount", 0, _XML, n)
|
|
||||||
CreateProp(RequestsWaitTimer, Sites.Instagram, "RequestsWaitTimer", 1000, _XML, n)
|
|
||||||
CreateProp(RequestsWaitTimerTaskCount, Sites.Instagram, "RequestsWaitTimerTaskCount", 1, _XML, n)
|
|
||||||
CreateProp(SleepTimerOnPostsLimit, Sites.Instagram, "SleepTimerOnPostsLimit", 60000, _XML, n)
|
|
||||||
If Site = Sites.Instagram Then
|
|
||||||
InstagramDownloadingErrorDate = New XMLValue(Of Date) With {.ToStringFunction = Function(ss, vv) AConvert(Of String)(vv, AModes.Var, Nothing)}
|
|
||||||
InstagramDownloadingErrorDate.SetExtended("InstagramDownloadingErrorDate", Now.AddYears(-10), _XML, n)
|
|
||||||
Else
|
|
||||||
InstagramDownloadingErrorDate = New XMLValue(Of Date)
|
|
||||||
End If
|
|
||||||
|
|
||||||
SavedPostsUserName = New XMLValue(Of String)("SavedPostsUserName", String.Empty, _XML, n)
|
|
||||||
End Sub
|
|
||||||
Private Sub CreateProp(Of T)(ByRef p As XMLValue(Of T), ByVal s As Sites,
|
|
||||||
ByVal p_Name As String, ByVal p_Value As T, ByRef x As XmlFile, ByVal n() As String)
|
|
||||||
If Site = s Then
|
|
||||||
p = New XMLValue(Of T)(p_Name, p_Value, x, n)
|
|
||||||
Else
|
|
||||||
p = New XMLValue(Of T)
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
Friend Sub Update()
|
|
||||||
Responser.SaveSettings()
|
|
||||||
End Sub
|
|
||||||
Friend Function GatherInstaHash() As Boolean
|
|
||||||
Try
|
|
||||||
Dim rs As New RParams("=""([^""]+?ConsumerLibCommons[^""]+?.js)""", Nothing, 1) With {.MatchTimeOut = 10}
|
|
||||||
Dim r$ = Responser.GetResponse("https://instagram.com",, EDP.ThrowException)
|
|
||||||
If Not r.IsEmptyString Then
|
|
||||||
Dim hStr$ = RegexReplace(r, rs)
|
|
||||||
If Not hStr.IsEmptyString Then
|
|
||||||
Do While Left(hStr, 1) = "/" : hStr = Right(hStr, hStr.Length - 1) : Loop
|
|
||||||
hStr = $"https://instagram.com/{hStr}"
|
|
||||||
r = Responser.GetResponse(hStr,, EDP.ThrowException)
|
|
||||||
If Not r.IsEmptyString Then
|
|
||||||
rs = New RParams("generatePaginationActionCreators.+?.profilePosts.byUserId.get.+?queryId:.([\d\w\S]+?)""", Nothing, 1) With {.MatchTimeOut = 10}
|
|
||||||
Dim h$ = RegexReplace(r, rs)
|
|
||||||
If Not h.IsEmptyString Then
|
|
||||||
InstaHash.Value = h
|
|
||||||
InstaHashUpdateRequired.Value = False
|
|
||||||
Return True
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
Return False
|
|
||||||
Catch ex As Exception
|
|
||||||
InstaHashUpdateRequired.Value = True
|
|
||||||
InstaHash.Value = String.Empty
|
|
||||||
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, "[SiteSettings.GaterInstaHash]", False)
|
|
||||||
End Try
|
|
||||||
End Function
|
|
||||||
#Region "IDisposable Support"
|
|
||||||
Private disposedValue As Boolean = False
|
|
||||||
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
|
||||||
If Not disposedValue Then
|
|
||||||
If disposing Then Responser.Dispose()
|
|
||||||
disposedValue = True
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
Protected Overrides Sub Finalize()
|
|
||||||
Dispose(False)
|
|
||||||
MyBase.Finalize()
|
|
||||||
End Sub
|
|
||||||
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
|
|
||||||
Dispose(True)
|
|
||||||
GC.SuppressFinalize(Me)
|
|
||||||
End Sub
|
|
||||||
#End Region
|
|
||||||
End Class
|
|
||||||
End Namespace
|
|
||||||
106
SCrawler/API/Base/SiteSettingsBase.vb
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.WEB
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Namespace API.Base
|
||||||
|
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer
|
||||||
|
Friend ReadOnly Property Site As String Implements ISiteSettings.Site
|
||||||
|
Friend Overridable ReadOnly Property Icon As Icon = Nothing Implements ISiteSettings.Icon
|
||||||
|
Friend Overridable ReadOnly Property Image As Image = Nothing Implements ISiteSettings.Image
|
||||||
|
Friend Overridable ReadOnly Property Responser As Response Implements IResponserContainer.Responser
|
||||||
|
Friend MustOverride Function GetInstance(ByVal What As Download) As IPluginContentProvider Implements ISiteSettings.GetInstance
|
||||||
|
Friend Sub New(ByVal SiteName As String)
|
||||||
|
Site = SiteName
|
||||||
|
End Sub
|
||||||
|
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String)
|
||||||
|
Site = SiteName
|
||||||
|
Responser = New Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||||
|
With Responser
|
||||||
|
If .File.Exists Then .LoadSettings() Else .CookiesDomain = CookiesDomain : .SaveSettings()
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
#Region "XML"
|
||||||
|
Friend Overridable Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String))) Implements ISiteSettings.Load
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Initialize"
|
||||||
|
Friend Overridable Sub BeginInit() Implements ISiteSettings.BeginInit
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub EndInit() Implements ISiteSettings.EndInit
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub BeginUpdate() Implements ISiteSettings.BeginUpdate
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub EndUpdate() Implements ISiteSettings.EndUpdate
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Before and After Download"
|
||||||
|
Friend Overridable Sub DownloadStarted(ByVal What As Download) Implements ISiteSettings.DownloadStarted
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download) Implements ISiteSettings.BeforeStartDownload
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub AfterDownload(ByVal User As Object, ByVal What As Download) Implements ISiteSettings.AfterDownload
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub DownloadDone(ByVal What As Download) Implements ISiteSettings.DownloadDone
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "User info"
|
||||||
|
Protected UrlPatternUser As String = String.Empty
|
||||||
|
Protected UrlPatternChannel As String = String.Empty
|
||||||
|
Friend Overridable Function GetUserUrl(ByVal UserName As String, ByVal Channel As Boolean) As String Implements ISiteSettings.GetUserUrl
|
||||||
|
If Channel Then
|
||||||
|
If Not UrlPatternChannel.IsEmptyString Then Return String.Format(UrlPatternChannel, UserName)
|
||||||
|
Else
|
||||||
|
If Not UrlPatternUser.IsEmptyString Then Return String.Format(UrlPatternUser, UserName)
|
||||||
|
End If
|
||||||
|
Return String.Empty
|
||||||
|
End Function
|
||||||
|
Protected UserRegex As RParams = Nothing
|
||||||
|
Friend Overridable Function IsMyUser(ByVal UserURL As String) As ExchangeOptions Implements ISiteSettings.IsMyUser
|
||||||
|
Try
|
||||||
|
If Not UserRegex Is Nothing Then
|
||||||
|
Dim s$ = RegexReplace(UserURL, UserRegex)
|
||||||
|
If Not s.IsEmptyString Then Return New ExchangeOptions(Site, s)
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, "[API.Base.SiteSettingsBase.IsMyUser]")
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Protected ImageVideoContains As String = String.Empty
|
||||||
|
Friend Overridable Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions Implements ISiteSettings.IsMyImageVideo
|
||||||
|
If Not ImageVideoContains.IsEmptyString AndAlso URL.Contains(ImageVideoContains) Then
|
||||||
|
Return New ExchangeOptions With {.Exists = True}
|
||||||
|
Else
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Friend Overridable Function GetSpecialData(ByVal URL As String) As IEnumerable(Of IPluginUserMedia) Implements ISiteSettings.GetSpecialData
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Friend Overridable Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
#Region "Ready, Available"
|
||||||
|
Friend Overridable Function Available(ByVal What As Download) As Boolean Implements ISiteSettings.Available
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
Friend Overridable Function ReadyToDownload(ByVal What As Download) As Boolean Implements ISiteSettings.ReadyToDownload
|
||||||
|
Return True
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
|
Friend Overridable Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean) Implements ISiteSettings.UserOptions
|
||||||
|
Options = Nothing
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Sub OpenSettingsForm() Implements ISiteSettings.OpenSettingsForm
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -18,8 +18,8 @@ Namespace API.Base
|
|||||||
GIF = 50
|
GIF = 50
|
||||||
m3u8 = 100
|
m3u8 = 100
|
||||||
End Enum
|
End Enum
|
||||||
Friend Enum States : Unknown : Tried : Downloaded : Skipped : End Enum
|
Friend Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : End Enum
|
||||||
Friend Type As Types
|
Friend [Type] As Types
|
||||||
Friend URL_BASE As String
|
Friend URL_BASE As String
|
||||||
Friend URL As String
|
Friend URL As String
|
||||||
Friend MD5 As String
|
Friend MD5 As String
|
||||||
@@ -27,6 +27,11 @@ Namespace API.Base
|
|||||||
Friend Post As UserPost
|
Friend Post As UserPost
|
||||||
Friend PictureOption As String
|
Friend PictureOption As String
|
||||||
Friend State As States
|
Friend State As States
|
||||||
|
''' <summary>
|
||||||
|
''' SomeFolder<br/>
|
||||||
|
''' SomeFolder\SomeFolder2
|
||||||
|
''' </summary>
|
||||||
|
Friend SpecialFolder As String
|
||||||
Friend Sub New(ByVal _URL As String)
|
Friend Sub New(ByVal _URL As String)
|
||||||
URL = _URL
|
URL = _URL
|
||||||
URL_BASE = _URL
|
URL_BASE = _URL
|
||||||
@@ -35,7 +40,18 @@ Namespace API.Base
|
|||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal _URL As String, ByVal _Type As Types)
|
Friend Sub New(ByVal _URL As String, ByVal _Type As Types)
|
||||||
Me.New(_URL)
|
Me.New(_URL)
|
||||||
Type = _Type
|
[Type] = _Type
|
||||||
|
End Sub
|
||||||
|
Friend Sub New(ByVal m As Plugin.IPluginUserMedia)
|
||||||
|
If Not IsNothing(m) Then
|
||||||
|
[Type] = m.ContentType
|
||||||
|
URL = m.URL
|
||||||
|
MD5 = m.MD5
|
||||||
|
File = m.File
|
||||||
|
Post = New UserPost With {.ID = m.PostID, .[Date] = m.PostDate}
|
||||||
|
State = m.DownloadState
|
||||||
|
SpecialFolder = m.SpecialFolder
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Public Shared Widening Operator CType(ByVal _URL As String) As UserMedia
|
Public Shared Widening Operator CType(ByVal _URL As String) As UserMedia
|
||||||
Return New UserMedia(_URL)
|
Return New UserMedia(_URL)
|
||||||
@@ -46,6 +62,18 @@ Namespace API.Base
|
|||||||
Public Overrides Function ToString() As String
|
Public Overrides Function ToString() As String
|
||||||
Return URL
|
Return URL
|
||||||
End Function
|
End Function
|
||||||
|
Friend Function PluginUserMedia() As Plugin.PluginUserMedia
|
||||||
|
Return New Plugin.PluginUserMedia With {
|
||||||
|
.ContentType = Type,
|
||||||
|
.DownloadState = State,
|
||||||
|
.File = File,
|
||||||
|
.MD5 = MD5,
|
||||||
|
.URL = URL,
|
||||||
|
.SpecialFolder = SpecialFolder,
|
||||||
|
.PostID = Post.ID,
|
||||||
|
.PostDate = Post.Date
|
||||||
|
}
|
||||||
|
End Function
|
||||||
Friend Overloads Function Equals(ByVal Other As UserMedia) As Boolean Implements IEquatable(Of UserMedia).Equals
|
Friend Overloads Function Equals(ByVal Other As UserMedia) As Boolean Implements IEquatable(Of UserMedia).Equals
|
||||||
Return URL = Other.URL
|
Return URL = Other.URL
|
||||||
End Function
|
End Function
|
||||||
|
|||||||
@@ -12,35 +12,80 @@ Imports PersonalUtilities.Forms.Toolbars
|
|||||||
Imports System.IO
|
Imports System.IO
|
||||||
Imports System.Net
|
Imports System.Net
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
Namespace API.Base
|
Namespace API.Base
|
||||||
Friend MustInherit Class UserDataBase : Implements IUserData
|
Friend MustInherit Class UserDataBase : Implements IUserData, IPluginContentProvider, IThrower
|
||||||
Friend Const UserFileAppender As String = "User"
|
Friend Const UserFileAppender As String = "User"
|
||||||
Friend Event OnUserUpdated As IUserData.OnUserUpdatedEventHandler Implements IUserData.OnUserUpdated
|
Private ReadOnly _OnUserUpdatedHandlers As List(Of IUserData.OnUserUpdatedEventHandler)
|
||||||
Protected Sub Raise_OnUserUpdated()
|
Friend Custom Event OnUserUpdated As IUserData.OnUserUpdatedEventHandler Implements IUserData.OnUserUpdated
|
||||||
|
AddHandler(ByVal e As IUserData.OnUserUpdatedEventHandler)
|
||||||
|
If Not _OnUserUpdatedHandlers.Contains(e) Then _OnUserUpdatedHandlers.Add(e)
|
||||||
|
End AddHandler
|
||||||
|
RemoveHandler(ByVal e As IUserData.OnUserUpdatedEventHandler)
|
||||||
|
If _OnUserUpdatedHandlers.Contains(e) Then _OnUserUpdatedHandlers.Remove(e)
|
||||||
|
End RemoveHandler
|
||||||
|
RaiseEvent(ByVal User As IUserData)
|
||||||
|
If _OnUserUpdatedHandlers.Count > 0 Then
|
||||||
|
For Each e As IUserData.OnUserUpdatedEventHandler In _OnUserUpdatedHandlers
|
||||||
|
Try : e.Invoke(User) : Catch : End Try
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End RaiseEvent
|
||||||
|
End Event
|
||||||
|
Protected Sub RaiseEvent_OnUserUpdated()
|
||||||
RaiseEvent OnUserUpdated(Me)
|
RaiseEvent OnUserUpdated(Me)
|
||||||
End Sub
|
End Sub
|
||||||
|
Friend Sub RemoveUpdateHandlers()
|
||||||
|
_OnUserUpdatedHandlers.Clear()
|
||||||
|
End Sub
|
||||||
#Region "Collection buttons"
|
#Region "Collection buttons"
|
||||||
|
Private _CollectionButtonsExists As Boolean = False
|
||||||
|
Private _CollectionButtonsColorsSet As Boolean = False
|
||||||
|
Friend InternalCollectionIndex As Integer = -1
|
||||||
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_DOWN As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_EDIT As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_DELETE As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_OPEN_PATH As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_OPEN_PATH As ToolStripMenuItem
|
||||||
Friend WithEvents BTT_CONTEXT_OPEN_SITE As ToolStripMenuItem
|
Friend WithEvents BTT_CONTEXT_OPEN_SITE As ToolStripMenuItem
|
||||||
Friend Sub CreateButtons(ByVal CollectionIndex As Integer)
|
Friend Sub CreateButtons(ByVal CollectionIndex As Integer)
|
||||||
|
InternalCollectionIndex = CollectionIndex
|
||||||
Dim tn$ = $"[{Site}] - {Name}"
|
Dim tn$ = $"[{Site}] - {Name}"
|
||||||
Dim _tn$ = $"{Site}{Name}"
|
Dim _tn$ = $"{Site}{Name}"
|
||||||
Dim tnn As Func(Of String, String) = Function(Input) $"{Input}{_tn}"
|
Dim tnn As Func(Of String, String) = Function(Input) $"{Input}{_tn}"
|
||||||
Dim i As Image = Nothing
|
Dim i As Image = Nothing
|
||||||
Select Case Site
|
With HOST.Source
|
||||||
Case Sites.Reddit : i = My.Resources.RedditIcon.ToBitmap
|
If Not .Icon Is Nothing Then
|
||||||
Case Sites.Twitter : i = My.Resources.TwitterIcon.ToBitmap
|
i = .Icon.ToBitmap
|
||||||
End Select
|
ElseIf Not .Image Is Nothing Then
|
||||||
|
i = .Image
|
||||||
|
End If
|
||||||
|
End With
|
||||||
BTT_CONTEXT_DOWN = New ToolStripMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = CollectionIndex}
|
BTT_CONTEXT_DOWN = New ToolStripMenuItem(tn, i) With {.Name = tnn("DOWN"), .Tag = CollectionIndex}
|
||||||
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = CollectionIndex}
|
BTT_CONTEXT_EDIT = New ToolStripMenuItem(tn, i) With {.Name = tnn("EDIT"), .Tag = CollectionIndex}
|
||||||
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = CollectionIndex}
|
BTT_CONTEXT_DELETE = New ToolStripMenuItem(tn, i) With {.Name = tnn("DELETE"), .Tag = CollectionIndex}
|
||||||
BTT_CONTEXT_OPEN_PATH = New ToolStripMenuItem(tn, i) With {.Name = tnn("PATH"), .Tag = CollectionIndex}
|
BTT_CONTEXT_OPEN_PATH = New ToolStripMenuItem(tn, i) With {.Name = tnn("PATH"), .Tag = CollectionIndex}
|
||||||
BTT_CONTEXT_OPEN_SITE = New ToolStripMenuItem(tn, i) With {.Name = tnn("SITE"), .Tag = CollectionIndex}
|
BTT_CONTEXT_OPEN_SITE = New ToolStripMenuItem(tn, i) With {.Name = tnn("SITE"), .Tag = CollectionIndex}
|
||||||
|
UpdateButtonsColor()
|
||||||
|
_CollectionButtonsExists = True
|
||||||
|
If _UserInformationLoaded Then _CollectionButtonsColorsSet = True
|
||||||
|
End Sub
|
||||||
|
Private Sub UpdateButtonsColor()
|
||||||
|
Dim cb As Color = SystemColors.Control
|
||||||
|
Dim cf As Color = SystemColors.ControlText
|
||||||
|
If Not UserExists Then
|
||||||
|
cb = ColorBttDeleteBack
|
||||||
|
cf = ColorBttDeleteFore
|
||||||
|
ElseIf UserSuspended Then
|
||||||
|
cb = ColorBttEditBack
|
||||||
|
cf = ColorBttEditFore
|
||||||
|
End If
|
||||||
|
For Each b As ToolStripMenuItem In {BTT_CONTEXT_DOWN, BTT_CONTEXT_EDIT, BTT_CONTEXT_DELETE, BTT_CONTEXT_OPEN_PATH, BTT_CONTEXT_OPEN_SITE}
|
||||||
|
If Not b Is Nothing Then b.BackColor = cb : b.ForeColor = cf
|
||||||
|
Next
|
||||||
|
If _UserInformationLoaded Then _CollectionButtonsColorsSet = True
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "XML Declarations"
|
#Region "XML Declarations"
|
||||||
@@ -80,21 +125,17 @@ Namespace API.Base
|
|||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
Friend MustOverride Property Site As Sites Implements IContentProvider.Site
|
Friend ReadOnly Property Site As String Implements IContentProvider.Site
|
||||||
Protected _Progress As MyProgress
|
|
||||||
Friend Overridable Property Progress As MyProgress
|
|
||||||
Get
|
Get
|
||||||
If _Progress Is Nothing Then Return MainProgress Else Return _Progress
|
Return HOST.Name
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal p As MyProgress)
|
|
||||||
_Progress = p
|
|
||||||
End Set
|
|
||||||
End Property
|
End Property
|
||||||
|
Friend Property Progress As MyProgress
|
||||||
Friend User As UserInfo
|
Friend User As UserInfo
|
||||||
Friend Property IsSavedPosts As Boolean
|
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
|
||||||
Friend Overridable Property UserExists As Boolean = True Implements IUserData.Exists
|
Friend Overridable Property UserExists As Boolean = True Implements IUserData.Exists, IPluginContentProvider.UserExists
|
||||||
Friend Overridable Property UserSuspended As Boolean = False Implements IUserData.Suspended
|
Friend Overridable Property UserSuspended As Boolean = False Implements IUserData.Suspended, IPluginContentProvider.UserSuspended
|
||||||
Friend Overridable Property Name As String Implements IContentProvider.Name
|
Friend Overridable Property Name As String Implements IContentProvider.Name, IPluginContentProvider.Name
|
||||||
Get
|
Get
|
||||||
Return User.Name
|
Return User.Name
|
||||||
End Get
|
End Get
|
||||||
@@ -104,10 +145,31 @@ Namespace API.Base
|
|||||||
Settings.UpdateUsersList(User)
|
Settings.UpdateUsersList(User)
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Friend Overridable Property ID As String = String.Empty Implements IContentProvider.ID
|
Friend Overridable Property ID As String = String.Empty Implements IContentProvider.ID, IPluginContentProvider.ID
|
||||||
Friend Overridable Property FriendlyName As String = String.Empty Implements IContentProvider.FriendlyName
|
Friend Overridable Property FriendlyName As String = String.Empty Implements IContentProvider.FriendlyName
|
||||||
Friend Property UserDescription As String = String.Empty Implements IContentProvider.Description
|
#Region "UserDescription"
|
||||||
Friend Property ParseUserMediaOnly As Boolean = False Implements IUserData.ParseUserMediaOnly
|
Friend Property UserDescription As String = String.Empty Implements IContentProvider.Description, IPluginContentProvider.UserDescription
|
||||||
|
Protected _DescriptionEveryTime As Boolean = False
|
||||||
|
Protected _DescriptionChecked As Boolean = False
|
||||||
|
Protected Function UserDescriptionNeedToUpdate() As Boolean
|
||||||
|
Return (UserDescription.IsEmptyString Or _DescriptionEveryTime) And Not _DescriptionChecked
|
||||||
|
End Function
|
||||||
|
Protected Sub UserDescriptionUpdate(ByVal Descr As String)
|
||||||
|
If UserDescriptionNeedToUpdate() Then
|
||||||
|
If UserDescription.IsEmptyString Then
|
||||||
|
UserDescription = Descr
|
||||||
|
ElseIf Not UserDescription.Contains(Descr) Then
|
||||||
|
UserDescription &= $"{vbNewLine}----{vbNewLine}{Descr}"
|
||||||
|
End If
|
||||||
|
_DescriptionChecked = True
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Protected Sub UserDescriptionReset()
|
||||||
|
_DescriptionChecked = False
|
||||||
|
_DescriptionEveryTime = Settings.UpdateUserDescriptionEveryTime
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
Friend Property ParseUserMediaOnly As Boolean = False Implements IUserData.ParseUserMediaOnly, IPluginContentProvider.ParseUserMediaOnly
|
||||||
Protected _Favorite As Boolean = False
|
Protected _Favorite As Boolean = False
|
||||||
Friend Overridable Property Favorite As Boolean Implements IContentProvider.Favorite
|
Friend Overridable Property Favorite As Boolean Implements IContentProvider.Favorite
|
||||||
Get
|
Get
|
||||||
@@ -178,7 +240,7 @@ BlockPictureFolder:
|
|||||||
p = New UserImage(PicList.First, l, s, MyFile)
|
p = New UserImage(PicList.First, l, s, MyFile)
|
||||||
GoTo BlockReturn
|
GoTo BlockReturn
|
||||||
Else
|
Else
|
||||||
f.Delete(SFO.Path, False, False, EDP.None)
|
f.Delete(SFO.Path, Settings.DeleteMode, EDP.None)
|
||||||
DelPath = False
|
DelPath = False
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -198,7 +260,7 @@ BlockDeletePictureFolder:
|
|||||||
On Error GoTo BlockReturn
|
On Error GoTo BlockReturn
|
||||||
If DelPath Then
|
If DelPath Then
|
||||||
f = SFile.GetPath($"{MyFile.PathWithSeparator}Pictures")
|
f = SFile.GetPath($"{MyFile.PathWithSeparator}Pictures")
|
||||||
If f.Exists(SFO.Path, False) Then f.Delete(SFO.Path, False, False)
|
If f.Exists(SFO.Path, False) Then f.Delete(SFO.Path, Settings.DeleteMode)
|
||||||
End If
|
End If
|
||||||
BlockReturn:
|
BlockReturn:
|
||||||
On Error GoTo BlockNullPicture
|
On Error GoTo BlockNullPicture
|
||||||
@@ -298,85 +360,121 @@ BlockNullPicture:
|
|||||||
End Property
|
End Property
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Information"
|
#Region "Information"
|
||||||
Protected _CountVideo As Integer = 0
|
|
||||||
Protected Property _CountPictures As Integer = 0
|
|
||||||
Friend Overridable Property LastUpdated As Date?
|
Friend Overridable Property LastUpdated As Date?
|
||||||
Friend ReadOnly Property TotalContentCount As Integer
|
|
||||||
Get
|
|
||||||
Return _CountVideo + _CountPictures
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Friend Overridable Property HasError As Boolean = False Implements IUserData.HasError
|
Friend Overridable Property HasError As Boolean = False Implements IUserData.HasError
|
||||||
Private _DownloadedPicturesTotal As Integer = 0
|
Private _DownloadedPicturesTotal As Integer = 0
|
||||||
Private _DownloadedPicturesSession As Integer = 0
|
Private _DownloadedPicturesSession As Integer = 0
|
||||||
Friend Property DownloadedPictures As Integer Implements IUserData.DownloadedPictures
|
Friend Property DownloadedPictures(ByVal Total As Boolean) As Integer Implements IUserData.DownloadedPictures
|
||||||
Get
|
Get
|
||||||
Return _DownloadedPicturesSession
|
Return IIf(Total, _DownloadedPicturesTotal, _DownloadedPicturesSession)
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal NewValue As Integer)
|
Set(ByVal NewValue As Integer)
|
||||||
|
If Total Then
|
||||||
|
_DownloadedPicturesTotal = NewValue
|
||||||
|
Else
|
||||||
_DownloadedPicturesSession = NewValue
|
_DownloadedPicturesSession = NewValue
|
||||||
|
End If
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Private _DownloadedVideosTotal As Integer = 0
|
Private _DownloadedVideosTotal As Integer = 0
|
||||||
Private _DownloadedVideosSession As Integer = 0
|
Private _DownloadedVideosSession As Integer = 0
|
||||||
Friend Property DownloadedVideos As Integer Implements IUserData.DownloadedVideos
|
Friend Property DownloadedVideos(ByVal Total As Boolean) As Integer Implements IUserData.DownloadedVideos
|
||||||
Get
|
Get
|
||||||
Return _DownloadedVideosSession
|
Return IIf(Total, _DownloadedVideosTotal, _DownloadedVideosSession)
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal NewValue As Integer)
|
Set(ByVal NewValue As Integer)
|
||||||
|
If Total Then
|
||||||
|
_DownloadedVideosTotal = NewValue
|
||||||
|
Else
|
||||||
_DownloadedVideosSession = NewValue
|
_DownloadedVideosSession = NewValue
|
||||||
|
End If
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Friend Overridable ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer Implements IUserData.DownloadedTotal
|
Friend Overridable ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer Implements IUserData.DownloadedTotal
|
||||||
Get
|
Get
|
||||||
If Total Then
|
Return DownloadedPictures(Total) + DownloadedVideos(Total)
|
||||||
Return _DownloadedPicturesTotal + _DownloadedVideosTotal
|
|
||||||
Else
|
|
||||||
Return _DownloadedPicturesSession + _DownloadedVideosSession
|
|
||||||
End If
|
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Friend ReadOnly Property DownloadedInformation As String Implements IUserData.DownloadedInformation
|
Friend ReadOnly Property DownloadedInformation As String Implements IUserData.DownloadedInformation
|
||||||
Get
|
Get
|
||||||
Dim luv$ = String.Empty
|
Dim luv$ = String.Empty
|
||||||
If LastUpdated.HasValue Then luv = $"{LastUpdated.Value.ToStringDate(ADateTime.Formats.BaseDateTime)}: "
|
If LastUpdated.HasValue Then luv = $"{LastUpdated.Value.ToStringDate(ADateTime.Formats.BaseDateTime)}: "
|
||||||
Return $"{luv}{Name} [{Site}]{IIf(HasError, " (with errors)", String.Empty)}: P - {_DownloadedPicturesTotal}; V - {_DownloadedVideosTotal}" &
|
Return $"{luv}{Name} [{Site}]{IIf(HasError, " (with errors)", String.Empty)}: P - {DownloadedPictures(False)}; V - {DownloadedVideos(False)}" &
|
||||||
$" (P - {_CountPictures}; V - {_CountVideo})"
|
$" (P - {DownloadedPictures(True)}; V - {DownloadedVideos(True)})"
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
|
#Region "Plugins Support"
|
||||||
|
Protected Event ProgressChanged As IPluginContentProvider.ProgressChangedEventHandler Implements IPluginContentProvider.ProgressChanged
|
||||||
|
Protected Event TotalCountChanged As IPluginContentProvider.TotalCountChangedEventHandler Implements IPluginContentProvider.TotalCountChanged
|
||||||
|
Friend Property HOST As SettingsHost Implements IUserData.HOST
|
||||||
|
Private Property IPluginContentProvider_Settings As ISiteSettings Implements IPluginContentProvider.Settings
|
||||||
|
Get
|
||||||
|
Return HOST.Source
|
||||||
|
End Get
|
||||||
|
Set(ByVal s As ISiteSettings)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private Property IPluginContentProvider_Thrower As IThrower Implements IPluginContentProvider.Thrower
|
||||||
|
Private Property IPluginContentProvider_LogProvider As ILogProvider Implements IPluginContentProvider.LogProvider
|
||||||
|
Friend Property ExternalPlugin As IPluginContentProvider
|
||||||
|
Private Property IPluginContentProvider_ExistingContentList As List(Of PluginUserMedia) Implements IPluginContentProvider.ExistingContentList
|
||||||
|
Private Property IPluginContentProvider_TempPostsList As List(Of String) Implements IPluginContentProvider.TempPostsList
|
||||||
|
Private Property IPluginContentProvider_TempMediaList As List(Of IPluginUserMedia) Implements IPluginContentProvider.TempMediaList
|
||||||
|
Private Property IPluginContentProvider_SeparateVideoFolder As Boolean Implements IPluginContentProvider.SeparateVideoFolder
|
||||||
|
Private Property IPluginContentProvider_DataPath As String Implements IPluginContentProvider.DataPath
|
||||||
|
Private Sub IPluginContentProvider_XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String))) Implements IPluginContentProvider.XmlFieldsSet
|
||||||
|
End Sub
|
||||||
|
Private Function IPluginContentProvider_XmlFieldsGet() As List(Of KeyValuePair(Of String, String)) Implements IPluginContentProvider.XmlFieldsGet
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Private Sub IPluginContentProvider_GetMedia() Implements IPluginContentProvider.GetMedia
|
||||||
|
End Sub
|
||||||
|
Private Sub IPluginContentProvider_Download() Implements IPluginContentProvider.Download
|
||||||
|
End Sub
|
||||||
|
Friend Overridable Function ExchangeOptionsGet() As Object Implements IPluginContentProvider.ExchangeOptionsGet
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Friend Overridable Sub ExchangeOptionsSet(ByVal Obj As Object) Implements IPluginContentProvider.ExchangeOptionsSet
|
||||||
|
End Sub
|
||||||
|
Private _ExternalCompatibilityToken As CancellationToken
|
||||||
|
#End Region
|
||||||
|
#Region "IIndexable Support"
|
||||||
|
Friend Property Index As Integer = 0 Implements IIndexable.Index
|
||||||
|
Private Function SetIndex(ByVal Obj As Object, ByVal _Index As Integer) As Object Implements IIndexable.SetIndex
|
||||||
|
DirectCast(Obj, UserDataBase).Index = _Index
|
||||||
|
Return Obj
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
#Region "LVI"
|
#Region "LVI"
|
||||||
Friend ReadOnly Property LVIKey As String Implements IUserData.LVIKey
|
Friend ReadOnly Property LVIKey As String Implements IUserData.Key
|
||||||
Get
|
Get
|
||||||
If Not _IsCollection Then
|
If Not _IsCollection Then
|
||||||
Return $"{Site.ToString.ToUpper}_{Name}"
|
Return $"{IIf(IsChannel, "C", String.Empty)}{Site.ToString.ToUpper}_{Name}"
|
||||||
Else
|
Else
|
||||||
Return $"CCCC_{CollectionName}"
|
Return $"CCCC_{CollectionName}"
|
||||||
End If
|
End If
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Private _LVIIndex As Integer = -1
|
|
||||||
Private ReadOnly Property LVIIndex As Integer Implements IUserData.LVIIndex
|
|
||||||
Get
|
|
||||||
Return _LVIIndex
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Friend Function GetLVI(ByVal Destination As ListView) As ListViewItem Implements IUserData.GetLVI
|
Friend Function GetLVI(ByVal Destination As ListView) As ListViewItem Implements IUserData.GetLVI
|
||||||
_LVIIndex = Destination.Items.Count
|
|
||||||
If Settings.ViewModeIsPicture Then
|
If Settings.ViewModeIsPicture Then
|
||||||
Return New ListViewItem(ToString(), LVIKey, GetLVIGroup(Destination)) With {.Name = LVIKey, .Tag = LVIKey}
|
Return ListImagesLoader.ApplyLVIColor(Me, New ListViewItem(ToString(), LVIKey, GetLVIGroup(Destination)) With {.Name = LVIKey, .Tag = LVIKey}, True)
|
||||||
Else
|
Else
|
||||||
Return New ListViewItem(ToString(), GetLVIGroup(Destination)) With {.Name = LVIKey, .Tag = LVIKey}
|
Return ListImagesLoader.ApplyLVIColor(Me, New ListViewItem(ToString(), GetLVIGroup(Destination)) With {.Name = LVIKey, .Tag = LVIKey}, True)
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Friend Overridable ReadOnly Property FitToAddParams As Boolean Implements IUserData.FitToAddParams
|
Friend Overridable ReadOnly Property FitToAddParams As Boolean Implements IUserData.FitToAddParams
|
||||||
Get
|
Get
|
||||||
|
If Settings.LastUpdatedDate.HasValue AndAlso LastUpdated.HasValue AndAlso
|
||||||
|
LastUpdated.Value.Date > Settings.LastUpdatedDate.Value.Date Then Return False
|
||||||
If Settings.SelectedSites.Count = 0 OrElse Settings.SelectedSites.Contains(Site) Then
|
If Settings.SelectedSites.Count = 0 OrElse Settings.SelectedSites.Contains(Site) Then
|
||||||
Select Case Settings.ShowingMode.Value
|
Select Case Settings.ShowingMode.Value
|
||||||
Case ShowingModes.Regular : Return Not Temporary And Not Favorite
|
Case ShowingModes.Regular : Return Not Temporary And Not Favorite
|
||||||
Case ShowingModes.Temporary : Return Temporary
|
Case ShowingModes.Temporary : Return Temporary
|
||||||
Case ShowingModes.Favorite : Return Favorite
|
Case ShowingModes.Favorite : Return Favorite
|
||||||
|
Case ShowingModes.Deleted : Return Not UserExists
|
||||||
|
Case ShowingModes.Suspended : Return UserSuspended
|
||||||
Case ShowingModes.Labels : Return Settings.Labels.CurrentSelection.ListContains(Labels)
|
Case ShowingModes.Labels : Return Settings.Labels.CurrentSelection.ListContains(Labels)
|
||||||
Case ShowingModes.NoLabels : Return Labels.Count = 0
|
Case ShowingModes.NoLabels : Return Labels.Count = 0
|
||||||
Case Else : Return True
|
Case Else : Return True
|
||||||
@@ -393,12 +491,10 @@ BlockNullPicture:
|
|||||||
For i% = 0 To Labels.Count - 1
|
For i% = 0 To Labels.Count - 1
|
||||||
If Settings.Labels.CurrentSelection.Contains(Labels(i)) Then Return Destination.Groups.Item(Labels(i))
|
If Settings.Labels.CurrentSelection.Contains(Labels(i)) Then Return Destination.Groups.Item(Labels(i))
|
||||||
Next
|
Next
|
||||||
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
|
|
||||||
Else
|
|
||||||
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
|
|
||||||
End If
|
End If
|
||||||
|
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
|
||||||
Else
|
Else
|
||||||
Return Destination.Groups.Item(GetLviGroupName(Site, Temporary, Favorite, IsCollection, IsChannel))
|
Return Destination.Groups.Item(GetLviGroupName(HOST, Temporary, Favorite, IsCollection, IsChannel))
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
|
Return Destination.Groups.Item(LabelsKeeper.NoLabeledName)
|
||||||
@@ -407,9 +503,9 @@ BlockNullPicture:
|
|||||||
Friend Overridable Function GetUserInformation() As String
|
Friend Overridable Function GetUserInformation() As String
|
||||||
Dim OutStr$ = $"User: {Name}"
|
Dim OutStr$ = $"User: {Name}"
|
||||||
OutStr.StringAppendLine($"Path: {MyFile.CutPath.Path}")
|
OutStr.StringAppendLine($"Path: {MyFile.CutPath.Path}")
|
||||||
OutStr.StringAppendLine($"Total downloaded ({TotalContentCount.NumToString(ANumbers.Formats.Number, 3)}):")
|
OutStr.StringAppendLine($"Total downloaded ({DownloadedTotal(True).NumToString(ANumbers.Formats.Number, 3)}):")
|
||||||
OutStr.StringAppendLine($"Pictures: {_CountPictures.NumToString(ANumbers.Formats.Number, 3)}")
|
OutStr.StringAppendLine($"Pictures: {DownloadedPictures(True).NumToString(ANumbers.Formats.Number, 3)}")
|
||||||
OutStr.StringAppendLine($"Videos: {_CountVideo.NumToString(ANumbers.Formats.Number, 3)}")
|
OutStr.StringAppendLine($"Videos: {DownloadedVideos(True).NumToString(ANumbers.Formats.Number, 3)}")
|
||||||
If Not UserDescription.IsEmptyString Then
|
If Not UserDescription.IsEmptyString Then
|
||||||
OutStr.StringAppendLine(String.Empty)
|
OutStr.StringAppendLine(String.Empty)
|
||||||
OutStr.StringAppendLine(UserDescription)
|
OutStr.StringAppendLine(UserDescription)
|
||||||
@@ -418,8 +514,8 @@ BlockNullPicture:
|
|||||||
OutStr.StringAppendLine($"Last updated at: {AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, "not yet")}")
|
OutStr.StringAppendLine($"Last updated at: {AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, "not yet")}")
|
||||||
If _DataParsed Then
|
If _DataParsed Then
|
||||||
OutStr.StringAppendLine("Downloaded now:")
|
OutStr.StringAppendLine("Downloaded now:")
|
||||||
OutStr.StringAppendLine($"Pictures: {_CountPictures.NumToString(ANumbers.Formats.Number, 3)}")
|
OutStr.StringAppendLine($"Pictures: {DownloadedTotal(False).NumToString(ANumbers.Formats.Number, 3)}")
|
||||||
OutStr.StringAppendLine($"Videos: {_CountVideo.NumToString(ANumbers.Formats.Number, 3)}")
|
OutStr.StringAppendLine($"Videos: {DownloadedVideos(False).NumToString(ANumbers.Formats.Number, 3)}")
|
||||||
End If
|
End If
|
||||||
Return OutStr
|
Return OutStr
|
||||||
End Function
|
End Function
|
||||||
@@ -434,33 +530,34 @@ BlockNullPicture:
|
|||||||
_TempMediaList = New List(Of UserMedia)
|
_TempMediaList = New List(Of UserMedia)
|
||||||
_TempPostsList = New List(Of String)
|
_TempPostsList = New List(Of String)
|
||||||
Labels = New List(Of String)
|
Labels = New List(Of String)
|
||||||
|
_OnUserUpdatedHandlers = New List(Of IUserData.OnUserUpdatedEventHandler)
|
||||||
If InvokeImageHandler Then ImageHandler(Me)
|
If InvokeImageHandler Then ImageHandler(Me)
|
||||||
End Sub
|
End Sub
|
||||||
|
Friend Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
|
||||||
|
Optional ByVal AttachUserInfo As Boolean = True) Implements IUserData.SetEnvironment
|
||||||
|
HOST = h
|
||||||
|
If AttachUserInfo Then
|
||||||
|
User = u
|
||||||
|
If _LoadUserInformation Then LoadUserInformation()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
''' <exception cref="ArgumentOutOfRangeException"></exception>
|
''' <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
Friend Overloads Shared Function GetInstance(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True) As IUserData
|
Friend Overloads Shared Function GetInstance(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True) As IUserData
|
||||||
Select Case u.Site
|
If Not u.Plugin.IsEmptyString Then
|
||||||
Case Sites.Reddit
|
Return Settings(u.Plugin).GetInstance(u.DownloadOption, u, _LoadUserInformation)
|
||||||
If u.IsChannel Then
|
|
||||||
Return New Reddit.Channel(u, _LoadUserInformation)
|
|
||||||
Else
|
Else
|
||||||
Return New Reddit.UserData(u, _LoadUserInformation)
|
Throw New ArgumentOutOfRangeException("Plugin", $"Plugin [{u.Plugin}] information does not recognized by loader")
|
||||||
End If
|
End If
|
||||||
Case Sites.Twitter : Return New Twitter.UserData(u, _LoadUserInformation)
|
|
||||||
Case Sites.Instagram : Return New Instagram.UserData(u, _LoadUserInformation)
|
|
||||||
Case Sites.RedGifs : Return New RedGifs.UserData(u, _LoadUserInformation)
|
|
||||||
Case Else : Throw New ArgumentOutOfRangeException("Site", $"Site [{u.Site}] information does not recognized by loader")
|
|
||||||
End Select
|
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Information & Content data files loader and saver"
|
#Region "Information & Content data files loader and saver"
|
||||||
#Region "User information"
|
#Region "User information"
|
||||||
|
Private _UserInformationLoaded As Boolean = False
|
||||||
Friend Overridable Sub LoadUserInformation() Implements IUserData.LoadUserInformation
|
Friend Overridable Sub LoadUserInformation() Implements IUserData.LoadUserInformation
|
||||||
Try
|
Try
|
||||||
If MyFile.Exists Then
|
If MyFile.Exists Then
|
||||||
FileExists = True
|
FileExists = True
|
||||||
Using x As New XmlFile(MyFile) With {.XmlReadOnly = True}
|
Using x As New XmlFile(MyFile) With {.XmlReadOnly = True}
|
||||||
User.Site = Site
|
|
||||||
Site = x.Value(Name_Site).FromXML(Of Integer)(0)
|
|
||||||
User.Name = x.Value(Name_UserName)
|
User.Name = x.Value(Name_UserName)
|
||||||
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
|
UserExists = x.Value(Name_UserExists).FromXML(Of Boolean)(True)
|
||||||
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
|
UserSuspended = x.Value(Name_UserSuspended).FromXML(Of Boolean)(False)
|
||||||
@@ -475,8 +572,8 @@ BlockNullPicture:
|
|||||||
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
||||||
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
||||||
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
||||||
_CountVideo = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
||||||
_CountPictures = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
||||||
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
||||||
DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False)
|
DataMerging = x.Value(Name_DataMerging).FromXML(Of Boolean)(False)
|
||||||
ChangeCollectionName(x.Value(Name_CollectionName), False)
|
ChangeCollectionName(x.Value(Name_CollectionName), False)
|
||||||
@@ -484,6 +581,8 @@ BlockNullPicture:
|
|||||||
LoadUserInformation_OptionalFields(x, True)
|
LoadUserInformation_OptionalFields(x, True)
|
||||||
End Using
|
End Using
|
||||||
UpdateDataFiles()
|
UpdateDataFiles()
|
||||||
|
_UserInformationLoaded = True
|
||||||
|
If _CollectionButtonsExists And Not _CollectionButtonsColorsSet And (Not UserExists Or UserSuspended) Then UpdateButtonsColor()
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LogError(ex, "user information loading error")
|
LogError(ex, "user information loading error")
|
||||||
@@ -493,7 +592,7 @@ BlockNullPicture:
|
|||||||
Try
|
Try
|
||||||
MyFile.Exists(SFO.Path)
|
MyFile.Exists(SFO.Path)
|
||||||
Using x As New XmlFile With {.Name = "User"}
|
Using x As New XmlFile With {.Name = "User"}
|
||||||
x.Add(Name_Site, CInt(Site))
|
x.Add(Name_Site, Site)
|
||||||
x.Add(Name_UserName, User.Name)
|
x.Add(Name_UserName, User.Name)
|
||||||
x.Add(Name_UserExists, UserExists.BoolToInteger)
|
x.Add(Name_UserExists, UserExists.BoolToInteger)
|
||||||
x.Add(Name_UserSuspended, UserSuspended.BoolToInteger)
|
x.Add(Name_UserSuspended, UserSuspended.BoolToInteger)
|
||||||
@@ -512,8 +611,8 @@ BlockNullPicture:
|
|||||||
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
||||||
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
||||||
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
||||||
x.Add(Name_VideoCount, _CountVideo)
|
x.Add(Name_VideoCount, DownloadedVideos(True))
|
||||||
x.Add(Name_PicturesCount, _CountPictures)
|
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
||||||
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
||||||
x.Add(Name_CollectionName, CollectionName)
|
x.Add(Name_CollectionName, CollectionName)
|
||||||
x.Add(Name_LabelsName, Labels.ListToString(, "|", EDP.ReturnValue))
|
x.Add(Name_LabelsName, Labels.ListToString(, "|", EDP.ReturnValue))
|
||||||
@@ -597,42 +696,43 @@ BlockNullPicture:
|
|||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Open site, folder"
|
#Region "Open site, folder"
|
||||||
Friend Overridable Sub OpenSite() Implements IContentProvider.OpenSite
|
Friend Overridable Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing) Implements IContentProvider.OpenSite
|
||||||
Try
|
Try
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = HOST.Source.GetUserUrl(Name, IsChannel)
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit : URL = $"https://www.reddit.com/{IIf(IsChannel, "r", "user")}/{Name}/"
|
|
||||||
Case Sites.Twitter : URL = $"https://twitter.com/{Name}"
|
|
||||||
Case Sites.Instagram : URL = $"https://www.instagram.com/{Name}/"
|
|
||||||
Case Sites.RedGifs : URL = $"https://www.redgifs.com/users/{Name}/"
|
|
||||||
Case Else : MsgBoxE($"Site [{Site}] opening not implemented", MsgBoxStyle.Exclamation)
|
|
||||||
End Select
|
|
||||||
If Not URL.IsEmptyString Then Process.Start(URL)
|
If Not URL.IsEmptyString Then Process.Start(URL)
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
MsgBoxE($"Error on trying to open [{Site}] page of user [{Name}]", MsgBoxStyle.Critical)
|
If Not e.Exists Then e = New ErrorsDescriber(EDP.ShowAllMsg)
|
||||||
|
MsgBoxE($"Error on trying to open [{Site}] page of user [{Name}]", MsgBoxStyle.Critical, e)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overridable Sub OpenFolder() Implements IUserData.OpenFolder
|
Friend Overridable Sub OpenFolder() Implements IUserData.OpenFolder
|
||||||
MyFile.CutPath.Open(SFO.Path, EDP.None)
|
GlobalOpenPath(MyFile.CutPath)
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Download functions and options"
|
#Region "Download functions and options"
|
||||||
Friend Overridable Property DownloadTopCount As Integer? = Nothing Implements IUserData.DownloadTopCount
|
Friend Overridable Property DownloadTopCount As Integer? = Nothing Implements IUserData.DownloadTopCount, IPluginContentProvider.PostsNumberLimit
|
||||||
Protected Responser As PersonalUtilities.Tools.WEB.Response
|
Protected Responser As PersonalUtilities.Tools.WEB.Response
|
||||||
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
|
Friend Overridable Sub DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
|
||||||
Dim Canceled As Boolean = False
|
Dim Canceled As Boolean = False
|
||||||
|
_ExternalCompatibilityToken = Token
|
||||||
Try
|
Try
|
||||||
UpdateDataFiles()
|
UpdateDataFiles()
|
||||||
|
UserDescriptionReset()
|
||||||
If Not Responser Is Nothing Then Responser.Dispose()
|
If Not Responser Is Nothing Then Responser.Dispose()
|
||||||
Responser = New PersonalUtilities.Tools.WEB.Response
|
Responser = New PersonalUtilities.Tools.WEB.Response
|
||||||
Responser.Copy(Settings(Site).Responser)
|
If TypeOf HOST.Source Is IResponserContainer Then
|
||||||
|
With DirectCast(HOST.Source, IResponserContainer)
|
||||||
|
If Not .Responser Is Nothing Then Responser.Copy(.Responser)
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
|
||||||
Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(False) Is Nothing
|
Dim UpPic As Boolean = Settings.ViewModeIsPicture AndAlso GetPicture(False) Is Nothing
|
||||||
Dim sEnvir() As Boolean = {UserExists, UserSuspended}
|
Dim sEnvir() As Boolean = {UserExists, UserSuspended}
|
||||||
Dim EnvirChanged As Func(Of Boolean) = Function() Not sEnvir(0) = UserExists Or Not sEnvir(1) = UserSuspended
|
Dim EnvirChanged As Func(Of Boolean) = Function() Not sEnvir(0) = UserExists Or Not sEnvir(1) = UserSuspended
|
||||||
UserExists = True
|
UserExists = True
|
||||||
UserSuspended = False
|
UserSuspended = False
|
||||||
_DownloadedPicturesSession = 0
|
DownloadedPictures(False) = 0
|
||||||
_DownloadedVideosSession = 0
|
DownloadedVideos(False) = 0
|
||||||
_TempMediaList.Clear()
|
_TempMediaList.Clear()
|
||||||
_TempPostsList.Clear()
|
_TempPostsList.Clear()
|
||||||
Dim __SaveData As Boolean = Not CreatedByChannel Or Not Settings.FromChannelDownloadTopUse
|
Dim __SaveData As Boolean = Not CreatedByChannel Or Not Settings.FromChannelDownloadTopUse
|
||||||
@@ -641,6 +741,7 @@ BlockNullPicture:
|
|||||||
|
|
||||||
If MyFilePosts.Exists Then _TempPostsList.ListAddList(File.ReadAllLines(MyFilePosts))
|
If MyFilePosts.Exists Then _TempPostsList.ListAddList(File.ReadAllLines(MyFilePosts))
|
||||||
If _ContentList.Count > 0 Then _TempPostsList.ListAddList(_ContentList.Select(Function(u) u.Post.ID), LNC)
|
If _ContentList.Count > 0 Then _TempPostsList.ListAddList(_ContentList.Select(Function(u) u.Post.ID), LNC)
|
||||||
|
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
DownloadDataF(Token)
|
DownloadDataF(Token)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
@@ -658,28 +759,25 @@ BlockNullPicture:
|
|||||||
DownloadContent(Token)
|
DownloadContent(Token)
|
||||||
ThrowIfDisposed()
|
ThrowIfDisposed()
|
||||||
_ContentList.ListAddList(_ContentNew.Where(Function(c) c.State = UStates.Downloaded), LNC)
|
_ContentList.ListAddList(_ContentNew.Where(Function(c) c.State = UStates.Downloaded), LNC)
|
||||||
_CountPictures = _ContentList.LongCount(Function(c) c.Type = UTypes.Picture)
|
If DownloadedTotal(False) > 0 Or EnvirChanged.Invoke Then
|
||||||
_CountVideo = _ContentList.LongCount(Function(c) c.Type = UTypes.Video)
|
|
||||||
If DownloadedPictures + DownloadedVideos > 0 Or EnvirChanged.Invoke Then
|
|
||||||
If __SaveData Then
|
If __SaveData Then
|
||||||
LastUpdated = Now
|
LastUpdated = Now
|
||||||
|
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
|
||||||
If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser)
|
If Labels.Contains(LabelsKeeper.NoParsedUser) Then Labels.Remove(LabelsKeeper.NoParsedUser)
|
||||||
UpdateContentInformation()
|
UpdateContentInformation()
|
||||||
Else
|
Else
|
||||||
_CountVideo = 0
|
DownloadedVideos(False) = 0
|
||||||
_CountPictures = 0
|
DownloadedPictures(False) = 0
|
||||||
_ContentList.Clear()
|
_ContentList.Clear()
|
||||||
CreatedByChannel = False
|
CreatedByChannel = False
|
||||||
End If
|
End If
|
||||||
If Not UserExists Then ReadyForDownload = False
|
If Not UserExists Then ReadyForDownload = False
|
||||||
UpdateUserInformation()
|
UpdateUserInformation()
|
||||||
|
If _CollectionButtonsExists AndAlso EnvirChanged.Invoke Then UpdateButtonsColor()
|
||||||
End If
|
End If
|
||||||
ThrowIfDisposed()
|
ThrowIfDisposed()
|
||||||
If Not CreatedByChannel Then
|
If UpPic Or EnvirChanged.Invoke Then RaiseEvent_OnUserUpdated()
|
||||||
_DownloadedPicturesTotal += _DownloadedPicturesSession
|
|
||||||
_DownloadedVideosTotal += _DownloadedVideosSession
|
|
||||||
End If
|
|
||||||
If UpPic Or EnvirChanged.Invoke Then Raise_OnUserUpdated()
|
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
MyMainLOG = $"{Site} - {Name}: downloading canceled"
|
MyMainLOG = $"{Site} - {Name}: downloading canceled"
|
||||||
Canceled = True
|
Canceled = True
|
||||||
@@ -752,17 +850,22 @@ BlockNullPicture:
|
|||||||
End Select
|
End Select
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If __isVideo And vsf Then f.Path = $"{f.PathWithSeparator}Video"
|
If Not v.SpecialFolder.IsEmptyString Then
|
||||||
|
f.Path = $"{f.PathWithSeparator}{v.SpecialFolder}\".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)
|
||||||
|
End If
|
||||||
w.DownloadFile(v.URL_BASE, f.ToString)
|
w.DownloadFile(v.URL_BASE, f.ToString)
|
||||||
|
|
||||||
If __isVideo Then
|
If __isVideo Then
|
||||||
v.Type = UTypes.Video
|
v.Type = UTypes.Video
|
||||||
DownloadedVideos += 1
|
DownloadedVideos(False) += 1
|
||||||
_CountVideo += 1
|
|
||||||
Else
|
Else
|
||||||
v.Type = UTypes.Picture
|
v.Type = UTypes.Picture
|
||||||
DownloadedPictures += 1
|
DownloadedPictures(False) += 1
|
||||||
_CountPictures += 1
|
|
||||||
End If
|
End If
|
||||||
|
|
||||||
v.File = ChangeFileNameByProvider(f, v)
|
v.File = ChangeFileNameByProvider(f, v)
|
||||||
@@ -832,7 +935,7 @@ BlockNullPicture:
|
|||||||
End Function
|
End Function
|
||||||
Friend Function DeleteF(ByVal Instance As IUserData) As Integer
|
Friend Function DeleteF(ByVal Instance As IUserData) As Integer
|
||||||
Dim f As SFile = SFile.GetPath(MyFile.CutPath.Path)
|
Dim f As SFile = SFile.GetPath(MyFile.CutPath.Path)
|
||||||
If f.Exists(SFO.Path, False) AndAlso (User.Merged OrElse f.Delete(SFO.Path, False, False)) Then
|
If f.Exists(SFO.Path, False) AndAlso (User.Merged OrElse f.Delete(SFO.Path, Settings.DeleteMode)) Then
|
||||||
ImageHandler(Me, False)
|
ImageHandler(Me, False)
|
||||||
Settings.UsersList.Remove(User)
|
Settings.UsersList.Remove(User)
|
||||||
Settings.UpdateUsersList()
|
Settings.UpdateUsersList()
|
||||||
@@ -878,7 +981,7 @@ BlockNullPicture:
|
|||||||
_TurnBack = False
|
_TurnBack = False
|
||||||
Return False
|
Return False
|
||||||
End If
|
End If
|
||||||
f.Delete(SFO.Path, False, False, EDP.ThrowException)
|
f.Delete(SFO.Path, Settings.DeleteMode, EDP.ThrowException)
|
||||||
End If
|
End If
|
||||||
f.CutPath.Exists(SFO.Path)
|
f.CutPath.Exists(SFO.Path)
|
||||||
Directory.Move(UserBefore.File.CutPath(, EDP.ThrowException).Path, f.Path)
|
Directory.Move(UserBefore.File.CutPath(, EDP.ThrowException).Path, f.Path)
|
||||||
@@ -933,7 +1036,7 @@ BlockNullPicture:
|
|||||||
FilesMover.Invoke
|
FilesMover.Invoke
|
||||||
If SFile.GetFiles(UserBefore.File.CutPath,, SearchOption.AllDirectories,
|
If SFile.GetFiles(UserBefore.File.CutPath,, SearchOption.AllDirectories,
|
||||||
New ErrorsDescriber(False, False, False, New List(Of SFile))).Count = 0 Then
|
New ErrorsDescriber(False, False, False, New List(Of SFile))).Count = 0 Then
|
||||||
UserBefore.File.CutPath.Delete(SFO.Path, False, False, EDP.SendInLog)
|
UserBefore.File.CutPath.Delete(SFO.Path, Settings.DeleteMode, EDP.SendInLog)
|
||||||
End If
|
End If
|
||||||
UpdateUserInformation()
|
UpdateUserInformation()
|
||||||
End If
|
End If
|
||||||
@@ -963,33 +1066,42 @@ BlockNullPicture:
|
|||||||
Protected Sub ThrowIfDisposed()
|
Protected Sub ThrowIfDisposed()
|
||||||
If Disposed Then Throw New ObjectDisposedException(ToString(), "Object disposed")
|
If Disposed Then Throw New ObjectDisposedException(ToString(), "Object disposed")
|
||||||
End Sub
|
End Sub
|
||||||
|
''' <inheritdoc cref="ThrowAny(CancellationToken)"/>
|
||||||
|
Private Overloads Sub ThrowAny() Implements IThrower.ThrowAny
|
||||||
|
ThrowAny(_ExternalCompatibilityToken)
|
||||||
|
End Sub
|
||||||
''' <exception cref="OperationCanceledException"></exception>
|
''' <exception cref="OperationCanceledException"></exception>
|
||||||
''' <exception cref="ObjectDisposedException"></exception>
|
''' <exception cref="ObjectDisposedException"></exception>
|
||||||
Protected Sub ThrowAny(ByVal Token As CancellationToken)
|
Friend Overloads Sub ThrowAny(ByVal Token As CancellationToken)
|
||||||
Token.ThrowIfCancellationRequested()
|
Token.ThrowIfCancellationRequested()
|
||||||
ThrowIfDisposed()
|
ThrowIfDisposed()
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
Public Overrides Function ToString() As String
|
Public Overrides Function ToString() As String
|
||||||
If Settings.ViewModeIsPicture Then
|
|
||||||
If IsCollection Then
|
If IsCollection Then
|
||||||
Return CollectionName
|
Return CollectionName
|
||||||
Else
|
Else
|
||||||
Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName)
|
Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName)
|
||||||
End If
|
End If
|
||||||
Else
|
'If Settings.ViewModeIsPicture Then
|
||||||
Dim t$ = String.Empty
|
' If IsCollection Then
|
||||||
If Temporary Then
|
' Return CollectionName
|
||||||
t = " (T)"
|
' Else
|
||||||
ElseIf Favorite Then
|
' Return IIf(FriendlyName.IsEmptyString, Name, FriendlyName)
|
||||||
t = " (F)"
|
' End If
|
||||||
End If
|
'Else
|
||||||
If IsCollection Then
|
' Dim t$ = String.Empty
|
||||||
Return $"Collection [{CollectionName}]{t}"
|
' If Temporary Then
|
||||||
Else
|
' t = " (T)"
|
||||||
Return $"[{Site}]{t} {IIf(FriendlyName.IsEmptyString, Name, FriendlyName)}"
|
' ElseIf Favorite Then
|
||||||
End If
|
' t = " (F)"
|
||||||
End If
|
' End If
|
||||||
|
' If IsCollection Then
|
||||||
|
' Return $"Collection [{CollectionName}]{t}"
|
||||||
|
' Else
|
||||||
|
' Return $"[{Site}]{t} {IIf(FriendlyName.IsEmptyString, Name, FriendlyName)}"
|
||||||
|
' End If
|
||||||
|
'End If
|
||||||
End Function
|
End Function
|
||||||
#Region "Buttons actions"
|
#Region "Buttons actions"
|
||||||
Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click
|
Private Sub BTT_CONTEXT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_DOWN.Click
|
||||||
@@ -1012,38 +1124,25 @@ BlockNullPicture:
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "IComparable Support"
|
#Region "IComparable Support"
|
||||||
Friend Overridable Function CompareTo(ByVal Other As UserDataBase) As Integer Implements IComparable(Of UserDataBase).CompareTo
|
Friend Overridable Function CompareTo(ByVal Other As UserDataBase) As Integer Implements IComparable(Of UserDataBase).CompareTo
|
||||||
Dim x% = CompareValue(Me)
|
|
||||||
Dim y% = CompareValue(Other)
|
|
||||||
If x.CompareTo(y) = 0 Then
|
|
||||||
Return Name.CompareTo(Other.Name)
|
Return Name.CompareTo(Other.Name)
|
||||||
Else
|
|
||||||
Return x.CompareTo(y)
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
Protected Function CompareValue(ByVal x As UserDataBase) As Integer
|
|
||||||
Dim OutValue% = CInt(x.Site) * 10000
|
|
||||||
If x.IsCollection Then OutValue -= 1000
|
|
||||||
If x.Temporary Then OutValue += 2000
|
|
||||||
If x.Favorite Then OutValue -= 500
|
|
||||||
Return OutValue
|
|
||||||
End Function
|
End Function
|
||||||
Friend Overridable Function CompareTo(ByVal Obj As Object) As Integer Implements IComparable.CompareTo
|
Friend Overridable Function CompareTo(ByVal Obj As Object) As Integer Implements IComparable.CompareTo
|
||||||
If TypeOf Obj Is Reddit.Channel Then
|
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserDataBase Then
|
||||||
Return CompareTo(DirectCast(DirectCast(Obj, Reddit.Channel).Instance, UserDataBase))
|
|
||||||
Else
|
|
||||||
Return CompareTo(DirectCast(Obj, UserDataBase))
|
Return CompareTo(DirectCast(Obj, UserDataBase))
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "IEquatable Support"
|
#Region "IEquatable Support"
|
||||||
Friend Overridable Overloads Function Equals(ByVal Other As UserDataBase) As Boolean Implements IEquatable(Of UserDataBase).Equals
|
Friend Overridable Overloads Function Equals(ByVal Other As UserDataBase) As Boolean Implements IEquatable(Of UserDataBase).Equals
|
||||||
Return Site = Other.Site And Name = Other.Name And IsSavedPosts = Other.IsSavedPosts
|
Return LVIKey = Other.LVIKey And IsSavedPosts = Other.IsSavedPosts
|
||||||
End Function
|
End Function
|
||||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||||
If TypeOf Obj Is Reddit.Channel Then
|
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserDataBase Then
|
||||||
Return Equals(DirectCast(DirectCast(Obj, Reddit.Channel).Instance, UserDataBase))
|
|
||||||
Else
|
|
||||||
Return Equals(DirectCast(Obj, UserDataBase))
|
Return Equals(DirectCast(Obj, UserDataBase))
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
@@ -1067,7 +1166,7 @@ BlockNullPicture:
|
|||||||
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
|
If Not BTT_CONTEXT_DELETE Is Nothing Then BTT_CONTEXT_DELETE.Dispose()
|
||||||
If Not BTT_CONTEXT_OPEN_PATH Is Nothing Then BTT_CONTEXT_OPEN_PATH.Dispose()
|
If Not BTT_CONTEXT_OPEN_PATH Is Nothing Then BTT_CONTEXT_OPEN_PATH.Dispose()
|
||||||
If Not BTT_CONTEXT_OPEN_SITE Is Nothing Then BTT_CONTEXT_OPEN_SITE.Dispose()
|
If Not BTT_CONTEXT_OPEN_SITE Is Nothing Then BTT_CONTEXT_OPEN_SITE.Dispose()
|
||||||
If _InvokeImageHandler Then ImageHandler(Me, False)
|
_OnUserUpdatedHandlers.Clear()
|
||||||
End If
|
End If
|
||||||
disposedValue = True
|
disposedValue = True
|
||||||
End If
|
End If
|
||||||
@@ -1083,17 +1182,17 @@ BlockNullPicture:
|
|||||||
#End Region
|
#End Region
|
||||||
End Class
|
End Class
|
||||||
Friend Interface IContentProvider
|
Friend Interface IContentProvider
|
||||||
Property Site As Sites
|
ReadOnly Property Site As String
|
||||||
Property Name As String
|
Property Name As String
|
||||||
Property ID As String
|
Property ID As String
|
||||||
Property FriendlyName As String
|
Property FriendlyName As String
|
||||||
Property Description As String
|
Property Description As String
|
||||||
Property Favorite As Boolean
|
Property Favorite As Boolean
|
||||||
Property Temporary As Boolean
|
Property Temporary As Boolean
|
||||||
Sub OpenSite()
|
Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing)
|
||||||
Sub DownloadData(ByVal Token As CancellationToken)
|
Sub DownloadData(ByVal Token As CancellationToken)
|
||||||
End Interface
|
End Interface
|
||||||
Friend Interface IUserData : Inherits IContentProvider, IComparable(Of UserDataBase), IComparable, IEquatable(Of UserDataBase), IDisposable
|
Friend Interface IUserData : Inherits IContentProvider, IComparable(Of UserDataBase), IComparable, IEquatable(Of UserDataBase), IIndexable, IDisposable
|
||||||
Event OnUserUpdated(ByVal User As IUserData)
|
Event OnUserUpdated(ByVal User As IUserData)
|
||||||
Property ParseUserMediaOnly As Boolean
|
Property ParseUserMediaOnly As Boolean
|
||||||
#Region "Images"
|
#Region "Images"
|
||||||
@@ -1110,16 +1209,16 @@ BlockNullPicture:
|
|||||||
Property Exists As Boolean
|
Property Exists As Boolean
|
||||||
Property Suspended As Boolean
|
Property Suspended As Boolean
|
||||||
Property ReadyForDownload As Boolean
|
Property ReadyForDownload As Boolean
|
||||||
|
Property HOST As SettingsHost
|
||||||
Property [File] As SFile
|
Property [File] As SFile
|
||||||
Property FileExists As Boolean
|
Property FileExists As Boolean
|
||||||
Property DownloadedPictures As Integer
|
Property DownloadedPictures(ByVal Total As Boolean) As Integer
|
||||||
Property DownloadedVideos As Integer
|
Property DownloadedVideos(ByVal Total As Boolean) As Integer
|
||||||
ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
|
ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
|
||||||
ReadOnly Property DownloadedInformation As String
|
ReadOnly Property DownloadedInformation As String
|
||||||
Property HasError As Boolean
|
Property HasError As Boolean
|
||||||
ReadOnly Property FitToAddParams As Boolean
|
ReadOnly Property FitToAddParams As Boolean
|
||||||
ReadOnly Property LVIKey As String
|
ReadOnly Property Key As String
|
||||||
ReadOnly Property LVIIndex As Integer
|
|
||||||
Property DownloadImages As Boolean
|
Property DownloadImages As Boolean
|
||||||
Property DownloadVideos As Boolean
|
Property DownloadVideos As Boolean
|
||||||
Function GetLVI(ByVal Destination As ListView) As ListViewItem
|
Function GetLVI(ByVal Destination As ListView) As ListViewItem
|
||||||
@@ -1137,6 +1236,8 @@ BlockNullPicture:
|
|||||||
Sub OpenFolder()
|
Sub OpenFolder()
|
||||||
ReadOnly Property Self As IUserData
|
ReadOnly Property Self As IUserData
|
||||||
Property DownloadTopCount As Integer?
|
Property DownloadTopCount As Integer?
|
||||||
|
Sub SetEnvironment(ByRef h As SettingsHost, ByVal u As UserInfo, ByVal _LoadUserInformation As Boolean,
|
||||||
|
Optional ByVal AttachUserInfo As Boolean = True)
|
||||||
ReadOnly Property Disposed As Boolean
|
ReadOnly Property Disposed As Boolean
|
||||||
End Interface
|
End Interface
|
||||||
Friend Interface IChannelLimits
|
Friend Interface IChannelLimits
|
||||||
|
|||||||
35
SCrawler/API/Gfycat/Envir.vb
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports System.Net
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Namespace API.Gfycat
|
||||||
|
Friend NotInheritable Class Envir
|
||||||
|
Private Sub New()
|
||||||
|
End Sub
|
||||||
|
Friend Shared Function GetVideo(ByVal URL As String) As String
|
||||||
|
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
|
||||||
|
Catch ex As Exception
|
||||||
|
Dim e As EDP = EDP.ReturnValue
|
||||||
|
If TypeOf ex Is WebException Then
|
||||||
|
Dim obj As HttpWebResponse = TryCast(DirectCast(ex, WebException).Response, HttpWebResponse)
|
||||||
|
If Not If(obj?.StatusCode, HttpStatusCode.OK) = HttpStatusCode.NotFound Then e += EDP.SendInLog
|
||||||
|
End If
|
||||||
|
Return ErrorsDescriber.Execute(e, ex, $"[API.Gfycat.Envir.GetVideo({URL})]", String.Empty)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Dim u$ = GetVideo(URL)
|
||||||
|
Return If(u.IsEmptyString, Nothing, {New UserMedia(u, UserMedia.Types.Video)})
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
36
SCrawler/API/Instagram/AuthNullException.vb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports Sections = SCrawler.API.Instagram.UserData.Sections
|
||||||
|
Namespace API.Instagram
|
||||||
|
Friend Class AuthNullException : Inherits ArgumentNullException
|
||||||
|
Public Overrides ReadOnly Property ParamName As String
|
||||||
|
Public Overrides ReadOnly Property Message As String
|
||||||
|
Friend Sub New(ByVal s As Sections, ByVal IsSavedPosts As Boolean)
|
||||||
|
If IsSavedPosts Then
|
||||||
|
ParamName = "HashSavedPosts"
|
||||||
|
ElseIf s = Sections.Timeline Then
|
||||||
|
ParamName = "Hash"
|
||||||
|
Else
|
||||||
|
ParamName = "IG_APP_ID, IG_WWW_CLAIM"
|
||||||
|
End If
|
||||||
|
Message = $"Instagram auth for [{s}] is not set"
|
||||||
|
End Sub
|
||||||
|
Friend Shared Sub ThrowIfNull(ByVal s As Sections, ByVal IsSavedPosts As Boolean, ByVal Host As SiteSettings)
|
||||||
|
Dim b As Boolean = False
|
||||||
|
If IsSavedPosts Then
|
||||||
|
If Not ACheck(Host.HashSavedPosts.Value) Then b = True
|
||||||
|
ElseIf s = Sections.Timeline Then
|
||||||
|
If Not ACheck(Host.Hash.Value) Then Host.HashUpdateRequired.Value = True : b = True
|
||||||
|
Else
|
||||||
|
If Not Host.StoriesAndTaggedReady Then b = True
|
||||||
|
End If
|
||||||
|
If b Then Throw New AuthNullException(s, IsSavedPosts)
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Namespace API.Instagram
|
Namespace API.Instagram
|
||||||
Friend Module Declarations
|
Friend Module Declarations
|
||||||
|
Friend Const InstagramSite As String = "Instagram"
|
||||||
Friend ReadOnly FilesPattern As RParams = RParams.DMS(".+?([^/\?]+?\.[\w\d]{3,4})(?=(\?|\Z))", 1, EDP.ReturnValue)
|
Friend ReadOnly FilesPattern As RParams = RParams.DMS(".+?([^/\?]+?\.[\w\d]{3,4})(?=(\?|\Z))", 1, EDP.ReturnValue)
|
||||||
Friend ReadOnly Property DateProvider As New JsonDate
|
Friend ReadOnly Property DateProvider As New JsonDate
|
||||||
Friend Class JsonDate : Implements ICustomProvider
|
Friend Class JsonDate : Implements ICustomProvider
|
||||||
|
|||||||
23
SCrawler/API/Instagram/EditorExchangeOptions.vb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Namespace API.Instagram
|
||||||
|
Friend Class EditorExchangeOptions
|
||||||
|
Friend Property GetStories As Boolean
|
||||||
|
Friend Property GetTagged As Boolean
|
||||||
|
Private ReadOnly Property MySiteSettings As SiteSettings
|
||||||
|
Friend Sub New(ByVal h As ISiteSettings)
|
||||||
|
MySiteSettings = DirectCast(h, SiteSettings)
|
||||||
|
With MySiteSettings
|
||||||
|
GetStories = CBool(.GetStories.Value)
|
||||||
|
GetTagged = CBool(.GetTagged.Value)
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
15
SCrawler/API/Instagram/ExitException.vb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace API.Instagram
|
||||||
|
Friend Class ExitException : Inherits Exception
|
||||||
|
Friend Sub New(ByRef CompleteArg As Boolean)
|
||||||
|
CompleteArg = True
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
120
SCrawler/API/Instagram/OptionsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace API.Instagram
|
||||||
|
<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()
|
||||||
|
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||||
|
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()
|
||||||
|
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(260, 53)
|
||||||
|
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.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_GET_STORIES, 0, 0)
|
||||||
|
TP_MAIN.Controls.Add(Me.CH_GET_TAGGED, 0, 1)
|
||||||
|
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
|
TP_MAIN.Name = "TP_MAIN"
|
||||||
|
TP_MAIN.RowCount = 3
|
||||||
|
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 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.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.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.Text = "Get stories"
|
||||||
|
Me.CH_GET_STORIES.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'CH_GET_TAGGED
|
||||||
|
'
|
||||||
|
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.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.Text = "Get tagged data"
|
||||||
|
Me.CH_GET_TAGGED.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.Controls.Add(CONTAINER_MAIN)
|
||||||
|
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MaximizeBox = False
|
||||||
|
Me.MaximumSize = New System.Drawing.Size(276, 117)
|
||||||
|
Me.MinimizeBox = False
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(276, 117)
|
||||||
|
Me.Name = "OptionsForm"
|
||||||
|
Me.ShowIcon = False
|
||||||
|
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()
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents CH_GET_STORIES As CheckBox
|
||||||
|
Private WithEvents CH_GET_TAGGED As CheckBox
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
126
SCrawler/API/Instagram/OptionsForm.resx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?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>
|
||||||
|
</root>
|
||||||
44
SCrawler/API/Instagram/OptionsForm.vb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports PersonalUtilities.Forms
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Namespace API.Instagram
|
||||||
|
Friend Class OptionsForm : Implements IOkCancelToolbar
|
||||||
|
Private ReadOnly MyDefs As DefaultFormProps
|
||||||
|
Private ReadOnly Property MyExchangeOptions As EditorExchangeOptions
|
||||||
|
Friend Sub New(ByRef ExchangeOptions As EditorExchangeOptions)
|
||||||
|
InitializeComponent()
|
||||||
|
MyExchangeOptions = ExchangeOptions
|
||||||
|
MyDefs = New DefaultFormProps
|
||||||
|
End Sub
|
||||||
|
Private Sub OptionsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
With MyDefs
|
||||||
|
.MyViewInitialize(Me, Settings.Design, True)
|
||||||
|
.AddOkCancelToolbar()
|
||||||
|
.DelegateClosingChecker()
|
||||||
|
.AppendDetectors()
|
||||||
|
With MyExchangeOptions
|
||||||
|
CH_GET_STORIES.Checked = .GetStories
|
||||||
|
CH_GET_TAGGED.Checked = .GetTagged
|
||||||
|
End With
|
||||||
|
.EndLoaderOperations()
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
Private Sub ToolbarBttOK() Implements IOkCancelToolbar.ToolbarBttOK
|
||||||
|
With MyExchangeOptions
|
||||||
|
.GetStories = CH_GET_STORIES.Checked
|
||||||
|
.GetTagged = CH_GET_TAGGED.Checked
|
||||||
|
End With
|
||||||
|
MyDefs.CloseForm()
|
||||||
|
End Sub
|
||||||
|
Private Sub ToolbarBttCancel() Implements IOkCancelToolbar.ToolbarBttCancel
|
||||||
|
MyDefs.CloseForm(DialogResult.Cancel)
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
Imports SCrawler.API.Base
|
|
||||||
Imports System.Threading
|
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
|
||||||
Namespace API.Instagram
|
|
||||||
Friend NotInheritable Class ProfileSaved
|
|
||||||
Friend Shared ReadOnly Property DataPath As SFile = Settings(Sites.Instagram).SavedPostsPath
|
|
||||||
Private Sub New()
|
|
||||||
End Sub
|
|
||||||
Friend Shared Sub Download(ByRef Bar As MyProgress, ByVal Token As CancellationToken)
|
|
||||||
Try
|
|
||||||
Dim u As New UserInfo(Settings(Sites.Instagram).SavedPostsUserName.Value, Sites.Instagram) With {.SpecialPath = DataPath}
|
|
||||||
u.UpdateUserFile()
|
|
||||||
Using user As New UserData(u,, False)
|
|
||||||
DirectCast(user.Self, UserDataBase).IsSavedPosts = True
|
|
||||||
user.Progress = Bar
|
|
||||||
If Not user.FileExists Then user.UpdateUserInformation()
|
|
||||||
If Settings(Sites.Instagram).InstagramLastDownloadDate.Value < Now.AddMinutes(60) Then
|
|
||||||
user.RequestsCount = Settings(Sites.Instagram).InstagramLastRequestsCount
|
|
||||||
End If
|
|
||||||
user.DownloadData(Token)
|
|
||||||
Bar.InformationTemporary = $"Images: {user.DownloadedPictures}; Videos: {user.DownloadedVideos}"
|
|
||||||
With Settings
|
|
||||||
.BeginUpdate()
|
|
||||||
With .Site(Sites.Instagram)
|
|
||||||
.InstagramLastDownloadDate.Value = Now
|
|
||||||
.InstagramLastRequestsCount.Value = user.RequestsCount
|
|
||||||
End With
|
|
||||||
.EndUpdate()
|
|
||||||
End With
|
|
||||||
End Using
|
|
||||||
Catch ex As Exception
|
|
||||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[API.Instagram.ProfileSaved.Download]")
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
End Namespace
|
|
||||||
314
SCrawler/API/Instagram/SiteSettings.vb
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Attributes
|
||||||
|
Imports PersonalUtilities.Tools
|
||||||
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Functions.XML.Base
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Namespace API.Instagram
|
||||||
|
<Manifest("AndyProgram_Instagram"), UseClassAsIs, SeparatedTasks(1), SavedPosts, SpecialForm(False)>
|
||||||
|
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||||
|
#Region "Interface Declarations"
|
||||||
|
Friend Overrides ReadOnly Property Icon As Icon
|
||||||
|
Get
|
||||||
|
Return My.Resources.InstagramIcon
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Overrides ReadOnly Property Image As Image
|
||||||
|
Get
|
||||||
|
Return My.Resources.InstagramPic76
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
#End Region
|
||||||
|
#Region "Providers"
|
||||||
|
Private Class TimersChecker : Implements ICustomProvider
|
||||||
|
Private ReadOnly _LowestValue As Integer
|
||||||
|
Friend Sub New(ByVal LowestValue As Integer)
|
||||||
|
_LowestValue = LowestValue
|
||||||
|
End Sub
|
||||||
|
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||||
|
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||||
|
If ACheck(Of Integer)(Value) AndAlso CInt(Value) >= _LowestValue Then
|
||||||
|
Return Value
|
||||||
|
Else
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
|
||||||
|
Throw New NotImplementedException()
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
#End Region
|
||||||
|
#Region "Authorization properties"
|
||||||
|
<PropertyOption(ControlText:="Hash", ControlToolTip:="Instagram session hash", IsAuth:=True), PXML("InstaHash"), ControlNumber(0)>
|
||||||
|
Friend ReadOnly Property Hash As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="Hash 2", ControlToolTip:="Instagram session hash for saved posts", IsAuth:=True), PXML("InstaHashSavedPosts"), ControlNumber(1)>
|
||||||
|
Friend ReadOnly Property HashSavedPosts As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-ig-app-id", IsAuth:=True), ControlNumber(2)>
|
||||||
|
Friend Property IG_APP_ID As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="x-ig-www-claim", IsAuth:=True), ControlNumber(3)>
|
||||||
|
Friend Property IG_WWW_CLAIM As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="Saved posts user", IsAuth:=True), PXML("SavedPostsUserName"), ControlNumber(4)>
|
||||||
|
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||||
|
Friend ReadOnly Property StoriesAndTaggedReady As Boolean
|
||||||
|
Get
|
||||||
|
Return ACheck(IG_APP_ID.Value) And ACheck(IG_WWW_CLAIM.Value)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
#End Region
|
||||||
|
#Region "Download properties"
|
||||||
|
Friend ReadOnly Property HashUpdateRequired As XMLValue(Of Boolean)
|
||||||
|
<PropertyOption(ControlText:="Request timer", AllowNull:=False), PXML("RequestsWaitTimer"), ControlNumber(5)>
|
||||||
|
Friend ReadOnly Property RequestsWaitTimer As PropertyValue
|
||||||
|
<Provider(NameOf(RequestsWaitTimer), FieldsChecker:=True)>
|
||||||
|
Private ReadOnly Property RequestsWaitTimerProvider As IFormatProvider
|
||||||
|
<PropertyOption(ControlText:="Request timer counter", AllowNull:=False), PXML("RequestsWaitTimerTaskCount"), ControlNumber(6)>
|
||||||
|
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(7)>
|
||||||
|
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
|
||||||
|
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
|
||||||
|
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
|
||||||
|
<PropertyOption(ControlText:="Get stories"), PXML, ControlNumber(8)>
|
||||||
|
Friend ReadOnly Property GetStories As PropertyValue
|
||||||
|
<PropertyOption(ControlText:="Get tagged photos"), PXML, ControlNumber(9)>
|
||||||
|
Friend ReadOnly Property GetTagged As PropertyValue
|
||||||
|
#End Region
|
||||||
|
#Region "429 bypass"
|
||||||
|
Friend ReadOnly Property DownloadingErrorDate As XMLValue(Of Date)
|
||||||
|
Friend Property LastApplyingValue As Integer? = Nothing
|
||||||
|
Friend ReadOnly Property ReadyForDownload As Boolean
|
||||||
|
Get
|
||||||
|
With DownloadingErrorDate
|
||||||
|
If .ValueF.Exists Then
|
||||||
|
Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10)) < Now
|
||||||
|
Else
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property LastDownloadDate As XMLValue(Of Date)
|
||||||
|
Friend ReadOnly Property LastRequestsCount As XMLValue(Of Integer)
|
||||||
|
Private TooManyRequestsReadyForCatch As Boolean = True
|
||||||
|
Friend Function GetWaitDate() As Date
|
||||||
|
With DownloadingErrorDate
|
||||||
|
If .ValueF.Exists Then
|
||||||
|
Return .ValueF.Value.AddMinutes(If(LastApplyingValue, 10))
|
||||||
|
Else
|
||||||
|
Return Now
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Function
|
||||||
|
Friend Sub TooManyRequests(ByVal Catched As Boolean)
|
||||||
|
With DownloadingErrorDate
|
||||||
|
If Catched Then
|
||||||
|
If Not .ValueF.Exists Then
|
||||||
|
.Value = Now
|
||||||
|
If TooManyRequestsReadyForCatch Then
|
||||||
|
LastApplyingValue = If(LastApplyingValue, 0) + 10
|
||||||
|
TooManyRequestsReadyForCatch = False
|
||||||
|
MyMainLOG = $"Instagram downloading error: too many requests. Try again after {If(LastApplyingValue, 10)} minutes..."
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
.ValueF = Nothing
|
||||||
|
LastApplyingValue = Nothing
|
||||||
|
TooManyRequestsReadyForCatch = True
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
Friend Overrides ReadOnly Property Responser As WEB.Response
|
||||||
|
Friend Sub New(ByRef _XML As XmlFile, ByVal GlobalPath As SFile)
|
||||||
|
MyBase.New(InstagramSite)
|
||||||
|
Responser = New WEB.Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||||
|
|
||||||
|
Dim app_id$ = String.Empty
|
||||||
|
Dim www_claim$ = String.Empty
|
||||||
|
|
||||||
|
With Responser
|
||||||
|
If .File.Exists Then
|
||||||
|
.LoadSettings()
|
||||||
|
With .Headers
|
||||||
|
If .ContainsKey(Header_IG_APP_ID) Then app_id = .Item(Header_IG_APP_ID)
|
||||||
|
If .ContainsKey(Header_IG_WWW_CLAIM) Then www_claim = .Item(Header_IG_WWW_CLAIM)
|
||||||
|
End With
|
||||||
|
Else
|
||||||
|
.CookiesDomain = "instagram.com"
|
||||||
|
.SaveSettings()
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
|
||||||
|
Dim n() As String = {SettingsCLS.Name_Node_Sites, Site.ToString}
|
||||||
|
|
||||||
|
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
|
||||||
|
HashUpdateRequired = New XMLValue(Of Boolean)("InstaHashUpdateRequired", True, _XML, n)
|
||||||
|
Hash = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
HashSavedPosts = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
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))
|
||||||
|
|
||||||
|
RequestsWaitTimer = New PropertyValue(1000)
|
||||||
|
RequestsWaitTimerProvider = New TimersChecker(100)
|
||||||
|
RequestsWaitTimerTaskCount = New PropertyValue(1)
|
||||||
|
RequestsWaitTimerTaskCountProvider = New TimersChecker(1)
|
||||||
|
SleepTimerOnPostsLimit = New PropertyValue(6000)
|
||||||
|
SleepTimerOnPostsLimitProvider = New TimersChecker(10000)
|
||||||
|
|
||||||
|
GetStories = New PropertyValue(False)
|
||||||
|
GetTagged = New PropertyValue(False)
|
||||||
|
|
||||||
|
DownloadingErrorDate = New XMLValue(Of Date) With {
|
||||||
|
.Provider = New XMLValueConversionProvider(Function(ss, vv) 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)
|
||||||
|
|
||||||
|
UrlPatternUser = "https://www.instagram.com/{0}/"
|
||||||
|
UserRegex = RParams.DMS("[htps:/]{7,8}.*?instagram.com/([^/]+)", 1)
|
||||||
|
ImageVideoContains = "instagram.com"
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider
|
||||||
|
Select Case What
|
||||||
|
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))}
|
||||||
|
Return u
|
||||||
|
End Select
|
||||||
|
Return Nothing
|
||||||
|
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 Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
||||||
|
If Not PropName.IsEmptyString Then
|
||||||
|
Dim f$ = String.Empty
|
||||||
|
Select Case PropName
|
||||||
|
Case NameOf(IG_APP_ID) : f = Header_IG_APP_ID
|
||||||
|
Case NameOf(IG_WWW_CLAIM) : f = Header_IG_WWW_CLAIM
|
||||||
|
End Select
|
||||||
|
If Not f.IsEmptyString Then
|
||||||
|
If Responser.Headers.Count > 0 AndAlso Responser.Headers.ContainsKey(f) Then Responser.Headers.Remove(f)
|
||||||
|
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||||
|
Responser.SaveSettings()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
<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
|
||||||
|
Friend Overrides Sub BeginInit()
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Sub EndInit()
|
||||||
|
If (CStr(Hash.Value).IsEmptyString Or HashUpdateRequired) AndAlso Responser.Cookies.ListExists Then GatherInstaHash()
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function ReadyToDownload(ByVal What As Download) As Boolean
|
||||||
|
Return ActiveJobs < 2 AndAlso ReadyForDownload
|
||||||
|
End Function
|
||||||
|
#Region "Downloading"
|
||||||
|
Private ActiveJobs As Integer = 0
|
||||||
|
Private _NextWNM As UserData.WNM = UserData.WNM.Notify
|
||||||
|
Friend Overrides Sub DownloadStarted(ByVal What As Download)
|
||||||
|
If CStr(Hash.Value).IsEmptyString Or HashUpdateRequired Then GatherInstaHash()
|
||||||
|
ActiveJobs += 1
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Sub BeforeStartDownload(ByVal User As Object, ByVal What As Download)
|
||||||
|
With DirectCast(User, UserData)
|
||||||
|
If What = Download.Main Then .WaitNotificationMode = _NextWNM
|
||||||
|
If LastDownloadDate.Value.AddMinutes(60) > Now Then
|
||||||
|
.RequestsCount = LastRequestsCount
|
||||||
|
Else
|
||||||
|
LastRequestsCount.Value = 0
|
||||||
|
.RequestsCount = 0
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Sub AfterDownload(ByVal User As Object, ByVal What As Download)
|
||||||
|
With DirectCast(User, UserData)
|
||||||
|
_NextWNM = .WaitNotificationMode
|
||||||
|
If _NextWNM = UserData.WNM.SkipTemp Or _NextWNM = UserData.WNM.SkipCurrent Then _NextWNM = UserData.WNM.Notify
|
||||||
|
LastRequestsCount.Value = .RequestsCount
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Sub DownloadDone(ByVal What As Download)
|
||||||
|
_NextWNM = UserData.WNM.Notify
|
||||||
|
LastDownloadDate.Value = Now
|
||||||
|
ActiveJobs -= 1
|
||||||
|
If HashUpdateRequired Then MyMainLOG = "Check your Instagram credentials"
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
<PropertyUpdater(NameOf(Hash))>
|
||||||
|
Friend Function GatherInstaHash() As Boolean
|
||||||
|
Try
|
||||||
|
If Not Responser.Cookies.ListExists Then Throw New Exception("Instagram cookies does not set")
|
||||||
|
Dim rs As New RParams("=""([^""]+?ConsumerLibCommons[^""]+?.js)""", Nothing, 1) With {.MatchTimeOut = 10}
|
||||||
|
Dim r$ = Responser.GetResponse("https://instagram.com",, EDP.ThrowException)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Dim hStr$ = RegexReplace(r, rs)
|
||||||
|
If Not hStr.IsEmptyString Then
|
||||||
|
Do While Left(hStr, 1) = "/" : hStr = Right(hStr, hStr.Length - 1) : Loop
|
||||||
|
hStr = $"https://instagram.com/{hStr}"
|
||||||
|
r = Responser.GetResponse(hStr,, EDP.ThrowException)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
rs = New RParams("generatePaginationActionCreators.+?.profilePosts.byUserId.get.+?queryId:.([\d\w\S]+?)""", Nothing, 1) With {.MatchTimeOut = 10}
|
||||||
|
Dim h$ = RegexReplace(r, rs)
|
||||||
|
If Not h.IsEmptyString Then
|
||||||
|
Hash.Value = h
|
||||||
|
HashUpdateRequired.Value = False
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return False
|
||||||
|
Catch ex As Exception
|
||||||
|
HashUpdateRequired.Value = True
|
||||||
|
Hash.Value = String.Empty
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, "[SiteSettings.GaterInstaHash]", False)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Return UserData.GetVideoInfo(URL, Responser)
|
||||||
|
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
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
Imports PersonalUtilities.Functions.Messaging
|
Imports PersonalUtilities.Functions.Messaging
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.WEB
|
||||||
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
|
||||||
Imports SCrawler.API.Base
|
Imports SCrawler.API.Base
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports System.Net
|
Imports System.Net
|
||||||
@@ -20,60 +20,83 @@ Namespace API.Instagram
|
|||||||
Private Const MaxPostsCount As Integer = 200
|
Private Const MaxPostsCount As Integer = 200
|
||||||
Private Const Name_LastCursor As String = "LastCursor"
|
Private Const Name_LastCursor As String = "LastCursor"
|
||||||
Private Const Name_FirstLoadingDone As String = "FirstLoadingDone"
|
Private Const Name_FirstLoadingDone As String = "FirstLoadingDone"
|
||||||
Friend Overrides Property Site As Sites = Sites.Instagram
|
Private Const Name_GetStories As String = "GetStories"
|
||||||
Friend Overrides Property Progress As MyProgress
|
Private Const Name_GetTagged As String = "GetTaggedData"
|
||||||
|
Private Const Name_TaggedChecked As String = "TaggedChecked"
|
||||||
|
Private ReadOnly Property MySiteSettings As SiteSettings
|
||||||
Get
|
Get
|
||||||
If Not _Progress Is Nothing Then Return _Progress Else Return MainProgressInst
|
Return DirectCast(HOST.Source, SiteSettings)
|
||||||
End Get
|
End Get
|
||||||
Set(ByVal p As MyProgress)
|
|
||||||
_Progress = p
|
|
||||||
End Set
|
|
||||||
End Property
|
End Property
|
||||||
Private ReadOnly _SavedPostsIDs As New List(Of String)
|
Private ReadOnly _SavedPostsIDs As New List(Of String)
|
||||||
Private LastCursor As String = String.Empty
|
Private LastCursor As String = String.Empty
|
||||||
Private FirstLoadingDone As Boolean = True
|
Private FirstLoadingDone As Boolean = False
|
||||||
''' <summary>Video downloader initializer</summary>
|
Friend Property GetStories As Boolean
|
||||||
Private Sub New()
|
Friend Property GetTaggedData As Boolean
|
||||||
|
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||||
|
Return New EditorExchangeOptions(HOST.Source) With {.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)
|
||||||
|
GetStories = .GetStories
|
||||||
|
GetTaggedData = .GetTagged
|
||||||
|
End With
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>Default initializer</summary>
|
Friend Sub New()
|
||||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True, Optional ByVal InvokeImageHandler As Boolean = True)
|
|
||||||
MyBase.New(InvokeImageHandler)
|
|
||||||
User = u
|
|
||||||
If _LoadUserInformation Then LoadUserInformation()
|
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
If Loading Then
|
If Loading Then
|
||||||
LastCursor = Container.Value(Name_LastCursor)
|
LastCursor = Container.Value(Name_LastCursor)
|
||||||
FirstLoadingDone = Container.Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
|
FirstLoadingDone = Container.Value(Name_FirstLoadingDone).FromXML(Of Boolean)(False)
|
||||||
|
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
|
Else
|
||||||
Container.Add(Name_LastCursor, LastCursor)
|
Container.Add(Name_LastCursor, LastCursor)
|
||||||
Container.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
|
Container.Add(Name_FirstLoadingDone, FirstLoadingDone.BoolToInteger)
|
||||||
|
Container.Add(Name_GetStories, GetStories.BoolToInteger)
|
||||||
|
Container.Add(Name_GetTagged, GetTaggedData.BoolToInteger)
|
||||||
|
Container.Add(Name_TaggedChecked, TaggedChecked.BoolToInteger)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
#Region "Download data"
|
||||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||||
Try
|
Try
|
||||||
_InstaHash = String.Empty
|
_InstaHash = String.Empty
|
||||||
HasError = False
|
HasError = False
|
||||||
If Not LastCursor.IsEmptyString Then
|
If Not LastCursor.IsEmptyString Then
|
||||||
DownloadData(LastCursor, Token)
|
DownloadData(LastCursor, Sections.Timeline, Token)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If Not HasError Then FirstLoadingDone = True
|
If Not HasError Then FirstLoadingDone = True
|
||||||
End If
|
End If
|
||||||
If Not HasError Then
|
If Not HasError Then
|
||||||
DownloadData(String.Empty, Token)
|
DownloadData(String.Empty, Sections.Timeline, Token)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If Not HasError Then FirstLoadingDone = True
|
If Not HasError Then FirstLoadingDone = True
|
||||||
End If
|
End If
|
||||||
If FirstLoadingDone Then LastCursor = String.Empty
|
If FirstLoadingDone Then LastCursor = String.Empty
|
||||||
If IsSavedPosts Then DownloadPosts(Token)
|
If IsSavedPosts Then
|
||||||
|
DownloadPosts(Token)
|
||||||
|
ElseIf MySiteSettings.StoriesAndTaggedReady Then
|
||||||
|
If GetStories Then DownloadData(String.Empty, Sections.Stories, Token)
|
||||||
|
If GetTaggedData Then DownloadData(String.Empty, Sections.Tagged, Token)
|
||||||
|
End If
|
||||||
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
If WaitNotificationMode = WNM.SkipTemp Or WaitNotificationMode = WNM.SkipCurrent Then WaitNotificationMode = WNM.Notify
|
||||||
|
Catch eex As ExitException
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ProcessException(ex, Token, "[API.Instagram.UserData.DownloadDataF", False)
|
ProcessException(ex, Token, "[API.Instagram.UserData.DownloadDataF", False)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Private _InstaHash As String = String.Empty
|
Private _InstaHash As String = String.Empty
|
||||||
|
Friend Enum Sections
|
||||||
|
Timeline
|
||||||
|
Tagged
|
||||||
|
Stories
|
||||||
|
End Enum
|
||||||
#Region "429 bypass"
|
#Region "429 bypass"
|
||||||
Friend RequestsCount As Integer = 0
|
Friend Property RequestsCount As Integer = 0
|
||||||
Friend Enum WNM As Integer
|
Friend Enum WNM As Integer
|
||||||
Notify = 0
|
Notify = 0
|
||||||
SkipCurrent = 1
|
SkipCurrent = 1
|
||||||
@@ -85,11 +108,11 @@ Namespace API.Instagram
|
|||||||
Private ProgressTempSet As Boolean = False
|
Private ProgressTempSet As Boolean = False
|
||||||
Private Const InstAborted As String = "InstAborted"
|
Private Const InstAborted As String = "InstAborted"
|
||||||
Private Function Ready() As Boolean
|
Private Function Ready() As Boolean
|
||||||
With Settings(Sites.Instagram)
|
With MySiteSettings
|
||||||
If Not .InstagramReadyForDownload Then
|
If Not .ReadyForDownload Then
|
||||||
If WaitNotificationMode = WNM.Notify Then
|
If WaitNotificationMode = WNM.Notify Then
|
||||||
Dim m As New MMessage("Instagram [too many requests] error." & vbCr &
|
Dim m As New MMessage("Instagram [too many requests] error." & vbCr &
|
||||||
$"The program suggests waiting {If(Settings(Sites.Instagram).InstagramLastApplyingValue, 0)} minutes." & vbCr &
|
$"The program suggests waiting {If(.LastApplyingValue, 0)} minutes." & vbCr &
|
||||||
"What do you want to do?", "Waiting for Instagram download...",
|
"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") With {.ToolTip = "Wait and ask again when the error is found."},
|
||||||
@@ -105,7 +128,7 @@ Namespace API.Instagram
|
|||||||
Case Else : WaitNotificationMode = WNM.SkipTemp
|
Case Else : WaitNotificationMode = WNM.SkipTemp
|
||||||
End Select
|
End Select
|
||||||
End If
|
End If
|
||||||
If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until {Settings(Sites.Instagram).GetInstaWaitDate().ToString(ParsersDataDateProvider)}"
|
If Not ProgressTempSet Then Progress.InformationTemporary = $"Waiting until { .GetWaitDate().ToString(ParsersDataDateProvider)}"
|
||||||
ProgressTempSet = True
|
ProgressTempSet = True
|
||||||
Return False
|
Return False
|
||||||
Else
|
Else
|
||||||
@@ -115,22 +138,28 @@ Namespace API.Instagram
|
|||||||
End Function
|
End Function
|
||||||
Private Sub ReconfigureAwaiter()
|
Private Sub ReconfigureAwaiter()
|
||||||
If WaitNotificationMode = WNM.SkipTemp Then WaitNotificationMode = WNM.Notify
|
If WaitNotificationMode = WNM.SkipTemp Then WaitNotificationMode = WNM.Notify
|
||||||
If Caught429 Then Caught429 = False : RequestsCount = 0
|
If Caught429 Then Caught429 = False ': RequestsCount = 0
|
||||||
ProgressTempSet = False
|
ProgressTempSet = False
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub NextRequest(ByVal StartWait As Boolean)
|
Private Sub NextRequest(ByVal StartWait As Boolean)
|
||||||
With Settings(Sites.Instagram)
|
With MySiteSettings
|
||||||
If StartWait And (RequestsCount Mod .RequestsWaitTimerTaskCount.Value) = 0 Then Thread.Sleep(.RequestsWaitTimer)
|
If StartWait And RequestsCount > 0 And (RequestsCount Mod .RequestsWaitTimerTaskCount.Value) = 0 Then Thread.Sleep(CInt(.RequestsWaitTimer.Value))
|
||||||
If RequestsCount >= MaxPostsCount - 5 Then Thread.Sleep(.SleepTimerOnPostsLimit)
|
If RequestsCount >= MaxPostsCount - 5 Then Thread.Sleep(CInt(.SleepTimerOnPostsLimit.Value))
|
||||||
End With
|
End With
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
|
Private Const StoriesFolder As String = "Stories"
|
||||||
|
Private Const TaggedFolder As String = "Tagged"
|
||||||
|
Private TaggedChecked As Boolean = False
|
||||||
|
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Section As Sections, ByVal Token As CancellationToken)
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
|
Dim StoriesList As List(Of String) = Nothing
|
||||||
|
Dim StoriesRequested As Boolean = False
|
||||||
Dim _DownloadComplete As Boolean = False
|
Dim _DownloadComplete As Boolean = False
|
||||||
LastCursor = Cursor
|
LastCursor = Cursor
|
||||||
Try
|
Try
|
||||||
Do While Not _DownloadComplete
|
Do While Not _DownloadComplete
|
||||||
|
ThrowAny(Token)
|
||||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||||
ReconfigureAwaiter()
|
ReconfigureAwaiter()
|
||||||
|
|
||||||
@@ -138,33 +167,61 @@ Namespace API.Instagram
|
|||||||
Dim n As EContainer, nn As EContainer, node As EContainer
|
Dim n As EContainer, nn As EContainer, node As EContainer
|
||||||
Dim HasNextPage As Boolean = False
|
Dim HasNextPage As Boolean = False
|
||||||
Dim EndCursor$ = String.Empty
|
Dim EndCursor$ = String.Empty
|
||||||
Dim PostID$ = String.Empty, PostDate$ = String.Empty
|
Dim PostID$ = String.Empty, PostDate$ = String.Empty, SpecFolder$ = String.Empty
|
||||||
|
Dim TaggedCount%
|
||||||
|
Dim ENode() As Object = Nothing
|
||||||
NextRequest(True)
|
NextRequest(True)
|
||||||
|
|
||||||
'Check environment
|
'Check environment
|
||||||
If Cursor.IsEmptyString And _InstaHash.IsEmptyString Then _
|
If Cursor.IsEmptyString And _InstaHash.IsEmptyString Then _
|
||||||
_InstaHash = If(IsSavedPosts, Settings(Sites.Instagram).InstaHash_SP, Settings(Sites.Instagram).InstaHash).Value
|
_InstaHash = CStr(If(IsSavedPosts, MySiteSettings.HashSavedPosts, MySiteSettings.Hash).Value)
|
||||||
If _InstaHash.IsEmptyString Then Throw New ArgumentNullException(IIf(IsSavedPosts, "InstaHashSavedPosts", "InstaHash"), "Query hash is null")
|
AuthNullException.ThrowIfNull(Section, IsSavedPosts, MySiteSettings)
|
||||||
If ID.IsEmptyString Then GetUserId()
|
If ID.IsEmptyString Then GetUserId()
|
||||||
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
If ID.IsEmptyString Then Throw New ArgumentException("User ID is not detected", "ID")
|
||||||
|
|
||||||
'Create query
|
'Create query
|
||||||
|
Select Case Section
|
||||||
|
Case Sections.Timeline
|
||||||
Dim vars$ = "{""id"":" & ID & ",""first"":50,""after"":""" & Cursor & """}"
|
Dim vars$ = "{""id"":" & ID & ",""first"":50,""after"":""" & Cursor & """}"
|
||||||
vars = SymbolsConverter.ASCII.EncodeSymbolsOnly(vars)
|
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={_InstaHash}&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
|
||||||
|
StoriesList = GetStoriesList()
|
||||||
|
MySiteSettings.TooManyRequests(False)
|
||||||
|
RequestsCount += 1
|
||||||
|
ThrowAny(Token)
|
||||||
|
End If
|
||||||
|
If StoriesList.ListExists Then
|
||||||
|
GetStoriesData(StoriesList, Token)
|
||||||
|
MySiteSettings.TooManyRequests(False)
|
||||||
|
RequestsCount += 1
|
||||||
|
End If
|
||||||
|
If StoriesList.ListExists Then
|
||||||
|
Continue Do
|
||||||
|
Else
|
||||||
|
Throw New ExitException(_DownloadComplete)
|
||||||
|
End If
|
||||||
|
End Select
|
||||||
|
|
||||||
'Get response
|
'Get response
|
||||||
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
Dim r$ = Responser.GetResponse(URL,, EDP.ThrowException)
|
||||||
Settings(Sites.Instagram).InstagramTooManyRequests(False)
|
MySiteSettings.TooManyRequests(False)
|
||||||
RequestsCount += 1
|
RequestsCount += 1
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
|
|
||||||
'Data
|
'Data
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||||
n = j.ItemF({"data", "user", 0}).XmlIfNothing
|
n = j.ItemF(ENode).XmlIfNothing
|
||||||
If n.Count > 0 Then
|
If n.Count > 0 Then
|
||||||
|
Select Case Section
|
||||||
|
Case Sections.Timeline
|
||||||
If n.Contains("page_info") Then
|
If n.Contains("page_info") Then
|
||||||
With n("page_info")
|
With n("page_info")
|
||||||
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
HasNextPage = .Value("has_next_page").FromXML(Of Boolean)(False)
|
||||||
@@ -179,32 +236,62 @@ Namespace API.Instagram
|
|||||||
If IsSavedPosts Then
|
If IsSavedPosts Then
|
||||||
PostID = node.Value("shortcode")
|
PostID = node.Value("shortcode")
|
||||||
If Not PostID.IsEmptyString Then
|
If Not PostID.IsEmptyString Then
|
||||||
If _TempPostsList.Contains(PostID) Then Exit Sub Else _SavedPostsIDs.Add(PostID)
|
If _TempPostsList.Contains(PostID) Then Throw New ExitException(_DownloadComplete) Else _SavedPostsIDs.Add(PostID)
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
PostID = node.Value("id")
|
PostID = node.Value("id")
|
||||||
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) Then Exit Sub
|
If Not PostID.IsEmptyString And _TempPostsList.Contains(PostID) Then Throw New ExitException(_DownloadComplete)
|
||||||
_TempPostsList.Add(PostID)
|
_TempPostsList.Add(PostID)
|
||||||
PostDate = node.Value("taken_at_timestamp")
|
PostDate = node.Value("taken_at_timestamp")
|
||||||
ObtainMedia(node, PostID, PostDate)
|
ObtainMedia(node, PostID, PostDate, SpecFolder)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
|
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)
|
||||||
|
Next
|
||||||
|
If Not TaggedChecked Then
|
||||||
|
TaggedCount = j.Value("total_count").FromXML(Of Integer)(0)
|
||||||
|
TaggedChecked = True
|
||||||
|
If TaggedChecked > 200 Then
|
||||||
|
Dim a% = MsgBoxE({$"The number of tagged posts is {TaggedCount.NumToString(New ANumbers With {
|
||||||
|
.FormatOptions = ANumbers.Options.GroupIntegral})}" & vbCr &
|
||||||
|
"The tagged data download operation can take a long time.", "Too much tagged data"}, vbExclamation,,,
|
||||||
|
{"Continue",
|
||||||
|
New MsgBoxButton("Disable and cancel") With {
|
||||||
|
.ToolTip = "Disable downloading tagged data and cancel downloading tagged data."},
|
||||||
|
"Cancel"})
|
||||||
|
If a > 0 Then
|
||||||
|
If a = 1 Then GetTaggedData = False
|
||||||
|
Throw New ExitException(_DownloadComplete)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Select
|
||||||
Else
|
Else
|
||||||
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso _TempMediaList.Count = 0 Then
|
If j.Value("status") = "ok" AndAlso j({"data", "user"}).XmlIfNothing.Count = 0 AndAlso _TempMediaList.Count = 0 Then
|
||||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
MySiteSettings.HashUpdateRequired.Value = True
|
||||||
UserExists = False
|
UserExists = False
|
||||||
_DownloadComplete = True
|
Throw New ExitException(_DownloadComplete)
|
||||||
Exit Sub
|
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
Else
|
Else
|
||||||
_DownloadComplete = True
|
Throw New ExitException(_DownloadComplete)
|
||||||
Exit Sub
|
|
||||||
End If
|
End If
|
||||||
_DownloadComplete = True
|
_DownloadComplete = True
|
||||||
If HasNextPage And Not EndCursor.IsEmptyString Then DownloadData(EndCursor, Token)
|
If HasNextPage And Not EndCursor.IsEmptyString Then DownloadData(EndCursor, Section, Token)
|
||||||
|
Catch iane As AuthNullException
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, iane)
|
||||||
|
Throw New ExitException(_DownloadComplete)
|
||||||
|
Catch eex As ExitException
|
||||||
|
Throw eex
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
Exit Do
|
Exit Do
|
||||||
Catch dex As ObjectDisposedException When Disposed
|
Catch dex As ObjectDisposedException When Disposed
|
||||||
@@ -213,6 +300,8 @@ Namespace API.Instagram
|
|||||||
If DownloadingException(ex, $"data downloading error [{URL}]") = 1 Then Continue Do Else Exit Do
|
If DownloadingException(ex, $"data downloading error [{URL}]") = 1 Then Continue Do Else Exit Do
|
||||||
End Try
|
End Try
|
||||||
Loop
|
Loop
|
||||||
|
Catch eex2 As ExitException
|
||||||
|
If (Section = Sections.Timeline Or Section = Sections.Tagged) And Not Cursor.IsEmptyString Then Throw eex2
|
||||||
Catch oex2 As OperationCanceledException When Token.IsCancellationRequested Or oex2.HelpLink = InstAborted
|
Catch oex2 As OperationCanceledException When Token.IsCancellationRequested Or oex2.HelpLink = InstAborted
|
||||||
If oex2.HelpLink = InstAborted Then HasError = True
|
If oex2.HelpLink = InstAborted Then HasError = True
|
||||||
Catch DoEx As Exception
|
Catch DoEx As Exception
|
||||||
@@ -225,6 +314,7 @@ Namespace API.Instagram
|
|||||||
Dim _Index% = 0
|
Dim _Index% = 0
|
||||||
Try
|
Try
|
||||||
Do While Not _DownloadComplete
|
Do While Not _DownloadComplete
|
||||||
|
ThrowAny(Token)
|
||||||
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
If Not Ready() Then Thread.Sleep(10000) : ThrowAny(Token) : Continue Do
|
||||||
ReconfigureAwaiter()
|
ReconfigureAwaiter()
|
||||||
|
|
||||||
@@ -238,10 +328,10 @@ Namespace API.Instagram
|
|||||||
_Index = i
|
_Index = i
|
||||||
URL = $"https://instagram.com/p/{_SavedPostsIDs(i)}/?__a=1"
|
URL = $"https://instagram.com/p/{_SavedPostsIDs(i)}/?__a=1"
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
NextRequest((i + 1 Mod 5) = 0)
|
NextRequest(((i + 1) Mod 5) = 0)
|
||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
r = Responser.GetResponse(URL,, e)
|
r = Responser.GetResponse(URL,, e)
|
||||||
Settings(Sites.Instagram).InstagramTooManyRequests(False)
|
MySiteSettings.TooManyRequests(False)
|
||||||
RequestsCount += 1
|
RequestsCount += 1
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
j = JsonDocument.Parse(r)
|
j = JsonDocument.Parse(r)
|
||||||
@@ -249,7 +339,7 @@ Namespace API.Instagram
|
|||||||
_MediaObtained = False
|
_MediaObtained = False
|
||||||
If j.Contains({"graphql", "shortcode_media"}) Then
|
If j.Contains({"graphql", "shortcode_media"}) Then
|
||||||
With j({"graphql", "shortcode_media"}).XmlIfNothing
|
With j({"graphql", "shortcode_media"}).XmlIfNothing
|
||||||
If .Count > 0 Then ObtainMedia(.Self, _SavedPostsIDs(i), String.Empty) : _MediaObtained = True
|
If .Count > 0 Then ObtainMedia(.Self, _SavedPostsIDs(i), String.Empty, String.Empty) : _MediaObtained = True
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
If Not _MediaObtained AndAlso j.Contains("items") Then
|
If Not _MediaObtained AndAlso j.Contains("items") Then
|
||||||
@@ -263,8 +353,8 @@ Namespace API.Instagram
|
|||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
_DownloadComplete = True
|
|
||||||
End If
|
End If
|
||||||
|
_DownloadComplete = True
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
Exit Do
|
Exit Do
|
||||||
Catch dex As ObjectDisposedException When Disposed
|
Catch dex As ObjectDisposedException When Disposed
|
||||||
@@ -279,7 +369,9 @@ Namespace API.Instagram
|
|||||||
ProcessException(DoEx, Token, $"downloading saved posts error [{URL}]")
|
ProcessException(DoEx, Token, $"downloading saved posts error [{URL}]")
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub ObtainMedia(ByVal node As EContainer, ByVal PostID As String, ByVal PostDate As String)
|
#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) =
|
Dim CreateMedia As Action(Of EContainer) =
|
||||||
Sub(ByVal e As EContainer)
|
Sub(ByVal e As EContainer)
|
||||||
Dim t As UTypes = If(e.Value("is_video").FromXML(Of Boolean)(False), UTypes.Video, UTypes.Picture)
|
Dim t As UTypes = If(e.Value("is_video").FromXML(Of Boolean)(False), UTypes.Video, UTypes.Picture)
|
||||||
@@ -289,7 +381,7 @@ Namespace API.Instagram
|
|||||||
Else
|
Else
|
||||||
tmpValue = e.Value("video_url")
|
tmpValue = e.Value("video_url")
|
||||||
End If
|
End If
|
||||||
If Not tmpValue.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(t, tmpValue, PostID, PostDate), LNC)
|
If Not tmpValue.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(t, tmpValue, PostID, PostDate, SpecFolder), LNC)
|
||||||
End Sub
|
End Sub
|
||||||
If node.Contains({"edge_sidecar_to_children", "edges"}) Then
|
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
|
For Each edge As EContainer In node({"edge_sidecar_to_children", "edges"}) : CreateMedia(edge("node").XmlIfNothing) : Next
|
||||||
@@ -297,7 +389,7 @@ Namespace API.Instagram
|
|||||||
CreateMedia(node)
|
CreateMedia(node)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String)
|
Private Sub ObtainMedia2(ByVal n As EContainer, ByVal PostID As String, Optional ByVal SpecialFolder As String = Nothing)
|
||||||
Try
|
Try
|
||||||
Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0
|
Dim img As Predicate(Of EContainer) = Function(_img) Not _img.Name.IsEmptyString AndAlso _img.Name.StartsWith("image_versions") AndAlso _img.Count > 0
|
||||||
Dim vid As Predicate(Of EContainer) = Function(_vid) Not _vid.Name.IsEmptyString AndAlso _vid.Name.StartsWith("video_versions") AndAlso _vid.Count > 0
|
Dim vid As Predicate(Of EContainer) = Function(_vid) Not _vid.Name.IsEmptyString AndAlso _vid.Name.StartsWith("video_versions") AndAlso _vid.Count > 0
|
||||||
@@ -322,7 +414,7 @@ Namespace API.Instagram
|
|||||||
l.ListAddList(.Select(ss), LNC)
|
l.ListAddList(.Select(ss), LNC)
|
||||||
If l.Count > 0 Then
|
If l.Count > 0 Then
|
||||||
l.Sort()
|
l.Sort()
|
||||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, Nothing), LNC)
|
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, Nothing, SpecialFolder), LNC)
|
||||||
l.Clear()
|
l.Clear()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -337,7 +429,7 @@ Namespace API.Instagram
|
|||||||
l.ListAddList(.Select(ss), LNC)
|
l.ListAddList(.Select(ss), LNC)
|
||||||
If l.Count > 0 Then
|
If l.Count > 0 Then
|
||||||
l.Sort()
|
l.Sort()
|
||||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, Nothing), LNC)
|
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, Nothing, SpecialFolder), LNC)
|
||||||
l.Clear()
|
l.Clear()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -346,7 +438,7 @@ Namespace API.Instagram
|
|||||||
Case 8
|
Case 8
|
||||||
With n("carousel_media").XmlIfNothing
|
With n("carousel_media").XmlIfNothing
|
||||||
If .Count > 0 Then
|
If .Count > 0 Then
|
||||||
For Each d In .Self : ObtainMedia2(d, PostID) : Next
|
For Each d In .Self : ObtainMedia2(d, PostID, SpecialFolder) : Next
|
||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
End Select
|
End Select
|
||||||
@@ -354,9 +446,10 @@ Namespace API.Instagram
|
|||||||
l.Clear()
|
l.Clear()
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "API.Instagram.GetGallery")
|
ErrorsDescriber.Execute(EDP.SendInLog, ex, "API.Instagram.ObtainMedia2")
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
#End Region
|
||||||
Private Sub GetUserId()
|
Private Sub GetUserId()
|
||||||
Try
|
Try
|
||||||
Dim r$ = Responser.GetResponse($"https://www.instagram.com/{Name}/?__a=1",, EDP.ThrowException)
|
Dim r$ = Responser.GetResponse($"https://www.instagram.com/{Name}/?__a=1",, EDP.ThrowException)
|
||||||
@@ -373,6 +466,59 @@ Namespace API.Instagram
|
|||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
#Region "Pinned stories"
|
||||||
|
Private Sub GetStoriesData(ByRef StoriesList As List(Of String), ByVal Token As CancellationToken)
|
||||||
|
Const ReqUrl$ = "https://i.instagram.com/api/v1/feed/reels_media/?{0}"
|
||||||
|
Dim tmpList As IEnumerable(Of String)
|
||||||
|
Dim qStr$, r$, sFolder$, storyID$
|
||||||
|
Dim i% = -1
|
||||||
|
Dim jj As EContainer, s As EContainer
|
||||||
|
ThrowAny(Token)
|
||||||
|
If StoriesList.ListExists Then
|
||||||
|
tmpList = StoriesList.Take(5)
|
||||||
|
If tmpList.ListExists Then
|
||||||
|
qStr = String.Format(ReqUrl, tmpList.Select(Function(q) $"reel_ids=highlight:{q}").ListToString(, "&"))
|
||||||
|
r = Responser.GetResponse(qStr,, EDP.ThrowException)
|
||||||
|
ThrowAny(Token)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||||
|
If j.Contains("reels") Then
|
||||||
|
For Each jj In j("reels")
|
||||||
|
i += 1
|
||||||
|
sFolder = jj.Value("title")
|
||||||
|
storyID = jj.Value("id").Replace("highlight:", String.Empty)
|
||||||
|
If sFolder.IsEmptyString Then sFolder = $"Story_{storyID}"
|
||||||
|
If sFolder.IsEmptyString Then sFolder = $"Story_{i}"
|
||||||
|
sFolder = $"{StoriesFolder}\{sFolder}"
|
||||||
|
If Not storyID.IsEmptyString Then storyID &= ":"
|
||||||
|
With jj("items").XmlIfNothing
|
||||||
|
If .Count > 0 Then
|
||||||
|
For Each s In .Self : ThrowAny(Token) : ObtainMedia2(s, storyID & s.Value("id"), sFolder) : Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
StoriesList.RemoveRange(0, tmpList.Count)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Function GetStoriesList() As List(Of String)
|
||||||
|
Try
|
||||||
|
Dim r$ = Responser.GetResponse($"https://i.instagram.com/api/v1/highlights/{ID}/highlights_tray/",, EDP.ThrowException)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r).XmlIfNothing()("tray").XmlIfNothing
|
||||||
|
If j.Count > 0 Then Return j.Select(Function(jj) jj.Value("id").Replace("highlight:", String.Empty)).ListIfNothing
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
Catch ex As Exception
|
||||||
|
DownloadingException(ex, "API.Instagram.GetStoriesList")
|
||||||
|
Return Nothing
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
#End Region
|
||||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||||
@@ -388,38 +534,40 @@ Namespace API.Instagram
|
|||||||
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
ElseIf Responser.StatusCode = HttpStatusCode.BadRequest Then
|
||||||
HasError = True
|
HasError = True
|
||||||
MyMainLOG = "Instagram credentials have expired"
|
MyMainLOG = "Instagram credentials have expired"
|
||||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
MySiteSettings.HashUpdateRequired.Value = True
|
||||||
ElseIf Responser.StatusCode = 429 Then
|
ElseIf Responser.StatusCode = 429 Then
|
||||||
With Settings(Sites.Instagram)
|
With MySiteSettings
|
||||||
Dim WaiterExists As Boolean = .InstagramLastApplyingValue.HasValue
|
Dim WaiterExists As Boolean = .LastApplyingValue.HasValue
|
||||||
.InstagramTooManyRequests(True)
|
.TooManyRequests(True)
|
||||||
If Not WaiterExists Then .InstagramLastApplyingValue = 2
|
If Not WaiterExists Then .LastApplyingValue = 2
|
||||||
End With
|
End With
|
||||||
Caught429 = True
|
Caught429 = True
|
||||||
MyMainLOG = $"Number of requests before error 429: {RequestsCount}"
|
MyMainLOG = $"Number of requests before error 429: {RequestsCount}"
|
||||||
Return 1
|
Return 1
|
||||||
Else
|
Else
|
||||||
Settings(Sites.Instagram).InstaHashUpdateRequired.Value = True
|
MySiteSettings.HashUpdateRequired.Value = True
|
||||||
If Not FromPE Then LogError(ex, Message) : HasError = True
|
If Not FromPE Then LogError(ex, Message) : HasError = True
|
||||||
Return 0
|
Return 0
|
||||||
End If
|
End If
|
||||||
Return 2
|
Return 2
|
||||||
End Function
|
End Function
|
||||||
Private Shared Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String) As UserMedia
|
Private Shared Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||||
|
Optional ByVal SpecialFolder As String = Nothing) As UserMedia
|
||||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||||
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID}}
|
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID}}
|
||||||
If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern))
|
If Not m.URL.IsEmptyString Then m.File = CStr(RegexReplace(m.URL, FilesPattern))
|
||||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateProvider, Nothing) Else m.Post.Date = Nothing
|
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateProvider, Nothing) Else m.Post.Date = Nothing
|
||||||
|
m.SpecialFolder = SpecialFolder
|
||||||
Return m
|
Return m
|
||||||
End Function
|
End Function
|
||||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal r As Response) As IEnumerable(Of UserMedia)
|
||||||
Try
|
Try
|
||||||
If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then
|
If Not URL.IsEmptyString AndAlso URL.Contains("instagram.com") Then
|
||||||
Dim PID$ = RegexReplace(URL, RParams.DMS(".*?instagram.com/p/([_\w\d]+)", 1))
|
Dim PID$ = RegexReplace(URL, RParams.DMS(".*?instagram.com/p/([_\w\d]+)", 1))
|
||||||
If Not PID.IsEmptyString Then
|
If Not PID.IsEmptyString Then
|
||||||
Using t As New UserData
|
Using t As New UserData
|
||||||
t.Responser = New PersonalUtilities.Tools.WEB.Response
|
t.Responser = New Response
|
||||||
t.Responser.Copy(Settings(Sites.Instagram).Responser)
|
t.Responser.Copy(r)
|
||||||
t._SavedPostsIDs.Add(PID)
|
t._SavedPostsIDs.Add(PID)
|
||||||
t.DownloadPosts(Nothing)
|
t.DownloadPosts(Nothing)
|
||||||
Return ListAddList(Nothing, t._TempMediaList)
|
Return ListAddList(Nothing, t._TempMediaList)
|
||||||
|
|||||||
@@ -10,264 +10,24 @@ Imports PersonalUtilities.Tools
|
|||||||
Imports PersonalUtilities.Forms.Toolbars
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
Imports SCrawler.API.Base
|
Imports SCrawler.API.Base
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Namespace API.Reddit
|
Namespace API.Reddit
|
||||||
Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel),
|
Friend Class Channel : Implements ICollection(Of UserPost), IEquatable(Of Channel), IComparable(Of Channel),
|
||||||
IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IUserData, IDisposable
|
IRangeSwitcherContainer(Of UserPost), ILoaderSaver, IMyEnumerator(Of UserPost), IChannelLimits, IDisposable
|
||||||
#Region "XML Nodes' Names"
|
#Region "XML Nodes' Names"
|
||||||
Private Const Name_Name As String = "Name"
|
Private Const Name_Name As String = "Name"
|
||||||
Private Const Name_ID As String = "ID"
|
Private Const Name_ID As String = "ID"
|
||||||
Private Const Name_Date As String = "Date"
|
Private Const Name_Date As String = "Date"
|
||||||
Private Const Name_PostsNode As String = "Posts"
|
Private Const Name_PostsNode As String = "Posts"
|
||||||
Private Const Name_UsersAdded As String = "UsersAdded"
|
Private Const Name_UsersAdded As String = "UsersAdded"
|
||||||
|
Private Const Name_UsersExistent As String = "UsersExistent"
|
||||||
Private Const Name_PostsDownloaded As String = "PostsDownloaded"
|
Private Const Name_PostsDownloaded As String = "PostsDownloaded"
|
||||||
#End Region
|
#End Region
|
||||||
Friend Const DefaultDownloadLimitCount As Integer = 1000
|
Friend Const DefaultDownloadLimitCount As Integer = 1000
|
||||||
#Region "IUserData Support"
|
Friend ReadOnly Property Site As String = RedditSite
|
||||||
Private Event OnUserUpdated As IUserData.OnUserUpdatedEventHandler Implements IUserData.OnUserUpdated
|
Friend Property Name As String
|
||||||
Friend Property Instance As IUserData
|
Friend Property ID As String
|
||||||
Private Property IUserData_ParseUserMediaOnly As Boolean = False Implements IUserData.ParseUserMediaOnly
|
|
||||||
Private Property IUserData_Exists As Boolean Implements IUserData.Exists
|
|
||||||
Get
|
|
||||||
Return Instance.Exists
|
|
||||||
End Get
|
|
||||||
Set(ByVal e As Boolean)
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_Suspended As Boolean Implements IUserData.Suspended
|
|
||||||
Get
|
|
||||||
Return Instance.Suspended
|
|
||||||
End Get
|
|
||||||
Set(ByVal s As Boolean)
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_IsCollection As Boolean Implements IUserData.IsCollection
|
|
||||||
Get
|
|
||||||
Return Instance.IsCollection
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_CollectionName As String Implements IUserData.CollectionName
|
|
||||||
Get
|
|
||||||
Return Instance.CollectionName
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewName As String)
|
|
||||||
Instance.CollectionName = NewName
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_IncludedInCollection As Boolean Implements IUserData.IncludedInCollection
|
|
||||||
Get
|
|
||||||
Return Instance.IncludedInCollection
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_Labels As List(Of String) Implements IUserData.Labels
|
|
||||||
Get
|
|
||||||
Return Instance.Labels
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_IsChannel As Boolean = True Implements IUserData.IsChannel
|
|
||||||
Private Property IUserData_ReadyForDownload As Boolean Implements IUserData.ReadyForDownload
|
|
||||||
Get
|
|
||||||
Return Instance.ReadyForDownload
|
|
||||||
End Get
|
|
||||||
Set(ByVal IsReady As Boolean)
|
|
||||||
Instance.ReadyForDownload = IsReady
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_File As SFile Implements IUserData.File
|
|
||||||
Get
|
|
||||||
Return Instance.File
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewFile As SFile)
|
|
||||||
Instance.File = NewFile
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_FileExists As Boolean Implements IUserData.FileExists
|
|
||||||
Get
|
|
||||||
Return Instance.FileExists
|
|
||||||
End Get
|
|
||||||
Set(ByVal IsExists As Boolean)
|
|
||||||
Instance.FileExists = IsExists
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_DownloadedPictures As Integer Implements IUserData.DownloadedPictures
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadedPictures
|
|
||||||
End Get
|
|
||||||
Set(ByVal c As Integer)
|
|
||||||
Instance.DownloadedPictures = c
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_DownloadedVideos As Integer Implements IUserData.DownloadedVideos
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadedVideos
|
|
||||||
End Get
|
|
||||||
Set(ByVal c As Integer)
|
|
||||||
Instance.DownloadedVideos = c
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_DownloadedTotal(Optional Total As Boolean = True) As Integer Implements IUserData.DownloadedTotal
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadedTotal
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_DownloadedInformation As String Implements IUserData.DownloadedInformation
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadedInformation
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_HasError As Boolean Implements IUserData.HasError
|
|
||||||
Get
|
|
||||||
Return Instance.HasError
|
|
||||||
End Get
|
|
||||||
Set(ByVal e As Boolean)
|
|
||||||
Instance.HasError = e
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_FitToAddParams As Boolean Implements IUserData.FitToAddParams
|
|
||||||
Get
|
|
||||||
Return Instance.FitToAddParams
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_LVIKey As String Implements IUserData.LVIKey
|
|
||||||
Get
|
|
||||||
Return Instance.LVIKey
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_LVIIndex As Integer Implements IUserData.LVIIndex
|
|
||||||
Get
|
|
||||||
Return Instance.LVIIndex
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_DownloadImages As Boolean Implements IUserData.DownloadImages
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadImages
|
|
||||||
End Get
|
|
||||||
Set(ByVal d As Boolean)
|
|
||||||
Instance.DownloadImages = d
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_DownloadVideos As Boolean Implements IUserData.DownloadVideos
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadVideos
|
|
||||||
End Get
|
|
||||||
Set(ByVal d As Boolean)
|
|
||||||
Instance.DownloadVideos = d
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly Property IUserData_Self As IUserData Implements IUserData.Self
|
|
||||||
Get
|
|
||||||
Return Instance
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_DownloadTopCount As Integer? Implements IUserData.DownloadTopCount
|
|
||||||
Get
|
|
||||||
Return Instance.DownloadTopCount
|
|
||||||
End Get
|
|
||||||
Set(ByVal c As Integer?)
|
|
||||||
Instance.DownloadTopCount = c
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Friend Property Site As Sites = Sites.Reddit Implements IContentProvider.Site
|
|
||||||
Private Property IUserData_FriendlyName As String Implements IContentProvider.FriendlyName
|
|
||||||
Get
|
|
||||||
Return Instance.FriendlyName
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewName As String)
|
|
||||||
Instance.FriendlyName = NewName
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_Description As String Implements IContentProvider.Description
|
|
||||||
Get
|
|
||||||
Return Instance.Description
|
|
||||||
End Get
|
|
||||||
Set(ByVal d As String)
|
|
||||||
Instance.Description = d
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_Favorite As Boolean Implements IContentProvider.Favorite
|
|
||||||
Get
|
|
||||||
Return Instance.Favorite
|
|
||||||
End Get
|
|
||||||
Set(ByVal f As Boolean)
|
|
||||||
Instance.Favorite = f
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Property IUserData_Temporary As Boolean Implements IContentProvider.Temporary
|
|
||||||
Get
|
|
||||||
Return Instance.Temporary
|
|
||||||
End Get
|
|
||||||
Set(ByVal t As Boolean)
|
|
||||||
Instance.Temporary = t
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private Sub IUserData_SetPicture(ByVal f As SFile) Implements IUserData.SetPicture
|
|
||||||
Instance.SetPicture(f)
|
|
||||||
End Sub
|
|
||||||
Private Sub IUserData_LoadUserInformation() Implements IUserData.LoadUserInformation
|
|
||||||
Instance.LoadUserInformation()
|
|
||||||
End Sub
|
|
||||||
Private Sub IUserData_UpdateUserInformation() Implements IUserData.UpdateUserInformation
|
|
||||||
Instance.UpdateUserInformation()
|
|
||||||
End Sub
|
|
||||||
Private Sub IUserData_OpenFolder() Implements IUserData.OpenFolder
|
|
||||||
Instance.OpenFolder()
|
|
||||||
End Sub
|
|
||||||
Private Sub IUserData_OpenSite() Implements IContentProvider.OpenSite
|
|
||||||
Instance.OpenSite()
|
|
||||||
End Sub
|
|
||||||
Private Sub IUserData_DownloadData(ByVal Token As CancellationToken) Implements IContentProvider.DownloadData
|
|
||||||
DownloadData(Token, False, Nothing)
|
|
||||||
End Sub
|
|
||||||
Private Function IUserData_GetPicture() As Image Implements IUserData.GetPicture
|
|
||||||
Return Instance.GetPicture()
|
|
||||||
End Function
|
|
||||||
Private Function IUserData_GetLVI(ByVal Destination As ListView) As ListViewItem Implements IUserData.GetLVI
|
|
||||||
Return Instance.GetLVI(Destination)
|
|
||||||
End Function
|
|
||||||
Private Function IUserData_GetLVIGroup(ByVal Destination As ListView) As ListViewGroup Implements IUserData.GetLVIGroup
|
|
||||||
Return Instance.GetLVIGroup(Destination)
|
|
||||||
End Function
|
|
||||||
Private Function IUserData_Delete() As Integer Implements IUserData.Delete
|
|
||||||
Return DirectCast(Instance, UserDataBase).DeleteF(Me)
|
|
||||||
End Function
|
|
||||||
Private Function IUserData_MoveFiles(ByVal CollectionName As String) As Boolean Implements IUserData.MoveFiles
|
|
||||||
Return DirectCast(Instance, UserDataBase).MoveFilesF(Me, CollectionName)
|
|
||||||
End Function
|
|
||||||
#End Region
|
|
||||||
Private _Name As String = String.Empty
|
|
||||||
Friend Property Name As String Implements IUserData.Name
|
|
||||||
Get
|
|
||||||
If IsRegularChannel Then
|
|
||||||
Return Instance.Name
|
|
||||||
Else
|
|
||||||
Return _Name
|
|
||||||
End If
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewName As String)
|
|
||||||
If IsRegularChannel Then
|
|
||||||
Instance.Name = NewName
|
|
||||||
Else
|
|
||||||
_Name = NewName
|
|
||||||
End If
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private _ID As String = String.Empty
|
|
||||||
Friend Property ID As String Implements IUserData.ID
|
|
||||||
Get
|
|
||||||
If IsRegularChannel Then
|
|
||||||
Return Instance.ID
|
|
||||||
Else
|
|
||||||
Return _ID
|
|
||||||
End If
|
|
||||||
End Get
|
|
||||||
Set(ByVal NewID As String)
|
|
||||||
If IsRegularChannel Then
|
|
||||||
Instance.ID = NewID
|
|
||||||
Else
|
|
||||||
_ID = NewID
|
|
||||||
End If
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Friend ReadOnly Property CUser As UserInfo
|
Friend ReadOnly Property CUser As UserInfo
|
||||||
Get
|
Get
|
||||||
Return New UserInfo(Me)
|
Return New UserInfo(Me)
|
||||||
@@ -313,17 +73,30 @@ Namespace API.Reddit
|
|||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
Private ReadOnly Property Range As RangeSwitcher(Of UserPost)
|
Private ReadOnly Property Range As RangeSwitcher(Of UserPost)
|
||||||
Friend ReadOnly Property CountOfAddedUsers As List(Of Integer)
|
#Region "Statistics support"
|
||||||
Friend ReadOnly Property CountOfLoadedPostsPerSession As List(Of Integer)
|
Private ReadOnly CountOfAddedUsers As List(Of Integer)
|
||||||
|
Private ReadOnly CountOfLoadedPostsPerSession As List(Of Integer)
|
||||||
|
Friend ReadOnly Property ChannelExistentUserNames As List(Of String)
|
||||||
Private _FirstUserAdded As Boolean = False
|
Private _FirstUserAdded As Boolean = False
|
||||||
Friend Sub UserAdded(Optional ByVal IsAdded As Boolean = True)
|
Friend Sub UserAdded(ByVal UserName As String, Optional ByVal IsAdded As Boolean = True)
|
||||||
If Not _FirstUserAdded Then CountOfAddedUsers.Add(0) : _FirstUserAdded = True
|
If Not _FirstUserAdded Then CountOfAddedUsers.Add(0) : _FirstUserAdded = True
|
||||||
Dim v% = CountOfAddedUsers.Last
|
Dim v% = CountOfAddedUsers.Last
|
||||||
v += IIf(IsAdded, 1, -1)
|
v += IIf(IsAdded, 1, -1)
|
||||||
If v < 0 Then v = 0
|
If v < 0 Then v = 0
|
||||||
CountOfAddedUsers(CountOfAddedUsers.Count - 1) = v
|
CountOfAddedUsers(CountOfAddedUsers.Count - 1) = v
|
||||||
|
If Not ChannelExistentUserNames.Contains(UserName) Then ChannelExistentUserNames.Add(UserName)
|
||||||
|
End Sub
|
||||||
|
Friend Sub UpdateUsersStats()
|
||||||
|
If Posts.Count > 0 Or PostsLatest.Count > 0 Then
|
||||||
|
ChannelExistentUserNames.ListAddList((From p As UserPost In PostsAll
|
||||||
|
Where Not p.UserID.IsEmptyString AndAlso
|
||||||
|
Settings.UsersList.Exists(Function(u) u.Site = Site And u.Name = p.UserID)
|
||||||
|
Select p.UserID), LAP.NotContainsOnly)
|
||||||
|
ChannelExistentUserNames.RemoveAll(Function(u) Not Settings.UsersList.Exists(Function(uu) uu.Site = Site And uu.Name = u))
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Friend Function GetChannelStats(ByVal Extended As Boolean) As String
|
Friend Function GetChannelStats(ByVal Extended As Boolean) As String
|
||||||
|
UpdateUsersStats()
|
||||||
Dim s$ = String.Empty
|
Dim s$ = String.Empty
|
||||||
Dim p As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
Dim p As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||||
If Extended Then
|
If Extended Then
|
||||||
@@ -332,12 +105,15 @@ Namespace API.Reddit
|
|||||||
s.StringAppendLine($"Users added from this channel (session): {CountOfAddedUsers.LastOrDefault.NumToString(p)}")
|
s.StringAppendLine($"Users added from this channel (session): {CountOfAddedUsers.LastOrDefault.NumToString(p)}")
|
||||||
s.StringAppendLine($"Posts downloaded (avg): {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)}")
|
s.StringAppendLine($"Posts downloaded (avg): {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)}")
|
||||||
s.StringAppendLine($"Posts downloaded (session): {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)}")
|
s.StringAppendLine($"Posts downloaded (session): {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)}")
|
||||||
|
s.StringAppendLine($"My users in this channel: {ChannelExistentUserNames.Count.NumToString(p)}")
|
||||||
Else
|
Else
|
||||||
s.StringAppend($"Users: {CountOfAddedUsers.Sum.NumToString(p)} (avg: {CountOfAddedUsers.DefaultIfEmpty(0).Average.RoundDown.NumToString(p)}; s: {CountOfAddedUsers.LastOrDefault.NumToString(p)})")
|
s.StringAppend($"Users: {CountOfAddedUsers.Sum.NumToString(p)} (avg: {CountOfAddedUsers.DefaultIfEmpty(0).Average.RoundDown.NumToString(p)}; s: {CountOfAddedUsers.LastOrDefault.NumToString(p)})")
|
||||||
s.StringAppend($"Posts: {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)} (s: {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)})", "; ")
|
s.StringAppend($"Posts: {CountOfLoadedPostsPerSession.DefaultIfEmpty(0).Average.RoundUp.NumToString(p)} (s: {CountOfLoadedPostsPerSession.LastOrDefault.NumToString(p)})", "; ")
|
||||||
|
s.StringAppend($"My users: {ChannelExistentUserNames.Count.NumToString(p)}", "; ")
|
||||||
End If
|
End If
|
||||||
Return s
|
Return s
|
||||||
End Function
|
End Function
|
||||||
|
#End Region
|
||||||
#Region "Limits Support"
|
#Region "Limits Support"
|
||||||
Private _DownloadLimitCount As Integer? = Nothing
|
Private _DownloadLimitCount As Integer? = Nothing
|
||||||
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
||||||
@@ -401,31 +177,23 @@ Namespace API.Reddit
|
|||||||
End Sub
|
End Sub
|
||||||
Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits
|
Friend Property AutoGetLimits As Boolean = True Implements IChannelLimits.AutoGetLimits
|
||||||
#End Region
|
#End Region
|
||||||
Friend ReadOnly IsRegularChannel As Boolean = False
|
Friend ReadOnly Property HOST As SettingsHost
|
||||||
Friend Sub New()
|
Friend Sub New()
|
||||||
Posts = New List(Of UserPost)
|
Posts = New List(Of UserPost)
|
||||||
PostsLatest = New List(Of UserPost)
|
PostsLatest = New List(Of UserPost)
|
||||||
Range = New RangeSwitcher(Of UserPost)(Me)
|
Range = New RangeSwitcher(Of UserPost)(Me)
|
||||||
CountOfAddedUsers = New List(Of Integer)
|
CountOfAddedUsers = New List(Of Integer)
|
||||||
CountOfLoadedPostsPerSession = New List(Of Integer)
|
CountOfLoadedPostsPerSession = New List(Of Integer)
|
||||||
|
ChannelExistentUserNames = New List(Of String)
|
||||||
|
HOST = Settings(RedditSiteKey)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal f As SFile)
|
Friend Sub New(ByVal f As SFile)
|
||||||
Me.New
|
Me.New
|
||||||
LoadData(f, False)
|
LoadData(f, False)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
|
||||||
Me.New
|
|
||||||
Instance = New UserData(u, _LoadUserInformation) With {.SaveToCache = False, .SkipExistsUsers = False, .ChannelInfo = Me}
|
|
||||||
AutoGetLimits = True
|
|
||||||
DirectCast(Instance, UserData).SetLimit(Me)
|
|
||||||
IsRegularChannel = True
|
|
||||||
End Sub
|
|
||||||
Public Shared Widening Operator CType(ByVal f As SFile) As Channel
|
Public Shared Widening Operator CType(ByVal f As SFile) As Channel
|
||||||
Return New Channel(f)
|
Return New Channel(f)
|
||||||
End Operator
|
End Operator
|
||||||
Public Shared Widening Operator CType(ByVal c As Channel) As UserDataBase
|
|
||||||
Return DirectCast(c.Instance, UserDataBase)
|
|
||||||
End Operator
|
|
||||||
Public Overrides Function ToString() As String
|
Public Overrides Function ToString() As String
|
||||||
If Not Name.IsEmptyString Then
|
If Not Name.IsEmptyString Then
|
||||||
Return Name
|
Return Name
|
||||||
@@ -434,21 +202,20 @@ Namespace API.Reddit
|
|||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Friend Sub Delete()
|
Friend Sub Delete()
|
||||||
If File.Exists Then File.Delete()
|
File.Delete(, SFODelete.DeleteToRecycleBin)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub DownloadData(ByVal Token As CancellationToken, Optional ByVal SkipExists As Boolean = True,
|
Friend Sub DownloadData(ByVal Token As CancellationToken, Optional ByVal SkipExists As Boolean = True,
|
||||||
Optional ByVal p As MyProgress = Nothing)
|
Optional ByVal p As MyProgress = Nothing)
|
||||||
Try
|
Try
|
||||||
_Downloading = True
|
_Downloading = True
|
||||||
If Not Instance Is Nothing Then
|
Using d As New UserData With {
|
||||||
Instance.DownloadData(Token)
|
|
||||||
Else
|
|
||||||
Using d As New UserData(CUser, False, False) With {
|
|
||||||
.Progress = p,
|
.Progress = p,
|
||||||
.SaveToCache = True,
|
.SaveToCache = True,
|
||||||
.SkipExistsUsers = SkipExists,
|
.SkipExistsUsers = SkipExists,
|
||||||
.ChannelInfo = Me
|
.ChannelInfo = Me
|
||||||
}
|
}
|
||||||
|
d.SetEnvironment(HOST, CUser, False)
|
||||||
|
d.RemoveUpdateHandlers()
|
||||||
d.SetLimit(Me)
|
d.SetLimit(Me)
|
||||||
d.DownloadData(Token)
|
d.DownloadData(Token)
|
||||||
Dim b% = Posts.Count
|
Dim b% = Posts.Count
|
||||||
@@ -456,8 +223,8 @@ Namespace API.Reddit
|
|||||||
If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b)
|
If Posts.Count - b > 0 Then CountOfLoadedPostsPerSession.Add(Posts.Count - b)
|
||||||
Posts.Sort()
|
Posts.Sort()
|
||||||
LatestParsedDate = If(Posts.FirstOrDefault(Function(pp) pp.Date.HasValue).Date, LatestParsedDate)
|
LatestParsedDate = If(Posts.FirstOrDefault(Function(pp) pp.Date.HasValue).Date, LatestParsedDate)
|
||||||
|
UpdateUsersStats()
|
||||||
End Using
|
End Using
|
||||||
End If
|
|
||||||
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
Finally
|
Finally
|
||||||
_Downloading = False
|
_Downloading = False
|
||||||
@@ -498,21 +265,12 @@ Namespace API.Reddit
|
|||||||
Friend Overloads Function Equals(ByVal Other As Channel) As Boolean Implements IEquatable(Of Channel).Equals
|
Friend Overloads Function Equals(ByVal Other As Channel) As Boolean Implements IEquatable(Of Channel).Equals
|
||||||
Return ID = Other.ID
|
Return ID = Other.ID
|
||||||
End Function
|
End Function
|
||||||
Private Overloads Function Equals(ByVal Other As UserDataBase) As Boolean Implements IEquatable(Of UserDataBase).Equals
|
|
||||||
If Not Instance Is Nothing Then
|
|
||||||
Return Instance.Equals(Other)
|
|
||||||
Else
|
|
||||||
Return False
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
|
Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||||
If Not Obj Is Nothing Then
|
If Not Obj Is Nothing Then
|
||||||
If TypeOf Obj Is String Then
|
If TypeOf Obj Is String Then
|
||||||
Return ID = CStr(Obj)
|
Return ID = CStr(Obj)
|
||||||
ElseIf TypeOf Obj Is Channel Then
|
ElseIf TypeOf Obj Is Channel Then
|
||||||
Return Equals(DirectCast(Obj, Channel))
|
Return Equals(DirectCast(Obj, Channel))
|
||||||
ElseIf TypeOf Obj Is UserDataBase Then
|
|
||||||
Return Equals(DirectCast(Obj, UserDataBase))
|
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Return False
|
Return False
|
||||||
@@ -526,22 +284,6 @@ Namespace API.Reddit
|
|||||||
Return ID.CompareTo(Other.ID)
|
Return ID.CompareTo(Other.ID)
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
Private Overloads Function CompareTo(ByVal Other As UserDataBase) As Integer Implements IComparable(Of UserDataBase).CompareTo
|
|
||||||
If Not Instance Is Nothing Then
|
|
||||||
Return Instance.CompareTo(Other)
|
|
||||||
Else
|
|
||||||
Return 0
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
Private Overloads Function CompareTo(ByVal Obj As Object) As Integer Implements IComparable.CompareTo
|
|
||||||
If TypeOf Obj Is Channel Then
|
|
||||||
Return CompareTo(DirectCast(Obj, Channel))
|
|
||||||
ElseIf TypeOf Obj Is UserDataBase And Not Instance Is Nothing Then
|
|
||||||
Return Instance.CompareTo(Obj)
|
|
||||||
Else
|
|
||||||
Return 0
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
#End Region
|
#End Region
|
||||||
#Region "ILoaderSaver Support"
|
#Region "ILoaderSaver Support"
|
||||||
Friend Overloads Function LoadData(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Load
|
Friend Overloads Function LoadData(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Load
|
||||||
@@ -553,11 +295,13 @@ Namespace API.Reddit
|
|||||||
x.LoadData()
|
x.LoadData()
|
||||||
If x.Count > 0 Then
|
If x.Count > 0 Then
|
||||||
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||||
|
Dim lc As New ListAddParams(LAP.ClearBeforeAdd)
|
||||||
Name = x.Value(Name_Name)
|
Name = x.Value(Name_Name)
|
||||||
ID = x.Value(Name_ID)
|
ID = x.Value(Name_ID)
|
||||||
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing)
|
LatestParsedDate = AConvert(Of Date)(x.Value(Name_Date), XMLDateProvider, Nothing)
|
||||||
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), LAP.ClearBeforeAdd)
|
CountOfAddedUsers.ListAddList(x.Value(Name_UsersAdded).StringToList(Of Integer)("|"), lc)
|
||||||
CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), LAP.ClearBeforeAdd)
|
CountOfLoadedPostsPerSession.ListAddList(x.Value(Name_PostsDownloaded).StringToList(Of Integer)("|"), lc)
|
||||||
|
ChannelExistentUserNames.ListAddList(x.Value(Name_UsersExistent).StringToList(Of String)("|"), LNC)
|
||||||
If Not PartialLoad Then
|
If Not PartialLoad Then
|
||||||
With x(Name_PostsNode).XmlIfNothing
|
With x(Name_PostsNode).XmlIfNothing
|
||||||
If .Count > 0 Then .ForEach(Sub(ee) PostsLatest.Add(New UserPost With {
|
If .Count > 0 Then .ForEach(Sub(ee) PostsLatest.Add(New UserPost With {
|
||||||
@@ -572,6 +316,7 @@ Namespace API.Reddit
|
|||||||
End Function
|
End Function
|
||||||
Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save
|
Friend Overloads Function Save(Optional ByVal f As SFile = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Boolean Implements ILoaderSaver.Save
|
||||||
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
Dim XMLDateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||||
|
UpdateUsersStats()
|
||||||
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"}
|
Using x As New XmlFile With {.AllowSameNames = True, .Name = "Channel"}
|
||||||
x.Add(Name_Name, Name)
|
x.Add(Name_Name, Name)
|
||||||
x.Add(Name_ID, ID)
|
x.Add(Name_ID, ID)
|
||||||
@@ -584,6 +329,7 @@ Namespace API.Reddit
|
|||||||
x.Add(Name_PostsNode, String.Empty)
|
x.Add(Name_PostsNode, String.Empty)
|
||||||
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString(, "|"))
|
x.Add(Name_UsersAdded, CountOfAddedUsers.ListToString(, "|"))
|
||||||
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString(, "|"))
|
x.Add(Name_PostsDownloaded, CountOfLoadedPostsPerSession.ListToString(, "|"))
|
||||||
|
x.Add(Name_UsersExistent, ChannelExistentUserNames.ListToString(, "|"))
|
||||||
With x(Name_PostsNode)
|
With x(Name_PostsNode)
|
||||||
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
|
tmpPostList.Take(200).ToList.ForEach(Sub(p) .Add(New EContainer("Post",
|
||||||
String.Empty,
|
String.Empty,
|
||||||
@@ -603,11 +349,6 @@ Namespace API.Reddit
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "IDisposable Support"
|
#Region "IDisposable Support"
|
||||||
Private disposedValue As Boolean = False
|
Private disposedValue As Boolean = False
|
||||||
Friend ReadOnly Property Disposed As Boolean Implements IUserData.Disposed
|
|
||||||
Get
|
|
||||||
Return disposedValue
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
If Not disposedValue Then
|
If Not disposedValue Then
|
||||||
If disposing Then
|
If disposing Then
|
||||||
@@ -616,8 +357,8 @@ Namespace API.Reddit
|
|||||||
CountOfAddedUsers.Clear()
|
CountOfAddedUsers.Clear()
|
||||||
CountOfLoadedPostsPerSession.Clear()
|
CountOfLoadedPostsPerSession.Clear()
|
||||||
Range.Dispose()
|
Range.Dispose()
|
||||||
If Not Instance Is Nothing Then Instance.Dispose()
|
ChannelExistentUserNames.Clear()
|
||||||
If CachePath.Exists(SFO.Path, False) Then CachePath.Delete(SFO.Path, False, False, EDP.SendInLog)
|
CachePath.Delete(SFO.Path, SFODelete.None, EDP.SendInLog)
|
||||||
End If
|
End If
|
||||||
disposedValue = True
|
disposedValue = True
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -15,15 +15,39 @@ Namespace API.Reddit
|
|||||||
Friend Shared ReadOnly Property ChannelsPath As SFile = $"{SettingsFolderName}\Channels\"
|
Friend Shared ReadOnly Property ChannelsPath As SFile = $"{SettingsFolderName}\Channels\"
|
||||||
Friend Shared ReadOnly Property ChannelsPathCache As SFile = $"{Settings.GlobalPath.Value.PathWithSeparator}_CachedData\"
|
Friend Shared ReadOnly Property ChannelsPathCache As SFile = $"{Settings.GlobalPath.Value.PathWithSeparator}_CachedData\"
|
||||||
Private ReadOnly Channels As List(Of Channel)
|
Private ReadOnly Channels As List(Of Channel)
|
||||||
|
Friend Structure ChannelImage : Implements IEquatable(Of ChannelImage)
|
||||||
|
Friend File As SFile
|
||||||
|
Friend Channel As String
|
||||||
|
Friend Sub New(ByVal ChannelName As String, ByVal f As SFile)
|
||||||
|
Channel = ChannelName
|
||||||
|
File = f
|
||||||
|
End Sub
|
||||||
|
Friend Overloads Function Equals(ByVal Other As ChannelImage) As Boolean Implements IEquatable(Of ChannelImage).Equals
|
||||||
|
Return Channel = Other.Channel And File.File = Other.File.File
|
||||||
|
End Function
|
||||||
|
Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||||
|
Return Equals(DirectCast(Obj, ChannelImage))
|
||||||
|
End Function
|
||||||
|
End Structure
|
||||||
Friend ReadOnly Property Downloading As Boolean
|
Friend ReadOnly Property Downloading As Boolean
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
Return Count > 0 AndAlso Channels.Exists(Function(c) c.Downloading)
|
||||||
Return Channels.Exists(Function(c) c.Downloading)
|
|
||||||
Else
|
|
||||||
Return False
|
|
||||||
End If
|
|
||||||
End Get
|
End Get
|
||||||
End Property
|
End Property
|
||||||
|
Friend Function GetUserFiles(ByVal UserName As String) As IEnumerable(Of ChannelImage)
|
||||||
|
Try
|
||||||
|
If Settings.ChannelsAddUserImagesFromAllChannels.Value And Count > 0 Then
|
||||||
|
Return Channels.SelectMany(Function(c) From p As UserPost In c.Posts Where p.UserID = UserName Select New ChannelImage(c.Name, p.CachedFile))
|
||||||
|
Else
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Friend Sub UpdateUsersStats()
|
||||||
|
If Channels.Count > 0 Then Channels.ForEach(Sub(c) c.UpdateUsersStats())
|
||||||
|
End Sub
|
||||||
#Region "Limits Support"
|
#Region "Limits Support"
|
||||||
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
||||||
<Obsolete("This property cannot be used in collections", True)> Private Property DownloadLimitPost As String Implements IChannelLimits.DownloadLimitPost
|
<Obsolete("This property cannot be used in collections", True)> Private Property DownloadLimitPost As String Implements IChannelLimits.DownloadLimitPost
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ Imports PersonalUtilities.Functions.XML.Base
|
|||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Namespace API.Reddit
|
Namespace API.Reddit
|
||||||
Friend Module Declarations
|
Friend Module Declarations
|
||||||
|
Friend Const RedditSite As String = "Reddit"
|
||||||
|
Friend Const RedditSiteKey As String = "AndyProgram_Reddit"
|
||||||
Friend ReadOnly JsonNodesJson() As NodeParams = {New NodeParams("posts", True, True, True, True, 3)}
|
Friend ReadOnly JsonNodesJson() As NodeParams = {New NodeParams("posts", True, True, True, True, 3)}
|
||||||
Friend ReadOnly ChannelJsonNodes() As NodeParams = {New NodeParams("data", True, True, True, True, 1),
|
Friend ReadOnly ChannelJsonNodes() As NodeParams = {New NodeParams("data", True, True, True, True, 1),
|
||||||
New NodeParams("children", True, True, True)}
|
New NodeParams("children", True, True, True)}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ Namespace API.Reddit
|
|||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Return ErrorsDescriber.Execute(DPED, ex, "[M3U8.Save]", New SFile)
|
Return ErrorsDescriber.Execute(DPED, ex, "[M3U8.Save]", New SFile)
|
||||||
Finally
|
Finally
|
||||||
If Not CachePath.IsEmptyString AndAlso CachePath.Exists(SFO.Path, False) Then CachePath.Delete(SFO.Path, False, False, DPED)
|
CachePath.Delete(SFO.Path, SFODelete.None, DPED)
|
||||||
End Try
|
End Try
|
||||||
End Function
|
End Function
|
||||||
Friend Shared Function Download(ByVal URL As String, ByVal f As SFile) As SFile
|
Friend Shared Function Download(ByVal URL As String, ByVal f As SFile) As SFile
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
Imports SCrawler.API.Base
|
|
||||||
Imports System.Threading
|
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
|
||||||
Namespace API.Reddit
|
|
||||||
Friend NotInheritable Class ProfileSaved
|
|
||||||
Friend Shared ReadOnly Property DataPath As SFile = Settings(Sites.Reddit).SavedPostsPath
|
|
||||||
Private Sub New()
|
|
||||||
End Sub
|
|
||||||
Friend Shared Sub Download(ByRef Bar As MyProgress, ByVal Token As CancellationToken)
|
|
||||||
Try
|
|
||||||
Dim u As New UserInfo(Settings(Sites.Reddit).SavedPostsUserName.Value, Sites.Reddit) With {.IsChannel = True, .SpecialPath = DataPath}
|
|
||||||
u.UpdateUserFile()
|
|
||||||
Using user As New UserData(u,, False)
|
|
||||||
DirectCast(user.Self, UserDataBase).IsSavedPosts = True
|
|
||||||
user.Progress = Bar
|
|
||||||
If Not user.FileExists Then user.UpdateUserInformation()
|
|
||||||
user.DownloadData(Token)
|
|
||||||
Bar.InformationTemporary = $"Images: {user.DownloadedPictures}; Videos: {user.DownloadedVideos}"
|
|
||||||
End Using
|
|
||||||
Catch ex As Exception
|
|
||||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[API.Reddit.ProfileSaved.Download]")
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
End Namespace
|
|
||||||
97
SCrawler/API/Reddit/SiteSettings.vb
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Attributes
|
||||||
|
Imports PersonalUtilities.Tools
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports DownDetector = SCrawler.API.Base.DownDetector
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Namespace API.Reddit
|
||||||
|
<Manifest(RedditSiteKey), UseClassAsIs, SavedPosts>
|
||||||
|
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||||
|
Friend Overrides ReadOnly Property Icon As Icon
|
||||||
|
Get
|
||||||
|
Return My.Resources.RedditIcon
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Overrides ReadOnly Property Image As Image
|
||||||
|
Get
|
||||||
|
Return My.Resources.RedditPic512
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
<PropertyOption(ControlText:="Saved posts user"), PXML("SavedPostsUserName")>
|
||||||
|
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||||
|
Friend Overrides ReadOnly Property Responser As WEB.Response
|
||||||
|
Friend Sub New()
|
||||||
|
MyBase.New(RedditSite)
|
||||||
|
Responser = New WEB.Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||||
|
|
||||||
|
With Responser
|
||||||
|
If .File.Exists Then
|
||||||
|
.LoadSettings()
|
||||||
|
Else
|
||||||
|
.CookiesDomain = "reddit.com"
|
||||||
|
.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
||||||
|
.SaveSettings()
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
|
||||||
|
UrlPatternUser = "https://www.reddit.com/user/{0}/"
|
||||||
|
UrlPatternChannel = "https://www.reddit.com/r/{0}/"
|
||||||
|
ImageVideoContains = "redgifs"
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function GetInstance(ByVal What As Download) As IPluginContentProvider
|
||||||
|
Select Case What
|
||||||
|
Case Download.Main : Return New UserData
|
||||||
|
Case Download.Channel : Return New UserData With {.SaveToCache = False, .SkipExistsUsers = False, .AutoGetLimits = True}
|
||||||
|
Case Download.SavedPosts
|
||||||
|
Dim u As New UserData With {.IsSavedPosts = True}
|
||||||
|
DirectCast(u, UserDataBase).User = New UserInfo With {.Name = CStr(AConvert(Of String)(SavedPostsUserName.Value, String.Empty))}
|
||||||
|
Return u
|
||||||
|
End Select
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Private ReadOnly RedditRegEx1 As RParams = RParams.DMS("[htps:/]{7,8}.*?reddit.com/user/([^/]+)", 1)
|
||||||
|
Private ReadOnly RedditRegEx2 As RParams = RParams.DMS(".?u/([^/]+)", 1)
|
||||||
|
Private ReadOnly RedditChannelRegEx1 As RParams = RParams.DMS("[htps:/]{7,8}.*?reddit.com/r/([^/]+)", 1)
|
||||||
|
Private ReadOnly RedditChannelRegEx2 As RParams = RParams.DMS(".?r/([^/]+)", 1)
|
||||||
|
Friend Overrides Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
|
||||||
|
Dim s$
|
||||||
|
Dim c% = 0
|
||||||
|
For Each r As RParams In {RedditRegEx1, RedditRegEx2, RedditChannelRegEx1, RedditChannelRegEx2}
|
||||||
|
s = RegexReplace(UserURL, r)
|
||||||
|
If Not s.IsEmptyString Then Return New ExchangeOptions(Site, s, c > 1)
|
||||||
|
c += 1
|
||||||
|
Next
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function Available(ByVal What As Download) As Boolean
|
||||||
|
Try
|
||||||
|
Dim dl As List(Of DownDetector.Data) = DownDetector.GetData("reddit")
|
||||||
|
If dl.ListExists Then
|
||||||
|
dl = dl.Take(4).ToList
|
||||||
|
Dim avg% = dl.Average(Function(d) d.Value)
|
||||||
|
If avg > 100 Then
|
||||||
|
Return MsgBoxE({"Over the past hour, Reddit has received an average of " &
|
||||||
|
avg.NumToString(New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}) & " outage reports:" & vbCr &
|
||||||
|
dl.ListToString(, vbCr) & vbCr & vbCr &
|
||||||
|
"Do you want to continue parsing Reddit data?", "There are outage reports on Reddit"}, vbYesNo) = vbYes
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return True
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendInLog + EDP.ReturnValue, ex, "[API.Reddit.SiteSettings.Available]", True)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Return UserData.GetVideoInfo(URL, Responser)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Imports PersonalUtilities.Tools.ImageRenderer
|
Imports PersonalUtilities.Tools.ImageRenderer
|
||||||
|
Imports PersonalUtilities.Tools.WEB
|
||||||
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
Imports PersonalUtilities.Tools.WebDocuments.JSON
|
||||||
Imports System.Net
|
Imports System.Net
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
@@ -17,7 +18,11 @@ Imports UStates = SCrawler.API.Base.UserMedia.States
|
|||||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
Namespace API.Reddit
|
Namespace API.Reddit
|
||||||
Friend Class UserData : Inherits UserDataBase : Implements IChannelData
|
Friend Class UserData : Inherits UserDataBase : Implements IChannelData
|
||||||
Friend Overrides Property Site As Sites = Sites.Reddit
|
Private ReadOnly Property MySiteSettings As SiteSettings
|
||||||
|
Get
|
||||||
|
Return DirectCast(HOST.Source, SiteSettings)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
#Region "Channels Support"
|
#Region "Channels Support"
|
||||||
#Region "IChannelLimits Support"
|
#Region "IChannelLimits Support"
|
||||||
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
Friend Property DownloadLimitCount As Integer? Implements IChannelLimits.DownloadLimitCount
|
||||||
@@ -50,22 +55,12 @@ Namespace API.Reddit
|
|||||||
Select c.Post) Else Return Nothing
|
Select c.Post) Else Return Nothing
|
||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Initializers"
|
#Region "Initializer"
|
||||||
''' <summary>Video downloader initializer</summary>
|
Friend Sub New()
|
||||||
Private Sub New()
|
|
||||||
ChannelPostsNames = New List(Of String)
|
ChannelPostsNames = New List(Of String)
|
||||||
_ExistsUsersNames = New List(Of String)
|
_ExistsUsersNames = New List(Of String)
|
||||||
_CrossPosts = New List(Of String)
|
_CrossPosts = New List(Of String)
|
||||||
End Sub
|
End Sub
|
||||||
''' <summary>Default initializer</summary>
|
|
||||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True, Optional ByVal InvokeImageHandler As Boolean = True)
|
|
||||||
MyBase.New(InvokeImageHandler)
|
|
||||||
ChannelPostsNames = New List(Of String)
|
|
||||||
_ExistsUsersNames = New List(Of String)
|
|
||||||
_CrossPosts = New List(Of String)
|
|
||||||
User = u
|
|
||||||
If _LoadUserInformation Then LoadUserInformation()
|
|
||||||
End Sub
|
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Load and Update user info"
|
#Region "Load and Update user info"
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
@@ -73,11 +68,12 @@ Namespace API.Reddit
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "Download Overrides"
|
#Region "Download Overrides"
|
||||||
Friend Overrides Sub DownloadData(ByVal Token As CancellationToken)
|
Friend Overrides Sub DownloadData(ByVal Token As CancellationToken)
|
||||||
|
UserDescriptionReset()
|
||||||
_CrossPosts.Clear()
|
_CrossPosts.Clear()
|
||||||
If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo.IsRegularChannel) Then
|
If Not IsSavedPosts AndAlso (IsChannel AndAlso Not ChannelInfo Is Nothing) Then
|
||||||
If Not Responser Is Nothing Then Responser.Dispose()
|
If Not Responser Is Nothing Then Responser.Dispose()
|
||||||
Responser = New PersonalUtilities.Tools.WEB.Response
|
Responser = New Response
|
||||||
Responser.Copy(Settings(Sites.Reddit).Responser)
|
Responser.Copy(MySiteSettings.Responser)
|
||||||
ChannelPostsNames.ListAddList(ChannelInfo.PostsAll.Select(Function(p) p.ID), LNC)
|
ChannelPostsNames.ListAddList(ChannelInfo.PostsAll.Select(Function(p) p.ID), LNC)
|
||||||
If SkipExistsUsers Then _ExistsUsersNames.ListAddList(Settings.UsersList.Select(Function(p) p.Name), LNC)
|
If SkipExistsUsers Then _ExistsUsersNames.ListAddList(Settings.UsersList.Select(Function(p) p.Name), LNC)
|
||||||
DownloadDataF(Token)
|
DownloadDataF(Token)
|
||||||
@@ -93,7 +89,7 @@ Namespace API.Reddit
|
|||||||
If IsSavedPosts Then
|
If IsSavedPosts Then
|
||||||
DownloadDataChannel(String.Empty, Token)
|
DownloadDataChannel(String.Empty, Token)
|
||||||
ElseIf IsChannel Then
|
ElseIf IsChannel Then
|
||||||
If ChannelInfo.IsRegularChannel Then
|
If ChannelInfo Is Nothing Then
|
||||||
ChannelPostsNames.ListAddList(_TempPostsList, LNC)
|
ChannelPostsNames.ListAddList(_TempPostsList, LNC)
|
||||||
If ChannelPostsNames.Count > 0 Then
|
If ChannelPostsNames.Count > 0 Then
|
||||||
DownloadLimitCount = Nothing
|
DownloadLimitCount = Nothing
|
||||||
@@ -104,7 +100,7 @@ Namespace API.Reddit
|
|||||||
If DownloadTopCount.HasValue Then DownloadLimitCount = DownloadTopCount
|
If DownloadTopCount.HasValue Then DownloadLimitCount = DownloadTopCount
|
||||||
End If
|
End If
|
||||||
DownloadDataChannel(String.Empty, Token)
|
DownloadDataChannel(String.Empty, Token)
|
||||||
If ChannelInfo.IsRegularChannel Then _TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC)
|
If ChannelInfo Is Nothing Then _TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC)
|
||||||
Else
|
Else
|
||||||
DownloadDataUser(String.Empty, Token)
|
DownloadDataUser(String.Empty, Token)
|
||||||
End If
|
End If
|
||||||
@@ -138,6 +134,7 @@ Namespace API.Reddit
|
|||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||||
If w.Count > 0 Then
|
If w.Count > 0 Then
|
||||||
|
If UserDescriptionNeedToUpdate() Then UserDescriptionUpdate(w.ItemF({"subredditAboutInfo", 0, "publicDescription"}).XmlIfNothingValue)
|
||||||
n = w.GetNode(JsonNodesJson)
|
n = w.GetNode(JsonNodesJson)
|
||||||
If Not n Is Nothing AndAlso n.Count > 0 Then
|
If Not n Is Nothing AndAlso n.Count > 0 Then
|
||||||
For Each nn In n
|
For Each nn In n
|
||||||
@@ -170,7 +167,7 @@ Namespace API.Reddit
|
|||||||
_ItemsBefore = _TempMediaList.Count
|
_ItemsBefore = _TempMediaList.Count
|
||||||
added = True
|
added = True
|
||||||
s = nn.ItemF({"source", "url"})
|
s = nn.ItemF({"source", "url"})
|
||||||
If s.XmlIfNothingValue("/").Contains("redgifs.com") Then
|
If s.XmlIfNothingValue("/").StringContains({"redgifs.com", "gfycat.com"}) Then
|
||||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.VideoPre, s.Value, _PostID(), PostDate,, IsChannel), LNC)
|
_TempMediaList.ListAddValue(MediaFromData(UTypes.VideoPre, s.Value, _PostID(), PostDate,, IsChannel), LNC)
|
||||||
ElseIf Not CreateImgurMedia(s.XmlIfNothingValue, _PostID(), PostDate,, IsChannel) Then
|
ElseIf Not CreateImgurMedia(s.XmlIfNothingValue, _PostID(), PostDate,, IsChannel) Then
|
||||||
s = nn.ItemF({"media"}).XmlIfNothing
|
s = nn.ItemF({"media"}).XmlIfNothing
|
||||||
@@ -199,7 +196,7 @@ Namespace API.Reddit
|
|||||||
If Not s.IsEmptyString AndAlso TryFile(s.Value) Then
|
If Not s.IsEmptyString AndAlso TryFile(s.Value) Then
|
||||||
With s.Value.ToLower
|
With s.Value.ToLower
|
||||||
Select Case True
|
Select Case True
|
||||||
Case .Contains("redgifs") : tmpType = UTypes.VideoPre
|
Case .Contains("redgifs"), .Contains("gfycat") : tmpType = UTypes.VideoPre
|
||||||
Case .Contains("m3u8") : If Settings.UseM3U8 Then tmpType = UTypes.m3u8
|
Case .Contains("m3u8") : If Settings.UseM3U8 Then tmpType = UTypes.m3u8
|
||||||
Case .Contains(".gif") And TryFile(s.Value) : tmpType = UTypes.GIF
|
Case .Contains(".gif") And TryFile(s.Value) : tmpType = UTypes.GIF
|
||||||
Case TryFile(s.Value) : tmpType = UTypes.Picture
|
Case TryFile(s.Value) : tmpType = UTypes.Picture
|
||||||
@@ -264,13 +261,28 @@ Namespace API.Reddit
|
|||||||
End With
|
End With
|
||||||
If lDate.HasValue AndAlso lDate.Value <= DownloadLimitDate.Value Then Exit Sub
|
If lDate.HasValue AndAlso lDate.Value <= DownloadLimitDate.Value Then Exit Sub
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
If IsSavedPosts Then
|
||||||
|
If Not _TempPostsList.Contains(PostID) Then
|
||||||
NewPostDetected = True
|
NewPostDetected = True
|
||||||
|
_TempPostsList.Add(PostID)
|
||||||
|
Else
|
||||||
|
ExistsDetected = True
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
NewPostDetected = True
|
||||||
|
End If
|
||||||
|
|
||||||
If s.Contains("created") Then PostDate = s("created").Value Else PostDate = String.Empty
|
If s.Contains("created") Then PostDate = s("created").Value Else PostDate = String.Empty
|
||||||
_UserID = s.Value("author")
|
_UserID = s.Value("author")
|
||||||
|
|
||||||
If SkipExistsUsers AndAlso _ExistsUsersNames.Count > 0 AndAlso
|
If SkipExistsUsers AndAlso _ExistsUsersNames.Count > 0 AndAlso
|
||||||
Not _UserID.IsEmptyString AndAlso _ExistsUsersNames.Contains(_UserID) Then Continue For
|
Not _UserID.IsEmptyString AndAlso _ExistsUsersNames.Contains(_UserID) Then
|
||||||
|
If Not IsSavedPosts AndAlso Not ChannelInfo Is Nothing Then _
|
||||||
|
ChannelInfo.ChannelExistentUserNames.ListAddValue(_UserID, LNC)
|
||||||
|
Continue For
|
||||||
|
End If
|
||||||
|
|
||||||
tmpUrl = s.Value("url")
|
tmpUrl = s.Value("url")
|
||||||
If Not tmpUrl.IsEmptyString AndAlso tmpUrl.Contains("redgifs.com") Then
|
If Not tmpUrl.IsEmptyString AndAlso tmpUrl.Contains("redgifs.com") Then
|
||||||
@@ -393,7 +405,15 @@ Namespace API.Reddit
|
|||||||
ThrowAny(Token)
|
ThrowAny(Token)
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Or _TempMediaList(i).Type = v2 Then
|
If _TempMediaList(i).Type = UTypes.VideoPre Or _TempMediaList(i).Type = v2 Then
|
||||||
m = _TempMediaList(i)
|
m = _TempMediaList(i)
|
||||||
If _TempMediaList(i).Type = UTypes.VideoPre Then r = Responser.GetResponse(m.URL,, e) Else r = m.URL
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
||||||
|
If m.URL.Contains("gfycat.com") Then
|
||||||
|
r = Gfycat.Envir.GetVideo(m.URL)
|
||||||
|
Else
|
||||||
|
r = Responser.GetResponse(m.URL,, e)
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
r = m.URL
|
||||||
|
End If
|
||||||
_TempMediaList(i) = New UserMedia
|
_TempMediaList(i) = New UserMedia
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
v = RegexReplace(r, VideoRegEx)
|
v = RegexReplace(r, VideoRegEx)
|
||||||
@@ -410,13 +430,13 @@ Namespace API.Reddit
|
|||||||
ProcessException(ex, Token, "video reparsing error", False)
|
ProcessException(ex, Token, "video reparsing error", False)
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Response) As IEnumerable(Of UserMedia)
|
||||||
Try
|
Try
|
||||||
If Not URL.IsEmptyString AndAlso URL.Contains("redgifs") Then
|
If Not URL.IsEmptyString AndAlso URL.Contains("redgifs") Then
|
||||||
Using r As New UserData
|
Using r As New UserData
|
||||||
r._TempMediaList.Add(MediaFromData(UTypes.VideoPre, URL, String.Empty, String.Empty,, False))
|
r._TempMediaList.Add(MediaFromData(UTypes.VideoPre, URL, String.Empty, String.Empty,, False))
|
||||||
r.Responser = New PersonalUtilities.Tools.WEB.Response
|
r.Responser = New Response
|
||||||
r.Responser.Copy(Settings(Sites.Reddit).Responser)
|
r.Responser.Copy(resp)
|
||||||
r.ReparseVideo(Nothing)
|
r.ReparseVideo(Nothing)
|
||||||
If r._TempMediaList.ListExists Then Return {r._TempMediaList(0)}
|
If r._TempMediaList.ListExists Then Return {r._TempMediaList(0)}
|
||||||
End Using
|
End Using
|
||||||
@@ -465,7 +485,7 @@ Namespace API.Reddit
|
|||||||
If _ContentNew.Count > 0 Then
|
If _ContentNew.Count > 0 Then
|
||||||
MyFile.Exists(SFO.Path)
|
MyFile.Exists(SFO.Path)
|
||||||
Dim MyDir$
|
Dim MyDir$
|
||||||
If Not IsSavedPosts AndAlso (IsChannel And SaveToCache) Then
|
If Not IsSavedPosts AndAlso (IsChannel And SaveToCache And Not ChannelInfo Is Nothing) Then
|
||||||
MyDir = ChannelInfo.CachePath.PathNoSeparator
|
MyDir = ChannelInfo.CachePath.PathNoSeparator
|
||||||
Else
|
Else
|
||||||
MyDir = MyFile.CutPath.PathNoSeparator
|
MyDir = MyFile.CutPath.PathNoSeparator
|
||||||
@@ -584,8 +604,8 @@ Namespace API.Reddit
|
|||||||
End If
|
End If
|
||||||
If Not v.Type = UTypes.m3u8 Or Not f.IsEmptyString Then
|
If Not v.Type = UTypes.m3u8 Or Not f.IsEmptyString Then
|
||||||
Select Case v.Type
|
Select Case v.Type
|
||||||
Case UTypes.Picture : DownloadedPictures += 1 : _CountPictures += 1
|
Case UTypes.Picture : DownloadedPictures(False) += 1
|
||||||
Case UTypes.Video, UTypes.m3u8 : DownloadedVideos += 1 : _CountVideo += 1
|
Case UTypes.Video, UTypes.m3u8 : DownloadedVideos(False) += 1
|
||||||
End Select
|
End Select
|
||||||
If Not IsChannel Or Not SaveToCache Then
|
If Not IsChannel Or Not SaveToCache Then
|
||||||
v.File = ChangeFileNameByProvider(f, v)
|
v.File = ChangeFileNameByProvider(f, v)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Namespace API.RedGifs
|
Namespace API.RedGifs
|
||||||
Friend Module Declarations
|
Friend Module Declarations
|
||||||
|
Friend Const RedGifsSite As String = "RedGifs"
|
||||||
Friend ReadOnly DateProvider As New JsonDate
|
Friend ReadOnly DateProvider As New JsonDate
|
||||||
Friend Class JsonDate : Implements ICustomProvider
|
Friend Class JsonDate : Implements ICustomProvider
|
||||||
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
Friend Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||||
|
|||||||
29
SCrawler/API/Redgifs/SiteSettings.vb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Attributes
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Namespace API.RedGifs
|
||||||
|
<Manifest("AndyProgram_RedGifs"), UseClassAsIs>
|
||||||
|
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||||
|
Friend Sub New()
|
||||||
|
MyBase.New(RedGifsSite, "redgifs.com")
|
||||||
|
UrlPatternUser = "https://www.redgifs.com/users/{0}/"
|
||||||
|
UserRegex = RParams.DMS("[htps:/]{7,8}.*?redgifs.com/users/([^/]+)", 1)
|
||||||
|
ImageVideoContains = "redgifs"
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
|
||||||
|
Return New UserData
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Return Reddit.UserData.GetVideoInfo(URL, Nothing)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -15,10 +15,7 @@ Imports SCrawler.API.Base
|
|||||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
Namespace API.RedGifs
|
Namespace API.RedGifs
|
||||||
Friend Class UserData : Inherits UserDataBase
|
Friend Class UserData : Inherits UserDataBase
|
||||||
Friend Overrides Property Site As Sites = Sites.RedGifs
|
Friend Sub New()
|
||||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
|
||||||
User = u
|
|
||||||
If _LoadUserInformation Then LoadUserInformation()
|
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Imports PersonalUtilities.Functions.XML.Base
|
|||||||
Imports PersonalUtilities.Functions.RegularExpressions
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
Namespace API.Twitter
|
Namespace API.Twitter
|
||||||
Friend Module Declarations
|
Friend Module Declarations
|
||||||
|
Friend Const TwitterSite As String = "Twitter"
|
||||||
Friend DateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
Friend DateProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||||
Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)}
|
Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)}
|
||||||
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
|
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
|
||||||
|
|||||||
99
SCrawler/API/Twitter/SiteSettings.vb
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports SCrawler.Plugin
|
||||||
|
Imports SCrawler.Plugin.Attributes
|
||||||
|
Imports PersonalUtilities.Tools
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Namespace API.Twitter
|
||||||
|
<Manifest("AndyProgram_Twitter"), UseClassAsIs>
|
||||||
|
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||||
|
Friend Const Header_Authorization As String = "authorization"
|
||||||
|
Friend Const Header_Token As String = "x-csrf-token"
|
||||||
|
Friend Overrides ReadOnly Property Icon As Icon
|
||||||
|
Get
|
||||||
|
Return My.Resources.TwitterIcon
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Overrides ReadOnly Property Image As Image
|
||||||
|
Get
|
||||||
|
Return My.Resources.TwitterPic400
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
<PropertyOption(AllowNull:=False, 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")>
|
||||||
|
Private ReadOnly Property Token As PropertyValue
|
||||||
|
Friend Overrides ReadOnly Property Responser As WEB.Response
|
||||||
|
Friend Sub New()
|
||||||
|
MyBase.New(TwitterSite)
|
||||||
|
Responser = New WEB.Response($"{SettingsFolderName}\Responser_{Site}.xml")
|
||||||
|
|
||||||
|
Dim a$ = String.Empty
|
||||||
|
Dim t$ = String.Empty
|
||||||
|
|
||||||
|
With Responser
|
||||||
|
If .File.Exists Then
|
||||||
|
.LoadSettings()
|
||||||
|
With .Headers
|
||||||
|
If .ContainsKey(Header_Authorization) Then a = .Item(Header_Authorization)
|
||||||
|
If .ContainsKey(Header_Token) Then t = .Item(Header_Token)
|
||||||
|
End With
|
||||||
|
Else
|
||||||
|
.ContentType = "application/json"
|
||||||
|
.Accept = "*/*"
|
||||||
|
.CookiesDomain = "twitter.com"
|
||||||
|
.Decoders.Add(SymbolsConverter.Converters.Unicode)
|
||||||
|
With .Headers
|
||||||
|
.Add("sec-ch-ua", " Not;A Brand" & Chr(34) & ";v=" & Chr(34) & "99" & Chr(34) & ", " & Chr(34) &
|
||||||
|
"Google Chrome" & Chr(34) & ";v=" & Chr(34) & "91" & Chr(34) & ", " & Chr(34) & "Chromium" &
|
||||||
|
Chr(34) & ";v=" & Chr(34) & "91" & Chr(34))
|
||||||
|
.Add("sec-ch-ua-mobile", "?0")
|
||||||
|
.Add("sec-fetch-dest", "empty")
|
||||||
|
.Add("sec-fetch-mode", "cors")
|
||||||
|
.Add("sec-fetch-site", "same-origin")
|
||||||
|
.Add(Header_Token, String.Empty)
|
||||||
|
.Add("x-twitter-active-user", "yes")
|
||||||
|
.Add("x-twitter-auth-type", "OAuth2Session")
|
||||||
|
.Add(Header_Authorization, String.Empty)
|
||||||
|
End With
|
||||||
|
.SaveSettings()
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
|
||||||
|
Auth = New PropertyValue(a, GetType(String), Sub(v) ChangeResponserFields(NameOf(Auth), v))
|
||||||
|
Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
|
||||||
|
|
||||||
|
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
|
||||||
|
UrlPatternUser = "https://twitter.com/{0}"
|
||||||
|
ImageVideoContains = "twitter"
|
||||||
|
End Sub
|
||||||
|
Private Sub ChangeResponserFields(ByVal PropName As String, ByVal Value As Object)
|
||||||
|
If Not PropName.IsEmptyString Then
|
||||||
|
Dim f$ = String.Empty
|
||||||
|
Select Case PropName
|
||||||
|
Case NameOf(Auth) : f = Header_Authorization
|
||||||
|
Case NameOf(Token) : f = Header_Token
|
||||||
|
End Select
|
||||||
|
If Not f.IsEmptyString Then
|
||||||
|
If Responser.Headers.Count > 0 AndAlso Responser.Headers.ContainsKey(f) Then Responser.Headers.Remove(f)
|
||||||
|
If Not CStr(Value).IsEmptyString Then Responser.Headers.Add(f, CStr(Value))
|
||||||
|
Responser.SaveSettings()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Friend Overrides Function GetInstance(ByVal What As ISiteSettings.Download) As IPluginContentProvider
|
||||||
|
Return New UserData
|
||||||
|
End Function
|
||||||
|
Friend Overrides Function GetSpecialDataF(ByVal URL As String) As IEnumerable(Of UserMedia)
|
||||||
|
Return UserData.GetVideoInfo(URL, Responser)
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -16,27 +16,25 @@ Imports SCrawler.API.Base
|
|||||||
Namespace API.Twitter
|
Namespace API.Twitter
|
||||||
Friend Class UserData : Inherits UserDataBase
|
Friend Class UserData : Inherits UserDataBase
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
Friend Overrides Property Site As Sites = Sites.Twitter
|
Private ReadOnly _DataNames As List(Of String)
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Initializer"
|
#Region "Initializer"
|
||||||
Friend Sub New(ByVal u As UserInfo, Optional ByVal _LoadUserInformation As Boolean = True)
|
Friend Sub New()
|
||||||
User = u
|
_DataNames = New List(Of String)
|
||||||
If _LoadUserInformation Then LoadUserInformation()
|
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Load and Update user info"
|
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
|
||||||
#Region "Download functions"
|
#Region "Download functions"
|
||||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||||
|
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||||
DownloadData(String.Empty, Token)
|
DownloadData(String.Empty, Token)
|
||||||
End Sub
|
End Sub
|
||||||
Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken)
|
Private Overloads Sub DownloadData(ByVal POST As String, ByVal Token As CancellationToken)
|
||||||
Dim URL$ = String.Empty
|
Dim URL$ = String.Empty
|
||||||
Try
|
Try
|
||||||
Dim PostID$ = String.Empty
|
Dim PostID$ = String.Empty
|
||||||
Dim PostDate$
|
Dim PostDate$, dName$
|
||||||
Dim m As EContainer, nn As EContainer, s As EContainer
|
Dim m As EContainer, nn As EContainer, s As EContainer
|
||||||
Dim NewPostDetected As Boolean = False
|
Dim NewPostDetected As Boolean = False
|
||||||
Dim ExistsDetected As Boolean = False
|
Dim ExistsDetected As Boolean = False
|
||||||
@@ -61,6 +59,8 @@ Namespace API.Twitter
|
|||||||
If Not ID.IsEmptyString Then UpdateUserInformation()
|
If Not ID.IsEmptyString Then UpdateUserInformation()
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
If UserDescriptionNeedToUpdate() AndAlso nn.Value({"user"}, "screen_name") = Name Then UserDescriptionUpdate(nn.Value({"user"}, "description"))
|
||||||
|
|
||||||
'Date Pattern:
|
'Date Pattern:
|
||||||
'Sat Jan 01 01:10:15 +0000 2000
|
'Sat Jan 01 01:10:15 +0000 2000
|
||||||
If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty
|
If nn.Contains("created_at") Then PostDate = nn("created_at").Value Else PostDate = String.Empty
|
||||||
@@ -81,9 +81,13 @@ Namespace API.Twitter
|
|||||||
If Not s Is Nothing AndAlso s.Count > 0 Then
|
If Not s Is Nothing AndAlso s.Count > 0 Then
|
||||||
For Each m In s
|
For Each m In s
|
||||||
If m.Count > 0 AndAlso m.Contains("media_url") Then
|
If m.Count > 0 AndAlso m.Contains("media_url") Then
|
||||||
|
dName = UrlFile(m("media_url").Value)
|
||||||
|
If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then
|
||||||
|
_DataNames.Add(dName)
|
||||||
_TempMediaList.ListAddValue(MediaFromData(m("media_url").Value,
|
_TempMediaList.ListAddValue(MediaFromData(m("media_url").Value,
|
||||||
PostID, PostDate, GetPictureOption(m)), LNC)
|
PostID, PostDate, GetPictureOption(m)), LNC)
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -99,12 +103,12 @@ Namespace API.Twitter
|
|||||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Friend Shared Function GetVideoInfo(ByVal URL As String) As IEnumerable(Of UserMedia)
|
Friend Shared Function GetVideoInfo(ByVal URL As String, ByVal resp As Response) As IEnumerable(Of UserMedia)
|
||||||
Try
|
Try
|
||||||
If URL.Contains("twitter") Then
|
If URL.Contains("twitter") Then
|
||||||
Dim PostID$ = RegexReplace(URL, RParams.DM("(?<=/)\d+", 0))
|
Dim PostID$ = RegexReplace(URL, RParams.DM("(?<=/)\d+", 0))
|
||||||
If Not PostID.IsEmptyString Then
|
If Not PostID.IsEmptyString Then
|
||||||
Dim r$ = DirectCast(Settings(Sites.Twitter).Responser.Copy(), Response).
|
Dim r$ = DirectCast(resp.Copy(), Response).
|
||||||
GetResponse($"https://api.twitter.com/1.1/statuses/show.json?id={PostID}",, EDP.ReturnValue)
|
GetResponse($"https://api.twitter.com/1.1/statuses/show.json?id={PostID}",, EDP.ReturnValue)
|
||||||
If Not r.IsEmptyString Then
|
If Not r.IsEmptyString Then
|
||||||
Using j As EContainer = JsonDocument.Parse(r)
|
Using j As EContainer = JsonDocument.Parse(r)
|
||||||
@@ -147,7 +151,14 @@ Namespace API.Twitter
|
|||||||
Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String) As Boolean
|
Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String) As Boolean
|
||||||
Try
|
Try
|
||||||
Dim URL$ = GetVideoNodeURL(w)
|
Dim URL$ = GetVideoNodeURL(w)
|
||||||
If Not URL.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate), LNC) : Return True
|
If Not URL.IsEmptyString Then
|
||||||
|
Dim f$ = UrlFile(URL)
|
||||||
|
If Not f.IsEmptyString AndAlso Not _DataNames.Contains(f) Then
|
||||||
|
_DataNames.Add(f)
|
||||||
|
_TempMediaList.ListAddValue(MediaFromData(URL, PostID, PostDate), LNC)
|
||||||
|
End If
|
||||||
|
Return True
|
||||||
|
End If
|
||||||
Return False
|
Return False
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
LogError(ex, "[API.Twitter.UserData.CheckVideoNode]")
|
LogError(ex, "[API.Twitter.UserData.CheckVideoNode]")
|
||||||
@@ -177,6 +188,14 @@ Namespace API.Twitter
|
|||||||
End Function
|
End Function
|
||||||
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
Protected Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Function UrlFile(ByVal URL As String) 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
|
||||||
|
Catch ex As Exception
|
||||||
|
Return String.Empty
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
Private Shared Function MediaFromData(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
Private Shared Function MediaFromData(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||||
Optional ByVal _PictureOption As String = "") As UserMedia
|
Optional ByVal _PictureOption As String = "") As UserMedia
|
||||||
@@ -206,5 +225,9 @@ Namespace API.Twitter
|
|||||||
End If
|
End If
|
||||||
Return 1
|
Return 1
|
||||||
End Function
|
End Function
|
||||||
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue And disposing Then _DataNames.Clear()
|
||||||
|
MyBase.Dispose(disposing)
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -8,13 +8,14 @@
|
|||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports PersonalUtilities.Tools
|
Imports PersonalUtilities.Tools
|
||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Functions.Messaging
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports SCrawler.API.Base
|
Imports SCrawler.API.Base
|
||||||
Namespace API
|
Namespace API
|
||||||
Friend Class UserDataBind : Inherits UserDataBase : Implements ICollection(Of IUserData), IMyEnumerator(Of IUserData)
|
Friend Class UserDataBind : Inherits UserDataBase : Implements ICollection(Of IUserData), IMyEnumerator(Of IUserData)
|
||||||
Friend Event OnCollectionSelfRemoved()
|
Friend Event OnCollectionSelfRemoved(ByVal Collection As IUserData)
|
||||||
|
Friend Event OnUserRemoved(ByVal User As IUserData)
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
Friend Overrides Property Site As Sites = Sites.Undefined
|
|
||||||
Friend ReadOnly Property Collections As List(Of IUserData)
|
Friend ReadOnly Property Collections As List(Of IUserData)
|
||||||
Private _CollectionName As String = String.Empty
|
Private _CollectionName As String = String.Empty
|
||||||
Friend Overrides Property CollectionName As String
|
Friend Overrides Property CollectionName As String
|
||||||
@@ -121,7 +122,7 @@ Namespace API
|
|||||||
Friend Overrides Property DataMerging As Boolean
|
Friend Overrides Property DataMerging As Boolean
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return DirectCast(Collections(0).Self, UserDataBase).DataMerging
|
Return DirectCast(Collections(0), UserDataBase).DataMerging
|
||||||
Else
|
Else
|
||||||
Return False
|
Return False
|
||||||
End If
|
End If
|
||||||
@@ -184,15 +185,15 @@ Namespace API
|
|||||||
End Property
|
End Property
|
||||||
Friend Overrides Function GetUserInformation() As String
|
Friend Overrides Function GetUserInformation() As String
|
||||||
Dim OutStr$ = String.Empty
|
Dim OutStr$ = String.Empty
|
||||||
If Count > 0 Then Collections.ForEach(Sub(c) OutStr.StringAppendLine(DirectCast(c.Self, UserDataBase).GetUserInformation(), $"{vbCrLf}{vbCrLf}"))
|
If Count > 0 Then Collections.ForEach(Sub(c) OutStr.StringAppendLine(DirectCast(c, UserDataBase).GetUserInformation(), $"{vbCrLf}{vbCrLf}"))
|
||||||
Return OutStr
|
Return OutStr
|
||||||
End Function
|
End Function
|
||||||
Friend Overrides Property LastUpdated As Date?
|
Friend Overrides Property LastUpdated As Date?
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
With If((From c In Collections
|
With If((From c As IUserData In Collections
|
||||||
Where DirectCast(c.Self, UserDataBase).LastUpdated.HasValue
|
Where DirectCast(c, UserDataBase).LastUpdated.HasValue
|
||||||
Select DirectCast(c.Self, UserDataBase).LastUpdated.Value).ToList, New List(Of Date))
|
Select DirectCast(c, UserDataBase).LastUpdated.Value).ToList, New List(Of Date))
|
||||||
If .Count > 0 Then Return .Max
|
If .Count > 0 Then Return .Max
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
@@ -210,7 +211,7 @@ Namespace API
|
|||||||
Friend ReadOnly Property ContextDown As ToolStripMenuItem()
|
Friend ReadOnly Property ContextDown As ToolStripMenuItem()
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return Collections.Select(Function(c) DirectCast(c.Self, UserDataBase).BTT_CONTEXT_DOWN).ToArray
|
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_DOWN).ToArray
|
||||||
Else
|
Else
|
||||||
Return New ToolStripMenuItem() {}
|
Return New ToolStripMenuItem() {}
|
||||||
End If
|
End If
|
||||||
@@ -219,7 +220,7 @@ Namespace API
|
|||||||
Friend ReadOnly Property ContextEdit As ToolStripMenuItem()
|
Friend ReadOnly Property ContextEdit As ToolStripMenuItem()
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return Collections.Select(Function(c) DirectCast(c.Self, UserDataBase).BTT_CONTEXT_EDIT).ToArray
|
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_EDIT).ToArray
|
||||||
Else
|
Else
|
||||||
Return New ToolStripMenuItem() {}
|
Return New ToolStripMenuItem() {}
|
||||||
End If
|
End If
|
||||||
@@ -228,7 +229,7 @@ Namespace API
|
|||||||
Friend ReadOnly Property ContextDelete As ToolStripMenuItem()
|
Friend ReadOnly Property ContextDelete As ToolStripMenuItem()
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return Collections.Select(Function(c) DirectCast(c.Self, UserDataBase).BTT_CONTEXT_DELETE).ToArray
|
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_DELETE).ToArray
|
||||||
Else
|
Else
|
||||||
Return New ToolStripMenuItem() {}
|
Return New ToolStripMenuItem() {}
|
||||||
End If
|
End If
|
||||||
@@ -237,7 +238,7 @@ Namespace API
|
|||||||
Friend ReadOnly Property ContextPath As ToolStripMenuItem()
|
Friend ReadOnly Property ContextPath As ToolStripMenuItem()
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return Collections.Select(Function(c) DirectCast(c.Self, UserDataBase).BTT_CONTEXT_OPEN_PATH).ToArray
|
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_OPEN_PATH).ToArray
|
||||||
Else
|
Else
|
||||||
Return New ToolStripMenuItem() {}
|
Return New ToolStripMenuItem() {}
|
||||||
End If
|
End If
|
||||||
@@ -246,7 +247,7 @@ Namespace API
|
|||||||
Friend ReadOnly Property ContextSite As ToolStripMenuItem()
|
Friend ReadOnly Property ContextSite As ToolStripMenuItem()
|
||||||
Get
|
Get
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
Return Collections.Select(Function(c) DirectCast(c.Self, UserDataBase).BTT_CONTEXT_OPEN_SITE).ToArray
|
Return Collections.Select(Function(c) DirectCast(c, UserDataBase).BTT_CONTEXT_OPEN_SITE).ToArray
|
||||||
Else
|
Else
|
||||||
Return New ToolStripMenuItem() {}
|
Return New ToolStripMenuItem() {}
|
||||||
End If
|
End If
|
||||||
@@ -270,7 +271,7 @@ Namespace API
|
|||||||
If Count > 0 Then Collections.ForEach(Sub(c) c.UpdateUserInformation())
|
If Count > 0 Then Collections.ForEach(Sub(c) c.UpdateUserInformation())
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overrides Sub LoadContentInformation()
|
Friend Overrides Sub LoadContentInformation()
|
||||||
If Count > 0 Then Collections.ForEach(Sub(c) DirectCast(c.Self, UserDataBase).LoadContentInformation())
|
If Count > 0 Then Collections.ForEach(Sub(c) DirectCast(c, UserDataBase).LoadContentInformation())
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||||
End Sub
|
End Sub
|
||||||
@@ -299,14 +300,15 @@ Namespace API
|
|||||||
Return 0
|
Return 0
|
||||||
End Function
|
End Function
|
||||||
Private Sub User_OnUserUpdated(ByVal User As IUserData)
|
Private Sub User_OnUserUpdated(ByVal User As IUserData)
|
||||||
Raise_OnUserUpdated()
|
RaiseEvent_OnUserUpdated()
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overrides Sub OpenSite()
|
Friend Overrides Sub OpenSite(Optional ByVal e As ErrorsDescriber = Nothing)
|
||||||
If Count > 0 Then Collections(0).OpenSite()
|
If Not e.Exists Then e = New ErrorsDescriber(EDP.SendInLog)
|
||||||
|
If Count > 0 Then Collections.ForEach(Sub(c) c.OpenSite(e))
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overrides Sub OpenFolder()
|
Friend Overrides Sub OpenFolder()
|
||||||
Try
|
Try
|
||||||
If Count > 0 Then Collections(0).File.CutPath(2).Open(SFO.Path, EDP.None)
|
If Count > 0 Then GlobalOpenPath(Collections(0).File.CutPath(2))
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
@@ -328,17 +330,20 @@ Namespace API
|
|||||||
If DataMerging Then DirectCast(.Self, UserDataBase).MergeData()
|
If DataMerging Then DirectCast(.Self, UserDataBase).MergeData()
|
||||||
Collections.Add(_Item)
|
Collections.Add(_Item)
|
||||||
With Collections.Last
|
With Collections.Last
|
||||||
If Collections.Count - 1 > 0 Then
|
If Count > 1 Then
|
||||||
|
If _CollectionName.IsEmptyString Then _CollectionName = .CollectionName
|
||||||
.Temporary = Temporary
|
.Temporary = Temporary
|
||||||
.Favorite = Favorite
|
.Favorite = Favorite
|
||||||
|
.ReadyForDownload = ReadyForDownload
|
||||||
|
ConsolidateLabels()
|
||||||
.UpdateUserInformation()
|
.UpdateUserInformation()
|
||||||
End If
|
End If
|
||||||
ImageHandler(_Item, False)
|
ImageHandler(_Item, False)
|
||||||
|
AddRemoveBttDeleteHandler(.Self, True)
|
||||||
AddHandler .Self.OnUserUpdated, AddressOf User_OnUserUpdated
|
AddHandler .Self.OnUserUpdated, AddressOf User_OnUserUpdated
|
||||||
DirectCast(.Self, UserDataBase).CreateButtons(Count - 1)
|
|
||||||
End With
|
End With
|
||||||
Else
|
Else
|
||||||
Throw New InvalidOperationException("User data doe not move to the collection folder")
|
Throw New InvalidOperationException("User data was not moved to the collection folder")
|
||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
End Sub
|
End Sub
|
||||||
@@ -346,22 +351,43 @@ Namespace API
|
|||||||
Friend Overloads Sub Add(ByVal u As UserInfo, Optional ByVal _LoadData As Boolean = True)
|
Friend Overloads Sub Add(ByVal u As UserInfo, Optional ByVal _LoadData As Boolean = True)
|
||||||
Collections.Add(GetInstance(u, _LoadData))
|
Collections.Add(GetInstance(u, _LoadData))
|
||||||
If Not Collections.Last Is Nothing Then
|
If Not Collections.Last Is Nothing Then
|
||||||
With DirectCast(Collections.Last.Self, UserDataBase)
|
With Collections.Last
|
||||||
.CreateButtons(Count - 1)
|
If _CollectionName.IsEmptyString Then _CollectionName = .CollectionName
|
||||||
AddHandler .BTT_CONTEXT_DELETE.Click, AddressOf BTT_CONTEXT_DELETE_Click
|
AddRemoveBttDeleteHandler(.Self, True)
|
||||||
|
AddHandler .OnUserUpdated, AddressOf User_OnUserUpdated
|
||||||
End With
|
End With
|
||||||
AddHandler Collections.Last.OnUserUpdated, AddressOf User_OnUserUpdated
|
|
||||||
Else
|
Else
|
||||||
Collections.RemoveAt(Count - 1)
|
Collections.RemoveAt(Count - 1)
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub AddRemoveBttDeleteHandler(ByRef User As IUserData, ByVal IsAdd As Boolean)
|
||||||
|
Try
|
||||||
|
With DirectCast(User, UserDataBase)
|
||||||
|
If IsAdd Then
|
||||||
|
.CreateButtons(Count - 1)
|
||||||
|
AddHandler .BTT_CONTEXT_DELETE.Click, AddressOf DeleteRemoveUserFromCollection
|
||||||
|
Else
|
||||||
|
RemoveHandler .BTT_CONTEXT_DELETE.Click, AddressOf DeleteRemoveUserFromCollection
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub ConsolidateLabels()
|
||||||
|
If Count > 1 Then
|
||||||
|
Dim l As New List(Of String)
|
||||||
|
Dim lp As New ListAddParams(LAP.ClearBeforeAdd)
|
||||||
|
l.ListAddList(Collections.SelectMany(Function(c) c.Labels), LNC)
|
||||||
|
Collections.ForEach(Sub(c) c.Labels.ListAddList(l, lp))
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
|
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
|
||||||
If Not _Items Is Nothing AndAlso _Items.Count > 0 Then
|
If Not _Items Is Nothing AndAlso _Items.Count > 0 Then
|
||||||
For i% = 0 To _Items.Count - 1 : Add(_Items(i)) : Next
|
For i% = 0 To _Items.Count - 1 : Add(_Items(i)) : Next
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overrides Function MoveFiles(ByVal __CollectionName As String) As Boolean
|
Friend Overrides Function MoveFiles(ByVal __CollectionName As String) As Boolean
|
||||||
Throw New NotImplementedException("Files moving does not available if collection context")
|
Throw New NotImplementedException("Move files is not available in the collection context")
|
||||||
End Function
|
End Function
|
||||||
Friend Overloads Sub MergeData(ByVal Merging As Boolean)
|
Friend Overloads Sub MergeData(ByVal Merging As Boolean)
|
||||||
If Count > 0 Then
|
If Count > 0 Then
|
||||||
@@ -370,7 +396,7 @@ Namespace API
|
|||||||
MsgBoxE($"Collection [{CollectionName}] data already merged")
|
MsgBoxE($"Collection [{CollectionName}] data already merged")
|
||||||
Else
|
Else
|
||||||
If Collections.Count > 1 Then
|
If Collections.Count > 1 Then
|
||||||
Collections.ForEach(Sub(c) DirectCast(c.Self, UserDataBase).MergeData())
|
Collections.ForEach(Sub(c) DirectCast(c, UserDataBase).MergeData())
|
||||||
MsgBoxE($"Collection [{CollectionName}] data merged")
|
MsgBoxE($"Collection [{CollectionName}] data merged")
|
||||||
Else
|
Else
|
||||||
MsgBoxE($"Collection [{CollectionName}] contains only one user profile" & vbCr &
|
MsgBoxE($"Collection [{CollectionName}] contains only one user profile" & vbCr &
|
||||||
@@ -403,8 +429,10 @@ Namespace API
|
|||||||
"Operation canceled", MsgBoxStyle.Critical)
|
"Operation canceled", MsgBoxStyle.Critical)
|
||||||
Return False
|
Return False
|
||||||
Else
|
Else
|
||||||
DirectCast(_Item.Self, UserDataBase).MoveFiles(String.Empty)
|
DirectCast(_Item, UserDataBase).MoveFiles(String.Empty)
|
||||||
ImageHandler(_Item)
|
ImageHandler(_Item)
|
||||||
|
AddRemoveBttDeleteHandler(_Item, False)
|
||||||
|
RaiseEvent OnUserRemoved(_Item)
|
||||||
Return Collections.Remove(_Item)
|
Return Collections.Remove(_Item)
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
@@ -420,14 +448,16 @@ Namespace API
|
|||||||
ImageHandler(Me, False)
|
ImageHandler(Me, False)
|
||||||
Collections.ListClearDispose
|
Collections.ListClearDispose
|
||||||
Dispose(False)
|
Dispose(False)
|
||||||
If f.Exists(SFO.Path, False) Then f.Delete(SFO.Path, True, False, EDP.SendInLog)
|
f.Delete(SFO.Path, SFODelete.EmptyOnly + Settings.DeleteMode, EDP.SendInLog)
|
||||||
Return 2
|
Return 2
|
||||||
Else
|
Else
|
||||||
If DataMerging Then
|
If DataMerging Then
|
||||||
MsgBoxE($"Collection [{CollectionName}] data are already merged{vbCr}Cannot split merged collection{vbCr}Operation canceled", MsgBoxStyle.Exclamation)
|
MsgBoxE($"Collection [{CollectionName}] data are already merged{vbCr}Cannot split merged collection{vbCr}Operation canceled", MsgBoxStyle.Exclamation)
|
||||||
Return 0
|
Return 0
|
||||||
End If
|
End If
|
||||||
If MsgBoxE({$"Do you want to delete collection only?{vbCr}Users will not be deleted", "Collection deleting"},
|
If MsgBoxE({"Do you want to delete only the collection and split users' profiles??" & vbCr &
|
||||||
|
"Users will be removed from the collection and split by sites." & vbCr &
|
||||||
|
"All user data will remain.", "Collection deleting"},
|
||||||
MsgBoxStyle.Question + MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
|
MsgBoxStyle.Question + MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
|
||||||
f = Collections(0).File.CutPath(2)
|
f = Collections(0).File.CutPath(2)
|
||||||
Settings.Users.Remove(Me)
|
Settings.Users.Remove(Me)
|
||||||
@@ -436,7 +466,7 @@ Namespace API
|
|||||||
ImageHandler(c)
|
ImageHandler(c)
|
||||||
End Sub)
|
End Sub)
|
||||||
Collections.Clear()
|
Collections.Clear()
|
||||||
f.Delete(SFO.Path,,, EDP.SendInLog)
|
f.Delete(SFO.Path, SFODelete.Default + Settings.DeleteMode, EDP.SendInLog)
|
||||||
Downloader.UserRemove(Me)
|
Downloader.UserRemove(Me)
|
||||||
ImageHandler(Me, False)
|
ImageHandler(Me, False)
|
||||||
Dispose(False)
|
Dispose(False)
|
||||||
@@ -448,28 +478,45 @@ Namespace API
|
|||||||
End If
|
End If
|
||||||
Return 0
|
Return 0
|
||||||
End Function
|
End Function
|
||||||
Private Sub BTT_CONTEXT_DELETE_Click(sender As Object, e As EventArgs)
|
Private Sub DeleteRemoveUserFromCollection(sender As Object, e As EventArgs)
|
||||||
With DirectCast(sender, ToolStripMenuItem)
|
With DirectCast(sender, ToolStripMenuItem)
|
||||||
Dim i% = AConvert(Of Integer)(.Tag, -1)
|
Dim i% = AConvert(Of Integer)(.Tag, -1)
|
||||||
If i >= 0 Then
|
If i >= 0 Then
|
||||||
Dim n$ = Collections(i).Name
|
Dim n$ = Collections(i).Name
|
||||||
Dim s$ = Collections(i).Site.ToString
|
Dim s$ = Collections(i).Site.ToString
|
||||||
If MsgBoxE({$"Do you really want to delete user profile [{n}] of site [{s}]?" & vbCr &
|
Dim RemoveMeIfNull As Action = Sub()
|
||||||
"This profile will be removed from collection and all data will be erased",
|
|
||||||
"Profile removing"}, MsgBoxStyle.Exclamation,,, {"Process", "Cancel"}) = 0 Then
|
|
||||||
Collections(i).Delete()
|
|
||||||
Collections(i).Dispose()
|
|
||||||
Collections.RemoveAt(i)
|
|
||||||
MsgBoxE($"User profile [{n}] of site [{s}] has been removed")
|
|
||||||
If Count = 0 Then
|
If Count = 0 Then
|
||||||
Settings.Users.Remove(Me)
|
Settings.Users.Remove(Me)
|
||||||
ImageHandler(Me, False)
|
ImageHandler(Me, False)
|
||||||
RaiseEvent OnCollectionSelfRemoved()
|
RaiseEvent OnCollectionSelfRemoved(Me)
|
||||||
Dispose(False)
|
Dispose(False)
|
||||||
End If
|
End If
|
||||||
Else
|
End Sub
|
||||||
MsgBoxE("Operation canceled")
|
Select Case MsgBoxE({$"Are you sure you want to remove user profile [{n}] of site [{s}] from collection [{Name}]?" & vbCr &
|
||||||
End If
|
"You can remove a user from the collection while keeping data (Remove) or deleting the data (Delete)" & vbCr &
|
||||||
|
"Deleting this profile will remove it from the collection and all its data will be erased." & vbCr &
|
||||||
|
"Removing this profile will remove it from the collection and all its data will remain." &
|
||||||
|
"This user will still appear in the program, but not in the collection.",
|
||||||
|
"Deleting a user"}, vbExclamation,,,
|
||||||
|
{
|
||||||
|
New MsgBoxButton("Remove") With {
|
||||||
|
.ToolTip = "Remove a user from the collection only. All its data will remain. The user will appear in the program."},
|
||||||
|
New MsgBoxButton("Delete") With {
|
||||||
|
.ToolTip = "Delete a user from the collection and erase their data."},
|
||||||
|
"Cancel"
|
||||||
|
}).Index
|
||||||
|
Case 0
|
||||||
|
Remove(Collections(i))
|
||||||
|
MsgBoxE($"User [{s} - {n}] has been removed from the collection. Now it should be displayed in the program.")
|
||||||
|
RemoveMeIfNull.Invoke
|
||||||
|
Case 1
|
||||||
|
Collections(i).Delete()
|
||||||
|
Collections(i).Dispose()
|
||||||
|
Collections.RemoveAt(i)
|
||||||
|
MsgBoxE($"User profile [{n}] of site [{s}] has been deleted")
|
||||||
|
RemoveMeIfNull.Invoke
|
||||||
|
Case Else : MsgBoxE("Operation canceled")
|
||||||
|
End Select
|
||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
End Sub
|
End Sub
|
||||||
@@ -482,26 +529,6 @@ Namespace API
|
|||||||
End Function
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#End Region
|
#End Region
|
||||||
Friend Overrides Function CompareTo(ByVal Other As UserDataBase) As Integer
|
|
||||||
If TypeOf Other Is UserDataBind Then
|
|
||||||
Dim x% = CompareValue(Me)
|
|
||||||
Dim y% = CompareValue(Other)
|
|
||||||
If x.CompareTo(y) = 0 Then
|
|
||||||
Return CollectionName.CompareTo(Other.CollectionName)
|
|
||||||
Else
|
|
||||||
Return x.CompareTo(y)
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
Return -1
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
Friend Overrides Function CompareTo(ByVal Obj As Object) As Integer
|
|
||||||
If TypeOf Obj Is UserDataBind Then
|
|
||||||
Return CompareTo(DirectCast(Obj, UserDataBind))
|
|
||||||
Else
|
|
||||||
Return -1
|
|
||||||
End If
|
|
||||||
End Function
|
|
||||||
Friend Overrides Function Equals(ByVal Other As UserDataBase) As Boolean
|
Friend Overrides Function Equals(ByVal Other As UserDataBase) As Boolean
|
||||||
If Other.IsCollection Then
|
If Other.IsCollection Then
|
||||||
Return CollectionName = Other.CollectionName
|
Return CollectionName = Other.CollectionName
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Imports System.ComponentModel
|
|||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports SCrawler.API.Base
|
Imports SCrawler.API.Base
|
||||||
Imports SCrawler.API.Reddit
|
Imports SCrawler.API.Reddit
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports CmbDefaultButtons = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
|
Imports CmbDefaultButtons = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
|
||||||
Imports RButton = PersonalUtilities.Tools.RangeSwitcherButton.Types
|
Imports RButton = PersonalUtilities.Tools.RangeSwitcherButton.Types
|
||||||
Friend Class ChannelViewForm : Implements IChannelLimits
|
Friend Class ChannelViewForm : Implements IChannelLimits
|
||||||
@@ -37,7 +38,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
Return u.ToString
|
Return u.ToString
|
||||||
End Operator
|
End Operator
|
||||||
Friend Sub ChannelUserAdded(Optional ByVal IsAdded As Boolean = True)
|
Friend Sub ChannelUserAdded(Optional ByVal IsAdded As Boolean = True)
|
||||||
If Not Channel Is Nothing Then Channel.UserAdded(IsAdded)
|
If Not Channel Is Nothing Then Channel.UserAdded(ID, IsAdded)
|
||||||
End Sub
|
End Sub
|
||||||
Public Overrides Function ToString() As String
|
Public Overrides Function ToString() As String
|
||||||
Return ID
|
Return ID
|
||||||
@@ -121,6 +122,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
Private Sub SetLimit(ByVal Source As IChannelLimits) Implements IChannelLimits.SetLimit
|
Private Sub SetLimit(ByVal Source As IChannelLimits) Implements IChannelLimits.SetLimit
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
|
Private ReadOnly HOST As SettingsHost
|
||||||
Private ReadOnly PendingUsers As List(Of PendingUser)
|
Private ReadOnly PendingUsers As List(Of PendingUser)
|
||||||
Private ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly)
|
Private ReadOnly LNC As New ListAddParams(LAP.NotContainsOnly)
|
||||||
Private WithEvents MyRange As RangeSwitcher(Of UserPost)
|
Private WithEvents MyRange As RangeSwitcher(Of UserPost)
|
||||||
@@ -144,6 +146,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
CProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
CProvider = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||||
LimitProvider = New ADateTime("dd.MM.yyyy HH:mm")
|
LimitProvider = New ADateTime("dd.MM.yyyy HH:mm")
|
||||||
PendingUsers = New List(Of PendingUser)
|
PendingUsers = New List(Of PendingUser)
|
||||||
|
HOST = Settings(RedditSiteKey)
|
||||||
|
|
||||||
CMB_CHANNELS = New ComboBoxExtended With {
|
CMB_CHANNELS = New ComboBoxExtended With {
|
||||||
.CaptionMode = ICaptionControl.Modes.CheckBox,
|
.CaptionMode = ICaptionControl.Modes.CheckBox,
|
||||||
@@ -323,7 +326,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
Private Async Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click
|
Private Async Sub BTT_DOWNLOAD_Click(sender As Object, e As EventArgs) Handles BTT_DOWNLOAD.Click
|
||||||
Try
|
Try
|
||||||
AppendPendingUsers()
|
AppendPendingUsers()
|
||||||
If Not TokenSource Is Nothing Then Exit Sub
|
If Not TokenSource Is Nothing OrElse Not HOST.Source.Available(Plugin.ISiteSettings.Download.Channel) Then Exit Sub
|
||||||
Dim InvokeToken As Action = Sub()
|
Dim InvokeToken As Action = Sub()
|
||||||
If TokenSource Is Nothing Then
|
If TokenSource Is Nothing Then
|
||||||
CProgress.TotalCount = 0
|
CProgress.TotalCount = 0
|
||||||
@@ -353,6 +356,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
_CollectionDownloading = True
|
_CollectionDownloading = True
|
||||||
Settings.Channels.SetLimit(Me)
|
Settings.Channels.SetLimit(Me)
|
||||||
Await Task.Run(Sub() Settings.Channels.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
Await Task.Run(Sub() Settings.Channels.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
||||||
|
Settings.Channels.UpdateUsersStats()
|
||||||
RaiseEvent OnDownloadDone("All channels downloaded")
|
RaiseEvent OnDownloadDone("All channels downloaded")
|
||||||
Token.ThrowIfCancellationRequested()
|
Token.ThrowIfCancellationRequested()
|
||||||
c = GetCurrentChannel()
|
c = GetCurrentChannel()
|
||||||
@@ -362,6 +366,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
InvokeToken.Invoke()
|
InvokeToken.Invoke()
|
||||||
c.SetLimit(Me)
|
c.SetLimit(Me)
|
||||||
Await Task.Run(Sub() c.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
Await Task.Run(Sub() c.DownloadData(Token, CH_HIDE_EXISTS_USERS.Checked, CProgress))
|
||||||
|
c.UpdateUsersStats()
|
||||||
RaiseEvent OnDownloadDone($"Channel [{c.Name}] downloaded")
|
RaiseEvent OnDownloadDone($"Channel [{c.Name}] downloaded")
|
||||||
Token.ThrowIfCancellationRequested()
|
Token.ThrowIfCancellationRequested()
|
||||||
End If
|
End If
|
||||||
@@ -433,25 +438,34 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
Dim Added% = 0, Skipped% = 0
|
Dim Added% = 0, Skipped% = 0
|
||||||
Dim StartIndex% = Settings.Users.Count
|
Dim StartIndex% = Settings.Users.Count
|
||||||
Dim f As SFile
|
Dim f As SFile
|
||||||
|
Dim umo As Boolean = HOST.GetUserMediaOnly
|
||||||
Settings.Labels.Add(CannelsLabelName)
|
Settings.Labels.Add(CannelsLabelName)
|
||||||
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
|
Settings.Labels.Add(LabelsKeeper.NoParsedUser)
|
||||||
Dim rUsers$() = UserBanned(PendingUsers.Select(Function(u) u.ID).ToArray)
|
Dim rUsers$() = UserBanned(PendingUsers.Select(Function(u) u.ID).ToArray)
|
||||||
If rUsers.ListExists Then PendingUsers.RemoveAll(Function(u) rUsers.Contains(u))
|
If rUsers.ListExists Then PendingUsers.RemoveAll(Function(u) rUsers.Contains(u))
|
||||||
If PendingUsers.Count > 0 Then
|
If PendingUsers.Count > 0 Then
|
||||||
With PendingUsers.Select(Function(u) New UserInfo(u, Sites.Reddit))
|
Dim c As New ListAddParams(LAP.NotContainsOnly)
|
||||||
|
Dim cn$
|
||||||
|
Dim tmpUser As IUserData
|
||||||
|
With PendingUsers.Select(Function(u) New UserInfo(u, HOST))
|
||||||
For i = 0 To .Count - 1
|
For i = 0 To .Count - 1
|
||||||
If Not Settings.UsersList.Contains(.ElementAt(i)) Then
|
If Not Settings.UsersList.Contains(.ElementAt(i)) Then
|
||||||
f = PendingUsers(i).File
|
f = PendingUsers(i).File
|
||||||
|
cn = If(PendingUsers(i).Channel?.Name, String.Empty)
|
||||||
Settings.UpdateUsersList(.ElementAt(i))
|
Settings.UpdateUsersList(.ElementAt(i))
|
||||||
Settings.Users.Add(New UserData(.ElementAt(i), False) With {
|
tmpUser = HOST.GetInstance(Plugin.ISiteSettings.Download.Main, .ElementAt(i), False)
|
||||||
.Temporary = Settings.ChannelsDefaultTemporary,
|
With DirectCast(tmpUser, UserData)
|
||||||
.CreatedByChannel = True,
|
.Temporary = Settings.ChannelsDefaultTemporary
|
||||||
|
.CreatedByChannel = True
|
||||||
.ReadyForDownload = Settings.ChannelsDefaultReadyForDownload
|
.ReadyForDownload = Settings.ChannelsDefaultReadyForDownload
|
||||||
})
|
.ParseUserMediaOnly = umo
|
||||||
|
End With
|
||||||
|
Settings.Users.Add(tmpUser)
|
||||||
With Settings.Users.Last
|
With Settings.Users.Last
|
||||||
.Labels.Add(CannelsLabelName)
|
.Labels.Add(CannelsLabelName)
|
||||||
.UpdateUserInformation()
|
.UpdateUserInformation()
|
||||||
If Settings.FromChannelCopyImageToUser And Not f.IsEmptyString And Not .File.IsEmptyString Then CopyFile(f, .File)
|
If Settings.FromChannelCopyImageToUser And Not f.IsEmptyString And Not .File.IsEmptyString Then _
|
||||||
|
CopyFile(ListAddValue(Nothing, New ChannelsCollection.ChannelImage(cn, f)).ListAddList(Settings.Channels.GetUserFiles(.Name), c), .File)
|
||||||
End With
|
End With
|
||||||
Added += 1
|
Added += 1
|
||||||
Else
|
Else
|
||||||
@@ -464,17 +478,26 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
BTT_ADD_USERS.Text = "Add"
|
BTT_ADD_USERS.Text = "Add"
|
||||||
MsgBoxE($"Added users: {Added.ToString(CProvider)}{vbCr}Skipped users: {Skipped.ToString(CProvider)}{vbCr}Total: {PendingUsers.Count.ToString(CProvider)}")
|
MsgBoxE($"Added users: {Added.ToString(CProvider)}{vbCr}Skipped users: {Skipped.ToString(CProvider)}{vbCr}Total: {PendingUsers.Count.ToString(CProvider)}")
|
||||||
RaiseEvent OnUsersAdded(StartIndex)
|
RaiseEvent OnUsersAdded(StartIndex)
|
||||||
|
Settings.Channels.UpdateUsersStats()
|
||||||
Else
|
Else
|
||||||
MsgBoxE("No one users selected for add to collection")
|
MsgBoxE("No one users selected for add to collection")
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub CopyFile(ByVal Source As SFile, ByVal Destination As SFile)
|
Private Sub CopyFile(ByVal Source As IEnumerable(Of ChannelsCollection.ChannelImage), ByVal Destination As SFile)
|
||||||
Try
|
Try
|
||||||
If Not Source.IsEmptyString And Not Destination.IsEmptyString Then
|
If Source.ListExists And Not Destination.IsEmptyString Then
|
||||||
Destination = Destination.CutPath.PathWithSeparator & "ChannelImage\"
|
Destination = Destination.CutPath.PathWithSeparator & "ChannelImage\"
|
||||||
Destination.Name = Source.Name
|
Dim f As SFile
|
||||||
Destination.Extension = Source.Extension
|
Dim i% = 0
|
||||||
If Source.Exists AndAlso Destination.Exists(SFO.Path) Then IO.File.Copy(Source, Destination)
|
If Destination.Exists(SFO.Path) Then
|
||||||
|
For Each ff As ChannelsCollection.ChannelImage In Source
|
||||||
|
f = Destination
|
||||||
|
f.Extension = ff.File.Extension
|
||||||
|
f.Name = $"{IIf(i = 0, "!", String.Empty)}{ff.Channel}_{ff.File.Name}"
|
||||||
|
If ff.File.Exists Then IO.File.Copy(ff.File, f)
|
||||||
|
i += 1
|
||||||
|
Next
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
End Try
|
End Try
|
||||||
@@ -660,7 +683,7 @@ Friend Class ChannelViewForm : Implements IChannelLimits
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_C_OPEN_FOLDER_Click(sender As Object, e As EventArgs) Handles BTT_C_OPEN_FOLDER.Click
|
Private Sub BTT_C_OPEN_FOLDER_Click(sender As Object, e As EventArgs) Handles BTT_C_OPEN_FOLDER.Click
|
||||||
Dim f As SFile = GetPostBySelected().CachedFile
|
Dim f As SFile = GetPostBySelected().CachedFile
|
||||||
If Not f.IsEmptyString Then f.Open(SFO.Path)
|
If Not f.IsEmptyString Then GlobalOpenPath(f, EDP.LogMessageValue)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_C_REMOVE_FROM_SELECTED_Click(sender As Object, e As EventArgs) Handles BTT_C_REMOVE_FROM_SELECTED.Click
|
Private Sub BTT_C_REMOVE_FROM_SELECTED_Click(sender As Object, e As EventArgs) Handles BTT_C_REMOVE_FROM_SELECTED.Click
|
||||||
Try
|
Try
|
||||||
|
|||||||
BIN
SCrawler/Content/Icons/DownArrow_Blue_24.ico
Normal file
|
After Width: | Height: | Size: 29 KiB |
61
SCrawler/Download/ActiveDownloadingProgress.Designer.vb
generated
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Namespace DownloadObjects
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class ActiveDownloadingProgress : 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 resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ActiveDownloadingProgress))
|
||||||
|
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'TP_MAIN
|
||||||
|
'
|
||||||
|
Me.TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||||
|
Me.TP_MAIN.ColumnCount = 1
|
||||||
|
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||||
|
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
|
Me.TP_MAIN.Name = "TP_MAIN"
|
||||||
|
Me.TP_MAIN.RowCount = 1
|
||||||
|
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 62.0!))
|
||||||
|
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 62.0!))
|
||||||
|
Me.TP_MAIN.Size = New System.Drawing.Size(434, 61)
|
||||||
|
Me.TP_MAIN.TabIndex = 0
|
||||||
|
'
|
||||||
|
'ActiveDownloadingProgress
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(434, 61)
|
||||||
|
Me.Controls.Add(Me.TP_MAIN)
|
||||||
|
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(450, 100)
|
||||||
|
Me.Name = "ActiveDownloadingProgress"
|
||||||
|
Me.Text = "Active downloading progress"
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents TP_MAIN As TableLayoutPanel
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
624
SCrawler/Download/ActiveDownloadingProgress.resx
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
AAABAAwAMDAQAAEABABoBgAAxgAAACAgEAABAAQA6AIAAC4HAAAYGBAAAQAEAOgBAAAWCgAAEBAQAAEA
|
||||||
|
BAAoAQAA/gsAADAwAAABAAgAqA4AACYNAAAgIAAAAQAIAKgIAADOGwAAGBgAAAEACADIBgAAdiQAABAQ
|
||||||
|
AAABAAgAaAUAAD4rAAAwMAAAAQAgAKglAACmMAAAICAAAAEAIACoEAAATlYAABgYAAABACAAiAkAAPZm
|
||||||
|
AAAQEAAAAQAgAGgEAAB+cAAAKAAAADAAAABgAAAAAQAEAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
|
||||||
|
/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjsjgAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAIbOh4AAAAAAAAAAAAAAAAAAAAAAAAAAAH5mfsgAAAAAAAAAAAAAAAAAAAAAAAAAB+
|
||||||
|
xs54YAAAAAAAAAAAAAAAAAAAAAAAAAfsbmxo5wAAAAAAAAAAAAAAAAAAAAAAAIbObObOeMAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAACG5+zmzsaOgAAAAAAAAAAAAAAAAAAAAABn7ObOZmbneAAAAAAAAAAAAAAAAAAAAAfs5s
|
||||||
|
5+zs7I7AAAAAAAAAAAAAAAAAAAAH7Ofm7G7GbGiOAAAAAAAAAAAAAAAAAAB+fs7Ofs5+zmzngAAAAAAA
|
||||||
|
AAAAAAAAAAhn7Ojs5uzm7OZ4yAAAAAAAAAAAAAAAAAaOfm7Obsfsbs7OjnAAAAAAAAAAAAAAAH7Ojs7n
|
||||||
|
7O7ObOZs54AAAAAAAAAAAAAABn6Ozuduzn5uznzmyOcAAAAAAAAAAAAAfn7I6M7s5+zn7Obs5oyAAAAA
|
||||||
|
AAAAAAAIZ+jujuzo7Obs5uxubOjnAAAAAAAAAAAG586M5+js7n7OfOfs5s54cAAAAAAAAABnzo7o5+zu
|
||||||
|
fs5+5uzmzmzowAAAAAAAAAdujn5+fu7Ozuzs7Ofs5+bI6AAAAAAAAHzn7OjOjI5+5+jufs5uzs5ueOAA
|
||||||
|
AAAAAG6M6O6O7n7Ofs7Ozo7Ofmzs53gAAAAAB+zo7IznyOzuzufufs6Ofo6Ofn4AAAAACEdsZ2Z87o5+
|
||||||
|
js7O7O5cjHx8jIgAAAAAAAAAAAAAfOfs7Ojs6OfgAAAAAAAAAAAAAAAAAAAAbo7O6O7O7OfAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAfsjm7Obo7s6AAAAAAAAAAAAAAAAAAAAAaO5+zo7OyO5wAAAAAAAAAAAAAAAAAAAAzn7O
|
||||||
|
js7n7sjAAAAAAAAAAAAAAAAAAAAAaM6Ozuzuzu5wAAAAAAAAAAAAAAAAAAAAbn7Obn5+jshgAAAAAAAA
|
||||||
|
AAAAAAAAAAAAbOjn7Ozs7O5wAAAAAAAAAAAAAAAAAAAAfnzn5+bn7n7AAAAAAAAAAAAAAAAAAAAAbOjs
|
||||||
|
7OzuzshgAAAAAAAAAAAAAAAAAAAAaOyOfn7I5+5wAAAAAAAAAAAAAAAAAAAAbOfs7Ozm7OfAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAbnzn5+bs5u5wAAAAAAAAAAAAAAAAAAAAfOfsjOx+zn7AAAAAAAAAAAAAAAAAAAAAbnzn
|
||||||
|
5o7OfshgAAAAAAAAAAAAAAAAAAAAx+Z+zs5uzm5gAAAAAAAAAAAAAAAAAAAAbs7H5+fObsjAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAZ2js585s7O5wAAAAAAAAAAAAAAAAAAAAjOyH5+jn53aAAAAAAAAAAAAAAAAAAAAACGZs
|
||||||
|
bHxsfGgAAAAAAAAAAAD///////8AAP///////wAA////////AAD///j///8AAP//8H///wAA///gP///
|
||||||
|
AAD//+Af//8AAP//wB///wAA//+AD///AAD//wAH//8AAP/+AAP//wAA//4AAf//AAD//AAB//8AAP/4
|
||||||
|
AAD//wAA//AAAH//AAD/4AAAP/8AAP/gAAAf/wAA/8AAAB//AAD/gAAAD/8AAP8AAAAH/wAA/gAAAAP/
|
||||||
|
AAD+AAAAAf8AAPwAAAAB/wAA+AAAAAD/AADwAAAAAH8AAPAAAAAAPwAA4AAAAAA/AADgAAAAAD8AAP/8
|
||||||
|
AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//
|
||||||
|
AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8
|
||||||
|
AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//4AA///AAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
|
||||||
|
AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5+AAAAAAAAAAAAAAAAAA
|
||||||
|
BoyHAAAAAAAAAAAAAAAAAOfn7AAAAAAAAAAAAAAAAAjIzn6AAAAAAAAAAAAAAAAO5uxo7AAAAAAAAAAA
|
||||||
|
AAAAaM7ObI6AAAAAAAAAAAAADn5ubOboyAAAAAAAAAAAAH7Ozs5sbo4AAAAAAAAAAAjI5+fn7saM4AAA
|
||||||
|
AAAAAAAO7n7Ozsbs6OcAAAAAAAAAaH7O5+bn5s6MgAAAAAAABo7o5+zs7Ozm6OAAAAAAAH7I7Ozufn5u
|
||||||
|
zsfsAAAAAAjOjn6Ofs7s5+bsjnAAAAAG6Ozo7O7n5+zs5ujnAAAAaOyOjo587Ozo6I7IjIAAAGxmxsZ+
|
||||||
|
7o7uzsbG7O4AAAAAAAAM587OyOhgAAAAAAAAAAAABo7n5+7OYAAAAAAAAAAAAAzozuzujsAAAAAAAAAA
|
||||||
|
AAAGjufuzs5wAAAAAAAAAAAADOfOyOfowAAAAAAAAAAAAAaOfm7O7mAAAAAAAAAAAAAM7Ofs5sjAAAAA
|
||||||
|
AAAAAAAABn585+7oYAAAAAAAAAAAAAyM6Oxs58AAAAAAAAAAAAAG5+zm5+5gAAAAAAAAAAAABOx+fs7I
|
||||||
|
wAAAAAAAAAAAAAZ+Z8hs7kAAAAAAAAAAAAAMjOjm52fAAAAAAAAAAAAAAGbExsbOAAAAAAAA///////8
|
||||||
|
f///+D////A////gH///4A///8AH//+AA///AAP//gAB//4AAP/8AAB/+AAAf/AAAD/gAAAf4AAAD8AA
|
||||||
|
AAfAAAAP/4AH//+AB///gAf//4AH//+AB///gAf//4AH//+AB///gAf//4AH//+AB///gAf//4AH///A
|
||||||
|
D/8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA
|
||||||
|
AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAABgAAAAAAAAAAAAAAeOAAAAAAAAAAAAAG7IcAAAAAAAAAAAB+fujgAAAAAAAAAAbs7OyHAAAAAAAA
|
||||||
|
AGjufm7oYAAAAAAABo7OzsfOhwAAAAAAaO5+5+7s6GAAAAAG5+zs7Ozn7PYAAABo6Ojo7n6IjojgAAAM
|
||||||
|
bGzs7OyOx+wAAAAAAAfo7o7nAAAAAAAAAAaM7OyGAAAAAAAAAAbufu6MAAAAAAAAAAd+zn6GAAAAAAAA
|
||||||
|
AAzn7OznAAAAAAAAAAaOzuiGAAAAAAAAAAbn587sAAAAAAAAAAZ87m6GAAAAAAAAAAzozs6MAAAAAAAA
|
||||||
|
AAaOh+eGAAAAAAAAAABsbGxgAAAAAAAAAAAAAAAAAAAAAP///wD/7/8A/8f/AP+D/wD/Af8A/gD/APwA
|
||||||
|
fwD4AD8A8AAfAOAADwDAAAcA4AAPAP4A/wD+AP8A/gD/AP4A/wD+AP8A/gD/AP4A/wD+AP8A/gD/AP4A
|
||||||
|
/wD/Af8A////ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
|
||||||
|
AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAABgAA
|
||||||
|
AAAAAABoYAAAAAAABo6MAAAAAABozshgAAAABo5uboYAAABo7OfOeGAABo5+fn6OhgB2xs7O6MfHgAAA
|
||||||
|
aOfIYAAAAABuzujgAAAAAGjn6MAAAAAAzs5+cAAAAABo5+jAAAAAAG7OyOAAAAAAaI6OcAAAAAAMbGYA
|
||||||
|
AAD+/wAA/H8AAPg/AADwHwAA4A8AAMAHAACAAwAAAAEAAPAfAADwHwAA8B8AAPAfAADwHwAA8B8AAPAf
|
||||||
|
AAD4PwAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAACjaB0ApmsgAKlt
|
||||||
|
IwCrcCYArXMqALF1LACzeC4ArHYwALR6MQC4fTQAt385AMh1AADJdwQAy3gAAM17AADOfQEAy3oHAM5/
|
||||||
|
CQDMfA0A0H4BAMt/GQC7gDcAvoI6ALmBPADRgAIA0oIEANSDBADVhQUA1ogGANaMBwDZiQYA3I0GANKE
|
||||||
|
CgDWhwkA0YIMANaMCwDZiggA2o0JANyOCQDbkgsA3pAKAN6UCwDekg0A3ZQNAM+EGgDRhhUA1YkSANiN
|
||||||
|
EgDajhcA2pISANqSHgDalh4A3ZgaAOGUCgDgkg0A4ZUOAOSWDgDhmA4A5ZgPAOicDgDklxAA45cVAOGY
|
||||||
|
EADlmRAA5ZwRAOSdFwDonRIA550YAOmfGwDpoBIA6qEUAO2iFADrpBQA7qUWAO6mGADvqBgA8KUXAPCm
|
||||||
|
GADxqRgA9KsZAPKsGgD0rBoA9a0cAPiuGgD1sBsA+bEbAPixHADOhycAzo0lAMqKKwDRjCIA0Y8lANSP
|
||||||
|
JgDTji0A05ImANiRIwDdnScA1JQpANmVKwDXmCoA25stAMGJNQDAhj0A0I84AM2VPwDTmTYA3JwyANKR
|
||||||
|
OQDSlDgA2Js6AOGeIADknS8A3qAxANyiPwDopCAA7qogAOKiLQDtqykA8asjAPOxJwD6syAA+LMkAPq1
|
||||||
|
JwD2tSoA+rYsAPq4LgDiozEA6qUzAOepNQDpqTEA66wyAOmrNwDtqjUA6qw2AO2vNQDjpjoA6aw4AOir
|
||||||
|
PwDwrDgA67A3AO2xOQDssT8A8rIwAPazMwD2tzEA8bE2APq7NgDytDoA+Lc6APW5PAD5uToA+bw7APi7
|
||||||
|
PQD5vD0A/L49APzAPgCxgEMAv4VAALaFSAC5h0sAvJZmALyacgC5mnYAxYlBAMOLRgDHi0QAyY1GAMaO
|
||||||
|
SgDJj0oAyZBEAMyQSgDPlEkAypFNAM6TTADNlE4A0pVHANebQwDUnUUA0JRNANaaSgDDkVUAzpZWAM2X
|
||||||
|
WwDOmVsAzZpdANGZVgDUmlcA0ppaANOcWwDQnF4A16BHANqiSADapUkA3adLAN2lTQDbo1QA1KFeANql
|
||||||
|
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
|
||||||
|
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD///j///8AAP//8H///wAA///gP///
|
||||||
|
AAD//+Af//8AAP//wB///wAA//+AD///AAD//wAH//8AAP/+AAP//wAA//4AAf//AAD//AAB//8AAP/4
|
||||||
|
AAD//wAA//AAAH//AAD/4AAAP/8AAP/gAAAf/wAA/8AAAB//AAD/gAAAD/8AAP8AAAAH/wAA/gAAAAP/
|
||||||
|
AAD+AAAAAf8AAPwAAAAB/wAA+AAAAAD/AADwAAAAAH8AAPAAAAAAPwAA4AAAAAA/AADgAAAAAD8AAP/8
|
||||||
|
AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//
|
||||||
|
AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//wAAf//AAD//AAB//8AAP/8
|
||||||
|
AAH//wAA//wAAf//AAD//AAB//8AAP/8AAH//wAA//4AA///AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
|
||||||
|
AAAAAAAAAAAAAAABAAAAAQAAAAAAAKdIAACpSgAArU0AALBSAACxVQAAtFYAALdYAAC5WwAAuVwAALxe
|
||||||
|
AAC/YQAAvGgNALllFwC5Zx8AtWUpAMJkAADFaAAAyGsAAMxuAgDOcQYA0nYJANR5DQDFdREAz34aANd8
|
||||||
|
EADafxMA0IAGANSDBQDThAYA1YUFANiJBwDThg8A2YoIANqNCQDcjQoA25AKAN2QCgDekQ0A35UNAN2A
|
||||||
|
FgDXjxAA2Y4UAN6DGQDWjBsA3ZEQAN6UFgDdmBgA4JMKAOCSDQDhlQ4A5ZcPAOSZDgDghhsA44geAOSW
|
||||||
|
EADjmxEA5ZoQAOScEQDnnxQA6Z0SAOWcGgDpoBIA6aEUAO2iFADtpBYA5qAZAO+oGgDwphcA8acYAPGp
|
||||||
|
GAD0qxkA86waAPSsGgD1rhwA9rAbAPawHAD4sBoA+LEcAMyAIADXhSMA0IUnAN+NKgDRkScA2pYhAN2b
|
||||||
|
IwDcmyUA05MoANWWKQDali8A2ZksANucLQDcnS4A3Z0xAN2TOwDblT8A1po7ANKYPADVmj0A154+AOaO
|
||||||
|
JADjkCoA5ZIuAOqTKgDtkysA7ZQrAOiTLQDulSwA4pIxAOmWMQDrlzUA6J02AOOaOQDgnTwA6pw5APCa
|
||||||
|
NADynj0A36AvAN6hMADdoDgA2aE/AOSgIQDioSYA7KchAO2oJgDgoCkA6agrAPewIAD5tCIA+bQnAPOx
|
||||||
|
KAD5tigA+bcvAOOmMgDjpjQA5KU0AOepNQDnrD8A6Ko4AOyvOADprj8A86A/AO+zOgDysjAA8LE3APe4
|
||||||
|
NgD7ujEA8rY7APCzPQDytj4A9Lg6APW6PQD7vDoA+b0+AMWARADPkEUA3ZlEANmbTQDPnF8A0phUAOqe
|
||||||
|
QgDdoEEA2aJGAN2kRADep0kA3aVOANuiUADdplQA4ahGAO2qRwDooEgA4alKAOOtTQDzoUAA869EAPap
|
||||||
|
TgDsskAA77JGAOewTgDusUoA6rBMAPC1QwD0ukUA9rxGAPm9QQDwskkA8rVNAPe+SAD1uk8A+L5IAPWp
|
||||||
|
UADyqlQA6rRRAO22UgDuuFQA47BbAPCyUQD0vFAA8r5WAPC2XAD4sV0AyZ5nAMSlfwDfr3MA2K19AOWt
|
||||||
|
YgDltmcA67NgAOm5YQDsu2oA77ptAPW+awDwvm0A+bhpAOizcQDiu34A7Lt9APS9cAD7wEIA+8FGAPnA
|
||||||
|
SAD4wk4A+MNZAPnEWgD6w2AA/ctkAMOnhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAABta58AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbc2/a8oAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAKpvpabIawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWcqgdHaa/awAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAG2JLR8dIM6tXgAAAAAAAAAAAAAAAAAAAAAAAAAAAABlsT0xIx8dLNJzngAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAUq58PDMxIyMdWdVr4gAAAAAAAAAAAAAAAAAAAAAAAJypj0REMzMxJSMdochr
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAADLcN9KRURERDMxJSMjw69lAAAAAAAAAAAAAAAAAAAAAFDhuH9KSkQzRDMx
|
||||||
|
JSMq0o1fAAAAAAAAAAAAAAAAAAAY4Nu4gUdHQ0VEM0QlJSNU2XPJAAAAAAAAAAAAAAAAT8TcuNuSTUpK
|
||||||
|
R0REMzsxJSNd1WsAAAAAAAAAAAAAAJtw3bi425hNTUpKSkRERDMzMSOryGsAAAAAAAAAAADMUd2Vl7i4
|
||||||
|
mIFNTU1KSkRERDMzMSXQr2wAAAAAAAAAABfBsJOXmLi4g01NTU1KSkRERDk5MS3ZdJ0AAAAAAAAMz7S0
|
||||||
|
urrFxbiETYFNTU1KSo+xlbq6tMfTa9gAAAAAAJoGBgYGCQkL35FLTU2BTU1KthkZKys1NmSgAAAAAAAA
|
||||||
|
AAAAAAAAAAnfl0pLTU1NgU29FgAAAAAAAAAAAAAAAAAAAAAAAAAABt2VgkpNgU1NTdwVAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAGxrGPSkpKTU2B2xQAAAAAAAAAAAAAAAAAAAAAAAAAAAbCi5BDREpLTU3cEwAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAABMGIi3xAR0pLTdwTAAAAAAAAAAAAAAAAAAAAAAAAAAADsoWKjzlEQ0pL3BEA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAOrhYWFOztEREq7EQAAAAAAAAAAAAAAAAAAAAAAAAAAA6tdXIV5OTtE
|
||||||
|
Q7YLAAAAAAAAAAAAAAAAAAAAAAAAAAABpVxcdn0nMztEtgkAAAAAAAAAAAAAAAAAAAAAAAAAAAGhWFpd
|
||||||
|
di8nMzu1CQAAAAAAAAAAAAAAAAAAAAAAAAAAAaVTWFxdViUnJ7EGAAAAAAAAAAAAAAAAAAAAAAAAAAAB
|
||||||
|
YFNYWFhcKSQnsAYAAAAAAAAAAAAAAAAAAAAAAAAAAA/XYWBjoaF3VFZWDQAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAA8BAQEBAQEEBA4AAAAAAAAAAAAAAAD///////x////4P///8D///+Af///gD///wAf//4AD//8A
|
||||||
|
A//+AAH//gAA//wAAH/4AAB/8AAAP+AAAB/gAAAPwAAAB8AAAA//gAf//4AH//+AB///gAf//4AH//+A
|
||||||
|
B///gAf//4AH//+AB///gAf//4AH//+AB///gAf//8AP/ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
|
||||||
|
AAAAAAAAAAEAAAABAAAAAAAApWYWAKhpGQCqbBsAqm0dAKxuHgCucCEAsHMjALJ2JgC2eioAuH4uALyC
|
||||||
|
MgC9gzQAvoU1AN+YEwDklw8A5ZkQAOmdEgDooBIA6aEUAO2hFQDtpRYA8KYXAPGqFwDxpxgA8qoZAPSr
|
||||||
|
GgD0rRoA86wcAPauHAD3sBoA97AcAPmwGgD4sRwAwIY3AMGJOQDDizwAxIs8AMWNPgDjnSUA5J4nAN6g
|
||||||
|
MADnoyAA5aAnAOSjKQDgoi8A7awpAPCsIwD6syIA+rcrAOKlMwDqqzIA6Kk3AOSpOgDpqz0A+rozAPq6
|
||||||
|
NADytjsA97s+APe8PAD5uzgA36VCAN+sVADgqUQA5axHAOmuQADkrUoA6bNKAO63TgDws0EA9btDAPS6
|
||||||
|
RQD6vkEA9LxMAPm+SADhrlUA5LJZAPK7UAD7wEMA+8NOAPbBUAD6xFIA+8VUAPDDaQD0xmwA9shtAPjK
|
||||||
|
bgD6zW8A8cmCAPPMhAD0zoYA99CHAPDPmQDw0JkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAACZcJgAAAAAAAAAAAAAAAAAAAAAAAAAAJjYnXSYAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAiRREPJ10mAAAAAAAAAAAAAAAAAAAAAAtHFhYQECddJgAAAAAAAAAAAAAAAAAACkobGxYRERAnXSYA
|
||||||
|
AAAAAAAAAAAAAAAJUjAbGxgbFhEQKF0mAAAAAAAAAAAAAAhSTjEgGxsbFhYRECtdJgAAAAAAAAAABjpI
|
||||||
|
SDggICAbGBgWERAnXSYAAAAAAAAFOVBSUk84IDAgGxtUW1paWlwmAAAAAAAABQUGBgg8IDAgMBtWCwsL
|
||||||
|
IiIAAAAAAAAAAAAAAAY6HiAgMCBXCgAAAAAAAAAAAAAAAAAAAAVHGx4wICBXCgAAAAAAAAAAAAAAAAAA
|
||||||
|
AAVJGxseMCBXCQAAAAAAAAAAAAAAAAAAAAVJLxsbHjBXCAAAAAAAAAAAAAAAAAAAAAFELhYcGx5XCAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAFDMxMVGxtXBgAAAAAAAAAAAAAAAAAAAAFANCsWFhxVBgAAAAAAAAAAAAAAAAAA
|
||||||
|
AAE/MisOEBZVBQAAAAAAAAAAAAAAAAAAAAE9KS0OEBNUAwAAAAAAAAAAAAAAAAAAAAE+S0xAND9TAwAA
|
||||||
|
AAAAAAAAAAAAAAAAAAABAQEBAwEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP/v
|
||||||
|
/wD/x/8A/4P/AP8B/wD+AP8A/AB/APgAPwDwAB8A4AAPAMAABwDgAA8A/gD/AP4A/wD+AP8A/gD/AP4A
|
||||||
|
/wD+AP8A/gD/AP4A/wD+AP8A/gD/AP8B/wD///8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
|
||||||
|
AAAAAQAAAAEAAAAAAAClZhYAsnYmALN4KQC4fi8A1Y0XANWOGADXkBkA2pUbANuVHADclhwA3poeAOCc
|
||||||
|
HwDgmyAA46EiAOaiIwDmpiMA56cnAOilIwDppiUA66omAO2rJwDuricA46YsAOyrKADurikA7q4sAPCv
|
||||||
|
KQDvsS4A8LAqAO2vMQDkpjgA5q8+AOqwOADwszIA4qtBAOi0TwDyvEoA7LlSAOSyXADnt18Aw5ljAMui
|
||||||
|
bQDqumEA5LhoAOa7cADpv3MA78FlAPDFdgDyyXkA88x6APXNegD20IAA6MeQAOnIkQDpyZcAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAP///wAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAzcCAAAAAAAAAAAAAAAAAycFNQIAAAAA
|
||||||
|
AAAAAAAAAysLCAY1BAAAAAAAAAAAAy8SDg0IBjUEAAAAAAAAAzMaFBIODQgINQQAAAAAAzQlIhQaEg4f
|
||||||
|
Li01BAAAKQEBAQEbGhQUMAQEBAQqAAAAAAABGxsbFDMEAAAAAAAAAAAAARwbGxszBAAAAAAAAAAAAAEe
|
||||||
|
FBsbMwQAAAAAAAAAAAABIRQcHDMEAAAAAAAAAAAAASARFBQzBAAAAAAAAAAAAAEjFw4WMwQAAAAAAAAA
|
||||||
|
AAABLCgkJjMDAAAAAAAAAAAAAAEBAQEBAAAAAAAA/v8AAPx/AAD4PwAA8B8AAOAPAADABwAAgAMAAAAB
|
||||||
|
AADwHwAA8B8AAPAfAADwHwAA8B8AAPAfAADwHwAA+D8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAABgAAAAgAAAAGAAAAAwAA
|
||||||
|
AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAFgAA
|
||||||
|
ABsAAAAWAAAACwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAA
|
||||||
|
AAwAAAAfAAAAMwAAADwAAAAyAAAAHQAAAAsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAACAAAACSccDyHPllLiypFQ4M2UUesdFQtZAAAANQAAABoAAAAJAAAAAgAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAEAAAAHAAAAF8aOTb/RlU3z0pVH/82UU/K/iUvcAAAAUAAAADAAAAAWAAAABgAA
|
||||||
|
AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAUAAAATs4BGjtOXUfXLfxn/0pE5/9ikYP7Rl1T3pXdBvQAA
|
||||||
|
AEoAAAAqAAAAEgAAAAUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAA+RaDhc0ZdR+M6HJv3Legf/yHUA/9aa
|
||||||
|
Sv/Tn1v51JlU+nxZMZcAAABDAAAAJAAAAA4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAADFg/ITLPlE/1z4wz+NGC
|
||||||
|
DP/NewD/y3gA/8l3BP/apVv/zZdV89OYU/hHMxxzAAAAPAAAAB8AAAALAAAAAgAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJJxwOIMiO
|
||||||
|
SuHNj0Dy1YkR/9ODBf/QfwH/zXsA/8t4AP/MfA3/3apl/8yXV/DLklDuHBQLXQAAADYAAAAaAAAACAAA
|
||||||
|
AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA
|
||||||
|
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
|
||||||
|
HP/1rRv/9Kwa//OqGf/xqBj/76QX/+6iFf/roBP/6JwS/+aZEP/klg//4JMN/96OC//bjQn/2YkI/9WF
|
||||||
|
Bv/fpkz/06Zp8s2TUPY/LRhtAAAAOQAAABwAAAAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAEGRAFFKRqI9mwdibx56o3//G0Ov/ztjv/9bo8//a7Pv/5vED/+r1A//q+Qf/7wEP/+rgu//mx
|
||||||
|
G//5sh3/+bId//ixHP/2sBz/9a0b//SrGv/yqhn/8agY//CmF//uoxX/6qAT/+mdEf/mmRD/5JYP/+CT
|
||||||
|
Dv/ejwr/3IwK/9mJB//Whwn/4q5d/9GiZ+7Hj0znEg0HSAAAACcAAAAPAAAAAwAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAGoGcgpaluIvLdoDP/6q03/++yOf/xtDr/87Y7//S4PP/2uz3/+bw+//m9
|
||||||
|
QP/6vkL/+rs3//myHP/5sh3/+bId//myHf/5sR3/+LAc//WtHP/0rRv/9KsZ//KpGP/wphf/7qMV/+ug
|
||||||
|
E//onhL/55oR/+SXD//hlA3/3pAL/9yNCf/Zigf/2I0S/+S0aP/ToGPwvolJxAAAACcAAAARAAAABQAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACiaB9ppmsg9dKVL//nqjX/67A3/+6yOP/wtDr/87Y7//W4
|
||||||
|
PP/4uz3/+b0+//m9QP/5vUD/+rw7//myHv/5sh3/+bId//myHf/5sh3/+LEd//iwHP/2rhv/9awb//Or
|
||||||
|
Gv/xqBn/8KYY/+6jFf/roBP/6p4Q/+icDv/llw3/4ZQK/9+QCf/cjQb/2okF/9mRHf/ismj40ZVQ9MGK
|
||||||
|
SogAAAALAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmaR7PyYgn+uSdL//loDD/56Iy/+qk
|
||||||
|
M//rpjT/7qk3//CrOP/xrTn/8a05//CxOP/4vD7/+bxA//izJP/4sRz/+bId//myHf/5sh3/+bId//mx
|
||||||
|
Hf/4sBz/9q4c//WsG//zqxr/8qkY//GrI//xsDr/8bFF//W0Sf/2s0n/9LJI//OwSP/yr0f/8a1G//Cs
|
||||||
|
R//urEv/5ahV6dGVT+AAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkaR2XpGoe/6Vq
|
||||||
|
H/+mayD/pmwh/6hsIv+pbSP/qW4k/6twJf+scCf/rXIn/65zKf/6vDz/+LxA//a1Kv/2sBr/+bEd//my
|
||||||
|
Hf/5sh3/+bId//myHf/5sR3/+LAc//auHP/1rRv/9Ksa//a3Ov/EiED/xYlB/8aKQ//Hi0T/yY1G/8qO
|
||||||
|
R//Lj0n/zJBK/82RS//Ok0z/0JRN/9GVTpcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK1yJ//5uzv/9rs+//a3
|
||||||
|
Mf/1rhr/9rAc//iyHf/5sh3/+bId//myHf/5sh3/+bEd//iwHP/2rhz/9a0b//m5Ov/Chj//AAAAKwAA
|
||||||
|
AA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKtw
|
||||||
|
Jf/4tzr/9Lg9//W3OP/0rRz/9a4b//awHP/4sh3/+bId//myHf/5sh3/+bId//mxHf/4sBz/9q4c//q8
|
||||||
|
O//AhT3/AAAAKwAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAKpvJP/0tTn/8rU8//O2Pf/zsSf/86wZ//WuG//2sBz/+LEd//myHf/5sh3/+bId//my
|
||||||
|
Hf/5sh3/+LEc//u9PP+/gzv/AAAAKwAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
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
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
72
SCrawler/Download/ActiveDownloadingProgress.vb
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.ComponentModel
|
||||||
|
Imports PersonalUtilities.Forms
|
||||||
|
Namespace DownloadObjects
|
||||||
|
Friend Class ActiveDownloadingProgress
|
||||||
|
Private Const MinWidth As Integer = 450
|
||||||
|
Private MyView As FormsView
|
||||||
|
Friend Property Opened As Boolean = False
|
||||||
|
Private ReadOnly JobsList As List(Of DownloadProgress)
|
||||||
|
Friend Sub New()
|
||||||
|
InitializeComponent()
|
||||||
|
JobsList = New List(Of DownloadProgress)
|
||||||
|
AddHandler Downloader.OnReconfigured, AddressOf Downloader_OnReconfigured
|
||||||
|
Downloader_OnReconfigured()
|
||||||
|
End Sub
|
||||||
|
Private Sub ActiveDownloadingProgress_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
MyView = New FormsView(Me)
|
||||||
|
MyView.ImportFromXML(Settings.Design)
|
||||||
|
MyView.SetMeSize()
|
||||||
|
Opened = True
|
||||||
|
End Sub
|
||||||
|
Private Sub ActiveDownloadingProgress_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||||
|
MyView.ExportToXML(Settings.Design)
|
||||||
|
e.Cancel = True
|
||||||
|
Hide()
|
||||||
|
End Sub
|
||||||
|
Private Sub Downloader_OnReconfigured()
|
||||||
|
Const RowHeight% = 30
|
||||||
|
With TP_MAIN
|
||||||
|
If .Controls.Count > 0 Then
|
||||||
|
For Each c As Control In .Controls
|
||||||
|
If Not c Is Nothing Then c.Dispose()
|
||||||
|
Next
|
||||||
|
.Controls.Clear()
|
||||||
|
End If
|
||||||
|
.RowStyles.Clear()
|
||||||
|
.RowCount = 0
|
||||||
|
End With
|
||||||
|
JobsList.ListClearDispose
|
||||||
|
With Downloader
|
||||||
|
If .Pool.Count > 0 Then
|
||||||
|
For Each j As TDownloader.Job In .Pool
|
||||||
|
With TP_MAIN
|
||||||
|
.RowStyles.Add(New RowStyle(SizeType.Absolute, RowHeight))
|
||||||
|
.RowCount += 1
|
||||||
|
JobsList.Add(New DownloadProgress(j))
|
||||||
|
AddHandler JobsList.Last.OnTotalCountChange, AddressOf Jobs_OnTotalCountChange
|
||||||
|
.Controls.Add(JobsList.Last.Get, 0, .RowStyles.Count - 1)
|
||||||
|
End With
|
||||||
|
Next
|
||||||
|
TP_MAIN.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
|
||||||
|
TP_MAIN.RowCount += 1
|
||||||
|
End If
|
||||||
|
Dim s As Size = Size
|
||||||
|
s.Height = TP_MAIN.RowStyles.Count * RowHeight + PaddingE.GetOf({TP_MAIN}).Vertical(TP_MAIN.RowStyles.Count) - TP_MAIN.RowStyles.Count * 2
|
||||||
|
MinimumSize = New Size(MinWidth, s.Height)
|
||||||
|
Size = s
|
||||||
|
End With
|
||||||
|
TP_MAIN.Refresh()
|
||||||
|
End Sub
|
||||||
|
Private Sub Jobs_OnTotalCountChange()
|
||||||
|
If JobsList.Count > 0 Then MainProgress.TotalCount = JobsList.Sum(Function(j) CLng(j.Job.Progress.TotalCount))
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
190
SCrawler/Download/DownloadProgress.vb
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Imports TDJob = SCrawler.DownloadObjects.TDownloader.Job
|
||||||
|
Namespace DownloadObjects
|
||||||
|
Friend Class DownloadProgress : Implements IDisposable
|
||||||
|
Friend Event OnDownloadDone(ByVal Message As String)
|
||||||
|
Friend Event OnTotalCountChange()
|
||||||
|
Private ReadOnly TP_MAIN As TableLayoutPanel
|
||||||
|
Private ReadOnly TP_CONTROLS As TableLayoutPanel
|
||||||
|
Private WithEvents BTT_START As Button
|
||||||
|
Private WithEvents BTT_STOP As Button
|
||||||
|
Private WithEvents BTT_OPEN As Button
|
||||||
|
Private ReadOnly PR_MAIN As ProgressBar
|
||||||
|
Private ReadOnly LBL_INFO As Label
|
||||||
|
Private ReadOnly Property Instance As API.Base.ProfileSaved
|
||||||
|
Friend ReadOnly Property Job As TDJob
|
||||||
|
#Region "Initializer"
|
||||||
|
Friend Sub New(ByVal _Job As TDJob)
|
||||||
|
Job = _Job
|
||||||
|
|
||||||
|
TP_MAIN = New TableLayoutPanel With {.Margin = New Padding(0), .Dock = DockStyle.Fill}
|
||||||
|
TP_MAIN.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
|
||||||
|
TP_MAIN.ColumnCount = 1
|
||||||
|
TP_CONTROLS = New TableLayoutPanel With {.Margin = New Padding(0), .Dock = DockStyle.Fill}
|
||||||
|
PR_MAIN = New ProgressBar With {.Dock = DockStyle.Fill}
|
||||||
|
LBL_INFO = New Label With {.Text = String.Empty, .Dock = DockStyle.Fill}
|
||||||
|
CreateButton(BTT_STOP, My.Resources.Delete)
|
||||||
|
|
||||||
|
If Job.Type = Download.Main Then
|
||||||
|
LBL_INFO.Margin = New Padding(3)
|
||||||
|
LBL_INFO.TextAlign = ContentAlignment.MiddleLeft
|
||||||
|
With TP_MAIN
|
||||||
|
.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
|
||||||
|
.RowCount = 1
|
||||||
|
End With
|
||||||
|
With TP_CONTROLS
|
||||||
|
.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 30))
|
||||||
|
.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 150))
|
||||||
|
.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
|
||||||
|
.ColumnCount = .ColumnStyles.Count
|
||||||
|
.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
|
||||||
|
.RowCount = 1
|
||||||
|
With .Controls
|
||||||
|
.Add(BTT_STOP, 0, 0)
|
||||||
|
.Add(PR_MAIN, 1, 0)
|
||||||
|
.Add(LBL_INFO, 2, 0)
|
||||||
|
End With
|
||||||
|
End With
|
||||||
|
TP_MAIN.Controls.Add(TP_CONTROLS, 0, 0)
|
||||||
|
Else
|
||||||
|
LBL_INFO.Padding = New Padding(3, 0, 3, 0)
|
||||||
|
LBL_INFO.TextAlign = ContentAlignment.TopCenter
|
||||||
|
CreateButton(BTT_START, My.Resources.StartPic_01_Green_16)
|
||||||
|
CreateButton(BTT_OPEN, PersonalUtilities.My.Resources.OpenFolderPic)
|
||||||
|
With TP_CONTROLS
|
||||||
|
With .ColumnStyles
|
||||||
|
.Add(New ColumnStyle(SizeType.Absolute, 30))
|
||||||
|
.Add(New ColumnStyle(SizeType.Absolute, 30))
|
||||||
|
.Add(New ColumnStyle(SizeType.Absolute, 30))
|
||||||
|
.Add(New ColumnStyle(SizeType.Percent, 100))
|
||||||
|
End With
|
||||||
|
.ColumnCount = 4
|
||||||
|
.RowStyles.Add(New RowStyle(SizeType.Percent, 50))
|
||||||
|
.RowCount = 1
|
||||||
|
With .Controls
|
||||||
|
.Add(BTT_START, 0, 0)
|
||||||
|
.Add(BTT_STOP, 1, 0)
|
||||||
|
.Add(BTT_OPEN, 2, 0)
|
||||||
|
.Add(PR_MAIN, 3, 0)
|
||||||
|
End With
|
||||||
|
End With
|
||||||
|
With TP_MAIN
|
||||||
|
With .RowStyles
|
||||||
|
.Add(New RowStyle(SizeType.Absolute, 30))
|
||||||
|
.Add(New RowStyle(SizeType.Percent, 100))
|
||||||
|
End With
|
||||||
|
.RowCount = 2
|
||||||
|
End With
|
||||||
|
TP_MAIN.Controls.Add(TP_CONTROLS, 0, 0)
|
||||||
|
TP_MAIN.Controls.Add(LBL_INFO, 0, 1)
|
||||||
|
End If
|
||||||
|
|
||||||
|
With Job
|
||||||
|
.Progress = New MyProgress(PR_MAIN, LBL_INFO) With {.DropCurrentProgressOnTotalChange = False}
|
||||||
|
With .Progress
|
||||||
|
AddHandler .OnProgressChange, AddressOf JobProgress_OnProgressChange
|
||||||
|
AddHandler .OnTotalCountChange, AddressOf JobProgress_OnTotalCountChange
|
||||||
|
End With
|
||||||
|
End With
|
||||||
|
|
||||||
|
If Job.Type = Download.SavedPosts And Not Job.Progress Is Nothing Then Job.Progress.InformationTemporary = Job.Host.Name
|
||||||
|
Instance = New API.Base.ProfileSaved(Job.Host, Job.Progress)
|
||||||
|
End Sub
|
||||||
|
Private Sub CreateButton(ByRef BTT As Button, ByVal Img As Image)
|
||||||
|
BTT = New Button With {
|
||||||
|
.BackgroundImage = Img,
|
||||||
|
.BackgroundImageLayout = ImageLayout.Zoom,
|
||||||
|
.Text = String.Empty,
|
||||||
|
.Dock = DockStyle.Fill
|
||||||
|
}
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
Friend Function [Get]() As TableLayoutPanel
|
||||||
|
Return TP_MAIN
|
||||||
|
End Function
|
||||||
|
#Region "Buttons"
|
||||||
|
Private Sub BTT_START_Click(sender As Object, e As EventArgs) Handles BTT_START.Click
|
||||||
|
Start()
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_STOP.Click
|
||||||
|
[Stop]()
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_OPEN.Click
|
||||||
|
GlobalOpenPath(Job.Host.SavedPostsPath)
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Start, Stop"
|
||||||
|
Friend Sub Start()
|
||||||
|
Job.Start(AddressOf DownloadData)
|
||||||
|
End Sub
|
||||||
|
Friend Sub [Stop]()
|
||||||
|
Job.Stop()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "SavedPosts downloading"
|
||||||
|
Private Sub DownloadData()
|
||||||
|
Dim btte As Action(Of Button, Boolean) = Sub(b, e) If b.InvokeRequired Then b.Invoke(Sub() b.Enabled = e) Else b.Enabled = e
|
||||||
|
Try
|
||||||
|
btte.Invoke(BTT_START, False)
|
||||||
|
btte.Invoke(BTT_STOP, True)
|
||||||
|
Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading started"
|
||||||
|
Job.Start()
|
||||||
|
Instance.Download(Job.Token)
|
||||||
|
RaiseEvent OnDownloadDone($"Downloading saved {Job.Host.Name} posts is completed")
|
||||||
|
Catch ex As Exception
|
||||||
|
Job.Progress.InformationTemporary = $"{Job.Host.Name} downloading error"
|
||||||
|
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Job.Host.Name} saved posts downloading error", "Saved posts"})
|
||||||
|
Finally
|
||||||
|
btte.Invoke(BTT_START, True)
|
||||||
|
btte.Invoke(BTT_STOP, False)
|
||||||
|
Job.Stopped()
|
||||||
|
If Job.Type = Download.SavedPosts Then Job.Progress.TotalCount = 0 : Job.Progress.CurrentCounter = 0
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "Progress, Jobs count"
|
||||||
|
Private Sub JobProgress_OnTotalCountChange(ByVal Source As IMyProgress, ByVal Index As Integer)
|
||||||
|
RaiseEvent OnTotalCountChange()
|
||||||
|
End Sub
|
||||||
|
Private Sub JobProgress_OnProgressChange(ByVal Source As IMyProgress, ByVal Index As Integer)
|
||||||
|
MainProgress.Perform()
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
#Region "IDisposable Support"
|
||||||
|
Private disposedValue As Boolean = False
|
||||||
|
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue Then
|
||||||
|
If disposing Then
|
||||||
|
If Not BTT_START Is Nothing Then BTT_START.Dispose()
|
||||||
|
If Not BTT_STOP Is Nothing Then BTT_STOP.Dispose()
|
||||||
|
If Not BTT_OPEN Is Nothing Then BTT_OPEN.Dispose()
|
||||||
|
PR_MAIN.Dispose()
|
||||||
|
LBL_INFO.Dispose()
|
||||||
|
TP_CONTROLS.Controls.Clear()
|
||||||
|
TP_CONTROLS.Dispose()
|
||||||
|
TP_MAIN.Controls.Clear()
|
||||||
|
TP_MAIN.Dispose()
|
||||||
|
End If
|
||||||
|
disposedValue = True
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Sub Finalize()
|
||||||
|
Dispose(False)
|
||||||
|
MyBase.Finalize()
|
||||||
|
End Sub
|
||||||
|
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
|
||||||
|
Dispose(True)
|
||||||
|
GC.SuppressFinalize(Me)
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
110
SCrawler/Download/DownloadSavedPostsForm.Designer.vb
generated
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class DownloadSavedPostsForm : 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 TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||||
|
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||||
|
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadSavedPostsForm))
|
||||||
|
Me.BTT_DOWN_ALL = New System.Windows.Forms.Button()
|
||||||
|
Me.BTT_STOP_ALL = New System.Windows.Forms.Button()
|
||||||
|
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
|
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
|
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||||
|
TP_BUTTONS.SuspendLayout()
|
||||||
|
Me.TP_MAIN.SuspendLayout()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'TP_BUTTONS
|
||||||
|
'
|
||||||
|
TP_BUTTONS.ColumnCount = 2
|
||||||
|
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||||
|
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||||
|
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||||
|
TP_BUTTONS.Controls.Add(Me.BTT_DOWN_ALL, 0, 0)
|
||||||
|
TP_BUTTONS.Controls.Add(Me.BTT_STOP_ALL, 1, 0)
|
||||||
|
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
TP_BUTTONS.Location = New System.Drawing.Point(2, 2)
|
||||||
|
TP_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
|
||||||
|
TP_BUTTONS.Name = "TP_BUTTONS"
|
||||||
|
TP_BUTTONS.RowCount = 1
|
||||||
|
TP_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
TP_BUTTONS.Size = New System.Drawing.Size(480, 37)
|
||||||
|
TP_BUTTONS.TabIndex = 0
|
||||||
|
'
|
||||||
|
'BTT_DOWN_ALL
|
||||||
|
'
|
||||||
|
Me.BTT_DOWN_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.BTT_DOWN_ALL.Location = New System.Drawing.Point(3, 3)
|
||||||
|
Me.BTT_DOWN_ALL.Name = "BTT_DOWN_ALL"
|
||||||
|
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(234, 31)
|
||||||
|
Me.BTT_DOWN_ALL.TabIndex = 0
|
||||||
|
Me.BTT_DOWN_ALL.Text = "Download ALL"
|
||||||
|
Me.BTT_DOWN_ALL.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'BTT_STOP_ALL
|
||||||
|
'
|
||||||
|
Me.BTT_STOP_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.BTT_STOP_ALL.Location = New System.Drawing.Point(243, 3)
|
||||||
|
Me.BTT_STOP_ALL.Name = "BTT_STOP_ALL"
|
||||||
|
Me.BTT_STOP_ALL.Size = New System.Drawing.Size(234, 31)
|
||||||
|
Me.BTT_STOP_ALL.TabIndex = 1
|
||||||
|
Me.BTT_STOP_ALL.Text = "Stop ALL"
|
||||||
|
Me.BTT_STOP_ALL.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'TP_MAIN
|
||||||
|
'
|
||||||
|
Me.TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Inset
|
||||||
|
Me.TP_MAIN.ColumnCount = 1
|
||||||
|
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
|
Me.TP_MAIN.Controls.Add(TP_BUTTONS, 0, 0)
|
||||||
|
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
|
Me.TP_MAIN.Name = "TP_MAIN"
|
||||||
|
Me.TP_MAIN.RowCount = 1
|
||||||
|
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||||
|
Me.TP_MAIN.Size = New System.Drawing.Size(484, 41)
|
||||||
|
Me.TP_MAIN.TabIndex = 0
|
||||||
|
'
|
||||||
|
'DownloadSavedPostsForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(484, 41)
|
||||||
|
Me.Controls.Add(Me.TP_MAIN)
|
||||||
|
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||||
|
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
||||||
|
Me.MaximizeBox = False
|
||||||
|
Me.MaximumSize = New System.Drawing.Size(500, 80)
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(500, 80)
|
||||||
|
Me.Name = "DownloadSavedPostsForm"
|
||||||
|
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||||
|
Me.Text = "Saved posts"
|
||||||
|
TP_BUTTONS.ResumeLayout(False)
|
||||||
|
Me.TP_MAIN.ResumeLayout(False)
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
Private WithEvents BTT_DOWN_ALL As Button
|
||||||
|
Private WithEvents BTT_STOP_ALL As Button
|
||||||
|
Private WithEvents TP_MAIN As TableLayoutPanel
|
||||||
|
End Class
|
||||||
@@ -117,62 +117,16 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="TP_REDDIT.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>
|
<value>False</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="TP_REDDIT_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>False</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
|
||||||
<metadata name="TP_INST.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="TP_INST_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</value>
|
|
||||||
</metadata>
|
</metadata>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="BTT_INST_OPEN.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>
|
|
||||||
<metadata name="TP_REDDIT_PR.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</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>
|
|
||||||
<data name="BTT_REDDIT_OPEN.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>
|
|
||||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>17, 17</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA
|
||||||
77
SCrawler/Download/DownloadSavedPostsForm.vb
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.ComponentModel
|
||||||
|
Imports PersonalUtilities.Forms
|
||||||
|
Imports SCrawler.DownloadObjects
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
|
Friend Class DownloadSavedPostsForm
|
||||||
|
Friend Event OnDownloadDone(ByVal Message As String)
|
||||||
|
Private MyView As FormsView
|
||||||
|
Private ReadOnly JobsList As List(Of DownloadProgress)
|
||||||
|
Friend ReadOnly Property Working As Boolean
|
||||||
|
Get
|
||||||
|
Return JobsList.Count > 0 AndAlso JobsList.Exists(Function(j) j.Job.Working)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Sub [Stop]()
|
||||||
|
If JobsList.Count > 0 Then JobsList.ForEach(Sub(j) j.Stop())
|
||||||
|
End Sub
|
||||||
|
Private Sub [Start]()
|
||||||
|
If JobsList.Count > 0 Then JobsList.ForEach(Sub(j) j.Start())
|
||||||
|
End Sub
|
||||||
|
Friend Sub New()
|
||||||
|
InitializeComponent()
|
||||||
|
JobsList = New List(Of DownloadProgress)
|
||||||
|
If Settings.Plugins.Count > 0 Then
|
||||||
|
Dim j As TDownloader.Job
|
||||||
|
For Each p As PluginHost In Settings.Plugins
|
||||||
|
If p.Settings.IsSavedPostsCompatible Then
|
||||||
|
j = New TDownloader.Job(Plugin.ISiteSettings.Download.SavedPosts)
|
||||||
|
j.AddHost(p.Settings)
|
||||||
|
JobsList.Add(New DownloadProgress(j))
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadSavedPostsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
MyView = New FormsView(Me) With {.LocationOnly = True}
|
||||||
|
MyView.ImportFromXML(Settings.Design)
|
||||||
|
MyView.SetMeSize()
|
||||||
|
If JobsList.Count > 0 Then
|
||||||
|
For Each j As DownloadProgress In JobsList
|
||||||
|
AddHandler j.OnDownloadDone, AddressOf Jobs_OnDownloadDone
|
||||||
|
TP_MAIN.RowStyles.Add(New RowStyle(SizeType.Absolute, 60))
|
||||||
|
TP_MAIN.RowCount += 1
|
||||||
|
TP_MAIN.Controls.Add(j.Get, 0, TP_MAIN.RowStyles.Count - 1)
|
||||||
|
Next
|
||||||
|
Dim s As Size = Size
|
||||||
|
s.Height += (60 * JobsList.Count + JobsList.Count)
|
||||||
|
MinimumSize = s
|
||||||
|
Size = s
|
||||||
|
MaximumSize = s
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadSavedPostsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||||
|
e.Cancel = True
|
||||||
|
Hide()
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadSavedPostsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||||
|
[Stop]()
|
||||||
|
MyView.Dispose(Settings.Design)
|
||||||
|
End Sub
|
||||||
|
Private Sub Jobs_OnDownloadDone(ByVal Message As String)
|
||||||
|
RaiseEvent OnDownloadDone(Message)
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_DOWN_ALL_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_ALL.Click
|
||||||
|
Start()
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_STOP_ALL_Click(sender As Object, e As EventArgs) Handles BTT_STOP_ALL.Click
|
||||||
|
[Stop]()
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
179
SCrawler/Download/DownloadedInfoForm.Designer.vb
generated
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
Namespace DownloadObjects
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class DownloadedInfoForm : 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 SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadedInfoForm))
|
||||||
|
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
|
||||||
|
Me.MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
|
||||||
|
Me.MENU_VIEW_SESSION = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.MENU_VIEW_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
||||||
|
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_UP = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_DOWN = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_FIND = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_CLEAR = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.ToolbarBOTTOM = New System.Windows.Forms.StatusStrip()
|
||||||
|
Me.LIST_DOWN = New System.Windows.Forms.ListBox()
|
||||||
|
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
Me.ToolbarTOP.SuspendLayout()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'SEP_1
|
||||||
|
'
|
||||||
|
SEP_1.Name = "SEP_1"
|
||||||
|
SEP_1.Size = New System.Drawing.Size(6, 25)
|
||||||
|
'
|
||||||
|
'SEP_2
|
||||||
|
'
|
||||||
|
SEP_2.Name = "SEP_2"
|
||||||
|
SEP_2.Size = New System.Drawing.Size(6, 25)
|
||||||
|
'
|
||||||
|
'ToolbarTOP
|
||||||
|
'
|
||||||
|
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||||
|
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW, Me.BTT_REFRESH, SEP_1, Me.BTT_UP, Me.BTT_DOWN, Me.BTT_FIND, SEP_2, Me.BTT_CLEAR})
|
||||||
|
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
|
||||||
|
Me.ToolbarTOP.Name = "ToolbarTOP"
|
||||||
|
Me.ToolbarTOP.Size = New System.Drawing.Size(554, 25)
|
||||||
|
Me.ToolbarTOP.TabIndex = 0
|
||||||
|
'
|
||||||
|
'MENU_VIEW
|
||||||
|
'
|
||||||
|
Me.MENU_VIEW.AutoToolTip = False
|
||||||
|
Me.MENU_VIEW.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
||||||
|
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW_SESSION, Me.MENU_VIEW_ALL})
|
||||||
|
Me.MENU_VIEW.Image = CType(resources.GetObject("MENU_VIEW.Image"), System.Drawing.Image)
|
||||||
|
Me.MENU_VIEW.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.MENU_VIEW.Name = "MENU_VIEW"
|
||||||
|
Me.MENU_VIEW.Size = New System.Drawing.Size(45, 22)
|
||||||
|
Me.MENU_VIEW.Text = "View"
|
||||||
|
'
|
||||||
|
'MENU_VIEW_SESSION
|
||||||
|
'
|
||||||
|
Me.MENU_VIEW_SESSION.AutoToolTip = True
|
||||||
|
Me.MENU_VIEW_SESSION.Name = "MENU_VIEW_SESSION"
|
||||||
|
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(113, 22)
|
||||||
|
Me.MENU_VIEW_SESSION.Text = "Session"
|
||||||
|
Me.MENU_VIEW_SESSION.ToolTipText = "Show downloaded users by this session"
|
||||||
|
'
|
||||||
|
'MENU_VIEW_ALL
|
||||||
|
'
|
||||||
|
Me.MENU_VIEW_ALL.AutoToolTip = True
|
||||||
|
Me.MENU_VIEW_ALL.Name = "MENU_VIEW_ALL"
|
||||||
|
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(113, 22)
|
||||||
|
Me.MENU_VIEW_ALL.Text = "All"
|
||||||
|
Me.MENU_VIEW_ALL.ToolTipText = "Show all users (sorted by latest download)"
|
||||||
|
'
|
||||||
|
'BTT_REFRESH
|
||||||
|
'
|
||||||
|
Me.BTT_REFRESH.Image = Global.SCrawler.My.Resources.Resources.Refresh
|
||||||
|
Me.BTT_REFRESH.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_REFRESH.Name = "BTT_REFRESH"
|
||||||
|
Me.BTT_REFRESH.Size = New System.Drawing.Size(89, 22)
|
||||||
|
Me.BTT_REFRESH.Text = "Refresh (F5)"
|
||||||
|
Me.BTT_REFRESH.ToolTipText = "Force list refresh"
|
||||||
|
'
|
||||||
|
'BTT_UP
|
||||||
|
'
|
||||||
|
Me.BTT_UP.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
|
||||||
|
Me.BTT_UP.Image = CType(resources.GetObject("BTT_UP.Image"), System.Drawing.Image)
|
||||||
|
Me.BTT_UP.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_UP.Name = "BTT_UP"
|
||||||
|
Me.BTT_UP.Size = New System.Drawing.Size(23, 22)
|
||||||
|
Me.BTT_UP.Text = "Up"
|
||||||
|
Me.BTT_UP.ToolTipText = "Up (F3)"
|
||||||
|
'
|
||||||
|
'BTT_DOWN
|
||||||
|
'
|
||||||
|
Me.BTT_DOWN.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
|
||||||
|
Me.BTT_DOWN.Image = CType(resources.GetObject("BTT_DOWN.Image"), System.Drawing.Image)
|
||||||
|
Me.BTT_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_DOWN.Name = "BTT_DOWN"
|
||||||
|
Me.BTT_DOWN.Size = New System.Drawing.Size(23, 22)
|
||||||
|
Me.BTT_DOWN.Text = "Down"
|
||||||
|
Me.BTT_DOWN.ToolTipText = "Down (F2)"
|
||||||
|
'
|
||||||
|
'BTT_FIND
|
||||||
|
'
|
||||||
|
Me.BTT_FIND.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
||||||
|
Me.BTT_FIND.Image = CType(resources.GetObject("BTT_FIND.Image"), System.Drawing.Image)
|
||||||
|
Me.BTT_FIND.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_FIND.Name = "BTT_FIND"
|
||||||
|
Me.BTT_FIND.Size = New System.Drawing.Size(57, 22)
|
||||||
|
Me.BTT_FIND.Text = "Find (F4)"
|
||||||
|
Me.BTT_FIND.ToolTipText = "Find in the main window"
|
||||||
|
'
|
||||||
|
'BTT_CLEAR
|
||||||
|
'
|
||||||
|
Me.BTT_CLEAR.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
||||||
|
Me.BTT_CLEAR.Image = CType(resources.GetObject("BTT_CLEAR.Image"), System.Drawing.Image)
|
||||||
|
Me.BTT_CLEAR.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_CLEAR.Name = "BTT_CLEAR"
|
||||||
|
Me.BTT_CLEAR.Size = New System.Drawing.Size(38, 22)
|
||||||
|
Me.BTT_CLEAR.Text = "Clear"
|
||||||
|
Me.BTT_CLEAR.ToolTipText = "Clear info list"
|
||||||
|
'
|
||||||
|
'ToolbarBOTTOM
|
||||||
|
'
|
||||||
|
Me.ToolbarBOTTOM.Location = New System.Drawing.Point(0, 389)
|
||||||
|
Me.ToolbarBOTTOM.Name = "ToolbarBOTTOM"
|
||||||
|
Me.ToolbarBOTTOM.Size = New System.Drawing.Size(554, 22)
|
||||||
|
Me.ToolbarBOTTOM.TabIndex = 1
|
||||||
|
'
|
||||||
|
'LIST_DOWN
|
||||||
|
'
|
||||||
|
Me.LIST_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.LIST_DOWN.FormattingEnabled = True
|
||||||
|
Me.LIST_DOWN.Location = New System.Drawing.Point(0, 25)
|
||||||
|
Me.LIST_DOWN.Name = "LIST_DOWN"
|
||||||
|
Me.LIST_DOWN.Size = New System.Drawing.Size(554, 364)
|
||||||
|
Me.LIST_DOWN.TabIndex = 2
|
||||||
|
'
|
||||||
|
'DownloadedInfoForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(554, 411)
|
||||||
|
Me.Controls.Add(Me.LIST_DOWN)
|
||||||
|
Me.Controls.Add(Me.ToolbarBOTTOM)
|
||||||
|
Me.Controls.Add(Me.ToolbarTOP)
|
||||||
|
Me.KeyPreview = True
|
||||||
|
Me.MinimumSize = New System.Drawing.Size(570, 450)
|
||||||
|
Me.Name = "DownloadedInfoForm"
|
||||||
|
Me.ShowIcon = False
|
||||||
|
Me.Text = "Downloaded items"
|
||||||
|
Me.ToolbarTOP.ResumeLayout(False)
|
||||||
|
Me.ToolbarTOP.PerformLayout()
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
Me.PerformLayout()
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents ToolbarTOP As ToolStrip
|
||||||
|
Private WithEvents MENU_VIEW As ToolStripDropDownButton
|
||||||
|
Private WithEvents MENU_VIEW_SESSION As ToolStripMenuItem
|
||||||
|
Private WithEvents MENU_VIEW_ALL As ToolStripMenuItem
|
||||||
|
Private WithEvents BTT_REFRESH As ToolStripButton
|
||||||
|
Private WithEvents ToolbarBOTTOM As StatusStrip
|
||||||
|
Private WithEvents LIST_DOWN As ListBox
|
||||||
|
Private WithEvents BTT_CLEAR As ToolStripButton
|
||||||
|
Private WithEvents BTT_FIND As ToolStripButton
|
||||||
|
Private WithEvents BTT_UP As ToolStripButton
|
||||||
|
Private WithEvents BTT_DOWN As ToolStripButton
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
@@ -117,6 +117,12 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="ToolbarTOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
@@ -136,9 +142,44 @@
|
|||||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="BTT_UP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>False</value>
|
<value>
|
||||||
</metadata>
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEuSURBVDhPpZM9S8NQFIajg1b9BW6CoOLiV6Uu/gcF/RH+
|
||||||
|
gYa6dBQXQQyNttXNL3DUSRehxUEouLSjm2MzSCJ+lMdzaGggTWiiF1443POeh/fAvQZvDbjYgKstuN5O
|
||||||
|
JvVebvLz+oihBfYSHC+nUzmLkx8SgNL04mQlncqrOIURAWikvwJ2MwMAR7PSk/WiegMB1hzc7kgtPXux
|
||||||
|
vx8L0PpwGh4K8PkOjdNukjAkEqBxdfjehO8PeufZFsiMQBbEl40B6LAaavv+VOg0b6C6FiTpA+jw2Tqd
|
||||||
|
l3Pcuo1XswLVS7hPFbySAKz5borIFeRxdA6mcIvjeCG5xQm8vUnfGwfwIVRz8er54gBJFQD+85RHBaCf
|
||||||
|
yd8plSo5HHMYQ79kO58RmkgiJZJ42+YYX607fgE+Y9hMRvWbWAAAAABJRU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="BTT_DOWN.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFASURBVDhPrZO7SgNBFEDXBxp/wVZNERRf0TT+gwr6B9aW
|
||||||
|
WSIolja+VpbERFsfiJAiCiIigrWdRmzsrDSLElA2Mcd7JSFCNrpRFw47M3vvmTuzMwYPV7AzAXtTsD/t
|
||||||
|
D43dnaR4f4GhDeKDkBhqjGQYJ9okArXpwOZwYyRHcGJtItCSfiuYC/y7QN5WD6x31WJ1S9yAxITrCOL9
|
||||||
|
sD0G1wdwm4abwypZ6d9lZOfHwe6tI0jIn1DJ5RJeT/58heeFTkp2nyRLFZ5LUImWe2pC4bWcKsnH8zzO
|
||||||
|
tuAuyzIk8Zs9UIm0VXIWg7cX8ieLkmzgrgVhK1KNqyuoYId4T8/wZLZSWJWZvyYrPwqEkhWkuBGC1Gjt
|
||||||
|
dz+CTypr9hgvC/5ylNtFoJdJD4fO1AipCI7ZjKFXMhcNiE2QknwhsTmzAzd7xAdy1dicvhZiDAAAAABJ
|
||||||
|
RU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="BTT_FIND.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
|
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||||
|
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||||
|
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||||
|
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||||
|
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||||
|
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||||
|
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||||
|
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||||
|
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||||
|
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
<data name="BTT_CLEAR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="BTT_CLEAR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||||
191
SCrawler/Download/DownloadedInfoForm.vb
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.ComponentModel
|
||||||
|
Imports PersonalUtilities.Forms
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Namespace DownloadObjects
|
||||||
|
Friend Class DownloadedInfoForm
|
||||||
|
Friend Event OnUserLooking(ByVal Key As String)
|
||||||
|
Private MyView As FormsView
|
||||||
|
Private ReadOnly LParams As New ListAddParams(LAP.IgnoreICopier) With {.e = EDP.None}
|
||||||
|
Friend Enum ViewModes As Integer
|
||||||
|
Session = 0
|
||||||
|
All = 1
|
||||||
|
End Enum
|
||||||
|
Friend Property ViewMode As ViewModes
|
||||||
|
Get
|
||||||
|
Return IIf(MENU_VIEW_ALL.Checked, ViewModes.All, ViewModes.Session)
|
||||||
|
End Get
|
||||||
|
Set(ByVal SMode As ViewModes)
|
||||||
|
Settings.InfoViewMode.Value = CInt(SMode)
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private ReadOnly _TempUsersList As List(Of IUserData)
|
||||||
|
Friend Sub New()
|
||||||
|
InitializeComponent()
|
||||||
|
_TempUsersList = New List(Of IUserData)
|
||||||
|
If Settings.InfoViewMode.Value = CInt(ViewModes.All) Then
|
||||||
|
MENU_VIEW_SESSION.Checked = False
|
||||||
|
MENU_VIEW_ALL.Checked = True
|
||||||
|
Else
|
||||||
|
MENU_VIEW_SESSION.Checked = True
|
||||||
|
MENU_VIEW_ALL.Checked = False
|
||||||
|
End If
|
||||||
|
Settings.InfoViewMode.Value = ViewMode
|
||||||
|
RefillList()
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadedInfoForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
Try
|
||||||
|
If MyView Is Nothing Then
|
||||||
|
MyView = New FormsView(Me)
|
||||||
|
MyView.ImportFromXML(Settings.Design)
|
||||||
|
MyView.SetMeSize()
|
||||||
|
End If
|
||||||
|
BTT_CLEAR.Visible = ViewMode = ViewModes.Session
|
||||||
|
RefillList()
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadedInfoForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||||
|
e.Cancel = True
|
||||||
|
Hide()
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadedInfoForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||||
|
If Not MyView Is Nothing Then MyView.Dispose(Settings.Design)
|
||||||
|
_TempUsersList.Clear()
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadedInfoForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||||
|
Dim b As Boolean = True
|
||||||
|
Select Case e.KeyCode
|
||||||
|
Case Keys.F5 : RefillList()
|
||||||
|
Case Keys.F2 : UpdateNavigationButtons(1)
|
||||||
|
Case Keys.F3 : UpdateNavigationButtons(-1)
|
||||||
|
Case Keys.F4 : BTT_FIND.PerformClick()
|
||||||
|
Case Keys.Enter : LIST_DOWN_MouseDoubleClick(Nothing, Nothing)
|
||||||
|
Case Else : b = False
|
||||||
|
End Select
|
||||||
|
If b Then e.Handled = True
|
||||||
|
End Sub
|
||||||
|
Private Class UsersDateOrder : Implements IComparer(Of IUserData)
|
||||||
|
Friend Function Compare(ByVal x As IUserData, ByVal y As IUserData) As Integer Implements IComparer(Of IUserData).Compare
|
||||||
|
Dim xv& = If(DirectCast(x, UserDataBase).LastUpdated.HasValue, DirectCast(x, UserDataBase).LastUpdated.Value.Ticks, 0)
|
||||||
|
Dim yv& = If(DirectCast(y, UserDataBase).LastUpdated.HasValue, DirectCast(y, UserDataBase).LastUpdated.Value.Ticks, 0)
|
||||||
|
Return xv.CompareTo(yv) * -1
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
|
Private Sub RefillList()
|
||||||
|
Try
|
||||||
|
_TempUsersList.Clear()
|
||||||
|
Dim lClear As Action = Sub() LIST_DOWN.Items.Clear()
|
||||||
|
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(lClear) Else lClear.Invoke
|
||||||
|
If ViewMode = ViewModes.Session Then
|
||||||
|
_TempUsersList.ListAddList(Downloader.Downloaded, LParams)
|
||||||
|
Else
|
||||||
|
_TempUsersList.ListAddList(Settings.Users.SelectMany(Of IUserData) _
|
||||||
|
(Function(u) If(u.IsCollection, DirectCast(u, API.UserDataBind).Collections, {u})), LParams)
|
||||||
|
End If
|
||||||
|
If _TempUsersList.Count > 0 Then
|
||||||
|
_TempUsersList.Sort(New UsersDateOrder)
|
||||||
|
For Each user As IUserData In _TempUsersList
|
||||||
|
If LIST_DOWN.InvokeRequired Then
|
||||||
|
LIST_DOWN.Invoke(Sub() LIST_DOWN.Items.Add(user.DownloadedInformation))
|
||||||
|
Else
|
||||||
|
LIST_DOWN.Items.Add(user.DownloadedInformation)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
If _LatestSelected >= 0 AndAlso _LatestSelected <= LIST_DOWN.Items.Count - 1 Then
|
||||||
|
Dim aSel As Action = Sub() LIST_DOWN.SelectedIndex = _LatestSelected
|
||||||
|
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(aSel) Else aSel.Invoke
|
||||||
|
Else
|
||||||
|
_LatestSelected = -1
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
_LatestSelected = -1
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[DownloadedInfoForm.RefillList]")
|
||||||
|
Finally
|
||||||
|
UpdateNavigationButtons(Nothing)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub MENU_VIEW_SESSION_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_SESSION.Click
|
||||||
|
MENU_VIEW_SESSION.Checked = True
|
||||||
|
MENU_VIEW_ALL.Checked = False
|
||||||
|
ViewMode = ViewModes.Session
|
||||||
|
BTT_CLEAR.Visible = True
|
||||||
|
RefillList()
|
||||||
|
End Sub
|
||||||
|
Private Sub MENU_VIEW_ALL_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_ALL.Click
|
||||||
|
MENU_VIEW_SESSION.Checked = False
|
||||||
|
MENU_VIEW_ALL.Checked = True
|
||||||
|
ViewMode = ViewModes.All
|
||||||
|
BTT_CLEAR.Visible = False
|
||||||
|
RefillList()
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_REFRESH_Click(sender As Object, e As EventArgs) Handles BTT_REFRESH.Click
|
||||||
|
RefillList()
|
||||||
|
End Sub
|
||||||
|
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 OnUserLooking(Settings.Users(i).Key)
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
|
||||||
|
If LIST_DOWN.Items.Count > 0 Then
|
||||||
|
Downloader.Downloaded.Clear()
|
||||||
|
RefillList()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private _LatestSelected As Integer = -1
|
||||||
|
Private Sub LIST_DOWN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_DOWN.SelectedIndexChanged
|
||||||
|
_LatestSelected = LIST_DOWN.SelectedIndex
|
||||||
|
UpdateNavigationButtons(Nothing)
|
||||||
|
End Sub
|
||||||
|
Private Sub LIST_DOWN_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_DOWN.MouseDoubleClick
|
||||||
|
Try
|
||||||
|
If _LatestSelected >= 0 AndAlso _LatestSelected <= _TempUsersList.Count - 1 AndAlso
|
||||||
|
Not DirectCast(_TempUsersList(_LatestSelected), UserDataBase).Disposed Then _TempUsersList(_LatestSelected).OpenFolder()
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Friend Sub Downloader_OnDownloadCountChange()
|
||||||
|
If ViewMode = ViewModes.Session Then RefillList()
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_UP_Click(sender As Object, e As EventArgs) Handles BTT_UP.Click
|
||||||
|
UpdateNavigationButtons(-1)
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||||
|
UpdateNavigationButtons(1)
|
||||||
|
End Sub
|
||||||
|
Private Sub UpdateNavigationButtons(ByVal Offset As Integer?)
|
||||||
|
Dim u As Boolean = False, d As Boolean = False
|
||||||
|
With LIST_DOWN
|
||||||
|
If .Items.Count > 0 Then
|
||||||
|
u = _LatestSelected > 0
|
||||||
|
d = _LatestSelected < .Items.Count - 1
|
||||||
|
End If
|
||||||
|
Dim a As Action = Sub()
|
||||||
|
BTT_UP.Enabled = u
|
||||||
|
BTT_DOWN.Enabled = d
|
||||||
|
End Sub
|
||||||
|
If ToolbarTOP.InvokeRequired Then ToolbarTOP.Invoke(a) Else a.Invoke
|
||||||
|
a = Nothing
|
||||||
|
If Offset.HasValue AndAlso .Items.Count > 0 AndAlso
|
||||||
|
(_LatestSelected + Offset.Value).ValueBetween(0, .Items.Count - 1) Then a = Sub() .SelectedIndex = _LatestSelected + Offset.Value
|
||||||
|
If Not a Is Nothing Then
|
||||||
|
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(a) Else a.Invoke
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
434
SCrawler/Download/TDownloader.vb
Normal file
@@ -0,0 +1,434 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Threading
|
||||||
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports EOptions = PersonalUtilities.Forms.Toolbars.IMyProgress.EnableOptions
|
||||||
|
Imports SCrawler.API
|
||||||
|
Imports SCrawler.API.Base
|
||||||
|
Imports SCrawler.Plugin.Hosts
|
||||||
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Namespace DownloadObjects
|
||||||
|
Friend Class TDownloader : Implements IDisposable
|
||||||
|
Friend Event OnJobsChange(ByVal JobsCount As Integer)
|
||||||
|
Friend Event OnDownloadCountChange()
|
||||||
|
Friend Event OnDownloading(ByVal Value As Boolean)
|
||||||
|
Friend Event SendNotification(ByVal Message As String)
|
||||||
|
Friend Event OnReconfigured()
|
||||||
|
Friend ReadOnly Property Downloaded As List(Of IUserData)
|
||||||
|
Private ReadOnly NProv As IFormatProvider
|
||||||
|
Friend ReadOnly Property Working As Boolean
|
||||||
|
Get
|
||||||
|
Return Pool.Count > 0 AndAlso Pool.Exists(Function(j) j.Working)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
#Region "Jobs"
|
||||||
|
Friend Class Job : Implements IDisposable
|
||||||
|
Friend Event OnItemsCountChange(ByVal Sender As Job, ByVal Count As Integer)
|
||||||
|
Private ReadOnly Hosts As List(Of SettingsHost)
|
||||||
|
Private ReadOnly Keys As List(Of String)
|
||||||
|
Private ReadOnly RemovingKeys As List(Of String)
|
||||||
|
Private TokenSource As CancellationTokenSource
|
||||||
|
Friend Token As CancellationToken
|
||||||
|
Private [Thread] As Thread
|
||||||
|
Private _Working As Boolean
|
||||||
|
Friend ReadOnly Property Items As List(Of IUserData)
|
||||||
|
Friend ReadOnly Property [Type] As Download
|
||||||
|
Friend ReadOnly Property Count As Integer
|
||||||
|
Get
|
||||||
|
Return Items.Count
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property Working As Boolean
|
||||||
|
Get
|
||||||
|
Return _Working OrElse If(Thread?.IsAlive, False)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property IsSeparated As Boolean
|
||||||
|
Get
|
||||||
|
Return Hosts.Count = 1 AndAlso Hosts(0).IsSeparatedTasks
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property Name As String
|
||||||
|
Get
|
||||||
|
Return Hosts(0).Name
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property TaskCount As Integer
|
||||||
|
Get
|
||||||
|
Return Hosts(0).TaskCount
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend ReadOnly Property Host As SettingsHost
|
||||||
|
Get
|
||||||
|
If Hosts.Count > 0 Then
|
||||||
|
Dim k$ = Hosts(0).Key
|
||||||
|
Dim i% = Settings.Plugins.FindIndex(Function(p) p.Key = k)
|
||||||
|
If i >= 0 Then Return Settings.Plugins(i).Settings
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Property Progress As MyProgress
|
||||||
|
Friend Sub New(ByVal JobType As Download)
|
||||||
|
Hosts = New List(Of SettingsHost)
|
||||||
|
RemovingKeys = New List(Of String)
|
||||||
|
Keys = New List(Of String)
|
||||||
|
Items = New List(Of IUserData)
|
||||||
|
[Type] = JobType
|
||||||
|
End Sub
|
||||||
|
Friend Function Add(ByVal User As IUserData) As Boolean
|
||||||
|
With DirectCast(User, UserDataBase)
|
||||||
|
If Keys.Count > 0 Then
|
||||||
|
Dim i% = Keys.IndexOf(.User.Plugin)
|
||||||
|
If i >= 0 Then
|
||||||
|
Items.Add(User)
|
||||||
|
RaiseEvent OnItemsCountChange(Me, Count)
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
If RemovingKeys.Count > 0 Then Return RemovingKeys.IndexOf(.User.Plugin) >= 0
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
Friend Sub AddHost(ByRef h As SettingsHost)
|
||||||
|
Hosts.Add(h)
|
||||||
|
Keys.Add(h.Key)
|
||||||
|
End Sub
|
||||||
|
Friend Function UserHost(ByVal User As IUserData) As SettingsHost
|
||||||
|
Dim i% = Keys.IndexOf(DirectCast(User, UserDataBase).User.Plugin)
|
||||||
|
If i >= 0 Then Return Hosts(i) Else Throw New KeyNotFoundException($"Plugin key [{DirectCast(User, UserDataBase).User.Plugin}] not found")
|
||||||
|
End Function
|
||||||
|
Friend Function Available() As Boolean
|
||||||
|
If Hosts.Count > 0 Then
|
||||||
|
Dim k$
|
||||||
|
For i% = Hosts.Count - 1 To 0 Step -1
|
||||||
|
If Not Hosts(i).Available(Type) Then
|
||||||
|
k = Hosts(i).Key
|
||||||
|
If Not RemovingKeys.Contains(k) Then RemovingKeys.Add(k)
|
||||||
|
Hosts(i).DownloadDone(Type)
|
||||||
|
Hosts.RemoveAt(i)
|
||||||
|
Keys.RemoveAt(i)
|
||||||
|
If Items.Count > 0 Then Items.RemoveAll(Function(u) DirectCast(u, UserDataBase).HOST.Key = k)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
Return Hosts.Count > 0
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Friend Sub ThrowIfCancellationRequested()
|
||||||
|
Token.ThrowIfCancellationRequested()
|
||||||
|
End Sub
|
||||||
|
Friend ReadOnly Property IsCancellationRequested As Boolean
|
||||||
|
Get
|
||||||
|
Return Token.IsCancellationRequested
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
Friend Sub [Start](ByVal [ThreadStart] As ThreadStart)
|
||||||
|
Thread = New Thread(ThreadStart) With {.IsBackground = True}
|
||||||
|
Thread.SetApartmentState(ApartmentState.MTA)
|
||||||
|
Thread.Start()
|
||||||
|
End Sub
|
||||||
|
Friend Sub [Start]()
|
||||||
|
If Hosts.Count > 0 Then Hosts.ForEach(Sub(h) h.DownloadStarted([Type]))
|
||||||
|
TokenSource = New CancellationTokenSource
|
||||||
|
Token = TokenSource.Token
|
||||||
|
_Working = True
|
||||||
|
End Sub
|
||||||
|
Friend Sub [Stop]()
|
||||||
|
If Not TokenSource Is Nothing Then TokenSource.Cancel()
|
||||||
|
End Sub
|
||||||
|
Friend Sub Stopped()
|
||||||
|
_Working = False
|
||||||
|
TokenSource = Nothing
|
||||||
|
Try
|
||||||
|
If Not Thread Is Nothing Then
|
||||||
|
If Thread.IsAlive Then Thread.Abort()
|
||||||
|
Thread = Nothing
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
If Hosts.Count > 0 Then Hosts.ForEach(Sub(h) h.DownloadDone([Type]))
|
||||||
|
End Sub
|
||||||
|
#Region "IDisposable Support"
|
||||||
|
Private disposedValue As Boolean = False
|
||||||
|
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue Then
|
||||||
|
If disposing Then
|
||||||
|
Hosts.Clear()
|
||||||
|
Keys.Clear()
|
||||||
|
RemovingKeys.Clear()
|
||||||
|
Items.Clear()
|
||||||
|
End If
|
||||||
|
disposedValue = True
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Sub Finalize()
|
||||||
|
Dispose(False)
|
||||||
|
MyBase.Finalize()
|
||||||
|
End Sub
|
||||||
|
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
|
||||||
|
Dispose(True)
|
||||||
|
GC.SuppressFinalize(Me)
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
End Class
|
||||||
|
Friend ReadOnly Pool As List(Of Job)
|
||||||
|
#End Region
|
||||||
|
Friend Sub New()
|
||||||
|
Downloaded = New List(Of IUserData)
|
||||||
|
NProv = New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
|
||||||
|
Pool = New List(Of Job)
|
||||||
|
End Sub
|
||||||
|
Friend Sub ReconfPool()
|
||||||
|
If Pool.Count = 0 OrElse Not Pool.Exists(Function(j) j.Working Or j.Count > 0) Then
|
||||||
|
Pool.ListClearDispose
|
||||||
|
If Settings.Plugins.Count > 0 Then
|
||||||
|
Pool.Add(New Job(Download.Main))
|
||||||
|
For Each p As PluginHost In Settings.Plugins
|
||||||
|
If p.Settings.IsSeparatedTasks Then
|
||||||
|
Pool.Add(New Job(Download.Main))
|
||||||
|
Pool.Last.AddHost(p.Settings)
|
||||||
|
Else
|
||||||
|
Pool(0).AddHost(p.Settings)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
RaiseEvent OnReconfigured()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private CheckerThread As Thread
|
||||||
|
Private Sub [Start]()
|
||||||
|
If Not MyProgressForm.Opened AndAlso Pool.LongCount(Function(p) p.Count > 0) > 1 Then MyProgressForm.Show()
|
||||||
|
If Not If(CheckerThread?.IsAlive, False) Then
|
||||||
|
MainProgress.Enabled = True
|
||||||
|
CheckerThread = New Thread(New ThreadStart(AddressOf JobsChecker))
|
||||||
|
CheckerThread.SetApartmentState(ApartmentState.MTA)
|
||||||
|
CheckerThread.Start()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub JobsChecker()
|
||||||
|
Try
|
||||||
|
MainProgress.TotalCount = 0
|
||||||
|
Do While Pool.Exists(Function(p) p.Count > 0)
|
||||||
|
For Each j As Job In Pool
|
||||||
|
If j.Count > 0 And Not j.Working Then j.Start(New ThreadStart(Sub() StartDownloading(j)))
|
||||||
|
Next
|
||||||
|
Thread.Sleep(200)
|
||||||
|
Loop
|
||||||
|
Catch ex As Exception
|
||||||
|
Finally
|
||||||
|
With MainProgress
|
||||||
|
.TotalCount = 0
|
||||||
|
.CurrentCounter = 0
|
||||||
|
.InformationTemporary = "All data downloaded"
|
||||||
|
.Enabled(EOptions.ProgressBar) = False
|
||||||
|
End With
|
||||||
|
If Pool.Count > 0 Then Pool.ForEach(Sub(p) If Not p.Progress Is Nothing Then p.Progress.TotalCount = 0)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub StartDownloading(ByRef _Job As Job)
|
||||||
|
RaiseEvent OnDownloading(True)
|
||||||
|
Dim isSeparated As Boolean = _Job.IsSeparated
|
||||||
|
Dim n$ = _Job.Name
|
||||||
|
Dim pt As Func(Of String, String) = Function(ByVal t As String) As String
|
||||||
|
Dim _t$ = If(isSeparated, $"{n} {Left(t, 1).ToLower}{Right(t, t.Length - 1)}", t)
|
||||||
|
RaiseEvent SendNotification(_t)
|
||||||
|
Return _t
|
||||||
|
End Function
|
||||||
|
Try
|
||||||
|
_Job.Start()
|
||||||
|
_Job.Progress.TotalCount = 0
|
||||||
|
_Job.Progress.CurrentCounter = 0
|
||||||
|
_Job.Progress.Enabled = True
|
||||||
|
Dim SiteChecked As Boolean = False
|
||||||
|
Do While _Job.Count > 0
|
||||||
|
_Job.ThrowIfCancellationRequested()
|
||||||
|
If Not SiteChecked Then
|
||||||
|
If Not _Job.Available Then Exit Sub Else SiteChecked = True : Continue Do
|
||||||
|
End If
|
||||||
|
UpdateJobsLabel()
|
||||||
|
DownloadData(_Job, _Job.Token)
|
||||||
|
_Job.ThrowIfCancellationRequested()
|
||||||
|
Thread.Sleep(500)
|
||||||
|
Loop
|
||||||
|
_Job.Progress.InformationTemporary = pt("All data downloaded")
|
||||||
|
Catch oex As OperationCanceledException When _Job.IsCancellationRequested
|
||||||
|
_Job.Progress.InformationTemporary = pt("Downloading canceled")
|
||||||
|
Catch ex As Exception
|
||||||
|
_Job.Progress.InformationTemporary = pt("Downloading error")
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, ex, "TDownloader.Start")
|
||||||
|
Finally
|
||||||
|
_Job.Stopped()
|
||||||
|
UpdateJobsLabel()
|
||||||
|
RaiseEvent OnDownloading(False)
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Friend Sub [Stop]()
|
||||||
|
If Pool.Count > 0 Then
|
||||||
|
For Each j As Job In Pool
|
||||||
|
If j.Working Then j.Stop()
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub UpdateJobsLabel()
|
||||||
|
RaiseEvent OnJobsChange(Pool.Sum(Function(j) j.Count))
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadData(ByRef _Job As Job, ByVal Token As CancellationToken)
|
||||||
|
Try
|
||||||
|
If _Job.Count > 0 Then
|
||||||
|
Const nf As ANumbers.Formats = ANumbers.Formats.Number
|
||||||
|
Dim t As New List(Of Task)
|
||||||
|
Dim i% = 0
|
||||||
|
Dim limit% = _Job.TaskCount
|
||||||
|
Dim Keys As New List(Of String)
|
||||||
|
Dim h As Boolean = False
|
||||||
|
Dim host As SettingsHost = Nothing
|
||||||
|
For Each _Item As IUserData In _Job.Items
|
||||||
|
If Not _Item.Disposed Then
|
||||||
|
Keys.Add(_Item.Key)
|
||||||
|
host = _Job.UserHost(_Item)
|
||||||
|
If host.Source.ReadyToDownload(Download.Main) Then
|
||||||
|
host.BeforeStartDownload(_Item, Download.Main)
|
||||||
|
_Job.ThrowIfCancellationRequested()
|
||||||
|
DirectCast(_Item, UserDataBase).Progress = _Job.Progress
|
||||||
|
t.Add(Task.Run(Sub() _Item.DownloadData(Token)))
|
||||||
|
i += 1
|
||||||
|
If i >= limit Then Exit For
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
If t.Count > 0 Or Keys.Count > 0 Then
|
||||||
|
With _Job.Progress
|
||||||
|
.Enabled(EOptions.All) = True
|
||||||
|
.Information = IIf(_Job.IsSeparated, $"{_Job.Name} d", "D")
|
||||||
|
.Information &= $"ownloading {t.Count.NumToString(nf, NProv)}/{_Job.Items.Count.NumToString(nf, NProv)} profiles' data"
|
||||||
|
.InformationTemporary = .Information
|
||||||
|
End With
|
||||||
|
If t.Count > 0 Then Task.WaitAll(t.ToArray)
|
||||||
|
Dim dcc As Boolean = False
|
||||||
|
If Keys.Count > 0 Then
|
||||||
|
For Each k$ In Keys
|
||||||
|
i = _Job.Items.FindIndex(Function(ii) ii.Key = k)
|
||||||
|
If i >= 0 Then
|
||||||
|
With _Job.Items(i)
|
||||||
|
host.AfterDownload(_Job.Items(i), Download.Main)
|
||||||
|
If Not .Disposed AndAlso Not .IsCollection AndAlso .DownloadedTotal(False) > 0 Then
|
||||||
|
If Not Downloaded.Contains(.Self) Then Downloaded.Add(GetUserFromMainCollection(.Self))
|
||||||
|
dcc = True
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
_Job.Items.RemoveAt(i)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Keys.Clear()
|
||||||
|
_Job.Items.RemoveAll(Function(ii) ii.Disposed)
|
||||||
|
If dcc Then Downloaded.RemoveAll(Function(u) u Is Nothing)
|
||||||
|
If dcc And Downloaded.Count > 0 Then RaiseEvent OnDownloadCountChange()
|
||||||
|
t.Clear()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Catch aoex As ArgumentOutOfRangeException
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, aoex, $"TDownloader.DownloadData: index out of range ({_Job.Count})")
|
||||||
|
Catch oex As OperationCanceledException When _Job.IsCancellationRequested
|
||||||
|
Catch ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.SendInLog, ex, "TDownloader.DownloadData")
|
||||||
|
Finally
|
||||||
|
If Settings.UserListUpdateRequired Then _
|
||||||
|
Task.WaitAll(Task.Run(Sub()
|
||||||
|
While Settings.UserListUpdateRequired : Settings.UpdateUsersList() : End While
|
||||||
|
End Sub))
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Function GetUserFromMainCollection(ByVal User As IUserData) As IUserData
|
||||||
|
Dim uSimple As Predicate(Of IUserData) = Function(u) u.Equals(DirectCast(User, UserDataBase))
|
||||||
|
Dim uCol As Predicate(Of IUserData) = Function(ByVal u As IUserData) As Boolean
|
||||||
|
If u.IsCollection Then
|
||||||
|
Return DirectCast(u, UserDataBind).Collections.Exists(uSimple)
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Dim uu As Predicate(Of IUserData)
|
||||||
|
If User.IncludedInCollection Then uu = uCol Else uu = uSimple
|
||||||
|
Dim i% = Settings.Users.FindIndex(uu)
|
||||||
|
If i >= 0 Then
|
||||||
|
If Settings.Users(i).IsCollection Then
|
||||||
|
With DirectCast(Settings.Users(i), UserDataBind)
|
||||||
|
i = .Collections.FindIndex(uSimple)
|
||||||
|
If i >= 0 Then Return .Collections(i)
|
||||||
|
End With
|
||||||
|
Else
|
||||||
|
Return Settings.Users(i)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Private Sub AddItem(ByVal Item As IUserData, ByVal _UpdateJobsLabel As Boolean)
|
||||||
|
ReconfPool()
|
||||||
|
If Item.IsCollection Then
|
||||||
|
Item.DownloadData(Nothing)
|
||||||
|
Else
|
||||||
|
If Not Contains(Item) Then
|
||||||
|
If Pool.Count > 0 Then
|
||||||
|
For i% = 0 To Pool.Count - 1
|
||||||
|
If Pool(i).Add(Item) Then Exit For
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
If _UpdateJobsLabel Then UpdateJobsLabel()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Friend Sub Add(ByVal Item As IUserData)
|
||||||
|
AddItem(Item, True)
|
||||||
|
Start()
|
||||||
|
End Sub
|
||||||
|
Friend Sub AddRange(ByVal _Items As IEnumerable(Of IUserData))
|
||||||
|
If _Items.ListExists Then
|
||||||
|
For i% = 0 To _Items.Count - 1 : AddItem(_Items(i), False) : Next
|
||||||
|
UpdateJobsLabel()
|
||||||
|
End If
|
||||||
|
Start()
|
||||||
|
End Sub
|
||||||
|
Private Function Contains(ByVal _Item As IUserData)
|
||||||
|
If Pool.Count > 0 Then
|
||||||
|
For Each j As Job In Pool
|
||||||
|
If j.Items.Count > 0 AndAlso j.Items.Contains(_Item) Then Return True
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Return False
|
||||||
|
End Function
|
||||||
|
Friend Sub UserRemove(ByVal _Item As IUserData)
|
||||||
|
If Downloaded.Count > 0 AndAlso Downloaded.Contains(_Item) Then Downloaded.Remove(_Item) : RaiseEvent OnDownloadCountChange()
|
||||||
|
End Sub
|
||||||
|
#Region "IDisposable Support"
|
||||||
|
Private disposedValue As Boolean = False
|
||||||
|
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
|
||||||
|
If Not disposedValue Then
|
||||||
|
If disposing Then
|
||||||
|
[Stop]()
|
||||||
|
Pool.ListClearDispose
|
||||||
|
Downloaded.Clear()
|
||||||
|
End If
|
||||||
|
disposedValue = True
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Protected Overrides Sub Finalize()
|
||||||
|
Dispose(False)
|
||||||
|
MyBase.Finalize()
|
||||||
|
End Sub
|
||||||
|
Friend Overloads Sub Dispose() Implements IDisposable.Dispose
|
||||||
|
Dispose(True)
|
||||||
|
GC.SuppressFinalize(Me)
|
||||||
|
End Sub
|
||||||
|
#End Region
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
160
SCrawler/Download/VideosDownloaderForm.Designer.vb
generated
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
Namespace DownloadObjects
|
||||||
|
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||||
|
Partial Friend Class VideosDownloaderForm : 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 SEP_1 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
|
||||||
|
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
|
||||||
|
Me.BTT_ADD = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_ADD_LIST = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_DELETE = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_DOWN = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.BTT_OPEN_PATH = New System.Windows.Forms.ToolStripButton()
|
||||||
|
Me.ToolbarBOTTOM = New System.Windows.Forms.StatusStrip()
|
||||||
|
Me.PR_V = New System.Windows.Forms.ToolStripProgressBar()
|
||||||
|
Me.LBL_STATUS = New System.Windows.Forms.ToolStripStatusLabel()
|
||||||
|
Me.LIST_VIDEOS = New System.Windows.Forms.ListBox()
|
||||||
|
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||||
|
Me.ToolbarTOP.SuspendLayout()
|
||||||
|
Me.ToolbarBOTTOM.SuspendLayout()
|
||||||
|
Me.SuspendLayout()
|
||||||
|
'
|
||||||
|
'SEP_1
|
||||||
|
'
|
||||||
|
SEP_1.Name = "SEP_1"
|
||||||
|
SEP_1.Size = New System.Drawing.Size(6, 25)
|
||||||
|
'
|
||||||
|
'SEP_2
|
||||||
|
'
|
||||||
|
SEP_2.Name = "SEP_2"
|
||||||
|
SEP_2.Size = New System.Drawing.Size(6, 25)
|
||||||
|
'
|
||||||
|
'ToolbarTOP
|
||||||
|
'
|
||||||
|
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||||
|
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_ADD, Me.BTT_ADD_LIST, Me.BTT_DELETE, SEP_1, Me.BTT_DOWN, SEP_2, Me.BTT_OPEN_PATH})
|
||||||
|
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
|
||||||
|
Me.ToolbarTOP.Name = "ToolbarTOP"
|
||||||
|
Me.ToolbarTOP.Size = New System.Drawing.Size(524, 25)
|
||||||
|
Me.ToolbarTOP.TabIndex = 0
|
||||||
|
'
|
||||||
|
'BTT_ADD
|
||||||
|
'
|
||||||
|
Me.BTT_ADD.AutoToolTip = False
|
||||||
|
Me.BTT_ADD.Image = Global.SCrawler.My.Resources.Resources.PlusPIC
|
||||||
|
Me.BTT_ADD.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_ADD.Name = "BTT_ADD"
|
||||||
|
Me.BTT_ADD.Size = New System.Drawing.Size(75, 22)
|
||||||
|
Me.BTT_ADD.Text = "Add (Ins)"
|
||||||
|
'
|
||||||
|
'BTT_ADD_LIST
|
||||||
|
'
|
||||||
|
Me.BTT_ADD_LIST.AutoToolTip = False
|
||||||
|
Me.BTT_ADD_LIST.Image = Global.SCrawler.My.Resources.Resources.PlusPIC
|
||||||
|
Me.BTT_ADD_LIST.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_ADD_LIST.Name = "BTT_ADD_LIST"
|
||||||
|
Me.BTT_ADD_LIST.Size = New System.Drawing.Size(67, 22)
|
||||||
|
Me.BTT_ADD_LIST.Text = "Add list"
|
||||||
|
'
|
||||||
|
'BTT_DELETE
|
||||||
|
'
|
||||||
|
Me.BTT_DELETE.AutoToolTip = False
|
||||||
|
Me.BTT_DELETE.Image = Global.SCrawler.My.Resources.Resources.Delete
|
||||||
|
Me.BTT_DELETE.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_DELETE.Name = "BTT_DELETE"
|
||||||
|
Me.BTT_DELETE.Size = New System.Drawing.Size(83, 22)
|
||||||
|
Me.BTT_DELETE.Text = "Delete (F8)"
|
||||||
|
'
|
||||||
|
'BTT_DOWN
|
||||||
|
'
|
||||||
|
Me.BTT_DOWN.AutoToolTip = False
|
||||||
|
Me.BTT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_01_Green_16
|
||||||
|
Me.BTT_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_DOWN.Name = "BTT_DOWN"
|
||||||
|
Me.BTT_DOWN.Size = New System.Drawing.Size(104, 22)
|
||||||
|
Me.BTT_DOWN.Text = "Download (F5)"
|
||||||
|
'
|
||||||
|
'BTT_OPEN_PATH
|
||||||
|
'
|
||||||
|
Me.BTT_OPEN_PATH.AutoToolTip = False
|
||||||
|
Me.BTT_OPEN_PATH.Image = Global.SCrawler.My.Resources.Resources.Folder_32
|
||||||
|
Me.BTT_OPEN_PATH.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||||
|
Me.BTT_OPEN_PATH.Name = "BTT_OPEN_PATH"
|
||||||
|
Me.BTT_OPEN_PATH.Size = New System.Drawing.Size(120, 22)
|
||||||
|
Me.BTT_OPEN_PATH.Text = "Open saving path"
|
||||||
|
'
|
||||||
|
'ToolbarBOTTOM
|
||||||
|
'
|
||||||
|
Me.ToolbarBOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_V, Me.LBL_STATUS})
|
||||||
|
Me.ToolbarBOTTOM.Location = New System.Drawing.Point(0, 339)
|
||||||
|
Me.ToolbarBOTTOM.Name = "ToolbarBOTTOM"
|
||||||
|
Me.ToolbarBOTTOM.Size = New System.Drawing.Size(524, 22)
|
||||||
|
Me.ToolbarBOTTOM.TabIndex = 1
|
||||||
|
'
|
||||||
|
'PR_V
|
||||||
|
'
|
||||||
|
Me.PR_V.Name = "PR_V"
|
||||||
|
Me.PR_V.Size = New System.Drawing.Size(200, 16)
|
||||||
|
Me.PR_V.Visible = False
|
||||||
|
'
|
||||||
|
'LBL_STATUS
|
||||||
|
'
|
||||||
|
Me.LBL_STATUS.Name = "LBL_STATUS"
|
||||||
|
Me.LBL_STATUS.Size = New System.Drawing.Size(0, 17)
|
||||||
|
'
|
||||||
|
'LIST_VIDEOS
|
||||||
|
'
|
||||||
|
Me.LIST_VIDEOS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.LIST_VIDEOS.FormattingEnabled = True
|
||||||
|
Me.LIST_VIDEOS.Location = New System.Drawing.Point(0, 25)
|
||||||
|
Me.LIST_VIDEOS.Name = "LIST_VIDEOS"
|
||||||
|
Me.LIST_VIDEOS.Size = New System.Drawing.Size(524, 314)
|
||||||
|
Me.LIST_VIDEOS.TabIndex = 2
|
||||||
|
'
|
||||||
|
'VideosDownloaderForm
|
||||||
|
'
|
||||||
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
|
Me.ClientSize = New System.Drawing.Size(524, 361)
|
||||||
|
Me.Controls.Add(Me.LIST_VIDEOS)
|
||||||
|
Me.Controls.Add(Me.ToolbarBOTTOM)
|
||||||
|
Me.Controls.Add(Me.ToolbarTOP)
|
||||||
|
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()
|
||||||
|
Me.ToolbarBOTTOM.ResumeLayout(False)
|
||||||
|
Me.ToolbarBOTTOM.PerformLayout()
|
||||||
|
Me.ResumeLayout(False)
|
||||||
|
Me.PerformLayout()
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private WithEvents ToolbarTOP As ToolStrip
|
||||||
|
Private WithEvents BTT_ADD As ToolStripButton
|
||||||
|
Private WithEvents BTT_ADD_LIST As ToolStripButton
|
||||||
|
Private WithEvents BTT_DELETE As ToolStripButton
|
||||||
|
Private WithEvents ToolbarBOTTOM As StatusStrip
|
||||||
|
Private WithEvents PR_V As ToolStripProgressBar
|
||||||
|
Private WithEvents LBL_STATUS As ToolStripStatusLabel
|
||||||
|
Private WithEvents LIST_VIDEOS As ListBox
|
||||||
|
Private WithEvents BTT_DOWN As ToolStripButton
|
||||||
|
Private WithEvents BTT_OPEN_PATH As ToolStripButton
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
142
SCrawler/Download/VideosDownloaderForm.vb
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
' Copyright (C) 2022 Andy
|
||||||
|
' This program is free software: you can redistribute it and/or modify
|
||||||
|
' it under the terms of the GNU General Public License as published by
|
||||||
|
' the Free Software Foundation, either version 3 of the License, or
|
||||||
|
' (at your option) any later version.
|
||||||
|
'
|
||||||
|
' This program is distributed in the hope that it will be useful,
|
||||||
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.ComponentModel
|
||||||
|
Imports PersonalUtilities.Forms
|
||||||
|
Namespace DownloadObjects
|
||||||
|
Friend Class VideosDownloaderForm
|
||||||
|
Private MyView As FormsView
|
||||||
|
Private ReadOnly MyPR As Toolbars.MyProgress
|
||||||
|
Private ReadOnly UrlList As List(Of String)
|
||||||
|
Private ReadOnly DownloadingUrlsFile As SFile = $"{SettingsFolderName}\VideosUrls.txt"
|
||||||
|
Friend Sub New()
|
||||||
|
InitializeComponent()
|
||||||
|
UrlList = New List(Of String)
|
||||||
|
MyPR = New Toolbars.MyProgress(ToolbarBOTTOM, PR_V, LBL_STATUS, "Downloading video")
|
||||||
|
If DownloadingUrlsFile.Exists Then _
|
||||||
|
UrlList.ListAddList(DownloadingUrlsFile.GetText.StringToList(Of String, List(Of String))(Environment.NewLine), LAP.NotContainsOnly)
|
||||||
|
End Sub
|
||||||
|
Private Sub VideosDownloaderForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||||
|
Try
|
||||||
|
MyView = New FormsView(Me)
|
||||||
|
MyView.ImportFromXML(Settings.Design)
|
||||||
|
MyView.SetMeSize()
|
||||||
|
RefillList(False)
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub VideosDownloaderForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
||||||
|
e.Cancel = True
|
||||||
|
Hide()
|
||||||
|
End Sub
|
||||||
|
Private Sub VideosDownloaderForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||||
|
If Not MyView Is Nothing Then MyView.Dispose(Settings.Design)
|
||||||
|
If UrlList.Count > 0 Then UpdateUrlsFile()
|
||||||
|
UrlList.Clear()
|
||||||
|
End Sub
|
||||||
|
Private Sub VideosDownloaderForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
||||||
|
Dim b As Boolean = True
|
||||||
|
Select Case e.KeyCode
|
||||||
|
Case Keys.Insert : AddVideo()
|
||||||
|
Case Keys.F5 : DownloadVideos()
|
||||||
|
Case Keys.F8 : BTT_DELETE_Click(Nothing, EventArgs.Empty)
|
||||||
|
Case Else : b = False
|
||||||
|
End Select
|
||||||
|
If b Then e.Handled = True
|
||||||
|
End Sub
|
||||||
|
Private Sub RefillList(Optional ByVal Update As Boolean = True)
|
||||||
|
Try
|
||||||
|
With LIST_VIDEOS
|
||||||
|
.Items.Clear()
|
||||||
|
If UrlList.Count > 0 Then UrlList.ForEach(Sub(u) .Items.Add(u))
|
||||||
|
If .Items.Count > 0 And _LatestSelected >= 0 And _LatestSelected <= .Items.Count - 1 Then .SelectedIndex = _LatestSelected
|
||||||
|
If Update Then UpdateUrlsFile()
|
||||||
|
End With
|
||||||
|
Catch ex As Exception
|
||||||
|
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "Error on list refill")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub UpdateUrlsFile()
|
||||||
|
If UrlList.Count > 0 Then
|
||||||
|
TextSaver.SaveTextToFile(UrlList.ListToString(, Environment.NewLine), DownloadingUrlsFile, True,, EDP.SendInLog)
|
||||||
|
Else
|
||||||
|
DownloadingUrlsFile.Delete(, Settings.DeleteMode, EDP.SendInLog)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_ADD_Click(sender As Object, e As EventArgs) Handles BTT_ADD.Click
|
||||||
|
AddVideo()
|
||||||
|
End Sub
|
||||||
|
Private Sub AddVideo()
|
||||||
|
Dim URL$ = GetNewVideoURL()
|
||||||
|
If Not URL.IsEmptyString Then
|
||||||
|
If Not UrlList.Contains(URL) Then
|
||||||
|
UrlList.Add(URL)
|
||||||
|
RefillList()
|
||||||
|
Else
|
||||||
|
MsgBoxE("This URL already added to list")
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_ADD_LIST_Click(sender As Object, e As EventArgs) Handles BTT_ADD_LIST.Click
|
||||||
|
Dim l$ = InputBoxE("Enter URLs (new line as delimiter):", "URLs list", GetCurrentBuffer(),,,,,, True)
|
||||||
|
If Not l.IsEmptyString Then
|
||||||
|
Dim ub% = UrlList.Count
|
||||||
|
UrlList.ListAddList(l.StringFormatLines.StringToList(Of String, List(Of String))(vbCrLf).ListForEach(Function(u, i) u.Trim,, False))
|
||||||
|
If Not UrlList.Count = ub Then RefillList()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE.Click
|
||||||
|
If _LatestSelected >= 0 And _LatestSelected <= UrlList.Count - 1 Then
|
||||||
|
If MsgBoxE({$"Do you really want to delete video URL:{vbCr}{UrlList(_LatestSelected)}", "Deleting URL..."},
|
||||||
|
MsgBoxStyle.Exclamation + MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
|
||||||
|
UrlList.RemoveAt(_LatestSelected)
|
||||||
|
RefillList()
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
MsgBoxE("URL does not selected", MsgBoxStyle.Exclamation)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||||
|
DownloadVideos()
|
||||||
|
End Sub
|
||||||
|
Private Sub DownloadVideos()
|
||||||
|
If UrlList.Count > 0 Then
|
||||||
|
MyPR.TotalCount = UrlList.Count
|
||||||
|
MyPR.Enabled = True
|
||||||
|
Dim IsFirst As Boolean = True
|
||||||
|
For i% = UrlList.Count - 1 To 0 Step -1
|
||||||
|
If DownloadVideoByURL(UrlList(i), IsFirst, True) Then UrlList.RemoveAt(i)
|
||||||
|
MyPR.Perform()
|
||||||
|
IsFirst = False
|
||||||
|
Next
|
||||||
|
MyPR.Done()
|
||||||
|
RefillList()
|
||||||
|
MyPR.Enabled = False
|
||||||
|
Else
|
||||||
|
MsgBoxE("No one video added", MsgBoxStyle.Exclamation)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Private _LatestSelected As Integer = -1
|
||||||
|
Private Sub LIST_VIDEOS_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_VIDEOS.SelectedIndexChanged
|
||||||
|
_LatestSelected = LIST_VIDEOS.SelectedIndex
|
||||||
|
End Sub
|
||||||
|
Private Sub BTT_OPEN_PATH_Click(sender As Object, e As EventArgs) Handles BTT_OPEN_PATH.Click
|
||||||
|
With Settings.LatestSavingPath
|
||||||
|
If Not .Value.IsEmptyString Then
|
||||||
|
If .Value.Exists(SFO.Path, False) Then
|
||||||
|
.Value.Open(SFO.Path, EDP.ShowMainMsg)
|
||||||
|
Else
|
||||||
|
MsgBoxE($"Path [{ .Value}] does not exists!", MsgBoxStyle.Exclamation)
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
MsgBoxE("Saving path does not set!", MsgBoxStyle.Exclamation)
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
336
SCrawler/DownloadSavedPostsForm.Designer.vb
generated
@@ -1,336 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
|
||||||
Partial Friend Class DownloadSavedPostsForm : 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 TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim TP_REDDIT As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim TP_REDDIT_PR As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim TP_INST As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim TP_INST_PR As System.Windows.Forms.TableLayoutPanel
|
|
||||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadSavedPostsForm))
|
|
||||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
|
||||||
Me.BTT_DOWN_ALL = New System.Windows.Forms.Button()
|
|
||||||
Me.BTT_STOP_ALL = New System.Windows.Forms.Button()
|
|
||||||
Me.BTT_REDDIT_START = New System.Windows.Forms.Button()
|
|
||||||
Me.BTT_REDDIT_STOP = New System.Windows.Forms.Button()
|
|
||||||
Me.PR_REDDIT = New System.Windows.Forms.ProgressBar()
|
|
||||||
Me.BTT_REDDIT_OPEN = New System.Windows.Forms.Button()
|
|
||||||
Me.LBL_REDDIT = New System.Windows.Forms.Label()
|
|
||||||
Me.BTT_INST_START = New System.Windows.Forms.Button()
|
|
||||||
Me.BTT_INST_STOP = New System.Windows.Forms.Button()
|
|
||||||
Me.PR_INST = New System.Windows.Forms.ProgressBar()
|
|
||||||
Me.BTT_INST_OPEN = New System.Windows.Forms.Button()
|
|
||||||
Me.LBL_INST = New System.Windows.Forms.Label()
|
|
||||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TP_REDDIT = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TP_REDDIT_PR = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TP_INST = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TP_INST_PR = New System.Windows.Forms.TableLayoutPanel()
|
|
||||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
|
||||||
TP_MAIN.SuspendLayout()
|
|
||||||
TP_BUTTONS.SuspendLayout()
|
|
||||||
TP_REDDIT.SuspendLayout()
|
|
||||||
TP_REDDIT_PR.SuspendLayout()
|
|
||||||
TP_INST.SuspendLayout()
|
|
||||||
TP_INST_PR.SuspendLayout()
|
|
||||||
Me.SuspendLayout()
|
|
||||||
'
|
|
||||||
'TP_MAIN
|
|
||||||
'
|
|
||||||
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Inset
|
|
||||||
TP_MAIN.ColumnCount = 1
|
|
||||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_MAIN.Controls.Add(TP_BUTTONS, 0, 0)
|
|
||||||
TP_MAIN.Controls.Add(TP_REDDIT, 0, 1)
|
|
||||||
TP_MAIN.Controls.Add(TP_INST, 0, 2)
|
|
||||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
|
||||||
TP_MAIN.Name = "TP_MAIN"
|
|
||||||
TP_MAIN.RowCount = 3
|
|
||||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_MAIN.Size = New System.Drawing.Size(484, 156)
|
|
||||||
TP_MAIN.TabIndex = 0
|
|
||||||
'
|
|
||||||
'TP_BUTTONS
|
|
||||||
'
|
|
||||||
TP_BUTTONS.ColumnCount = 2
|
|
||||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
|
||||||
TP_BUTTONS.Controls.Add(Me.BTT_DOWN_ALL, 0, 0)
|
|
||||||
TP_BUTTONS.Controls.Add(Me.BTT_STOP_ALL, 1, 0)
|
|
||||||
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_BUTTONS.Location = New System.Drawing.Point(2, 2)
|
|
||||||
TP_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
|
|
||||||
TP_BUTTONS.Name = "TP_BUTTONS"
|
|
||||||
TP_BUTTONS.RowCount = 1
|
|
||||||
TP_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_BUTTONS.Size = New System.Drawing.Size(480, 30)
|
|
||||||
TP_BUTTONS.TabIndex = 0
|
|
||||||
'
|
|
||||||
'BTT_DOWN_ALL
|
|
||||||
'
|
|
||||||
Me.BTT_DOWN_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_DOWN_ALL.Location = New System.Drawing.Point(3, 3)
|
|
||||||
Me.BTT_DOWN_ALL.Name = "BTT_DOWN_ALL"
|
|
||||||
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(234, 24)
|
|
||||||
Me.BTT_DOWN_ALL.TabIndex = 0
|
|
||||||
Me.BTT_DOWN_ALL.Text = "Download ALL"
|
|
||||||
Me.BTT_DOWN_ALL.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'BTT_STOP_ALL
|
|
||||||
'
|
|
||||||
Me.BTT_STOP_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_STOP_ALL.Location = New System.Drawing.Point(243, 3)
|
|
||||||
Me.BTT_STOP_ALL.Name = "BTT_STOP_ALL"
|
|
||||||
Me.BTT_STOP_ALL.Size = New System.Drawing.Size(234, 24)
|
|
||||||
Me.BTT_STOP_ALL.TabIndex = 1
|
|
||||||
Me.BTT_STOP_ALL.Text = "Stop ALL"
|
|
||||||
Me.BTT_STOP_ALL.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'TP_REDDIT
|
|
||||||
'
|
|
||||||
TP_REDDIT.ColumnCount = 1
|
|
||||||
TP_REDDIT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_REDDIT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
|
||||||
TP_REDDIT.Controls.Add(TP_REDDIT_PR, 0, 0)
|
|
||||||
TP_REDDIT.Controls.Add(Me.LBL_REDDIT, 0, 1)
|
|
||||||
TP_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_REDDIT.Location = New System.Drawing.Point(2, 34)
|
|
||||||
TP_REDDIT.Margin = New System.Windows.Forms.Padding(0)
|
|
||||||
TP_REDDIT.Name = "TP_REDDIT"
|
|
||||||
TP_REDDIT.RowCount = 2
|
|
||||||
TP_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_REDDIT.Size = New System.Drawing.Size(480, 59)
|
|
||||||
TP_REDDIT.TabIndex = 1
|
|
||||||
'
|
|
||||||
'TP_REDDIT_PR
|
|
||||||
'
|
|
||||||
TP_REDDIT_PR.ColumnCount = 4
|
|
||||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_REDDIT_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_START, 0, 0)
|
|
||||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_STOP, 1, 0)
|
|
||||||
TP_REDDIT_PR.Controls.Add(Me.PR_REDDIT, 3, 0)
|
|
||||||
TP_REDDIT_PR.Controls.Add(Me.BTT_REDDIT_OPEN, 2, 0)
|
|
||||||
TP_REDDIT_PR.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_REDDIT_PR.Location = New System.Drawing.Point(0, 0)
|
|
||||||
TP_REDDIT_PR.Margin = New System.Windows.Forms.Padding(0)
|
|
||||||
TP_REDDIT_PR.Name = "TP_REDDIT_PR"
|
|
||||||
TP_REDDIT_PR.RowCount = 1
|
|
||||||
TP_REDDIT_PR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_REDDIT_PR.Size = New System.Drawing.Size(480, 29)
|
|
||||||
TP_REDDIT_PR.TabIndex = 0
|
|
||||||
'
|
|
||||||
'BTT_REDDIT_START
|
|
||||||
'
|
|
||||||
Me.BTT_REDDIT_START.BackgroundImage = Global.SCrawler.My.Resources.Resources.StartPic_01_Green_16
|
|
||||||
Me.BTT_REDDIT_START.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_REDDIT_START.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_REDDIT_START.Location = New System.Drawing.Point(3, 3)
|
|
||||||
Me.BTT_REDDIT_START.Name = "BTT_REDDIT_START"
|
|
||||||
Me.BTT_REDDIT_START.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_REDDIT_START.TabIndex = 0
|
|
||||||
TT_MAIN.SetToolTip(Me.BTT_REDDIT_START, "Start downloading saved Reddit posts")
|
|
||||||
Me.BTT_REDDIT_START.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'BTT_REDDIT_STOP
|
|
||||||
'
|
|
||||||
Me.BTT_REDDIT_STOP.BackgroundImage = Global.SCrawler.My.Resources.Resources.Delete
|
|
||||||
Me.BTT_REDDIT_STOP.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_REDDIT_STOP.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_REDDIT_STOP.Enabled = False
|
|
||||||
Me.BTT_REDDIT_STOP.Location = New System.Drawing.Point(33, 3)
|
|
||||||
Me.BTT_REDDIT_STOP.Name = "BTT_REDDIT_STOP"
|
|
||||||
Me.BTT_REDDIT_STOP.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_REDDIT_STOP.TabIndex = 1
|
|
||||||
TT_MAIN.SetToolTip(Me.BTT_REDDIT_STOP, "Stop downloading saved Reddit posts")
|
|
||||||
Me.BTT_REDDIT_STOP.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'PR_REDDIT
|
|
||||||
'
|
|
||||||
Me.PR_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.PR_REDDIT.Location = New System.Drawing.Point(93, 3)
|
|
||||||
Me.PR_REDDIT.Name = "PR_REDDIT"
|
|
||||||
Me.PR_REDDIT.Size = New System.Drawing.Size(384, 23)
|
|
||||||
Me.PR_REDDIT.TabIndex = 2
|
|
||||||
'
|
|
||||||
'BTT_REDDIT_OPEN
|
|
||||||
'
|
|
||||||
Me.BTT_REDDIT_OPEN.BackgroundImage = CType(resources.GetObject("BTT_REDDIT_OPEN.BackgroundImage"), System.Drawing.Image)
|
|
||||||
Me.BTT_REDDIT_OPEN.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_REDDIT_OPEN.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_REDDIT_OPEN.Location = New System.Drawing.Point(63, 3)
|
|
||||||
Me.BTT_REDDIT_OPEN.Name = "BTT_REDDIT_OPEN"
|
|
||||||
Me.BTT_REDDIT_OPEN.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_REDDIT_OPEN.TabIndex = 3
|
|
||||||
Me.BTT_REDDIT_OPEN.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'LBL_REDDIT
|
|
||||||
'
|
|
||||||
Me.LBL_REDDIT.AutoSize = True
|
|
||||||
Me.LBL_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.LBL_REDDIT.Location = New System.Drawing.Point(3, 29)
|
|
||||||
Me.LBL_REDDIT.Name = "LBL_REDDIT"
|
|
||||||
Me.LBL_REDDIT.Size = New System.Drawing.Size(474, 30)
|
|
||||||
Me.LBL_REDDIT.TabIndex = 1
|
|
||||||
Me.LBL_REDDIT.Text = "Reddit"
|
|
||||||
Me.LBL_REDDIT.TextAlign = System.Drawing.ContentAlignment.TopCenter
|
|
||||||
'
|
|
||||||
'TP_INST
|
|
||||||
'
|
|
||||||
TP_INST.ColumnCount = 1
|
|
||||||
TP_INST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_INST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
|
||||||
TP_INST.Controls.Add(TP_INST_PR, 0, 0)
|
|
||||||
TP_INST.Controls.Add(Me.LBL_INST, 0, 1)
|
|
||||||
TP_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_INST.Location = New System.Drawing.Point(2, 95)
|
|
||||||
TP_INST.Margin = New System.Windows.Forms.Padding(0)
|
|
||||||
TP_INST.Name = "TP_INST"
|
|
||||||
TP_INST.RowCount = 2
|
|
||||||
TP_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
|
||||||
TP_INST.Size = New System.Drawing.Size(480, 59)
|
|
||||||
TP_INST.TabIndex = 2
|
|
||||||
'
|
|
||||||
'TP_INST_PR
|
|
||||||
'
|
|
||||||
TP_INST_PR.ColumnCount = 4
|
|
||||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
|
||||||
TP_INST_PR.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_INST_PR.Controls.Add(Me.BTT_INST_START, 0, 0)
|
|
||||||
TP_INST_PR.Controls.Add(Me.BTT_INST_STOP, 1, 0)
|
|
||||||
TP_INST_PR.Controls.Add(Me.PR_INST, 3, 0)
|
|
||||||
TP_INST_PR.Controls.Add(Me.BTT_INST_OPEN, 2, 0)
|
|
||||||
TP_INST_PR.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
TP_INST_PR.Location = New System.Drawing.Point(0, 0)
|
|
||||||
TP_INST_PR.Margin = New System.Windows.Forms.Padding(0)
|
|
||||||
TP_INST_PR.Name = "TP_INST_PR"
|
|
||||||
TP_INST_PR.RowCount = 1
|
|
||||||
TP_INST_PR.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
TP_INST_PR.Size = New System.Drawing.Size(480, 29)
|
|
||||||
TP_INST_PR.TabIndex = 0
|
|
||||||
'
|
|
||||||
'BTT_INST_START
|
|
||||||
'
|
|
||||||
Me.BTT_INST_START.BackgroundImage = Global.SCrawler.My.Resources.Resources.StartPic_01_Green_16
|
|
||||||
Me.BTT_INST_START.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_INST_START.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_INST_START.Location = New System.Drawing.Point(3, 3)
|
|
||||||
Me.BTT_INST_START.Name = "BTT_INST_START"
|
|
||||||
Me.BTT_INST_START.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_INST_START.TabIndex = 0
|
|
||||||
TT_MAIN.SetToolTip(Me.BTT_INST_START, "Start downloading saved Instagram posts")
|
|
||||||
Me.BTT_INST_START.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'BTT_INST_STOP
|
|
||||||
'
|
|
||||||
Me.BTT_INST_STOP.BackgroundImage = Global.SCrawler.My.Resources.Resources.Delete
|
|
||||||
Me.BTT_INST_STOP.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_INST_STOP.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_INST_STOP.Enabled = False
|
|
||||||
Me.BTT_INST_STOP.Location = New System.Drawing.Point(33, 3)
|
|
||||||
Me.BTT_INST_STOP.Name = "BTT_INST_STOP"
|
|
||||||
Me.BTT_INST_STOP.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_INST_STOP.TabIndex = 1
|
|
||||||
TT_MAIN.SetToolTip(Me.BTT_INST_STOP, "Stop downloading saved Instagram posts")
|
|
||||||
Me.BTT_INST_STOP.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'PR_INST
|
|
||||||
'
|
|
||||||
Me.PR_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.PR_INST.Location = New System.Drawing.Point(93, 3)
|
|
||||||
Me.PR_INST.Name = "PR_INST"
|
|
||||||
Me.PR_INST.Size = New System.Drawing.Size(384, 23)
|
|
||||||
Me.PR_INST.TabIndex = 2
|
|
||||||
'
|
|
||||||
'BTT_INST_OPEN
|
|
||||||
'
|
|
||||||
Me.BTT_INST_OPEN.BackgroundImage = CType(resources.GetObject("BTT_INST_OPEN.BackgroundImage"), System.Drawing.Image)
|
|
||||||
Me.BTT_INST_OPEN.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
|
|
||||||
Me.BTT_INST_OPEN.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.BTT_INST_OPEN.Location = New System.Drawing.Point(63, 3)
|
|
||||||
Me.BTT_INST_OPEN.Name = "BTT_INST_OPEN"
|
|
||||||
Me.BTT_INST_OPEN.Size = New System.Drawing.Size(24, 23)
|
|
||||||
Me.BTT_INST_OPEN.TabIndex = 3
|
|
||||||
Me.BTT_INST_OPEN.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'LBL_INST
|
|
||||||
'
|
|
||||||
Me.LBL_INST.AutoSize = True
|
|
||||||
Me.LBL_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.LBL_INST.Location = New System.Drawing.Point(3, 29)
|
|
||||||
Me.LBL_INST.Name = "LBL_INST"
|
|
||||||
Me.LBL_INST.Size = New System.Drawing.Size(474, 30)
|
|
||||||
Me.LBL_INST.TabIndex = 1
|
|
||||||
Me.LBL_INST.Text = "Instagram"
|
|
||||||
Me.LBL_INST.TextAlign = System.Drawing.ContentAlignment.TopCenter
|
|
||||||
'
|
|
||||||
'DownloadSavedPostsForm
|
|
||||||
'
|
|
||||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
|
||||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
|
||||||
Me.ClientSize = New System.Drawing.Size(484, 156)
|
|
||||||
Me.Controls.Add(TP_MAIN)
|
|
||||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
|
||||||
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
|
||||||
Me.MaximizeBox = False
|
|
||||||
Me.MaximumSize = New System.Drawing.Size(500, 195)
|
|
||||||
Me.MinimumSize = New System.Drawing.Size(500, 195)
|
|
||||||
Me.Name = "DownloadSavedPostsForm"
|
|
||||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
|
||||||
Me.Text = "Saved posts"
|
|
||||||
TP_MAIN.ResumeLayout(False)
|
|
||||||
TP_BUTTONS.ResumeLayout(False)
|
|
||||||
TP_REDDIT.ResumeLayout(False)
|
|
||||||
TP_REDDIT.PerformLayout()
|
|
||||||
TP_REDDIT_PR.ResumeLayout(False)
|
|
||||||
TP_INST.ResumeLayout(False)
|
|
||||||
TP_INST.PerformLayout()
|
|
||||||
TP_INST_PR.ResumeLayout(False)
|
|
||||||
Me.ResumeLayout(False)
|
|
||||||
|
|
||||||
End Sub
|
|
||||||
Private WithEvents BTT_DOWN_ALL As Button
|
|
||||||
Private WithEvents BTT_STOP_ALL As Button
|
|
||||||
Private WithEvents BTT_REDDIT_START As Button
|
|
||||||
Private WithEvents BTT_REDDIT_STOP As Button
|
|
||||||
Private WithEvents PR_REDDIT As ProgressBar
|
|
||||||
Private WithEvents LBL_REDDIT As Label
|
|
||||||
Private WithEvents BTT_INST_START As Button
|
|
||||||
Private WithEvents BTT_INST_STOP As Button
|
|
||||||
Private WithEvents PR_INST As ProgressBar
|
|
||||||
Private WithEvents LBL_INST As Label
|
|
||||||
Private WithEvents BTT_REDDIT_OPEN As Button
|
|
||||||
Private WithEvents BTT_INST_OPEN As Button
|
|
||||||
End Class
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
Imports System.ComponentModel
|
|
||||||
Imports System.Threading
|
|
||||||
Imports PersonalUtilities.Forms
|
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
|
||||||
Imports SCrawler.API
|
|
||||||
Imports Job = SCrawler.TDownloader.Job
|
|
||||||
Friend Class DownloadSavedPostsForm
|
|
||||||
Friend Event OnDownloadDone(ByVal Message As String)
|
|
||||||
Private MyView As FormsView
|
|
||||||
Private ReadOnly ProgressReddit As MyProgress
|
|
||||||
Private ReadOnly ProgressInstgram As MyProgress
|
|
||||||
Private JobReddit As Job
|
|
||||||
Private JobInstagram As Job
|
|
||||||
Friend ReadOnly Property Working As Boolean
|
|
||||||
Get
|
|
||||||
Return JobReddit Or JobInstagram
|
|
||||||
End Get
|
|
||||||
End Property
|
|
||||||
#Region "Start and Stop functions"
|
|
||||||
Friend Overloads Sub [Stop]()
|
|
||||||
[Stop](Sites.Reddit)
|
|
||||||
[Stop](Sites.Instagram)
|
|
||||||
End Sub
|
|
||||||
Private Overloads Sub [Stop](ByVal Site As Sites)
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit : If JobReddit Then JobReddit.Stop()
|
|
||||||
Case Sites.Instagram : If JobInstagram Then JobInstagram.Stop()
|
|
||||||
End Select
|
|
||||||
End Sub
|
|
||||||
Private Overloads Sub [Start]()
|
|
||||||
Start(Sites.Reddit)
|
|
||||||
Start(Sites.Instagram)
|
|
||||||
End Sub
|
|
||||||
Private Overloads Sub [Start](ByVal Site As Sites)
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit : If Not JobReddit Then JobReddit.Start(New ThreadStart(Sub() DownloadData(Sites.Reddit)))
|
|
||||||
Case Sites.Instagram
|
|
||||||
If Not JobInstagram Then
|
|
||||||
If Not Downloader.Working(Sites.Instagram) Then
|
|
||||||
Downloader.InstagramSavedPostsDownloading = True
|
|
||||||
JobInstagram.Start(New ThreadStart(Sub() DownloadData(Sites.Instagram)))
|
|
||||||
Else
|
|
||||||
MsgBoxE({$"Downloading Instagram profiles still works.{vbCr}Wait for this to be done before starting.{vbCr}Operation canceled",
|
|
||||||
"Instagram saved posts"}, MsgBoxStyle.Critical)
|
|
||||||
End If
|
|
||||||
End If
|
|
||||||
End Select
|
|
||||||
End Sub
|
|
||||||
#End Region
|
|
||||||
#Region "Form functions"
|
|
||||||
Friend Sub New()
|
|
||||||
InitializeComponent()
|
|
||||||
ProgressReddit = New MyProgress(PR_REDDIT, LBL_REDDIT)
|
|
||||||
ProgressInstgram = New MyProgress(PR_INST, LBL_INST)
|
|
||||||
JobReddit = New Job(ProgressReddit) With {.Site = Sites.Reddit}
|
|
||||||
JobInstagram = New Job(ProgressInstgram) With {.Site = Sites.Instagram}
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadSavedPostsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
|
||||||
MyView = New FormsView(Me) With {.LocationOnly = True}
|
|
||||||
MyView.ImportFromXML(Settings.Design)
|
|
||||||
MyView.SetMeSize()
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadSavedPostsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
|
||||||
e.Cancel = True
|
|
||||||
Hide()
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadSavedPostsForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
|
||||||
[Stop]()
|
|
||||||
MyView.Dispose(Settings.Design)
|
|
||||||
End Sub
|
|
||||||
#End Region
|
|
||||||
#Region "Controls"
|
|
||||||
Private Sub BTT_DOWN_ALL_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_ALL.Click
|
|
||||||
Start()
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_STOP_ALL_Click(sender As Object, e As EventArgs) Handles BTT_STOP_ALL.Click
|
|
||||||
[Stop]()
|
|
||||||
End Sub
|
|
||||||
#Region "Reddit"
|
|
||||||
Private Sub BTT_REDDIT_START_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_START.Click
|
|
||||||
Start(Sites.Reddit)
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_REDDIT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_STOP.Click
|
|
||||||
[Stop](Sites.Reddit)
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_REDDIT_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_REDDIT_OPEN.Click
|
|
||||||
OpenPath(Reddit.ProfileSaved.DataPath)
|
|
||||||
End Sub
|
|
||||||
Private Sub LBL_REDDIT_DoubleClick(sender As Object, e As EventArgs) Handles LBL_REDDIT.DoubleClick
|
|
||||||
OpenPath(Reddit.ProfileSaved.DataPath)
|
|
||||||
End Sub
|
|
||||||
#End Region
|
|
||||||
#Region "Instagram"
|
|
||||||
Private Sub BTT_INST_START_Click(sender As Object, e As EventArgs) Handles BTT_INST_START.Click
|
|
||||||
Start(Sites.Instagram)
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_INST_STOP_Click(sender As Object, e As EventArgs) Handles BTT_INST_STOP.Click
|
|
||||||
[Stop](Sites.Instagram)
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_INST_OPEN_Click(sender As Object, e As EventArgs) Handles BTT_INST_OPEN.Click
|
|
||||||
OpenPath(Instagram.ProfileSaved.DataPath)
|
|
||||||
End Sub
|
|
||||||
Private Sub LBL_INST_DoubleClick(sender As Object, e As EventArgs) Handles LBL_INST.DoubleClick
|
|
||||||
OpenPath(Instagram.ProfileSaved.DataPath)
|
|
||||||
End Sub
|
|
||||||
#End Region
|
|
||||||
#End Region
|
|
||||||
Private Sub DownloadData(ByVal Site As Sites)
|
|
||||||
Dim btte As Action(Of Button, Boolean) = Sub(b, e) If b.InvokeRequired Then b.Invoke(Sub() b.Enabled = e) Else b.Enabled = e
|
|
||||||
Try
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit
|
|
||||||
btte(BTT_REDDIT_START, False)
|
|
||||||
btte(BTT_REDDIT_STOP, True)
|
|
||||||
JobReddit.Progress.InformationTemporary = "Reddit downloading started"
|
|
||||||
JobReddit.Start()
|
|
||||||
Reddit.ProfileSaved.Download(JobReddit.Progress, JobReddit)
|
|
||||||
Case Sites.Instagram
|
|
||||||
btte(BTT_INST_START, False)
|
|
||||||
btte(BTT_INST_STOP, True)
|
|
||||||
JobInstagram.Progress.InformationTemporary = "Instagram downloading started"
|
|
||||||
JobInstagram.Start()
|
|
||||||
Instagram.ProfileSaved.Download(JobInstagram.Progress, JobInstagram)
|
|
||||||
End Select
|
|
||||||
RaiseEvent OnDownloadDone($"Downloading saved {Site} posts is completed")
|
|
||||||
Catch ex As Exception
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit : JobReddit.Progress.InformationTemporary = "Reddit downloading error"
|
|
||||||
Case Sites.Instagram : JobInstagram.Progress.InformationTemporary = "Instagram downloading error"
|
|
||||||
End Select
|
|
||||||
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, {$"{Site} saved posts downloading error", "Saved posts"})
|
|
||||||
Finally
|
|
||||||
Select Case Site
|
|
||||||
Case Sites.Reddit
|
|
||||||
JobReddit.Stopped()
|
|
||||||
btte(BTT_REDDIT_START, True)
|
|
||||||
btte(BTT_REDDIT_STOP, False)
|
|
||||||
Case Sites.Instagram
|
|
||||||
JobInstagram.Stopped()
|
|
||||||
btte(BTT_INST_START, True)
|
|
||||||
btte(BTT_INST_STOP, False)
|
|
||||||
Downloader.InstagramSavedPostsDownloading = False
|
|
||||||
End Select
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
Private Sub OpenPath(ByVal f As SFile)
|
|
||||||
If f.Exists(SFO.Path, False) Then f.Open(SFO.Path)
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
134
SCrawler/DownloadedInfoForm.Designer.vb
generated
@@ -1,134 +0,0 @@
|
|||||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
|
||||||
Partial Friend Class DownloadedInfoForm : 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 resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadedInfoForm))
|
|
||||||
Dim SEP_1 As System.Windows.Forms.ToolStripSeparator
|
|
||||||
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
|
|
||||||
Me.MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
|
|
||||||
Me.MENU_VIEW_SESSION = New System.Windows.Forms.ToolStripMenuItem()
|
|
||||||
Me.MENU_VIEW_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
|
||||||
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
|
|
||||||
Me.ToolbarBOTTOM = New System.Windows.Forms.StatusStrip()
|
|
||||||
Me.LIST_DOWN = New System.Windows.Forms.ListBox()
|
|
||||||
Me.BTT_CLEAR = New System.Windows.Forms.ToolStripButton()
|
|
||||||
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
|
||||||
Me.ToolbarTOP.SuspendLayout()
|
|
||||||
Me.SuspendLayout()
|
|
||||||
'
|
|
||||||
'ToolbarTOP
|
|
||||||
'
|
|
||||||
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
|
||||||
Me.ToolbarTOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW, Me.BTT_REFRESH, SEP_1, Me.BTT_CLEAR})
|
|
||||||
Me.ToolbarTOP.Location = New System.Drawing.Point(0, 0)
|
|
||||||
Me.ToolbarTOP.Name = "ToolbarTOP"
|
|
||||||
Me.ToolbarTOP.Size = New System.Drawing.Size(554, 25)
|
|
||||||
Me.ToolbarTOP.TabIndex = 0
|
|
||||||
'
|
|
||||||
'MENU_VIEW
|
|
||||||
'
|
|
||||||
Me.MENU_VIEW.AutoToolTip = False
|
|
||||||
Me.MENU_VIEW.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
|
||||||
Me.MENU_VIEW.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.MENU_VIEW_SESSION, Me.MENU_VIEW_ALL})
|
|
||||||
Me.MENU_VIEW.Image = CType(resources.GetObject("MENU_VIEW.Image"), System.Drawing.Image)
|
|
||||||
Me.MENU_VIEW.ImageTransparentColor = System.Drawing.Color.Magenta
|
|
||||||
Me.MENU_VIEW.Name = "MENU_VIEW"
|
|
||||||
Me.MENU_VIEW.Size = New System.Drawing.Size(45, 22)
|
|
||||||
Me.MENU_VIEW.Text = "View"
|
|
||||||
'
|
|
||||||
'MENU_VIEW_SESSION
|
|
||||||
'
|
|
||||||
Me.MENU_VIEW_SESSION.AutoToolTip = True
|
|
||||||
Me.MENU_VIEW_SESSION.Name = "MENU_VIEW_SESSION"
|
|
||||||
Me.MENU_VIEW_SESSION.Size = New System.Drawing.Size(113, 22)
|
|
||||||
Me.MENU_VIEW_SESSION.Text = "Session"
|
|
||||||
Me.MENU_VIEW_SESSION.ToolTipText = "Show downloaded users by this session"
|
|
||||||
'
|
|
||||||
'MENU_VIEW_ALL
|
|
||||||
'
|
|
||||||
Me.MENU_VIEW_ALL.AutoToolTip = True
|
|
||||||
Me.MENU_VIEW_ALL.Name = "MENU_VIEW_ALL"
|
|
||||||
Me.MENU_VIEW_ALL.Size = New System.Drawing.Size(113, 22)
|
|
||||||
Me.MENU_VIEW_ALL.Text = "All"
|
|
||||||
Me.MENU_VIEW_ALL.ToolTipText = "Show all users (sorted by latest download)"
|
|
||||||
'
|
|
||||||
'BTT_REFRESH
|
|
||||||
'
|
|
||||||
Me.BTT_REFRESH.Image = Global.SCrawler.My.Resources.Resources.Refresh
|
|
||||||
Me.BTT_REFRESH.ImageTransparentColor = System.Drawing.Color.Magenta
|
|
||||||
Me.BTT_REFRESH.Name = "BTT_REFRESH"
|
|
||||||
Me.BTT_REFRESH.Size = New System.Drawing.Size(89, 22)
|
|
||||||
Me.BTT_REFRESH.Text = "Refresh (F5)"
|
|
||||||
Me.BTT_REFRESH.ToolTipText = "Force list refresh"
|
|
||||||
'
|
|
||||||
'ToolbarBOTTOM
|
|
||||||
'
|
|
||||||
Me.ToolbarBOTTOM.Location = New System.Drawing.Point(0, 389)
|
|
||||||
Me.ToolbarBOTTOM.Name = "ToolbarBOTTOM"
|
|
||||||
Me.ToolbarBOTTOM.Size = New System.Drawing.Size(554, 22)
|
|
||||||
Me.ToolbarBOTTOM.TabIndex = 1
|
|
||||||
'
|
|
||||||
'LIST_DOWN
|
|
||||||
'
|
|
||||||
Me.LIST_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.LIST_DOWN.FormattingEnabled = True
|
|
||||||
Me.LIST_DOWN.Location = New System.Drawing.Point(0, 25)
|
|
||||||
Me.LIST_DOWN.Name = "LIST_DOWN"
|
|
||||||
Me.LIST_DOWN.Size = New System.Drawing.Size(554, 364)
|
|
||||||
Me.LIST_DOWN.TabIndex = 2
|
|
||||||
'
|
|
||||||
'SEP_1
|
|
||||||
'
|
|
||||||
SEP_1.Name = "SEP_1"
|
|
||||||
SEP_1.Size = New System.Drawing.Size(6, 25)
|
|
||||||
'
|
|
||||||
'BTT_CLEAR
|
|
||||||
'
|
|
||||||
Me.BTT_CLEAR.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
|
|
||||||
Me.BTT_CLEAR.Image = CType(resources.GetObject("BTT_CLEAR.Image"), System.Drawing.Image)
|
|
||||||
Me.BTT_CLEAR.ImageTransparentColor = System.Drawing.Color.Magenta
|
|
||||||
Me.BTT_CLEAR.Name = "BTT_CLEAR"
|
|
||||||
Me.BTT_CLEAR.Size = New System.Drawing.Size(38, 22)
|
|
||||||
Me.BTT_CLEAR.Text = "Clear"
|
|
||||||
Me.BTT_CLEAR.ToolTipText = "Clear info list"
|
|
||||||
'
|
|
||||||
'DownloadedInfoForm
|
|
||||||
'
|
|
||||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
|
||||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
|
||||||
Me.ClientSize = New System.Drawing.Size(554, 411)
|
|
||||||
Me.Controls.Add(Me.LIST_DOWN)
|
|
||||||
Me.Controls.Add(Me.ToolbarBOTTOM)
|
|
||||||
Me.Controls.Add(Me.ToolbarTOP)
|
|
||||||
Me.KeyPreview = True
|
|
||||||
Me.MinimumSize = New System.Drawing.Size(570, 450)
|
|
||||||
Me.Name = "DownloadedInfoForm"
|
|
||||||
Me.ShowIcon = False
|
|
||||||
Me.Text = "Downloaded items"
|
|
||||||
Me.ToolbarTOP.ResumeLayout(False)
|
|
||||||
Me.ToolbarTOP.PerformLayout()
|
|
||||||
Me.ResumeLayout(False)
|
|
||||||
Me.PerformLayout()
|
|
||||||
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private WithEvents ToolbarTOP As ToolStrip
|
|
||||||
Private WithEvents MENU_VIEW As ToolStripDropDownButton
|
|
||||||
Private WithEvents MENU_VIEW_SESSION As ToolStripMenuItem
|
|
||||||
Private WithEvents MENU_VIEW_ALL As ToolStripMenuItem
|
|
||||||
Private WithEvents BTT_REFRESH As ToolStripButton
|
|
||||||
Private WithEvents ToolbarBOTTOM As StatusStrip
|
|
||||||
Private WithEvents LIST_DOWN As ListBox
|
|
||||||
Private WithEvents BTT_CLEAR As ToolStripButton
|
|
||||||
End Class
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
' Copyright (C) 2022 Andy
|
|
||||||
' This program is free software: you can redistribute it and/or modify
|
|
||||||
' it under the terms of the GNU General Public License as published by
|
|
||||||
' the Free Software Foundation, either version 3 of the License, or
|
|
||||||
' (at your option) any later version.
|
|
||||||
'
|
|
||||||
' This program is distributed in the hope that it will be useful,
|
|
||||||
' but WITHOUT ANY WARRANTY
|
|
||||||
Imports System.ComponentModel
|
|
||||||
Imports PersonalUtilities.Forms
|
|
||||||
Imports SCrawler.API.Base
|
|
||||||
Friend Class DownloadedInfoForm
|
|
||||||
Private MyView As FormsView
|
|
||||||
Private ReadOnly LParams As New ListAddParams(LAP.IgnoreICopier) With {.e = EDP.None}
|
|
||||||
Friend Enum ViewModes As Integer
|
|
||||||
Session = 0
|
|
||||||
All = 1
|
|
||||||
End Enum
|
|
||||||
Friend Property ViewMode As ViewModes
|
|
||||||
Get
|
|
||||||
Return IIf(MENU_VIEW_ALL.Checked, ViewModes.All, ViewModes.Session)
|
|
||||||
End Get
|
|
||||||
Set(ByVal SMode As ViewModes)
|
|
||||||
Settings.InfoViewMode.Value = CInt(SMode)
|
|
||||||
End Set
|
|
||||||
End Property
|
|
||||||
Private ReadOnly _TempUsersList As List(Of IUserData)
|
|
||||||
Friend Sub New()
|
|
||||||
InitializeComponent()
|
|
||||||
_TempUsersList = New List(Of IUserData)
|
|
||||||
If Settings.InfoViewMode.Value = CInt(ViewModes.All) Then
|
|
||||||
MENU_VIEW_SESSION.Checked = False
|
|
||||||
MENU_VIEW_ALL.Checked = True
|
|
||||||
Else
|
|
||||||
MENU_VIEW_SESSION.Checked = True
|
|
||||||
MENU_VIEW_ALL.Checked = False
|
|
||||||
End If
|
|
||||||
Settings.InfoViewMode.Value = ViewMode
|
|
||||||
RefillList()
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadedInfoForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
|
||||||
Try
|
|
||||||
If MyView Is Nothing Then
|
|
||||||
MyView = New FormsView(Me)
|
|
||||||
MyView.ImportFromXML(Settings.Design)
|
|
||||||
MyView.SetMeSize()
|
|
||||||
End If
|
|
||||||
BTT_CLEAR.Visible = ViewMode = ViewModes.Session
|
|
||||||
RefillList()
|
|
||||||
Catch ex As Exception
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadedInfoForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
|
|
||||||
e.Cancel = True
|
|
||||||
Hide()
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadedInfoForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
|
||||||
If Not MyView Is Nothing Then MyView.Dispose(Settings.Design)
|
|
||||||
_TempUsersList.Clear()
|
|
||||||
End Sub
|
|
||||||
Private Sub DownloadedInfoForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
|
|
||||||
If e.KeyCode = Keys.F5 Then RefillList() : e.Handled = True
|
|
||||||
End Sub
|
|
||||||
Private Class UsersDateOrder : Implements IComparer(Of IUserData)
|
|
||||||
Friend Function Compare(ByVal x As IUserData, ByVal y As IUserData) As Integer Implements IComparer(Of IUserData).Compare
|
|
||||||
Dim xv& = If(DirectCast(x.Self, UserDataBase).LastUpdated.HasValue, DirectCast(x.Self, UserDataBase).LastUpdated.Value.Ticks, 0)
|
|
||||||
Dim yv& = If(DirectCast(y.Self, UserDataBase).LastUpdated.HasValue, DirectCast(y.Self, UserDataBase).LastUpdated.Value.Ticks, 0)
|
|
||||||
Return xv.CompareTo(yv) * -1
|
|
||||||
End Function
|
|
||||||
End Class
|
|
||||||
Private Sub RefillList()
|
|
||||||
Try
|
|
||||||
_TempUsersList.Clear()
|
|
||||||
Dim lClear As Action = Sub() LIST_DOWN.Items.Clear()
|
|
||||||
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(lClear) Else lClear.Invoke
|
|
||||||
If ViewMode = ViewModes.Session Then
|
|
||||||
_TempUsersList.ListAddList(Downloader.Downloaded, LParams)
|
|
||||||
Else
|
|
||||||
_TempUsersList.ListAddList(Settings.Users.SelectMany(Of IUserData) _
|
|
||||||
(Function(u) If(u.IsCollection, DirectCast(u, API.UserDataBind).Collections, {u})), LParams)
|
|
||||||
End If
|
|
||||||
If _TempUsersList.Count > 0 Then
|
|
||||||
_TempUsersList.Sort(New UsersDateOrder)
|
|
||||||
For Each user As IUserData In _TempUsersList
|
|
||||||
If LIST_DOWN.InvokeRequired Then
|
|
||||||
LIST_DOWN.Invoke(Sub() LIST_DOWN.Items.Add(user.DownloadedInformation))
|
|
||||||
Else
|
|
||||||
LIST_DOWN.Items.Add(user.DownloadedInformation)
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
If _LatestSelected >= 0 AndAlso _LatestSelected <= LIST_DOWN.Items.Count - 1 Then
|
|
||||||
Dim aSel As Action = Sub() LIST_DOWN.SelectedIndex = _LatestSelected
|
|
||||||
If LIST_DOWN.InvokeRequired Then LIST_DOWN.Invoke(aSel) Else aSel.Invoke
|
|
||||||
Else
|
|
||||||
_LatestSelected = -1
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
_LatestSelected = -1
|
|
||||||
End If
|
|
||||||
Catch ex As Exception
|
|
||||||
ErrorsDescriber.Execute(EDP.SendInLog, ex, "[DownloadedInfoForm.RefillList]")
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
Private Sub MENU_VIEW_SESSION_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_SESSION.Click
|
|
||||||
MENU_VIEW_SESSION.Checked = True
|
|
||||||
MENU_VIEW_ALL.Checked = False
|
|
||||||
ViewMode = ViewModes.Session
|
|
||||||
BTT_CLEAR.Visible = True
|
|
||||||
RefillList()
|
|
||||||
End Sub
|
|
||||||
Private Sub MENU_VIEW_ALL_Click(sender As Object, e As EventArgs) Handles MENU_VIEW_ALL.Click
|
|
||||||
MENU_VIEW_SESSION.Checked = False
|
|
||||||
MENU_VIEW_ALL.Checked = True
|
|
||||||
ViewMode = ViewModes.All
|
|
||||||
BTT_CLEAR.Visible = False
|
|
||||||
RefillList()
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_REFRESH_Click(sender As Object, e As EventArgs) Handles BTT_REFRESH.Click
|
|
||||||
RefillList()
|
|
||||||
End Sub
|
|
||||||
Private Sub BTT_CLEAR_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR.Click
|
|
||||||
If LIST_DOWN.Items.Count > 0 Then
|
|
||||||
Downloader.Downloaded.Clear()
|
|
||||||
RefillList()
|
|
||||||
End If
|
|
||||||
End Sub
|
|
||||||
Private _LatestSelected As Integer = -1
|
|
||||||
Private Sub LIST_DOWN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_DOWN.SelectedIndexChanged
|
|
||||||
_LatestSelected = LIST_DOWN.SelectedIndex
|
|
||||||
End Sub
|
|
||||||
Private Sub LIST_DOWN_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles LIST_DOWN.MouseDoubleClick
|
|
||||||
Try
|
|
||||||
If _LatestSelected >= 0 AndAlso _LatestSelected <= _TempUsersList.Count - 1 AndAlso
|
|
||||||
Not DirectCast(_TempUsersList(_LatestSelected).Self, UserDataBase).Disposed Then _TempUsersList(_LatestSelected).OpenFolder()
|
|
||||||
Catch ex As Exception
|
|
||||||
End Try
|
|
||||||
End Sub
|
|
||||||
Friend Sub Downloader_OnDownloadCountChange()
|
|
||||||
If ViewMode = ViewModes.Session Then RefillList()
|
|
||||||
End Sub
|
|
||||||
End Class
|
|
||||||
436
SCrawler/Editors/GlobalSettingsForm.Designer.vb
generated
@@ -27,6 +27,7 @@
|
|||||||
Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel
|
Dim TP_FILE_NAME As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel
|
Dim TP_FILE_PATTERNS As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim LBL_DATE_POS As System.Windows.Forms.Label
|
Dim LBL_DATE_POS As System.Windows.Forms.Label
|
||||||
|
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||||
Dim TP_CHANNELS_IMGS As System.Windows.Forms.TableLayoutPanel
|
Dim TP_CHANNELS_IMGS As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim TAB_BASIS As System.Windows.Forms.TabPage
|
Dim TAB_BASIS As System.Windows.Forms.TabPage
|
||||||
@@ -34,12 +35,6 @@
|
|||||||
Dim TP_DEFS As System.Windows.Forms.TableLayoutPanel
|
Dim TP_DEFS As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim TAB_DEFS_CHANNELS As System.Windows.Forms.TabPage
|
Dim TAB_DEFS_CHANNELS As System.Windows.Forms.TabPage
|
||||||
Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel
|
Dim TP_CHANNELS As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim TAB_DEFS_REDDIT As System.Windows.Forms.TabPage
|
|
||||||
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 TAB_DEFS_TWITTER As System.Windows.Forms.TabPage
|
|
||||||
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()
|
|
||||||
Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_GLOBAL_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_IMAGE_LARGE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_IMAGE_SMALL = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
@@ -58,32 +53,22 @@
|
|||||||
Me.CH_EXIT_CONFIRM = New System.Windows.Forms.CheckBox()
|
Me.CH_EXIT_CONFIRM = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_CLOSE_TO_TRAY = New System.Windows.Forms.CheckBox()
|
Me.CH_CLOSE_TO_TRAY = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_SHOW_NOTIFY = New System.Windows.Forms.CheckBox()
|
Me.CH_SHOW_NOTIFY = New System.Windows.Forms.CheckBox()
|
||||||
|
Me.CH_FAST_LOAD = New System.Windows.Forms.CheckBox()
|
||||||
|
Me.TXT_FOLDER_CMD = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.CH_COPY_CHANNEL_USER_IMAGE = New System.Windows.Forms.CheckBox()
|
Me.CH_COPY_CHANNEL_USER_IMAGE = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_DEF_TEMP = New System.Windows.Forms.CheckBox()
|
Me.CH_DEF_TEMP = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_DOWN_IMAGES = New System.Windows.Forms.CheckBox()
|
Me.CH_DOWN_IMAGES = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_DOWN_VIDEOS = New System.Windows.Forms.CheckBox()
|
Me.CH_DOWN_VIDEOS = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_SEPARATE_VIDEO_FOLDER = New System.Windows.Forms.CheckBox()
|
Me.CH_SEPARATE_VIDEO_FOLDER = New System.Windows.Forms.CheckBox()
|
||||||
Me.CH_CHANNELS_USERS_TEMP = New System.Windows.Forms.CheckBox()
|
Me.CH_CHANNELS_USERS_TEMP = New System.Windows.Forms.CheckBox()
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL = New System.Windows.Forms.CheckBox()
|
||||||
|
Me.CH_UDESCR_UP = New System.Windows.Forms.CheckBox()
|
||||||
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_CHANNELS_ROWS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_CHANNELS_COLUMNS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.TXT_CHANNEL_USER_POST_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
Me.TXT_CHANNEL_USER_POST_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||||
Me.DEFS_REDDIT = New SCrawler.Editors.SiteDefaults()
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.CH_REDDIT_USER_MEDIA = New System.Windows.Forms.CheckBox()
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.DEFS_TWITTER = New SCrawler.Editors.SiteDefaults()
|
|
||||||
Me.CH_TWITTER_USER_MEDIA = New System.Windows.Forms.CheckBox()
|
|
||||||
Me.TXT_REQ_WAIT_TIMER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.TXT_REQ_COUNT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.TXT_LIMIT_TIMER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
|
Me.TAB_MAIN = New System.Windows.Forms.TabControl()
|
||||||
Me.TAB_DEFS_INSTAGRAM = New System.Windows.Forms.TabPage()
|
|
||||||
Me.DEFS_INST = New SCrawler.Editors.SiteDefaults()
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
|
||||||
Me.TAB_DEFS_REDGIFS = New System.Windows.Forms.TabPage()
|
|
||||||
Me.DEFS_REDGIFS = New SCrawler.Editors.SiteDefaults()
|
|
||||||
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
Me.CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||||
|
Me.CH_RECYCLE_DEL = New System.Windows.Forms.CheckBox()
|
||||||
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
|
TP_BASIS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
|
TP_IMAGES = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
|
TP_FILE_NAME = New System.Windows.Forms.TableLayoutPanel()
|
||||||
@@ -96,8 +81,6 @@
|
|||||||
TP_DEFS = New System.Windows.Forms.TableLayoutPanel()
|
TP_DEFS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TAB_DEFS_CHANNELS = New System.Windows.Forms.TabPage()
|
TAB_DEFS_CHANNELS = New System.Windows.Forms.TabPage()
|
||||||
TP_CHANNELS = New System.Windows.Forms.TableLayoutPanel()
|
TP_CHANNELS = New System.Windows.Forms.TableLayoutPanel()
|
||||||
TAB_DEFS_REDDIT = New System.Windows.Forms.TabPage()
|
|
||||||
TAB_DEFS_TWITTER = New System.Windows.Forms.TabPage()
|
|
||||||
TP_BASIS.SuspendLayout()
|
TP_BASIS.SuspendLayout()
|
||||||
CType(Me.TXT_GLOBAL_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_GLOBAL_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
TP_IMAGES.SuspendLayout()
|
TP_IMAGES.SuspendLayout()
|
||||||
@@ -109,6 +92,7 @@
|
|||||||
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_IMGUR_CLIENT_ID, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
TP_FILE_NAME.SuspendLayout()
|
TP_FILE_NAME.SuspendLayout()
|
||||||
TP_FILE_PATTERNS.SuspendLayout()
|
TP_FILE_PATTERNS.SuspendLayout()
|
||||||
|
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
TP_CHANNELS_IMGS.SuspendLayout()
|
TP_CHANNELS_IMGS.SuspendLayout()
|
||||||
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
@@ -118,21 +102,7 @@
|
|||||||
TAB_DEFS_CHANNELS.SuspendLayout()
|
TAB_DEFS_CHANNELS.SuspendLayout()
|
||||||
TP_CHANNELS.SuspendLayout()
|
TP_CHANNELS.SuspendLayout()
|
||||||
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit()
|
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||||
TAB_DEFS_REDDIT.SuspendLayout()
|
|
||||||
Me.DEFS_REDDIT.SuspendLayout()
|
|
||||||
CType(Me.TXT_REDDIT_SAVED_POSTS_USER, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
CType(Me.TXT_REDDIT_SAVED_POSTS_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
TAB_DEFS_TWITTER.SuspendLayout()
|
|
||||||
Me.DEFS_TWITTER.SuspendLayout()
|
|
||||||
CType(Me.TXT_REQ_WAIT_TIMER, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
CType(Me.TXT_REQ_COUNT, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
CType(Me.TXT_LIMIT_TIMER, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
Me.TAB_MAIN.SuspendLayout()
|
Me.TAB_MAIN.SuspendLayout()
|
||||||
Me.TAB_DEFS_INSTAGRAM.SuspendLayout()
|
|
||||||
Me.DEFS_INST.SuspendLayout()
|
|
||||||
CType(Me.TXT_INST_SAVED_POSTS_USER, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
CType(Me.TXT_INST_SAVED_POSTS_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
|
|
||||||
Me.TAB_DEFS_REDGIFS.SuspendLayout()
|
|
||||||
Me.CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
Me.CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||||
Me.CONTAINER_MAIN.SuspendLayout()
|
Me.CONTAINER_MAIN.SuspendLayout()
|
||||||
Me.SuspendLayout()
|
Me.SuspendLayout()
|
||||||
@@ -154,10 +124,13 @@
|
|||||||
TP_BASIS.Controls.Add(Me.CH_EXIT_CONFIRM, 0, 9)
|
TP_BASIS.Controls.Add(Me.CH_EXIT_CONFIRM, 0, 9)
|
||||||
TP_BASIS.Controls.Add(Me.CH_CLOSE_TO_TRAY, 0, 10)
|
TP_BASIS.Controls.Add(Me.CH_CLOSE_TO_TRAY, 0, 10)
|
||||||
TP_BASIS.Controls.Add(Me.CH_SHOW_NOTIFY, 0, 11)
|
TP_BASIS.Controls.Add(Me.CH_SHOW_NOTIFY, 0, 11)
|
||||||
|
TP_BASIS.Controls.Add(Me.CH_FAST_LOAD, 0, 12)
|
||||||
|
TP_BASIS.Controls.Add(Me.TXT_FOLDER_CMD, 0, 13)
|
||||||
|
TP_BASIS.Controls.Add(Me.CH_RECYCLE_DEL, 0, 14)
|
||||||
TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_BASIS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_BASIS.Location = New System.Drawing.Point(3, 3)
|
TP_BASIS.Location = New System.Drawing.Point(3, 3)
|
||||||
TP_BASIS.Name = "TP_BASIS"
|
TP_BASIS.Name = "TP_BASIS"
|
||||||
TP_BASIS.RowCount = 13
|
TP_BASIS.RowCount = 16
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
@@ -170,8 +143,11 @@
|
|||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_BASIS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_BASIS.Size = New System.Drawing.Size(570, 366)
|
TP_BASIS.Size = New System.Drawing.Size(570, 422)
|
||||||
TP_BASIS.TabIndex = 0
|
TP_BASIS.TabIndex = 0
|
||||||
'
|
'
|
||||||
'TXT_GLOBAL_PATH
|
'TXT_GLOBAL_PATH
|
||||||
@@ -489,6 +465,40 @@
|
|||||||
Me.CH_SHOW_NOTIFY.Text = "Show notifications"
|
Me.CH_SHOW_NOTIFY.Text = "Show notifications"
|
||||||
Me.CH_SHOW_NOTIFY.UseVisualStyleBackColor = True
|
Me.CH_SHOW_NOTIFY.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
|
'CH_FAST_LOAD
|
||||||
|
'
|
||||||
|
Me.CH_FAST_LOAD.AutoSize = True
|
||||||
|
Me.CH_FAST_LOAD.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.CH_FAST_LOAD.Location = New System.Drawing.Point(4, 344)
|
||||||
|
Me.CH_FAST_LOAD.Name = "CH_FAST_LOAD"
|
||||||
|
Me.CH_FAST_LOAD.Size = New System.Drawing.Size(562, 19)
|
||||||
|
Me.CH_FAST_LOAD.TabIndex = 12
|
||||||
|
Me.CH_FAST_LOAD.Text = "Fast profiles loading"
|
||||||
|
TT_MAIN.SetToolTip(Me.CH_FAST_LOAD, "Fast loading of profiles in the main window")
|
||||||
|
Me.CH_FAST_LOAD.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'TXT_FOLDER_CMD
|
||||||
|
'
|
||||||
|
Me.TXT_FOLDER_CMD.AutoShowClearButton = True
|
||||||
|
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
||||||
|
ActionButton7.Enabled = False
|
||||||
|
ActionButton7.Index = 0
|
||||||
|
ActionButton7.Name = "BTT_CLEAR"
|
||||||
|
ActionButton7.Visible = False
|
||||||
|
Me.TXT_FOLDER_CMD.Buttons.Add(ActionButton7)
|
||||||
|
Me.TXT_FOLDER_CMD.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
|
||||||
|
Me.TXT_FOLDER_CMD.CaptionText = "Folder cmd"
|
||||||
|
Me.TXT_FOLDER_CMD.CaptionToolTipEnabled = True
|
||||||
|
Me.TXT_FOLDER_CMD.CaptionToolTipText = "The command to open a folder."
|
||||||
|
Me.TXT_FOLDER_CMD.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.TXT_FOLDER_CMD.LeaveDefaultButtons = True
|
||||||
|
Me.TXT_FOLDER_CMD.Location = New System.Drawing.Point(4, 370)
|
||||||
|
Me.TXT_FOLDER_CMD.Name = "TXT_FOLDER_CMD"
|
||||||
|
Me.TXT_FOLDER_CMD.PlaceholderEnabled = True
|
||||||
|
Me.TXT_FOLDER_CMD.PlaceholderText = "MyCommand /arg {0}"
|
||||||
|
Me.TXT_FOLDER_CMD.Size = New System.Drawing.Size(562, 22)
|
||||||
|
Me.TXT_FOLDER_CMD.TabIndex = 13
|
||||||
|
'
|
||||||
'CH_COPY_CHANNEL_USER_IMAGE
|
'CH_COPY_CHANNEL_USER_IMAGE
|
||||||
'
|
'
|
||||||
Me.CH_COPY_CHANNEL_USER_IMAGE.AutoSize = True
|
Me.CH_COPY_CHANNEL_USER_IMAGE.AutoSize = True
|
||||||
@@ -554,14 +564,39 @@
|
|||||||
'
|
'
|
||||||
Me.CH_CHANNELS_USERS_TEMP.AutoSize = True
|
Me.CH_CHANNELS_USERS_TEMP.AutoSize = True
|
||||||
Me.CH_CHANNELS_USERS_TEMP.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.CH_CHANNELS_USERS_TEMP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.CH_CHANNELS_USERS_TEMP.Location = New System.Drawing.Point(4, 88)
|
Me.CH_CHANNELS_USERS_TEMP.Location = New System.Drawing.Point(4, 114)
|
||||||
Me.CH_CHANNELS_USERS_TEMP.Name = "CH_CHANNELS_USERS_TEMP"
|
Me.CH_CHANNELS_USERS_TEMP.Name = "CH_CHANNELS_USERS_TEMP"
|
||||||
Me.CH_CHANNELS_USERS_TEMP.Size = New System.Drawing.Size(562, 19)
|
Me.CH_CHANNELS_USERS_TEMP.Size = New System.Drawing.Size(562, 19)
|
||||||
Me.CH_CHANNELS_USERS_TEMP.TabIndex = 3
|
Me.CH_CHANNELS_USERS_TEMP.TabIndex = 4
|
||||||
Me.CH_CHANNELS_USERS_TEMP.Text = "Create temporary users"
|
Me.CH_CHANNELS_USERS_TEMP.Text = "Create temporary users"
|
||||||
TT_MAIN.SetToolTip(Me.CH_CHANNELS_USERS_TEMP, "Users added from channels will be created with this parameter")
|
TT_MAIN.SetToolTip(Me.CH_CHANNELS_USERS_TEMP, "Users added from channels will be created with this parameter")
|
||||||
Me.CH_CHANNELS_USERS_TEMP.UseVisualStyleBackColor = True
|
Me.CH_CHANNELS_USERS_TEMP.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
|
'CH_COPY_CHANNEL_USER_IMAGE_ALL
|
||||||
|
'
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.AutoSize = True
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.Location = New System.Drawing.Point(4, 88)
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.Name = "CH_COPY_CHANNEL_USER_IMAGE_ALL"
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.Size = New System.Drawing.Size(562, 19)
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.TabIndex = 3
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.Text = "Copy images from all channels"
|
||||||
|
TT_MAIN.SetToolTip(Me.CH_COPY_CHANNEL_USER_IMAGE_ALL, "Copy user images from all channels you have when adding a user from a channel")
|
||||||
|
Me.CH_COPY_CHANNEL_USER_IMAGE_ALL.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
|
'CH_UDESCR_UP
|
||||||
|
'
|
||||||
|
Me.CH_UDESCR_UP.AutoSize = True
|
||||||
|
Me.CH_UDESCR_UP.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.CH_UDESCR_UP.Location = New System.Drawing.Point(4, 108)
|
||||||
|
Me.CH_UDESCR_UP.Name = "CH_UDESCR_UP"
|
||||||
|
Me.CH_UDESCR_UP.Size = New System.Drawing.Size(562, 19)
|
||||||
|
Me.CH_UDESCR_UP.TabIndex = 4
|
||||||
|
Me.CH_UDESCR_UP.Text = "Update user description every time"
|
||||||
|
TT_MAIN.SetToolTip(Me.CH_UDESCR_UP, "If the user description does not contain a new user description, then the new one" &
|
||||||
|
" will be added via a new line")
|
||||||
|
Me.CH_UDESCR_UP.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
'TP_CHANNELS_IMGS
|
'TP_CHANNELS_IMGS
|
||||||
'
|
'
|
||||||
TP_CHANNELS_IMGS.ColumnCount = 2
|
TP_CHANNELS_IMGS.ColumnCount = 2
|
||||||
@@ -613,7 +648,7 @@
|
|||||||
TAB_BASIS.Location = New System.Drawing.Point(4, 22)
|
TAB_BASIS.Location = New System.Drawing.Point(4, 22)
|
||||||
TAB_BASIS.Name = "TAB_BASIS"
|
TAB_BASIS.Name = "TAB_BASIS"
|
||||||
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
|
TAB_BASIS.Padding = New System.Windows.Forms.Padding(3)
|
||||||
TAB_BASIS.Size = New System.Drawing.Size(576, 372)
|
TAB_BASIS.Size = New System.Drawing.Size(576, 428)
|
||||||
TAB_BASIS.TabIndex = 0
|
TAB_BASIS.TabIndex = 0
|
||||||
TAB_BASIS.Text = "Basis"
|
TAB_BASIS.Text = "Basis"
|
||||||
'
|
'
|
||||||
@@ -623,7 +658,7 @@
|
|||||||
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
|
TAB_DEFAULTS.Location = New System.Drawing.Point(4, 22)
|
||||||
TAB_DEFAULTS.Name = "TAB_DEFAULTS"
|
TAB_DEFAULTS.Name = "TAB_DEFAULTS"
|
||||||
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
|
TAB_DEFAULTS.Padding = New System.Windows.Forms.Padding(3)
|
||||||
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 372)
|
TAB_DEFAULTS.Size = New System.Drawing.Size(576, 426)
|
||||||
TAB_DEFAULTS.TabIndex = 1
|
TAB_DEFAULTS.TabIndex = 1
|
||||||
TAB_DEFAULTS.Text = "Defaults"
|
TAB_DEFAULTS.Text = "Defaults"
|
||||||
'
|
'
|
||||||
@@ -636,16 +671,18 @@
|
|||||||
TP_DEFS.Controls.Add(Me.CH_DOWN_VIDEOS, 0, 3)
|
TP_DEFS.Controls.Add(Me.CH_DOWN_VIDEOS, 0, 3)
|
||||||
TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES, 0, 2)
|
TP_DEFS.Controls.Add(Me.CH_DOWN_IMAGES, 0, 2)
|
||||||
TP_DEFS.Controls.Add(Me.CH_DEF_TEMP, 0, 1)
|
TP_DEFS.Controls.Add(Me.CH_DEF_TEMP, 0, 1)
|
||||||
|
TP_DEFS.Controls.Add(Me.CH_UDESCR_UP, 0, 4)
|
||||||
TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_DEFS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_DEFS.Location = New System.Drawing.Point(3, 3)
|
TP_DEFS.Location = New System.Drawing.Point(3, 3)
|
||||||
TP_DEFS.Name = "TP_DEFS"
|
TP_DEFS.Name = "TP_DEFS"
|
||||||
TP_DEFS.RowCount = 5
|
TP_DEFS.RowCount = 6
|
||||||
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_DEFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_DEFS.Size = New System.Drawing.Size(570, 366)
|
TP_DEFS.Size = New System.Drawing.Size(570, 420)
|
||||||
TP_DEFS.TabIndex = 0
|
TP_DEFS.TabIndex = 0
|
||||||
'
|
'
|
||||||
'TAB_DEFS_CHANNELS
|
'TAB_DEFS_CHANNELS
|
||||||
@@ -654,7 +691,7 @@
|
|||||||
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
|
TAB_DEFS_CHANNELS.Location = New System.Drawing.Point(4, 22)
|
||||||
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
|
TAB_DEFS_CHANNELS.Name = "TAB_DEFS_CHANNELS"
|
||||||
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
|
TAB_DEFS_CHANNELS.Padding = New System.Windows.Forms.Padding(3)
|
||||||
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 372)
|
TAB_DEFS_CHANNELS.Size = New System.Drawing.Size(576, 426)
|
||||||
TAB_DEFS_CHANNELS.TabIndex = 4
|
TAB_DEFS_CHANNELS.TabIndex = 4
|
||||||
TAB_DEFS_CHANNELS.Text = "Channels"
|
TAB_DEFS_CHANNELS.Text = "Channels"
|
||||||
'
|
'
|
||||||
@@ -666,19 +703,19 @@
|
|||||||
TP_CHANNELS.Controls.Add(Me.TXT_CHANNEL_USER_POST_LIMIT, 0, 1)
|
TP_CHANNELS.Controls.Add(Me.TXT_CHANNEL_USER_POST_LIMIT, 0, 1)
|
||||||
TP_CHANNELS.Controls.Add(TP_CHANNELS_IMGS, 0, 0)
|
TP_CHANNELS.Controls.Add(TP_CHANNELS_IMGS, 0, 0)
|
||||||
TP_CHANNELS.Controls.Add(Me.CH_COPY_CHANNEL_USER_IMAGE, 0, 2)
|
TP_CHANNELS.Controls.Add(Me.CH_COPY_CHANNEL_USER_IMAGE, 0, 2)
|
||||||
TP_CHANNELS.Controls.Add(Me.CH_CHANNELS_USERS_TEMP, 0, 3)
|
TP_CHANNELS.Controls.Add(Me.CH_CHANNELS_USERS_TEMP, 0, 4)
|
||||||
|
TP_CHANNELS.Controls.Add(Me.CH_COPY_CHANNEL_USER_IMAGE_ALL, 0, 3)
|
||||||
TP_CHANNELS.Dock = System.Windows.Forms.DockStyle.Fill
|
TP_CHANNELS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
TP_CHANNELS.Location = New System.Drawing.Point(3, 3)
|
TP_CHANNELS.Location = New System.Drawing.Point(3, 3)
|
||||||
TP_CHANNELS.Name = "TP_CHANNELS"
|
TP_CHANNELS.Name = "TP_CHANNELS"
|
||||||
TP_CHANNELS.RowCount = 5
|
TP_CHANNELS.RowCount = 6
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
TP_CHANNELS.Size = New System.Drawing.Size(570, 420)
|
||||||
TP_CHANNELS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
|
||||||
TP_CHANNELS.Size = New System.Drawing.Size(570, 366)
|
|
||||||
TP_CHANNELS.TabIndex = 0
|
TP_CHANNELS.TabIndex = 0
|
||||||
'
|
'
|
||||||
'TXT_CHANNEL_USER_POST_LIMIT
|
'TXT_CHANNEL_USER_POST_LIMIT
|
||||||
@@ -701,284 +738,58 @@
|
|||||||
Me.TXT_CHANNEL_USER_POST_LIMIT.Text = "1"
|
Me.TXT_CHANNEL_USER_POST_LIMIT.Text = "1"
|
||||||
Me.TXT_CHANNEL_USER_POST_LIMIT.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center
|
Me.TXT_CHANNEL_USER_POST_LIMIT.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center
|
||||||
'
|
'
|
||||||
'TAB_DEFS_REDDIT
|
|
||||||
'
|
|
||||||
TAB_DEFS_REDDIT.Controls.Add(Me.DEFS_REDDIT)
|
|
||||||
TAB_DEFS_REDDIT.Location = New System.Drawing.Point(4, 22)
|
|
||||||
TAB_DEFS_REDDIT.Name = "TAB_DEFS_REDDIT"
|
|
||||||
TAB_DEFS_REDDIT.Padding = New System.Windows.Forms.Padding(3)
|
|
||||||
TAB_DEFS_REDDIT.Size = New System.Drawing.Size(576, 372)
|
|
||||||
TAB_DEFS_REDDIT.TabIndex = 2
|
|
||||||
TAB_DEFS_REDDIT.Text = "Reddit"
|
|
||||||
'
|
|
||||||
'DEFS_REDDIT
|
|
||||||
'
|
|
||||||
Me.DEFS_REDDIT.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
|
||||||
Me.DEFS_REDDIT.ColumnCount = 1
|
|
||||||
Me.DEFS_REDDIT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_REDDIT.Controls.Add(Me.TXT_REDDIT_SAVED_POSTS_USER, 0, 4)
|
|
||||||
Me.DEFS_REDDIT.Controls.Add(Me.CH_REDDIT_USER_MEDIA, 0, 3)
|
|
||||||
Me.DEFS_REDDIT.Controls.Add(Me.TXT_REDDIT_SAVED_POSTS_PATH, 0, 5)
|
|
||||||
Me.DEFS_REDDIT.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.DEFS_REDDIT.Location = New System.Drawing.Point(3, 3)
|
|
||||||
Me.DEFS_REDDIT.Name = "DEFS_REDDIT"
|
|
||||||
Me.DEFS_REDDIT.RowCount = 7
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_REDDIT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_REDDIT.Size = New System.Drawing.Size(570, 366)
|
|
||||||
Me.DEFS_REDDIT.TabIndex = 1
|
|
||||||
'
|
|
||||||
'TXT_REDDIT_SAVED_POSTS_USER
|
|
||||||
'
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.CaptionText = "Saved posts user"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.Location = New System.Drawing.Point(4, 108)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.Name = "TXT_REDDIT_SAVED_POSTS_USER"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.Size = New System.Drawing.Size(562, 22)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_USER.TabIndex = 4
|
|
||||||
'
|
|
||||||
'CH_REDDIT_USER_MEDIA
|
|
||||||
'
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.AutoSize = True
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.Location = New System.Drawing.Point(4, 82)
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.Name = "CH_REDDIT_USER_MEDIA"
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.Size = New System.Drawing.Size(562, 19)
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.TabIndex = 3
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.Text = "Get user media only"
|
|
||||||
Me.CH_REDDIT_USER_MEDIA.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'TXT_REDDIT_SAVED_POSTS_PATH
|
|
||||||
'
|
|
||||||
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
|
||||||
ActionButton7.Index = 0
|
|
||||||
ActionButton7.Name = "BTT_OPEN"
|
|
||||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
|
||||||
ActionButton8.Index = 1
|
|
||||||
ActionButton8.Name = "BTT_CLEAR"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Buttons.Add(ActionButton7)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Buttons.Add(ActionButton8)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.CaptionText = "Saved posts path"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.CaptionToolTipEnabled = True
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.CaptionToolTipText = "Special path (clear to use default)"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Location = New System.Drawing.Point(4, 137)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Name = "TXT_REDDIT_SAVED_POSTS_PATH"
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.Size = New System.Drawing.Size(562, 22)
|
|
||||||
Me.TXT_REDDIT_SAVED_POSTS_PATH.TabIndex = 8
|
|
||||||
'
|
|
||||||
'TAB_DEFS_TWITTER
|
|
||||||
'
|
|
||||||
TAB_DEFS_TWITTER.Controls.Add(Me.DEFS_TWITTER)
|
|
||||||
TAB_DEFS_TWITTER.Location = New System.Drawing.Point(4, 22)
|
|
||||||
TAB_DEFS_TWITTER.Name = "TAB_DEFS_TWITTER"
|
|
||||||
TAB_DEFS_TWITTER.Padding = New System.Windows.Forms.Padding(3)
|
|
||||||
TAB_DEFS_TWITTER.Size = New System.Drawing.Size(576, 372)
|
|
||||||
TAB_DEFS_TWITTER.TabIndex = 3
|
|
||||||
TAB_DEFS_TWITTER.Text = "Twitter"
|
|
||||||
'
|
|
||||||
'DEFS_TWITTER
|
|
||||||
'
|
|
||||||
Me.DEFS_TWITTER.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
|
||||||
Me.DEFS_TWITTER.ColumnCount = 1
|
|
||||||
Me.DEFS_TWITTER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_TWITTER.Controls.Add(Me.CH_TWITTER_USER_MEDIA, 0, 3)
|
|
||||||
Me.DEFS_TWITTER.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.DEFS_TWITTER.Location = New System.Drawing.Point(3, 3)
|
|
||||||
Me.DEFS_TWITTER.Name = "DEFS_TWITTER"
|
|
||||||
Me.DEFS_TWITTER.RowCount = 5
|
|
||||||
Me.DEFS_TWITTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_TWITTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_TWITTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_TWITTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_TWITTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_TWITTER.Size = New System.Drawing.Size(570, 366)
|
|
||||||
Me.DEFS_TWITTER.TabIndex = 1
|
|
||||||
'
|
|
||||||
'CH_TWITTER_USER_MEDIA
|
|
||||||
'
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.AutoSize = True
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.Location = New System.Drawing.Point(4, 82)
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.Name = "CH_TWITTER_USER_MEDIA"
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.Size = New System.Drawing.Size(562, 19)
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.TabIndex = 3
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.Text = "Get user media only"
|
|
||||||
Me.CH_TWITTER_USER_MEDIA.UseVisualStyleBackColor = True
|
|
||||||
'
|
|
||||||
'TXT_REQ_WAIT_TIMER
|
|
||||||
'
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.CaptionText = "Request timer"
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.CaptionWidth = 120.0R
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.Location = New System.Drawing.Point(4, 82)
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.Name = "TXT_REQ_WAIT_TIMER"
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.Size = New System.Drawing.Size(568, 22)
|
|
||||||
Me.TXT_REQ_WAIT_TIMER.TabIndex = 3
|
|
||||||
'
|
|
||||||
'TXT_REQ_COUNT
|
|
||||||
'
|
|
||||||
Me.TXT_REQ_COUNT.CaptionText = "Request timer counter"
|
|
||||||
Me.TXT_REQ_COUNT.CaptionWidth = 120.0R
|
|
||||||
Me.TXT_REQ_COUNT.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_REQ_COUNT.Location = New System.Drawing.Point(4, 111)
|
|
||||||
Me.TXT_REQ_COUNT.Name = "TXT_REQ_COUNT"
|
|
||||||
Me.TXT_REQ_COUNT.Size = New System.Drawing.Size(568, 22)
|
|
||||||
Me.TXT_REQ_COUNT.TabIndex = 4
|
|
||||||
'
|
|
||||||
'TXT_LIMIT_TIMER
|
|
||||||
'
|
|
||||||
Me.TXT_LIMIT_TIMER.CaptionText = "Posts limit timer"
|
|
||||||
Me.TXT_LIMIT_TIMER.CaptionWidth = 120.0R
|
|
||||||
Me.TXT_LIMIT_TIMER.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_LIMIT_TIMER.Location = New System.Drawing.Point(4, 140)
|
|
||||||
Me.TXT_LIMIT_TIMER.Name = "TXT_LIMIT_TIMER"
|
|
||||||
Me.TXT_LIMIT_TIMER.Size = New System.Drawing.Size(568, 22)
|
|
||||||
Me.TXT_LIMIT_TIMER.TabIndex = 5
|
|
||||||
'
|
|
||||||
'TAB_MAIN
|
'TAB_MAIN
|
||||||
'
|
'
|
||||||
Me.TAB_MAIN.Controls.Add(TAB_BASIS)
|
Me.TAB_MAIN.Controls.Add(TAB_BASIS)
|
||||||
Me.TAB_MAIN.Controls.Add(TAB_DEFAULTS)
|
Me.TAB_MAIN.Controls.Add(TAB_DEFAULTS)
|
||||||
Me.TAB_MAIN.Controls.Add(TAB_DEFS_CHANNELS)
|
Me.TAB_MAIN.Controls.Add(TAB_DEFS_CHANNELS)
|
||||||
Me.TAB_MAIN.Controls.Add(TAB_DEFS_REDDIT)
|
|
||||||
Me.TAB_MAIN.Controls.Add(TAB_DEFS_TWITTER)
|
|
||||||
Me.TAB_MAIN.Controls.Add(Me.TAB_DEFS_INSTAGRAM)
|
|
||||||
Me.TAB_MAIN.Controls.Add(Me.TAB_DEFS_REDGIFS)
|
|
||||||
Me.TAB_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.TAB_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
|
Me.TAB_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
Me.TAB_MAIN.Name = "TAB_MAIN"
|
Me.TAB_MAIN.Name = "TAB_MAIN"
|
||||||
Me.TAB_MAIN.SelectedIndex = 0
|
Me.TAB_MAIN.SelectedIndex = 0
|
||||||
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 398)
|
Me.TAB_MAIN.Size = New System.Drawing.Size(584, 454)
|
||||||
Me.TAB_MAIN.TabIndex = 1
|
Me.TAB_MAIN.TabIndex = 1
|
||||||
'
|
'
|
||||||
'TAB_DEFS_INSTAGRAM
|
|
||||||
'
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.BackColor = System.Drawing.SystemColors.Control
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.Controls.Add(Me.DEFS_INST)
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.Location = New System.Drawing.Point(4, 22)
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.Name = "TAB_DEFS_INSTAGRAM"
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.Size = New System.Drawing.Size(576, 372)
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.TabIndex = 5
|
|
||||||
Me.TAB_DEFS_INSTAGRAM.Text = "Instagram"
|
|
||||||
'
|
|
||||||
'DEFS_INST
|
|
||||||
'
|
|
||||||
Me.DEFS_INST.BaseControlsPadding = New System.Windows.Forms.Padding(120, 0, 0, 0)
|
|
||||||
Me.DEFS_INST.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
|
||||||
Me.DEFS_INST.ColumnCount = 1
|
|
||||||
Me.DEFS_INST.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_INST.Controls.Add(Me.TXT_LIMIT_TIMER, 0, 5)
|
|
||||||
Me.DEFS_INST.Controls.Add(Me.TXT_REQ_COUNT, 0, 4)
|
|
||||||
Me.DEFS_INST.Controls.Add(Me.TXT_REQ_WAIT_TIMER, 0, 3)
|
|
||||||
Me.DEFS_INST.Controls.Add(Me.TXT_INST_SAVED_POSTS_USER, 0, 6)
|
|
||||||
Me.DEFS_INST.Controls.Add(Me.TXT_INST_SAVED_POSTS_PATH, 0, 7)
|
|
||||||
Me.DEFS_INST.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.DEFS_INST.Location = New System.Drawing.Point(0, 0)
|
|
||||||
Me.DEFS_INST.Name = "DEFS_INST"
|
|
||||||
Me.DEFS_INST.RowCount = 9
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
|
||||||
Me.DEFS_INST.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_INST.Size = New System.Drawing.Size(576, 372)
|
|
||||||
Me.DEFS_INST.TabIndex = 1
|
|
||||||
'
|
|
||||||
'TXT_INST_SAVED_POSTS_USER
|
|
||||||
'
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.CaptionText = "Saved posts user"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.CaptionWidth = 120.0R
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.Location = New System.Drawing.Point(4, 169)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.Name = "TXT_INST_SAVED_POSTS_USER"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.Size = New System.Drawing.Size(568, 22)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_USER.TabIndex = 9
|
|
||||||
'
|
|
||||||
'TXT_INST_SAVED_POSTS_PATH
|
|
||||||
'
|
|
||||||
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
|
|
||||||
ActionButton9.Index = 0
|
|
||||||
ActionButton9.Name = "BTT_OPEN"
|
|
||||||
ActionButton10.BackgroundImage = CType(resources.GetObject("ActionButton10.BackgroundImage"), System.Drawing.Image)
|
|
||||||
ActionButton10.Index = 1
|
|
||||||
ActionButton10.Name = "BTT_CLEAR"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Buttons.Add(ActionButton9)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Buttons.Add(ActionButton10)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.CaptionText = "Saved posts path"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.CaptionToolTipEnabled = True
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.CaptionToolTipText = "Special path (clear to use default)"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.CaptionWidth = 120.0R
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Location = New System.Drawing.Point(4, 198)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Name = "TXT_INST_SAVED_POSTS_PATH"
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.Size = New System.Drawing.Size(568, 22)
|
|
||||||
Me.TXT_INST_SAVED_POSTS_PATH.TabIndex = 13
|
|
||||||
'
|
|
||||||
'TAB_DEFS_REDGIFS
|
|
||||||
'
|
|
||||||
Me.TAB_DEFS_REDGIFS.BackColor = System.Drawing.SystemColors.Control
|
|
||||||
Me.TAB_DEFS_REDGIFS.Controls.Add(Me.DEFS_REDGIFS)
|
|
||||||
Me.TAB_DEFS_REDGIFS.Location = New System.Drawing.Point(4, 22)
|
|
||||||
Me.TAB_DEFS_REDGIFS.Name = "TAB_DEFS_REDGIFS"
|
|
||||||
Me.TAB_DEFS_REDGIFS.Size = New System.Drawing.Size(576, 372)
|
|
||||||
Me.TAB_DEFS_REDGIFS.TabIndex = 6
|
|
||||||
Me.TAB_DEFS_REDGIFS.Text = "RedGifs"
|
|
||||||
'
|
|
||||||
'DEFS_REDGIFS
|
|
||||||
'
|
|
||||||
Me.DEFS_REDGIFS.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
|
||||||
Me.DEFS_REDGIFS.ColumnCount = 1
|
|
||||||
Me.DEFS_REDGIFS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_REDGIFS.Dock = System.Windows.Forms.DockStyle.Fill
|
|
||||||
Me.DEFS_REDGIFS.Location = New System.Drawing.Point(0, 0)
|
|
||||||
Me.DEFS_REDGIFS.Name = "DEFS_REDGIFS"
|
|
||||||
Me.DEFS_REDGIFS.RowCount = 4
|
|
||||||
Me.DEFS_REDGIFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDGIFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDGIFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
|
||||||
Me.DEFS_REDGIFS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
|
||||||
Me.DEFS_REDGIFS.Size = New System.Drawing.Size(576, 372)
|
|
||||||
Me.DEFS_REDGIFS.TabIndex = 0
|
|
||||||
'
|
|
||||||
'CONTAINER_MAIN
|
'CONTAINER_MAIN
|
||||||
'
|
'
|
||||||
'
|
'
|
||||||
'CONTAINER_MAIN.ContentPanel
|
'CONTAINER_MAIN.ContentPanel
|
||||||
'
|
'
|
||||||
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
|
Me.CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TAB_MAIN)
|
||||||
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 398)
|
Me.CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(584, 454)
|
||||||
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
Me.CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
Me.CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||||
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
Me.CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||||
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
Me.CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||||
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
|
Me.CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||||
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 398)
|
Me.CONTAINER_MAIN.Size = New System.Drawing.Size(584, 479)
|
||||||
Me.CONTAINER_MAIN.TabIndex = 0
|
Me.CONTAINER_MAIN.TabIndex = 0
|
||||||
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
|
Me.CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||||
'
|
'
|
||||||
|
'CH_RECYCLE_DEL
|
||||||
|
'
|
||||||
|
Me.CH_RECYCLE_DEL.AutoSize = True
|
||||||
|
Me.CH_RECYCLE_DEL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||||
|
Me.CH_RECYCLE_DEL.Location = New System.Drawing.Point(4, 399)
|
||||||
|
Me.CH_RECYCLE_DEL.Name = "CH_RECYCLE_DEL"
|
||||||
|
Me.CH_RECYCLE_DEL.Size = New System.Drawing.Size(562, 19)
|
||||||
|
Me.CH_RECYCLE_DEL.TabIndex = 14
|
||||||
|
Me.CH_RECYCLE_DEL.Text = "Delete data to recycle bin"
|
||||||
|
Me.CH_RECYCLE_DEL.UseVisualStyleBackColor = True
|
||||||
|
'
|
||||||
'GlobalSettingsForm
|
'GlobalSettingsForm
|
||||||
'
|
'
|
||||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||||
Me.ClientSize = New System.Drawing.Size(584, 398)
|
Me.ClientSize = New System.Drawing.Size(584, 479)
|
||||||
Me.Controls.Add(Me.CONTAINER_MAIN)
|
Me.Controls.Add(Me.CONTAINER_MAIN)
|
||||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||||
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
|
||||||
Me.KeyPreview = True
|
Me.KeyPreview = True
|
||||||
Me.MaximizeBox = False
|
Me.MaximizeBox = False
|
||||||
Me.MaximumSize = New System.Drawing.Size(600, 437)
|
Me.MaximumSize = New System.Drawing.Size(600, 518)
|
||||||
Me.MinimizeBox = False
|
Me.MinimizeBox = False
|
||||||
Me.MinimumSize = New System.Drawing.Size(600, 437)
|
Me.MinimumSize = New System.Drawing.Size(600, 518)
|
||||||
Me.Name = "GlobalSettingsForm"
|
Me.Name = "GlobalSettingsForm"
|
||||||
Me.ShowInTaskbar = False
|
Me.ShowInTaskbar = False
|
||||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||||
@@ -997,6 +808,7 @@
|
|||||||
TP_FILE_NAME.PerformLayout()
|
TP_FILE_NAME.PerformLayout()
|
||||||
TP_FILE_PATTERNS.ResumeLayout(False)
|
TP_FILE_PATTERNS.ResumeLayout(False)
|
||||||
TP_FILE_PATTERNS.PerformLayout()
|
TP_FILE_PATTERNS.PerformLayout()
|
||||||
|
CType(Me.TXT_FOLDER_CMD, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
TP_CHANNELS_IMGS.ResumeLayout(False)
|
TP_CHANNELS_IMGS.ResumeLayout(False)
|
||||||
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_CHANNELS_ROWS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_CHANNELS_COLUMNS, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
@@ -1008,23 +820,7 @@
|
|||||||
TP_CHANNELS.ResumeLayout(False)
|
TP_CHANNELS.ResumeLayout(False)
|
||||||
TP_CHANNELS.PerformLayout()
|
TP_CHANNELS.PerformLayout()
|
||||||
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).EndInit()
|
CType(Me.TXT_CHANNEL_USER_POST_LIMIT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||||
TAB_DEFS_REDDIT.ResumeLayout(False)
|
|
||||||
Me.DEFS_REDDIT.ResumeLayout(False)
|
|
||||||
Me.DEFS_REDDIT.PerformLayout()
|
|
||||||
CType(Me.TXT_REDDIT_SAVED_POSTS_USER, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
CType(Me.TXT_REDDIT_SAVED_POSTS_PATH, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
TAB_DEFS_TWITTER.ResumeLayout(False)
|
|
||||||
Me.DEFS_TWITTER.ResumeLayout(False)
|
|
||||||
Me.DEFS_TWITTER.PerformLayout()
|
|
||||||
CType(Me.TXT_REQ_WAIT_TIMER, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
CType(Me.TXT_REQ_COUNT, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
CType(Me.TXT_LIMIT_TIMER, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
Me.TAB_MAIN.ResumeLayout(False)
|
Me.TAB_MAIN.ResumeLayout(False)
|
||||||
Me.TAB_DEFS_INSTAGRAM.ResumeLayout(False)
|
|
||||||
Me.DEFS_INST.ResumeLayout(False)
|
|
||||||
CType(Me.TXT_INST_SAVED_POSTS_USER, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
CType(Me.TXT_INST_SAVED_POSTS_PATH, System.ComponentModel.ISupportInitialize).EndInit()
|
|
||||||
Me.TAB_DEFS_REDGIFS.ResumeLayout(False)
|
|
||||||
Me.CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
Me.CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||||
Me.CONTAINER_MAIN.ResumeLayout(False)
|
Me.CONTAINER_MAIN.ResumeLayout(False)
|
||||||
Me.CONTAINER_MAIN.PerformLayout()
|
Me.CONTAINER_MAIN.PerformLayout()
|
||||||
@@ -1048,11 +844,8 @@
|
|||||||
Private WithEvents CH_DOWN_VIDEOS As CheckBox
|
Private WithEvents CH_DOWN_VIDEOS As CheckBox
|
||||||
Private WithEvents CH_DOWN_IMAGES As CheckBox
|
Private WithEvents CH_DOWN_IMAGES As CheckBox
|
||||||
Private WithEvents CH_DEF_TEMP As CheckBox
|
Private WithEvents CH_DEF_TEMP As CheckBox
|
||||||
Private WithEvents CH_TWITTER_USER_MEDIA As CheckBox
|
|
||||||
Private WithEvents CH_CHANNELS_USERS_TEMP As CheckBox
|
Private WithEvents CH_CHANNELS_USERS_TEMP As CheckBox
|
||||||
Private WithEvents TAB_DEFS_INSTAGRAM As TabPage
|
|
||||||
Private WithEvents TXT_IMGUR_CLIENT_ID As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents TXT_IMGUR_CLIENT_ID As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
Private WithEvents TXT_REDDIT_SAVED_POSTS_USER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
|
||||||
Private WithEvents OPT_FILE_NAME_REPLACE As RadioButton
|
Private WithEvents OPT_FILE_NAME_REPLACE As RadioButton
|
||||||
Private WithEvents OPT_FILE_NAME_ADD_DATE As RadioButton
|
Private WithEvents OPT_FILE_NAME_ADD_DATE As RadioButton
|
||||||
Private WithEvents CH_FILE_NAME_CHANGE As CheckBox
|
Private WithEvents CH_FILE_NAME_CHANGE As CheckBox
|
||||||
@@ -1062,19 +855,12 @@
|
|||||||
Private WithEvents OPT_FILE_DATE_END As RadioButton
|
Private WithEvents OPT_FILE_DATE_END As RadioButton
|
||||||
Private WithEvents CH_EXIT_CONFIRM As CheckBox
|
Private WithEvents CH_EXIT_CONFIRM As CheckBox
|
||||||
Private WithEvents CH_CLOSE_TO_TRAY As CheckBox
|
Private WithEvents CH_CLOSE_TO_TRAY As CheckBox
|
||||||
Private WithEvents TXT_REQ_WAIT_TIMER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
|
||||||
Private WithEvents TXT_REQ_COUNT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
|
||||||
Private WithEvents TXT_LIMIT_TIMER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
|
||||||
Private WithEvents TAB_DEFS_REDGIFS As TabPage
|
|
||||||
Private WithEvents TAB_MAIN As TabControl
|
Private WithEvents TAB_MAIN As TabControl
|
||||||
Private WithEvents DEFS_TWITTER As SiteDefaults
|
|
||||||
Private WithEvents DEFS_REDDIT As SiteDefaults
|
|
||||||
Private WithEvents DEFS_INST As SiteDefaults
|
|
||||||
Private WithEvents DEFS_REDGIFS As SiteDefaults
|
|
||||||
Private WithEvents TXT_INST_SAVED_POSTS_USER As PersonalUtilities.Forms.Controls.TextBoxExtended
|
|
||||||
Private WithEvents CH_SHOW_NOTIFY As CheckBox
|
Private WithEvents CH_SHOW_NOTIFY As CheckBox
|
||||||
Private WithEvents CH_REDDIT_USER_MEDIA As CheckBox
|
Private WithEvents CH_COPY_CHANNEL_USER_IMAGE_ALL As CheckBox
|
||||||
Private WithEvents TXT_REDDIT_SAVED_POSTS_PATH As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents CH_UDESCR_UP As CheckBox
|
||||||
Private WithEvents TXT_INST_SAVED_POSTS_PATH As PersonalUtilities.Forms.Controls.TextBoxExtended
|
Private WithEvents CH_FAST_LOAD As CheckBox
|
||||||
|
Private WithEvents TXT_FOLDER_CMD As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||||
|
Private WithEvents CH_RECYCLE_DEL As CheckBox
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -206,6 +206,14 @@
|
|||||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||||
|
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||||
|
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||||
|
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
<data name="CH_SEPARATE_VIDEO_FOLDER.ToolTip" xml:space="preserve">
|
<data name="CH_SEPARATE_VIDEO_FOLDER.ToolTip" xml:space="preserve">
|
||||||
<value>This is a global setting for newly added users only.
|
<value>This is a global setting for newly added users only.
|
||||||
This parameter specifies how the video will be stored in the users' download path.
|
This parameter specifies how the video will be stored in the users' download path.
|
||||||
@@ -229,50 +237,6 @@ If checked, videos will be stored in separate folder; otherwise, videos will be
|
|||||||
<metadata name="TP_CHANNELS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="TP_CHANNELS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="TAB_DEFS_REDDIT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>False</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>
|
|
||||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
|
||||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
|
||||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
|
||||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
|
||||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
|
||||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
|
||||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
|
||||||
</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>
|
|
||||||
<metadata name="TAB_DEFS_TWITTER.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">
|
|
||||||
<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>
|
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
AAABAA8AAAAQAAEABAAwOgAA9gAAADAwEAABAAQAaAYAACg7AAAgIBAAAQAEAOgCAACQQQAAGBgQAAEA
|
AAABAA8AAAAQAAEABAAwOgAA9gAAADAwEAABAAQAaAYAACg7AAAgIBAAAQAEAOgCAACQQQAAGBgQAAEA
|
||||||
|
|||||||