mirror of
https://github.com/AAndyProgram/SCrawler.git
synced 2026-03-15 08:12:17 +00:00
Compare commits
8 Commits
2025.2.25.
...
2025.10.4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dfd4e8bd1 | ||
|
|
1404afdfa3 | ||
|
|
5857fcfae3 | ||
|
|
e09752a2d5 | ||
|
|
05772a9fc4 | ||
|
|
24ad338c60 | ||
|
|
ff0c4587eb | ||
|
|
fff63d0a9f |
340
Changelog.md
340
Changelog.md
@@ -1,4 +1,156 @@
|
||||
# 2025.2.25.0
|
||||
# Program versions
|
||||
- [ffmpeg](https://github.com/AAndyProgram/SCrawler/wiki/Settings#ffmpeg)
|
||||
- x64 version - [release](https://github.com/GyanD/codexffmpeg/releases/tag/5.1.2); [zip](https://github.com/GyanD/codexffmpeg/releases/download/5.1.2/ffmpeg-5.1.2-full_build.zip); **version `5.1.2-full_build-www.gyan.dev`**
|
||||
- x86 version - [release](https://github.com/yt-dlp/FFmpeg-Builds/releases/tag/autobuild-2022-11-30-12-57); [zip](https://github.com/yt-dlp/FFmpeg-Builds/releases/download/autobuild-2022-11-30-12-57/ffmpeg-N-109274-gd7a5f068c2-win32-gpl.zip); **version `N-109457-geeb280f351-20221226`**
|
||||
- [Gallery-dl](https://github.com/AAndyProgram/SCrawler/wiki/Settings#gallery-dl) - **1.30.9**
|
||||
- [YT-DLP](https://github.com/AAndyProgram/SCrawler/wiki/Settings#yt-dlp) - **2025.09.26**
|
||||
- [OF-Scraper](https://github.com/AAndyProgram/SCrawler/wiki/Settings#of-scraper) - **3.12.9** ([release](https://github.com/datawhores/OF-Scraper/releases/tag/3.12.9))
|
||||
|
||||
# 2025
|
||||
## 2025.10.4.0
|
||||
|
||||
*2025-10-04*
|
||||
|
||||
**xHamster downloads are temporarily disabled**
|
||||
|
||||
- Added
|
||||
- Sites:
|
||||
- Bluesky: **saved posts downloading**
|
||||
- xHamster: **temporarily disable the plugin**
|
||||
- Minor improvements
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.09.26**
|
||||
- gallery-dl up to version **1.30.9**
|
||||
|
||||
## 2025.9.1.0
|
||||
|
||||
*2025-09-01*
|
||||
|
||||
- Fixed
|
||||
- PornHub: data is not downloading
|
||||
|
||||
## 2025.8.30.0
|
||||
|
||||
*2025-08-30*
|
||||
|
||||
- Added
|
||||
- YouTube:
|
||||
- **video trim** *(button `Trim`)*
|
||||
- embed chapters into video file
|
||||
- add artist name when downloading audio
|
||||
- Correct handling of `webp` files
|
||||
- Minor improvements
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.08.27**
|
||||
- gallery-dl up to version **1.30.5**
|
||||
- Fixed
|
||||
- **YouTube: downloading error**
|
||||
- Minor bugs
|
||||
|
||||
## 2025.8.1.0
|
||||
|
||||
*2025-08-01*
|
||||
|
||||
- Added
|
||||
- Sites:
|
||||
- Reddit: **bypass error `429`**
|
||||
- Twitter: **[large profile option](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter-user-settings) in user settings**
|
||||
- Minor improvements
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.07.21**
|
||||
- gallery-dl up to version **1.30.2**
|
||||
- Fixed
|
||||
- Reddit: in some cases crossposts don't download
|
||||
- Minor bugs
|
||||
|
||||
## 2025.7.18.0
|
||||
|
||||
*2025-07-18*
|
||||
|
||||
- Added
|
||||
- Sites:
|
||||
- OnlyFans: support for GIF files
|
||||
- Reddit: extended `429` error handling
|
||||
- Xhamster: support for downloading 'moments'
|
||||
- Minor improvements
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.06.30**
|
||||
- gallery-dl up to version **1.30.0**
|
||||
- Fixed
|
||||
- OnlyFans: **hanging on purchased content**
|
||||
- Minor bugs
|
||||
|
||||
## 2025.6.12.0
|
||||
|
||||
*2025-06-12*
|
||||
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.06.09**
|
||||
- Fixed
|
||||
- Sites:
|
||||
- YouTube: audio formats of protocol `m3u8` are not handled correctly
|
||||
- BlueSky: data is not downloaded in some cases
|
||||
- Reddit: new users do not inherit default text settings
|
||||
- Saved posts: text downloading with saved posts
|
||||
- Environment incorrect output
|
||||
|
||||
## 2025.6.1.0
|
||||
|
||||
*2025-06-01*
|
||||
|
||||
- Added
|
||||
- Sites:
|
||||
- YouTube (standalone app):
|
||||
- support for **youtu.be** domain
|
||||
- **filters**
|
||||
- hotkey `Ctrl+F5` for refresh
|
||||
- **Bluesky, Instagram, OnlyFans, Reddit, Threads, Twitter: the ability to download text posts**
|
||||
- OnlyFans:
|
||||
- updated `DynamicRules`
|
||||
- `backend` option *(`aio` & `httpx`)*
|
||||
- Reddit: add `Best` and `Rising` view modes
|
||||
- TikTok: downloading of avatar, site name and description
|
||||
- Feed:
|
||||
- **filters**
|
||||
- add the ability to show test posts
|
||||
- Minor improvements
|
||||
- Updated
|
||||
- yt-dlp up to version **2025.05.22**
|
||||
- gallery-dl up to version **1.29.7**
|
||||
- PluginProvider
|
||||
- IUserMedia: properties `PostText`, `PostTextFile`, `PostTextFileSpecialFolder`
|
||||
- Fixed
|
||||
- Sites:
|
||||
- OnlyFans:
|
||||
- DRM videos are not downloading in some cases *(only if you can't download video try changing `backend` option to `httpx`)*
|
||||
- incorrect open posts
|
||||
- while limited downloading, the first time, the profile still loads completely
|
||||
- Reddit:
|
||||
- **data is not downloading**
|
||||
- post date is incorrect
|
||||
- Threads
|
||||
- change domain from `net` to `com`
|
||||
- data is not downloading
|
||||
- Twitter
|
||||
- fix JSON error
|
||||
- data is not downloaded in some cases
|
||||
- Minor bugs
|
||||
|
||||
## 2025.3.17.0
|
||||
|
||||
*2025-03-17*
|
||||
|
||||
- Added
|
||||
- **TikTok: downloading photos**
|
||||
- Updated
|
||||
- gallery-dl up to version **1.29.2**
|
||||
- Fixed
|
||||
- Sites
|
||||
- Facebook: reels aren't downloaded from noname profiles
|
||||
- PornHub: newly added users aren't downloading
|
||||
- Threads: users aren't updated if there is a pinned post
|
||||
|
||||
## 2025.2.25.0
|
||||
|
||||
*2025-02-25*
|
||||
|
||||
@@ -30,7 +182,7 @@
|
||||
- Threads: **data is not downloading**
|
||||
- Minor bugs
|
||||
|
||||
# 2025.1.12.0
|
||||
## 2025.1.12.0
|
||||
|
||||
*2025-01-12*
|
||||
|
||||
@@ -55,7 +207,8 @@
|
||||
- YouTube: **communities are not downloading** *(see settings in wiki)*
|
||||
- Minor bugs
|
||||
|
||||
# 2024.11.21.0
|
||||
# 2024
|
||||
## 2024.11.21.0
|
||||
|
||||
*2024-11-21*
|
||||
|
||||
@@ -78,7 +231,7 @@
|
||||
- Main window: in some cases users are not updated in the list
|
||||
- Minor bugs
|
||||
|
||||
# 2024.10.24.0
|
||||
## 2024.10.24.0
|
||||
|
||||
*2024-10-24*
|
||||
|
||||
@@ -103,7 +256,7 @@
|
||||
- Can't change data path (issue #206)
|
||||
- Minor bugs
|
||||
|
||||
# 2024.9.2.0
|
||||
## 2024.9.2.0
|
||||
|
||||
*2024-09-02*
|
||||
|
||||
@@ -119,7 +272,7 @@
|
||||
- YouTube (SCrawler): incorrect parsing of video page
|
||||
- Minor bugs
|
||||
|
||||
# 2024.8.10.0
|
||||
## 2024.8.10.0
|
||||
|
||||
*2024-08-10*
|
||||
|
||||
@@ -131,7 +284,7 @@
|
||||
- Fixed
|
||||
- YouTube (standalone app): **video is being parsed using cookies but is not downloading** *(Issue #205)*
|
||||
|
||||
# 2024.8.1.0
|
||||
## 2024.8.1.0
|
||||
|
||||
*2024-08-01*
|
||||
|
||||
@@ -140,7 +293,7 @@
|
||||
- Updated
|
||||
- yt-dlp up to version **2024.08.01**
|
||||
|
||||
# 2024.7.24.0
|
||||
## 2024.7.24.0
|
||||
|
||||
*2024-07-24*
|
||||
|
||||
@@ -163,7 +316,7 @@
|
||||
- OnlyFans: rules parsing bug
|
||||
- Minor bugs
|
||||
|
||||
# 2024.6.25.0
|
||||
## 2024.6.25.0
|
||||
|
||||
*2024-06-25*
|
||||
|
||||
@@ -177,7 +330,7 @@
|
||||
- Fixed
|
||||
- Minor bugs
|
||||
|
||||
# 2024.6.10.0
|
||||
## 2024.6.10.0
|
||||
|
||||
*2024-06-10*
|
||||
|
||||
@@ -190,7 +343,7 @@
|
||||
- Fixed
|
||||
- Minor bugs
|
||||
|
||||
# 2024.6.6.0
|
||||
## 2024.6.6.0
|
||||
|
||||
*2024-06-06*
|
||||
|
||||
@@ -206,7 +359,7 @@
|
||||
- OnlyFans: **data is not downloading**
|
||||
- Minor bugs
|
||||
|
||||
# 2024.6.4.0
|
||||
## 2024.6.4.0
|
||||
|
||||
*2024-06-04*
|
||||
|
||||
@@ -225,7 +378,7 @@
|
||||
- Twitter: deleting user directory when redownloading missing posts
|
||||
- Minor bugs
|
||||
|
||||
# 2024.5.19.0
|
||||
## 2024.5.19.0
|
||||
|
||||
*2024-05-19*
|
||||
|
||||
@@ -234,7 +387,7 @@
|
||||
- Fixed
|
||||
- YouTube (SCrawler): advanced settings are not saved when changed
|
||||
|
||||
# 2024.5.18.0
|
||||
## 2024.5.18.0
|
||||
|
||||
*2024-05-18*
|
||||
|
||||
@@ -261,7 +414,7 @@
|
||||
- Twitter: **data is not downloading due to domain change from twitter.com to x.com**
|
||||
- Minor bugs
|
||||
|
||||
# 2024.5.4.0
|
||||
## 2024.5.4.0
|
||||
|
||||
*2024-05-04*
|
||||
|
||||
@@ -276,7 +429,7 @@
|
||||
- Reddit: token update error
|
||||
- Threads: unable to obtain credentials (`ID`)
|
||||
|
||||
# 2024.4.26.0
|
||||
## 2024.4.26.0
|
||||
|
||||
*2024-04-26*
|
||||
|
||||
@@ -289,14 +442,14 @@
|
||||
- Fixed
|
||||
- xHamster: **saved posts aren't downloading**
|
||||
|
||||
# 2024.4.14.0
|
||||
## 2024.4.14.0
|
||||
|
||||
*2024-04-14*
|
||||
|
||||
- Fixed
|
||||
- Facebook: can't get tokens
|
||||
|
||||
# 2024.4.13.0
|
||||
## 2024.4.13.0
|
||||
|
||||
*2024-04-13*
|
||||
|
||||
@@ -310,7 +463,7 @@
|
||||
- YouTube: remove last download date when erasing history data
|
||||
- Instagram: **saved posts aren't downloading**
|
||||
|
||||
# 2024.4.10.0
|
||||
## 2024.4.10.0
|
||||
|
||||
*2024-04-10*
|
||||
|
||||
@@ -378,7 +531,7 @@
|
||||
- Feed: a scrolling bug where the feed scrolls up after returning to it
|
||||
- Minor bugs
|
||||
|
||||
# 2024.2.25.0
|
||||
## 2024.2.25.0
|
||||
|
||||
*2024-02-25*
|
||||
|
||||
@@ -412,7 +565,7 @@
|
||||
- TikTok: files with long names aren't downloaded
|
||||
- Minor bugs
|
||||
|
||||
# 2024.1.26.0
|
||||
## 2024.1.26.0
|
||||
|
||||
*2024-01-26*
|
||||
|
||||
@@ -424,7 +577,7 @@
|
||||
- Instagram: stories (user) downloading with the wrong aspect ratio for some users
|
||||
- Minor bugs
|
||||
|
||||
# 2024.1.20.0
|
||||
## 2024.1.20.0
|
||||
|
||||
*2024-01-20*
|
||||
|
||||
@@ -432,7 +585,7 @@
|
||||
- Instagram: **the ability to download reels**
|
||||
- LPSG: handle 404 error
|
||||
|
||||
# 2024.1.18.0
|
||||
## 2024.1.18.0
|
||||
|
||||
*2024-01-18*
|
||||
|
||||
@@ -442,7 +595,7 @@
|
||||
- YouTube (standalone app): URL array form doesn't show scrollbars
|
||||
- Minor bugs
|
||||
|
||||
# 2024.1.12.1
|
||||
## 2024.1.12.1
|
||||
|
||||
*2024-01-12*
|
||||
|
||||
@@ -455,7 +608,7 @@
|
||||
- YouTube: incorrect opening of a post from the feed
|
||||
- YouTube: wrong date to data parsing
|
||||
|
||||
# 2024.1.12.0
|
||||
## 2024.1.12.0
|
||||
|
||||
*2024-01-12*
|
||||
|
||||
@@ -471,7 +624,8 @@
|
||||
- xHamster: profiles are not downloading
|
||||
- Minor bugs
|
||||
|
||||
# 2023.12.27.0
|
||||
# 2023
|
||||
## 2023.12.27.0
|
||||
|
||||
*2023-12-27*
|
||||
|
||||
@@ -485,7 +639,7 @@
|
||||
- Saved posts: session file is not updated when new data is added
|
||||
- Minor bugs
|
||||
|
||||
# 2023.12.15.0
|
||||
## 2023.12.15.0
|
||||
|
||||
*2023-12-15*
|
||||
|
||||
@@ -493,7 +647,7 @@
|
||||
- Twitter: some twitter profiles don't download completely
|
||||
- Minor bugs
|
||||
|
||||
# 2023.12.14.0
|
||||
## 2023.12.14.0
|
||||
|
||||
*2023-12-14*
|
||||
|
||||
@@ -501,7 +655,7 @@
|
||||
- YouTube: options `Create thumbnail files (video)` and `Create thumbnail files (music)`
|
||||
- YouTube: `Select all` and `Select none` buttons
|
||||
|
||||
# 2023.12.13.0
|
||||
## 2023.12.13.0
|
||||
|
||||
*2023-12-13*
|
||||
|
||||
@@ -513,7 +667,7 @@
|
||||
- Feed: saved posts are added to the end of the feed
|
||||
- xHamster: some videos won't download
|
||||
|
||||
# 2023.12.10.0
|
||||
## 2023.12.10.0
|
||||
|
||||
*2023-12-10*
|
||||
|
||||
@@ -522,7 +676,7 @@
|
||||
- Fixed
|
||||
- Twitter: data is not downloading
|
||||
|
||||
# 2023.12.7.0
|
||||
## 2023.12.7.0
|
||||
|
||||
*2023-12-07*
|
||||
|
||||
@@ -538,14 +692,14 @@
|
||||
- Standalone downloader: URL files are not deleted along with the file
|
||||
- Minor bugs
|
||||
|
||||
# 2023.11.25.0
|
||||
## 2023.11.25.0
|
||||
|
||||
*2023-11-25*
|
||||
|
||||
- Fixed
|
||||
- Reddit: missing refresh token button in the settings form
|
||||
|
||||
# 2023.11.24.0
|
||||
## 2023.11.24.0
|
||||
|
||||
*2023-11-24*
|
||||
|
||||
@@ -569,7 +723,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- YouTube: path not set when adding array to download
|
||||
- Minor bugs
|
||||
|
||||
# 2023.11.17.0
|
||||
## 2023.11.17.0
|
||||
|
||||
*2023-11-17*
|
||||
|
||||
@@ -599,7 +753,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Automation: handle automation start error (in some cases) when changing scheduler
|
||||
- Minor bugs
|
||||
|
||||
# 2023.10.10.0
|
||||
## 2023.10.10.0
|
||||
|
||||
*2023-10-10*
|
||||
|
||||
@@ -625,7 +779,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Standalone downloader: cached thumbnail is not removed when item is removed from the list
|
||||
- Minor bugs
|
||||
|
||||
# 2023.10.1.0
|
||||
## 2023.10.1.0
|
||||
|
||||
*2023-10-01*
|
||||
|
||||
@@ -640,14 +794,14 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- JustForFans: some profiles won't download
|
||||
- Minor bugs
|
||||
|
||||
# 2023.9.21.0
|
||||
## 2023.9.21.0
|
||||
|
||||
*2023-09-21*
|
||||
|
||||
- Fixed
|
||||
- PornHub: videos are not downloading
|
||||
|
||||
# 2023.9.20.0
|
||||
## 2023.9.20.0
|
||||
|
||||
*2023-09-20*
|
||||
|
||||
@@ -663,7 +817,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Instagram: handle error 500
|
||||
- Collections: update labels only for the added user
|
||||
|
||||
# 2023.8.27.0
|
||||
## 2023.8.27.0
|
||||
|
||||
*2023-08-27*
|
||||
|
||||
@@ -682,7 +836,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Auto downloader: downloading stuck
|
||||
- Minor bugs
|
||||
|
||||
# 2023.8.6.0
|
||||
## 2023.8.6.0
|
||||
|
||||
*2023-08-06*
|
||||
|
||||
@@ -770,7 +924,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- YouTube: a bug that caused the video to redownload
|
||||
- Minor bugs
|
||||
|
||||
# 2023.6.19.0
|
||||
## 2023.6.19.0
|
||||
|
||||
*2023-06-19*
|
||||
|
||||
@@ -790,7 +944,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Progress bar bugs
|
||||
- Minor bugs
|
||||
|
||||
# 2023.6.9.0
|
||||
## 2023.6.9.0
|
||||
|
||||
*2023-06-09*
|
||||
|
||||
@@ -799,7 +953,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Twitter: make the algorithm faster
|
||||
- Make progress more informative
|
||||
|
||||
# 2023.6.8.0
|
||||
## 2023.6.8.0
|
||||
|
||||
*2023-06-08*
|
||||
|
||||
@@ -811,7 +965,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Twitter: profile not fully downloaded
|
||||
- Corrected form size for small monitors (Issue #136)
|
||||
|
||||
# 2023.6.5.0
|
||||
## 2023.6.5.0
|
||||
|
||||
*2023-06-05*
|
||||
|
||||
@@ -830,7 +984,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Saved posts: remove main progress perform when downloading saved posts
|
||||
- Minor bugs
|
||||
|
||||
# 2023.5.12.0
|
||||
## 2023.5.12.0
|
||||
|
||||
*2023-05-12*
|
||||
|
||||
@@ -848,7 +1002,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Reddit: missing & broken images bug
|
||||
- Main window: collection pointing bug
|
||||
|
||||
# 2023.4.28.0
|
||||
## 2023.4.28.0
|
||||
|
||||
*2023-04-28*
|
||||
|
||||
@@ -892,7 +1046,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- PornHub: photo galleries bug (Issue #115)
|
||||
- Minor bugs
|
||||
|
||||
# 2023.3.5.0
|
||||
## 2023.3.5.0
|
||||
|
||||
*2023-03-05*
|
||||
|
||||
@@ -901,7 +1055,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- An error that could occur during Twitter MD5 comparison.
|
||||
- A bug in the ffmpeg file parts concatenation algorithm that could occur in some cases.
|
||||
|
||||
# 2023.3.1.0
|
||||
## 2023.3.1.0
|
||||
|
||||
*2023-03-01*
|
||||
|
||||
@@ -923,7 +1077,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- (Issue #106) problem with non-Latin characters
|
||||
- ffmpeg: maximum input length error when merging parts of files
|
||||
|
||||
# 2023.2.5.0
|
||||
## 2023.2.5.0
|
||||
|
||||
*2023-02-05*
|
||||
|
||||
@@ -932,7 +1086,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- (Issue #101) Failed download Gfycat video in some cases
|
||||
|
||||
# 2023.1.27.0
|
||||
## 2023.1.27.0
|
||||
|
||||
*2023-01-27*
|
||||
|
||||
@@ -946,7 +1100,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- `Interaction` option to the `Provider` attribute
|
||||
- `IPropertyProvider` interface
|
||||
|
||||
# 2023.1.24.1
|
||||
## 2023.1.24.1
|
||||
|
||||
*2023-01-24*
|
||||
|
||||
@@ -955,7 +1109,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- (Issue #100) some Imgur albums won't download
|
||||
|
||||
# 2023.1.24.0
|
||||
## 2023.1.24.0
|
||||
|
||||
*2023-01-24*
|
||||
|
||||
@@ -963,7 +1117,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- (Issue #100) Imgur albums not downloading
|
||||
- When deleting a collection with the 'ban' option, users in the collection are not banned
|
||||
|
||||
# 2023.1.2.0
|
||||
## 2023.1.2.0
|
||||
|
||||
*2023-01-02*
|
||||
|
||||
@@ -978,7 +1132,8 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed a bug in the user list loading algorithm
|
||||
- Notifications: pressing any button opens SCrawler
|
||||
|
||||
# 2022.12.27.0
|
||||
# 2022
|
||||
## 2022.12.27.0
|
||||
|
||||
*2022-12-27*
|
||||
|
||||
@@ -988,7 +1143,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- XVideos not downloading (sorry, I broke it in a previous release)
|
||||
|
||||
# 2022.12.26.0
|
||||
## 2022.12.26.0
|
||||
|
||||
*2022-12-26*
|
||||
|
||||
@@ -1011,7 +1166,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- (Issue #69) **RedGifs data is not downloading**. Again.
|
||||
- Minor bugs
|
||||
|
||||
# 2022.11.16.0
|
||||
## 2022.11.16.0
|
||||
|
||||
*2022-11-16*
|
||||
|
||||
@@ -1045,7 +1200,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Users search form doesn't remember last size
|
||||
- Minor bugs
|
||||
|
||||
# 2022.10.23.0
|
||||
## 2022.10.23.0
|
||||
|
||||
*2022-10-23*
|
||||
|
||||
@@ -1064,7 +1219,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- (Issue #69) **RedGifs data is not downloading**. Requires token.
|
||||
- Minor bugs
|
||||
|
||||
# 2022.10.18.0
|
||||
## 2022.10.18.0
|
||||
|
||||
*2022-10-18*
|
||||
|
||||
@@ -1099,7 +1254,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- When trying to delete multiple collections, each collection asked for confirmation to delete
|
||||
- Minor bugs
|
||||
|
||||
# 2022.9.24.0
|
||||
## 2022.9.24.0
|
||||
|
||||
*2022-09-24*
|
||||
|
||||
@@ -1117,7 +1272,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Bug in the XVIDEOS downloader
|
||||
- Minor bugs
|
||||
|
||||
# 2022.9.17.0
|
||||
## 2022.9.17.0
|
||||
|
||||
*2022-09-17*
|
||||
|
||||
@@ -1133,7 +1288,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Incorrect feed sorting algorithm
|
||||
- Minor bugs
|
||||
|
||||
# 2022.9.16.0
|
||||
## 2022.9.16.0
|
||||
|
||||
*2022-09-16*
|
||||
|
||||
@@ -1142,7 +1297,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Incorrect rendering of the 'Feed' table when the number of columns is more than one
|
||||
- Minor design bugs
|
||||
|
||||
# 2022.9.13.0
|
||||
## 2022.9.13.0
|
||||
|
||||
*2022-09-13*
|
||||
|
||||
@@ -1152,21 +1307,21 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- (Issue #70) Instagram posts not downloading if there are pinned posts that have already been downloaded
|
||||
- Minor bugs
|
||||
|
||||
# 2022.9.10.0
|
||||
## 2022.9.10.0
|
||||
|
||||
*2022-09-10*
|
||||
|
||||
- Fixed
|
||||
- The memory is still leaking. This time because of the video. *Using WMP was not the best choice.*
|
||||
|
||||
# 2022.9.8.1
|
||||
## 2022.9.8.1
|
||||
|
||||
*2022-09-08*
|
||||
|
||||
- Fixed
|
||||
- Unexpected memory leak when using the 'Feed' form
|
||||
|
||||
# 2022.9.8.0
|
||||
## 2022.9.8.0
|
||||
|
||||
*2022-09-08*
|
||||
|
||||
@@ -1177,7 +1332,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- (Issue #67) Saved Instagram posts not downloading
|
||||
|
||||
# 2022.8.28.0
|
||||
## 2022.8.28.0
|
||||
|
||||
*2022-08-28*
|
||||
|
||||
@@ -1186,7 +1341,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- Incorrect number of posts displayed in the Reddit channels downloader.
|
||||
|
||||
# 2022.8.22.0
|
||||
## 2022.8.22.0
|
||||
|
||||
*2022-08-22*
|
||||
|
||||
@@ -1200,7 +1355,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- AutoDownloader option ```Show notifications``` not saved
|
||||
- Minor bugs
|
||||
|
||||
# 2022.7.7.0
|
||||
## 2022.7.7.0
|
||||
|
||||
*2022-07-07*
|
||||
|
||||
@@ -1218,7 +1373,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- In some cases, Twitter image is not downloading
|
||||
- Minor bugs
|
||||
|
||||
# 2022.6.10.0
|
||||
## 2022.6.10.0
|
||||
|
||||
*2022-06-10*
|
||||
|
||||
@@ -1227,7 +1382,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- Fixed
|
||||
- Can't get Instagram user ID
|
||||
|
||||
# 2022.6.6.0
|
||||
## 2022.6.6.0
|
||||
|
||||
*2022-06-06*
|
||||
|
||||
@@ -1237,7 +1392,7 @@ For those of you who use TikTok, I recommend updating [TikTok plugin](https://gi
|
||||
- GIFs from Twitter not downloading
|
||||
- Not quite correct algorithm for stopping automation
|
||||
|
||||
# 2022.6.3.0
|
||||
## 2022.6.3.0
|
||||
|
||||
*2022-06-03*
|
||||
|
||||
@@ -1252,7 +1407,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Videos hosted on Reddit that are downloaded via m3u8 playlists are missing an audio track.
|
||||
- Instagram hash not able to be auto-filled from cookies
|
||||
|
||||
# 3.0.0.10
|
||||
## 3.0.0.10
|
||||
|
||||
*2022-05-23*
|
||||
|
||||
@@ -1275,7 +1430,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- In some cases, the date and time are not added to the filename
|
||||
- Unable to download photos from Twitter in full resolution (4K)
|
||||
|
||||
# 3.0.0.9
|
||||
## 3.0.0.9
|
||||
|
||||
*2022-04-24*
|
||||
|
||||
@@ -1287,7 +1442,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Removed adding "No Parsed" internal label when not needed
|
||||
- Redownloading Instagram Stories
|
||||
|
||||
# 3.0.0.8
|
||||
## 3.0.0.8
|
||||
|
||||
*2022-04-19*
|
||||
|
||||
@@ -1297,7 +1452,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Fixed
|
||||
- The script does not run after the user download is complete
|
||||
|
||||
# 3.0.0.7
|
||||
## 3.0.0.7
|
||||
|
||||
*2022-04-14*
|
||||
|
||||
@@ -1309,7 +1464,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- (Issue #33) Instagram Stories downloading error
|
||||
- LPSG downloader does not download all content
|
||||
|
||||
# 3.0.0.6
|
||||
## 3.0.0.6
|
||||
|
||||
*2022-04-04*
|
||||
|
||||
@@ -1322,14 +1477,14 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Incorrect behavior of the main progress bar when downloading saved posts
|
||||
- (Issue #25) Date and Time not added for Stories and Tagged Photos
|
||||
|
||||
# 3.0.0.5
|
||||
## 3.0.0.5
|
||||
|
||||
*2022-04-02*
|
||||
|
||||
- Added
|
||||
- ```New```, ```Hot```, ```Top``` Reddit channel and user download modes
|
||||
|
||||
# 3.0.0.4
|
||||
## 3.0.0.4
|
||||
|
||||
*2022-03-26*
|
||||
|
||||
@@ -1337,7 +1492,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- External plugins do not save information about downloaded files
|
||||
- The user cannot be added to the collection if a special path has been specified.
|
||||
|
||||
# 3.0.0.3
|
||||
## 3.0.0.3
|
||||
|
||||
*2022-03-24*
|
||||
|
||||
@@ -1350,7 +1505,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Typo when applying "Download UHD" in XVIDEOS plugin
|
||||
- The sites filter does not work unless the "Fast profiles loading" option is enabled.
|
||||
|
||||
# 3.0.0.2
|
||||
## 3.0.0.2
|
||||
|
||||
*2022-03-22*
|
||||
|
||||
@@ -1362,7 +1517,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Fixed
|
||||
- Minor bugs
|
||||
|
||||
# 3.0.0.1
|
||||
## 3.0.0.1
|
||||
|
||||
*2022-03-20*
|
||||
|
||||
@@ -1377,7 +1532,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
- Some design fixes
|
||||
- Minor bugs
|
||||
|
||||
# 3.0.0.0
|
||||
## 3.0.0.0
|
||||
|
||||
*2022-03-17*
|
||||
|
||||
@@ -1419,7 +1574,7 @@ Changed version numbering method. From now on, new versions will be numbered by
|
||||
|
||||
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
|
||||
|
||||
*2022-02-07*
|
||||
|
||||
@@ -1435,7 +1590,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- **Error when specifying network paths**
|
||||
- Minor bugs
|
||||
|
||||
# 2.0.0.3
|
||||
## 2.0.0.3
|
||||
|
||||
*2022-02-02*
|
||||
|
||||
@@ -1452,7 +1607,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Collection ignored when validated when creating a new user
|
||||
- Incorrect number of Instagram profiles downloads per session
|
||||
|
||||
# 2.0.0.2
|
||||
## 2.0.0.2
|
||||
|
||||
*2022-01-23*
|
||||
|
||||
@@ -1476,7 +1631,8 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Fixed
|
||||
- The program was showing incorrect information about the total numbers of images and videos downloaded when a Reddit user was created from a channel
|
||||
|
||||
# 2.0.0.1
|
||||
# 2021
|
||||
## 2.0.0.1
|
||||
|
||||
*2021-12-29*
|
||||
|
||||
@@ -1486,7 +1642,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Incorrect filling of user parameters in the user creation form
|
||||
- In some cases, the global settings cannot be saved.
|
||||
|
||||
# 2.0.0.0
|
||||
## 2.0.0.0
|
||||
|
||||
*2021-12-27*
|
||||
|
||||
@@ -1505,7 +1661,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Suspended profiles do not change status if the profile is no longer suspended
|
||||
- Limited download for Twitter not implemented
|
||||
|
||||
# 1.0.1.0
|
||||
## 1.0.1.0
|
||||
|
||||
*2021-12-20*
|
||||
|
||||
@@ -1528,7 +1684,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Users in the main window are not refreshed if new users are added by a list that includes banned and/or unrecognized users.
|
||||
- Minor bugs
|
||||
|
||||
# 1.0.0.4
|
||||
## 1.0.0.4
|
||||
|
||||
*2021-12-12*
|
||||
|
||||
@@ -1538,7 +1694,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Fixed
|
||||
- Images hosted on Imgur won't download
|
||||
|
||||
# 1.0.0.3
|
||||
## 1.0.0.3
|
||||
|
||||
*2021-12-11*
|
||||
|
||||
@@ -1546,7 +1702,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Custom "Download videos" option is not saved
|
||||
- The "Download all" button is not activated after changing modes
|
||||
|
||||
# 1.0.0.2
|
||||
## 1.0.0.2
|
||||
|
||||
*2021-12-10*
|
||||
|
||||
@@ -1556,7 +1712,7 @@ At the requests of some users, I added [screenshots](ProgramScreenshots) of the
|
||||
- Fixed
|
||||
- In some cases, the "Stop" button is not activated after download start
|
||||
|
||||
# 1.0.0.1
|
||||
## 1.0.0.1
|
||||
|
||||
*2021-12-09*
|
||||
|
||||
|
||||
14
README.md
14
README.md
@@ -35,17 +35,17 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
||||
# What can program do:
|
||||
- Download pictures and videos from user profiles:
|
||||
- YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks;
|
||||
- Reddit images, galleries of images, videos, saved posts;
|
||||
- Reddit images, galleries of images, videos, text, saved posts;
|
||||
- Redgifs images and videos (https://www.redgifs.com/);
|
||||
- Twitter images and videos, saved (bookmarked) posts, likes, communities;
|
||||
- Bluesky images and videos;
|
||||
- OnlyFans images and videos, saved (bookmarked) posts, stories;
|
||||
- Twitter images and videos, text, saved (bookmarked) posts, likes, communities;
|
||||
- Bluesky images and videos, text;
|
||||
- OnlyFans images and videos, text, saved (bookmarked) posts, stories;
|
||||
- JustForFans images and videos, saved (bookmarked) posts;
|
||||
- Mastodon images and videos, saved (bookmarked) posts;
|
||||
- Instagram images and videos, tagged posts, stories, saved posts;
|
||||
- Threads images and videos, saved posts;
|
||||
- Instagram images and videos, text, tagged posts, stories, saved posts;
|
||||
- Threads images and videos, text, saved posts;
|
||||
- Facebook images and videos, stories, saved posts;
|
||||
- TikTok videos;
|
||||
- TikTok images and videos;
|
||||
- Pinterest boards, users, saved posts;
|
||||
- Imgur images, galleries and videos;
|
||||
- Gfycat videos;
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyVersion("2025.6.1.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.6.1.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
@@ -35,6 +35,9 @@ Namespace Plugin
|
||||
Public Property DownloadState As UserMediaStates Implements IUserMedia.DownloadState
|
||||
Public Property PostID As String Implements IUserMedia.PostID
|
||||
Public Property PostDate As Date? Implements IUserMedia.PostDate
|
||||
Public Property PostText As String Implements IUserMedia.PostText
|
||||
Public Property PostTextFile As String Implements IUserMedia.PostTextFile
|
||||
Public Property PostTextFileSpecialFolder As Boolean Implements IUserMedia.PostTextFileSpecialFolder
|
||||
Public Property SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||
Public Property Attempts As Integer Implements IUserMedia.Attempts
|
||||
Public Property [Object] As Object Implements IUserMedia.Object
|
||||
@@ -48,6 +51,9 @@ Namespace Plugin
|
||||
Property DownloadState As UserMediaStates
|
||||
Property PostID As String
|
||||
Property PostDate As Date?
|
||||
Property PostText As String
|
||||
Property PostTextFile As String
|
||||
Property PostTextFileSpecialFolder As Boolean
|
||||
Property SpecialFolder As String
|
||||
Property Attempts As Integer
|
||||
Property [Object] As Object
|
||||
|
||||
BIN
SCrawler.Shared/Content/Icons/FilterIcon.ico
Normal file
BIN
SCrawler.Shared/Content/Icons/FilterIcon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
SCrawler.Shared/Content/Images/FilterPic.png
Normal file
BIN
SCrawler.Shared/Content/Images/FilterPic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 320 B |
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2023.12.15.0")>
|
||||
<Assembly: AssemblyFileVersion("2023.12.15.0")>
|
||||
<Assembly: AssemblyVersion("2025.6.1.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.6.1.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
26
SCrawler.Shared/My Project/Resources.Designer.vb
generated
26
SCrawler.Shared/My Project/Resources.Designer.vb
generated
@@ -26,7 +26,7 @@ Namespace My.Resources
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
Public Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
@@ -36,7 +36,7 @@ Namespace My.Resources
|
||||
''' 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
|
||||
Public 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)
|
||||
@@ -51,7 +51,7 @@ Namespace My.Resources
|
||||
''' 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
|
||||
Public Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
@@ -59,5 +59,25 @@ Namespace My.Resources
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
'''</summary>
|
||||
Public ReadOnly Property FilterIcon() As System.Drawing.Icon
|
||||
Get
|
||||
Dim obj As Object = ResourceManager.GetObject("FilterIcon", resourceCulture)
|
||||
Return CType(obj,System.Drawing.Icon)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
'''</summary>
|
||||
Public ReadOnly Property FilterPic() As System.Drawing.Bitmap
|
||||
Get
|
||||
Dim obj As Object = ResourceManager.GetObject("FilterPic", resourceCulture)
|
||||
Return CType(obj,System.Drawing.Bitmap)
|
||||
End Get
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
@@ -60,6 +60,7 @@
|
||||
: 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">
|
||||
@@ -68,9 +69,10 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<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">
|
||||
@@ -85,9 +87,10 @@
|
||||
<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="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">
|
||||
@@ -109,9 +112,16 @@
|
||||
<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>
|
||||
<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=2.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>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="FilterIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Icons\FilterIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="FilterPic" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Content\Images\FilterPic.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -82,6 +82,7 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -123,7 +124,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<Generator>PublicVbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -147,5 +148,9 @@
|
||||
<Name>PersonalUtilities</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Icons\FilterIcon.ico" />
|
||||
<Content Include="Content\Images\FilterPic.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -136,4 +136,34 @@ Namespace API.YouTube.Base
|
||||
End If
|
||||
End Function
|
||||
End Structure
|
||||
Public Structure TrimOption : Implements IComparable(Of TrimOption)
|
||||
Public Name As String
|
||||
Public Start As Integer
|
||||
Public ReadOnly Property StartTime As TimeSpan
|
||||
Get
|
||||
Return TimeSpan.FromSeconds(Start)
|
||||
End Get
|
||||
End Property
|
||||
Public [End] As Integer
|
||||
Public ReadOnly Property EndTime As TimeSpan
|
||||
Get
|
||||
Return TimeSpan.FromSeconds([End])
|
||||
End Get
|
||||
End Property
|
||||
Public Shared Widening Operator CType(ByVal t As TrimOption) As String
|
||||
Return t.ToString
|
||||
End Operator
|
||||
Public Overrides Function ToString() As String
|
||||
Dim v$ = $"{Start} - {[End]}"
|
||||
If Not Name.IsEmptyString Then v = $"[{v}] - {Name}"
|
||||
Return v
|
||||
End Function
|
||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||
Try : With DirectCast(Obj, TrimOption) : Return Start = .Start And [End] = .End : End With : Catch : End Try
|
||||
Return False
|
||||
End Function
|
||||
Private Function CompareTo(ByVal Other As TrimOption) As Integer Implements IComparable(Of TrimOption).CompareTo
|
||||
Return Start.CompareTo(Other.Start)
|
||||
End Function
|
||||
End Structure
|
||||
End Namespace
|
||||
@@ -18,6 +18,7 @@ Namespace API.YouTube.Base
|
||||
Public Const TrueUrlPattern As String = "https?://[^/]*?youtube.com/[^\?/&]+((\??[^\?/&]+|/[^\?/&]+))"
|
||||
'2 - type; 5 - id
|
||||
Public Const UrlTypePattern As String = "(?<=https?://[^/]*?youtube.com/)((@|[^\?/&]+))([/\?]{0,1}(list=|v=|)([^\?/&]*))(?=(\S+|\Z|))"
|
||||
Public Const UrlTypePattern_BE As String = "(?<=https?://[^/]*?youtu.be/)([^\?/&]+)"
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Public Shared Function StandardizeURL(ByVal URL As String) As String
|
||||
@@ -36,6 +37,7 @@ Namespace API.YouTube.Base
|
||||
Next
|
||||
data.Clear()
|
||||
End If
|
||||
If val.IsEmptyString Then val = RegexReplace(URL, RParams.DMS(UrlTypePattern_BE, 0, EDP.ReturnValue))
|
||||
If Not val.IsEmptyString Then Return $"https://www.youtube.com/watch?v={val}"
|
||||
End If
|
||||
End If
|
||||
@@ -100,6 +102,9 @@ Namespace API.YouTube.Base
|
||||
Return YouTubeMediaType.Channel
|
||||
End Select
|
||||
End If
|
||||
Else
|
||||
Dim v$ = RegexReplace(URL, RParams.DMS(UrlTypePattern_BE, 0, EDP.ReturnValue))
|
||||
If Not v.IsEmptyString Then Return YouTubeMediaType.Single
|
||||
End If
|
||||
End If
|
||||
Return YouTubeMediaType.Undefined
|
||||
|
||||
@@ -33,6 +33,7 @@ Namespace API.YouTube.Base
|
||||
#Region "Declarations"
|
||||
<Browsable(False)> Private ReadOnly Property XML As XmlFile Implements IXMLValuesContainer.XML
|
||||
<Browsable(False)> Friend ReadOnly Property DesignXml As XmlFile
|
||||
<Browsable(False)> Friend ReadOnly Property FILTER As Controls.YTDataFilter
|
||||
<Browsable(False)> Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode
|
||||
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
|
||||
<Browsable(False)> Friend ReadOnly Property DownloadLocations As DownloadLocationsCollection
|
||||
@@ -267,6 +268,9 @@ Namespace API.YouTube.Base
|
||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}, FileDateMode.None), Category("Defaults"), DisplayName("Add channel to file name"),
|
||||
Description("Add channel name before/after the file name")>
|
||||
Public ReadOnly Property FileAddChannelToFileName As XMLValue(Of FileDateMode)
|
||||
<Browsable(True), GridVisible, XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Parse long user titles"),
|
||||
Description("Suitable for multiple artists")>
|
||||
Public ReadOnly Property ParseLongUserTitle As XMLValue(Of Boolean)
|
||||
#End Region
|
||||
#Region "Defaults ChannelsDownload"
|
||||
<Browsable(True), GridVisible, XMLVN({"Defaults", "Channels"}), Category("Defaults"), DisplayName("Default download tabs for channels"),
|
||||
@@ -318,8 +322,11 @@ Namespace API.YouTube.Base
|
||||
Description("Convert non-AVC codecs (eg 'VP9') to AVC. Not recommended due to high CPU usage!")>
|
||||
Public ReadOnly Property DefaultVideoConvertNonAVC As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, False), Category("Defaults Video"), DisplayName("Embed thumbnail (video)"),
|
||||
Description("Embed thumbnail in the video as cover art. Default: true.")>
|
||||
Description("Embed thumbnail in the video as cover art. Default: false.")>
|
||||
Public ReadOnly Property DefaultVideoEmbedThumbnail As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, True), Category("Defaults Video"), DisplayName("Embed chapters"),
|
||||
Description("Embed chapters in the video. Default: true.")>
|
||||
Public ReadOnly Property DefaultVideoEmbedChapters As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}), Category("Defaults Video"), DisplayName("Include zero size formats"),
|
||||
Description("Include formats with zero size (or undefined size).")>
|
||||
Public ReadOnly Property DefaultVideoIncludeNullSize As XMLValue(Of Boolean)
|
||||
@@ -495,6 +502,26 @@ Namespace API.YouTube.Base
|
||||
Description("Additional format for downloading subtitles. This means that all subtitles will be converted to the formats you choose and saved as separate files.")>
|
||||
Public ReadOnly Property DefaultSubtitlesFormatAddit As XMLValuesCollection(Of String)
|
||||
#End Region
|
||||
#Region "Trim"
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsTrim"}, False), Category("Defaults Trimming"), DisplayName("Delete original file"),
|
||||
Description("If true, the original file will be deleted after trimming")>
|
||||
Public ReadOnly Property TrimDeleteOriginalFile As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsTrim"}, False), Category("Defaults Trimming"), DisplayName("Add to M3U8"),
|
||||
Description("If true, the trimmed files will be added to the M3U8 playlist (if selected)")>
|
||||
Public ReadOnly Property TrimAddTrimmedFilesToM3U8 As XMLValue(Of Boolean)
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsTrim"}, False), Category("Defaults Trimming"), DisplayName("Separate folder"),
|
||||
Description("Place the trimmed files in a separate folder")>
|
||||
Public ReadOnly Property TrimSeparateFolder As XMLValue(Of Boolean)
|
||||
Friend Const TrimSeparateFolderNameDefault As String = "Trim"
|
||||
<Browsable(True), GridVisible, XMLVN({"DefaultsTrim"}, TrimSeparateFolderNameDefault), Category("Defaults Trimming"), DisplayName("Separate folder name"),
|
||||
Description("Name of a separate folder")>
|
||||
Public ReadOnly Property TrimSeparateFolderName As XMLValue(Of String)
|
||||
#End Region
|
||||
#Region "Errors"
|
||||
<Browsable(True), GridVisible, XMLVN({"Errors"}, True), Category("ERRORS"), DisplayName("Ignore downloading errors"),
|
||||
Description("Ignore download errors if some files are missing (e.g. subtitles) and continue downloading")>
|
||||
Public ReadOnly Property ErrorsIgnore As XMLValue(Of Boolean)
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Public Sub New()
|
||||
@@ -514,6 +541,7 @@ Namespace API.YouTube.Base
|
||||
XML.LoadData(EDP.None)
|
||||
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
|
||||
DesignXml.LoadData(EDP.None)
|
||||
FILTER = New Controls.YTDataFilter
|
||||
InitializeXMLValueProperties(Me)
|
||||
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
|
||||
Cookies = New CookieKeeper
|
||||
|
||||
158
SCrawler.YouTube/Controls/ChaptersForm.Designer.vb
generated
Normal file
158
SCrawler.YouTube/Controls/ChaptersForm.Designer.vb
generated
Normal file
@@ -0,0 +1,158 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class ChaptersForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||
Me.BTT_ALL = New System.Windows.Forms.Button()
|
||||
Me.BTT_NONE = New System.Windows.Forms.Button()
|
||||
Me.BTT_INVERT = New System.Windows.Forms.Button()
|
||||
Me.LIST_CHAPTERS = New System.Windows.Forms.CheckedListBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_BUTTONS.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 361)
|
||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||
CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 361)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_MAIN.Controls.Add(TP_BUTTONS, 0, 1)
|
||||
TP_MAIN.Controls.Add(Me.LIST_CHAPTERS, 0, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 2
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(384, 361)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_BUTTONS
|
||||
'
|
||||
TP_BUTTONS.ColumnCount = 3
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_ALL, 0, 0)
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_NONE, 1, 0)
|
||||
TP_BUTTONS.Controls.Add(Me.BTT_INVERT, 2, 0)
|
||||
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_BUTTONS.Location = New System.Drawing.Point(0, 331)
|
||||
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.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_BUTTONS.Size = New System.Drawing.Size(384, 30)
|
||||
TP_BUTTONS.TabIndex = 1
|
||||
'
|
||||
'BTT_ALL
|
||||
'
|
||||
Me.BTT_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_ALL.Location = New System.Drawing.Point(3, 3)
|
||||
Me.BTT_ALL.Name = "BTT_ALL"
|
||||
Me.BTT_ALL.Size = New System.Drawing.Size(122, 24)
|
||||
Me.BTT_ALL.TabIndex = 0
|
||||
Me.BTT_ALL.Text = "All"
|
||||
Me.BTT_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_NONE
|
||||
'
|
||||
Me.BTT_NONE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_NONE.Location = New System.Drawing.Point(131, 3)
|
||||
Me.BTT_NONE.Name = "BTT_NONE"
|
||||
Me.BTT_NONE.Size = New System.Drawing.Size(122, 24)
|
||||
Me.BTT_NONE.TabIndex = 1
|
||||
Me.BTT_NONE.Text = "None"
|
||||
Me.BTT_NONE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_INVERT
|
||||
'
|
||||
Me.BTT_INVERT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_INVERT.Location = New System.Drawing.Point(259, 3)
|
||||
Me.BTT_INVERT.Name = "BTT_INVERT"
|
||||
Me.BTT_INVERT.Size = New System.Drawing.Size(122, 24)
|
||||
Me.BTT_INVERT.TabIndex = 2
|
||||
Me.BTT_INVERT.Text = "Invert"
|
||||
Me.BTT_INVERT.UseVisualStyleBackColor = True
|
||||
'
|
||||
'LIST_CHAPTERS
|
||||
'
|
||||
Me.LIST_CHAPTERS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LIST_CHAPTERS.FormattingEnabled = True
|
||||
Me.LIST_CHAPTERS.Location = New System.Drawing.Point(3, 3)
|
||||
Me.LIST_CHAPTERS.Name = "LIST_CHAPTERS"
|
||||
Me.LIST_CHAPTERS.Size = New System.Drawing.Size(378, 325)
|
||||
Me.LIST_CHAPTERS.TabIndex = 0
|
||||
'
|
||||
'ChaptersForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(384, 361)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.KeyPreview = True
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(400, 400)
|
||||
Me.Name = "ChaptersForm"
|
||||
Me.ShowIcon = False
|
||||
Me.ShowInTaskbar = False
|
||||
Me.Text = "Chapters"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_BUTTONS.ResumeLayout(False)
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
|
||||
Private WithEvents BTT_ALL As Button
|
||||
Private WithEvents BTT_NONE As Button
|
||||
Private WithEvents BTT_INVERT As Button
|
||||
Private WithEvents LIST_CHAPTERS As CheckedListBox
|
||||
End Class
|
||||
End Namespace
|
||||
129
SCrawler.YouTube/Controls/ChaptersForm.resx
Normal file
129
SCrawler.YouTube/Controls/ChaptersForm.resx
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
66
SCrawler.YouTube/Controls/ChaptersForm.vb
Normal file
66
SCrawler.YouTube/Controls/ChaptersForm.vb
Normal file
@@ -0,0 +1,66 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API.YouTube.Base
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class ChaptersForm
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Private ReadOnly Property MyData As YouTubeMediaContainerBase
|
||||
Private ReadOnly Property MyDataSelected As List(Of TrimOption)
|
||||
Friend ReadOnly Property MyResult As List(Of TrimOption)
|
||||
Friend Sub New(ByRef data As YouTubeMediaContainerBase, ByVal selected As IEnumerable(Of TrimOption))
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me, MyYouTubeSettings.DesignXml)
|
||||
MyData = data
|
||||
MyDataSelected = New List(Of TrimOption)
|
||||
MyDataSelected.ListAddList(selected)
|
||||
MyResult = New List(Of TrimOption)
|
||||
End Sub
|
||||
Private Sub ChaptersForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar()
|
||||
|
||||
With LIST_CHAPTERS
|
||||
.BeginUpdate()
|
||||
.Items.AddRange(MyData.Chapters.Cast(Of Object).ToArray)
|
||||
If MyDataSelected.Count > 0 Then
|
||||
For i% = 0 To .Items.Count - 1 : .SetItemChecked(i, MyDataSelected.Contains(MyData.Chapters(i))) : Next
|
||||
End If
|
||||
.EndUpdate()
|
||||
End With
|
||||
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub ChaptersForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
MyResult.Clear()
|
||||
MyDataSelected.Clear()
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
With LIST_CHAPTERS
|
||||
For i% = 0 To .Items.Count - 1
|
||||
If .GetItemChecked(i) Then MyResult.Add(MyData.Chapters(i))
|
||||
Next
|
||||
End With
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
Private Sub BTT_ALL_NONE_INVERT_Click(sender As Object, e As EventArgs) Handles BTT_ALL.Click, BTT_NONE.Click, BTT_INVERT.Click
|
||||
Dim v As Boolean = sender Is BTT_ALL
|
||||
Dim isInvert As Boolean = sender Is BTT_INVERT
|
||||
With LIST_CHAPTERS
|
||||
.BeginUpdate()
|
||||
For i% = 0 To .Items.Count - 1 : .SetItemChecked(i, If(isInvert, Not .GetItemChecked(i), v)) : Next
|
||||
.EndUpdate()
|
||||
End With
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
324
SCrawler.YouTube/Controls/FilterForm.Designer.vb
generated
Normal file
324
SCrawler.YouTube/Controls/FilterForm.Designer.vb
generated
Normal file
@@ -0,0 +1,324 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class FilterForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_TYPES As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_USERS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_USERS_2 As System.Windows.Forms.TableLayoutPanel
|
||||
Me.CH_FILTER_ALL = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FILTER_SINGLE = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FILTER_CHANNEL = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_FILTER_PLS = New System.Windows.Forms.CheckBox()
|
||||
Me.TP_MUSIC = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.CH_M_ALL = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_M_VIDEO = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_M_MUSIC = New System.Windows.Forms.CheckBox()
|
||||
Me.LIST_USERS = New System.Windows.Forms.CheckedListBox()
|
||||
Me.CH_USERS_USE = New System.Windows.Forms.CheckBox()
|
||||
Me.BTT_SELECT_ALL = New System.Windows.Forms.Button()
|
||||
Me.BTT_SELECT_NONE = New System.Windows.Forms.Button()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_TYPES = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_USERS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_USERS_2 = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_TYPES.SuspendLayout()
|
||||
Me.TP_MUSIC.SuspendLayout()
|
||||
TP_USERS.SuspendLayout()
|
||||
TP_USERS_2.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 361)
|
||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||
CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 361)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Controls.Add(TP_TYPES, 0, 0)
|
||||
TP_MAIN.Controls.Add(Me.TP_MUSIC, 0, 1)
|
||||
TP_MAIN.Controls.Add(TP_USERS, 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, 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.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(384, 361)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_TYPES
|
||||
'
|
||||
TP_TYPES.ColumnCount = 4
|
||||
TP_TYPES.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_TYPES.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_TYPES.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_TYPES.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25.0!))
|
||||
TP_TYPES.Controls.Add(Me.CH_FILTER_ALL, 0, 0)
|
||||
TP_TYPES.Controls.Add(Me.CH_FILTER_SINGLE, 1, 0)
|
||||
TP_TYPES.Controls.Add(Me.CH_FILTER_CHANNEL, 2, 0)
|
||||
TP_TYPES.Controls.Add(Me.CH_FILTER_PLS, 3, 0)
|
||||
TP_TYPES.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_TYPES.Location = New System.Drawing.Point(0, 0)
|
||||
TP_TYPES.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_TYPES.Name = "TP_TYPES"
|
||||
TP_TYPES.RowCount = 1
|
||||
TP_TYPES.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_TYPES.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_TYPES.Size = New System.Drawing.Size(384, 25)
|
||||
TP_TYPES.TabIndex = 0
|
||||
'
|
||||
'CH_FILTER_ALL
|
||||
'
|
||||
Me.CH_FILTER_ALL.AutoSize = True
|
||||
Me.CH_FILTER_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FILTER_ALL.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_FILTER_ALL.Name = "CH_FILTER_ALL"
|
||||
Me.CH_FILTER_ALL.Size = New System.Drawing.Size(90, 19)
|
||||
Me.CH_FILTER_ALL.TabIndex = 0
|
||||
Me.CH_FILTER_ALL.Text = "ALL"
|
||||
Me.CH_FILTER_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_FILTER_SINGLE
|
||||
'
|
||||
Me.CH_FILTER_SINGLE.AutoSize = True
|
||||
Me.CH_FILTER_SINGLE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FILTER_SINGLE.Location = New System.Drawing.Point(99, 3)
|
||||
Me.CH_FILTER_SINGLE.Name = "CH_FILTER_SINGLE"
|
||||
Me.CH_FILTER_SINGLE.Size = New System.Drawing.Size(90, 19)
|
||||
Me.CH_FILTER_SINGLE.TabIndex = 1
|
||||
Me.CH_FILTER_SINGLE.Text = "Single"
|
||||
Me.CH_FILTER_SINGLE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_FILTER_CHANNEL
|
||||
'
|
||||
Me.CH_FILTER_CHANNEL.AutoSize = True
|
||||
Me.CH_FILTER_CHANNEL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FILTER_CHANNEL.Location = New System.Drawing.Point(195, 3)
|
||||
Me.CH_FILTER_CHANNEL.Name = "CH_FILTER_CHANNEL"
|
||||
Me.CH_FILTER_CHANNEL.Size = New System.Drawing.Size(90, 19)
|
||||
Me.CH_FILTER_CHANNEL.TabIndex = 2
|
||||
Me.CH_FILTER_CHANNEL.Text = "Channel"
|
||||
Me.CH_FILTER_CHANNEL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_FILTER_PLS
|
||||
'
|
||||
Me.CH_FILTER_PLS.AutoSize = True
|
||||
Me.CH_FILTER_PLS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_FILTER_PLS.Location = New System.Drawing.Point(291, 3)
|
||||
Me.CH_FILTER_PLS.Name = "CH_FILTER_PLS"
|
||||
Me.CH_FILTER_PLS.Size = New System.Drawing.Size(90, 19)
|
||||
Me.CH_FILTER_PLS.TabIndex = 3
|
||||
Me.CH_FILTER_PLS.Text = "Playlist"
|
||||
Me.CH_FILTER_PLS.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_MUSIC
|
||||
'
|
||||
Me.TP_MUSIC.ColumnCount = 3
|
||||
Me.TP_MUSIC.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
Me.TP_MUSIC.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
Me.TP_MUSIC.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
Me.TP_MUSIC.Controls.Add(Me.CH_M_ALL, 0, 0)
|
||||
Me.TP_MUSIC.Controls.Add(Me.CH_M_VIDEO, 1, 0)
|
||||
Me.TP_MUSIC.Controls.Add(Me.CH_M_MUSIC, 2, 0)
|
||||
Me.TP_MUSIC.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_MUSIC.Location = New System.Drawing.Point(0, 25)
|
||||
Me.TP_MUSIC.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_MUSIC.Name = "TP_MUSIC"
|
||||
Me.TP_MUSIC.RowCount = 1
|
||||
Me.TP_MUSIC.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MUSIC.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
Me.TP_MUSIC.Size = New System.Drawing.Size(384, 25)
|
||||
Me.TP_MUSIC.TabIndex = 1
|
||||
'
|
||||
'CH_M_ALL
|
||||
'
|
||||
Me.CH_M_ALL.AutoSize = True
|
||||
Me.CH_M_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_M_ALL.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_M_ALL.Name = "CH_M_ALL"
|
||||
Me.CH_M_ALL.Size = New System.Drawing.Size(122, 19)
|
||||
Me.CH_M_ALL.TabIndex = 0
|
||||
Me.CH_M_ALL.Text = "ALL"
|
||||
Me.CH_M_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_M_VIDEO
|
||||
'
|
||||
Me.CH_M_VIDEO.AutoSize = True
|
||||
Me.CH_M_VIDEO.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_M_VIDEO.Location = New System.Drawing.Point(131, 3)
|
||||
Me.CH_M_VIDEO.Name = "CH_M_VIDEO"
|
||||
Me.CH_M_VIDEO.Size = New System.Drawing.Size(122, 19)
|
||||
Me.CH_M_VIDEO.TabIndex = 1
|
||||
Me.CH_M_VIDEO.Text = "Video"
|
||||
Me.CH_M_VIDEO.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_M_MUSIC
|
||||
'
|
||||
Me.CH_M_MUSIC.AutoSize = True
|
||||
Me.CH_M_MUSIC.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_M_MUSIC.Location = New System.Drawing.Point(259, 3)
|
||||
Me.CH_M_MUSIC.Name = "CH_M_MUSIC"
|
||||
Me.CH_M_MUSIC.Size = New System.Drawing.Size(122, 19)
|
||||
Me.CH_M_MUSIC.TabIndex = 2
|
||||
Me.CH_M_MUSIC.Text = "Music"
|
||||
Me.CH_M_MUSIC.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_USERS
|
||||
'
|
||||
TP_USERS.ColumnCount = 1
|
||||
TP_USERS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_USERS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_USERS.Controls.Add(Me.LIST_USERS, 0, 1)
|
||||
TP_USERS.Controls.Add(TP_USERS_2, 0, 0)
|
||||
TP_USERS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_USERS.Location = New System.Drawing.Point(0, 50)
|
||||
TP_USERS.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_USERS.Name = "TP_USERS"
|
||||
TP_USERS.RowCount = 2
|
||||
TP_USERS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_USERS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_USERS.Size = New System.Drawing.Size(384, 311)
|
||||
TP_USERS.TabIndex = 3
|
||||
'
|
||||
'LIST_USERS
|
||||
'
|
||||
Me.LIST_USERS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LIST_USERS.FormattingEnabled = True
|
||||
Me.LIST_USERS.Location = New System.Drawing.Point(3, 28)
|
||||
Me.LIST_USERS.Name = "LIST_USERS"
|
||||
Me.LIST_USERS.Size = New System.Drawing.Size(378, 280)
|
||||
Me.LIST_USERS.TabIndex = 1
|
||||
'
|
||||
'TP_USERS_2
|
||||
'
|
||||
TP_USERS_2.ColumnCount = 3
|
||||
TP_USERS_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_USERS_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_USERS_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_USERS_2.Controls.Add(Me.CH_USERS_USE, 0, 0)
|
||||
TP_USERS_2.Controls.Add(Me.BTT_SELECT_ALL, 1, 0)
|
||||
TP_USERS_2.Controls.Add(Me.BTT_SELECT_NONE, 2, 0)
|
||||
TP_USERS_2.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_USERS_2.Location = New System.Drawing.Point(0, 0)
|
||||
TP_USERS_2.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_USERS_2.Name = "TP_USERS_2"
|
||||
TP_USERS_2.RowCount = 1
|
||||
TP_USERS_2.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_USERS_2.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_USERS_2.Size = New System.Drawing.Size(384, 25)
|
||||
TP_USERS_2.TabIndex = 0
|
||||
'
|
||||
'CH_USERS_USE
|
||||
'
|
||||
Me.CH_USERS_USE.AutoSize = True
|
||||
Me.CH_USERS_USE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_USERS_USE.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_USERS_USE.Name = "CH_USERS_USE"
|
||||
Me.CH_USERS_USE.Size = New System.Drawing.Size(122, 19)
|
||||
Me.CH_USERS_USE.TabIndex = 0
|
||||
Me.CH_USERS_USE.Text = "Filter users"
|
||||
Me.CH_USERS_USE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_SELECT_ALL
|
||||
'
|
||||
Me.BTT_SELECT_ALL.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_SELECT_ALL.Location = New System.Drawing.Point(129, 1)
|
||||
Me.BTT_SELECT_ALL.Margin = New System.Windows.Forms.Padding(1)
|
||||
Me.BTT_SELECT_ALL.Name = "BTT_SELECT_ALL"
|
||||
Me.BTT_SELECT_ALL.Size = New System.Drawing.Size(126, 23)
|
||||
Me.BTT_SELECT_ALL.TabIndex = 1
|
||||
Me.BTT_SELECT_ALL.Text = "All"
|
||||
Me.BTT_SELECT_ALL.UseVisualStyleBackColor = True
|
||||
'
|
||||
'BTT_SELECT_NONE
|
||||
'
|
||||
Me.BTT_SELECT_NONE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_SELECT_NONE.Location = New System.Drawing.Point(257, 1)
|
||||
Me.BTT_SELECT_NONE.Margin = New System.Windows.Forms.Padding(1)
|
||||
Me.BTT_SELECT_NONE.Name = "BTT_SELECT_NONE"
|
||||
Me.BTT_SELECT_NONE.Size = New System.Drawing.Size(126, 23)
|
||||
Me.BTT_SELECT_NONE.TabIndex = 2
|
||||
Me.BTT_SELECT_NONE.Text = "None"
|
||||
Me.BTT_SELECT_NONE.UseVisualStyleBackColor = True
|
||||
'
|
||||
'FilterForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(384, 361)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(400, 400)
|
||||
Me.Name = "FilterForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.Text = "Filter"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_TYPES.ResumeLayout(False)
|
||||
TP_TYPES.PerformLayout()
|
||||
Me.TP_MUSIC.ResumeLayout(False)
|
||||
Me.TP_MUSIC.PerformLayout()
|
||||
TP_USERS.ResumeLayout(False)
|
||||
TP_USERS_2.ResumeLayout(False)
|
||||
TP_USERS_2.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
|
||||
Private WithEvents CH_FILTER_ALL As CheckBox
|
||||
Private WithEvents CH_FILTER_SINGLE As CheckBox
|
||||
Private WithEvents CH_FILTER_CHANNEL As CheckBox
|
||||
Private WithEvents CH_FILTER_PLS As CheckBox
|
||||
Private WithEvents TP_MUSIC As TableLayoutPanel
|
||||
Private WithEvents CH_M_ALL As CheckBox
|
||||
Private WithEvents CH_M_VIDEO As CheckBox
|
||||
Private WithEvents CH_M_MUSIC As CheckBox
|
||||
Private WithEvents LIST_USERS As CheckedListBox
|
||||
Private WithEvents CH_USERS_USE As CheckBox
|
||||
Private WithEvents BTT_SELECT_ALL As Button
|
||||
Private WithEvents BTT_SELECT_NONE As Button
|
||||
End Class
|
||||
End Namespace
|
||||
135
SCrawler.YouTube/Controls/FilterForm.resx
Normal file
135
SCrawler.YouTube/Controls/FilterForm.resx
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_TYPES.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_USERS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_USERS_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
181
SCrawler.YouTube/Controls/FilterForm.vb
Normal file
181
SCrawler.YouTube/Controls/FilterForm.vb
Normal file
@@ -0,0 +1,181 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.YouTube.Base
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports SimpleUser = SCrawler.API.YouTube.Controls.YTDataFilter.SimpleUser
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class FilterForm
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Friend ReadOnly Property DATA As List(Of IYouTubeMediaContainer)
|
||||
Private ReadOnly Property DataTMP As List(Of IYouTubeMediaContainer)
|
||||
Private ReadOnly Property MyFilterTmp As YTDataFilter
|
||||
Private ReadOnly Property MyTmpUsers As List(Of SimpleUser)
|
||||
Friend Sub New(ByVal d As IEnumerable(Of IYouTubeMediaContainer))
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me, MyYouTubeSettings.DesignXml)
|
||||
DATA = New List(Of IYouTubeMediaContainer)
|
||||
DATA.ListAddList(d)
|
||||
DataTMP = New List(Of IYouTubeMediaContainer)
|
||||
DataTMP.ListAddList(d)
|
||||
MyFilterTmp = New YTDataFilter(MyYouTubeSettings.FILTER)
|
||||
MyTmpUsers = New List(Of SimpleUser)
|
||||
Icon = My.Resources.FilterIcon
|
||||
End Sub
|
||||
Private Sub FilterForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
Try
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar(True)
|
||||
|
||||
With MyYouTubeSettings.FILTER
|
||||
With .Types
|
||||
If .Count = 0 Or (.Count = 1 AndAlso .Item(0) = YouTubeMediaType.Undefined) Then
|
||||
CH_FILTER_ALL.Checked = True
|
||||
Else
|
||||
If .Contains(YouTubeMediaType.Single) Then CH_FILTER_SINGLE.Checked = True
|
||||
If .Contains(YouTubeMediaType.Channel) Then CH_FILTER_CHANNEL.Checked = True
|
||||
If .Contains(YouTubeMediaType.PlayList) Then CH_FILTER_PLS.Checked = True
|
||||
End If
|
||||
End With
|
||||
If .IsMusic And .IsVideo Then
|
||||
CH_M_ALL.Checked = True
|
||||
Else
|
||||
CH_M_MUSIC.Checked = .IsMusic
|
||||
CH_M_VIDEO.Checked = .IsVideo
|
||||
End If
|
||||
|
||||
CH_USERS_USE.Checked = .UserList.Count > 0
|
||||
End With
|
||||
|
||||
.EndLoaderOperations()
|
||||
_RefillEnabled = True
|
||||
RefillList(True)
|
||||
CH_USERS_USE_CheckedChanged()
|
||||
End With
|
||||
Catch ex As Exception
|
||||
MyDefs.InvokeLoaderError(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub FilterForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
DATA.ListClearDispose
|
||||
DataTMP.ListClearDispose
|
||||
MyTmpUsers.ListClearDispose
|
||||
End Sub
|
||||
Private _RefillEnabled As Boolean = False
|
||||
Private Sub RefillList(Optional ByVal Init As Boolean = False)
|
||||
If Not MyDefs.Initializing And _RefillEnabled Then
|
||||
ApplyFilter(MyFilterTmp, Init)
|
||||
MyFilterTmp.Populate(DATA, DataTMP, CH_USERS_USE.Checked)
|
||||
With DataTMP
|
||||
If .Count > 0 Then
|
||||
Dim tmpUsers As New List(Of SimpleUser)
|
||||
tmpUsers.ListAddList(DataTMP, LAP.NotContainsOnly, CType(Function(obj As YouTubeMediaContainerBase) CType(obj, SimpleUser), Func(Of Object, Object)))
|
||||
If tmpUsers.Count > 0 Then
|
||||
tmpUsers.Sort()
|
||||
LIST_USERS.BeginUpdate()
|
||||
LIST_USERS.Items.Clear()
|
||||
tmpUsers.ForEach(Sub(u) LIST_USERS.Items.Add(u, True))
|
||||
|
||||
If CH_USERS_USE.Checked And MyFilterTmp.UserList.Count > 0 Then
|
||||
For i% = 0 To LIST_USERS.Items.Count - 1
|
||||
LIST_USERS.SetItemChecked(i, MyFilterTmp.UserList.Contains(LIST_USERS.Items(i)))
|
||||
Next
|
||||
End If
|
||||
|
||||
LIST_USERS.EndUpdate()
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
Private Sub ApplyFilter(ByRef Filter As YTDataFilter, ByVal Init As Boolean)
|
||||
With Filter
|
||||
.Reset(False, Not Init)
|
||||
With .Types
|
||||
If CH_FILTER_ALL.Checked Then
|
||||
.Add(YouTubeMediaType.Undefined)
|
||||
Else
|
||||
If CH_FILTER_SINGLE.Checked Then .Add(YouTubeMediaType.Single)
|
||||
If CH_FILTER_CHANNEL.Checked Then .Add(YouTubeMediaType.Channel)
|
||||
If CH_FILTER_PLS.Checked Then .Add(YouTubeMediaType.PlayList)
|
||||
End If
|
||||
If .Count = 0 Then .Add(YouTubeMediaType.Undefined)
|
||||
End With
|
||||
If CH_M_ALL.Checked Then
|
||||
.IsMusic = True
|
||||
.IsVideo = True
|
||||
Else
|
||||
If CH_M_MUSIC.Checked Then .IsMusic = True
|
||||
If CH_M_VIDEO.Checked Then .IsVideo = True
|
||||
End If
|
||||
If Not .IsVideo And Not .IsMusic Then .IsMusic = True : .IsVideo = True
|
||||
|
||||
If CH_USERS_USE.Checked And Not Init Then
|
||||
.UserList.Clear()
|
||||
If LIST_USERS.CheckedItems.Count > 0 Then
|
||||
For Each item In LIST_USERS.CheckedItems : .UserList.Add(item) : Next
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
ApplyFilter(MyYouTubeSettings.FILTER, False)
|
||||
MyYouTubeSettings.FILTER.RemoveAll(DATA)
|
||||
MyYouTubeSettings.FILTER.Update()
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonDeleteClickOC(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonDeleteClickOC
|
||||
With MyYouTubeSettings.FILTER : .Reset() : .Update() : End With
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
Private Sub UpdateControlOptions(ByRef CNT As CheckBox, ByVal v As Boolean)
|
||||
If v Then CNT.Checked = True
|
||||
CNT.Enabled = Not v
|
||||
End Sub
|
||||
Private Sub CH_FILTER_ALL_CheckedChanged(sender As Object, e As EventArgs) Handles CH_FILTER_ALL.CheckedChanged
|
||||
_RefillEnabled = False
|
||||
Dim v As Boolean = CH_FILTER_ALL.Checked
|
||||
UpdateControlOptions(CH_FILTER_SINGLE, v)
|
||||
UpdateControlOptions(CH_FILTER_CHANNEL, v)
|
||||
UpdateControlOptions(CH_FILTER_PLS, v)
|
||||
_RefillEnabled = True
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub CH_FILTER_SINGLE_CHANNEL_PLS_CheckedChanged(sender As Object, e As EventArgs) Handles CH_FILTER_SINGLE.CheckedChanged,
|
||||
CH_FILTER_CHANNEL.CheckedChanged,
|
||||
CH_FILTER_PLS.CheckedChanged
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub CH_M_ALL_CheckedChanged(sender As Object, e As EventArgs) Handles CH_M_ALL.CheckedChanged
|
||||
_RefillEnabled = False
|
||||
Dim v As Boolean = CH_M_ALL.Checked
|
||||
UpdateControlOptions(CH_M_VIDEO, v)
|
||||
UpdateControlOptions(CH_M_MUSIC, v)
|
||||
_RefillEnabled = True
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub CH_M_VIDEO_MUSIC_CheckedChanged(sender As Object, e As EventArgs) Handles CH_M_VIDEO.CheckedChanged, CH_M_MUSIC.CheckedChanged
|
||||
RefillList()
|
||||
End Sub
|
||||
Private Sub CH_USERS_USE_CheckedChanged() Handles CH_USERS_USE.CheckedChanged
|
||||
LIST_USERS.Enabled = CH_USERS_USE.Checked
|
||||
BTT_SELECT_ALL.Enabled = CH_USERS_USE.Checked
|
||||
BTT_SELECT_NONE.Enabled = CH_USERS_USE.Checked
|
||||
End Sub
|
||||
Private Sub BTT_SELECT_ALL_NONE_Click(sender As Object, e As EventArgs) Handles BTT_SELECT_ALL.Click, BTT_SELECT_NONE.Click
|
||||
Dim checked As Boolean = sender Is BTT_SELECT_ALL
|
||||
With LIST_USERS
|
||||
If .Items.Count > 0 Then
|
||||
For i% = 0 To .Items.Count - 1 : .SetItemChecked(i, checked) : Next
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -155,7 +155,7 @@ Namespace API.YouTube.Controls
|
||||
With DirectCast(MyContainer, YouTubeMediaContainerBase)
|
||||
Select Case Sender.DefaultButton
|
||||
Case ADB.Open
|
||||
Using f As New SimpleListForm(Of String)(IIf(isLyrics, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
|
||||
Using f As New SimpleListForm(Of String)(If(isLyrics, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
|
||||
.DesignXML = DesignXML,
|
||||
.DesignXMLNodeName = SimpleArraysFormNode,
|
||||
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
|
||||
|
||||
274
SCrawler.YouTube/Controls/TrimOptionForm.Designer.vb
generated
Normal file
274
SCrawler.YouTube/Controls/TrimOptionForm.Designer.vb
generated
Normal file
@@ -0,0 +1,274 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class TrimOptionForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(TrimOptionForm))
|
||||
Dim TP_OPTIONS As System.Windows.Forms.TableLayoutPanel
|
||||
Me.TXT_NAME = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TP_TIME_TIME = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.TXT_FROM_DATE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_TO_DATE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.OPT_INT = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_TIME = New System.Windows.Forms.RadioButton()
|
||||
Me.TP_TIME_INT = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.TXT_FROM_INT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_TO_INT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_OPTIONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
CType(Me.TXT_NAME, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_OPTIONS.SuspendLayout()
|
||||
Me.TP_TIME_TIME.SuspendLayout()
|
||||
CType(Me.TXT_FROM_DATE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_TO_DATE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.TP_TIME_INT.SuspendLayout()
|
||||
CType(Me.TXT_FROM_INT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_TO_INT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(334, 112)
|
||||
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(334, 112)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
TP_MAIN.ColumnCount = 1
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
TP_MAIN.Controls.Add(Me.TXT_NAME, 0, 0)
|
||||
TP_MAIN.Controls.Add(TP_OPTIONS, 0, 1)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 2
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(334, 112)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TXT_NAME
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Name = "Clear"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_NAME.Buttons.Add(ActionButton1)
|
||||
Me.TXT_NAME.CaptionText = "Name"
|
||||
Me.TXT_NAME.CaptionToolTipText = "Section name"
|
||||
Me.TXT_NAME.CaptionWidth = 50.0R
|
||||
Me.TXT_NAME.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_NAME.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_NAME.Name = "TXT_NAME"
|
||||
Me.TXT_NAME.Size = New System.Drawing.Size(328, 22)
|
||||
Me.TXT_NAME.TabIndex = 0
|
||||
'
|
||||
'TP_OPTIONS
|
||||
'
|
||||
TP_OPTIONS.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
TP_OPTIONS.ColumnCount = 2
|
||||
TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 30.0!))
|
||||
TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_OPTIONS.Controls.Add(Me.TP_TIME_TIME, 1, 1)
|
||||
TP_OPTIONS.Controls.Add(Me.OPT_INT, 0, 0)
|
||||
TP_OPTIONS.Controls.Add(Me.OPT_TIME, 0, 1)
|
||||
TP_OPTIONS.Controls.Add(Me.TP_TIME_INT, 1, 0)
|
||||
TP_OPTIONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_OPTIONS.Location = New System.Drawing.Point(3, 31)
|
||||
TP_OPTIONS.Name = "TP_OPTIONS"
|
||||
TP_OPTIONS.RowCount = 3
|
||||
TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_OPTIONS.Size = New System.Drawing.Size(328, 78)
|
||||
TP_OPTIONS.TabIndex = 1
|
||||
'
|
||||
'TP_TIME_TIME
|
||||
'
|
||||
Me.TP_TIME_TIME.ColumnCount = 2
|
||||
Me.TP_TIME_TIME.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
Me.TP_TIME_TIME.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
Me.TP_TIME_TIME.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
Me.TP_TIME_TIME.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
Me.TP_TIME_TIME.Controls.Add(Me.TXT_FROM_DATE, 0, 0)
|
||||
Me.TP_TIME_TIME.Controls.Add(Me.TXT_TO_DATE, 1, 0)
|
||||
Me.TP_TIME_TIME.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_TIME_TIME.Location = New System.Drawing.Point(32, 27)
|
||||
Me.TP_TIME_TIME.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_TIME_TIME.Name = "TP_TIME_TIME"
|
||||
Me.TP_TIME_TIME.RowCount = 1
|
||||
Me.TP_TIME_TIME.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_TIME_TIME.Size = New System.Drawing.Size(295, 25)
|
||||
Me.TP_TIME_TIME.TabIndex = 3
|
||||
'
|
||||
'TXT_FROM_DATE
|
||||
'
|
||||
Me.TXT_FROM_DATE.CaptionPadding = New System.Windows.Forms.Padding(0, 0, 6, 0)
|
||||
Me.TXT_FROM_DATE.CaptionText = "From"
|
||||
Me.TXT_FROM_DATE.CaptionWidth = 40.0R
|
||||
Me.TXT_FROM_DATE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_FROM_DATE.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_FROM_DATE.Name = "TXT_FROM_DATE"
|
||||
Me.TXT_FROM_DATE.PlaceholderEnabled = True
|
||||
Me.TXT_FROM_DATE.PlaceholderText = "h:mm:ss"
|
||||
Me.TXT_FROM_DATE.Size = New System.Drawing.Size(141, 22)
|
||||
Me.TXT_FROM_DATE.TabIndex = 0
|
||||
'
|
||||
'TXT_TO_DATE
|
||||
'
|
||||
Me.TXT_TO_DATE.CaptionPadding = New System.Windows.Forms.Padding(0, 0, 6, 0)
|
||||
Me.TXT_TO_DATE.CaptionText = "To"
|
||||
Me.TXT_TO_DATE.CaptionWidth = 40.0R
|
||||
Me.TXT_TO_DATE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_TO_DATE.Location = New System.Drawing.Point(150, 3)
|
||||
Me.TXT_TO_DATE.Name = "TXT_TO_DATE"
|
||||
Me.TXT_TO_DATE.PlaceholderEnabled = True
|
||||
Me.TXT_TO_DATE.PlaceholderText = "h:mm:ss"
|
||||
Me.TXT_TO_DATE.Size = New System.Drawing.Size(142, 22)
|
||||
Me.TXT_TO_DATE.TabIndex = 1
|
||||
'
|
||||
'OPT_INT
|
||||
'
|
||||
Me.OPT_INT.AutoSize = True
|
||||
Me.OPT_INT.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||
Me.OPT_INT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_INT.Location = New System.Drawing.Point(4, 4)
|
||||
Me.OPT_INT.Name = "OPT_INT"
|
||||
Me.OPT_INT.Size = New System.Drawing.Size(24, 19)
|
||||
Me.OPT_INT.TabIndex = 0
|
||||
Me.OPT_INT.TabStop = True
|
||||
Me.OPT_INT.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OPT_TIME
|
||||
'
|
||||
Me.OPT_TIME.AutoSize = True
|
||||
Me.OPT_TIME.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
|
||||
Me.OPT_TIME.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_TIME.Location = New System.Drawing.Point(4, 30)
|
||||
Me.OPT_TIME.Name = "OPT_TIME"
|
||||
Me.OPT_TIME.Size = New System.Drawing.Size(24, 19)
|
||||
Me.OPT_TIME.TabIndex = 1
|
||||
Me.OPT_TIME.TabStop = True
|
||||
Me.OPT_TIME.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_TIME_INT
|
||||
'
|
||||
Me.TP_TIME_INT.ColumnCount = 2
|
||||
Me.TP_TIME_INT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
Me.TP_TIME_INT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
Me.TP_TIME_INT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
Me.TP_TIME_INT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
|
||||
Me.TP_TIME_INT.Controls.Add(Me.TXT_FROM_INT, 0, 0)
|
||||
Me.TP_TIME_INT.Controls.Add(Me.TXT_TO_INT, 1, 0)
|
||||
Me.TP_TIME_INT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_TIME_INT.Location = New System.Drawing.Point(32, 1)
|
||||
Me.TP_TIME_INT.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_TIME_INT.Name = "TP_TIME_INT"
|
||||
Me.TP_TIME_INT.RowCount = 1
|
||||
Me.TP_TIME_INT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_TIME_INT.Size = New System.Drawing.Size(295, 25)
|
||||
Me.TP_TIME_INT.TabIndex = 2
|
||||
'
|
||||
'TXT_FROM_INT
|
||||
'
|
||||
Me.TXT_FROM_INT.CaptionPadding = New System.Windows.Forms.Padding(0, 0, 6, 0)
|
||||
Me.TXT_FROM_INT.CaptionText = "From"
|
||||
Me.TXT_FROM_INT.CaptionWidth = 40.0R
|
||||
Me.TXT_FROM_INT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_FROM_INT.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_FROM_INT.Name = "TXT_FROM_INT"
|
||||
Me.TXT_FROM_INT.Size = New System.Drawing.Size(141, 22)
|
||||
Me.TXT_FROM_INT.TabIndex = 0
|
||||
'
|
||||
'TXT_TO_INT
|
||||
'
|
||||
Me.TXT_TO_INT.CaptionPadding = New System.Windows.Forms.Padding(0, 0, 6, 0)
|
||||
Me.TXT_TO_INT.CaptionText = "To"
|
||||
Me.TXT_TO_INT.CaptionWidth = 40.0R
|
||||
Me.TXT_TO_INT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_TO_INT.Location = New System.Drawing.Point(150, 3)
|
||||
Me.TXT_TO_INT.Name = "TXT_TO_INT"
|
||||
Me.TXT_TO_INT.Size = New System.Drawing.Size(142, 22)
|
||||
Me.TXT_TO_INT.TabIndex = 1
|
||||
'
|
||||
'TrimOptionForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(334, 112)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(350, 151)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(350, 151)
|
||||
Me.Name = "TrimOptionForm"
|
||||
Me.ShowIcon = False
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
Me.Text = "Trim option"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
CType(Me.TXT_NAME, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_OPTIONS.ResumeLayout(False)
|
||||
TP_OPTIONS.PerformLayout()
|
||||
Me.TP_TIME_TIME.ResumeLayout(False)
|
||||
CType(Me.TXT_FROM_DATE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_TO_DATE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.TP_TIME_INT.ResumeLayout(False)
|
||||
CType(Me.TXT_FROM_INT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_TO_INT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
|
||||
Private WithEvents TXT_NAME As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents OPT_INT As RadioButton
|
||||
Private WithEvents OPT_TIME As RadioButton
|
||||
Private WithEvents TP_TIME_INT As TableLayoutPanel
|
||||
Private WithEvents TP_TIME_TIME As TableLayoutPanel
|
||||
Private WithEvents TXT_FROM_DATE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_TO_DATE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_FROM_INT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents TXT_TO_INT As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
End Class
|
||||
End Namespace
|
||||
138
SCrawler.YouTube/Controls/TrimOptionForm.resx
Normal file
138
SCrawler.YouTube/Controls/TrimOptionForm.resx
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
vgAADr4B6kKxwAAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TP_OPTIONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
79
SCrawler.YouTube/Controls/TrimOptionForm.vb
Normal file
79
SCrawler.YouTube/Controls/TrimOptionForm.vb
Normal file
@@ -0,0 +1,79 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API.YouTube.Base
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class TrimOptionForm
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Friend Property MyTrimOption As TrimOption
|
||||
Private ReadOnly FieldsDateProvider As New CustomProvider(Function(v) AConvert(Of TimeSpan)(v, Nothing, EDP.ReturnValue))
|
||||
Private ReadOnly TCE As New ErrorsDescriber(False, False, False, New TimeSpan)
|
||||
Friend Sub New(Optional ByVal Opt As TrimOption = Nothing)
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me, MyYouTubeSettings.DesignXml)
|
||||
MyTrimOption = Opt
|
||||
End Sub
|
||||
Private Sub TrimOptionForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
Try
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar()
|
||||
|
||||
TXT_NAME.Text = MyTrimOption.Name
|
||||
TXT_FROM_INT.Text = MyTrimOption.Start
|
||||
TXT_TO_INT.Text = MyTrimOption.End
|
||||
|
||||
OPT_INT.Checked = True
|
||||
|
||||
.MyFieldsCheckerE = New FieldsChecker
|
||||
With .MyFieldsCheckerE
|
||||
.AddControl(Of Integer)(TXT_FROM_INT, "From")
|
||||
.AddControl(Of Integer)(TXT_TO_INT, "To")
|
||||
.AddControl(Of String)(TXT_FROM_DATE, "From (time)",, FieldsDateProvider)
|
||||
.AddControl(Of String)(TXT_TO_DATE, "To (time)",, FieldsDateProvider)
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
Catch ex As Exception
|
||||
MyDefs.InvokeLoaderError(ex)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
If MyDefs.MyFieldsChecker.AllParamsOK Then
|
||||
MyTrimOption = New TrimOption With {
|
||||
.Name = TXT_NAME.Text,
|
||||
.Start = AConvert(Of Integer)(TXT_FROM_INT.Text, 0),
|
||||
.[End] = AConvert(Of Integer)(TXT_TO_INT.Text, 0)
|
||||
}
|
||||
MyDefs.CloseForm()
|
||||
End If
|
||||
End Sub
|
||||
Private Sub OPT_INT_TIME_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_INT.CheckedChanged, OPT_TIME.CheckedChanged
|
||||
TP_TIME_INT.Enabled = OPT_INT.Checked
|
||||
TP_TIME_TIME.Enabled = OPT_TIME.Checked
|
||||
End Sub
|
||||
Private _TextHandlersEnabled As Boolean = True
|
||||
Private Sub TXT_FROM_TO_TextChanged(sender As Object, e As EventArgs) Handles TXT_FROM_INT.ActionOnTextChanged, TXT_TO_INT.ActionOnTextChanged,
|
||||
TXT_FROM_DATE.ActionOnTextChanged, TXT_TO_DATE.ActionOnTextChanged
|
||||
If _TextHandlersEnabled Then
|
||||
_TextHandlersEnabled = False
|
||||
Select Case DirectCast(sender, Control).Name
|
||||
Case TXT_FROM_INT.Name : TXT_FROM_DATE.Value = AConvert(Of String)(TimeSpan.FromSeconds(AConvert(Of Integer)(TXT_FROM_INT.Text, 0)), TimeToStringProviderH)
|
||||
Case TXT_TO_INT.Name : TXT_TO_DATE.Value = AConvert(Of String)(TimeSpan.FromSeconds(AConvert(Of Integer)(TXT_TO_INT.Text, 0)), TimeToStringProviderH)
|
||||
Case TXT_FROM_DATE.Name : TXT_FROM_INT.Text = CInt(CType(AConvert(Of TimeSpan)(TXT_FROM_DATE.Text, TCE), TimeSpan).TotalSeconds)
|
||||
Case TXT_TO_DATE.Name : TXT_TO_INT.Text = CInt(CType(AConvert(Of TimeSpan)(TXT_TO_DATE.Text, TCE), TimeSpan).TotalSeconds)
|
||||
End Select
|
||||
_TextHandlersEnabled = True
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -73,6 +73,7 @@ Namespace API.YouTube.Controls
|
||||
Me.OPT_VIDEO = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_AUDIO = New System.Windows.Forms.RadioButton()
|
||||
Me.LBL_AUDIO_CODEC = New System.Windows.Forms.Label()
|
||||
Me.BTT_TRIM = New System.Windows.Forms.Button()
|
||||
Me.TXT_FPS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_AUDIO_BITRATE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TP_HEADER_BASE = New System.Windows.Forms.TableLayoutPanel()
|
||||
@@ -545,20 +546,32 @@ Namespace API.YouTube.Controls
|
||||
Me.LBL_AUDIO_CODEC.TextAlign = System.Drawing.ContentAlignment.MiddleRight
|
||||
TT_MAIN.SetToolTip(Me.LBL_AUDIO_CODEC, "Output Audio Codec")
|
||||
'
|
||||
'BTT_TRIM
|
||||
'
|
||||
Me.BTT_TRIM.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.BTT_TRIM.Location = New System.Drawing.Point(541, 3)
|
||||
Me.BTT_TRIM.Name = "BTT_TRIM"
|
||||
Me.BTT_TRIM.Size = New System.Drawing.Size(45, 22)
|
||||
Me.BTT_TRIM.TabIndex = 2
|
||||
Me.BTT_TRIM.Text = "Trim"
|
||||
TT_MAIN.SetToolTip(Me.BTT_TRIM, "Trim the file by setting trimming options and/or selecting chapters")
|
||||
Me.BTT_TRIM.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_FPS_BITRATE
|
||||
'
|
||||
TP_FPS_BITRATE.ColumnCount = 2
|
||||
TP_FPS_BITRATE.ColumnCount = 3
|
||||
TP_FPS_BITRATE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_FPS_BITRATE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_FPS_BITRATE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 51.0!))
|
||||
TP_FPS_BITRATE.Controls.Add(Me.TXT_FPS, 0, 0)
|
||||
TP_FPS_BITRATE.Controls.Add(Me.TXT_AUDIO_BITRATE, 1, 0)
|
||||
TP_FPS_BITRATE.Controls.Add(Me.BTT_TRIM, 2, 0)
|
||||
TP_FPS_BITRATE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_FPS_BITRATE.Location = New System.Drawing.Point(6, 93)
|
||||
TP_FPS_BITRATE.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
|
||||
TP_FPS_BITRATE.Name = "TP_FPS_BITRATE"
|
||||
TP_FPS_BITRATE.RowCount = 1
|
||||
TP_FPS_BITRATE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_FPS_BITRATE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_FPS_BITRATE.Size = New System.Drawing.Size(589, 28)
|
||||
TP_FPS_BITRATE.TabIndex = 6
|
||||
'
|
||||
@@ -577,7 +590,7 @@ Namespace API.YouTube.Controls
|
||||
Me.TXT_FPS.Location = New System.Drawing.Point(3, 2)
|
||||
Me.TXT_FPS.Margin = New System.Windows.Forms.Padding(3, 2, 3, 3)
|
||||
Me.TXT_FPS.Name = "TXT_FPS"
|
||||
Me.TXT_FPS.Size = New System.Drawing.Size(288, 22)
|
||||
Me.TXT_FPS.Size = New System.Drawing.Size(263, 22)
|
||||
Me.TXT_FPS.TabIndex = 0
|
||||
Me.TXT_FPS.TextBoxWidthMinimal = 30
|
||||
'
|
||||
@@ -593,9 +606,9 @@ Namespace API.YouTube.Controls
|
||||
" to change."
|
||||
Me.TXT_AUDIO_BITRATE.CaptionWidth = 75.0R
|
||||
Me.TXT_AUDIO_BITRATE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_AUDIO_BITRATE.Location = New System.Drawing.Point(297, 3)
|
||||
Me.TXT_AUDIO_BITRATE.Location = New System.Drawing.Point(272, 3)
|
||||
Me.TXT_AUDIO_BITRATE.Name = "TXT_AUDIO_BITRATE"
|
||||
Me.TXT_AUDIO_BITRATE.Size = New System.Drawing.Size(289, 22)
|
||||
Me.TXT_AUDIO_BITRATE.Size = New System.Drawing.Size(263, 22)
|
||||
Me.TXT_AUDIO_BITRATE.TabIndex = 1
|
||||
'
|
||||
'TP_HEADER_BASE
|
||||
@@ -920,5 +933,6 @@ Namespace API.YouTube.Controls
|
||||
Private WithEvents CMB_PLS As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||
Private WithEvents BTT_PLS_BROWSE As SCrawler.API.YouTube.Controls.ButtonRC
|
||||
Private WithEvents TXT_AUDIO_BITRATE As PersonalUtilities.Forms.Controls.TextBoxExtended
|
||||
Private WithEvents BTT_TRIM As Button
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -139,98 +139,96 @@
|
||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAFFJREFUOE9joAr49u3bf1Lw169f50O1QgBI0MnJCY4/vP8Ix8hiILqtrQ3TEFIM
|
||||
AGGYIVDtpBsAwkQbgIyR1dDWAGLwqAGD0gByMFQ7JYCBAQChNviRiQ8ETwAAAABJRU5ErkJggg==
|
||||
vAAADrwBlbxySQAAAEhJREFUOE9jYKAG+Pbt239S8NevX+djGODk5ATHH95/hGNkMRDd1taGaQgpBiAb
|
||||
QrYBIEy0AdgMo70BxOBRAwalAeRguAGUAAChNviRcuLCdwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
AAAASUVORK5CYII=
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -248,115 +246,113 @@
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAFFJREFUOE9joAr49u3bf1Lw169f50O1QgBI0MnJCY4/vP8Ix8hiILqtrQ3TEFIM
|
||||
AGGYIVDtpBsAwkQbgIyR1dDWAGLwqAGD0gByMFQ7JYCBAQChNviRiQ8ETwAAAABJRU5ErkJggg==
|
||||
vAAADrwBlbxySQAAAEhJREFUOE9jYKAG+Pbt239S8NevX+djGODk5ATHH95/hGNkMRDd1taGaQgpBiAb
|
||||
QrYBIEy0AdgMo70BxOBRAwalAeRguAGUAAChNviRcuLCdwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeElE
|
||||
QVQ4T2P4//8/RRhMFHQfKgDi/yAaXQEhDCZAmkNbnvyXta4CciESLEws//FhmDqYAQUgzUBMngsowVgF
|
||||
ScFgYjQQsUsQi8FEYsXyAiD+D6LRFRDCYAKk2bPo6H9J40wgFyKBLeCQMUwdzIACkGYgHnKB+J8BAD5Q
|
||||
tqhi4tzWAAAAAElFTkSuQmCC
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAAAd0lE
|
||||
QVQ4T2P4//8/AyUYTBR0Hyoo6D70H0SjKyCEYQb8D2158l/Wuuo/TIKFieU/PoxuQAFIs6x1FXkuoARj
|
||||
CJCKwcRoIGIKkoLBRGLF8oLEiuX/QTS6AkIYZsB/z6Kj/yWNM8kLRJDNIM2SxpnkuYASjCFAKgYAPlC2
|
||||
qCS4LQgAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE65JREFUeF7t
|
||||
3X2sJWddB/DdLi2lQG2hdOHuvfM887J7Cxca4ELTQMDWKigIFpBAEAgi9g+CJpJo9Q8NJhgBiYZIYspL
|
||||
GlAKCkhEC4KgQlsLQkqhKi/lrYWWlxaw3dLddrerz/Q89+7dc2fbfTn3npf5fJJv2rS758z85nnOzJz5
|
||||
nZktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAE0xJREFUeF7t
|
||||
3X2MZWddB/BZSkspUFsoXZidOc/vnOfsTmGgARaaBgK2VkFBsIAEgkAQsX8QNJFEq39oMMEoSDREElOB
|
||||
EFAKCkhEAUGqQlsLQkoBlZfy1kJ5awH7QrvtbldzdndmZ597Snd37szce8/nk3xTQjsz5/zOefbO3vO9
|
||||
58zNAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMK3O3r79wVUIz65jfGNVxI/VIX69CvGO9M//a9P+e8o3B/8v
|
||||
vKn9s+3fyX8dAJgmaWd+fl3E96Wd/E9XdvZHkfbvXNa+Rn45AGCS3bvjj/E/h3box5OrmxjPyy8PAEyS
|
||||
XXO7zqhCeH/HDnwUOdCE+J6zdux4eH47YIrEGE8uy/Ls9Bnx/LooL0oH9b9Th/I1TVG+rCqKC+q6Xsh/
|
||||
FJgmO8vy6WknfdPQTnsjckMdwlPy2wITLO3wF6si/lGas1ekuXvX0Fzuyg9S3psOCl6qDwimQB3ji9Ok
|
||||
3btmEm907kpnEa/Mbw9Mlq1pB/6cdHZ/ZcfcPZrcXoXyrVVVFfl1gUmSdsS/libqPUMTd5NSvjktwrbB
|
||||
kgDjVi1UT26K+Nnu+XrMuaud60uPWHpIfhtg3JqyfEaanHcPTdZNTRPCPy4uLj40LxIwBudt2fKAtOP/
|
||||
0zQnN+5koIg3tpca81sC49J+LZcm5a3rJulYEq6LSV40YBOFEB6V5uFV6+flRiTsSwf9r81vDYzBCSO4
|
||||
vjfq/KAuiqfm5QM2QRPjuWnubUbz71DCn6W33zpYCmDT1EX5m92Tcuy5q47xFXkxgQ3UduqnOXfn0Bzc
|
||||
xJSvz4sCbIb2pzlp8v1w/WScnKSzkjekRT1hsMTAKC0vL5/Ydud3zb1NT1FelBcL2GiDm3d0TMTJy0ea
|
||||
pjk1LzYwAu3NvtLc+uTQXBtn7tYYCJtja/vQno5JOJFpQrzWb4hhNJoQnpjm1Q3D82wCcnNRFKfnxQQ2
|
||||
Qttk1zH5JjzhFmcIcHzyzb6O5aFem5J0sP/OvKjARmg7b7sm3xRkT3vDorwawJHb1t6Ep2NOTVoOtDch
|
||||
yssMjFr6IPh8x8SbnsT4lrQamgPhCMzPzz+sifHjnXNpMnN5XnRglJaWlk5KE2z/0ISbxnzQQ0bgvlXz
|
||||
1ePSXPnG0NyZ+DRF8Zi8CsCo7Azh0V0TbkrzRc2B0G3wIJ9429CcmZLce4MgYJTyff87JtzU5uayLM/J
|
||||
qwcM7vD5+jQ3DgzNlWnKDXldgFFJZwW/2jHZpj1727uZ5VWE3mofqJXmw4eG5sdUpqqqXXm1gFGoQnhJ
|
||||
12SbgRxoYvzjtIruK04vxRjPSvPgK0PzYmqTPqtemVcNGIU6xgu7JtusJH1ovH9ubu6UvLrQC2ncPyuN
|
||||
/58Mz4fpTvnmvHrAKJQL5dO6J9ssJXxucWFhLq8yzLKtaUf5h2ncb9zz+8eUKsYP53UERmHX/PyOrsk2
|
||||
g7nJDUWYZUuPWHpIE8oPdIz92UiMn86rCoxIOmOYta8KD5uftk2Peb1hZtTzdVOHcF3HmJ+ZVCF+Ia8u
|
||||
MCppcl0+PNlmOG1zYPtYYc2BzIQ0np+ZxvWPh8b5LObqvMrAqEzRo4BHmctijCfnEsBUqkP5u2ksz8Kd
|
||||
PI8g5SfyagOj0jbIpQk2c01DR5Brmh3NfC4DTI324LWO8V0dY3pm48mAsEGm7OEgo0sRb9wZ4+NzGWDi
|
||||
lWUZ0ti9Zt1YnvUU8fdyCYBRmsFbAh9xqhDvqEN4Xi4FTKz8s93vD4/hPiSdpJyXywCMWPtrgKuGJ12P
|
||||
ck/6gPmDXAuYOHVR/lY6UN3XMXb7kDv17MAGqhaqJ6WJ1sdegDUJ726a5oG5JDB2917vL+Kl3eO1N/lQ
|
||||
LgewUdIO8E0dk69vubosy+25JDA2bYNuFeJnOsZovxLjhbkkwEZZXl4+0QfOvfl2Ogg4O5cFNl1dFE9N
|
||||
4/B7Q+Oyj7mh/VzKZQE2UtM0j6iL+LWOidizhN3OPBiHuigvSmPwrvVjsn9pQnh1LguwGQa3Fo3fHp6M
|
||||
Pcw97c1WcllgQy0tLZ2UDr7/qmMc9jJNiF/WkwNjMHhQ0GzfX/yIU8RLfRCxkdq+kzTfrugcf/3MgZ1l
|
||||
+fRcHmCztU8Yq2P8h47J2cdcpTmQjdCE8IQ0vnzjdkjKP8nlAcZoWxXin3dP0n4l1eGb9UL92FwXOG51
|
||||
Ub48ja09w2Otz2nvTJpKs21QIWDs0lnKb6TJqTEphN3NQvncXBY4VtvSju4N3WOs17l6cXHxoblGwKRo
|
||||
r8mlHeAtHZO2b9mfDohem8sCR2XX3K4z0hj65NCYklSTGONpuUzApNlVFFWaqP81NHF7mvD2tnM7lwbu
|
||||
V/vwqTR2vrV+LPU7VSjf4ff+MAU0B65NeWVd12fm0sBhpTnzosHDp7rGUV8T9lVFvDiXCJgSrmEezDea
|
||||
onhMrgsM25rmyuvSODkwNG56nvZyYvi5XCNg2mgOXM3tVVH9ci4L3KtpmlN9W7Y+VYhfiEkuEzCt8n3L
|
||||
fzA8yXuY/b7OZEVZlovt3ew6xknf8965ublTcpmAaac5cG3C2zQ09Vv7bVAaC/+7fmz0Og6QYVZpDlyT
|
||||
GD/dPlgpl4b+2Nru5NIYuGfdmOhxmhB/VBblL+QaATNKc+DBfH1nCI/OdWHGtTewSdv874fGgIT4xfYb
|
||||
wlwmYNZpDlzNbVUIz85lYUblJ2i6BDacGP/u7O3bH5zLBPSF5sDV7K+L+Nu5LMyYtJP7xbSNfzy0zfue
|
||||
A+03gak8WwdVAnpHc+CaxHiJ5sCZsnK9f/+6bd3v3JZ2/r+SawT0mebAg0kfjB93v/Pp136t3X693bWN
|
||||
e56v6nsBhmkOXE24Ph0EnJXrwpSp63qhDuXnu7dtn1P+U1VVP5PLBHAozYGDtD+LchvU6TN4Iqa+lqGs
|
||||
XO8/YVAlgMPQHLiSsC+dNb0ml4UJVxflRWm73b1+O/Y5YXcVwvNziQDun+bANYnxkvO2bHlALg0TJsZ4
|
||||
cl3ESzu3Xa8Trm+KYimXCeDIaQ48mKqIH9McOHl2zc/vaIr42a5t1vN8tCiK03OZAI6J5sCVFPFr7QNk
|
||||
cl0Ys3yp6nvrtlO/s3K9f9ugSgDHSXPgILk58PxcFsYkX+93J8s1qUK8oynKF+YSAYyO5sCVhH3pgOjV
|
||||
uSxsoqZpHpjq//bu7dLjFPHGND+Xc5kARk9z4JrE+JZUEl+1bpLFhYW5VPf/WLcd5N/ruj4zlwlg42gO
|
||||
PCQfdXOVjdeE8MRU6xuGai9uXw2MgebA1YTrFkMoc10YsaYoX5rqfOf6uvc6e9LO/xW5RACbT3Pgam5N
|
||||
B0Q/m8vCCLT3XnCQ2ZXwnWqhenIuE8D4aA5czV3OykZj19yuM1I9PzlUXwnhirIst+cyAYyf5sA1GTQH
|
||||
uu/6MdoZ4+NTHb+1rq59j+v9wKTSHHhIPtI0zam5NByhNH5enGr306Fa9j1720ttuUQAE0tz4Epi/FJM
|
||||
cl24b8ZNd25KdTk31whg8mkOXEm4pX1EbS4LHebn5x+WdnIf765fr3NVCOFRuUwA00Nz4Gr21kX58lwW
|
||||
1qjmq8el+nxjqF4S4yVLS0sn5TIBTB/NgWuiOfAQTVE+J9XltnV16nXCvqqIF+cSAUw3zYGH5INnb9/+
|
||||
4Fyavtra7uRSLe4Zqk3f88MmxvNyjQBmhiavg/liVVVFrkuvLC4uPjSt/4eG6iEhXlOWZchlApg9mgNX
|
||||
c3P6wD8nl6UXqvlqZ1rv/xmqQ+/ThPJv5ufnH5TLBDC7NAeuZm97n/tclplWhfCstL4/GVr/nsf1fqCH
|
||||
NAeu5kB7aSSVZFabA13v786tVVFckGsE0C+aAw8mnSG/f25u7pRcmpnQbt8mlB/oWt8+pwnxWk+PBNAc
|
||||
uJoqxC/MSnNgs7BQ1yFc17WePc97Z+1AD+C4aA5czU3T/qjXdED3zLQePx5ar75nf77ev3VQJQBWaQ5c
|
||||
zZ4qhJfkskyVuigvapvbOtapt2lC/FFTls/IJQKgi+bA1aw0B07FGWOM8eQ6xnd1rEe/E+OX2jGdywTA
|
||||
fdEcuCYx/u2kXzNudjTz6az/c53L3+NUMX7YI6EBjp7mwIO5pt3J5rpMlHKhfFpavu8PLW/fM+s/7QTY
|
||||
eJoDV/PduiiWc1kmwuB6f7x7aDn7ntvrGC/MJQLgeGgOHKQK8Y46hOflsoxN0zQPbEJ8Z9cy9jxf3RnC
|
||||
o3OZABgFzYGrab9efl0qyViaAxcXFubSgchnOpar77k8xnhaLhMAo6Q5cE2K+L7NfoBMHcJT0nvfvG5Z
|
||||
+h3X+wE2iebAg7m6LMvtuS4bKl/v14txSMLuKoQX5BIBsBk0B64kfCfV4om5LCN33pYtD3DA1ZVwfb1Q
|
||||
PzaXCYDNpDlwJWH3RnSe75rbdUZ6/X9b/369z0eLojg9lwmAcdAcuJqV5sCRaEJ4QnrNbw+9R9+zcr1/
|
||||
26BKAIyV5sBDcll7W95cmmPSPocgvc6dQ6/b9+xpivJluUQATBDNgQdz1TE2B6phV4p446TdhAmAIens
|
||||
9ZXpQ1tz4KA58Am5LPfrrB07Hp7+zr90v1Z/UxXxU3Vdn5nLBMAk0xy4krC7WSifm8tyWGVZnl2F+M3u
|
||||
1+hxYrxkeXn5xFwmAKaB5sDV7E9nsRfnsqyTdnIvGtxiuPPv9jV7Ul1ekUsEwLTRHHgwVSjfsbS0dFIu
|
||||
TWtr+6uB9P8ODP/Znue7ZVmek2sEwBTT2Laa8sr2enb7jHoHRl0JV8QYH5nHDQCzwJ0DV/P1tKO7vuO/
|
||||
9zpVKN/qej/AjNIcKB3Z24TyVXmIADCrNAfKmtzUxHhuHhoAzDrNgZJyVQjhUXlIANAjmgN7m/Du471d
|
||||
MgBTzp0D+5Sw777uiQBAz2gO7EPCLSnn500OAAOaA2c615RlGfKmBoBDaQ6cvTQhvmd+fv5BeRMDwGFp
|
||||
DpyJuN4PwDHQHDjVubUqigvypgSAo6M5cPrShHjtYghl3oQAcGw0B05Rivi+ubm5U/KmA4Djozlw4rM/
|
||||
X+/fOthiADA6mgMnME2IP2rK8hl5GwHAxtAcOFH5SozxrLxpAGBjaQ4cf6oYP9w0zal5kwDA5tAcOLYc
|
||||
aC/FpE1wwmBLAMAm0xy46bk91fvCXH4AGCvNgZuRIn6tKYrH5JoDwGTQHLihuTzGeFouNQBMFs2BI4/r
|
||||
/QBMB82Bo0rYXYXwglxWAJh8mgOPN+H6eqF+bC4nAEwVzYHHkiL+c1EUp+caAsB00hx4FInxLalk2waV
|
||||
A4AppznwfrOnLsqX53IBwOzQHHiYFPHGaqF6Ui4TAMwezYGHpirip+q6PjOXBwBmmubANjFesry8fGKu
|
||||
CQD0Q4+bA/dWMf56LgMA9E8PmwO/W5blOXn1AaC/+tMcWF4ZY3xkXm0AYOabA2O8ZGlp6aS8ugDAGrPY
|
||||
HLi3CeWr8voBAIczQ82BN6UDmnPzagEA92f6mwPLz1dVVeTVAQCO1LQ2B1Yh/PX8/PyD8moAAEdrupoD
|
||||
w76qiBfnRQcAjtMUNAeGW1LOz8sLAIzKBDcHXlOWZciLCQCM2gQ2B142Nzd3Sl48AGCjTEhz4H7X+wFg
|
||||
k425OfDWqqh+Pi8KALDJtqWDgDemHfKBoR30hqUJ8dqY5PcHAMalKcrnpJ3z94Z31qNO+/t+1/sBYIKk
|
||||
k/LT6hD+Mu2oR/4rgXTW/+X02r+U3woAmDTtz/GaIv5F2nH/ZHhHfpS5J+Vf01n/S9LLbhu8OgAw0dpb
|
||||
8TYL5XPTmfvb0o78v/MOvWtHvybtzXzKT1Qx/n5d1wv5pQCAaXXvAUFRLLXd+3WMFzZF+cKUl7X/rIri
|
||||
gsWFhbn8RwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJQ6e/v2BzQpPSNHvLap4sM5xVeaFLflFP/XpfvfTYqvHfx3
|
||||
6XXdf9t9Tfl9AIApkFM6P1fxrpzixysv9seQ7msu7b5H+X0BgAl04IU/4j97XtSPN1e1EeeVPwcAmAC7
|
||||
5ned0aT07p4X8HFkf5viHWft2PGQ8ucCky8iTq7r+uwmpefkqr6ojfitnOpXtlX94qaqLsg5L5ZfA0yB
|
||||
nXX9lJzihp4X7nHnupzSE8ufD0yeuq6Xmir+IKd0eU5xZ896LvO9nOKdbVW/SA8IpkCOeEFOsadnMW9U
|
||||
7mxSelm5HcBE2NZW9TNzqq/oWbvHkluaVL+xaZqq/AHABGhS+pWc4u6exbsJqV8/Nzd3QrlNwNZoFpsn
|
||||
tFV8cnStrit3dmt9+aHLDyx/HrBF2rp+ak5xV8+C3bS0Kf3j0tLSg8ptAzbPeXNz922r+OMN/ctAFdd3
|
||||
lxrLnw1ssu5tuZzippFFuiVJn4+IKLcR2HgppYfnFFeOrsuNSNrbpvSqchuAzXOfMVzfG3e+l6vqSeWG
|
||||
AhunjTh3k8q/RdKfdl2DcnuADZar+tdHF+RE5M4c8dJye4Hx65r6OcXtPetwk1K/ptwmYAN1H83JKb4/
|
||||
uhgnJ23En3TvUpTbDqzf7t27T+za+eW625JU9UXl9gEb5ODNO3oW4uTlg23bnlpuP3D8upt95RSX9ay3
|
||||
rcpdioGwObZ1D+3pWYQTmTbFNT5DDOPRpvS4gzfiGl1rW5xvV1V1erm9wBh1JbuexTfhSTf6GwKsz6Gb
|
||||
fR3PQ702JW2Kt5TbDIxR17wtF96U5I7uhkXl/gD36oTuJjw9a2rSsr+7CVG58cCY5FR/umfhTU8i3qAc
|
||||
CEdnYWHhwW3ER0bW0eTmA+U+AGOwvLx8Uk6xr2fRTVve6yEj8JM1C82jc4qv9qyfiU5bVY8s9wVYp50p
|
||||
PaJcbFOczyoHQr+DD/KJm3vWzRTkwA2CgHE6dN//ngU3tfl2XdfnlPsJA9bd4fM13fX0nvUyLbmu3Clg
|
||||
ndqq/uWexTbt2dPdzazcVxia7oFaOcX7etbI1KVpml3l/gHr0KT0wnKhzUj2txF/6L7iDFVEnJVTfLFn
|
||||
bUxlmpReVu4jsA454sJyoc1SmpTePT8/f0q53zDLmpSenlP8qFwP05369eV+AutQL9ZPHl1os5b0qaXF
|
||||
xfly32EGbcup/v2c4u7RdTDdaSLeX+4ssA67FhZ2lAttRnODG4owy5YfuvzANtXv6Tn3ZyMRHy/3GVif
|
||||
bbP3VuE95sdd6bEcAEy7vJDbnNLne875mUmT4jPlfgPr1N1pq1xsM5yuHNg9Vlg5kJnQRjwtp/hhz7k+
|
||||
a7mq3HdgnaboUcDjzKURcXI5C5gmOdW/PSN38jyK1B8t9x9Yp64gN4uloaPI1e2OdqGcB0y67pfXHPG2
|
||||
nnN6ZuPJgLBBpuzhIONLFdfvjHhMOQ+YVHVdp+6X15FzedZTxe+UswDGYAZvCXzUaVLcllN6djkTmDSH
|
||||
Prb73fIcHkLaiPPKeQDj0X0a4Mpy0Q0od7cRv1cOBSZFrurfyCnt7Tl3h5DbdXZgAzWLzeMH2gVYk/T2
|
||||
tm3vV84GtsqB6/1VvHX0XB1U3lfOBRiznNLrehbf0HJVXdfby9nAZusKuk2KT/Sco8NKxIXlbIAx2717
|
||||
94n+wDmQb9R1fXY5H9gsuaqelFN8p+fcHFqu6/5cKucDbIC2bR+aq/hyz0IcWNKt/ubBVshVfVFOcefo
|
||||
OTm8tCm9opwPsIEO3lo0vlEuxgHm7u5mK+V8YCMsLy+flKv4y57zcJBpU3xBJwe2wMEHBc32/cWPOlW8
|
||||
1R9EbKSud5JTunzk3Btu9u+s66eUcwI2SfeEsRzxDz2Lc4i5UjmQjdCm9FjvuJWp/6icE7D5TmhS/Nno
|
||||
Ah1emhRfy4v5UeWA4Hjlqn5JTnFHea4NOd2dSbs/d8pZAVukTenXFJO6pFvbxfpZ5XzgGJ3QPZly9Pwa
|
||||
fK5aWlp6UDksYIt11+RySjf2LNqhZV+b0qvK+cDR2DW/64yc4rKe82rouSwiTivnBUyIXVXV5BT/1bN4
|
||||
B5j0pq65Xc4I7kn38Kmc4uuj59Kw06T6zT7vD1NAOXBt6ityzmeWM4JSjnj+wYdPlefQkJP2NlVcXM4K
|
||||
mGyuYR7OV9uqemQ5IDhkWxvx6u6jbT3nzoDTXU5MP1MOC5gSyoGruaWpml8s58OwtW17qnfLRtOk+ExE
|
||||
RDkvYMocum/598pFPsDs83YmK+q6XuruZtdzngw975yfnz+lnBcwpZQD1yb9lULTsHXvBuUU/zt6bgw6
|
||||
fkGGWaUcuCYRH+8erFTOiJm3rXuRO/gciZ7zYqBpU/ygruqfK4cFzBblwMP5ys6UHlEOiNnU3cAmp/j7
|
||||
nvNg6Pls9w5hOS9gRikHrubmJqVnlPNhthx6gqZLYGUi/u7s7dsfUM4LmHHKgavZl6v4zXI+zIYc8fM5
|
||||
xQ97jvuQs797J7C7JFLOCxgI5cA1ibhEOXCmrFzv3zdyrIedm9uIXyqHBQyQcuDhdE86c7/z6de9rd29
|
||||
vV0eX4kv6b0AJeXA1aRrI+KsckBMh5zzYk71p0eP69BT/1PTND9VzgvgAOXAg+k+FuU2qNPn4BMx9VqK
|
||||
rFzvv085L4AjKAeuJO3NqX5lOR8mU67qi3KKu0aP45CTbm1Sek45K4B7pBy4JhGXnDc3d99yRkyGiDg5
|
||||
V/HWkeM2+KRr26paLucFcK+UAw+nqeLDyoGTZ9fCwo62ik+Wx0viQ1VVnV7OC+BYKAeupIovdw+QKQfE
|
||||
1jh0qeo7I8dp2Fm53n9COS+A46IceDCHyoHnl/Nhcx263j/483FtmhS3tVX9vHJWAOumHLiStLdN6RXl
|
||||
fNh4bdveL6f0ptFjMvBUcX2uqt3lvADGRjlwTSLe4K3WzbO0uDifU/zHyHGQf885n1nOC2DslAOPyIfc
|
||||
XGXjtSk9Lqe4rmf+w47bVwNbQDlwNenzSynV5YAYj7aqX5RT3D4690Hnjhzx0nJWAJtGOXA1N7URP13O
|
||||
h+PX3XvBL5l9Sd9sFpsnlPMC2HTKgau509/KxmPX/K4zcorLemY88KTL67reXs4LYMsoB67JwXKg+64f
|
||||
p50Rj8kpvj4y16HH9X5gUikHHpEPtm17ajkjfrIc8YKc4sc98xxy9nSX2spZAUwa5cCVRHwuIqIcEL2c
|
||||
N/25oY04txwWwMRSDlxJurF7RG05Hw5bWFh4cBvxkdHZDT5XppQeXs4LYOIpB65mT67ql5TzYW6uWWge
|
||||
nVN8tWdmw07EJcvLyyeV8wKYGsqBa6IceIS2qp+ZU9w8MqdBJ+1tqri4nBXAVFIOPCLvPXv79geUMxqY
|
||||
bd2LXE5xd898hpzvtxHnlcMCmHZKXofz2aZpqnJAQ7C0tPSgnOJ9PTMZeq6u6zqV8wKYGcqBq/l2Xdfn
|
||||
lPOZZc1CszOn+J+eWQw6bar/ZmFh4f7lvABmjnLgavZ097kv5zOLmpSenlP8qGcGA47r/cAAKQeuZn93
|
||||
aWSGy4Gu9/fnpqaqLiiHBTAIyoGH06T07vn5+VPKGU2z7vi2qX5Pua9DT5viGk+PBFAOXE2T4jOzUg5s
|
||||
Fxdz95jkch8l3jlrv+gBrIty4GpumPZHvbYRT8spftizb0POvkPX+7eV8wIYPOXA1dzRpPTCcj7TIFf1
|
||||
RV25rWefBps2xQ/aun5qOSsA1lAOXM1KOXAq/sYYESfniLf17MewE/G57pwu5wVAD+XANYn420m/Ztzu
|
||||
aBdySp8a2faBp4l4v0dCAxw75cDDubp7kS0HNAnqxfrJOcV3e7Z5yJn1j3YCbDzlwNV8K1fV7nI+W+ng
|
||||
9f64q2dbh5xbcsSF5awAOA7KgQfTpLgtp/Tscj6brW3b+7Up3lJun8SXdqb0iHJeAKyDcuBqureXX71V
|
||||
5cClxcX5JsUnerZr6PlARJxWzguAMVAOXJMq3rXZD5DJKT2xe4jRyLYMO673A2wS5cDDuaqu6+3lgDbC
|
||||
oev9uhhHJN3apPTcclYAbCDlwJWkb7YpPa6cz7icNzd3X79w9SVdmxfzo8p5AbAJlANXkm7diOb5rvld
|
||||
Z+QU/zb68wafD1VVdXo5LwA2kXLgalbKgWPRpvTYnOIbPT9nyFm53n9COS8AtoBy4BG5tLstbzmjY9E9
|
||||
hyCnuL3new85d7RV/eJyVgBsPeXAw7nyOMuBZtiXKq6ftJswAVBoUnqZcmCXA+XAx5bzuSdn7djxkJzS
|
||||
v4x+n2GnqeJjOeczy3kBMIGUA1eSbm0X62eV8ynVdX12k+Jro18/8ERcsnv37hPLeQEwwZQDV7OvqeLi
|
||||
cj4rcsTzD95ieOTrhpw7csRLy1kBMCWUAw+nSfWbl5eXT1oznm3dpwa6Znv53w4836rr+pw1cwJgSim2
|
||||
raa+orue3T2j3i9GfUmXR8TDyhMIgCnmzoGr+cqBu9iN/v+DTpPqN7reDzCjlAOlJ3vaVL+8PFcAmDHK
|
||||
gbImN7QR55bnCAAzSjlQupslpZQeXp4bAMw+5cDBJr19vbdLBmDKuXPgkJL2/qR7IgAwMMqBQ0i6Mad0
|
||||
fnnsARg45cCZztV1XafymAPAAcqBs5c2xTsWFhbuXx5rACgpB85EXO8H4DgoB051bmqq6oLymALAUVEO
|
||||
nL60Ka5ZSqkujyUAHBPlwClKFe+an58/pTyGAHBclAMnPvsOXe/fVh47AFgv5cAJTJviB21dP7U8WAAw
|
||||
VsqBE5UvRsRZ5TECgA2hHLj1aSLe37btqeWxAYANpRy4ZdnfXYqZm5u7T3lMAGBTKAduem7JEReWxwEA
|
||||
toJy4Gakii+3VfXIcvgAsKWUAzc0H4iI08qZA8BEUA4ce1zvB2A6KAeOK+nWJqXnlvMFgImlHLjepGvz
|
||||
Yn5UOVcAmAbKgceTKv65qqrTy2ECwFRRDjyGRLyh+8WpnCEATCXlwHvNHbmqX1LODQCmnnLgPaSK65vF
|
||||
5vHlvABgZigHHpmmio/lnM8s5wQAs0g5sEvEJbt37z6xHA4AzLQBlwP3NBG/Ws4DAAZjgOXAb9V1fU45
|
||||
BwAYnOGUA+srIuJh5f4DwGDNfDkw4pLl5eWTyv0GAGazHLinTfXLyx0FAAozVA68oY04t9w/AOAeTH85
|
||||
sP500zRVuV8AwL2Y1nJgk9JfLyws3L/cHwDgKE1XOTDtbaq4uNwHAOD4TEE5MN2YUzq/3HAAYJ0muBx4
|
||||
dV3XqdxeAGBMJrAceOn8/Pwp5XYCAGM2IeXAfa73A8Am2+Jy4E1N1fxsuU0AwOY4IUe8NqfY3/MivSFp
|
||||
U1wTEVFuCACwydqqfmZO8Z3yxXrc6T7f73o/AEyQiDgtp/QXG/EpgTbFF3JKv1D+TABgQnQfx2ur+POc
|
||||
4kflC/kx5u6c4l+blF7YXWoofw4AMIG6W/G2i/Wzckp/lVP896EX9PJFvkh3M5/6o03E7+acF8vvCQBM
|
||||
mQO/EFTVctfezxEXtlX9vLaqX9z9s6mqC5YWF+fLrwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6LEtW/4flgYiLD1qeX0A
|
||||
AAAASUVORK5CYII=
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="LB_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -383,122 +379,122 @@
|
||||
<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
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</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
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
|
||||
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
|
||||
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
|
||||
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
|
||||
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
|
||||
cMaRN0UdBBkAAAAASUVORK5CYII=
|
||||
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||
khP7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton10.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
||||
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
||||
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
||||
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
||||
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
||||
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
||||
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
||||
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
||||
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
||||
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
||||
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACM0lE
|
||||
QVQ4T2P4//8/AyHMzicsqh6c34guDsIYAshYQFadhZmZhU1c18Yp8NCP/7LWvjHoajA0gbCwpqW7YeGs
|
||||
FXYTD15xnHnihuuiiw98D//6777kynNuAREpnAYwMjIyqQQX9zkvffDfZce3//b7//23PPD/v/HWr//1
|
||||
Vr74b7jm3X/VpI7FTIyMjFgNUAku6nRd//6/0ZTT31QbNlxXbthwQa3/6CO1ZS/+K8y+91968u3/qr1X
|
||||
/gsq6jliGCCoYmRp23/4u4R9eCczF782AwMDFwMDA7OYhV+C2ooP/5UnXf+vkDXnioi+cz4LG6cIhgGK
|
||||
zlE1/PLakcguArsquXuOSvmqayLatmnMjAx86PJwBhMzM4YkCPNKKpkxMTAIootjGIANswtKSKKLoWMM
|
||||
ARAW0LS20S2at1POM20quhyvspGFqLlfJoYBTCzsnEI6Dl6a6ZO32c66+t91/dv/Akq6wTB5IQVdfgnP
|
||||
jGSlpr1vuKTVPDAM4FczD7Ceeum/w6J7/y2XP/2vt/rNf9mGTUekC+eulKtYuUW+5+Qj2TlP/4u4psxD
|
||||
dhGSC9h4dUoWntZf9e6/0qr3/5V3/Puvuu//f6Xt///Lrvr8X3ryzf8SfsWbmNBiAsV/bJIqpkpLX/xU
|
||||
2/n3v+qcmx9VZl77oth97L1U2pQTgtq2WUwMDGzI6jEMAGFR/7wGzS3f//PIagawcvIqsLJzKTAyMLCi
|
||||
q8NpABMLK4dCfOsSZlYOUXQ5bBgArRReBMoH61gAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton11.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton12.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=
|
||||
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||
khP7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton13.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
||||
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
||||
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
||||
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
||||
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
||||
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
||||
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
||||
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
||||
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
||||
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
||||
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACM0lE
|
||||
QVQ4T2P4//8/AyHMzicsqh6c34guDsIYAshYQFadhZmZhU1c18Yp8NCP/7LWvjHoajA0gbCwpqW7YeGs
|
||||
FXYTD15xnHnihuuiiw98D//6777kynNuAREpnAYwMjIyqQQX9zkvffDfZce3//b7//23PPD/v/HWr//1
|
||||
Vr74b7jm3X/VpI7FTIyMjFgNUAku6nRd//6/0ZTT31QbNlxXbthwQa3/6CO1ZS/+K8y+91968u3/qr1X
|
||||
/gsq6jliGCCoYmRp23/4u4R9eCczF782AwMDFwMDA7OYhV+C2ooP/5UnXf+vkDXnioi+cz4LG6cIhgGK
|
||||
zlE1/PLakcguArsquXuOSvmqayLatmnMjAx86PJwBhMzM4YkCPNKKpkxMTAIootjGIANswtKSKKLoWMM
|
||||
ARAW0LS20S2at1POM20quhyvspGFqLlfJoYBTCzsnEI6Dl6a6ZO32c66+t91/dv/Akq6wTB5IQVdfgnP
|
||||
jGSlpr1vuKTVPDAM4FczD7Ceeum/w6J7/y2XP/2vt/rNf9mGTUekC+eulKtYuUW+5+Qj2TlP/4u4psxD
|
||||
dhGSC9h4dUoWntZf9e6/0qr3/5V3/Puvuu//f6Xt///Lrvr8X3ryzf8SfsWbmNBiAsV/bJIqpkpLX/xU
|
||||
2/n3v+qcmx9VZl77oth97L1U2pQTgtq2WUwMDGzI6jEMAGFR/7wGzS3f//PIagawcvIqsLJzKTAyMLCi
|
||||
q8NpABMLK4dCfOsSZlYOUXQ5bBgArRReBMoH61gAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton14.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton15.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=
|
||||
vAAADrwBlbxySQAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||
khP7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton16.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
|
||||
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
|
||||
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
|
||||
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
|
||||
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
|
||||
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
|
||||
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
|
||||
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
|
||||
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
|
||||
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
|
||||
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
|
||||
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACM0lE
|
||||
QVQ4T2P4//8/AyHMzicsqh6c34guDsIYAshYQFadhZmZhU1c18Yp8NCP/7LWvjHoajA0gbCwpqW7YeGs
|
||||
FXYTD15xnHnihuuiiw98D//6777kynNuAREpnAYwMjIyqQQX9zkvffDfZce3//b7//23PPD/v/HWr//1
|
||||
Vr74b7jm3X/VpI7FTIyMjFgNUAku6nRd//6/0ZTT31QbNlxXbthwQa3/6CO1ZS/+K8y+91968u3/qr1X
|
||||
/gsq6jliGCCoYmRp23/4u4R9eCczF782AwMDFwMDA7OYhV+C2ooP/5UnXf+vkDXnioi+cz4LG6cIhgGK
|
||||
zlE1/PLakcguArsquXuOSvmqayLatmnMjAx86PJwBhMzM4YkCPNKKpkxMTAIootjGIANswtKSKKLoWMM
|
||||
ARAW0LS20S2at1POM20quhyvspGFqLlfJoYBTCzsnEI6Dl6a6ZO32c66+t91/dv/Akq6wTB5IQVdfgnP
|
||||
jGSlpr1vuKTVPDAM4FczD7Ceeum/w6J7/y2XP/2vt/rNf9mGTUekC+eulKtYuUW+5+Qj2TlP/4u4psxD
|
||||
dhGSC9h4dUoWntZf9e6/0qr3/5V3/Puvuu//f6Xt///Lrvr8X3ryzf8SfsWbmNBiAsV/bJIqpkpLX/xU
|
||||
2/n3v+qcmx9VZl77oth97L1U2pQTgtq2WUwMDGzI6jEMAGFR/7wGzS3f//PIagawcvIqsLJzKTAyMLCi
|
||||
q8NpABMLK4dCfOsSZlYOUXQ5bBgArRReBMoH61gAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton17.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
|
||||
vAAADrwBlbxySQAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -465,6 +465,9 @@ Namespace API.YouTube.Controls
|
||||
TXT_FILE.Text = f
|
||||
End If
|
||||
End Sub
|
||||
Private Sub BTT_TRIM_Click(sender As Object, e As EventArgs) Handles BTT_TRIM.Click
|
||||
Using f As New VideoOptionsTrimForm(MyContainer) : f.ShowDialog() : End Using
|
||||
End Sub
|
||||
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick
|
||||
Select Case Sender.DefaultButton
|
||||
Case ADB.Open
|
||||
|
||||
166
SCrawler.YouTube/Controls/VideoOptionsTrimForm.Designer.vb
generated
Normal file
166
SCrawler.YouTube/Controls/VideoOptionsTrimForm.Designer.vb
generated
Normal file
@@ -0,0 +1,166 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.YouTube.Controls
|
||||
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
|
||||
Partial Friend Class VideoOptionsTrimForm : Inherits System.Windows.Forms.Form
|
||||
<System.Diagnostics.DebuggerNonUserCode()>
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
Try
|
||||
If disposing AndAlso components IsNot Nothing Then
|
||||
components.Dispose()
|
||||
End If
|
||||
Finally
|
||||
MyBase.Dispose(disposing)
|
||||
End Try
|
||||
End Sub
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TP_OPTIONS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||
Me.LIST_TRIM = New System.Windows.Forms.ListBox()
|
||||
Me.CH_DEL_ORIG = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_ADD_M3U8 = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_SEP_FOLDER = New System.Windows.Forms.CheckBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_OPTIONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_OPTIONS.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
'
|
||||
'
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(434, 236)
|
||||
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(434, 261)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_MAIN
|
||||
'
|
||||
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.LIST_TRIM, 0, 1)
|
||||
TP_MAIN.Controls.Add(TP_OPTIONS, 0, 0)
|
||||
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
TP_MAIN.Name = "TP_MAIN"
|
||||
TP_MAIN.RowCount = 2
|
||||
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, 100.0!))
|
||||
TP_MAIN.Size = New System.Drawing.Size(434, 236)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'LIST_TRIM
|
||||
'
|
||||
Me.LIST_TRIM.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.LIST_TRIM.FormattingEnabled = True
|
||||
Me.LIST_TRIM.Location = New System.Drawing.Point(3, 33)
|
||||
Me.LIST_TRIM.Name = "LIST_TRIM"
|
||||
Me.LIST_TRIM.Size = New System.Drawing.Size(428, 200)
|
||||
Me.LIST_TRIM.TabIndex = 0
|
||||
'
|
||||
'TP_OPTIONS
|
||||
'
|
||||
TP_OPTIONS.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
|
||||
TP_OPTIONS.ColumnCount = 3
|
||||
TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334!))
|
||||
TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334!))
|
||||
TP_OPTIONS.Controls.Add(Me.CH_DEL_ORIG, 0, 0)
|
||||
TP_OPTIONS.Controls.Add(Me.CH_ADD_M3U8, 1, 0)
|
||||
TP_OPTIONS.Controls.Add(Me.CH_SEP_FOLDER, 2, 0)
|
||||
TP_OPTIONS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_OPTIONS.Location = New System.Drawing.Point(3, 3)
|
||||
TP_OPTIONS.Name = "TP_OPTIONS"
|
||||
TP_OPTIONS.RowCount = 1
|
||||
TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 23.0!))
|
||||
TP_OPTIONS.Size = New System.Drawing.Size(428, 24)
|
||||
TP_OPTIONS.TabIndex = 1
|
||||
'
|
||||
'CH_DEL_ORIG
|
||||
'
|
||||
Me.CH_DEL_ORIG.AutoSize = True
|
||||
Me.CH_DEL_ORIG.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_DEL_ORIG.Location = New System.Drawing.Point(4, 4)
|
||||
Me.CH_DEL_ORIG.Name = "CH_DEL_ORIG"
|
||||
Me.CH_DEL_ORIG.Size = New System.Drawing.Size(135, 16)
|
||||
Me.CH_DEL_ORIG.TabIndex = 0
|
||||
Me.CH_DEL_ORIG.Text = "Delete original file"
|
||||
TT_MAIN.SetToolTip(Me.CH_DEL_ORIG, "If checked, the original file will be deleted after trimming")
|
||||
Me.CH_DEL_ORIG.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_ADD_M3U8
|
||||
'
|
||||
Me.CH_ADD_M3U8.AutoSize = True
|
||||
Me.CH_ADD_M3U8.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_ADD_M3U8.Location = New System.Drawing.Point(146, 4)
|
||||
Me.CH_ADD_M3U8.Name = "CH_ADD_M3U8"
|
||||
Me.CH_ADD_M3U8.Size = New System.Drawing.Size(135, 16)
|
||||
Me.CH_ADD_M3U8.TabIndex = 1
|
||||
Me.CH_ADD_M3U8.Text = "Add to M3U8"
|
||||
TT_MAIN.SetToolTip(Me.CH_ADD_M3U8, "If checked, the trimmed files will be added to the M3U8 playlist (if selected)")
|
||||
Me.CH_ADD_M3U8.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_SEP_FOLDER
|
||||
'
|
||||
Me.CH_SEP_FOLDER.AutoSize = True
|
||||
Me.CH_SEP_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_SEP_FOLDER.Location = New System.Drawing.Point(288, 4)
|
||||
Me.CH_SEP_FOLDER.Name = "CH_SEP_FOLDER"
|
||||
Me.CH_SEP_FOLDER.Size = New System.Drawing.Size(136, 16)
|
||||
Me.CH_SEP_FOLDER.TabIndex = 2
|
||||
Me.CH_SEP_FOLDER.Text = "Separate folder"
|
||||
TT_MAIN.SetToolTip(Me.CH_SEP_FOLDER, "Place the trimmed files in a separate folder")
|
||||
Me.CH_SEP_FOLDER.UseVisualStyleBackColor = True
|
||||
'
|
||||
'VideoOptionsTrimForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(434, 261)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.KeyPreview = True
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(450, 300)
|
||||
Me.Name = "VideoOptionsTrimForm"
|
||||
Me.ShowIcon = False
|
||||
Me.ShowInTaskbar = False
|
||||
Me.Text = "Trimming options"
|
||||
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
|
||||
CONTAINER_MAIN.ResumeLayout(False)
|
||||
CONTAINER_MAIN.PerformLayout()
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_OPTIONS.ResumeLayout(False)
|
||||
TP_OPTIONS.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
|
||||
Private WithEvents LIST_TRIM As ListBox
|
||||
Private WithEvents CH_DEL_ORIG As CheckBox
|
||||
Private WithEvents CH_ADD_M3U8 As CheckBox
|
||||
Private WithEvents CH_SEP_FOLDER As CheckBox
|
||||
End Class
|
||||
End Namespace
|
||||
135
SCrawler.YouTube/Controls/VideoOptionsTrimForm.resx
Normal file
135
SCrawler.YouTube/Controls/VideoOptionsTrimForm.resx
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TP_OPTIONS.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>
|
||||
</root>
|
||||
167
SCrawler.YouTube/Controls/VideoOptionsTrimForm.vb
Normal file
167
SCrawler.YouTube/Controls/VideoOptionsTrimForm.vb
Normal file
@@ -0,0 +1,167 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports PersonalUtilities.Forms
|
||||
Imports PersonalUtilities.Forms.Toolbars
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports SCrawler.API.YouTube.Base
|
||||
Imports ETC = PersonalUtilities.Forms.Toolbars.EditToolbar.ControlItem
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class VideoOptionsTrimForm
|
||||
#Region "Declarations"
|
||||
Private WithEvents MyDefs As DefaultFormOptions
|
||||
Private ReadOnly Property MyMedia As YouTubeMediaContainerBase
|
||||
Private ReadOnly Property TrimData As List(Of TrimOption)
|
||||
Private WithEvents BTT_CLEAR_ALL As ToolStripButton
|
||||
Private WithEvents BTT_CHAPTERS As ToolStripButton
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByRef Media As YouTubeMediaContainerBase)
|
||||
InitializeComponent()
|
||||
MyDefs = New DefaultFormOptions(Me, MyYouTubeSettings.DesignXml)
|
||||
MyMedia = Media
|
||||
TrimData = New List(Of TrimOption)
|
||||
TrimData.ListAddList(Media.TrimOptions)
|
||||
BTT_CLEAR_ALL = New ToolStripButton("Clear", PersonalUtilities.My.Resources.DeletePic_Red_24) With {
|
||||
.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
|
||||
.BackColor = MyColor.DeleteBack,
|
||||
.ForeColor = MyColor.DeleteFore
|
||||
}
|
||||
BTT_CHAPTERS = New ToolStripButton("Chapters") With {.DisplayStyle = ToolStripItemDisplayStyle.Text, .Enabled = Media.Chapters.Count > 0}
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form handlers"
|
||||
Private Sub VideoOptionsTrimForm_Load(sender As Object, e As EventArgs) Handles Me.Load
|
||||
With MyDefs
|
||||
.MyViewInitialize()
|
||||
.AddOkCancelToolbar()
|
||||
.AddEditToolbar({ETC.Add, ETC.Edit, ETC.Delete, BTT_CLEAR_ALL, ETC.Separator, BTT_CHAPTERS})
|
||||
|
||||
Refill()
|
||||
|
||||
With MyMedia
|
||||
If Not .TrimOptionsSet Then
|
||||
With MyYouTubeSettings
|
||||
CH_DEL_ORIG.Checked = .TrimDeleteOriginalFile
|
||||
CH_ADD_M3U8.Checked = .TrimAddTrimmedFilesToM3U8
|
||||
CH_SEP_FOLDER.Checked = .TrimSeparateFolder
|
||||
End With
|
||||
Else
|
||||
CH_DEL_ORIG.Checked = .TrimDeleteOriginalFile
|
||||
CH_ADD_M3U8.Checked = .TrimAddTrimmedFilesToM3U8
|
||||
CH_SEP_FOLDER.Checked = .TrimSeparateFolder
|
||||
End If
|
||||
End With
|
||||
|
||||
.EndLoaderOperations()
|
||||
End With
|
||||
End Sub
|
||||
Private Sub VideoOptionsTrimForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
|
||||
TrimData.Clear()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Refill"
|
||||
Private Sub Refill(Optional ByVal DEL As Boolean = False)
|
||||
Dim indx% = _CurrentIndex
|
||||
With LIST_TRIM
|
||||
.BeginUpdate()
|
||||
.Items.Clear()
|
||||
If TrimData.Count > 0 Then
|
||||
TrimData.Sort()
|
||||
.Items.AddRange(TrimData.Cast(Of Object).ToArray)
|
||||
If DEL Then indx -= IIf(indx - 1 < 0, 0, 1)
|
||||
If indx.ValueBetween(0, TrimData.Count - 1) Then
|
||||
.SelectedIndex = indx
|
||||
ElseIf (indx - 1).ValueBetween(0, TrimData.Count - 1) Then
|
||||
.SelectedIndex = indx - 1
|
||||
ElseIf (indx + 1).ValueBetween(0, TrimData.Count - 1) Then
|
||||
.SelectedIndex = indx + 1
|
||||
End If
|
||||
End If
|
||||
.EndUpdate()
|
||||
End With
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Ok"
|
||||
Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
|
||||
With MyMedia
|
||||
.TrimOptions.Clear()
|
||||
.TrimDeleteOriginalFile = CH_DEL_ORIG.Checked
|
||||
.TrimAddTrimmedFilesToM3U8 = CH_ADD_M3U8.Checked
|
||||
.TrimSeparateFolder = CH_SEP_FOLDER.Checked
|
||||
.TrimOptionsSet = True
|
||||
End With
|
||||
|
||||
If TrimData.Count > 0 Then
|
||||
TrimData.Sort()
|
||||
Dim indx% = 0
|
||||
Dim c%
|
||||
Dim opt As TrimOption
|
||||
Dim dic As New Dictionary(Of String, Integer)
|
||||
For i% = 0 To TrimData.Count - 1
|
||||
opt = TrimData(i)
|
||||
If opt.Name.IsEmptyString Then
|
||||
indx += 1
|
||||
opt.Name = indx
|
||||
Else
|
||||
c = TrimData.LongCount(Function(d) Not d.Name.IsEmptyString AndAlso d.Name = opt.Name)
|
||||
If c > 1 Then
|
||||
If Not dic.ContainsKey(opt.Name) Then dic.Add(opt.Name, 0)
|
||||
dic(opt.Name) += 1
|
||||
opt.Name &= $"_{dic(opt.Name)}"
|
||||
End If
|
||||
End If
|
||||
TrimData(i) = opt
|
||||
Next
|
||||
dic.Clear()
|
||||
MyMedia.TrimOptions.AddRange(TrimData)
|
||||
End If
|
||||
|
||||
MyDefs.CloseForm()
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Edit"
|
||||
Private Sub MyDefs_ButtonAddClick(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonAddClick
|
||||
Using f As New TrimOptionForm
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK AndAlso
|
||||
(TrimData.Count = 0 OrElse Not TrimData.Any(Function(t) t.End = f.MyTrimOption.End And t.Start = f.MyTrimOption.Start)) Then _
|
||||
TrimData.Add(f.MyTrimOption) : Refill()
|
||||
End Using
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonEditClick(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonEditClick
|
||||
If _CurrentIndex.ValueBetween(0, TrimData.Count - 1) Then
|
||||
Using f As New TrimOptionForm(TrimData(_CurrentIndex))
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Then TrimData(_CurrentIndex) = f.MyTrimOption : Refill()
|
||||
End Using
|
||||
End If
|
||||
End Sub
|
||||
Private Sub MyDefs_ButtonDeleteClickE(ByVal Sender As Object, ByVal e As EditToolbarEventArgs) Handles MyDefs.ButtonDeleteClickE
|
||||
If _CurrentIndex.ValueBetween(0, TrimData.Count - 1) AndAlso
|
||||
MsgBoxE({$"Are you sure you want to remove the following trim option?{vbCr}{vbCr}{TrimData(_CurrentIndex)}", "Remove trim option"}, vbYesNo + vbExclamation) = vbYes Then _
|
||||
TrimData.RemoveAt(_CurrentIndex) : Refill(True)
|
||||
End Sub
|
||||
Private Sub BTT_CLEAR_ALL_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR_ALL.Click
|
||||
If MsgBoxE({$"Are you sure you want to remove ALL trim options?", "Remove trim option"}, vbYesNo + vbCritical) = vbYes Then TrimData.Clear() : Refill()
|
||||
End Sub
|
||||
Private Sub BTT_CHAPTERS_Click(sender As Object, e As EventArgs) Handles BTT_CHAPTERS.Click
|
||||
Using f As New ChaptersForm(MyMedia, TrimData)
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK AndAlso f.MyResult.Count > 0 Then TrimData.ListAddList(f.MyResult, LAP.NotContainsOnly) : Refill()
|
||||
End Using
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "List"
|
||||
Private _CurrentIndex As Integer = -1
|
||||
Private Sub LIST_TRIM_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_TRIM.SelectedIndexChanged
|
||||
_CurrentIndex = LIST_TRIM.SelectedIndex
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
122
SCrawler.YouTube/Controls/YTDataFilter.vb
Normal file
122
SCrawler.YouTube/Controls/YTDataFilter.vb
Normal file
@@ -0,0 +1,122 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.YouTube.Base
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Namespace API.YouTube.Controls
|
||||
Friend Class YTDataFilter
|
||||
Private Const Name_Types As String = "Types"
|
||||
Private Const Name_IsMusic As String = "IsMusic"
|
||||
Private Const Name_IsVideo As String = "IsVideo"
|
||||
Private Const Name_UserList As String = "UserList"
|
||||
Friend Structure SimpleUser : Implements IEContainerProvider, IComparable(Of SimpleUser)
|
||||
Private Const Name_UID As String = "UID"
|
||||
Friend Title As String
|
||||
Friend ID As String
|
||||
Friend Sub New(ByVal _Title As String, ByVal _ID As String)
|
||||
Title = _Title
|
||||
ID = _ID
|
||||
End Sub
|
||||
Private Sub New(ByVal u As YouTubeMediaContainerBase)
|
||||
Title = u.Title
|
||||
ID = u.ID
|
||||
End Sub
|
||||
Public Shared Widening Operator CType(ByVal u As YouTubeMediaContainerBase) As SimpleUser
|
||||
Return New SimpleUser(u.UserTitle, u.UserID)
|
||||
End Operator
|
||||
Public Shared Widening Operator CType(ByVal e As EContainer) As SimpleUser
|
||||
Return New SimpleUser(e.Value, e.Attribute(Name_UID).Value)
|
||||
End Operator
|
||||
Public Overrides Function ToString() As String
|
||||
Return String.Format(CStr(Interaction.Switch(Title.IsEmptyString, "{1}", ID.IsEmptyString, "{0}", True, "{0} ({1})")), Title, ID)
|
||||
End Function
|
||||
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
||||
Return Not IsDBNull(Obj) AndAlso ToString() = DirectCast(Obj, SimpleUser).ToString
|
||||
End Function
|
||||
Private Function CompareTo(ByVal Other As SimpleUser) As Integer Implements IComparable(Of SimpleUser).CompareTo
|
||||
Return ToString.CompareTo(Other.ToString)
|
||||
End Function
|
||||
Private Function ToEContainer(Optional ByVal e As ErrorsDescriber = Nothing) As EContainer Implements IEContainerProvider.ToEContainer
|
||||
Return New EContainer("User", Title, {New EAttribute(Name_UID, ID)})
|
||||
End Function
|
||||
End Structure
|
||||
Friend ReadOnly Property Types As List(Of YouTubeMediaType)
|
||||
Friend Property IsMusic As Boolean = True
|
||||
Friend Property IsVideo As Boolean = True
|
||||
Friend ReadOnly Property UserList As List(Of SimpleUser)
|
||||
Private ReadOnly File As New SFile("Settings\YouTubeFilter.xml")
|
||||
Friend Sub New(Optional ByVal LoadFromFile As Boolean = True)
|
||||
Types = New List(Of YouTubeMediaType) From {YouTubeMediaType.Undefined}
|
||||
UserList = New List(Of SimpleUser)
|
||||
If LoadFromFile AndAlso File.Exists Then
|
||||
Using e As New XmlFile(File, Protector.Modes.All, False) With {.AllowSameNames = True}
|
||||
e.LoadData()
|
||||
If e.Count > 0 Then
|
||||
Types.Clear()
|
||||
Types.ListAddList(e.Value(Name_Types).StringToList(Of Integer)(","), LAP.NotContainsOnly)
|
||||
IsMusic = e.Value(Name_IsMusic).FromXML(Of Boolean)(True)
|
||||
IsVideo = e.Value(Name_IsVideo).FromXML(Of Boolean)(True)
|
||||
UserList.ListAddList(e(Name_UserList), LAP.IgnoreICopier)
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
End Sub
|
||||
Friend Sub New(ByVal f As YTDataFilter)
|
||||
Me.New(False)
|
||||
With f
|
||||
Types.ListAddList(.Types, LAP.NotContainsOnly)
|
||||
IsMusic = .IsMusic
|
||||
IsVideo = .IsVideo
|
||||
UserList.ListAddList(.UserList)
|
||||
End With
|
||||
End Sub
|
||||
Friend Sub Reset(Optional ByVal AddDefType As Boolean = True, Optional ByVal ClearUserList As Boolean = True)
|
||||
Types.Clear()
|
||||
If AddDefType Then Types.Add(YouTubeMediaType.Undefined)
|
||||
IsMusic = True
|
||||
IsVideo = True
|
||||
If ClearUserList Then UserList.Clear()
|
||||
End Sub
|
||||
Friend Sub Update()
|
||||
Using x As New XmlFile With {.AllowSameNames = True}
|
||||
With x
|
||||
.Add(Name_Types, Types.ListToStringE(","))
|
||||
.Add(Name_IsMusic, IsMusic.BoolToInteger)
|
||||
.Add(Name_IsVideo, IsVideo.BoolToInteger)
|
||||
.Add(Name_UserList, String.Empty)
|
||||
.Self()(Name_UserList).AddRange(UserList)
|
||||
.Name = "FILTER"
|
||||
.Save(File)
|
||||
End With
|
||||
End Using
|
||||
End Sub
|
||||
Friend Function Ready(ByVal Item As YouTubeMediaContainerBase, Optional ByVal IgnoreUserList As Boolean = False) As Boolean
|
||||
With Item
|
||||
If Not IsMusic Or Not IsVideo Then
|
||||
If .IsMusic And Not IsMusic Then Return False
|
||||
If Not .IsMusic And Not IsVideo Then Return False
|
||||
End If
|
||||
If Not Types.Contains(YouTubeMediaType.Undefined) AndAlso Not Types.Contains(.ObjectType) Then Return False
|
||||
If Not IgnoreUserList AndAlso UserList.Count > 0 AndAlso Not UserList.Contains(Item) Then Return False
|
||||
End With
|
||||
Return True
|
||||
End Function
|
||||
Friend Overloads Sub RemoveAll(ByRef Data As List(Of IYouTubeMediaContainer))
|
||||
Data.RemoveAll(Function(item) Not Ready(item))
|
||||
End Sub
|
||||
Friend Overloads Sub RemoveAll(ByRef Data As List(Of YouTubeMediaContainerBase))
|
||||
Data.RemoveAll(Function(item) Not Ready(item))
|
||||
End Sub
|
||||
Friend Sub Populate(ByVal InitList As List(Of IYouTubeMediaContainer), ByVal DestList As List(Of IYouTubeMediaContainer), ByVal IgnoreUserList As Boolean)
|
||||
DestList.Clear()
|
||||
If InitList.Count > 0 Then InitList.ForEach(Sub(item) If Ready(item, IgnoreUserList) Then DestList.ListAddValue(item))
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -54,6 +54,7 @@ Namespace API.YouTube
|
||||
Friend ReadOnly DateBaseProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
|
||||
Friend ReadOnly DateAddedProvider As New ADateTime(ADateTime.Formats.yyyymmdd) With {.DateSeparator = String.Empty}
|
||||
Friend ReadOnly TimeToStringProvider As IFormatProvider = New TimeToStringConverter
|
||||
Friend ReadOnly TimeToStringProviderH As IFormatProvider = New TimeToStringConverter(True)
|
||||
Friend ReadOnly TitleHtmlConverter As Func(Of String, String) = Function(Input) Input.StringRemoveWinForbiddenSymbols().StringTrim()
|
||||
Friend ReadOnly ProgressProvider As IMyProgressNumberProvider = MyProgressNumberProvider.Percentage
|
||||
Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue)
|
||||
@@ -80,11 +81,15 @@ Namespace API.YouTube
|
||||
Private Class TimeToStringConverter : Implements ICustomProvider
|
||||
Private ReadOnly _Provider As New ADateTime("mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
|
||||
Private ReadOnly _ProviderWithHours As New ADateTime("h\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
|
||||
Private ReadOnly ForceHours As Boolean
|
||||
Private ReadOnly Property Provider(ByVal t As TimeSpan) As IFormatProvider
|
||||
Get
|
||||
Return If(t.Hours > 0, _ProviderWithHours, _Provider)
|
||||
Return If(t.Hours > 0 Or ForceHours, _ProviderWithHours, _Provider)
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub New(Optional ByVal ForceHours As Boolean = False)
|
||||
Me.ForceHours = ForceHours
|
||||
End Sub
|
||||
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
|
||||
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
|
||||
If Not IsNothing(Value) Then
|
||||
|
||||
@@ -33,6 +33,7 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.BTT_CLEAR_DONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CLEAR_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SELECT_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_SELECT_NONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.TOOLBAR_BOTTOM = New System.Windows.Forms.StatusStrip()
|
||||
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
|
||||
Me.LBL_INFO = New System.Windows.Forms.ToolStripStatusLabel()
|
||||
@@ -43,6 +44,7 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.MENU_ADD = New System.Windows.Forms.ToolStripDropDownButton()
|
||||
Me.BTT_ADD = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
|
||||
Me.BTT_ADD_PLS_ARR = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
|
||||
Me.BTT_FILTER = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_DOWN = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_STOP = New System.Windows.Forms.ToolStripButton()
|
||||
Me.SEP_LOG = New System.Windows.Forms.ToolStripSeparator()
|
||||
@@ -50,7 +52,7 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.BTT_INFO = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_BUG_REPORT = New System.Windows.Forms.ToolStripButton()
|
||||
Me.BTT_SELECT_NONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.SEP_FILTER = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_3 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_DEL_CLEAR = New System.Windows.Forms.ToolStripDropDownButton()
|
||||
@@ -134,6 +136,12 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.BTT_SELECT_ALL.Size = New System.Drawing.Size(185, 22)
|
||||
Me.BTT_SELECT_ALL.Text = "Select all"
|
||||
'
|
||||
'BTT_SELECT_NONE
|
||||
'
|
||||
Me.BTT_SELECT_NONE.Name = "BTT_SELECT_NONE"
|
||||
Me.BTT_SELECT_NONE.Size = New System.Drawing.Size(185, 22)
|
||||
Me.BTT_SELECT_NONE.Text = "Select none"
|
||||
'
|
||||
'TOOLBAR_BOTTOM
|
||||
'
|
||||
Me.TOOLBAR_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_MAIN, Me.LBL_INFO})
|
||||
@@ -169,7 +177,7 @@ Namespace DownloadObjects.STDownloader
|
||||
'TOOLBAR_TOP
|
||||
'
|
||||
Me.TOOLBAR_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||
Me.TOOLBAR_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_SETTINGS, Me.SEP_1, Me.MENU_ADD, SEP_2, Me.BTT_DOWN, Me.BTT_STOP, SEP_3, MENU_DEL_CLEAR, Me.SEP_LOG, Me.BTT_LOG, Me.BTT_INFO, Me.BTT_DONATE, Me.BTT_BUG_REPORT})
|
||||
Me.TOOLBAR_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_SETTINGS, Me.SEP_1, Me.MENU_ADD, Me.SEP_FILTER, Me.BTT_FILTER, SEP_2, Me.BTT_DOWN, Me.BTT_STOP, SEP_3, MENU_DEL_CLEAR, Me.SEP_LOG, Me.BTT_LOG, Me.BTT_INFO, Me.BTT_DONATE, Me.BTT_BUG_REPORT})
|
||||
Me.TOOLBAR_TOP.Location = New System.Drawing.Point(0, 0)
|
||||
Me.TOOLBAR_TOP.Name = "TOOLBAR_TOP"
|
||||
Me.TOOLBAR_TOP.Size = New System.Drawing.Size(584, 25)
|
||||
@@ -222,6 +230,15 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.BTT_ADD_PLS_ARR.Text = "Add URL array"
|
||||
Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" &
|
||||
"dd without downloading."
|
||||
'
|
||||
'BTT_FILTER
|
||||
'
|
||||
Me.BTT_FILTER.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
|
||||
Me.BTT_FILTER.Image = CType(resources.GetObject("BTT_FILTER.Image"), System.Drawing.Image)
|
||||
Me.BTT_FILTER.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
Me.BTT_FILTER.Name = "BTT_FILTER"
|
||||
Me.BTT_FILTER.Size = New System.Drawing.Size(23, 22)
|
||||
Me.BTT_FILTER.Text = "Filter"
|
||||
'
|
||||
'BTT_DOWN
|
||||
'
|
||||
@@ -286,11 +303,10 @@ Namespace DownloadObjects.STDownloader
|
||||
Me.BTT_BUG_REPORT.Size = New System.Drawing.Size(23, 22)
|
||||
Me.BTT_BUG_REPORT.Text = "Bug report"
|
||||
'
|
||||
'BTT_SELECT_NONE
|
||||
'SEP_FILTER
|
||||
'
|
||||
Me.BTT_SELECT_NONE.Name = "BTT_SELECT_NONE"
|
||||
Me.BTT_SELECT_NONE.Size = New System.Drawing.Size(185, 22)
|
||||
Me.BTT_SELECT_NONE.Text = "Select none"
|
||||
Me.SEP_FILTER.Name = "SEP_FILTER"
|
||||
Me.SEP_FILTER.Size = New System.Drawing.Size(6, 25)
|
||||
'
|
||||
'VideoListForm
|
||||
'
|
||||
@@ -337,5 +353,7 @@ Namespace DownloadObjects.STDownloader
|
||||
Private WithEvents BTT_CLEAR_SELECTED As ToolStripMenuItem
|
||||
Private WithEvents BTT_SELECT_ALL As ToolStripMenuItem
|
||||
Private WithEvents BTT_SELECT_NONE As ToolStripMenuItem
|
||||
Public WithEvents BTT_FILTER As ToolStripButton
|
||||
Public WithEvents SEP_FILTER As ToolStripSeparator
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -130,30 +130,31 @@
|
||||
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
HR8AAAAASUVORK5CYII=
|
||||
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
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="MENU_DEL_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -162,88 +163,91 @@
|
||||
<data name="BTT_CLEAR_SELECTED.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
HR8AAAAASUVORK5CYII=
|
||||
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
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
HR8AAAAASUVORK5CYII=
|
||||
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
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="MENU_DEL_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -252,30 +256,31 @@
|
||||
<data name="MENU_DEL_CLEAR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
dCWdzmEAAAAASUVORK5CYII=
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAV8SURBVEhLjZVrTFNnGMcf3wpbR8+4dKjJgDnEAQLl0lJO
|
||||
3TTcpWjBFgQZI2JGLeNeLBCpgRBNNIjJkn3YPmwftsxkxi3RZdmYMCBDgagM3GBBLg6wlNIrlLklC/RZ
|
||||
3q7tpoLjn5ycNuec3///Ps97AQCA0YwMn97Q0I/7du2auhkS8tHhoKBXAWA7ffZ/mhSL2d9CQvqnd+4c
|
||||
uR4Wlg8APgCwzfPCWEUF725GxpeTTU04e/kyjms0jpss25PEMHsBwOsJ2lOaEArf0hcVzdnb23G1owOn
|
||||
CgosH0REVIb4+vp7THr27PnwQX09Pmxrw9nWVtS1t+N8YyN2smy/gGHe2MxkWiJJ1RcVzdsvXUJ7Wxva
|
||||
tVpcbWnBBzKZ9eugoPcBIMBZhT4+X0fhDzUanGtuRl1LCy5euIBTTU2Om2LxrRiGCX/aZFIsztQXFupo
|
||||
cgpf1WrR3tCAq42NaCspwd7AwHEAYAGAge7g4CtTZWU4q9HgvEaDujNnUK/V4tL58zij0Ti6WXYwmseL
|
||||
cJtMJiRkLhYU6FYuXkR7SwuuNjejXaPBVbUal8vLsVMsNp3g868BQLZzFIrdu1/rFIn6x06edDxSq3FB
|
||||
rcbFhgZcampCc2srGk+fxj6WHYzn8SJ/EgozFvLz9SvnzjlLYm9sRHt9Pdpra3GlvBx74+Mt4VzuZwCg
|
||||
BACBq+HgJeTzIzpFosH5EydQX12NhqoqXKqrQ5NajVatFmerqhxDEsn9mdxcnf3sWWdiu1qN9upqtFdW
|
||||
euCRXO4VACgDgCgXnLjL6h0fEBD5fULCwGRxscOgUqFRpUJzRQVaKivRVleHtpoaXKmvxxUKrqtDe03N
|
||||
P/CyMhwQiawCHo/CafJ9APDiE1PVbSIOCNjXHRs7qD92DI2lpWguLUWrUom28nJcVqlwuaQEl3Nz0ZaS
|
||||
gjaJBC0SCQ4kJdniGOYqAJxyJeduBHfLO9HfP6pbIBicTk9fsxw/jmapFM1CIZqCgtDEMGjy8kITh4Oz
|
||||
PJ6jKzTUyvr50YaqACAaAF56HtwtZ7nuCgSjiwyDBg4HlzgcNHI4TrDz2r4dR2Jj/8yPiPgWAN4DgJit
|
||||
wp3Sl5RU6CWSeQOX+yzcZTgVFrbWK5PNRAYH5wKA75bhNqXytCktzWRgmE3hCxwOznE4OB8VhSNy+fjb
|
||||
+/fHPb0YN5RZqdQaDx0yG3x8noEbvbyc5aLwWToCQnCMEByNi3OM5uX9ms+ytEybm1hPnWpeysqybJTc
|
||||
yOfjo6ysv2bCwx0UPumCDxOCA4TgHaFwfZSOZDMTq1KpNaSlWQ08nhP8RFl27MCJ7Ozfzx08ODR85Mji
|
||||
fGQk/kII3iMEbxOCPxKCvYTgYGLi+p38/PtpAgHdIP/d6i1lZU0UvrQRPDAQJ1JTH1cKhd0AUJUVHf3O
|
||||
eE7OzERUlAfeQwh2EYKdhGC/WLw+lJc3/KlMRhvv7Wy85ehR3ZKf37Nwmjw19bEqIaELACoAgDYyoC45
|
||||
+c0RhWL6fkyMB/4dIfgNIXiD9iQxce2eQvEAAHY7TQxy+YQlJGTD5BVC4Q8AUOmCu08qb3V6OjuSlzd9
|
||||
KybG8V/4V9u24T2RaK1XKl0AgAwA8Ieh4uKiRanUbA4M9CQfy8z8o3pjuFvetcnJSaNy+dTd2Fi87oL3
|
||||
JiWtfyGVPsreu/cTjwHdmLoKCs7qcnKscyzrmEhJeVwrEvU8B+6Wt/LAgQRajn6WdfRJJOvXpNKFl7nc
|
||||
DgCQe0pEPxaGhvoOKxSfP8zJMV5NTx8mhNQCgBAAeJvA3fK+UVj47s9y+cJtmcyUFR5OzwIFAAS5pqvn
|
||||
W/rDDwBEAHDYdd/q8n8BAOjUpDPnCAC8vuFaAACOKzE9rOmd/t+KaAi6/7/iuqihJ9jfOenaM1O34/0A
|
||||
AAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TOOLBAR_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
@@ -287,105 +292,123 @@
|
||||
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANoSURBVEhLrZVrSFNhGMePTbwkzoVlzUuUZdkizzIvFE5r
|
||||
K51a0bzU8kYXp2W4El1SGdL1axh9iz5IRPQljD51gUyitIvOOjNdytxNZ4Hh9xP/nvc0yQ+iYeeBPwze
|
||||
l//veZ/3/55xi1VYh6Iz/LYC84mtBbctvZiRxq4R9QM67BvUwSiQHDqUuwwSJLht6SUBPmvE5T0clO84
|
||||
xH7gkPApFBZfkYwAQSPG9HJY9SEE6wbCoRWUOB8olRfAOk+2hyN9KAa7h1fj+o8q+QA8AZLtEcgcUqHA
|
||||
GU/z34iO6Tr5ACcIkOFQociZgIrxzahza3FvxiofoFlIE43fElHt3oIGTzqavbvwYMb2b4CFcj6r0td5
|
||||
v6rcqWj0ZKB1QocrgXx0/mzByoeRC0r9OKpT6tAwm3HKd/GwDiVOPWpcBWj0HsQFfzluBGrodwYu+nNx
|
||||
NVCAa1NGdE634P60TQLdnbbi1o9aXJ2qxHl/GY2wGA3uI1B3RUECMHPlW8p4H4fEgTC6VKWUFNNYMo67
|
||||
t+KsNxuXJvaQgRE3p4okwJXJfDLToc6jxeGxFBhG1oB3KJHUHwYV+RxxmP4CWOfMnC3yjmjarEZp0Pyc
|
||||
Lxttfj2uBYwEyMflST1s/hy6ix04Nq7BodH1yBuOwzYhGvEDoVC95xBJj7J0cA6geEiHtWSupQ4MTrUU
|
||||
Q4uHR5MvCxcndqONTC/482Dz5eCcNxP1tFbt1uDA6Drk0kkl8/5QsMfIzEOeczC9nwM46tyLnUOxFMNE
|
||||
VLpSYaXLbKGktJIhM2327ZLURKOqp5GwNO0fXYucr3HY8iUK6o8KRNOII7o5cM9IXQR4MwdwmnJuE7Ri
|
||||
u1BNOkmqJ9WRTpHOiHe+nybzLFjcPMzjm1A0moRWbw0KX+X9qhW2i1UCL5pJWhL/mfSJ1MeLEoDFdL6I
|
||||
zYptahdaRYsnDWZXCgrplNl02gaPWVpbUCymixXb2C40iYfpXgpGErCDXvQGeySOuUokk+C2pdcfQIOY
|
||||
PxIvfejY1zSWklLhDM74f+sPoFbc7ohBIiVlBcWZ/TeUzeb8f4uZWIVKMak/HCqK4fLXHBQvKCV2GQEn
|
||||
KGHMPII6X8Zi+JQAvTICKil+kdQ5Rw+Ie0J6RIAeGQFlX0zSSEx9JHpApm7SS7kAlGVmNK8WzTnH/Qao
|
||||
hKygM1JCJAAAAABJRU5ErkJggg==
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOLSURBVEhLrZVfTFNXHMePQvhjQ+nSTVcoxjH8d7dLO0XJ
|
||||
CFdc62hX1OwKKJM/cQ7K7AKTQCE6TSM6X43L3pY9NMuy7MWw7GlqohLjKM5S9dwOOkzpvS20M2Hx/Zjv
|
||||
cm9FkRjUcL/J7+mcfD8nJ59zLyEvSd7FnGD+dzl40ahrS/e/dtQiLsIxx4SAj+8KcFMBbklAc9ypQZbu
|
||||
f+1ogHscWzNKYPyTwHyboPROLrqSHh0BlGPFYwRv3V6FDRP5sFMjBtON+gLUk5dH8rEtWozdk+tw7mGb
|
||||
fgCecqw8UoAdURNcsRI0xytwcd6rH+Ao5ViVZIInVorDM5vhTdjx46Ne/QD99H3m/seK9sRW+ORt6Fdq
|
||||
8PMj/6sBlvN8YcRrdY/bElvQI1dhaFbAmXQ9gv8N4M1fCpcdyyVDUDuhc8FxSUDDpIADMQc64i70KPtx
|
||||
ItWMb9Md6FGqcDK1C8NpF85m3AjOD+Cneb8G+mG+FxcedmI404rBVBO8iQb4EodgGTFAA6jlxlsE5hCB
|
||||
dSIPNmrUTBEflOPzxHv4WqnGN7MfYTjjxvmMRwOcmavHYEqAV7bj4IONcE69DZtkRFk4D6YQwSFJfAZQ
|
||||
T66Wq4s2qQjOKQsan5QfT1bjVMqBs2k3hjP1OD3ngD9VC5+8HUdmOHw6/Q7qJteCp0UomciFaZygcJSg
|
||||
8e4iQENUwPpwHuySEc6YRdOwS7ahL7kTJ2d349ScAydSdfAna3Fc2YFu2Yb2BId90xuwa3JdtjycC/Ux
|
||||
quWrLhOI44sAn8X24MOoGZ6YFa3xLeiVqzCg1GAoWauV9idrtOlTqtEt2zWb9k6vR+3fa7H1vgGWv3JQ
|
||||
dIug4DoB+YOAjBCINxcBjlGO+WklC9B2FqBfsADtZgHqZQH6JQvQr9j3/x5Dn7ITXQkbWmY2wTNdhiGl
|
||||
A65rdY87qY21UZ61UJ5VUp7x93jG3+EZH+KZBlA1XarXc6qNGBCgQ6xLrkRLfCM+iVlRHTXDJ7doa8uO
|
||||
qunLkgX0sYPxCrimSrFdMuHdSCGOxA9kr2ClyQJ8rH6qRPvQqV9T8zjB4diTO15psoBO9oFUDGs4F2+E
|
||||
CNR/Q9OC5yuNWtJLW1lZOB+mMYI1NwhyrhCIER0BR2klU8sLRglWqxr+TiCO6QhopTwrvEFALhOQ3wjI
|
||||
rwTiqI6ApvuidiViSNQekHhdhHhVL8AlQ/Cp10vnFTz/HxZurHotmkteAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANqSURBVEhLrZVbSJNhGMe/mjhN1IWdpjPMssOitqklidPS
|
||||
cksrmufyQAcPZWSKzqEZUla3UXQXXYyI6CaMrjpcmEV5KF31zXQt5k42Cxbdf/Hveb8meSEa+j3wh8H7
|
||||
8v897/P+32/cQhV+U2aV35JhLrG10LbFFzNS29RC7qgeBz7oYeRJdj1KXXkiJLRt8SUCPqqFFf0cYt5y
|
||||
iBvmkPA+DHW+AgkBvFqIHeCwengZkkbl0PIxaA8USwfYTgDWebJNjtSxWOwdX4urP6qkA+gIkGyLwK4x
|
||||
BQyOeJr/JtwM1ksHOEWAdLsCBY4EHJ/cgnq3Fnd/NUkHaOW1gvGLCtXubWj0pKLVm4n7v8z/B5gv5zMq
|
||||
fZXzu8q9Fec96bBM6XE5kA/rzzasehA5r5SPoqxih3kzGad8F47rUeTIRY3LgPPeI+jwl+JaoIZ+p6PT
|
||||
n40rAQN6po2wBttwL2gWQXeCTbjxoxZXpivR7i+hERai0V0OZW8URAAzj3lDGR/koBoNh4ZiyJJi+pqM
|
||||
k+7tuODNwMWpfWRgxPXpAhFw+Vs+melR79Gi7GsK8ibWQWOPQeJIOBTkU243/QOwzpk5W9TYo2mzEsUh
|
||||
82ZfBrr8uegJGAmQj0vfcmH2Z9FdpOHEpBpHnRuQM74GO/hoxI+GQTHEIZIeZfGHWYDCMT3Wk7mWOshz
|
||||
KMUY1nk0aPHtRufUXnSRaYc/B2ZfFpq9u9BAa9VuNQ47k5BNJxXNR8LAHiMzX/aMg2loFuCYYz/2jMVR
|
||||
DFWodG1FE11mGyXFQobMtNWXKaqFRtVAI2FpOuRcj6zPa7DtUxSU72SIphFH9HHgnpJ6CfB6FuAs5dzM
|
||||
pwrdfDXpNKmBVE86Qzon3P5+lsx3o86tQcXkZhQ4E2Hx1qCwL+d3LZ8mVPE6oYKUStJ9JL0nDeoEEcBi
|
||||
OlfEZsQ2dfMWoc6zExWuFBykU2bQaRs9FeLavGIxXajYxm6+RSijezFMJCCNXvRGWyROuIpEk9C2xddf
|
||||
QKOQPxEvfujY1zSOknLcEZrxUusvoFbQ2WOhoqSspDiz/4aSmZwvtZhJE18pJI7IoaAYrnjJQfacUmKT
|
||||
EHCKEsbMI6jz5SyGTwgwICGgkuIXSZ1z9IC4x6SHBOiXEFDyySSOxDRIogdk6iO9kApAWWZGc2rBnHPc
|
||||
H0WkrMjY2947AAAAAElFTkSuQmCC
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOKSURBVEhLrZVfTFNXHMePg/DHhlLTqSsU41A3vUZPVZSM
|
||||
cMW1G9SyLV4BZfIn6qBoF5gECtG5NOK218Vlb8seGrMsvhjMnuaWTMiiFLVUPbdChym9t4V2Jiy+H/M1
|
||||
91Y2RhbUcL/J7+mcfD8nJ59zLyEvSN6lnGD+tzn4v9HWlu5/5WhFQkTgzgkR798T4WYi3LKIprhLhyzd
|
||||
/8rRAfcFvnqUwHyLwHqboPRuLjqTHgMBTODFYwRrb6/Cxol8OJgZA+kGYwHaycsj+dgdLcaByfX48nGr
|
||||
cQDKBF4eKcDeqAV1sRI0xTfj0rzXOMBJJvAK2QJPrBTHZt6GN+HAD096jAP0sZ3c/acdbYlt8Cm70adW
|
||||
4ccn/pcDLOf5wjSM1DxtTWxFt1KBwVkRF9K1CP7dj9d/Klx2bFdNQf2ErgXHZRH1kyIOx5xoj9ehW/0I
|
||||
Z1NN+Crdjm61AudS+zGUrsPFjBvB+X5cnvfroO/ne/DN4w4MZVowkGqEN1EPX+IobMMm6ACt3HyTwBoi
|
||||
sE/kgTKzbor0qBwnEtvxmVqJz2ffxVDGja8zHh1wYa4WAykRXsWBI4+2wDX1BqhsRlk4D5YQwVFZ+heg
|
||||
nVwr1xapXATXlA0Nz8vPJCtxPuXExbQbQ5lafDHnhD9VDZ+yB8dnBByafhM1k+uwgxWhZCIXlnGCwlGC
|
||||
hnuLAPVRERvCeXDIZrhiNl3DToWiN7kP52YP4PycE2dTNfAnq3FG3YsuhaItIeDD6Y3YP7k+Wx7OhfYY
|
||||
tfJV1wmk8UWAj2Pv4Z2oFZ6YHS3xrehRKtCvVmEwWa2X9iWr9OlVK9GlOHSbPpjegOqH67DtgQm2Ozko
|
||||
uklQcIOA/EJAhgmkPxYBTjOB+5mDB1gbD7BPeIB18QDz8gA7xQPsU/7dX6fRq+5DZ4KieeYteKbLMKi2
|
||||
4+DvNU872C7eyihvZpQ7GOX0PuX0LuU0RLkO0DRdqtd/VBs2IcAGeaeyE83xLTgYs6MyaoVPadbXlh1N
|
||||
0xclC+jlR+KbUTdVij2yBZsihTgeP5y9gpUmC/Dx2qkS/UOnfU2t4wTHYs/veKXJAjr4LrkY9nAu1oQI
|
||||
tH9D44LnK41W0sNaeFk4H5YxgtUjBDm/EkgRAwEnmYNr5QWjBK9pGv5MII0ZCGhhlBeOEJDrBOQaAblC
|
||||
II0aCGh8IOlXIoUk/QFJNyRIvxkFuGoK/uP10nkJz58BqISsoFjBRioAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
QmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_FILTER.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
|
||||
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
|
||||
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
|
||||
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
|
||||
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
|
||||
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
|
||||
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
|
||||
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
|
||||
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
|
||||
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
bAAAAABJRU5ErkJggg==
|
||||
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
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFmSURBVFhH1dc/K4VhHMbxJ5EFEQbFiERKCotIrMJIiYEi
|
||||
pbwCZcOqJC9AikUWiqRkJYtSRDbESMT3V07dna7zHHru+9T51me+Ts//E+V7LRjFFAZRiZzUhDVc4/vX
|
||||
B47Rh6D14Aqp4XQ36ECQ2nALNezaQjG8Vo5DqMF0bxiA1+bwCTWoLMFbNTiDGsrkABXw0jDsKldDmdyj
|
||||
HokrwCrUSBz7wXbRJs4eLkdQI9m0I3ENeIAaiGN3QjMSZ4fxv+ffnKIKibOnmhqI84V5eMleOHY41VAm
|
||||
9k7wdgtW4wRqSHlCP7y2AjWmbMB7Y7DzqgZdz2iF9zrxCDXq2oU9uLz31+tgAcHahhp1DSFY9pGhRl29
|
||||
CFYXxrMoQ7BmsZfFPkoRpHWow+56hX26BWkRatR1gRIEaQLvUMMpOyhCkBpxBzWcMoOgLUMNm0vUIWj2
|
||||
ebaJF7jj5+hGTiqE/f+bxDRGUIt8LIp+AC/GHt3tQnwvAAAAAElFTkSuQmCC
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGTSURBVFhH1ZfPK21RGIaf5GaCCAPF0JVISWEiElNhSIkB
|
||||
RUr5C5QZpkryB0gxkQlFUjKlO1HKjcwQQyJatdXp7TtnH3t/Z+CpZ7be7z3tH2uvA7+cFmAUmAIGgSpd
|
||||
UCiagDXgCviMfAOOgT5d7E0P8C+jWL0GOjTkRRtwY5SqW0CJhtNSARwaZZYvwIAOSMsc8G6UZXNJB6Sh
|
||||
FjgzSnJ5AFTqoKQMR0+5luTyFmjQQUkoAlaNgjjDDw4PbWrC5nJkFORjuw5Lwl/gzhgeZ3gTmnVYEsJl
|
||||
/On9D54C1TosCWFX0+FxfgDzOigp4YMTLqeW5DJ8E9xewRrgxCjJ5gPQr0PSsmIUZXNDwx6MRfdVy9RH
|
||||
oFXDHnQC90ahuhttXO7k+xwsaNCTbaNQHdKQJ+GQoYVqr4Y86QLGYyzXkCezwF6M+0CZBr1YNy65+hwd
|
||||
3QrColGoXgClGvRiAng1SjPdAf5o0ItG4L9RmumMhrxZNkq/vQTqNeBNOJ5tAk9Sfg506+JCURz9/5sE
|
||||
poERoE4X/Rq+AC/GHt09Rk0KAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -39,6 +39,7 @@ Namespace DownloadObjects.STDownloader
|
||||
MyView = New FormView(Me)
|
||||
MyProgress = New MyProgress(TOOLBAR_BOTTOM, PR_MAIN, LBL_INFO)
|
||||
MyJob = New JobThread(Of MediaItem)
|
||||
BTT_FILTER.Image = My.Resources.FilterPic
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Form handlers"
|
||||
@@ -95,15 +96,18 @@ Namespace DownloadObjects.STDownloader
|
||||
Dim b As Boolean = True
|
||||
Select Case e.KeyCode
|
||||
Case Keys.Insert : BTT_ADD.PerformClick()
|
||||
Case Keys.F5 : BTT_DOWN.PerformClick()
|
||||
Case Keys.F5
|
||||
If e.Control Then LoadData(True) Else BTT_DOWN.PerformClick()
|
||||
Case Else : b = False
|
||||
End Select
|
||||
If b Then e.Handled = True
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Refill, save list"
|
||||
Protected Sub LoadData()
|
||||
Protected Sub LoadData(Optional ByVal ClearTable As Boolean = False)
|
||||
If ClearTable Then RemoveControls(,, False)
|
||||
Dim c As List(Of IYouTubeMediaContainer) = LoadData_GetFiles()
|
||||
If c.ListExists Then MyYouTubeSettings.FILTER.RemoveAll(c)
|
||||
If c.ListExists Then
|
||||
c.Sort(New ContainerDateComparer)
|
||||
SuspendLayout()
|
||||
@@ -332,6 +336,7 @@ Namespace DownloadObjects.STDownloader
|
||||
pForm.Dispose()
|
||||
End If
|
||||
If Not c Is Nothing Then
|
||||
If Not c.HasElements Then DirectCast(c, YouTubeMediaContainerBase).FileForceArtist()
|
||||
Dim f As Form
|
||||
Select Case c.ObjectType
|
||||
Case YouTubeMediaType.Single : f = New VideoOptionsForm(c) With {.UseCookies = useCookies}
|
||||
@@ -415,6 +420,12 @@ Namespace DownloadObjects.STDownloader
|
||||
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[VideoListForm.ValidateContainerURL]", True)
|
||||
End Try
|
||||
End Function
|
||||
Private Sub BTT_FILTER_Click(sender As Object, e As EventArgs) Handles BTT_FILTER.Click
|
||||
Using f As New FilterForm(LoadData_GetFiles)
|
||||
f.ShowDialog()
|
||||
If f.DialogResult = DialogResult.OK Or f.DialogResult = DialogResult.Abort Then LoadData(True)
|
||||
End Using
|
||||
End Sub
|
||||
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||
With TP_CONTROLS
|
||||
If .Controls.Count > 0 Then
|
||||
@@ -494,7 +505,8 @@ Namespace DownloadObjects.STDownloader
|
||||
Protected Sub CheckVersionImpl(ByVal Force As Boolean)
|
||||
CheckVersion(Force)
|
||||
End Sub
|
||||
Protected Overloads Sub RemoveControls(Optional ByVal Predicate As Predicate(Of MediaItem) = Nothing, Optional ByVal RemoveFiles As Boolean = False)
|
||||
Protected Overloads Sub RemoveControls(Optional ByVal Predicate As Predicate(Of MediaItem) = Nothing, Optional ByVal RemoveFiles As Boolean = False,
|
||||
Optional ByVal ProcessDelete As Boolean = True)
|
||||
ControlInvokeFast(TP_CONTROLS, Sub()
|
||||
With TP_CONTROLS
|
||||
If .Controls.Count > 0 Then
|
||||
@@ -509,7 +521,10 @@ Namespace DownloadObjects.STDownloader
|
||||
For i = rCnt.Count - 1 To 0 Step -1
|
||||
cnt = .Controls(rCnt(i))
|
||||
.Controls.RemoveAt(rCnt(i))
|
||||
If Not cnt.MyContainer Is Nothing Then cnt.MyContainer.Delete(RemoveFiles) : cnt.MyContainer.Dispose()
|
||||
If Not cnt.MyContainer Is Nothing Then
|
||||
If ProcessDelete Then cnt.MyContainer.Delete(RemoveFiles)
|
||||
cnt.MyContainer.Dispose()
|
||||
End If
|
||||
cnt.Dispose()
|
||||
Next
|
||||
End If
|
||||
|
||||
261
SCrawler.YouTube/Editors/BugReporterForm.Designer.vb
generated
261
SCrawler.YouTube/Editors/BugReporterForm.Designer.vb
generated
@@ -24,7 +24,6 @@ Namespace Editors
|
||||
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 ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(BugReporterForm))
|
||||
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
@@ -33,31 +32,32 @@ Namespace Editors
|
||||
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Me.BTT_EMAIL = New System.Windows.Forms.Button()
|
||||
Me.BTT_GITHUB = New System.Windows.Forms.Button()
|
||||
Me.BTT_COPY = New System.Windows.Forms.Button()
|
||||
Me.BTT_CANCEL = New System.Windows.Forms.Button()
|
||||
Me.BTT_ANON = New System.Windows.Forms.Button()
|
||||
Me.TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
Me.TXT_DESCR = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_URL_PROFILE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_URL_POST = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_REPRODUCE = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_EXPECT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TXT_LOG = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.BTT_EMAIL = New System.Windows.Forms.Button()
|
||||
Me.BTT_GITHUB = New System.Windows.Forms.Button()
|
||||
Me.BTT_COPY = New System.Windows.Forms.Button()
|
||||
Me.BTT_CANCEL = New System.Windows.Forms.Button()
|
||||
Me.BTT_ANON = New System.Windows.Forms.Button()
|
||||
Me.TXT_FILES = New PersonalUtilities.Forms.Controls.TextBoxExtended()
|
||||
Me.TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
|
||||
TP_MAIN.SuspendLayout()
|
||||
TP_BUTTONS.SuspendLayout()
|
||||
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_URL_PROFILE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_URL_POST, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_BUTTONS.SuspendLayout()
|
||||
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
@@ -88,6 +88,123 @@ Namespace Editors
|
||||
TP_MAIN.Size = New System.Drawing.Size(584, 461)
|
||||
TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TXT_DESCR
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton1.Name = "Clear"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_DESCR.Buttons.Add(ActionButton1)
|
||||
Me.TXT_DESCR.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_DESCR.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_DESCR.CaptionVisible = False
|
||||
Me.TXT_DESCR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_DESCR.GroupBoxed = True
|
||||
Me.TXT_DESCR.GroupBoxText = "Describe the bug or write your message"
|
||||
Me.TXT_DESCR.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_DESCR.Multiline = True
|
||||
Me.TXT_DESCR.Name = "TXT_DESCR"
|
||||
Me.TXT_DESCR.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_DESCR.TabIndex = 0
|
||||
Me.TXT_DESCR.TextToolTip = "A clear and concise description of what the bug is"
|
||||
Me.TXT_DESCR.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_URL_PROFILE
|
||||
'
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Name = "Clear"
|
||||
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_URL_PROFILE.Buttons.Add(ActionButton2)
|
||||
Me.TXT_URL_PROFILE.CaptionText = "Profile URL"
|
||||
Me.TXT_URL_PROFILE.CaptionWidth = 75.0R
|
||||
Me.TXT_URL_PROFILE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_URL_PROFILE.Location = New System.Drawing.Point(3, 78)
|
||||
Me.TXT_URL_PROFILE.Name = "TXT_URL_PROFILE"
|
||||
Me.TXT_URL_PROFILE.Size = New System.Drawing.Size(578, 22)
|
||||
Me.TXT_URL_PROFILE.TabIndex = 1
|
||||
'
|
||||
'TXT_URL_POST
|
||||
'
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Name = "Clear"
|
||||
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_URL_POST.Buttons.Add(ActionButton3)
|
||||
Me.TXT_URL_POST.CaptionText = "Post URL"
|
||||
Me.TXT_URL_POST.CaptionWidth = 75.0R
|
||||
Me.TXT_URL_POST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_URL_POST.Location = New System.Drawing.Point(3, 106)
|
||||
Me.TXT_URL_POST.Name = "TXT_URL_POST"
|
||||
Me.TXT_URL_POST.Size = New System.Drawing.Size(578, 22)
|
||||
Me.TXT_URL_POST.TabIndex = 2
|
||||
'
|
||||
'TXT_REPRODUCE
|
||||
'
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton4.Name = "Clear"
|
||||
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_REPRODUCE.Buttons.Add(ActionButton4)
|
||||
Me.TXT_REPRODUCE.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_REPRODUCE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_REPRODUCE.CaptionVisible = False
|
||||
Me.TXT_REPRODUCE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_REPRODUCE.GroupBoxed = True
|
||||
Me.TXT_REPRODUCE.GroupBoxText = "Steps to reproduce"
|
||||
Me.TXT_REPRODUCE.Location = New System.Drawing.Point(3, 134)
|
||||
Me.TXT_REPRODUCE.Multiline = True
|
||||
Me.TXT_REPRODUCE.Name = "TXT_REPRODUCE"
|
||||
Me.TXT_REPRODUCE.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_REPRODUCE.TabIndex = 3
|
||||
Me.TXT_REPRODUCE.TextToolTip = "Steps to reproduce the behavior:" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "1. Do something" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "2. See error"
|
||||
Me.TXT_REPRODUCE.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_EXPECT
|
||||
'
|
||||
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton5.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton5.Name = "Clear"
|
||||
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_EXPECT.Buttons.Add(ActionButton5)
|
||||
Me.TXT_EXPECT.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_EXPECT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_EXPECT.CaptionVisible = False
|
||||
Me.TXT_EXPECT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_EXPECT.GroupBoxed = True
|
||||
Me.TXT_EXPECT.GroupBoxText = "Expected behavior"
|
||||
Me.TXT_EXPECT.Location = New System.Drawing.Point(3, 209)
|
||||
Me.TXT_EXPECT.Multiline = True
|
||||
Me.TXT_EXPECT.Name = "TXT_EXPECT"
|
||||
Me.TXT_EXPECT.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_EXPECT.TabIndex = 4
|
||||
Me.TXT_EXPECT.TextToolTip = "A clear and concise description of what you expected to happen."
|
||||
Me.TXT_EXPECT.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_LOG
|
||||
'
|
||||
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton6.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton6.Name = "Open"
|
||||
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton6.ToolTipText = "Select log files to add their text to the message"
|
||||
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton7.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton7.Name = "Clear"
|
||||
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
ActionButton7.ToolTipText = "Empty"
|
||||
Me.TXT_LOG.Buttons.Add(ActionButton6)
|
||||
Me.TXT_LOG.Buttons.Add(ActionButton7)
|
||||
Me.TXT_LOG.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_LOG.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_LOG.CaptionVisible = False
|
||||
Me.TXT_LOG.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_LOG.GroupBoxed = True
|
||||
Me.TXT_LOG.GroupBoxText = "Log data"
|
||||
Me.TXT_LOG.Location = New System.Drawing.Point(3, 284)
|
||||
Me.TXT_LOG.Multiline = True
|
||||
Me.TXT_LOG.Name = "TXT_LOG"
|
||||
Me.TXT_LOG.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_LOG.TabIndex = 5
|
||||
'
|
||||
'TP_BUTTONS
|
||||
'
|
||||
TP_BUTTONS.ColumnCount = 6
|
||||
@@ -119,7 +236,7 @@ Namespace Editors
|
||||
Me.BTT_EMAIL.Name = "BTT_EMAIL"
|
||||
Me.BTT_EMAIL.Size = New System.Drawing.Size(94, 24)
|
||||
Me.BTT_EMAIL.TabIndex = 1
|
||||
Me.BTT_EMAIL.Text = "email"
|
||||
Me.BTT_EMAIL.Text = "Email"
|
||||
Me.TT_MAIN.SetToolTip(Me.BTT_EMAIL, "Create a message to send via email.")
|
||||
Me.BTT_EMAIL.UseVisualStyleBackColor = True
|
||||
'
|
||||
@@ -167,129 +284,6 @@ Namespace Editors
|
||||
Me.TT_MAIN.SetToolTip(Me.BTT_ANON, resources.GetString("BTT_ANON.ToolTip"))
|
||||
Me.BTT_ANON.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TXT_DESCR
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton1.Name = "Clear"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_DESCR.Buttons.Add(ActionButton1)
|
||||
Me.TXT_DESCR.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_DESCR.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_DESCR.CaptionVisible = False
|
||||
Me.TXT_DESCR.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_DESCR.GroupBoxed = True
|
||||
Me.TXT_DESCR.GroupBoxText = "Describe the bug or write your message"
|
||||
Me.TXT_DESCR.Lines = New String(-1) {}
|
||||
Me.TXT_DESCR.Location = New System.Drawing.Point(3, 3)
|
||||
Me.TXT_DESCR.Multiline = True
|
||||
Me.TXT_DESCR.Name = "TXT_DESCR"
|
||||
Me.TXT_DESCR.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_DESCR.TabIndex = 0
|
||||
Me.TXT_DESCR.TextToolTip = "A clear and concise description of what the bug is"
|
||||
Me.TXT_DESCR.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_URL_PROFILE
|
||||
'
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Name = "Clear"
|
||||
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_URL_PROFILE.Buttons.Add(ActionButton2)
|
||||
Me.TXT_URL_PROFILE.CaptionText = "Profile URL"
|
||||
Me.TXT_URL_PROFILE.CaptionWidth = 75.0R
|
||||
Me.TXT_URL_PROFILE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_URL_PROFILE.Lines = New String(-1) {}
|
||||
Me.TXT_URL_PROFILE.Location = New System.Drawing.Point(3, 78)
|
||||
Me.TXT_URL_PROFILE.Name = "TXT_URL_PROFILE"
|
||||
Me.TXT_URL_PROFILE.Size = New System.Drawing.Size(578, 22)
|
||||
Me.TXT_URL_PROFILE.TabIndex = 1
|
||||
'
|
||||
'TXT_URL_POST
|
||||
'
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Name = "Clear"
|
||||
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_URL_POST.Buttons.Add(ActionButton3)
|
||||
Me.TXT_URL_POST.CaptionText = "Post URL"
|
||||
Me.TXT_URL_POST.CaptionWidth = 75.0R
|
||||
Me.TXT_URL_POST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_URL_POST.Lines = New String(-1) {}
|
||||
Me.TXT_URL_POST.Location = New System.Drawing.Point(3, 106)
|
||||
Me.TXT_URL_POST.Name = "TXT_URL_POST"
|
||||
Me.TXT_URL_POST.Size = New System.Drawing.Size(578, 22)
|
||||
Me.TXT_URL_POST.TabIndex = 2
|
||||
'
|
||||
'TXT_REPRODUCE
|
||||
'
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton4.Name = "Clear"
|
||||
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_REPRODUCE.Buttons.Add(ActionButton4)
|
||||
Me.TXT_REPRODUCE.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_REPRODUCE.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_REPRODUCE.CaptionVisible = False
|
||||
Me.TXT_REPRODUCE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_REPRODUCE.GroupBoxed = True
|
||||
Me.TXT_REPRODUCE.GroupBoxText = "To Reproduce"
|
||||
Me.TXT_REPRODUCE.Lines = New String(-1) {}
|
||||
Me.TXT_REPRODUCE.Location = New System.Drawing.Point(3, 134)
|
||||
Me.TXT_REPRODUCE.Multiline = True
|
||||
Me.TXT_REPRODUCE.Name = "TXT_REPRODUCE"
|
||||
Me.TXT_REPRODUCE.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_REPRODUCE.TabIndex = 3
|
||||
Me.TXT_REPRODUCE.TextToolTip = "Steps to reproduce the behavior:" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "1. Do something" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "2. See error"
|
||||
Me.TXT_REPRODUCE.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_EXPECT
|
||||
'
|
||||
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton5.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton5.Name = "Clear"
|
||||
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
Me.TXT_EXPECT.Buttons.Add(ActionButton5)
|
||||
Me.TXT_EXPECT.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_EXPECT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_EXPECT.CaptionVisible = False
|
||||
Me.TXT_EXPECT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_EXPECT.GroupBoxed = True
|
||||
Me.TXT_EXPECT.GroupBoxText = "Expected behavior"
|
||||
Me.TXT_EXPECT.Lines = New String(-1) {}
|
||||
Me.TXT_EXPECT.Location = New System.Drawing.Point(3, 209)
|
||||
Me.TXT_EXPECT.Multiline = True
|
||||
Me.TXT_EXPECT.Name = "TXT_EXPECT"
|
||||
Me.TXT_EXPECT.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_EXPECT.TabIndex = 4
|
||||
Me.TXT_EXPECT.TextToolTip = "A clear and concise description of what you expected to happen."
|
||||
Me.TXT_EXPECT.TextToolTipEnabled = True
|
||||
'
|
||||
'TXT_LOG
|
||||
'
|
||||
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton6.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton6.Name = "Open"
|
||||
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
|
||||
ActionButton6.ToolTipText = "Select log files to add their text to the message"
|
||||
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton7.Dock = System.Windows.Forms.DockStyle.Top
|
||||
ActionButton7.Name = "Clear"
|
||||
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
|
||||
ActionButton7.ToolTipText = "Empty"
|
||||
Me.TXT_LOG.Buttons.Add(ActionButton6)
|
||||
Me.TXT_LOG.Buttons.Add(ActionButton7)
|
||||
Me.TXT_LOG.CaptionDock = System.Windows.Forms.DockStyle.Top
|
||||
Me.TXT_LOG.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.None
|
||||
Me.TXT_LOG.CaptionVisible = False
|
||||
Me.TXT_LOG.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_LOG.GroupBoxed = True
|
||||
Me.TXT_LOG.GroupBoxText = "Log data"
|
||||
Me.TXT_LOG.Lines = New String(-1) {}
|
||||
Me.TXT_LOG.Location = New System.Drawing.Point(3, 284)
|
||||
Me.TXT_LOG.Multiline = True
|
||||
Me.TXT_LOG.Name = "TXT_LOG"
|
||||
Me.TXT_LOG.Size = New System.Drawing.Size(578, 69)
|
||||
Me.TXT_LOG.TabIndex = 5
|
||||
'
|
||||
'TXT_FILES
|
||||
'
|
||||
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
|
||||
@@ -310,7 +304,6 @@ Namespace Editors
|
||||
Me.TXT_FILES.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TXT_FILES.GroupBoxed = True
|
||||
Me.TXT_FILES.GroupBoxText = "Files"
|
||||
Me.TXT_FILES.Lines = New String(-1) {}
|
||||
Me.TXT_FILES.Location = New System.Drawing.Point(3, 359)
|
||||
Me.TXT_FILES.Multiline = True
|
||||
Me.TXT_FILES.Name = "TXT_FILES"
|
||||
@@ -332,13 +325,13 @@ Namespace Editors
|
||||
Me.Name = "BugReporterForm"
|
||||
Me.Text = "New message"
|
||||
TP_MAIN.ResumeLayout(False)
|
||||
TP_BUTTONS.ResumeLayout(False)
|
||||
CType(Me.TXT_DESCR, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_URL_PROFILE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_URL_POST, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_REPRODUCE, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_EXPECT, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.TXT_LOG, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_BUTTONS.ResumeLayout(False)
|
||||
CType(Me.TXT_FILES, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
|
||||
@@ -124,60 +124,60 @@
|
||||
<data name="ActionButton1.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
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton2.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
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton6.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=
|
||||
wwAADsMBx2+oZAAAARlJREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbWujg3dATZPKYZC6BQhvw1AMkg3dP
|
||||
XQyl7WIyJIEW5CbS0/jKE5GwpCghgg9s6/8/y5Kj6DA45zcAwAAAezB6rjNnB4XX244NHt8wGs7wblop
|
||||
yRGxwZQBYKIfbn477EvqusY4jj2MgMpPiwav7l9UyYXmdrs9duzP4ApUmd72sfrxVsD33JQISyClvFUX
|
||||
w9nJssvJFei9CJUtgQ7394Du3YKLJaCbLMuwqips21ZNuDve/35X8J7nuRcMsVwsbYEQYlSWpRcMMR5P
|
||||
bAH9fU3TeMEQSZLYgsMpsDRNvXCIr89vWyCEeC6KwguGmL/ObYGU8oFOwA2ewwgYY9f6f7iUf3DGkTcu
|
||||
khP7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<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
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -195,31 +195,31 @@ If you would like a response from the developer, response, please add your conta
|
||||
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
|
||||
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
|
||||
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
|
||||
xAAADsQBlSsOGwAAAHpJREFUOE+1kVEKgDAMQ3e2/e+MXqpn6W/HxM7SpkIVB4HxSMKiTUTaFwVQ1X25
|
||||
DjMfSxskHBYsAxHJkjUjHgrUNMY4peaMPxb03rcZMVhgn2oDKAwn+L0aROH/Cny4NAGFSx8x+10ZDwV2
|
||||
gt+LOCxQsw1nPBS8VQBVTTzyhrdZSUm7AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -10,6 +10,7 @@ Imports System.Threading
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Tools.Web
|
||||
Imports PersonalUtilities.Functions.Messaging
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports SCrawler.DownloadObjects.STDownloader
|
||||
Public Module MainModShared
|
||||
Public Property BATCH As BatchExecutor
|
||||
@@ -135,9 +136,11 @@ Namespace Editors
|
||||
Public Shared Function GetProgramEnvirText(ByVal EnvirData As IDownloaderSettings, ByVal IsYouTube As Boolean) As String
|
||||
Try
|
||||
Dim output$ = String.Empty
|
||||
Dim verAfter As RParams = RParams.DM("\A\w\:\\.*", 0, EDP.ReturnValue)
|
||||
Using b As New BatchExecutor(True)
|
||||
Dim f As SFile
|
||||
Dim cmd$, ff$, vText$
|
||||
Dim ii%
|
||||
|
||||
For i% = 0 To IIf(IsYouTube, 1, 3)
|
||||
cmd = "--version"
|
||||
@@ -154,7 +157,17 @@ Namespace Editors
|
||||
Else
|
||||
b.Reset()
|
||||
b.Execute($"""{f}"" {cmd}", EDP.None)
|
||||
If b.OutputData.Count > 3 Then vText = b.OutputData(3) Else vText = "undefined"
|
||||
'If b.OutputData.Count > 3 Then vText = b.OutputData(3) Else vText = "undefined"
|
||||
|
||||
vText = String.Empty
|
||||
With b.OutputData
|
||||
If .Count > 0 Then
|
||||
ii = .FindIndex(Function(bb) Not CStr(RegexReplace(bb, verAfter)).IsEmptyString)
|
||||
If ii >= 0 And ii + 1 <= .Count - 1 Then vText = .Item(ii + 1)
|
||||
End If
|
||||
End With
|
||||
If vText.IsEmptyString Then vText = "undefined"
|
||||
|
||||
output.StringAppendLine($"{ff} version: {vText}")
|
||||
End If
|
||||
End If
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyVersion("2025.10.4.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.10.4.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
@@ -30,6 +30,11 @@ Namespace API.YouTube.Objects
|
||||
_File = CleanFileName(_File)
|
||||
End If
|
||||
End Sub
|
||||
Protected Friend Overrides Sub FileForceArtist()
|
||||
Dim __artistName$ = UserTitle.IfNullOrEmpty(AccountName)
|
||||
If Not _File.Name.IsEmptyString AndAlso Not _File.Name.ToLower.Contains(__artistName.ToLower) Then _
|
||||
_File.Name = $"{__artistName} - {_File.Name}"
|
||||
End Sub
|
||||
Public Overrides Function ToString(ByVal ForMediaItem As Boolean) As String
|
||||
Dim s$ = SizeStr
|
||||
If Not s.IsEmptyString Then s = $" [{s}]"
|
||||
|
||||
@@ -116,7 +116,9 @@ Namespace API.YouTube.Objects
|
||||
<XMLEC> Public Property IsShorts As Boolean = False Implements IYouTubeMediaContainer.IsShorts
|
||||
<XMLEC> Public Property ID As String Implements IYouTubeMediaContainer.ID, IUserMedia.PostID
|
||||
<XMLEC> Public Property Title As String Implements IDownloadableMedia.Title
|
||||
<XMLEC> Public Property Description As String Implements IYouTubeMediaContainer.Description
|
||||
<XMLEC> Public Property Description As String Implements IYouTubeMediaContainer.Description, IUserMedia.PostText
|
||||
Private Property IUserMedia_PostTextFile As String Implements IUserMedia.PostTextFile
|
||||
Private Property IUserMedia_PostTextFileSpecialFolder As Boolean Implements IUserMedia.PostTextFileSpecialFolder
|
||||
<XMLEC> Public Property PlaylistID As String Implements IYouTubeMediaContainer.PlaylistID
|
||||
<XMLEC> Public Property PlaylistTitle As String Implements IYouTubeMediaContainer.PlaylistTitle
|
||||
<XMLEC> Public Property UserID As String Implements IYouTubeMediaContainer.UserID
|
||||
@@ -354,6 +356,14 @@ Namespace API.YouTube.Objects
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Chapters, Trimming"
|
||||
Friend ReadOnly Property Chapters As List(Of TrimOption)
|
||||
Friend ReadOnly Property TrimOptions As List(Of TrimOption)
|
||||
Friend Property TrimDeleteOriginalFile As Boolean = False
|
||||
Friend Property TrimAddTrimmedFilesToM3U8 As Boolean = False
|
||||
Friend Property TrimSeparateFolder As Boolean = False
|
||||
Friend Property TrimOptionsSet As Boolean = False
|
||||
#End Region
|
||||
#Region "IUserMedia Support"
|
||||
<XMLEC> Private Property Attempts As Integer Implements IUserMedia.Attempts
|
||||
Private _Object As Object = Nothing
|
||||
@@ -682,6 +692,8 @@ Namespace API.YouTube.Objects
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Protected Friend Overridable Sub FileForceArtist()
|
||||
End Sub
|
||||
Friend Sub FileDateUpdate()
|
||||
Dim n$ = _File.Name.StringTrim
|
||||
Dim s$ = IIf(n.IsEmptyString, String.Empty, " ")
|
||||
@@ -736,6 +748,7 @@ Namespace API.YouTube.Objects
|
||||
#Region "Command"
|
||||
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
|
||||
Protected Const mp3 As String = "mp3"
|
||||
Private Const mp4 As String = "mp4"
|
||||
Private Const aac As String = "aac"
|
||||
Private Const ac3 As String = "ac3"
|
||||
Protected PostProcessing_AudioAC3 As Boolean = False
|
||||
@@ -771,7 +784,12 @@ Namespace API.YouTube.Objects
|
||||
'2023.3.4 -> 2023.7.6
|
||||
'cmd.StringAppend($"ba*[format_id={SelectedAudio.ID}]", "+")
|
||||
cmd.StringAppend(SelectedAudio.ID, "+")
|
||||
If OutputAudioCodec.StringToLower = ac3 Then
|
||||
If SelectedVideoIndex >= 0 And SelectedAudio.ProtocolType = Protocols.m3u8 And
|
||||
(SelectedAudio.Codec.StringToLower = mp4 Or OutputAudioCodec.StringToLower = mp4) Then
|
||||
PostProcessing_AudioAC3 = True
|
||||
formats.StringAppend($"--merge-output-format ""{mp4}{IIf(OutputVideoExtension.IsEmptyString, String.Empty, $"/{OutputVideoExtension.StringToLower}")}""", " ")
|
||||
atCodec = aac
|
||||
ElseIf OutputAudioCodec.StringToLower = ac3 Then
|
||||
PostProcessing_AudioAC3 = True
|
||||
formats.StringAppend($"--audio-format {aac}", " ")
|
||||
atCodec = aac
|
||||
@@ -815,9 +833,13 @@ Namespace API.YouTube.Objects
|
||||
'cmd = $"yt-dlp -f ""{cmd}"""
|
||||
'cmd = $"yt-dlp -f {cmd}"
|
||||
cmd = $"{YTDLP_NAME} -f {cmd}"
|
||||
If Not MyYouTubeSettings.ReplaceModificationDate Then cmd &= " --no-mtime"
|
||||
'yt-dlp 2025.07.21
|
||||
'If Not MyYouTubeSettings.ReplaceModificationDate Then cmd &= " --no-mtime"
|
||||
cmd &= $" --{IIf(MyYouTubeSettings.ReplaceModificationDate.Value, String.Empty, "no-")}mtime"
|
||||
If MyYouTubeSettings.DefaultVideoEmbedChapters Then cmd &= " --embed-chapters --add-chapters"
|
||||
cmd.StringAppend(formats, " ")
|
||||
cmd.StringAppend(subs, " ")
|
||||
If MyYouTubeSettings.ErrorsIgnore Then cmd &= " --no-abort-on-error --ignore-errors"
|
||||
cmd.StringAppend(YouTubeFunctions.GetCookiesCommand(WithCookies, YouTubeCookieNetscapeFile), " ")
|
||||
cmd &= $" {URL} -o ""{File.PathWithSeparator}{File.Name}"""
|
||||
File.Exists(SFO.Path, True)
|
||||
@@ -835,6 +857,8 @@ Namespace API.YouTube.Objects
|
||||
_Subtitles = New List(Of Subtitles)
|
||||
_SubtitlesDelegated = New List(Of Subtitles)
|
||||
SubtitlesSelectedIndexes = New List(Of Integer)
|
||||
Chapters = New List(Of TrimOption)
|
||||
TrimOptions = New List(Of TrimOption)
|
||||
MediaObjects = New List(Of MediaObject)
|
||||
_Files = New List(Of SFile)
|
||||
|
||||
@@ -1257,6 +1281,7 @@ Namespace API.YouTube.Objects
|
||||
Dim fPatternFiles$ = $"{File.Name}*." & "{0}"
|
||||
Dim fAacAudio As New TempFileConversion(New SFile(String.Format(fPattern, aac)), Me)
|
||||
Dim mp3ThumbEmbedded As Boolean = False
|
||||
Dim audioFiles As New List(Of SFile)
|
||||
|
||||
Dim tempFilesList As New List(Of TempFileConversion)
|
||||
Dim ttFile As TempFileConversion
|
||||
@@ -1364,13 +1389,17 @@ Namespace API.YouTube.Objects
|
||||
format = format.StringToLower
|
||||
f = String.Format(fPattern, format)
|
||||
AddFile(f)
|
||||
audioFiles.Add(f)
|
||||
If Not f.Exists Then
|
||||
tryToConvert.Invoke(format, f)
|
||||
updateBitrate(f)
|
||||
If format = mp3 And Not mp3ThumbEmbedded And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
||||
embedThumbTo.Invoke(f) : mp3ThumbEmbedded = True
|
||||
If Not M3U8_PlaylistFiles.ListExists AndAlso f.Exists Then M3U8_Append(f)
|
||||
If format = mp3 AndAlso f.Exists AndAlso MyYouTubeSettings.VideoPlaylist_AddExtractedMP3.Value Then M3U8_Append(f)
|
||||
If f.Exists Then
|
||||
If format = mp3 And Not mp3ThumbEmbedded And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
||||
embedThumbTo.Invoke(f) : mp3ThumbEmbedded = True
|
||||
If M3U8_PlaylistFiles.ListExists OrElse
|
||||
(format = mp3 AndAlso MyYouTubeSettings.VideoPlaylist_AddExtractedMP3.Value) Then _
|
||||
M3U8_Append(f)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
@@ -1423,6 +1452,43 @@ Namespace API.YouTube.Objects
|
||||
If OutputVideoFPS > 0 AndAlso SelectedVideo.Bitrate <> OutputVideoFPS Then _
|
||||
reencodeFile("ffmpeg -i ""{0}"" -filter:v fps=" & OutputVideoFPS.ToString.Replace(", ", ".") & " -c:a copy ""{1}""")
|
||||
End If
|
||||
|
||||
'Trimming
|
||||
If TrimOptions.Count > 0 AndAlso File.Exists Then
|
||||
Const trimCommand$ = "ffmpeg -i ""{0}"" -ss {1} -to {2} -c:v copy -c:a copy ""{3}"""
|
||||
Dim trimFirstFile As SFile = Nothing
|
||||
Dim trimFirstAdded As Boolean = False
|
||||
Dim processTrim As Action(Of TrimOption, SFile) =
|
||||
Sub(ByVal opt As TrimOption, ByVal pFile As SFile)
|
||||
Dim fNew As SFile = pFile
|
||||
fNew.Name &= $"_{opt.Name}"
|
||||
If TrimSeparateFolder Then fNew = $"{fNew.PathNoSeparator}\{MyYouTubeSettings.TrimSeparateFolderName.Value.IfNullOrEmpty(YouTubeSettings.TrimSeparateFolderNameDefault)}\{fNew.File}" : fNew.Exists(SFO.Path)
|
||||
format = fNew.Extension.StringToLower
|
||||
.Execute(String.Format(trimCommand,
|
||||
pFile,
|
||||
AConvert(Of String)(opt.StartTime, TimeToStringProvider),
|
||||
AConvert(Of String)(opt.EndTime, TimeToStringProvider),
|
||||
fNew))
|
||||
If fNew.Exists Then
|
||||
If trimFirstFile.IsEmptyString Then trimFirstFile = fNew
|
||||
AddFile(fNew)
|
||||
If format = mp3 And MyYouTubeSettings.DefaultAudioEmbedThumbnail_ExtractedFiles Then _
|
||||
embedThumbTo.Invoke(fNew) : mp3ThumbEmbedded = True
|
||||
If (TrimAddTrimmedFilesToM3U8 Or (TrimDeleteOriginalFile And Not trimFirstAdded)) AndAlso
|
||||
(M3U8_PlaylistFiles.ListExists OrElse
|
||||
(format = mp3 AndAlso MyYouTubeSettings.VideoPlaylist_AddExtractedMP3.Value)) Then _
|
||||
M3U8_Append(fNew) : trimFirstAdded = True
|
||||
End If
|
||||
End Sub
|
||||
For Each tr As TrimOption In TrimOptions
|
||||
processTrim(tr, File)
|
||||
If audioFiles.Count > 0 Then
|
||||
For Each f In audioFiles : processTrim(tr, f) : Next
|
||||
End If
|
||||
Next
|
||||
If TrimDeleteOriginalFile Then File.Delete() : File = trimFirstFile
|
||||
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
@@ -1650,12 +1716,20 @@ Namespace API.YouTube.Objects
|
||||
If Not tmpPls.IsEmptyString Then PlaylistTitle = tmpPls
|
||||
End If
|
||||
|
||||
Dim tmpTitle$
|
||||
UserID = .Value("uploader_id")
|
||||
UserTitle = TitleHtmlConverter.Invoke(.Value("uploader"))
|
||||
If Not UserTitle.IsEmptyString Then
|
||||
Dim tmpTitle$ = UserTitle.Replace("Topic", String.Empty).StringTrimEnd(" ", "-")
|
||||
tmpTitle = UserTitle.Replace("Topic", String.Empty).StringTrimEnd(" ", "-")
|
||||
If Not tmpTitle.IsEmptyString Then UserTitle = tmpTitle
|
||||
End If
|
||||
If MyYouTubeSettings.ParseLongUserTitle Or UserTitle.IsEmptyString Then
|
||||
tmpTitle = TitleHtmlConverter.Invoke(.Value("artist"))
|
||||
If Not tmpTitle.IsEmptyString Then
|
||||
If Not UserTitle.IsEmptyString AndAlso Not tmpTitle.Contains(UserTitle) Then tmpTitle = $"{UserTitle}, {tmpTitle}"
|
||||
UserTitle = ListAddList(Nothing, tmpTitle.Split(","), CType(Function(v$) v.StringTrim, Func(Of Object, Object)), EDP.ReturnValue).ListToString(" & ").IfNullOrEmpty(UserTitle)
|
||||
End If
|
||||
End If
|
||||
|
||||
Dim ext$ = IIf(IsMusic,
|
||||
MyYouTubeSettings.DefaultAudioCodecMusic.Value.StringToLower,
|
||||
@@ -1682,6 +1756,8 @@ Namespace API.YouTube.Objects
|
||||
ParseThumbnails(.Self)
|
||||
|
||||
ParseSubtitles(.Self)
|
||||
|
||||
ParseChapters(.Self)
|
||||
End With
|
||||
Return True
|
||||
End If
|
||||
@@ -1751,9 +1827,12 @@ Namespace API.YouTube.Objects
|
||||
If If(e({"formats"})?.Count, 0) > 0 Then
|
||||
Dim obj As MediaObject
|
||||
Dim nValue#
|
||||
Dim sValue$
|
||||
Dim sValue$ = String.Empty
|
||||
Dim allowWebm As Boolean = MyYouTubeSettings.DefaultVideoAllowWebm
|
||||
Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none"
|
||||
Dim validCodecValue As Func(Of String, Boolean) = Function(ByVal codec As String) As Boolean
|
||||
sValue = codec
|
||||
Return Not codec.IsEmptyString AndAlso Not codec = "none"
|
||||
End Function
|
||||
|
||||
For Each ee In e({"formats"})
|
||||
obj = New MediaObject With {
|
||||
@@ -1777,19 +1856,30 @@ Namespace API.YouTube.Objects
|
||||
If obj.Size <= 0 And obj.Bitrate > 0 And Duration.TotalSeconds > 0 Then _
|
||||
obj.Size = (obj.Bitrate / 8 * Duration.TotalSeconds).RoundVal(2)
|
||||
|
||||
sValue = ee.Value("vcodec")
|
||||
If validCodecValue(sValue) Then
|
||||
'sValue = ee.Value("vcodec")
|
||||
If validCodecValue(ee.Value("vcodec")) Then
|
||||
obj.Type = UMTypes.Video
|
||||
obj.Codec = sValue.Split(".").First
|
||||
If validCodecValue(ee.Value("acodec")) Then obj.Type = av
|
||||
ElseIf validCodecValue(ee.Value("acodec")) Then
|
||||
obj.Type = UMTypes.Audio
|
||||
obj.Codec = sValue.Split(".").First
|
||||
Else
|
||||
sValue = ee.Value("acodec")
|
||||
If validCodecValue(sValue) Then
|
||||
obj.Type = UMTypes.Audio
|
||||
obj.Codec = sValue.Split(".").First
|
||||
Else
|
||||
Continue For
|
||||
Dim fd As Boolean = False
|
||||
sValue = ee.Value("format_note")
|
||||
If Not sValue.IsEmptyString Then
|
||||
With ListAddList(Nothing, sValue.Split(","), CType(Function(v) CStr(v).StringToLower.StringTrim, Func(Of Object, Object)), EDP.ReturnValue)
|
||||
If .ListContains({"high", "low"}) Then
|
||||
obj.Type = UMTypes.Audio
|
||||
obj.Codec = ee.Value("ext")
|
||||
If obj.Protocol.StringToLower.StartsWith("m3u8") Then obj.Protocol = "m3u8"
|
||||
If obj.Bitrate <= 0 Then obj.Bitrate = IIf(.Contains("high"), 129, 53)
|
||||
If obj.Size <= 0 Then obj.Size = 1
|
||||
fd = True
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
If Not fd Then Continue For
|
||||
End If
|
||||
MediaObjects.Add(obj)
|
||||
Next
|
||||
@@ -1801,8 +1891,9 @@ Namespace API.YouTube.Objects
|
||||
Dim data As New List(Of MediaObject)(MediaObjects.Where(Function(mo) mo.Type = t And mo.Extension = webm))
|
||||
If data.Count > 0 Then
|
||||
Dim d As MediaObject = Nothing
|
||||
Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm
|
||||
Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
|
||||
Dim allWebm As Boolean = False, allAVC As Boolean = False
|
||||
Dim expWebm As Predicate(Of MediaObject) = Function(mo) Not allWebm And mo.Extension = webm
|
||||
Dim expAVC As Predicate(Of MediaObject) = Function(mo) Not allAVC And mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
|
||||
Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean, Boolean) =
|
||||
Function(mo, exp, isTrue, checkHttp) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width And
|
||||
(Not checkHttp OrElse mo.ProtocolType = Protocols.https)
|
||||
@@ -1810,6 +1901,8 @@ Namespace API.YouTube.Objects
|
||||
Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True, allowWebm)
|
||||
Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True, False)
|
||||
Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False, False)
|
||||
allWebm = data.All(FPredicate(Of MediaObject).ToFunc(expWebm))
|
||||
allAVC = data.All(FPredicate(Of MediaObject).ToFunc(expAVC))
|
||||
For Each d In data
|
||||
If MediaObjects.Count = 0 Then Exit For
|
||||
If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm)
|
||||
@@ -1930,6 +2023,15 @@ Namespace API.YouTube.Objects
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
Protected Sub ParseChapters(ByVal e As EContainer)
|
||||
With e({"chapters"})
|
||||
If .ListExists Then Chapters.AddRange(.Select(Function(ee) New TrimOption With {
|
||||
.Start = CInt(AConvert(Of Double)(ee.Value("start_time"), 0, EDP.ReturnValue)),
|
||||
.[End] = CInt(AConvert(Of Double)(ee.Value("end_time"), 0, EDP.ReturnValue)),
|
||||
.Name = CleanFileName(New SFile With {.Name = ee.Value("title")}).Name
|
||||
}))
|
||||
End With
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "IEContainerProvider Support"
|
||||
Private Function GetElementsChecked() As IEnumerable(Of EContainer)
|
||||
@@ -2004,6 +2106,8 @@ Namespace API.YouTube.Objects
|
||||
_Subtitles.Clear()
|
||||
_SubtitlesDelegated.Clear()
|
||||
SubtitlesSelectedIndexes.Clear()
|
||||
Chapters.Clear()
|
||||
TrimOptions.Clear()
|
||||
MediaObjects.Clear()
|
||||
_Files.Clear()
|
||||
PostProcessing_OutputAudioFormats.Clear()
|
||||
|
||||
@@ -124,12 +124,37 @@
|
||||
<Compile Include="Controls\ChannelTabsChooserForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ChaptersForm.Designer.vb">
|
||||
<DependentUpon>ChaptersForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\ChaptersForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\FilterForm.Designer.vb">
|
||||
<DependentUpon>FilterForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\FilterForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\PlayListParserForm.Designer.vb">
|
||||
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\PlayListParserForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\TrimOptionForm.Designer.vb">
|
||||
<DependentUpon>TrimOptionForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\TrimOptionForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\VideoOptionsTrimForm.Designer.vb">
|
||||
<DependentUpon>VideoOptionsTrimForm.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\VideoOptionsTrimForm.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Controls\YTDataFilter.vb" />
|
||||
<Compile Include="Downloader\DownloadLocationsCollection.vb" />
|
||||
<Compile Include="Downloader\IDownloaderSettings.vb" />
|
||||
<Compile Include="Downloader\Notificator.vb" />
|
||||
@@ -220,9 +245,21 @@
|
||||
<EmbeddedResource Include="Controls\ChannelTabsChooserForm.resx">
|
||||
<DependentUpon>ChannelTabsChooserForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Controls\ChaptersForm.resx">
|
||||
<DependentUpon>ChaptersForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Controls\FilterForm.resx">
|
||||
<DependentUpon>FilterForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Controls\PlayListParserForm.resx">
|
||||
<DependentUpon>PlayListParserForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Controls\TrimOptionForm.resx">
|
||||
<DependentUpon>TrimOptionForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Controls\VideoOptionsTrimForm.resx">
|
||||
<DependentUpon>VideoOptionsTrimForm.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Downloader\MediaItem.resx">
|
||||
<DependentUpon>MediaItem.vb</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.2.25.0")>
|
||||
<Assembly: AssemblyVersion("2025.10.4.0")>
|
||||
<Assembly: AssemblyFileVersion("2025.10.4.0")>
|
||||
<Assembly: NeutralResourcesLanguage("en")>
|
||||
|
||||
14
SCrawler.sln
14
SCrawler.sln
@@ -29,6 +29,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Updater", "SCrawle
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Shared", "SCrawler.Shared\SCrawler.Shared.vbproj", "{DC634700-24C7-42DD-BF8F-87E6CC54E625}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PersonalUtilities.Images", "..\..\MyUtilities\PersonalUtilities.Images\PersonalUtilities.Images.vbproj", "{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -135,6 +137,18 @@ Global
|
||||
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x64.Build.0 = Release|x64
|
||||
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.ActiveCfg = Release|x86
|
||||
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.Build.0 = Release|x86
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|x64.Build.0 = Debug|x64
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Debug|x86.Build.0 = Debug|x86
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|x64.ActiveCfg = Release|x64
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|x64.Build.0 = Release|x64
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|x86.ActiveCfg = Release|x86
|
||||
{B7EF76A9-96F3-4C53-B252-0AB5F79B67B3}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -30,6 +30,13 @@ Namespace API.Base
|
||||
Friend Const UseMD5ComparisonToolTip As String = "Each image will be checked for existence using MD5"
|
||||
Friend Const UserNameChangeCaption As String = "UserName"
|
||||
Friend Const UserNameChangeToolTip As String = "If the user has changed their UserName, you can set a new name here. Not required for new users."
|
||||
|
||||
Friend Const DownloadTextCaption As String = "Download text"
|
||||
Friend Const DownloadTextTip As String = "Download text (if available) for posts with image and video" & vbCr & "If this checkbox is checked, the post text will be downloaded along with the file and saved under the same name but with the 'txt' extension."
|
||||
Friend Const DownloadTextPostsCaption As String = "Download text posts"
|
||||
Friend Const DownloadTextPostsTip As String = "Download text (if available) for text posts (no image and video)"
|
||||
Friend Const DownloadTextSpecialFolderCaption As String = "Text special folder"
|
||||
Friend Const DownloadTextSpecialFolderTip As String = "If checked, text files will be saved to a separate folder"
|
||||
Private Sub New()
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@@ -13,10 +13,34 @@ Namespace API.Base
|
||||
Friend Overridable Property SiteKey As String
|
||||
<PSetting(Address:=SettingAddress.User, Caption:=DN.UserNameChangeCaption, ToolTip:=DN.UserNameChangeToolTip)>
|
||||
Friend Overridable Property UserName As String = String.Empty
|
||||
<PSetting(Address:=SettingAddress.User, Caption:=DN.DownloadTextCaption, ToolTip:=DN.DownloadTextTip)>
|
||||
Friend Overridable Property DownloadText As Boolean = False
|
||||
<PSetting(Address:=SettingAddress.User, Caption:=DN.DownloadTextPostsCaption, ToolTip:=DN.DownloadTextPostsTip)>
|
||||
Friend Overridable Property DownloadTextPosts As Boolean = False
|
||||
<PSetting(Address:=SettingAddress.User, Caption:=DN.DownloadTextSpecialFolderCaption, ToolTip:=DN.DownloadTextSpecialFolderTip)>
|
||||
Friend Overridable Property DownloadTextSpecialFolder As Boolean = False
|
||||
Friend Sub New(ByVal u As UserDataBase)
|
||||
UserName = u.NameTrue(True)
|
||||
DownloadText = u.DownloadText
|
||||
DownloadTextPosts = u.DownloadTextPosts
|
||||
DownloadTextSpecialFolder = u.DownloadTextSpecialFolder
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettingsBase)
|
||||
DownloadText = s.DownloadText.Value
|
||||
DownloadTextPosts = s.DownloadTextPosts.Value
|
||||
DownloadTextSpecialFolder = s.DownloadTextSpecialFolder.Value
|
||||
End Sub
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
Protected _ApplyBase_Name As Boolean = True
|
||||
Protected _ApplyBase_Text As Boolean = True
|
||||
Friend Sub ApplyBase(ByRef u As UserDataBase)
|
||||
If _ApplyBase_Name Then u.NameTrue = UserName
|
||||
If _ApplyBase_Text Then
|
||||
u.DownloadText = DownloadText
|
||||
u.DownloadTextPosts = DownloadTextPosts
|
||||
u.DownloadTextSpecialFolder = DownloadTextSpecialFolder
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
43
SCrawler/API/Base/EditorExchangeOptionsBase_P.vb
Normal file
43
SCrawler/API/Base/EditorExchangeOptionsBase_P.vb
Normal file
@@ -0,0 +1,43 @@
|
||||
' Copyright (C) Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.Base
|
||||
Friend Interface IPSite
|
||||
Property QueryString As String
|
||||
End Interface
|
||||
Friend Class EditorExchangeOptionsBase_P : Inherits EditorExchangeOptionsBase : Implements IPSite
|
||||
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property UserName As String
|
||||
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadText As Boolean
|
||||
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadTextPosts As Boolean
|
||||
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property DownloadTextSpecialFolder As Boolean
|
||||
<PSetting(Address:=SettingAddress.User, Caption:="Query",
|
||||
ToolTip:="Query string. Don't change this field when creating a user! Change it only for the same request.")>
|
||||
Friend Property QueryString As String Implements IPSite.QueryString
|
||||
Friend Sub New()
|
||||
DisableBase()
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserDataBase)
|
||||
MyBase.New(u)
|
||||
DisableBase()
|
||||
If TypeOf u Is IPSite Then QueryString = DirectCast(u, IPSite).QueryString
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettingsBase)
|
||||
MyBase.New(s)
|
||||
DisableBase()
|
||||
End Sub
|
||||
Friend Overridable Sub Apply(ByRef u As IPSite)
|
||||
ApplyBase(u)
|
||||
u.QueryString = QueryString
|
||||
End Sub
|
||||
Protected Overridable Sub DisableBase()
|
||||
_ApplyBase_Name = False
|
||||
_ApplyBase_Text = False
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -57,6 +57,7 @@ Namespace API.Base
|
||||
Property FileExists As Boolean
|
||||
Property DownloadedPictures(ByVal Total As Boolean) As Integer
|
||||
Property DownloadedVideos(ByVal Total As Boolean) As Integer
|
||||
Property DownloadedTexts(ByVal Total As Boolean) As Integer
|
||||
ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer
|
||||
ReadOnly Property DownloadedInformation As String
|
||||
Property HasError As Boolean
|
||||
|
||||
@@ -14,6 +14,7 @@ Imports PersonalUtilities.Tools.Web.Cookies
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||
Imports DN = SCrawler.API.Base.DeclaredNames
|
||||
Namespace API.Base
|
||||
Friend MustInherit Class SiteSettingsBase : Implements ISiteSettings, IResponserContainer
|
||||
#Region "Declarations"
|
||||
@@ -69,6 +70,14 @@ Namespace API.Base
|
||||
_UserOptionsExists = Not t Is Nothing
|
||||
End Set
|
||||
End Property
|
||||
#Region "New user defaults"
|
||||
<PropertyOption(ControlText:=DN.DownloadTextCaption, ControlToolTip:=DN.DownloadTextTip, Category:=DN.CAT_UserDefs), PXML, PClonable>
|
||||
Friend Overridable Property DownloadText As PropertyValue
|
||||
<PropertyOption(ControlText:=DN.DownloadTextPostsCaption, ControlToolTip:=DN.DownloadTextPostsTip, Category:=DN.CAT_UserDefs), PXML, PClonable>
|
||||
Friend Overridable Property DownloadTextPosts As PropertyValue
|
||||
<PropertyOption(ControlText:=DN.DownloadTextSpecialFolderCaption, ControlToolTip:=DN.DownloadTextSpecialFolderTip, Category:=DN.CAT_UserDefs), PXML, PClonable>
|
||||
Friend Overridable Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "EnvironmentPrograms"
|
||||
Private Property CMDEncoding As String Implements ISiteSettings.CMDEncoding
|
||||
@@ -124,6 +133,9 @@ Namespace API.Base
|
||||
_Image = __Image
|
||||
Responser = New Responser With {.DeclaredError = EDP.ThrowException}
|
||||
SettingsVersion = New PropertyValue(0)
|
||||
DownloadText = New PropertyValue(False)
|
||||
DownloadTextPosts = New PropertyValue(False)
|
||||
DownloadTextSpecialFolder = New PropertyValue(True)
|
||||
UpdateResponserFile()
|
||||
End Sub
|
||||
Friend Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
|
||||
@@ -394,7 +406,7 @@ Namespace API.Base
|
||||
With c.GetParameters
|
||||
If .ListExists Then
|
||||
If .Count = 1 Then
|
||||
Return .Self()(0).ParameterType.GetInterfaces.ListIfNothing.Where(Function(i) i Is Me.GetType).Count = 1
|
||||
Return .Self()(0).ParameterType Is Me.GetType
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
@@ -412,7 +424,8 @@ Namespace API.Base
|
||||
End If
|
||||
End With
|
||||
If Not constructor Is Nothing Then
|
||||
If args > 0 AndAlso Not constructor.GetParameters()(0).ParameterType Is GetType(ISiteSettings) Then Throw New Exception
|
||||
If args > 0 AndAlso constructor.GetParameters()(0).ParameterType.GetInterface(GetType(ISiteSettings).Name) Is Nothing Then _
|
||||
Throw New Exception("Class Interface type is incompatible")
|
||||
If args = 0 Then Options = constructor.Invoke(Nothing) Else Options = constructor.Invoke({Me})
|
||||
End If
|
||||
If Options Is Nothing Then Options = Activator.CreateInstance(_UserOptionsType)
|
||||
|
||||
@@ -32,6 +32,8 @@ Namespace API.Base
|
||||
Private Const Name_MediaPostID As String = "ID"
|
||||
Private Const Name_MediaPostDate As String = "Date"
|
||||
Private Const Name_SpecialFolder As String = "SpecialFolder"
|
||||
Private Const Name_PostTextFile As String = "PostTextFile"
|
||||
Private Const Name_PostTextFileSpecialFolder As String = "PostTextFileSpecialFolder"
|
||||
#End Region
|
||||
Friend Enum Types As Integer
|
||||
Undefined = 0
|
||||
@@ -46,12 +48,25 @@ Namespace API.Base
|
||||
End Enum
|
||||
Friend Enum States As Integer : Unknown = 0 : Tried = 1 : Downloaded = 2 : Skipped = 3 : Missing = 4 : End Enum
|
||||
Friend [Type] As Types
|
||||
Friend ReadOnly Property IsVideoType As Boolean
|
||||
Get
|
||||
Return Type = Types.m3u8 Or Type = Types.Video Or Type = Types.VideoPre
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property IsAudioType As Boolean
|
||||
Get
|
||||
Return Type = Types.Audio Or Type = Types.AudioPre
|
||||
End Get
|
||||
End Property
|
||||
Friend URL_BASE As String
|
||||
Friend URL As String
|
||||
Friend MD5 As String
|
||||
Friend [File] As SFile
|
||||
Friend Post As UserPost
|
||||
Friend PictureOption As String
|
||||
Friend PostText As String
|
||||
Friend PostTextFile As SFile
|
||||
Friend PostTextFileSpecialFolder As Boolean
|
||||
Friend State As States
|
||||
Friend Attempts As Integer
|
||||
''' <summary>
|
||||
@@ -125,6 +140,30 @@ Namespace API.Base
|
||||
Post = New UserPost(Post.ID, PostDate)
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_PostText As String Implements IUserMedia.PostText
|
||||
Get
|
||||
Return PostText
|
||||
End Get
|
||||
Set(ByVal NewText As String)
|
||||
PostText = NewText
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_PostTextFile As String Implements IUserMedia.PostTextFile
|
||||
Get
|
||||
Return PostTextFile.ToString
|
||||
End Get
|
||||
Set(ByVal NewPostFile As String)
|
||||
If Not NewPostFile.IsEmptyString Then PostTextFile = New SFile(NewPostFile) Else PostTextFile = Nothing
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_PostTextFileSpecialFolder As Boolean Implements IUserMedia.PostTextFileSpecialFolder
|
||||
Get
|
||||
Return PostTextFileSpecialFolder
|
||||
End Get
|
||||
Set(ByVal IsSpecialFolder As Boolean)
|
||||
PostTextFileSpecialFolder = IsSpecialFolder
|
||||
End Set
|
||||
End Property
|
||||
Private Property IUserMedia_SpecialFolder As String Implements IUserMedia.SpecialFolder
|
||||
Get
|
||||
Return SpecialFolder
|
||||
@@ -171,6 +210,9 @@ Namespace API.Base
|
||||
SpecialFolder = m.SpecialFolder
|
||||
Attempts = m.Attempts
|
||||
Me.Object = m.Object
|
||||
PostText = m.PostText
|
||||
PostTextFile = m.PostTextFile
|
||||
PostTextFileSpecialFolder = m.PostTextFileSpecialFolder
|
||||
End Sub
|
||||
Friend Sub New(ByVal e As EContainer, ByVal UserInstance As IUserData)
|
||||
Type = e.Attribute(Name_MediaType).Value.FromXML(Of Integer)(CInt(Types.Undefined))
|
||||
@@ -180,6 +222,8 @@ Namespace API.Base
|
||||
URL_BASE = e.Value
|
||||
MD5 = e.Attribute(Name_MediaHash).Value
|
||||
File = e.Attribute(Name_MediaFile).Value
|
||||
PostTextFile = e.Attribute(Name_PostTextFile).Value
|
||||
PostTextFileSpecialFolder = e.Attribute(Name_PostTextFileSpecialFolder).Value.FromXML(Of Boolean)(False)
|
||||
|
||||
Dim vp As Boolean? = Nothing
|
||||
Dim upath$ = String.Empty
|
||||
@@ -194,7 +238,13 @@ Namespace API.Base
|
||||
SpecialFolder = e.Attribute(Name_SpecialFolder).Value
|
||||
If Not SpecialFolder.IsEmptyString Then upath &= $"{SpecialFolder}\"
|
||||
If vp.HasValue AndAlso vp.Value Then upath &= $"Video\"
|
||||
If Not upath.IsEmptyString Then File = $"{upath.CSFilePS}{File.File}"
|
||||
If Not upath.IsEmptyString Then
|
||||
File = $"{upath.CSFilePS}{File.File}"
|
||||
If Not PostTextFile.IsEmptyString Then
|
||||
PostTextFile = $"{upath.CSFilePS}{IIf(PostTextFileSpecialFolder, $"{UserDataBase.PostTextSpecialFolderDefault}\", String.Empty)}{PostTextFile.File}"
|
||||
If Type = Types.Text Then File = PostTextFile
|
||||
End If
|
||||
End If
|
||||
|
||||
Post = New UserPost With {
|
||||
.ID = e.Attribute(Name_MediaPostID).Value,
|
||||
@@ -234,7 +284,9 @@ Namespace API.Base
|
||||
New EAttribute(Name_MediaURL, URL),
|
||||
New EAttribute(Name_MediaHash, MD5),
|
||||
New EAttribute(Name_MediaFile, File.File),
|
||||
New EAttribute(Name_PostTextFile, PostTextFile.File),
|
||||
New EAttribute(Name_SpecialFolder, SpecialFolder),
|
||||
New EAttribute(Name_PostTextFileSpecialFolder, PostTextFileSpecialFolder.BoolToInteger),
|
||||
New EAttribute(Name_MediaPostID, Post.ID),
|
||||
New EAttribute(Name_MediaPostDate, AConvert(Of String)(Post.Date, DateTimeDefaultProvider, String.Empty))
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ Imports CookieUpdateModes = PersonalUtilities.Tools.Web.Cookies.CookieKeeper.Upd
|
||||
Namespace API.Base
|
||||
Friend MustInherit Class UserDataBase : Implements IUserData, IPluginContentProvider, IThrower
|
||||
Friend Const UserFileAppender As String = "User"
|
||||
Friend Const PostTextSpecialFolderDefault As String = "txt"
|
||||
#Region "Events"
|
||||
Private ReadOnly UserUpdatedEventHandlers As List(Of IUserData.UserUpdatedEventHandler)
|
||||
Friend Custom Event UserUpdated As IUserData.UserUpdatedEventHandler Implements IUserData.UserUpdated
|
||||
@@ -152,6 +153,9 @@ Namespace API.Base
|
||||
Private Const Name_IsSubscription As String = UserInfo.Name_IsSubscription
|
||||
Private Const Name_Temporary As String = "Temporary"
|
||||
Private Const Name_Favorite As String = "Favorite"
|
||||
Private Const Name_DownloadText As String = "DownloadText"
|
||||
Private Const Name_DownloadTextPosts As String = "DownloadTextPosts"
|
||||
Private Const Name_DownloadTextSpecialFolder As String = "DownloadTextSpecialFolder"
|
||||
Private Const Name_BackColor As String = "BackColor"
|
||||
Private Const Name_ForeColor As String = "ForeColor"
|
||||
Private Const Name_CreatedByChannel As String = "CreatedByChannel"
|
||||
@@ -167,6 +171,7 @@ Namespace API.Base
|
||||
|
||||
Private Const Name_VideoCount As String = "VideoCount"
|
||||
Private Const Name_PicturesCount As String = "PicturesCount"
|
||||
Private Const Name_TextCount As String = "TextCount"
|
||||
Private Const Name_LastUpdated As String = "LastUpdated"
|
||||
|
||||
Private Const Name_ScriptUse As String = "ScriptUse"
|
||||
@@ -247,7 +252,20 @@ Namespace API.Base
|
||||
#End Region
|
||||
#Region "User name, ID, exist, suspend, options"
|
||||
Friend User As UserInfo
|
||||
Private _IsSavedPosts As Boolean = False
|
||||
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
|
||||
Get
|
||||
Return _IsSavedPosts
|
||||
End Get
|
||||
Set(ByVal __IsSavedPosts As Boolean)
|
||||
_IsSavedPosts = __IsSavedPosts
|
||||
If _IsSavedPosts Then
|
||||
DownloadText = True
|
||||
DownloadTextPosts = True
|
||||
DownloadTextSpecialFolder = True
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Private _UserExists As Boolean = True
|
||||
Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists
|
||||
Get
|
||||
@@ -295,7 +313,16 @@ Namespace API.Base
|
||||
Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name))
|
||||
End Get
|
||||
End Property
|
||||
Friend Overridable Property ID As String = String.Empty Implements IUserData.ID, IPluginContentProvider.ID
|
||||
Private _ID As String = String.Empty
|
||||
Friend Property ID As String Implements IUserData.ID, IPluginContentProvider.ID
|
||||
Get
|
||||
Return _ID
|
||||
End Get
|
||||
Set(ByVal NewId As String)
|
||||
If Not _ID = NewId Then EnvirChanged(NewId)
|
||||
_ID = NewId
|
||||
End Set
|
||||
End Property
|
||||
Protected _FriendlyName As String = String.Empty
|
||||
Friend Overridable Property FriendlyName As String Implements IUserData.FriendlyName
|
||||
Get
|
||||
@@ -639,6 +666,9 @@ BlockNullPicture:
|
||||
Friend Overridable Property ReadyForDownload As Boolean = True Implements IUserData.ReadyForDownload
|
||||
Friend Property DownloadImages As Boolean = True Implements IUserData.DownloadImages
|
||||
Friend Property DownloadVideos As Boolean = True Implements IUserData.DownloadVideos
|
||||
Friend Overridable Property DownloadText As Boolean = False
|
||||
Friend Overridable Property DownloadTextPosts As Boolean = False
|
||||
Friend Overridable Property DownloadTextSpecialFolder As Boolean = True
|
||||
Friend Property DownloadMissingOnly As Boolean = False Implements IUserData.DownloadMissingOnly
|
||||
Private _IconBannerDownloaded As Boolean = False
|
||||
Friend WriteOnly Property IconBannerDownloaded As Boolean
|
||||
@@ -750,9 +780,23 @@ BlockNullPicture:
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Private _DownloadedTextsTotal As Integer = 0
|
||||
Private _DownloadedTextsSession As Integer = 0
|
||||
Friend Property DownloadedTexts(ByVal Total As Boolean) As Integer Implements IUserData.DownloadedTexts
|
||||
Get
|
||||
Return IIf(Total, _DownloadedTextsTotal, _DownloadedTextsSession)
|
||||
End Get
|
||||
Set(ByVal NewValue As Integer)
|
||||
If Total Then
|
||||
_DownloadedTextsTotal = NewValue
|
||||
Else
|
||||
_DownloadedTextsSession = NewValue
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
Friend Overridable ReadOnly Property DownloadedTotal(Optional ByVal Total As Boolean = True) As Integer Implements IUserData.DownloadedTotal
|
||||
Get
|
||||
Return DownloadedPictures(Total) + DownloadedVideos(Total)
|
||||
Return DownloadedPictures(Total) + DownloadedVideos(Total) + DownloadedTexts(Total)
|
||||
End Get
|
||||
End Property
|
||||
Friend ReadOnly Property DownloadedInformation As String Implements IUserData.DownloadedInformation
|
||||
@@ -963,9 +1007,13 @@ BlockNullPicture:
|
||||
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
|
||||
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
|
||||
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
|
||||
DownloadText = x.Value(Name_DownloadText).FromXML(Of Boolean)(IsSavedPosts)
|
||||
DownloadTextPosts = x.Value(Name_DownloadTextPosts).FromXML(Of Boolean)(IsSavedPosts)
|
||||
DownloadTextSpecialFolder = x.Value(Name_DownloadTextSpecialFolder).FromXML(Of Boolean)(True)
|
||||
_IconBannerDownloaded = x.Value(Name_IconBannerDownloaded).FromXML(Of Boolean)(False)
|
||||
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
|
||||
DownloadedPictures(True) = x.Value(Name_PicturesCount).FromXML(Of Integer)(0)
|
||||
DownloadedTexts(True) = x.Value(Name_TextCount).FromXML(Of Integer)(0)
|
||||
LastUpdated = AConvert(Of Date)(x.Value(Name_LastUpdated), ADateTime.Formats.BaseDateTime, Nothing)
|
||||
ScriptUse = x.Value(Name_ScriptUse).FromXML(Of Boolean)(False)
|
||||
ScriptData = x.Value(Name_ScriptData)
|
||||
@@ -1025,9 +1073,13 @@ BlockNullPicture:
|
||||
x.Add(Name_ReadyForDownload, ReadyForDownload.BoolToInteger)
|
||||
x.Add(Name_DownloadImages, DownloadImages.BoolToInteger)
|
||||
x.Add(Name_DownloadVideos, DownloadVideos.BoolToInteger)
|
||||
x.Add(Name_DownloadText, DownloadText.BoolToInteger)
|
||||
x.Add(Name_DownloadTextPosts, DownloadTextPosts.BoolToInteger)
|
||||
x.Add(Name_DownloadTextSpecialFolder, DownloadTextSpecialFolder.BoolToInteger)
|
||||
x.Add(Name_IconBannerDownloaded, _IconBannerDownloaded.BoolToInteger)
|
||||
x.Add(Name_VideoCount, DownloadedVideos(True))
|
||||
x.Add(Name_PicturesCount, DownloadedPictures(True))
|
||||
x.Add(Name_TextCount, DownloadedTexts(True))
|
||||
x.Add(Name_LastUpdated, AConvert(Of String)(LastUpdated, ADateTime.Formats.BaseDateTime, String.Empty))
|
||||
x.Add(Name_ScriptUse, ScriptUse.BoolToInteger)
|
||||
x.Add(Name_ScriptData, ScriptData)
|
||||
@@ -1192,7 +1244,8 @@ BlockNullPicture:
|
||||
Select Case Caller
|
||||
Case NameOf(UserExists) : If Not _EnvirUserExists = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
||||
Case NameOf(UserSuspended) : If Not _EnvirUserSuspended = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
|
||||
Case NameOf(NameTrue) : _EnvirChanged = True : _EnvirInvokeUserUpdated = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||
Case NameOf(NameTrue) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||
Case NameOf(ID) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||
Case Else : _EnvirChanged = True
|
||||
End Select
|
||||
End If
|
||||
@@ -1246,6 +1299,7 @@ BlockNullPicture:
|
||||
If Not DownloadImages Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.GIF Or m.Type = UTypes.Picture)
|
||||
If Not DownloadVideos Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.Video Or
|
||||
m.Type = UTypes.VideoPre Or m.Type = UTypes.m3u8)
|
||||
If Not DownloadTextPosts Then _TempMediaList.RemoveAll(Function(m) m.Type = UTypes.Text)
|
||||
If DownloadMissingOnly Then _TempMediaList.RemoveAll(Function(m) Not m.State = UStates.Missing)
|
||||
End If
|
||||
|
||||
@@ -1461,6 +1515,7 @@ BlockNullPicture:
|
||||
Data.DownloadState = UserMediaStates.Missing
|
||||
End If
|
||||
YouTube.Objects.YouTubeMediaContainerBase.Update(_ContentNew(0), Data)
|
||||
If _ContentNew.Count > 1 Then Data.Files.ListAddList(_ContentNew.Select(Function(cc) cc.File), LNC)
|
||||
If ResetTitle And Not _ContentNew(0).File.Name.IsEmptyString Then Data.Title = _ContentNew(0).File.Name
|
||||
Else
|
||||
Data.DownloadState = UserMediaStates.Missing
|
||||
@@ -1658,7 +1713,8 @@ BlockNullPicture:
|
||||
Dim dCount% = 0, dTotal% = 0
|
||||
ThrowAny(Token)
|
||||
If _ContentNew.Count > 0 Then
|
||||
_ContentNew.RemoveAll(Function(c) c.URL.IsEmptyString)
|
||||
_ContentNew.RemoveAll(Function(c) Not c.Type = UTypes.Text And c.URL.IsEmptyString)
|
||||
If Not DownloadText Or Not DownloadTextPosts Then _ContentNew.RemoveAll(Function(c) c.Type = UTypes.Text)
|
||||
If _ContentNew.Count > 0 Then
|
||||
If UseMD5Comparison Then LoadMD5()
|
||||
MyFile.Exists(SFO.Path)
|
||||
@@ -1667,7 +1723,8 @@ BlockNullPicture:
|
||||
Dim vsf As Boolean = SeparateVideoFolderF
|
||||
Dim __isVideo As Boolean
|
||||
Dim __interrupt As Boolean
|
||||
Dim f As SFile
|
||||
Dim postProcessWebp As Boolean
|
||||
Dim f As SFile, fTxt As SFile
|
||||
Dim v As UserMedia
|
||||
Dim __fileDeleted As Boolean
|
||||
Dim fileNumProvider As SFileNumbers = SFileNumbers.Default
|
||||
@@ -1681,18 +1738,20 @@ BlockNullPicture:
|
||||
ErrorsDescriber.Execute(EDP.SendToLog, file_del_ex)
|
||||
End Try
|
||||
End Sub
|
||||
Dim updateDownCount As Action = Sub()
|
||||
Dim __n% = IIf(__fileDeleted, -1, 1)
|
||||
If __isVideo Then
|
||||
v.Type = UTypes.Video
|
||||
DownloadedVideos(False) += __n
|
||||
ElseIf v.Type = UTypes.GIF Then
|
||||
DownloadedPictures(False) += __n
|
||||
Else
|
||||
v.Type = UTypes.Picture
|
||||
DownloadedPictures(False) += __n
|
||||
End If
|
||||
End Sub
|
||||
Dim updateDownCount As Action(Of Boolean) = Sub(ByVal forceText As Boolean)
|
||||
Dim __n% = IIf(__fileDeleted And Not forceText, -1, 1)
|
||||
If v.Type = UTypes.Text Or forceText Then
|
||||
DownloadedTexts(False) += __n
|
||||
ElseIf __isVideo Then
|
||||
v.Type = UTypes.Video
|
||||
DownloadedVideos(False) += __n
|
||||
ElseIf v.Type = UTypes.GIF Then
|
||||
DownloadedPictures(False) += __n
|
||||
Else
|
||||
v.Type = UTypes.Picture
|
||||
DownloadedPictures(False) += __n
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Using w As New OptionalWebClient(Me)
|
||||
If vsf Then CSFileP($"{MyDir}\{VideoFolderName}\").Exists(SFO.Path)
|
||||
@@ -1724,9 +1783,11 @@ BlockNullPicture:
|
||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||
|
||||
__fileDeleted = False
|
||||
postProcessWebp = False
|
||||
|
||||
If Not f.IsEmptyString And Not v.URL.IsEmptyString Then
|
||||
If (v.Type = UTypes.Text And DownloadText) Or (Not f.IsEmptyString And Not v.URL.IsEmptyString) Then
|
||||
Try
|
||||
If v.Type = UTypes.Text Then GoTo stxt
|
||||
__isVideo = v.Type = UTypes.Video Or f.Extension = "mp4" Or v.Type = UTypes.m3u8
|
||||
|
||||
If f.Extension.IsEmptyString Then
|
||||
@@ -1735,8 +1796,9 @@ BlockNullPicture:
|
||||
Case UTypes.Video, UTypes.m3u8 : f.Extension = "mp4"
|
||||
Case UTypes.GIF : f.Extension = "gif"
|
||||
End Select
|
||||
ElseIf f.Extension = "webp" And Settings.DownloadNativeImageFormat Then
|
||||
f.Extension = "jpg"
|
||||
ElseIf f.Extension = UserImage.ExtWebp And Settings.DownloadNativeImageFormat And Settings.FfmpegFile.Exists Then
|
||||
'f.Extension = "jpg"
|
||||
postProcessWebp = True
|
||||
End If
|
||||
|
||||
If Not v.SpecialFolder.IsEmptyString Then
|
||||
@@ -1769,9 +1831,9 @@ BlockNullPicture:
|
||||
End If
|
||||
End If
|
||||
|
||||
updateDownCount()
|
||||
updateDownCount(False)
|
||||
|
||||
v.File = ChangeFileNameByProvider(f, v)
|
||||
v.File = DownloadContentDefault_ConvertWebp(ChangeFileNameByProvider(f, v), postProcessWebp)
|
||||
v.State = UStates.Downloaded
|
||||
DownloadContentDefault_PostProcessing(v, f, Token)
|
||||
If UseMD5Comparison And (v.Type = UTypes.GIF Or v.Type = UTypes.Picture) Then
|
||||
@@ -1780,7 +1842,7 @@ BlockNullPicture:
|
||||
If Not v.MD5.IsEmptyString Then
|
||||
If _MD5List.Contains(v.MD5) Then
|
||||
__fileDeleted = v.File.Delete(SFO.File, SFODelete.DeletePermanently, EDP.ReturnValue)
|
||||
If __fileDeleted Then dCount -= 1 : updateDownCount()
|
||||
If __fileDeleted Then dCount -= 1 : updateDownCount(False)
|
||||
Else
|
||||
_MD5List.Add(v.MD5)
|
||||
End If
|
||||
@@ -1789,7 +1851,33 @@ BlockNullPicture:
|
||||
dCount -= 1
|
||||
End If
|
||||
End If
|
||||
stxt:
|
||||
If DownloadText And Not v.PostText.IsEmptyString And (v.Type = UTypes.Text Or v.File.Exists) Then
|
||||
fTxt = v.File
|
||||
If fTxt.IsEmptyString Then
|
||||
If DownloadTextPosts And Not f.IsEmptyString Then
|
||||
fTxt = f
|
||||
If v.Type = UTypes.Text Then fTxt.Name &= IIf(fTxt.Name.IsEmptyString, String.Empty, "_") &
|
||||
v.Post.ID.StringRemoveWinForbiddenSymbols
|
||||
If fTxt.IsEmptyString Then Throw New ArgumentNullException("Text", "Error downloading text") With {.HelpLink = 10}
|
||||
Else
|
||||
Continue For
|
||||
End If
|
||||
End If
|
||||
v.PostTextFileSpecialFolder = DownloadTextSpecialFolder
|
||||
If DownloadTextSpecialFolder Then fTxt.Path = $"{fTxt.Path.StringTrimEnd("\")}\{PostTextSpecialFolderDefault}"
|
||||
fTxt.Extension = "txt"
|
||||
v.PostTextFile = TextSaver.SaveTextToFile(v.PostText, fTxt,,, Settings.FeedShowTextPosts_LogErrors_E)
|
||||
If Not v.PostTextFile.Exists Then Throw New ArgumentNullException("Text", "Error downloading text") With {.HelpLink = 10}
|
||||
If v.Type = UTypes.Text Then v.File = v.PostTextFile
|
||||
v.State = UStates.Downloaded
|
||||
updateDownCount(Not v.Type = UTypes.Text)
|
||||
If v.URL.IsEmptyString Then v.URL = v.PostTextFile.File
|
||||
If v.URL_BASE.IsEmptyString Then v.URL_BASE = v.URL
|
||||
End If
|
||||
dCount += 1
|
||||
Catch anex As ArgumentNullException When anex.HelpLink = 10
|
||||
LogError(anex, anex.Message, Settings.FeedShowTextPosts_LogErrors_E)
|
||||
Catch woex As OperationCanceledException When Token.IsCancellationRequested
|
||||
__deleteFile.Invoke(f, v.URL_BASE)
|
||||
v.State = UStates.Missing
|
||||
@@ -1797,7 +1885,7 @@ BlockNullPicture:
|
||||
_ContentNew(i) = v
|
||||
Throw woex
|
||||
Catch wex As Exception
|
||||
If DownloadContentDefault_ProcessDownloadException() Then
|
||||
If Not v.Type = UTypes.Text AndAlso DownloadContentDefault_ProcessDownloadException() Then
|
||||
v.Attempts += 1
|
||||
v.State = UStates.Missing
|
||||
If MissingErrorsAdd Then ErrorDownloading(f, v.URL)
|
||||
@@ -1845,6 +1933,22 @@ BlockNullPicture:
|
||||
End Function
|
||||
Protected Overridable Sub DownloadContentDefault_PostProcessing(ByRef m As UserMedia, ByVal File As SFile, ByVal Token As CancellationToken)
|
||||
End Sub
|
||||
Protected Overridable Function DownloadContentDefault_ConvertWebp(ByVal WebpFile As SFile, ByVal Process As Boolean) As SFile
|
||||
Dim f As SFile = WebpFile
|
||||
If Process AndAlso f.Exists Then
|
||||
f.Path = $"{f.PathWithSeparator}Sources"
|
||||
f.Exists(SFO.Path)
|
||||
If WebpFile.Copy(f) Then
|
||||
Dim newFile As SFile = WebpFile
|
||||
newFile.Extension = UserImage.ExtJpg
|
||||
f = UserImage.ConvertWebp(f, newFile)
|
||||
If f.Exists Then WebpFile.Delete(SFO.File, SFODelete.DeletePermanently, EDP.ReturnValue)
|
||||
Else
|
||||
f = WebpFile
|
||||
End If
|
||||
End If
|
||||
Return f
|
||||
End Function
|
||||
Protected Overridable Function DownloadContentDefault_ProcessDownloadException() As Boolean
|
||||
Return True
|
||||
End Function
|
||||
@@ -1990,7 +2094,7 @@ BlockNullPicture:
|
||||
End If
|
||||
If m.Contains(IUserData.EraseMode.Data) Then
|
||||
Dim files As List(Of SFile) = SFile.GetFiles(DownloadContentDefault_GetRootDir.CSFileP,, SearchOption.AllDirectories, e)
|
||||
If files.ListExists Then files.RemoveAll(Function(f) Not f.Extension.IsEmptyString AndAlso (f.Extension = "txt" Or f.Extension = "xml"))
|
||||
If files.ListExists Then files.RemoveAll(Function(f) Not f.Extension.IsEmptyString AndAlso ((f.Path.EndsWith(SettingsFolderName) And f.Extension = "txt") Or f.Extension = "xml"))
|
||||
If files.ListExists Then files.ForEach(Sub(f) f.Delete(SFO.File, Settings.DeleteMode, e))
|
||||
LatestData.Clear()
|
||||
result = True
|
||||
@@ -2203,6 +2307,7 @@ BlockNullPicture:
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Errors functions"
|
||||
''' <summary>ToStringForLog(): Message</summary>
|
||||
Protected Sub LogError(ByVal ex As Exception, ByVal Message As String, Optional ByVal e As ErrorsDescriber = Nothing)
|
||||
ErrorsDescriber.Execute(If(e.Exists, e, New ErrorsDescriber(EDP.SendToLog)), ex, $"{ToStringForLog()}: {Message}")
|
||||
End Sub
|
||||
@@ -2233,6 +2338,17 @@ BlockNullPicture:
|
||||
Friend Function ToStringForLog() As String
|
||||
Return $"{IIf(IncludedInCollection, $"[{CollectionName}] - ", String.Empty)}[{Site}] - {Name}"
|
||||
End Function
|
||||
Friend Overloads Function ToStringExt(ByVal UseFriendlyName As Boolean) As String
|
||||
Return $"{IIf(IncludedInCollection, $"[{CollectionName}] - ", String.Empty)}[{Site}] - {String.Format(CStr(IIf(Not FriendlyName.IsEmptyString And
|
||||
UseFriendlyName, "{1} ({0})", "{0}")), Name, FriendlyName)}"
|
||||
End Function
|
||||
Friend Overloads Shared Function ToStringExt(ByVal User As UserInfo) As String
|
||||
If Not IsDBNull(User) Then
|
||||
With User : Return $"{IIf(.IncludedInCollection, $"[{ .CollectionName}] - ", String.Empty)}[{ .Site}] - { .Name}" : End With
|
||||
Else
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
Public Overrides Function ToString() As String
|
||||
If IsCollection Then
|
||||
Return CollectionName
|
||||
|
||||
@@ -14,7 +14,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Namespace API.Bluesky
|
||||
<Manifest(BlueskySiteKey), SpecialForm(False)>
|
||||
<Manifest(BlueskySiteKey), SpecialForm(False), SavedPosts>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||
<PropertyOption(ControlText:="Cookies enabled", ControlToolTip:="If checked, cookies will be used in requests", IsAuth:=True), PXML, PClonable, HiddenControl>
|
||||
Friend ReadOnly Property CookiesEnabled As PropertyValue
|
||||
|
||||
@@ -27,6 +27,7 @@ Namespace API.Bluesky
|
||||
Return If(ID.IsEmptyString, String.Empty, SymbolsConverter.ASCII.EncodeSymbolsOnly(ID))
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly _TmpPosts2 As List(Of String)
|
||||
#End Region
|
||||
#Region "Loader"
|
||||
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
||||
@@ -36,12 +37,13 @@ Namespace API.Bluesky
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptionsBase AndAlso
|
||||
DirectCast(Obj, EditorExchangeOptionsBase).SiteKey = BlueskySiteKey Then NameTrue = DirectCast(Obj, EditorExchangeOptionsBase).UserName
|
||||
DirectCast(Obj, EditorExchangeOptionsBase).SiteKey = BlueskySiteKey Then DirectCast(Obj, EditorExchangeOptionsBase).ApplyBase(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New()
|
||||
UseInternalM3U8Function = True
|
||||
_TmpPosts2 = New List(Of String)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Token"
|
||||
@@ -62,31 +64,48 @@ Namespace API.Bluesky
|
||||
#Region "Download"
|
||||
Private _PostCount As Integer = 0
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
If Not CBool(MySettings.CookiesEnabled.Value) Then Responser.Cookies.Clear()
|
||||
UpdateToken(, True)
|
||||
_TokenUpdateCount = 0
|
||||
_PostCount = 0
|
||||
DownloadData(String.Empty, Token)
|
||||
_TmpPosts2.Clear()
|
||||
Try
|
||||
If Not CBool(MySettings.CookiesEnabled.Value) Then Responser.Cookies.Clear()
|
||||
UpdateToken(, True)
|
||||
_TokenUpdateCount = 0
|
||||
_PostCount = 0
|
||||
DownloadData(String.Empty, Token)
|
||||
Finally
|
||||
_TempPostsList.ListAddList(_TmpPosts2, LNC)
|
||||
_TmpPosts2.Clear()
|
||||
End Try
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
If ID.IsEmptyString Then GetProfileInfo(Token)
|
||||
If ID.IsEmptyString Then Throw New ArgumentNullException("ID", "ID is null")
|
||||
If Not IsSavedPosts And ID.IsEmptyString Then GetProfileInfo(Token)
|
||||
If Not IsSavedPosts And ID.IsEmptyString Then Throw New ArgumentNullException("ID", "ID is null")
|
||||
If UpdateToken() Then
|
||||
Dim nextCursor$ = String.Empty
|
||||
Dim c%
|
||||
URL = $"https://bsky.social/xrpc/app.bsky.feed.getAuthorFeed?actor={ID_Encoded}&filter=posts_and_author_threads&includePins=false&limit=99"
|
||||
If Not Cursor.IsEmptyString Then URL &= $"&cursor={SymbolsConverter.ASCII.EncodeSymbolsOnly(Cursor)}"
|
||||
Dim n$(), p$()
|
||||
If IsSavedPosts Then
|
||||
URL = "https://bsky.social/xrpc/app.bsky.bookmark.getBookmarks"
|
||||
If Not Cursor.IsEmptyString Then URL &= $"?cursor={Cursor}"
|
||||
n = {"bookmarks"}
|
||||
p = {"item"}
|
||||
Else
|
||||
URL = $"https://bsky.social/xrpc/app.bsky.feed.getAuthorFeed?actor={ID_Encoded}&filter=posts_and_author_threads&includePins=false&limit=99"
|
||||
If Not Cursor.IsEmptyString Then URL &= $"&cursor={SymbolsConverter.ASCII.EncodeSymbolsOnly(Cursor)}"
|
||||
n = {"feed"}
|
||||
p = {"post"}
|
||||
End If
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
TokenUpdateCountReset()
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If j.ListExists Then
|
||||
With j("feed")
|
||||
nextCursor = j.Value("cursor")
|
||||
With j(n)
|
||||
If .ListExists Then
|
||||
For Each post As EContainer In .Self
|
||||
With post({"post"})
|
||||
With post(p)
|
||||
c = DefaultParser(.Self,, nextCursor)
|
||||
Select Case c
|
||||
Case CInt(DateResult.Skip) * -1 : Continue For
|
||||
@@ -96,6 +115,8 @@ Namespace API.Bluesky
|
||||
If DownloadTopCount.HasValue AndAlso DownloadTopCount.Value <= _PostCount Then Exit Sub
|
||||
End With
|
||||
Next
|
||||
ElseIf IsSavedPosts Then
|
||||
nextCursor = String.Empty
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
@@ -117,7 +138,8 @@ Namespace API.Bluesky
|
||||
Private Function DefaultParser(ByVal e As EContainer, Optional ByVal CheckDateLimits As Boolean = True, Optional ByRef NextCursor As String = Nothing,
|
||||
Optional ByVal CheckTempPosts As Boolean = True, Optional ByVal State As UStates = UStates.Unknown) As Integer
|
||||
Const exitReturn% = CInt(DateResult.Exit) * -1
|
||||
Dim postID$, postDate$, __url$, __urlBase$
|
||||
Const skipReturn% = CInt(DateResult.Skip) * -1
|
||||
Dim postID$, postDate$, __url$, __urlBase$, __txt$, __userId$, __postAuthor$
|
||||
Dim updateUrl As Boolean
|
||||
Dim c% = 0
|
||||
Dim m As UserMedia
|
||||
@@ -127,22 +149,30 @@ Namespace API.Bluesky
|
||||
postID = GetPostID(.Value("uri"))
|
||||
postDate = String.Empty
|
||||
__urlBase = String.Empty
|
||||
__txt = String.Empty
|
||||
__userId = .Value({"author"}, "did")
|
||||
__postAuthor = String.Empty
|
||||
With .Item({"record"})
|
||||
If .ListExists Then
|
||||
'2025-01-28T02:42:12.415Z
|
||||
postDate = .Value("createdAt")
|
||||
NextCursor = postDate
|
||||
If Not IsSavedPosts Then NextCursor = postDate
|
||||
If CheckDateLimits Then
|
||||
Select Case CheckDatesLimit(postDate, DateProvider)
|
||||
Case DateResult.Skip : Return CInt(DateResult.Skip) * -1 'Continue For
|
||||
Case DateResult.Skip : Return skipReturn 'Continue For
|
||||
Case DateResult.Exit : Return exitReturn 'Exit Sub
|
||||
End Select
|
||||
End If
|
||||
|
||||
If CheckTempPosts Then
|
||||
If _TempPostsList.Contains(postID) Then Return exitReturn Else _TempPostsList.Add(postID)
|
||||
'If _TempPostsList.Contains(postID) Then Return exitReturn Else _TempPostsList.Add(postID)
|
||||
If _TempPostsList.Contains(postID) Then Return exitReturn Else _TmpPosts2.Add(postID)
|
||||
End If
|
||||
__urlBase = $"https://bsky.app/profile/{NameTrue}/post/{postID}"
|
||||
|
||||
If ParseUserMediaOnly And Not IsSavedPosts And Not ID.IsEmptyString And Not __userId.IsEmptyString And Not ID = __userId Then Return skipReturn
|
||||
|
||||
__postAuthor = e.Value({"author"}, "did")
|
||||
__urlBase = $"https://bsky.app/profile/{If(IsSavedPosts, __postAuthor, NameTrue)}/post/{postID}"
|
||||
End If
|
||||
End With
|
||||
|
||||
@@ -152,13 +182,18 @@ Namespace API.Bluesky
|
||||
.URL_BASE = __urlBase,
|
||||
.File = CreateFileFromUrl(url, type),
|
||||
.Post = New UserPost(postID, If(AConvert(Of Date)(postDate, DateProvider, Nothing, EDP.ReturnValue), Nothing)),
|
||||
.State = State
|
||||
.State = State,
|
||||
.PostText = __txt,
|
||||
.PostTextFileSpecialFolder = DownloadTextSpecialFolder
|
||||
}
|
||||
If type = UTypes.Text Then m.PostTextFile = $"{postID}.txt"
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
c += 1
|
||||
Return m
|
||||
End Function
|
||||
|
||||
__txt = .Value({"record"}, "text").IfNullOrEmpty(__txt)
|
||||
|
||||
For Each SecondExtraction As Boolean In {False, True}
|
||||
With If(SecondExtraction, .Item({"record", "embed"}), .Item("embed"))
|
||||
If .ListExists Then
|
||||
@@ -170,15 +205,26 @@ Namespace API.Bluesky
|
||||
__url = d.Value("fullsize")
|
||||
If __url.IsEmptyString Then __url = d.Value({"image", "ref"}, "$link") : updateUrl = True
|
||||
If __url.IsEmptyString And SecondExtraction Then updateUrl = False : __url = e.Value({"embed"}, "thumb")
|
||||
If Not __url.IsEmptyString Then createMedia(__url, UTypes.Picture)
|
||||
If Not __url.IsEmptyString Then
|
||||
If updateUrl AndAlso Not __url.StartsWith("http") Then _
|
||||
__url = $"https://cdn.bsky.app/img/feed_fullsize/plain/{__postAuthor}/{__url}@jpeg"
|
||||
createMedia(__url, UTypes.Picture)
|
||||
End If
|
||||
Next
|
||||
End With
|
||||
End If
|
||||
|
||||
If Not .Value("playlist").IsEmptyString Then createMedia(.Value("playlist"), UTypes.m3u8)
|
||||
|
||||
If If(.Item("external")?.Count, 0) > 0 Then createMedia(.Value({"external"}, "uri"), UTypes.GIF)
|
||||
If If(.Item("external")?.Count, 0) > 0 Then
|
||||
__txt = .Value({"external"}, "title").IfNullOrEmpty(__txt)
|
||||
createMedia(.Value({"external"}, "uri"), UTypes.GIF)
|
||||
End If
|
||||
|
||||
If If(.Item({"media"}, "external")?.Count, 0) > 0 Then
|
||||
__txt = .Value({"media", "external"}, "title").IfNullOrEmpty(__txt)
|
||||
createMedia(.Value({"media", "external"}, "uri"), UTypes.GIF)
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
|
||||
@@ -325,6 +371,12 @@ Namespace API.Bluesky
|
||||
Return 0
|
||||
End If
|
||||
End Function
|
||||
#End Region
|
||||
#Region "IDisposable Support"
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If disposing Then _TmpPosts2.Clear()
|
||||
MyBase.Dispose(disposing)
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -40,6 +40,9 @@ Namespace API.Facebook
|
||||
Friend ReadOnly Property ParseReelsBlock As PropertyValue
|
||||
<PropertyOption(ControlText:="Download stories", IsAuth:=False, Category:=DN.CAT_UserDefs), PXML, PClonable>
|
||||
Friend ReadOnly Property ParseStoriesBlock As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
|
||||
@@ -638,7 +638,7 @@ Namespace API.Facebook
|
||||
End If
|
||||
End Function
|
||||
Private Sub GetVideoPageID(ByVal GetReels As Boolean, ByVal Token As CancellationToken)
|
||||
Dim URL$ = $"{GetProfileUrl()}\{IIf(GetReels, "reels", "videos")}"
|
||||
Dim URL$ = $"{GetProfileUrl()}{IIf(IsNoNameProfile, "&sk=", "/")}{IIf(GetReels, IIf(IsNoNameProfile, "reels_tab", "reels"), "videos")}"
|
||||
Dim resp As Responser = HtmlResponserCreate()
|
||||
Try
|
||||
WaitTimer()
|
||||
@@ -676,10 +676,7 @@ Namespace API.Facebook
|
||||
End If
|
||||
Token_Photosby = RegexReplace(r, Regex_Photos_by)
|
||||
If StoryBucket.IsEmptyString Then StoryBucket = RegexReplace(r, Regex_StoryBucket)
|
||||
If ID.IsEmptyString Then
|
||||
ID = RegexReplace(r, Regex_UserID)
|
||||
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
|
||||
End If
|
||||
If ID.IsEmptyString Then ID = RegexReplace(r, Regex_UserID)
|
||||
End If
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, "get user token",, resp)
|
||||
|
||||
@@ -62,6 +62,7 @@ Namespace API.Instagram
|
||||
End With
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
With s
|
||||
GetTimeline = CBool(.GetTimeline.Value)
|
||||
GetReels = CBool(.GetReels.Value)
|
||||
|
||||
@@ -196,6 +196,18 @@ Namespace API.Instagram
|
||||
Friend ReadOnly Property SleepTimerOnPostsLimit As PropertyValue
|
||||
<Provider(NameOf(SleepTimerOnPostsLimit), FieldsChecker:=True)>
|
||||
Private ReadOnly Property SleepTimerOnPostsLimitProvider As IFormatProvider
|
||||
<PropertyOption(ControlText:="Next profile timer",
|
||||
ControlToolTip:="The time value (in milliseconds) the program will wait before processing the next profile." &
|
||||
vbCr & "-2 to use max timer." & vbCr & "-1 to disable." & vbCr & "The default value is -2" & TimersUrgentTip,
|
||||
AllowNull:=False, Category:=DN.CAT_Timers), PXML, PClonable>
|
||||
Friend ReadOnly Property SleepTimerRequestsNextProfile As PropertyValue
|
||||
Friend ReadOnly Property SleepTimerRequestsNextProfileMax As Integer
|
||||
Get
|
||||
Return {RequestsWaitTimer_Any, RequestsWaitTimer, SleepTimerOnPostsLimit}.Max(Function(obj) CInt(obj.Value))
|
||||
End Get
|
||||
End Property
|
||||
<Provider(NameOf(SleepTimerRequestsNextProfile), FieldsChecker:=True)>
|
||||
Private ReadOnly Property SleepTimerRequestsNextProfileProvider As IFormatProvider
|
||||
#End Region
|
||||
#Region "New user defaults"
|
||||
<PropertyOption(ControlText:="Get timeline", ControlToolTip:="Default value for new users", Category:=DN.CAT_UserDefs), PXML, PClonable>
|
||||
@@ -493,6 +505,8 @@ Namespace API.Instagram
|
||||
RequestsWaitTimerTaskCountProvider = New TimersChecker(1)
|
||||
SleepTimerOnPostsLimit = New PropertyValue(60000)
|
||||
SleepTimerOnPostsLimitProvider = New TimersChecker(10000)
|
||||
SleepTimerRequestsNextProfile = New PropertyValue(-2)
|
||||
SleepTimerRequestsNextProfileProvider = New TimersChecker(-2)
|
||||
|
||||
GetTimeline = New PropertyValue(True)
|
||||
GetTimeline_VideoPic = New PropertyValue(True)
|
||||
@@ -579,6 +593,7 @@ Namespace API.Instagram
|
||||
MDD.Reset()
|
||||
If ActiveSessionRequestsExists Then RefreshMyLastRequests(Now)
|
||||
ActiveSessionRequestsExists = False
|
||||
ActiveSessionLastProfileRequests = False
|
||||
_NextWNM = UserData.WNM.Notify
|
||||
_NextTagged = True
|
||||
SkipUntilNextSession = False
|
||||
@@ -596,6 +611,7 @@ Namespace API.Instagram
|
||||
Private ActiveJobs As Integer = 0
|
||||
Private ActiveSessionDate As Date
|
||||
Private ActiveSessionRequestsExists As Boolean = False
|
||||
Friend ActiveSessionLastProfileRequests As Boolean = False
|
||||
Private _NextWNM As UserData.WNM = UserData.WNM.Notify
|
||||
Private _NextTagged As Boolean = True
|
||||
Friend Overrides Sub DownloadStarted(ByVal What As Download)
|
||||
@@ -632,6 +648,7 @@ Namespace API.Instagram
|
||||
_NextWNM = .WaitNotificationMode
|
||||
If _NextWNM = UserData.WNM.SkipTemp Or _NextWNM = UserData.WNM.SkipCurrent Then _NextWNM = UserData.WNM.Notify
|
||||
_NextTagged = .TaggedCheckSession
|
||||
If MyLastRequestsCount <> .RequestsCountSession Then ActiveSessionLastProfileRequests = True
|
||||
MyLastRequestsCount = .RequestsCountSession
|
||||
If .RequestsCountSession > 0 Then ActiveSessionRequestsExists = True
|
||||
_FieldsChangerSuspended = True
|
||||
|
||||
@@ -164,6 +164,7 @@ Namespace API.Instagram
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptions Then
|
||||
With DirectCast(Obj, EditorExchangeOptions)
|
||||
.ApplyBase(Me)
|
||||
GetTimeline = .GetTimeline
|
||||
GetReels = .GetReels
|
||||
GetStories = .GetStories
|
||||
@@ -178,7 +179,6 @@ Namespace API.Instagram
|
||||
|
||||
PutImageVideoFolder = .PutImageVideoFolder
|
||||
|
||||
NameTrue = .UserName
|
||||
ForceUpdateUserName = .ForceUpdateUserName
|
||||
ForceUpdateUserInfo = .ForceUpdateUserInfo
|
||||
End With
|
||||
@@ -385,6 +385,20 @@ Namespace API.Instagram
|
||||
|
||||
Dim s As Sections = Sections.Timeline
|
||||
Dim errorFound As Boolean = False
|
||||
Dim firstWait As Boolean = False
|
||||
Dim __firstWait As Action = Sub()
|
||||
With MySiteSettings
|
||||
If Not firstWait And .ActiveSessionLastProfileRequests And CInt(.SleepTimerRequestsNextProfile.Value) <> -1 Then
|
||||
Dim ____v% = 0
|
||||
If CInt(.SleepTimerRequestsNextProfile.Value) = -2 Then
|
||||
____v = .SleepTimerRequestsNextProfileMax
|
||||
Else
|
||||
____v = CInt(.SleepTimerRequestsNextProfile.Value)
|
||||
End If
|
||||
If ____v > 0 Then firstWait = True : Thread.Sleep(____v)
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
Try
|
||||
Err5xx = -1
|
||||
ErrHandling = -1
|
||||
@@ -398,9 +412,11 @@ Namespace API.Instagram
|
||||
ThrowAny(Token)
|
||||
HasError = False
|
||||
Dim dt As Func(Of Boolean) = Function() (CBool(MySiteSettings.DownloadTimeline.Value) And GetTimeline) Or IsSavedPosts
|
||||
If FirstLoadingDone Then LastCursor = String.Empty
|
||||
If dt.Invoke And Not LastCursor.IsEmptyString Then
|
||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||
upClaimRequest.Invoke
|
||||
__firstWait.Invoke
|
||||
DownloadData(LastCursor, s, Token)
|
||||
ProgressPre.Done()
|
||||
ThrowAny(Token)
|
||||
@@ -410,6 +426,7 @@ Namespace API.Instagram
|
||||
s = IIf(IsSavedPosts, Sections.SavedPosts, Sections.Timeline)
|
||||
upClaimRequest.Invoke
|
||||
ChangeResponserMode(_UseGQL)
|
||||
__firstWait.Invoke
|
||||
DownloadData(String.Empty, s, Token)
|
||||
ProgressPre.Done()
|
||||
ThrowAny(Token)
|
||||
@@ -425,6 +442,7 @@ Namespace API.Instagram
|
||||
DefaultParser_ElemNode = {"node", "media"}
|
||||
upClaimRequest.Invoke
|
||||
ChangeResponserMode(True)
|
||||
__firstWait.Invoke
|
||||
DownloadData(String.Empty, s, Token)
|
||||
GetReelsGQL_SetEnvir = False
|
||||
ProgressPre.Done()
|
||||
@@ -434,6 +452,7 @@ Namespace API.Instagram
|
||||
If CBool(MySiteSettings.DownloadStories.Value) And GetStories Then
|
||||
s = Sections.Stories
|
||||
upClaimRequest.Invoke
|
||||
__firstWait.Invoke
|
||||
DownloadData(String.Empty, s, Token)
|
||||
ProgressPre.Done()
|
||||
End If
|
||||
@@ -442,6 +461,7 @@ Namespace API.Instagram
|
||||
If CBool(MySiteSettings.DownloadStoriesUser.Value) And GetStoriesUser Then
|
||||
s = Sections.UserStories
|
||||
upClaimRequest.Invoke
|
||||
__firstWait.Invoke
|
||||
DownloadData(String.Empty, s, Token)
|
||||
ProgressPre.Done()
|
||||
End If
|
||||
@@ -450,6 +470,7 @@ Namespace API.Instagram
|
||||
If CBool(MySiteSettings.DownloadTagged.Value) And GetTaggedData Then
|
||||
s = Sections.Tagged
|
||||
upClaimRequest.Invoke
|
||||
__firstWait.Invoke
|
||||
DownloadData(String.Empty, s, Token)
|
||||
ProgressPre.Done()
|
||||
DefaultParser_ElemNode = Nothing
|
||||
@@ -968,10 +989,12 @@ NextPageBlock:
|
||||
Dim PostIDKV As PostKV
|
||||
Dim Pinned As Boolean
|
||||
Dim PostDate$, PostOriginUrl$
|
||||
Dim PostText$ = String.Empty
|
||||
Dim i%, before%
|
||||
Dim usePinFunc As Boolean = Not DefaultParser_Pinned Is Nothing
|
||||
Dim skipPostFuncExists As Boolean = Not DefaultParser_SkipPost Is Nothing
|
||||
Dim nn As EContainer
|
||||
Dim textMedia As UserMedia
|
||||
If SpecFolder.IsEmptyString Then
|
||||
Select Case Section
|
||||
Case Sections.Tagged : SpecFolder = TaggedFolder
|
||||
@@ -1006,9 +1029,17 @@ NextPageBlock:
|
||||
Case DateResult.Exit : If Not Pinned Then Return False
|
||||
End Select
|
||||
End If
|
||||
If DownloadTextPosts Then PostText = DefaultParser_GetCaption(.Self)
|
||||
before = _TempMediaList.Count
|
||||
ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate,, PostOriginUrl, State, Attempts,, Section)
|
||||
If Not before = _TempMediaList.Count Then _TotalPostsParsed += 1
|
||||
ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate,, PostOriginUrl, State, Attempts,, Section, PostText)
|
||||
If Not before = _TempMediaList.Count Then
|
||||
_TotalPostsParsed += 1
|
||||
ElseIf DownloadTextPosts And DownloadText And Not PostText.IsEmptyString Then
|
||||
textMedia = MediaFromData(UTypes.Text, PostIDKV.ID, PostIDKV.ID, PostDate, SpecFolder, PostOriginUrl, State, Attempts, PostText)
|
||||
textMedia.URL = PostIDKV.ID
|
||||
textMedia.PostTextFile = $"{PostIDKV.ID}.txt"
|
||||
_TempMediaList.ListAddValue(textMedia, LNC)
|
||||
End If
|
||||
If _Limit > 0 And _TotalPostsParsed >= _Limit Then Return False
|
||||
End If
|
||||
Else
|
||||
@@ -1021,6 +1052,9 @@ NextPageBlock:
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
Protected Overridable Function DefaultParser_GetCaption(ByVal e As EContainer) As String
|
||||
Return e.Value({"caption"}, "text")
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Code ID converters"
|
||||
Protected Function CodeToID(ByVal Code As String) As String
|
||||
@@ -1069,7 +1103,8 @@ NextPageBlock:
|
||||
Optional ByVal PostOriginUrl As String = Nothing,
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal Attempts As Integer = 0,
|
||||
Optional ByVal TryExtractImage As Boolean = False,
|
||||
Optional ByVal Section As Sections = ObtainMedia_NoSection)
|
||||
Optional ByVal Section As Sections = ObtainMedia_NoSection,
|
||||
Optional ByVal Text As String = Nothing)
|
||||
Try
|
||||
Dim maxSize As Func(Of EContainer, Integer) = Function(ByVal _ss As EContainer) As Integer
|
||||
Dim w% = AConvert(Of Integer)(_ss.Value("width"), 0)
|
||||
@@ -1104,6 +1139,7 @@ NextPageBlock:
|
||||
End Function
|
||||
If Not ObtainMedia_SizeFuncVid Is Nothing Then ssVid = ObtainMedia_SizeFuncVid
|
||||
If Not ObtainMedia_SizeFuncPic Is Nothing Then ssPic = ObtainMedia_SizeFuncPic
|
||||
If DownloadTextPosts And Text.IsEmptyString Then Text = DefaultParser_GetCaption(n)
|
||||
If n.Count > 0 Then
|
||||
Dim l As New List(Of Sizes)
|
||||
Dim d As EContainer
|
||||
@@ -1116,12 +1152,30 @@ NextPageBlock:
|
||||
If TryExtractImage Then
|
||||
t = 1
|
||||
abstractDecision = True
|
||||
If Not SpecialFolder.IsEmptyString AndAlso PutImageVideoFolder Then
|
||||
Dim endsAbs As Boolean = SpecialFolder.EndsWith("*")
|
||||
If endsAbs Then SpecialFolder = SpecialFolder.TrimEnd("*")
|
||||
If Not SpecialFolder.IsEmptyString Then SpecialFolder = $"{SpecialFolder.TrimEnd("\")}\{VideoFolderName}{IIf(Not endsAbs, "*", String.Empty)}"
|
||||
If endsAbs Then SpecialFolder &= "*"
|
||||
Dim endsAbs As Boolean
|
||||
Dim newFolderName$
|
||||
If PutImageVideoFolder Then
|
||||
If SpecialFolder.IsEmptyString Then
|
||||
newFolderName = $"{VideoFolderName}\*"
|
||||
Else
|
||||
endsAbs = SpecialFolder.EndsWith("*")
|
||||
SpecialFolder = SpecialFolder.TrimEnd({CChar("\"), CChar("*")})
|
||||
If Not endsAbs Then SpecialFolder = $"{SpecialFolder}\{VideoFolderName}"
|
||||
newFolderName = $"{SpecialFolder}*"
|
||||
End If
|
||||
'Dim endsAbs As Boolean = SpecialFolder.EndsWith("*")
|
||||
'If endsAbs Then SpecialFolder = SpecialFolder.TrimEnd("*")
|
||||
'If Not SpecialFolder.IsEmptyString Then SpecialFolder = $"{SpecialFolder.TrimEnd("\")}\{VideoFolderName}{IIf(Not endsAbs, "*", String.Empty)}"
|
||||
'If endsAbs Then SpecialFolder &= "*"
|
||||
ElseIf Not SpecialFolder.IsEmptyString Then
|
||||
endsAbs = SpecialFolder.EndsWith("*")
|
||||
SpecialFolder = SpecialFolder.TrimEnd({CChar("\"), CChar("*")})
|
||||
If endsAbs Then SpecialFolder = $"{SpecialFolder}\Photos"
|
||||
newFolderName = $"{SpecialFolder}*"
|
||||
Else
|
||||
newFolderName = SpecialFolder
|
||||
End If
|
||||
SpecialFolder = newFolderName
|
||||
ElseIf t = -1 And InitialType = 8 And ObtainMedia_AllowAbstract Then
|
||||
If n.Contains(vid) Then
|
||||
t = 2
|
||||
@@ -1145,7 +1199,7 @@ NextPageBlock:
|
||||
If l.Count > 0 Then l.RemoveAll(wrongData)
|
||||
If l.Count > 0 Then
|
||||
l.Sort()
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, DateObj, SpecialFolder, PostOriginUrl, State, Attempts), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, l.First.Data, PostID, DateObj, SpecialFolder, PostOriginUrl, State, Attempts, Text), LNC)
|
||||
l.Clear()
|
||||
End If
|
||||
End If
|
||||
@@ -1162,19 +1216,19 @@ NextPageBlock:
|
||||
If l.Count > 0 Then l.RemoveAll(wrongData)
|
||||
If l.Count > 0 Then
|
||||
l.Sort()
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, DateObj, SpecialFolder, PostOriginUrl, State, Attempts), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, l.First.Data, PostID, DateObj, SpecialFolder, PostOriginUrl, State, Attempts, Text), LNC)
|
||||
l.Clear()
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
If Not TryExtractImage And Not Section = ObtainMedia_NoSection And ExtractImageFrom(Section) Then _
|
||||
ObtainMedia(n, PostID, SpecialFolder, DateObj, InitialType, PostOriginUrl, State, Attempts, True, Section)
|
||||
ObtainMedia(n, PostID, SpecialFolder, DateObj, InitialType, PostOriginUrl, State, Attempts, True, Section, Text)
|
||||
Case 8 'gallery
|
||||
DateObj = mDate(n)
|
||||
With n("carousel_media").XmlIfNothing
|
||||
If .Count > 0 Then
|
||||
For Each d In .Self : ObtainMedia(d, PostID, SpecialFolder, DateObj, 8, PostOriginUrl) : Next
|
||||
For Each d In .Self : ObtainMedia(d, PostID, SpecialFolder, DateObj, 8, PostOriginUrl,,,,, Text) : Next
|
||||
End If
|
||||
End With
|
||||
End Select
|
||||
@@ -1199,7 +1253,6 @@ NextPageBlock:
|
||||
If Not j Is Nothing AndAlso j.Contains({"data", "user"}) Then
|
||||
With j({"data", "user"})
|
||||
ID = .Value("id")
|
||||
_ForceSaveUserData = True
|
||||
__idFound = True
|
||||
UserSiteNameUpdate(.Value("full_name"))
|
||||
Dim descr$ = .Value("biography")
|
||||
@@ -1438,13 +1491,16 @@ NextPageBlock:
|
||||
#Region "Create media"
|
||||
Private Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal SpecialFolder As String = Nothing, Optional ByVal PostOriginUrl As String = Nothing,
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal Attempts As Integer = 0) As UserMedia
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal Attempts As Integer = 0,
|
||||
Optional ByVal Text As String = Nothing) As UserMedia
|
||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||
Dim m As New UserMedia(_URL, t) With {.URL_BASE = PostOriginUrl.IfNullOrEmpty(_URL), .Post = New UserPost With {.ID = PostID}}
|
||||
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, UnixDate32Provider, Nothing) Else m.Post.Date = Nothing
|
||||
m.SpecialFolder = SpecialFolder
|
||||
If State = UStates.Missing Then m.State = UStates.Missing : m.Attempts = Attempts
|
||||
m.PostText = Text
|
||||
m.PostTextFileSpecialFolder = DownloadTextSpecialFolder
|
||||
Return m
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
@@ -34,6 +34,9 @@ Namespace API.JustForFans
|
||||
Case NameOf(UserAgent) : If Not HeaderValue.IsEmptyString Then Responser.UserAgent = HeaderValue
|
||||
End Select
|
||||
End Sub
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
MyBase.New("JustForFans", "justfor.fans", AccName, Temp, My.Resources.SiteResources.JFFIcon_64, My.Resources.SiteResources.JFFPic_76)
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.LPSG
|
||||
<Manifest("AndyProgram_LPSG")>
|
||||
Friend Class SiteSettings : Inherits Base.SiteSettingsBase
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
MyBase.New("LPSG", "www.lpsg.com", AccName, Temp, My.Resources.SiteResources.LPSGIcon_48, My.Resources.SiteResources.LPSGPic_32)
|
||||
UrlPatternUser = "https://www.lpsg.com/threads/{0}/"
|
||||
|
||||
@@ -76,6 +76,9 @@ Namespace API.Mastodon
|
||||
<PropertyOption(IsAuth:=False, ControlText:="User related to my domain",
|
||||
ControlToolTip:="Open user profiles and user posts through my domain."), PXML, PClonable>
|
||||
Friend ReadOnly Property UserRelatedToMyDomain As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
|
||||
@@ -3,5 +3,4 @@ https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/main/dynamicR
|
||||
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/patch-1/dynamicRules.json
|
||||
https://github.com/DATAHOARDERS/dynamic-rules/blob/main/onlyfans.json
|
||||
https://github.com/DIGITALCRIMINAL/dynamic-rules/blob/main/onlyfans.json
|
||||
https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json
|
||||
https://github.com/rafa-9/dynamic-rules/blob/main/rules.json
|
||||
@@ -4,8 +4,8 @@ https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/main/dynamicR
|
||||
https://github.com/riley-access-labs/onlyfans-dynamic-rules-1/blob/patch-1/dynamicRules.json
|
||||
https://github.com/DATAHOARDERS/dynamic-rules/blob/main/onlyfans.json
|
||||
https://github.com/DIGITALCRIMINAL/dynamic-rules/blob/main/onlyfans.json
|
||||
https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json
|
||||
https://github.com/rafa-9/dynamic-rules/blob/main/rules.json
|
||||
|
||||
https://github.com/SneakyOvis/onlyfans-dynamic-rules/blob/main/rules.json
|
||||
https://github.com/Growik/onlyfans-dynamic-rules/blob/main/rules.json
|
||||
https://github.com/deviint/onlyfans-dynamic-rules/blob/main/dynamicRules.json
|
||||
@@ -37,6 +37,8 @@ Namespace API.OnlyFans
|
||||
Friend Const HeaderXBC As String = "X-Bc"
|
||||
Friend Const HeaderAppToken As String = "App-Token"
|
||||
Private Const AppTokenDefault As String = "33d57ade8c02dbc5a333db99ff9ae26a"
|
||||
Private Const BackendDefault As String = "aio"
|
||||
Private Const Backendhttpx As String = "httpx"
|
||||
<PropertyOption(ControlText:=HeaderUserID, AllowNull:=False, IsAuth:=True), PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property HH_USER_ID As PropertyValue
|
||||
<PropertyOption(ControlText:=HeaderXBC, AllowNull:=False, IsAuth:=True), PClonable(Clone:=False)>
|
||||
@@ -199,6 +201,24 @@ Namespace API.OnlyFans
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
<PClonable, PXML("OFS_BACKEND")> Private ReadOnly Property OFS_BACKEND_XML As PropertyValue
|
||||
<PropertyOption(ControlText:="backend", ControlToolTip:="The value of 'advanced_options' in the configuration" & vbCr &
|
||||
"If you can't download the video, try using 'httpx'", AllowNull:=False, Category:=CAT_OFS)>
|
||||
Friend ReadOnly Property OFS_BACKEND As PropertyValue
|
||||
Get
|
||||
If Not DefaultInstance Is Nothing Then
|
||||
Return DirectCast(DefaultInstance, SiteSettings).OFS_BACKEND_XML
|
||||
Else
|
||||
Return OFS_BACKEND_XML
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
<PropertyUpdater(NameOf(OFS_BACKEND))>
|
||||
Private Function OFS_BACKEND_Update() As Boolean
|
||||
DirectCast(If(DefaultInstance, Me), SiteSettings).OFS_BACKEND_XML.Value =
|
||||
CStr(IIf(MsgBoxE({"Select a value for the 'backend' option", "'backend' value"}, vbQuestion,,, {BackendDefault, Backendhttpx}) = 0, BackendDefault, Backendhttpx))
|
||||
Return True
|
||||
End Function
|
||||
#End Region
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
@@ -261,6 +281,7 @@ Namespace API.OnlyFans
|
||||
Keydb_Api_XML = New PropertyValue(String.Empty, GetType(String))
|
||||
OFS_KEYS_Key_XML = New PropertyValue(String.Empty, GetType(String))
|
||||
OFS_KEYS_ClientID_XML = New PropertyValue(String.Empty, GetType(String))
|
||||
OFS_BACKEND_XML = New PropertyValue(BackendDefault)
|
||||
|
||||
UpdateRules401_XML = New PropertyValue(False)
|
||||
|
||||
@@ -343,7 +364,8 @@ Namespace API.OnlyFans
|
||||
If p.IsEmptyString Then
|
||||
Return GetUserUrl(User)
|
||||
Else
|
||||
Return String.Format(UserPostPattern, p, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}"))
|
||||
'Return String.Format(UserPostPattern, p, If(User.ID.IsEmptyString, User.Name, $"u{User.ID}"))
|
||||
Return String.Format(UserPostPattern, p, User.NameTrue)
|
||||
End If
|
||||
Else
|
||||
Return String.Empty
|
||||
|
||||
@@ -66,6 +66,7 @@ Namespace API.OnlyFans
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
||||
With DirectCast(Obj, UserExchangeOptions)
|
||||
.ApplyBase(Me)
|
||||
MediaDownloadTimeline = .DownloadTimeline
|
||||
MediaDownloadStories = .DownloadStories
|
||||
MediaDownloadHighlights = .DownloadHighlights
|
||||
@@ -84,6 +85,7 @@ Namespace API.OnlyFans
|
||||
Private _OFScraperExists As Boolean = False
|
||||
Private OFSCache As CacheKeeper = Nothing
|
||||
Private _AbsMediaIndex As Integer = 0
|
||||
Private _DownloadedPostsSession As Integer = 0
|
||||
Private FunctionErr As Integer = FunctionErrDef
|
||||
Private Const FunctionErrDef As Integer = -100
|
||||
Private Sub ValidateOFScraper()
|
||||
@@ -95,6 +97,7 @@ Namespace API.OnlyFans
|
||||
If Not MySettings.SessionAborted Then
|
||||
ValidateOFScraper()
|
||||
_AbsMediaIndex = 0
|
||||
_DownloadedPostsSession = 0
|
||||
FunctionErr = FunctionErrDef
|
||||
If Not CCookie Is Nothing Then CCookie.Dispose()
|
||||
CCookie = Responser.Cookies.Copy
|
||||
@@ -113,6 +116,7 @@ Namespace API.OnlyFans
|
||||
If MediaDownloadHighlights And FunctionErr = FunctionErrDef Then DownloadHighlights(Token)
|
||||
If MediaDownloadChatMedia And FunctionErr = FunctionErrDef Then DownloadChatMedia(0, Token)
|
||||
End If
|
||||
If _TempMediaList.Count > 0 And Not _NameUpdated Then GetUserID(True)
|
||||
End If
|
||||
Finally
|
||||
Responser_ResponseReceived_RemoveHandler()
|
||||
@@ -144,7 +148,7 @@ Namespace API.OnlyFans
|
||||
Dim tmpCursor$ = String.Empty
|
||||
Dim hasMore As Boolean = False
|
||||
Dim path$ = String.Empty
|
||||
Dim postDate$, postID$
|
||||
Dim postDate$, postID$, txt$
|
||||
Dim n As EContainer
|
||||
Dim mediaList As List(Of UserMedia)
|
||||
Dim mediaResult As Boolean
|
||||
@@ -189,9 +193,21 @@ Namespace API.OnlyFans
|
||||
Case DateResult.Exit : Exit Sub
|
||||
End Select
|
||||
|
||||
txt = n.Value("text")
|
||||
|
||||
mediaResult = False
|
||||
mediaList = TryCreateMedia(n, postID, postDate, mediaResult)
|
||||
If mediaResult Then _TempMediaList.ListAddList(mediaList, LNC)
|
||||
mediaList = TryCreateMedia(n, postID, postDate, mediaResult,,,,, txt)
|
||||
If mediaResult Then
|
||||
_TempMediaList.ListAddList(mediaList, LNC)
|
||||
_DownloadedPostsSession += 1
|
||||
ElseIf Not txt.IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(New UserMedia(postID, UTypes.Text) With {
|
||||
.Post = New UserPost(postID, AConvert(Of Date)(postDate, DateProvider, Nothing)),
|
||||
.PostText = txt,
|
||||
.PostTextFileSpecialFolder = DownloadTextSpecialFolder,
|
||||
.PostTextFile = $"{postID}.txt"
|
||||
}, LNC)
|
||||
End If
|
||||
Next
|
||||
Else
|
||||
hasMore = False
|
||||
@@ -202,7 +218,10 @@ Namespace API.OnlyFans
|
||||
End If
|
||||
End If
|
||||
|
||||
If hasMore Then
|
||||
If DownloadTopCount.HasValue AndAlso DownloadTopCount.Value <= _DownloadedPostsSession Then
|
||||
_complete = True
|
||||
Exit Sub
|
||||
ElseIf hasMore Then
|
||||
If IsSavedPosts Then tmpCursor = CInt(Cursor.IfNullOrEmpty(0)) + 10
|
||||
DownloadTimeline(tmpCursor, Token)
|
||||
End If
|
||||
@@ -405,14 +424,14 @@ Namespace API.OnlyFans
|
||||
Private Function TryCreateMedia(ByVal n As EContainer, ByVal PostID As String, Optional ByVal PostDate As String = Nothing,
|
||||
Optional ByRef Result As Boolean = False, Optional ByVal IsHL As Boolean = False,
|
||||
Optional ByVal SpecFolder As String = Nothing, Optional ByVal PostUserID As String = Nothing,
|
||||
Optional ByVal TryUseOFS As Boolean = True) As List(Of UserMedia)
|
||||
Optional ByVal TryUseOFS As Boolean = True, Optional ByVal PostText As String = Nothing) As List(Of UserMedia)
|
||||
Dim postUrl$, postUrlBase$, ext$
|
||||
Dim t As UTypes
|
||||
Dim mList As New List(Of UserMedia)
|
||||
Result = False
|
||||
With n("media")
|
||||
If .ListExists Then
|
||||
For Each m In .Self
|
||||
For Each m As EContainer In .Self
|
||||
postUrl = GetMediaURL(m)
|
||||
'If IsHL Then
|
||||
' 'postUrl = m.Value({"files", "source"}, "url")
|
||||
@@ -421,48 +440,55 @@ Namespace API.OnlyFans
|
||||
' 'postUrl = m.Value({"source"}, "source").IfNullOrEmpty(m.Value("full"))
|
||||
' postUrl = GetMediaURL(m)
|
||||
'End If
|
||||
postUrlBase = String.Empty
|
||||
Select Case m.Value("type")
|
||||
Case "photo" : t = UTypes.Picture : ext = "jpg"
|
||||
Case "video"
|
||||
t = UTypes.Video
|
||||
ext = "mp4"
|
||||
If postUrl.IsEmptyString And Not IsHL And TryUseOFS Then
|
||||
t = UTypes.VideoPre
|
||||
_AbsMediaIndex += 1
|
||||
If Not PostUserID.IsEmptyString And IsSingleObjectDownload Then _
|
||||
postUrlBase = String.Format(SiteSettings.UserPostPattern, PostID, $"u{PostUserID}")
|
||||
End If
|
||||
Case Else : t = UTypes.Undefined : ext = String.Empty
|
||||
End Select
|
||||
If Not t = UTypes.Undefined And (Not postUrl.IsEmptyString Or t = UTypes.VideoPre) Then
|
||||
Dim media As New UserMedia(postUrl.IfNullOrEmpty(IIf(t = UTypes.VideoPre, $"{t}{_AbsMediaIndex}", String.Empty)), t) With {
|
||||
.Post = New UserPost(PostID, AConvert(Of Date)(PostDate, DateProvider, Nothing)),
|
||||
.SpecialFolder = SpecFolder
|
||||
}
|
||||
If postUrlBase.IsEmptyString And Not IsSingleObjectDownload Then postUrlBase = GetPostUrl(Me, media)
|
||||
If Not postUrlBase.IsEmptyString Then media.URL_BASE = postUrlBase
|
||||
media.File.Extension = ext
|
||||
Result = True
|
||||
mList.Add(media)
|
||||
If m.Value("canView").FromXML(Of Boolean)(True) Then
|
||||
postUrlBase = String.Empty
|
||||
Select Case m.Value("type")
|
||||
Case "photo" : t = UTypes.Picture : ext = "jpg"
|
||||
Case "video", "gif"
|
||||
t = UTypes.Video
|
||||
ext = "mp4"
|
||||
If postUrl.IsEmptyString And Not IsHL And TryUseOFS Then
|
||||
t = UTypes.VideoPre
|
||||
_AbsMediaIndex += 1
|
||||
If Not PostUserID.IsEmptyString And IsSingleObjectDownload Then _
|
||||
postUrlBase = String.Format(SiteSettings.UserPostPattern, PostID, $"u{PostUserID}")
|
||||
End If
|
||||
Case Else : t = UTypes.Undefined : ext = String.Empty
|
||||
End Select
|
||||
If Not t = UTypes.Undefined And (Not postUrl.IsEmptyString Or t = UTypes.VideoPre) Then
|
||||
Dim media As New UserMedia(postUrl.IfNullOrEmpty(IIf(t = UTypes.VideoPre, $"{t}{_AbsMediaIndex}", String.Empty)), t) With {
|
||||
.Post = New UserPost(PostID, AConvert(Of Date)(PostDate, DateProvider, Nothing)),
|
||||
.SpecialFolder = SpecFolder,
|
||||
.PostText = PostText,
|
||||
.PostTextFileSpecialFolder = DownloadTextSpecialFolder
|
||||
}
|
||||
If postUrlBase.IsEmptyString And Not IsSingleObjectDownload Then postUrlBase = GetPostUrl(Me, media)
|
||||
If Not postUrlBase.IsEmptyString Then media.URL_BASE = postUrlBase
|
||||
media.File.Extension = ext
|
||||
Result = True
|
||||
mList.Add(media)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
Return mList
|
||||
End Function
|
||||
Private Sub GetUserID()
|
||||
Private _NameUpdated As Boolean = False
|
||||
Private Sub GetUserID(Optional ByVal UpdateNameOnly As Boolean = False)
|
||||
Const brTag$ = "<br />"
|
||||
Dim path$ = $"/api2/v2/users/{Name}"
|
||||
Dim path$ = $"/api2/v2/users/{IIf(UpdateNameOnly, $"u{ID}", Name)}"
|
||||
Dim url$ = String.Format(BaseUrlPattern, path)
|
||||
Try
|
||||
If ID.IsEmptyString AndAlso UpdateSignature(path) Then
|
||||
If (ID.IsEmptyString Or UpdateNameOnly) AndAlso UpdateSignature(path) Then
|
||||
Dim r$ = Responser.GetResponse(url)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If j.ListExists Then
|
||||
NameTrue = j.Value("username")
|
||||
_NameUpdated = True
|
||||
If UpdateNameOnly Then Exit Sub
|
||||
ID = j.Value("id")
|
||||
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
|
||||
UserSiteNameUpdate(j.Value("name"))
|
||||
Dim descr$ = j.Value("about")
|
||||
If Not descr.IsEmptyString Then descr = descr.Replace(brTag, String.Empty)
|
||||
@@ -600,6 +626,7 @@ Namespace API.OnlyFans
|
||||
Const requestPattern$ = """{0}"" manual --config ""{1}"" --url {2}"
|
||||
Dim conf As SFile = OFS_CreateConfig()
|
||||
If conf.Exists Then
|
||||
If Not _NameUpdated Then GetUserID(True)
|
||||
Dim command$ = String.Format(requestPattern, MySettings.OFScraperPath.Value, conf, URL)
|
||||
'#If DEBUG Then
|
||||
'Debug.WriteLine(command)
|
||||
@@ -657,6 +684,7 @@ Namespace API.OnlyFans
|
||||
|
||||
updateConf("key-mode-default", CStr(MySettings.KeyModeDefault.Value).IfNullOrEmpty(SiteSettings.KeyModeDefault_Default), m1)
|
||||
updateConf("keydb_api", CStr(MySettings.Keydb_Api.Value), m1)
|
||||
updateConf("backend", CStr(MySettings.OFS_BACKEND.Value), m1)
|
||||
|
||||
If Not CStr(MySettings.OFS_KEYS_Key.Value).IsEmptyString And Not CStr(MySettings.OFS_KEYS_ClientID.Value).IsEmptyString Then
|
||||
updateConf("private-key", CStr(MySettings.OFS_KEYS_Key.Value).Replace("\", "/"), m3)
|
||||
@@ -730,6 +758,7 @@ Namespace API.OnlyFans
|
||||
If IsSingleObjectDownload Then
|
||||
URL = Media.URL_BASE
|
||||
Else
|
||||
If Not _NameUpdated Then GetUserID(True)
|
||||
URL = GetPostUrl(Me, Media)
|
||||
End If
|
||||
If Not URL.IsEmptyString Then
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.OnlyFans
|
||||
Friend Class UserExchangeOptions
|
||||
Friend Class UserExchangeOptions : Inherits Base.EditorExchangeOptionsBase
|
||||
<PSetting(NameOf(SiteSettings.DownloadTimeline), NameOf(MySettings))>
|
||||
Friend Property DownloadTimeline As Boolean
|
||||
<PSetting(NameOf(SiteSettings.DownloadStories), NameOf(MySettings))>
|
||||
@@ -18,7 +18,12 @@ Namespace API.OnlyFans
|
||||
<PSetting(NameOf(SiteSettings.DownloadChatMedia), NameOf(MySettings))>
|
||||
Friend Property DownloadChatMedia As Boolean
|
||||
Private ReadOnly MySettings As SiteSettings
|
||||
<PSetting(Address:=SettingAddress.None)> Friend Overrides Property UserName As String
|
||||
Private Sub New()
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
MyBase.New(u)
|
||||
_ApplyBase_Name = False
|
||||
DownloadTimeline = u.MediaDownloadTimeline
|
||||
DownloadStories = u.MediaDownloadStories
|
||||
DownloadHighlights = u.MediaDownloadHighlights
|
||||
@@ -26,6 +31,8 @@ Namespace API.OnlyFans
|
||||
MySettings = u.HOST.Source
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
_ApplyBase_Name = False
|
||||
DownloadTimeline = s.DownloadTimeline.Value
|
||||
DownloadStories = s.DownloadStories.Value
|
||||
DownloadHighlights = s.DownloadHighlights.Value
|
||||
|
||||
@@ -21,6 +21,9 @@ Namespace API.Pinterest
|
||||
Private ReadOnly Property MyConcurrentDownloadsProvider As IFormatProvider
|
||||
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
@@ -31,6 +34,7 @@ Namespace API.Pinterest
|
||||
CheckNetscapeCookiesOnEndInit = True
|
||||
UseNetscapeCookies = True
|
||||
UserRegex = RParams.DMS("https?://w{0,3}.?[^/]*?.?pinterest.com/([^/]+)/?(?(_)|([^/]*))/?([^/\?]*)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
|
||||
UserOptionsType = GetType(EditorExchangeOptions)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "GetInstance, Available"
|
||||
@@ -72,12 +76,6 @@ Namespace API.Pinterest
|
||||
Return String.Empty
|
||||
End If
|
||||
End Function
|
||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||
If Options Is Nothing Then Options = New EditorExchangeOptions
|
||||
If OpenForm Then
|
||||
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -170,6 +170,7 @@ Namespace API.Pinterest
|
||||
urls.ListAddList(GetDataFromGalleryDL(URL, True, Token), LNC)
|
||||
If urls.ListExists Then urls.RemoveAll(Function(__url) Not __url.Contains("BoardsResource/get/"))
|
||||
If urls.ListExists Then
|
||||
Responser.Headers.Add(PwsHeader)
|
||||
ProgressPre.ChangeMax(urls.Count)
|
||||
For Each URL In urls
|
||||
ProgressPre.Perform()
|
||||
@@ -193,6 +194,8 @@ Namespace API.Pinterest
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data (gallery-dl boards) downloading error [{URL}]")
|
||||
Return Nothing
|
||||
Finally
|
||||
Responser.Headers.Remove(PwsHeader)
|
||||
End Try
|
||||
End Function
|
||||
Private Sub DownloadBoardImages(ByRef Board As BoardInfo, ByVal Token As CancellationToken)
|
||||
|
||||
@@ -20,7 +20,7 @@ Namespace API.PornHub
|
||||
Friend ReadOnly RegexVideo_FlashVars_Vars As RParams = RParams.DM("var ([\w\d]{10,})=("".+?)(?=(;|\Z))", 0, RegexReturn.List)
|
||||
Friend ReadOnly RegexVideo_FlashVars_Compiler As RParams = RParams.DM("(?<=\*/)([\w\d\S]{10,})", 0, RegexReturn.List)
|
||||
Friend ReadOnly RegexVideo_FlashVars_UrlResolution As RParams = RParams.DMS("/(\d+)[^/]+\.mp4", 1, EDP.ReturnValue)
|
||||
Friend ReadOnly RegexUserVideos As RParams = RParams.DM("(\<li class=""pcVideoListItem)((?:(?!/li\>).)*?)(\<div.class=.private-vid-title((?:(?!/li\>).)*?)|)(\<a.href=.([^""]+?)"".title=.([^""]*?)"")(((?:(?!/li\>).)+?)(\<div class=.videoUploaderBlock)|)((?:(?!/li\>).)*?)(\</li\>)",
|
||||
Friend ReadOnly RegexUserVideos As RParams = RParams.DM("(\<li class=""pcVideoListItem)((?:(?!/li\>).)*?)(\<div.class=.private-vid-title((?:(?!/li\>).)*?)|)(\<a.href=.([^""]+?)"".title=.([^""]*?)"")(((?:(?!/li\>).)+?)(\<div class=.videoUploaderBlock.*?href=""([^""]+)"")|)((?:(?!/li\>).)*?)(\</li\>)",
|
||||
0, RegexOptions.Singleline, RegexReturn.List, EDP.ReturnValue, UnicodeHexConverter)
|
||||
Friend ReadOnly RegexVideo_Video_VideoKey As RParams = RParams.DMS("viewkey=([\w\d]+)", 1, EDP.ReturnValue)
|
||||
Friend ReadOnly RegexVideoPageTitle As RParams = RParams.DMS("meta (property|name)=""[^:]+?:title"" content=""([^""]+)""", 2, EDP.ReturnValue)
|
||||
|
||||
@@ -31,6 +31,9 @@ Namespace API.PornHub
|
||||
Friend ReadOnly Property DownloadGifsAsMp4 As PropertyValue
|
||||
<PropertyOption(ControlText:=DeclaredNames.SavedPostsUserNameCaption, ControlToolTip:=DeclaredNames.SavedPostsUserNameToolTip), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property SavedPostsUserName As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
|
||||
@@ -15,7 +15,7 @@ Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.PornHub
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Friend Class UserData : Inherits UserDataBase : Implements IPSite
|
||||
Private Const UrlPattern As String = "https://www.pornhub.com/{0}"
|
||||
#Region "Declarations"
|
||||
#Region "XML names"
|
||||
@@ -50,6 +50,7 @@ Namespace API.PornHub
|
||||
Friend URL As String
|
||||
Friend ID As String
|
||||
Friend Title As String
|
||||
Friend UserRef As String
|
||||
Friend Type As VideoTypes
|
||||
Friend Function ToUserMedia(Optional ByVal SpecialFolder As String = Nothing) As UserMedia
|
||||
Return New UserMedia(URL, UTypes.VideoPre) With {
|
||||
@@ -66,14 +67,16 @@ Namespace API.PornHub
|
||||
URL = String.Empty
|
||||
Else
|
||||
URL = String.Format(UrlPattern, URL.TrimStart("/"))
|
||||
|
||||
Title = TitleHtmlConverter(ParamsArray(1))
|
||||
If Not ParamsArray(2).IsEmptyString Then
|
||||
Type = VideoTypes.Private
|
||||
ElseIf Not ParamsArray(3).IsEmptyString Then
|
||||
Type = VideoTypes.Tagged
|
||||
'ElseIf Not ParamsArray(3).IsEmptyString Then
|
||||
' Type = VideoTypes.Tagged
|
||||
Else
|
||||
Type = VideoTypes.Uploaded
|
||||
End If
|
||||
If Not ParamsArray(3).IsEmptyString Then UserRef = ParamsArray(3).StringTrim
|
||||
End If
|
||||
End If
|
||||
Return Me
|
||||
@@ -140,7 +143,7 @@ Namespace API.PornHub
|
||||
End Get
|
||||
End Property
|
||||
Friend Property SiteMode As SiteModes = SiteModes.User
|
||||
Friend Property QueryString As String
|
||||
Friend Property QueryString As String Implements IPSite.QueryString
|
||||
Get
|
||||
If IsUser Then
|
||||
Return String.Empty
|
||||
@@ -163,17 +166,7 @@ Namespace API.PornHub
|
||||
Return New UserExchangeOptions(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
||||
With DirectCast(Obj, UserExchangeOptions)
|
||||
DownloadUHD = .DownloadUHD
|
||||
DownloadUploaded = .DownloadUploaded
|
||||
DownloadTagged = .DownloadTagged
|
||||
DownloadPrivate = .DownloadPrivate
|
||||
DownloadFavorite = .DownloadFavorite
|
||||
DownloadGifs = .DownloadGifs
|
||||
QueryString = .QueryString
|
||||
End With
|
||||
End If
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then DirectCast(Obj, UserExchangeOptions).Apply(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
Private ReadOnly Property MySettings As SiteSettings
|
||||
@@ -195,7 +188,7 @@ Namespace API.PornHub
|
||||
If Not Force OrElse (Not IsUser AndAlso Not SiteMode = SiteModes.Playlists AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
|
||||
Dim eObj As Plugin.ExchangeOptions = Nothing
|
||||
If Force Then eObj = MySettings.IsMyUser(NewUrl)
|
||||
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And Not Name.IsEmptyString And NameTrue.IsEmptyString) Then
|
||||
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And Not Name.IsEmptyString And NameTrue(True).IsEmptyString) Then
|
||||
If Not If(Force, eObj.Options, Options).IsEmptyString Then
|
||||
If (IsUser Or SiteMode = SiteModes.Playlists) And Force Then
|
||||
Return False
|
||||
@@ -241,7 +234,7 @@ Namespace API.PornHub
|
||||
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
|
||||
UpdateUserOptions()
|
||||
Else
|
||||
If UpdateUserOptions() Then .Value(Name_LabelsName) = LabelsString
|
||||
If UpdateUserOptions() Then .Value(Name_LabelsName) = LabelsString : .Value(Name_TrueName) = NameTrue(True)
|
||||
.Add(Name_PersonType, PersonType)
|
||||
.Add(Name_DownloadUHD, DownloadUHD.BoolToInteger)
|
||||
.Add(Name_DownloadUploaded, DownloadUploaded.BoolToInteger)
|
||||
@@ -348,10 +341,13 @@ Namespace API.PornHub
|
||||
Dim tryNextPage As Boolean = False
|
||||
Dim limit% = If(DownloadTopCount, -1)
|
||||
Dim cBefore% = _TempMediaList.Count
|
||||
Dim usrRef$ = String.Empty
|
||||
Dim npd$ = "?"
|
||||
If IsUser Then
|
||||
URL = $"https://www.pornhub.com/{PersonType}/{NameTrue}"
|
||||
usrRef = $"/{PersonType}/{NameTrue}"
|
||||
If Type = VideoTypes.Uploaded Then
|
||||
URL &= "/videos/upload"
|
||||
If Not PersonType = PersonTypeCannel Then URL &= "/videos/upload?o=mr" : npd = "&"
|
||||
ElseIf Type = VideoTypes.Tagged Then
|
||||
If Not SecondMode Then URL &= "/videos"
|
||||
specFolder = "Tagged"
|
||||
@@ -364,7 +360,7 @@ Namespace API.PornHub
|
||||
Else
|
||||
Throw New ArgumentException($"Type '{Type}' is not implemented in the video download function", "Type")
|
||||
End If
|
||||
If Page > 1 Then URL &= $"?page={Page}"
|
||||
If Page > 1 Then URL &= $"{npd}page={Page}"
|
||||
ElseIf SiteMode = SiteModes.Playlists Then
|
||||
If PlaylistToken.IsEmptyString Then Throw New ArgumentNullException("PlaylistToken", "Unable to get 'PlaylistToken'")
|
||||
URL = String.Format(PlayListUrlPattern, NameTrue, PlaylistToken, Page)
|
||||
@@ -377,12 +373,21 @@ Namespace API.PornHub
|
||||
'Debug.WriteLine(URL)
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
If Not r.IsEmptyString Then
|
||||
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexUserVideos}, {6, 7, 3, 10})
|
||||
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexUserVideos}, {6, 7, 3, 11})
|
||||
'If l.ListExists And Not SiteMode = SiteModes.Playlists Then l = l.ListTake(3, l.Count).ToList
|
||||
If l.ListExists And Not SiteMode = SiteModes.Playlists Then l = l.ListTake(1, l.Count).ToList
|
||||
If l.ListExists And Not SiteMode = SiteModes.Playlists And Not IsUser Then l = l.ListTake(1, l.Count).ToList
|
||||
If l.ListExists Then
|
||||
If IsUser Then
|
||||
If Type = VideoTypes.Favorite Then
|
||||
If Type = VideoTypes.Tagged Then
|
||||
l = l.ListTake(4, l.Count)
|
||||
If l.ListExists Then l.RemoveAll(Function(uv) Not uv.UserRef.IsEmptyString AndAlso uv.UserRef = usrRef)
|
||||
ElseIf Type = VideoTypes.Uploaded Then
|
||||
If PersonType = PersonTypeCannel Then
|
||||
l = l.ListTake(4, l.Count)
|
||||
Else
|
||||
l.RemoveAll(Function(uv) uv.UserRef.IsEmptyString OrElse Not uv.UserRef = usrRef)
|
||||
End If
|
||||
ElseIf Type = VideoTypes.Favorite Then
|
||||
l.RemoveAll(Function(uv) uv.Type = VideoTypes.Private)
|
||||
ElseIf Not PersonType = PersonTypeCannel Then
|
||||
l.RemoveAll(Function(uv) Not uv.Type = Type)
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.PornHub
|
||||
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
|
||||
Friend Class UserExchangeOptions : Inherits EditorExchangeOptionsBase_P
|
||||
<PSetting(NameOf(SiteSettings.DownloadUHD), NameOf(MySettings))>
|
||||
Friend Property DownloadUHD As Boolean
|
||||
<PSetting(NameOf(SiteSettings.DownloadUploaded), NameOf(MySettings))>
|
||||
@@ -23,16 +24,17 @@ Namespace API.PornHub
|
||||
Friend Property DownloadGifs As Boolean
|
||||
Private ReadOnly Property MySettings As SiteSettings
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
MyBase.New(u)
|
||||
DownloadUHD = u.DownloadUHD
|
||||
DownloadUploaded = u.DownloadUploaded
|
||||
DownloadTagged = u.DownloadTagged
|
||||
DownloadPrivate = u.DownloadPrivate
|
||||
DownloadFavorite = u.DownloadFavorite
|
||||
DownloadGifs = u.DownloadGifs
|
||||
QueryString = u.QueryString
|
||||
MySettings = u.HOST.Source
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
Dim v As CheckState = CInt(s.DownloadGifs.Value)
|
||||
DownloadUHD = s.DownloadUHD.Value
|
||||
DownloadUploaded = s.DownloadUploaded.Value
|
||||
@@ -42,5 +44,16 @@ Namespace API.PornHub
|
||||
DownloadGifs = Not v = CheckState.Unchecked
|
||||
MySettings = s
|
||||
End Sub
|
||||
Friend Overrides Sub Apply(ByRef u As IPSite)
|
||||
MyBase.Apply(u)
|
||||
With DirectCast(u, UserData)
|
||||
.DownloadUHD = DownloadUHD
|
||||
.DownloadUploaded = DownloadUploaded
|
||||
.DownloadTagged = DownloadTagged
|
||||
.DownloadPrivate = DownloadPrivate
|
||||
.DownloadFavorite = DownloadFavorite
|
||||
.DownloadGifs = DownloadGifs
|
||||
End With
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -88,14 +88,22 @@ Namespace API.Reddit
|
||||
End Property
|
||||
Friend Property ViewMode As View = View.New Implements IRedditView.ViewMode
|
||||
Friend Property ViewPeriod As Period = Period.All Implements IRedditView.ViewPeriod
|
||||
Friend Property DownloadText As Boolean = False Implements IRedditView.DownloadText
|
||||
Friend Property DownloadTextPosts As Boolean = False Implements IRedditView.DownloadTextPosts
|
||||
Friend Property DownloadTextSpecialFolder As Boolean = False Implements IRedditView.DownloadTextSpecialFolder
|
||||
Friend Property RedGifsAccount As String = String.Empty Implements IRedditView.RedGifsAccount
|
||||
Friend Property RedditAccount As String = String.Empty Implements IRedditView.RedditAccount
|
||||
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
|
||||
If Not Options Is Nothing Then
|
||||
ViewMode = Options.ViewMode
|
||||
ViewPeriod = Options.ViewPeriod
|
||||
RedditAccount = Options.RedditAccount
|
||||
RedGifsAccount = Options.RedGifsAccount
|
||||
With Options
|
||||
ViewMode = .ViewMode
|
||||
ViewPeriod = .ViewPeriod
|
||||
DownloadText = .DownloadText
|
||||
DownloadTextPosts = .DownloadTextPosts
|
||||
DownloadTextSpecialFolder = .DownloadTextSpecialFolder
|
||||
RedditAccount = .RedditAccount
|
||||
RedGifsAccount = .RedGifsAccount
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
#Region "Statistics support"
|
||||
|
||||
@@ -21,6 +21,6 @@ Namespace API.Reddit
|
||||
Friend ReadOnly UrlBasePattern As RParams = RParams.DM("(?<=/)([^/]+?\.[\w]{3,4})(?=(\?|\Z))", 0)
|
||||
Friend ReadOnly VideoRegEx As RParams = RParams.DM("http.{0,1}://[^" & Chr(34) & "]+?mp4", 0)
|
||||
Private ReadOnly EUR_PROVIDER As New ANumbers(ANumbers.Cultures.EUR)
|
||||
Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Double)(v, EUR_PROVIDER, v), n, e))
|
||||
<Obsolete("Use 'UnixDate32Provider'", True)> Friend ReadOnly UnixDate32ProviderReddit As New CustomProvider(Function(v, d, p, n, e) ADateTime.ParseUnix32(AConvert(Of Double)(v, EUR_PROVIDER, v), n, e))
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -12,6 +12,8 @@ Namespace API.Reddit
|
||||
[New] = 0
|
||||
Hot = 1
|
||||
Top = 2
|
||||
Best = 3
|
||||
Rising = 4
|
||||
End Enum
|
||||
Enum Period As Integer
|
||||
All = 0
|
||||
@@ -23,25 +25,45 @@ Namespace API.Reddit
|
||||
End Enum
|
||||
Property ViewMode As View
|
||||
Property ViewPeriod As Period
|
||||
Property DownloadText As Boolean
|
||||
Property DownloadTextPosts As Boolean
|
||||
Property DownloadTextSpecialFolder As Boolean
|
||||
Property RedGifsAccount As String
|
||||
Property RedditAccount As String
|
||||
Sub SetView(ByVal Options As IRedditView)
|
||||
End Interface
|
||||
Friend Class RedditViewExchange : Implements IRedditView
|
||||
Friend Class RedditViewExchange : Inherits Base.EditorExchangeOptionsBase : Implements IRedditView
|
||||
Friend Const Name_ViewMode As String = "ViewMode"
|
||||
Friend Const Name_ViewPeriod As String = "ViewPeriod"
|
||||
Friend Const Name_RedGifsAccount As String = "RedGifsAccount"
|
||||
Friend Const Name_RedditAccount As String = "RedditAccount"
|
||||
Friend Property ViewMode As IRedditView.View Implements IRedditView.ViewMode
|
||||
Friend Property ViewPeriod As IRedditView.Period Implements IRedditView.ViewPeriod
|
||||
Friend Overrides Property DownloadText As Boolean Implements IRedditView.DownloadText
|
||||
Friend Overrides Property DownloadTextPosts As Boolean Implements IRedditView.DownloadTextPosts
|
||||
Friend Overrides Property DownloadTextSpecialFolder As Boolean Implements IRedditView.DownloadTextSpecialFolder
|
||||
Friend Property RedGifsAccount As String Implements IRedditView.RedGifsAccount
|
||||
Friend Property RedditAccount As String Implements IRedditView.RedditAccount
|
||||
Friend Sub New(ByVal Options As IRedditView)
|
||||
MyBase.New(DirectCast(Options, UserData))
|
||||
SetView(Options)
|
||||
_ApplyBase_Name = False
|
||||
End Sub
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
_ApplyBase_Name = False
|
||||
End Sub
|
||||
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
|
||||
If Not Options Is Nothing Then
|
||||
ViewMode = Options.ViewMode
|
||||
ViewPeriod = Options.ViewPeriod
|
||||
RedGifsAccount = Options.RedGifsAccount
|
||||
RedditAccount = Options.RedditAccount
|
||||
With Options
|
||||
ViewMode = .ViewMode
|
||||
ViewPeriod = .ViewPeriod
|
||||
DownloadText = .DownloadText
|
||||
DownloadTextPosts = .DownloadTextPosts
|
||||
DownloadTextSpecialFolder = .DownloadTextSpecialFolder
|
||||
RedGifsAccount = .RedGifsAccount
|
||||
RedditAccount = .RedditAccount
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
154
SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb
generated
154
SCrawler/API/Reddit/RedditViewSettingsForm.Designer.vb
generated
@@ -22,17 +22,21 @@ Namespace API.Reddit
|
||||
Private components As System.ComponentModel.IContainer
|
||||
<System.Diagnostics.DebuggerStepThrough()>
|
||||
Private Sub InitializeComponent()
|
||||
Me.components = New System.ComponentModel.Container()
|
||||
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
|
||||
Dim TP_VIEW_MODE As System.Windows.Forms.TableLayoutPanel
|
||||
Dim LBL_VIEW_MODE As System.Windows.Forms.Label
|
||||
Dim LBL_PERIOD As System.Windows.Forms.Label
|
||||
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(RedditViewSettingsForm))
|
||||
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
|
||||
Dim TP_TEXT As System.Windows.Forms.TableLayoutPanel
|
||||
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.OPT_VIEW_MODE_NEW = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_VIEW_MODE_HOT = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_VIEW_MODE_TOP = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_VIEW_MODE_BEST = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_VIEW_MODE_RISING = New System.Windows.Forms.RadioButton()
|
||||
Me.TP_PERIOD = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.OPT_PERIOD_ALL = New System.Windows.Forms.RadioButton()
|
||||
Me.OPT_PERIOD_HOUR = New System.Windows.Forms.RadioButton()
|
||||
@@ -42,10 +46,15 @@ Namespace API.Reddit
|
||||
Me.OPT_PERIOD_YEAR = New System.Windows.Forms.RadioButton()
|
||||
Me.CMB_REDGIFS_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||
Me.CMB_REDDIT_ACC = New PersonalUtilities.Forms.Controls.ComboBoxExtended()
|
||||
Me.CH_TXT_DOWN_TXT = New System.Windows.Forms.CheckBox()
|
||||
Me.CH_TXT_DOWN_POSTS = New System.Windows.Forms.CheckBox()
|
||||
Me.TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER = New System.Windows.Forms.CheckBox()
|
||||
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
|
||||
TP_VIEW_MODE = New System.Windows.Forms.TableLayoutPanel()
|
||||
LBL_VIEW_MODE = New System.Windows.Forms.Label()
|
||||
LBL_PERIOD = New System.Windows.Forms.Label()
|
||||
TP_TEXT = New System.Windows.Forms.TableLayoutPanel()
|
||||
CONTAINER_MAIN.ContentPanel.SuspendLayout()
|
||||
CONTAINER_MAIN.SuspendLayout()
|
||||
Me.TP_MAIN.SuspendLayout()
|
||||
@@ -53,6 +62,7 @@ Namespace API.Reddit
|
||||
Me.TP_PERIOD.SuspendLayout()
|
||||
CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).BeginInit()
|
||||
TP_TEXT.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
'CONTAINER_MAIN
|
||||
@@ -61,13 +71,13 @@ Namespace API.Reddit
|
||||
'CONTAINER_MAIN.ContentPanel
|
||||
'
|
||||
CONTAINER_MAIN.ContentPanel.Controls.Add(Me.TP_MAIN)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 169)
|
||||
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(477, 222)
|
||||
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
CONTAINER_MAIN.LeftToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
|
||||
CONTAINER_MAIN.RightToolStripPanelVisible = False
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(477, 169)
|
||||
CONTAINER_MAIN.Size = New System.Drawing.Size(477, 222)
|
||||
CONTAINER_MAIN.TabIndex = 0
|
||||
CONTAINER_MAIN.TopToolStripPanelVisible = False
|
||||
'
|
||||
@@ -78,18 +88,20 @@ Namespace API.Reddit
|
||||
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MAIN.Controls.Add(TP_VIEW_MODE, 0, 0)
|
||||
Me.TP_MAIN.Controls.Add(Me.TP_PERIOD, 0, 1)
|
||||
Me.TP_MAIN.Controls.Add(Me.CMB_REDGIFS_ACC, 0, 3)
|
||||
Me.TP_MAIN.Controls.Add(Me.CMB_REDDIT_ACC, 0, 2)
|
||||
Me.TP_MAIN.Controls.Add(Me.CMB_REDGIFS_ACC, 0, 4)
|
||||
Me.TP_MAIN.Controls.Add(Me.CMB_REDDIT_ACC, 0, 3)
|
||||
Me.TP_MAIN.Controls.Add(TP_TEXT, 0, 2)
|
||||
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
|
||||
Me.TP_MAIN.Name = "TP_MAIN"
|
||||
Me.TP_MAIN.RowCount = 5
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
Me.TP_MAIN.RowCount = 6
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 56.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
Me.TP_MAIN.Size = New System.Drawing.Size(477, 169)
|
||||
Me.TP_MAIN.Size = New System.Drawing.Size(477, 222)
|
||||
Me.TP_MAIN.TabIndex = 0
|
||||
'
|
||||
'TP_VIEW_MODE
|
||||
@@ -103,14 +115,16 @@ Namespace API.Reddit
|
||||
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_NEW, 1, 0)
|
||||
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_HOT, 2, 0)
|
||||
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_TOP, 3, 0)
|
||||
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_BEST, 1, 1)
|
||||
TP_VIEW_MODE.Controls.Add(Me.OPT_VIEW_MODE_RISING, 2, 1)
|
||||
TP_VIEW_MODE.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_VIEW_MODE.Location = New System.Drawing.Point(1, 1)
|
||||
TP_VIEW_MODE.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_VIEW_MODE.Name = "TP_VIEW_MODE"
|
||||
TP_VIEW_MODE.RowCount = 1
|
||||
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
|
||||
TP_VIEW_MODE.Size = New System.Drawing.Size(475, 28)
|
||||
TP_VIEW_MODE.RowCount = 2
|
||||
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_VIEW_MODE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
|
||||
TP_VIEW_MODE.Size = New System.Drawing.Size(475, 56)
|
||||
TP_VIEW_MODE.TabIndex = 0
|
||||
'
|
||||
'LBL_VIEW_MODE
|
||||
@@ -160,6 +174,30 @@ Namespace API.Reddit
|
||||
Me.OPT_VIEW_MODE_TOP.Text = "Top"
|
||||
Me.OPT_VIEW_MODE_TOP.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OPT_VIEW_MODE_BEST
|
||||
'
|
||||
Me.OPT_VIEW_MODE_BEST.AutoSize = True
|
||||
Me.OPT_VIEW_MODE_BEST.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_VIEW_MODE_BEST.Location = New System.Drawing.Point(121, 31)
|
||||
Me.OPT_VIEW_MODE_BEST.Name = "OPT_VIEW_MODE_BEST"
|
||||
Me.OPT_VIEW_MODE_BEST.Size = New System.Drawing.Size(112, 22)
|
||||
Me.OPT_VIEW_MODE_BEST.TabIndex = 4
|
||||
Me.OPT_VIEW_MODE_BEST.TabStop = True
|
||||
Me.OPT_VIEW_MODE_BEST.Text = "Best"
|
||||
Me.OPT_VIEW_MODE_BEST.UseVisualStyleBackColor = True
|
||||
'
|
||||
'OPT_VIEW_MODE_RISING
|
||||
'
|
||||
Me.OPT_VIEW_MODE_RISING.AutoSize = True
|
||||
Me.OPT_VIEW_MODE_RISING.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.OPT_VIEW_MODE_RISING.Location = New System.Drawing.Point(239, 31)
|
||||
Me.OPT_VIEW_MODE_RISING.Name = "OPT_VIEW_MODE_RISING"
|
||||
Me.OPT_VIEW_MODE_RISING.Size = New System.Drawing.Size(112, 22)
|
||||
Me.OPT_VIEW_MODE_RISING.TabIndex = 5
|
||||
Me.OPT_VIEW_MODE_RISING.TabStop = True
|
||||
Me.OPT_VIEW_MODE_RISING.Text = "Rising"
|
||||
Me.OPT_VIEW_MODE_RISING.UseVisualStyleBackColor = True
|
||||
'
|
||||
'TP_PERIOD
|
||||
'
|
||||
Me.TP_PERIOD.ColumnCount = 4
|
||||
@@ -175,7 +213,7 @@ Namespace API.Reddit
|
||||
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_MONTH, 2, 1)
|
||||
Me.TP_PERIOD.Controls.Add(Me.OPT_PERIOD_YEAR, 3, 1)
|
||||
Me.TP_PERIOD.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.TP_PERIOD.Location = New System.Drawing.Point(1, 30)
|
||||
Me.TP_PERIOD.Location = New System.Drawing.Point(1, 58)
|
||||
Me.TP_PERIOD.Margin = New System.Windows.Forms.Padding(0)
|
||||
Me.TP_PERIOD.Name = "TP_PERIOD"
|
||||
Me.TP_PERIOD.RowCount = 2
|
||||
@@ -269,17 +307,17 @@ Namespace API.Reddit
|
||||
'
|
||||
'CMB_REDGIFS_ACC
|
||||
'
|
||||
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton1.Name = "ArrowDown"
|
||||
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
|
||||
Me.CMB_REDGIFS_ACC.Buttons.Add(ActionButton1)
|
||||
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton3.Name = "ArrowDown"
|
||||
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
|
||||
Me.CMB_REDGIFS_ACC.Buttons.Add(ActionButton3)
|
||||
Me.CMB_REDGIFS_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
|
||||
Me.CMB_REDGIFS_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent
|
||||
Me.CMB_REDGIFS_ACC.CaptionText = "RedGifs account"
|
||||
Me.CMB_REDGIFS_ACC.CaptionVisible = True
|
||||
Me.CMB_REDGIFS_ACC.CaptionWidth = 26.0R
|
||||
Me.CMB_REDGIFS_ACC.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CMB_REDGIFS_ACC.Location = New System.Drawing.Point(4, 119)
|
||||
Me.CMB_REDGIFS_ACC.Location = New System.Drawing.Point(4, 173)
|
||||
Me.CMB_REDGIFS_ACC.Name = "CMB_REDGIFS_ACC"
|
||||
Me.CMB_REDGIFS_ACC.Size = New System.Drawing.Size(469, 22)
|
||||
Me.CMB_REDGIFS_ACC.TabIndex = 4
|
||||
@@ -287,35 +325,89 @@ Namespace API.Reddit
|
||||
'
|
||||
'CMB_REDDIT_ACC
|
||||
'
|
||||
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton2.Name = "ArrowDown"
|
||||
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
|
||||
Me.CMB_REDDIT_ACC.Buttons.Add(ActionButton2)
|
||||
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
|
||||
ActionButton4.Name = "ArrowDown"
|
||||
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.ArrowDown
|
||||
Me.CMB_REDDIT_ACC.Buttons.Add(ActionButton4)
|
||||
Me.CMB_REDDIT_ACC.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.Label
|
||||
Me.CMB_REDDIT_ACC.CaptionSizeType = System.Windows.Forms.SizeType.Percent
|
||||
Me.CMB_REDDIT_ACC.CaptionText = "Reddit account"
|
||||
Me.CMB_REDDIT_ACC.CaptionVisible = True
|
||||
Me.CMB_REDDIT_ACC.CaptionWidth = 26.0R
|
||||
Me.CMB_REDDIT_ACC.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CMB_REDDIT_ACC.Location = New System.Drawing.Point(4, 90)
|
||||
Me.CMB_REDDIT_ACC.Location = New System.Drawing.Point(4, 144)
|
||||
Me.CMB_REDDIT_ACC.Name = "CMB_REDDIT_ACC"
|
||||
Me.CMB_REDDIT_ACC.Size = New System.Drawing.Size(469, 22)
|
||||
Me.CMB_REDDIT_ACC.TabIndex = 3
|
||||
Me.CMB_REDDIT_ACC.TextBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
|
||||
'
|
||||
'TP_TEXT
|
||||
'
|
||||
TP_TEXT.ColumnCount = 3
|
||||
TP_TEXT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_TEXT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_TEXT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
|
||||
TP_TEXT.Controls.Add(Me.CH_TXT_DOWN_TXT, 0, 0)
|
||||
TP_TEXT.Controls.Add(Me.CH_TXT_DOWN_POSTS, 1, 0)
|
||||
TP_TEXT.Controls.Add(Me.CH_TXT_DOWN_SPEC_FOLDER, 2, 0)
|
||||
TP_TEXT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
TP_TEXT.Location = New System.Drawing.Point(1, 115)
|
||||
TP_TEXT.Margin = New System.Windows.Forms.Padding(0)
|
||||
TP_TEXT.Name = "TP_TEXT"
|
||||
TP_TEXT.RowCount = 1
|
||||
TP_TEXT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
|
||||
TP_TEXT.Size = New System.Drawing.Size(475, 25)
|
||||
TP_TEXT.TabIndex = 5
|
||||
'
|
||||
'CH_TXT_DOWN_TXT
|
||||
'
|
||||
Me.CH_TXT_DOWN_TXT.AutoSize = True
|
||||
Me.CH_TXT_DOWN_TXT.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_TXT_DOWN_TXT.Location = New System.Drawing.Point(3, 3)
|
||||
Me.CH_TXT_DOWN_TXT.Name = "CH_TXT_DOWN_TXT"
|
||||
Me.CH_TXT_DOWN_TXT.Size = New System.Drawing.Size(152, 19)
|
||||
Me.CH_TXT_DOWN_TXT.TabIndex = 0
|
||||
Me.CH_TXT_DOWN_TXT.Text = "Download text"
|
||||
Me.TT_MAIN.SetToolTip(Me.CH_TXT_DOWN_TXT, "Download text (if available) for posts with image and video")
|
||||
Me.CH_TXT_DOWN_TXT.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_TXT_DOWN_POSTS
|
||||
'
|
||||
Me.CH_TXT_DOWN_POSTS.AutoSize = True
|
||||
Me.CH_TXT_DOWN_POSTS.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_TXT_DOWN_POSTS.Location = New System.Drawing.Point(161, 3)
|
||||
Me.CH_TXT_DOWN_POSTS.Name = "CH_TXT_DOWN_POSTS"
|
||||
Me.CH_TXT_DOWN_POSTS.Size = New System.Drawing.Size(152, 19)
|
||||
Me.CH_TXT_DOWN_POSTS.TabIndex = 1
|
||||
Me.CH_TXT_DOWN_POSTS.Text = "Download text posts"
|
||||
Me.TT_MAIN.SetToolTip(Me.CH_TXT_DOWN_POSTS, "Download text (if available) for text posts (no image and video)")
|
||||
Me.CH_TXT_DOWN_POSTS.UseVisualStyleBackColor = True
|
||||
'
|
||||
'CH_TXT_DOWN_SPEC_FOLDER
|
||||
'
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.AutoSize = True
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.Location = New System.Drawing.Point(319, 3)
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.Name = "CH_TXT_DOWN_SPEC_FOLDER"
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.Size = New System.Drawing.Size(153, 19)
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.TabIndex = 2
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.Text = "Text special folder"
|
||||
Me.TT_MAIN.SetToolTip(Me.CH_TXT_DOWN_SPEC_FOLDER, "If checked, text files will be saved to a separate folder")
|
||||
Me.CH_TXT_DOWN_SPEC_FOLDER.UseVisualStyleBackColor = True
|
||||
'
|
||||
'RedditViewSettingsForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
|
||||
Me.ClientSize = New System.Drawing.Size(477, 169)
|
||||
Me.ClientSize = New System.Drawing.Size(477, 222)
|
||||
Me.Controls.Add(CONTAINER_MAIN)
|
||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||
Me.Icon = Global.SCrawler.My.Resources.SiteResources.RedditIcon_128
|
||||
Me.KeyPreview = True
|
||||
Me.MaximizeBox = False
|
||||
Me.MaximumSize = New System.Drawing.Size(493, 208)
|
||||
Me.MaximumSize = New System.Drawing.Size(493, 261)
|
||||
Me.MinimizeBox = False
|
||||
Me.MinimumSize = New System.Drawing.Size(493, 208)
|
||||
Me.MinimumSize = New System.Drawing.Size(493, 261)
|
||||
Me.Name = "RedditViewSettingsForm"
|
||||
Me.ShowInTaskbar = False
|
||||
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
|
||||
@@ -330,6 +422,8 @@ Namespace API.Reddit
|
||||
Me.TP_PERIOD.PerformLayout()
|
||||
CType(Me.CMB_REDGIFS_ACC, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
CType(Me.CMB_REDDIT_ACC, System.ComponentModel.ISupportInitialize).EndInit()
|
||||
TP_TEXT.ResumeLayout(False)
|
||||
TP_TEXT.PerformLayout()
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
End Sub
|
||||
@@ -346,5 +440,11 @@ Namespace API.Reddit
|
||||
Private WithEvents CMB_REDGIFS_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||
Private WithEvents CMB_REDDIT_ACC As PersonalUtilities.Forms.Controls.ComboBoxExtended
|
||||
Private WithEvents TP_MAIN As TableLayoutPanel
|
||||
Private WithEvents OPT_VIEW_MODE_BEST As RadioButton
|
||||
Private WithEvents OPT_VIEW_MODE_RISING As RadioButton
|
||||
Private WithEvents CH_TXT_DOWN_TXT As CheckBox
|
||||
Private WithEvents TT_MAIN As ToolTip
|
||||
Private WithEvents CH_TXT_DOWN_POSTS As CheckBox
|
||||
Private WithEvents CH_TXT_DOWN_SPEC_FOLDER As CheckBox
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -130,184 +130,195 @@
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
AAAASUVORK5CYII=
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
AAAASUVORK5CYII=
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAYIj+H5YGIizEb/aEAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TP_TEXT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="LBL_VIEW_MODE.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="LBL_PERIOD.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -38,6 +38,8 @@ Namespace API.Reddit
|
||||
Select Case MyOptions.ViewMode
|
||||
Case CView.Hot : OPT_VIEW_MODE_HOT.Checked = True
|
||||
Case CView.Top : OPT_VIEW_MODE_TOP.Checked = True
|
||||
Case CView.Best : OPT_VIEW_MODE_BEST.Checked = True
|
||||
Case CView.Rising : OPT_VIEW_MODE_RISING.Checked = True
|
||||
Case Else : OPT_VIEW_MODE_NEW.Checked = True
|
||||
End Select
|
||||
Select Case MyOptions.ViewPeriod
|
||||
@@ -50,11 +52,15 @@ Namespace API.Reddit
|
||||
End Select
|
||||
ChangePeriodEnabled()
|
||||
|
||||
CH_TXT_DOWN_TXT.Checked = MyOptions.DownloadText
|
||||
CH_TXT_DOWN_POSTS.Checked = MyOptions.DownloadTextPosts
|
||||
CH_TXT_DOWN_SPEC_FOLDER.Checked = MyOptions.DownloadTextSpecialFolder
|
||||
|
||||
PopulateCMB(Settings(RedditSiteKey), CMB_REDDIT_ACC, MyOptions.RedditAccount)
|
||||
PopulateCMB(Settings(RedGifs.RedGifsSiteKey), CMB_REDGIFS_ACC, MyOptions.RedGifsAccount)
|
||||
If IsUserSettings Then
|
||||
TP_MAIN.Controls.Remove(CMB_REDDIT_ACC)
|
||||
TP_MAIN.RowStyles(2).Height = 0
|
||||
TP_MAIN.RowStyles(3).Height = 0
|
||||
TP_MAIN.Refresh()
|
||||
Dim s As Size = Size
|
||||
s.Height -= 28
|
||||
@@ -100,6 +106,8 @@ Namespace API.Reddit
|
||||
Select Case True
|
||||
Case OPT_VIEW_MODE_HOT.Checked : .ViewMode = CView.Hot
|
||||
Case OPT_VIEW_MODE_TOP.Checked : .ViewMode = CView.Top
|
||||
Case OPT_VIEW_MODE_BEST.Checked : .ViewMode = CView.Best
|
||||
Case OPT_VIEW_MODE_RISING.Checked : .ViewMode = CView.Rising
|
||||
Case Else : .ViewMode = CView.New
|
||||
End Select
|
||||
Select Case True
|
||||
@@ -110,6 +118,9 @@ Namespace API.Reddit
|
||||
Case OPT_PERIOD_YEAR.Checked : .ViewPeriod = CPeriod.Year
|
||||
Case Else : .ViewPeriod = CPeriod.All
|
||||
End Select
|
||||
.DownloadText = CH_TXT_DOWN_TXT.Checked
|
||||
.DownloadTextPosts = CH_TXT_DOWN_POSTS.Checked
|
||||
.DownloadTextSpecialFolder = CH_TXT_DOWN_SPEC_FOLDER.Checked
|
||||
.RedGifsAccount = CMB_REDGIFS_ACC.Text
|
||||
If Not IsUserSettings Then .RedditAccount = CMB_REDDIT_ACC.Text
|
||||
End With
|
||||
|
||||
@@ -9,26 +9,38 @@
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Imports System.Reflection
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Clients.Base
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports DN = SCrawler.API.Base.DeclaredNames
|
||||
Imports DownDetector = SCrawler.API.Base.DownDetector
|
||||
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||
Namespace API.Reddit
|
||||
<Manifest(RedditSiteKey), SavedPosts, SpecialForm(False), UseDownDetector>
|
||||
<Manifest(RedditSiteKey), SavedPosts, SeparatedTasks, SpecialForm(False), UseDownDetector>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase : Implements DownDetector.IDownDetector
|
||||
#Region "Declarations"
|
||||
#Region "Authorization"
|
||||
Private Const ApiClientID_Default As String = "dYctRA-SIJxyykHe27lGZg"
|
||||
Private Const ApiClientSecret_Default As String = "_5D6KzplRPDga-es1YlpzDIe9hiFlg"
|
||||
<PropertyOption(ControlText:="Login", ControlToolTip:="Your authorization username", IsAuth:=True), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property AuthUserName As PropertyValue
|
||||
<PropertyOption(ControlText:="Password", ControlToolTip:="Your authorization password", IsAuth:=True), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property AuthPassword As PropertyValue
|
||||
<PropertyOption(ControlText:="Client ID", ControlToolTip:="Your registered app client ID", IsAuth:=True), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property ApiClientID As PropertyValue
|
||||
<PropertyUpdater(NameOf(ApiClientID))> Private Function ApiClientID_SetDefault() As Boolean
|
||||
ApiClientID.Value = ApiClientID_Default
|
||||
Return True
|
||||
End Function
|
||||
<PropertyOption(ControlText:="Client Secret", ControlToolTip:="Your registered app client secret", IsAuth:=True), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property ApiClientSecret As PropertyValue
|
||||
<PropertyUpdater(NameOf(ApiClientSecret))> Private Function ApiClientSecret_SetDefault() As Boolean
|
||||
ApiClientSecret.Value = ApiClientSecret_Default
|
||||
Return True
|
||||
End Function
|
||||
<PropertyOption(ControlText:="Bearer token",
|
||||
ControlToolTip:="Bearer token (can be null)." & vbCr &
|
||||
"If you are using cookies to download the timeline, it is highly recommended that you add a token." & vbCr &
|
||||
@@ -58,14 +70,59 @@ Namespace API.Reddit
|
||||
Return {AuthUserName.Value, AuthPassword.Value, ApiClientID.Value, ApiClientSecret.Value}.All(Function(v$) Not v.IsEmptyString)
|
||||
End Get
|
||||
End Property
|
||||
<PropertiesDataChecker({NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret),
|
||||
NameOf(UseTokenForTimelines), NameOf(UseCookiesForTimelines)})>
|
||||
Private Function OAuthCredentialsChecker(ByVal p As IEnumerable(Of PropertyData)) As Boolean
|
||||
Const msgTitle$ = "OAuth credentials"
|
||||
If p.ListExists Then
|
||||
Dim useToken As Boolean = False, useCookies As Boolean = False
|
||||
Dim d$ = String.Empty
|
||||
Dim dCount As Byte = 0
|
||||
Dim members As IEnumerable(Of MemberInfo) = GetObjectMembers(Me)
|
||||
Dim getPropText As Func(Of String, String) = Function(name) members.First(Function(m) m.Name = name).GetCustomAttribute(Of PropertyOption).ControlText
|
||||
Dim dataStr As Action(Of String, String) = Sub(dd, name) If dd.IsEmptyString Then d.StringAppendLine(getPropText(name)) : dCount += 1
|
||||
For Each pp As PropertyData In p
|
||||
Select Case pp.Name
|
||||
Case NameOf(AuthUserName) : dataStr(pp.Value, NameOf(AuthUserName))
|
||||
Case NameOf(AuthPassword) : dataStr(pp.Value, NameOf(AuthPassword))
|
||||
Case NameOf(ApiClientID) : dataStr(pp.Value, NameOf(ApiClientID))
|
||||
Case NameOf(ApiClientSecret) : dataStr(pp.Value, NameOf(ApiClientSecret))
|
||||
Case NameOf(UseTokenForTimelines) : useToken = pp.Value
|
||||
Case NameOf(UseCookiesForTimelines) : useCookies = pp.Value
|
||||
Case Else : Throw New ArgumentException($"Property name '{pp.Name}' is not implemented", "Property Name")
|
||||
End Select
|
||||
Next
|
||||
If d.IsEmptyString Then
|
||||
If useToken And useCookies Then
|
||||
Return True
|
||||
Else
|
||||
If Not useToken Then d.StringAppendLine(getPropText(NameOf(UseTokenForTimelines)))
|
||||
If Not useCookies Then d.StringAppendLine(getPropText(NameOf(UseCookiesForTimelines)))
|
||||
MsgBoxE({$"You need to check the following options:{vbCr}{d}", msgTitle}, vbCritical)
|
||||
Return False
|
||||
End If
|
||||
ElseIf dCount = 4 Then
|
||||
Return MsgBoxE({$"You haven't configured OAuth. It's highly recommended to use OAuth.{vbCr}Do you still want to continue?", msgTitle},
|
||||
vbExclamation,,, {"Process", "Cancel"}) = 0
|
||||
Else
|
||||
MsgBoxE({$"You haven't filled in the following fields:{vbCr}{d}.{vbCr}{vbCr}" &
|
||||
"To use OAuth authorization, you must fill in all authorization fields.", msgTitle}, vbCritical)
|
||||
Return False
|
||||
End If
|
||||
End If
|
||||
Return True
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Other"
|
||||
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos", IsAuth:=False), PXML, PClonable>
|
||||
<PropertyOption(ControlText:="Use M3U8", ControlToolTip:="Use M3U8 or mp4 for Reddit videos"), PXML, PClonable, HiddenControl>
|
||||
Friend ReadOnly Property UseM3U8 As PropertyValue
|
||||
<PropertyOption(ControlText:="Check image", ControlToolTip:="Check the image if it exists before downloading (it makes downloading very slow)", IsAuth:=False), PXML, PClonable>
|
||||
<PropertyOption(ControlText:="Check image", ControlToolTip:="Check the image if it exists before downloading (it makes downloading very slow)"), PXML, PClonable, HiddenControl>
|
||||
Friend ReadOnly Property CheckImage As PropertyValue
|
||||
<PropertyOption(ControlText:="Check image: get original", ControlToolTip:="Get the original image if it exists", IsAuth:=False), PXML, PClonable>
|
||||
<PropertyOption(ControlText:="Check image: get original", ControlToolTip:="Get the original image if it exists"), PXML, PClonable, HiddenControl>
|
||||
Friend ReadOnly Property CheckImageReturnOrig As PropertyValue
|
||||
<PropertyOption(ControlText:=DN.ConcurrentDownloadsCaption,
|
||||
ControlToolTip:=DN.ConcurrentDownloadsToolTip, AllowNull:=False), PXML, TaskCounter, PClonable>
|
||||
Friend ReadOnly Property ConcurrentDownloads As PropertyValue
|
||||
#End Region
|
||||
#Region "IDownDetector Support"
|
||||
Private ReadOnly Property IDownDetector_Value As Integer Implements DownDetector.IDownDetector.Value
|
||||
@@ -96,6 +153,7 @@ Namespace API.Reddit
|
||||
With Responser
|
||||
Dim d% = .Decoders.Count
|
||||
.Decoders.ListAddList({SymbolsConverter.Converters.Unicode, SymbolsConverter.Converters.HTML}, LAP.NotContainsOnly)
|
||||
.Accept = "application/json"
|
||||
token = .Headers.Value(DeclaredNames.Header_Authorization)
|
||||
End With
|
||||
|
||||
@@ -104,7 +162,7 @@ Namespace API.Reddit
|
||||
ApiClientID = New PropertyValue(String.Empty, GetType(String))
|
||||
ApiClientSecret = New PropertyValue(String.Empty, GetType(String))
|
||||
BearerToken = New PropertyValue(token, GetType(String), Sub(v) Responser.Headers.Add(DeclaredNames.Header_Authorization, v))
|
||||
BearerTokenUseCurl = New PropertyValue(True)
|
||||
BearerTokenUseCurl = New PropertyValue(False)
|
||||
TokenUpdateInterval = New PropertyValue(360)
|
||||
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
|
||||
BearerTokenDateUpdate = New PropertyValue(Now.AddYears(-1))
|
||||
@@ -116,6 +174,7 @@ Namespace API.Reddit
|
||||
UseM3U8 = New PropertyValue(True)
|
||||
CheckImage = New PropertyValue(False)
|
||||
CheckImageReturnOrig = New PropertyValue(True)
|
||||
ConcurrentDownloads = New PropertyValue(1)
|
||||
|
||||
MDD = New MyDownDetector(Me)
|
||||
|
||||
@@ -123,11 +182,14 @@ Namespace API.Reddit
|
||||
ImageVideoContains = "reddit.com"
|
||||
UserRegex = RParams.DM("[htps:/]{7,8}.*?reddit.com/([user]{1,4})/([^/\?&]+)", 0, RegexReturn.ListByMatch, EDP.ReturnValue)
|
||||
End Sub
|
||||
Private Const SettingsVersionCurrent As Integer = 1
|
||||
Private Const SettingsVersionCurrent As Integer = 3
|
||||
Friend Overrides Sub EndInit()
|
||||
If CInt(SettingsVersion.Value) < SettingsVersionCurrent Then
|
||||
SettingsVersion.Value = SettingsVersionCurrent
|
||||
TokenUpdateInterval.Value = 360
|
||||
UseM3U8.Value = True
|
||||
CheckImage.Value = False
|
||||
CheckImageReturnOrig.Value = True
|
||||
BearerTokenUseCurl.Value = False
|
||||
End If
|
||||
MyBase.EndInit()
|
||||
End Sub
|
||||
@@ -164,6 +226,7 @@ Namespace API.Reddit
|
||||
End Sub
|
||||
End Class
|
||||
Friend Property SessionInterrupted As Boolean = False
|
||||
Friend Property RequestCount As Integer = 0
|
||||
Friend Overrides Function ReadyToDownload(ByVal What As Download) As Boolean
|
||||
If What = Download.Main Then
|
||||
Return Not SessionInterrupted
|
||||
@@ -179,6 +242,7 @@ Namespace API.Reddit
|
||||
End Function
|
||||
Friend Overrides Sub DownloadDone(ByVal What As Download)
|
||||
SessionInterrupted = False
|
||||
RequestCount = 0
|
||||
MDD.Reset()
|
||||
MyBase.DownloadDone(What)
|
||||
End Sub
|
||||
@@ -211,7 +275,7 @@ Namespace API.Reddit
|
||||
#End Region
|
||||
#Region "UserOptions"
|
||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||
If Options Is Nothing OrElse Not TypeOf Options Is RedditViewExchange Then Options = New RedditViewExchange
|
||||
If Options Is Nothing OrElse Not TypeOf Options Is RedditViewExchange Then Options = New RedditViewExchange(Me)
|
||||
If OpenForm Then
|
||||
Using f As New RedditViewSettingsForm(Options, True) : f.ShowDialog() : End Using
|
||||
End If
|
||||
@@ -232,23 +296,6 @@ Namespace API.Reddit
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Token"
|
||||
<PropertiesDataChecker({NameOf(AuthUserName), NameOf(AuthPassword), NameOf(ApiClientID), NameOf(ApiClientSecret)})>
|
||||
Private Function TokenPropertiesChecker(ByVal p As IEnumerable(Of PropertyData)) As Boolean
|
||||
If p.ListExists Then
|
||||
Dim wrong As New List(Of String)
|
||||
For i% = 0 To p.Count - 1
|
||||
If CStr(p(i).Value).IsEmptyString Then wrong.Add(p(i).Name)
|
||||
Next
|
||||
If wrong.Count > 0 And wrong.Count <> 4 Then
|
||||
MsgBoxE({$"You have not completed the following fields: {wrong.ListToString}." & vbCr &
|
||||
"To use OAuth authorization, all authorization fields must be filled in.", "Validate token fields"}, vbCritical)
|
||||
Return False
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
End If
|
||||
Return False
|
||||
End Function
|
||||
Private Function UpdateTokenIfRequired() As Boolean
|
||||
UpdateRedGifsToken()
|
||||
If (CBool(UseTokenForTimelines.Value) Or CBool(UseTokenForSavedPosts.Value)) AndAlso CredentialsExists Then
|
||||
|
||||
@@ -8,19 +8,20 @@
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Net
|
||||
Imports System.Threading
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Tools.ImageRenderer
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Clients.Base
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.API.Reddit.RedditViewExchange
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports SCrawler.Plugin.Hosts
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.ImageRenderer
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
|
||||
Imports CView = SCrawler.API.Reddit.IRedditView.View
|
||||
Imports UStates = SCrawler.API.Base.UserMedia.States
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Imports CView = SCrawler.API.Reddit.IRedditView.View
|
||||
Imports CPeriod = SCrawler.API.Reddit.IRedditView.Period
|
||||
Namespace API.Reddit
|
||||
Friend Class UserData : Inherits UserDataBase : Implements IChannelLimits, IRedditView
|
||||
#Region "Declarations"
|
||||
@@ -33,7 +34,8 @@ Namespace API.Reddit
|
||||
End Property
|
||||
Private ReadOnly Property DateTrueProvider(ByVal IsChannel As Boolean) As IFormatProvider
|
||||
Get
|
||||
Return If(IsChannel, UnixDate32ProviderReddit, UnixDate64Provider)
|
||||
Return UnixDate32Provider
|
||||
'Return If(IsChannel, UnixDate32ProviderReddit, UnixDate64Provider)
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property UseM3U8 As Boolean
|
||||
@@ -126,10 +128,16 @@ Namespace API.Reddit
|
||||
Friend Property ViewPeriod As CPeriod Implements IRedditView.ViewPeriod
|
||||
Friend Sub SetView(ByVal Options As IRedditView) Implements IRedditView.SetView
|
||||
If Not Options Is Nothing Then
|
||||
ViewMode = Options.ViewMode
|
||||
ViewPeriod = Options.ViewPeriod
|
||||
RedGifsAccount = Options.RedGifsAccount
|
||||
RedditAccount = Options.RedditAccount
|
||||
With Options
|
||||
ViewMode = .ViewMode
|
||||
ViewPeriod = .ViewPeriod
|
||||
DownloadText = .DownloadText
|
||||
DownloadTextPosts = .DownloadTextPosts
|
||||
DownloadTextSpecialFolder = .DownloadTextSpecialFolder
|
||||
RedGifsAccount = .RedGifsAccount
|
||||
RedditAccount = .RedditAccount
|
||||
If TypeOf Options Is RedditViewExchange Then DirectCast(Options, RedditViewExchange).ApplyBase(Me)
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
Private ReadOnly Property View As String
|
||||
@@ -137,6 +145,8 @@ Namespace API.Reddit
|
||||
Select Case ViewMode
|
||||
Case CView.Hot : Return "hot"
|
||||
Case CView.Top : Return "top"
|
||||
Case CView.Best : Return "best"
|
||||
Case CView.Rising : Return "rising"
|
||||
Case Else : Return "new"
|
||||
End Select
|
||||
End Get
|
||||
@@ -157,6 +167,9 @@ Namespace API.Reddit
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Friend Overrides Property DownloadText As Boolean Implements IRedditView.DownloadText
|
||||
Friend Overrides Property DownloadTextPosts As Boolean Implements IRedditView.DownloadTextPosts
|
||||
Friend Overrides Property DownloadTextSpecialFolder As Boolean Implements IRedditView.DownloadTextSpecialFolder
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New()
|
||||
@@ -215,7 +228,7 @@ Namespace API.Reddit
|
||||
End With
|
||||
End Sub
|
||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||
Return New RedditViewExchange With {.ViewMode = ViewMode, .ViewPeriod = ViewPeriod, .RedGifsAccount = RedGifsAccount, .RedditAccount = RedditAccount}
|
||||
Return New RedditViewExchange(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is IRedditView Then SetView(DirectCast(Obj, IRedditView))
|
||||
@@ -257,6 +270,8 @@ Namespace API.Reddit
|
||||
End If
|
||||
End With
|
||||
|
||||
Responser.ProcessExceptionDecision = AddressOf Err429Process
|
||||
|
||||
_TotalPostsDownloaded = 0
|
||||
If IsSavedPosts Then
|
||||
Responser.DecodersError = EDP.ReturnValue
|
||||
@@ -274,8 +289,13 @@ Namespace API.Reddit
|
||||
Else
|
||||
GetUserInfo()
|
||||
End If
|
||||
If SaveToCache AndAlso Not Responser.Decoders.Contains(SymbolsConverter.Converters.HTML) Then _
|
||||
Responser.Decoders.Add(SymbolsConverter.Converters.HTML)
|
||||
If SaveToCache Then
|
||||
DownloadText = False
|
||||
DownloadTextPosts = False
|
||||
DownloadTextSpecialFolder = False
|
||||
If Not Responser.Decoders.Contains(SymbolsConverter.Converters.HTML) Then _
|
||||
Responser.Decoders.Add(SymbolsConverter.Converters.HTML)
|
||||
End If
|
||||
DownloadDataChannel(String.Empty, Token)
|
||||
If ChannelInfo Is Nothing Then _TempPostsList.ListAddList(_TempMediaList.Select(Function(m) m.Post.ID), LNC)
|
||||
Else
|
||||
@@ -287,6 +307,7 @@ Namespace API.Reddit
|
||||
#End Region
|
||||
#Region "Download Functions (User, Channel)"
|
||||
Private Err429Count As Integer = 0
|
||||
Private Err429TryAgain As Boolean = False
|
||||
Private _TotalPostsDownloaded As Integer = 0
|
||||
Private ReadOnly _CrossPosts As List(Of String)
|
||||
Private Const SiteGfycatKey As String = "gfycat"
|
||||
@@ -294,6 +315,28 @@ Namespace API.Reddit
|
||||
Private Const Node_CrosspostRootId As String = "crosspostRootId"
|
||||
Private Const Node_CrosspostParentId As String = "crosspostParentId"
|
||||
Private Const Node_CrosspostParent As String = "crosspost_parent"
|
||||
Private Sub Wait429()
|
||||
With MySiteSettings
|
||||
If Not Err429TryAgain Then .RequestCount += 1
|
||||
Err429TryAgain = False
|
||||
If (.RequestCount Mod 100) = 0 Then Thread.Sleep(60100)
|
||||
End With
|
||||
End Sub
|
||||
Private Function Err429Process(ByVal Status As IResponserStatus, ByVal NullArg As Object, ByVal CurrErr As ErrorsDescriber) As ErrorsDescriber
|
||||
If Not Status Is Nothing AndAlso Status.StatusCode = 429 Then
|
||||
If Err429Count = 0 Then
|
||||
Err429Count += 1
|
||||
MySiteSettings.RequestCount = 100
|
||||
Err429TryAgain = True
|
||||
Return EDP.ReturnValue
|
||||
End If
|
||||
End If
|
||||
Return CurrErr
|
||||
End Function
|
||||
Private Sub Err429Reset()
|
||||
Err429Count = 0
|
||||
Err429TryAgain = False
|
||||
End Sub
|
||||
Private Sub DownloadDataUser(ByVal POST As String, ByVal Token As CancellationToken)
|
||||
Dim eObj% = 0
|
||||
Dim round% = 0
|
||||
@@ -311,58 +354,68 @@ Namespace API.Reddit
|
||||
Dim CheckNode As Predicate(Of EContainer) = Function(e) Not ParseUserMediaOnly OrElse If(e("author")?.Value, "/").ToLower.Equals(NameTrue.StringToLower)
|
||||
Dim _PostID As Func(Of String) = Function() PostTmp.IfNullOrEmpty(PostID)
|
||||
|
||||
URL = $"https://gateway.reddit.com/desktopapi/v1/user/{NameTrue}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
|
||||
'URL = $"https://gateway.reddit.com/desktopapi/v1/user/{NameTrue}/posts?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
|
||||
URL = $"https://oauth.reddit.com/user/{NameTrue}/submitted.json?rtj=only&allow_quarantined=true&allow_over18=1&include=identity&after={POST}&dist=25&sort={View}&t={Period}&layout=classic"
|
||||
ThrowAny(Token)
|
||||
Wait429()
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
If Not r.IsEmptyString Then
|
||||
Err429Reset()
|
||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If w.Count > 0 Then
|
||||
n = w.GetNode(JsonNodesJson)
|
||||
If Not n Is Nothing AndAlso n.Count > 0 Then
|
||||
'n = w.GetNode(JsonNodesJson)
|
||||
n = w.GetNode(ChannelJsonNodes)
|
||||
If n.ListExists Then
|
||||
ProgressPre.ChangeMax(n.Count)
|
||||
For Each nn In n
|
||||
ProgressPre.Perform()
|
||||
ThrowAny(Token)
|
||||
If nn.Count > 0 Then
|
||||
If CheckNode(nn) Then
|
||||
With nn("data")
|
||||
If .ListExists Then
|
||||
If CheckNode(.Self) Then
|
||||
|
||||
'Obtain post ID
|
||||
PostTmp = nn.Name
|
||||
If PostTmp.IsEmptyString Then PostTmp = nn.Value("id")
|
||||
If PostTmp.IsEmptyString Then Continue For
|
||||
'Check for CrossPost
|
||||
If IsCrossPost(nn) Then
|
||||
_CrossPosts.ListAddList({nn.Value(Node_CrosspostRootId),
|
||||
nn.Value(Node_CrosspostParentId),
|
||||
nn.Value(Node_CrosspostParent)}, LNC)
|
||||
Continue For
|
||||
Else
|
||||
If Not _CrossPosts.Contains(PostTmp) Then PostID = PostTmp : PostTmp = String.Empty
|
||||
'Obtain post ID
|
||||
PostID = String.Empty
|
||||
PostTmp = .Value("name") '.Name
|
||||
If PostTmp.IsEmptyString Then PostTmp = .Value("id")
|
||||
If PostTmp.IsEmptyString Then Continue For
|
||||
'Check for CrossPost
|
||||
If IsCrossPost(.Self) Then
|
||||
_CrossPosts.ListAddList({ .Value(Node_CrosspostRootId),
|
||||
.Value(Node_CrosspostParentId),
|
||||
.Value(Node_CrosspostParent),
|
||||
PostTmp}, LNC)
|
||||
If ParseUserMediaOnly Then Continue For
|
||||
Else
|
||||
If Not _CrossPosts.Contains(PostTmp) Then PostID = PostTmp : PostTmp = String.Empty
|
||||
End If
|
||||
|
||||
'Download decision
|
||||
If Not _TempPostsList.Contains(_PostID()) Then
|
||||
NewPostDetected = True
|
||||
_TempPostsList.Add(_PostID())
|
||||
Else
|
||||
If Not _CrossPosts.Contains(_PostID()) Then ExistsDetected = True
|
||||
Continue For
|
||||
End If
|
||||
PostDate = If(.Item("created")?.Value, String.Empty)
|
||||
Select Case CheckDatesLimit(PostDate, DateTrueProvider(IsChannel))
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : Exit Sub
|
||||
End Select
|
||||
|
||||
ParseContainer(.Self, _PostID(), PostDate,,, GetTextDocument(.Self))
|
||||
End If
|
||||
|
||||
'Download decision
|
||||
If Not _TempPostsList.Contains(_PostID()) Then
|
||||
NewPostDetected = True
|
||||
_TempPostsList.Add(_PostID())
|
||||
Else
|
||||
If Not _CrossPosts.Contains(_PostID()) Then ExistsDetected = True
|
||||
Continue For
|
||||
End If
|
||||
If nn.Contains("created") Then PostDate = nn("created").Value Else PostDate = String.Empty
|
||||
Select Case CheckDatesLimit(PostDate, DateTrueProvider(IsChannel))
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : Exit Sub
|
||||
End Select
|
||||
|
||||
ParseContainer(nn, _PostID(), PostDate)
|
||||
End If
|
||||
End If
|
||||
End With
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
End Using
|
||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
||||
If Not _PostID().IsEmptyString And NewPostDetected Then DownloadDataUser(_PostID(), Token)
|
||||
ElseIf Err429TryAgain Then
|
||||
Continue Do
|
||||
End If
|
||||
_completed = True
|
||||
Catch ex As Exception
|
||||
@@ -399,9 +452,11 @@ Namespace API.Reddit
|
||||
End If
|
||||
|
||||
ThrowAny(Token)
|
||||
Wait429()
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
If IsSavedPosts Then Err429Count = 0
|
||||
'If IsSavedPosts Then Err429Count = 0
|
||||
If Not r.IsEmptyString Then
|
||||
Err429Reset()
|
||||
Using w As EContainer = JsonDocument.Parse(r).XmlIfNothing
|
||||
If w.Count > 0 Then
|
||||
n = w.GetNode(ChannelJsonNodes)
|
||||
@@ -450,7 +505,7 @@ Namespace API.Reddit
|
||||
Continue For
|
||||
End If
|
||||
|
||||
ParseContainer(s, PostID, PostDate, _UserID)
|
||||
ParseContainer(s, PostID, PostDate, _UserID,, If(Not SaveToCache, GetTextDocument(s), String.Empty))
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
@@ -458,6 +513,8 @@ Namespace API.Reddit
|
||||
End Using
|
||||
If POST.IsEmptyString And ExistsDetected Then Exit Sub
|
||||
If Not PostID.IsEmptyString And NewPostDetected Then DownloadDataChannel(PostID, Token)
|
||||
ElseIf Err429TryAgain Then
|
||||
Continue Do
|
||||
End If
|
||||
_completed = True
|
||||
Catch ex As Exception
|
||||
@@ -475,11 +532,13 @@ Namespace API.Reddit
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "GetUserInfo"
|
||||
Private Sub GetUserInfo()
|
||||
Private Sub GetUserInfo(Optional ByVal Round As Integer = 0)
|
||||
Try
|
||||
If Not IsSavedPosts And ChannelInfo Is Nothing Then
|
||||
Wait429()
|
||||
Dim r$ = Responser.GetResponse($"https://reddit.com/{IIf(IsChannel, "r", "user")}/{NameTrue}/about.json",, EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then
|
||||
Err429Reset()
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If Not j Is Nothing AndAlso j.Contains({"data", "subreddit"}) Then
|
||||
If ID.IsEmptyString Then ID = j.Value({"data"}, "id")
|
||||
@@ -495,6 +554,8 @@ Namespace API.Reddit
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
ElseIf Err429TryAgain And Round < 2 Then
|
||||
GetUserInfo(Round + 1)
|
||||
End If
|
||||
End If
|
||||
Catch ex As Exception
|
||||
@@ -503,7 +564,7 @@ Namespace API.Reddit
|
||||
#End Region
|
||||
#Region "ParseContainer"
|
||||
Private Function ParseContainer(ByVal e As EContainer, ByVal PostID As String, ByVal PostDate As String, Optional ByVal UserID As String = Nothing,
|
||||
Optional ByVal AllowReparse As Boolean = True) As Boolean
|
||||
Optional ByVal AllowReparse As Boolean = True, Optional ByVal PostText As String = Nothing) As Boolean
|
||||
If Not e Is Nothing Then
|
||||
Dim UPicType As Func(Of String, UTypes) = Function(input) IIf(input = "image", UTypes.Picture, UTypes.GIF)
|
||||
Dim eCount As Predicate(Of EContainer) = Function(item) item.Count > 0
|
||||
@@ -513,24 +574,24 @@ Namespace API.Reddit
|
||||
If SaveToCache Then
|
||||
tmpUrl = e.Value({"media", "oembed"}, "thumbnail_url")
|
||||
If Not tmpUrl.IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, tmpUrl, PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, tmpUrl, PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
Else
|
||||
added = False
|
||||
End If
|
||||
Else
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.VideoPre, tmpUrl, PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.VideoPre, tmpUrl, PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
End If
|
||||
ElseIf CreateImgurMedia(tmpUrl, PostID, PostDate, UserID, IsChannel) Then
|
||||
ElseIf CreateImgurMedia(tmpUrl, PostID, PostDate, UserID, IsChannel, PostText) Then
|
||||
_TotalPostsDownloaded += 1
|
||||
ElseIf DownloadGallery(e, PostID, PostDate, UserID, SaveToCache) Then
|
||||
ElseIf DownloadGallery(e, PostID, PostDate, UserID, SaveToCache, PostText) Then
|
||||
_TotalPostsDownloaded += 1
|
||||
ElseIf Not If(e({"media"}, "type")?.Value, String.Empty).IsEmptyString Then
|
||||
With e("media")
|
||||
Dim t$ = .Item("type").Value
|
||||
Select Case t
|
||||
Case "gallery" : If DownloadGallery(.Self, PostID, PostDate) Then _TotalPostsDownloaded += 1 Else added = False
|
||||
Case "gallery" : If DownloadGallery(.Self, PostID, PostDate,,, PostText) Then _TotalPostsDownloaded += 1 Else added = False
|
||||
Case "image", "gifvideo"
|
||||
|
||||
Dim resolution As Sizes = Nothing
|
||||
@@ -565,17 +626,17 @@ Namespace API.Reddit
|
||||
End If
|
||||
|
||||
If Not chosenVal.IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UPicType(t), chosenVal, PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UPicType(t), chosenVal, PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
Else
|
||||
added = False
|
||||
End If
|
||||
Case "video"
|
||||
If UseM3U8 AndAlso .Item("hlsUrl").XmlIfNothingValue("/").ToLower.Contains("m3u8") Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.m3u8, .Value("hlsUrl"), PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.m3u8, .Value("hlsUrl"), PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
ElseIf Not UseM3U8 AndAlso .Item("fallback_url").XmlIfNothingValue("/").ToLower.Contains("mp4") Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, .Value("fallback_url"), PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, .Value("fallback_url"), PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
Else
|
||||
added = False
|
||||
@@ -588,16 +649,16 @@ Namespace API.Reddit
|
||||
If SaveToCache Then
|
||||
tmpUrl = GetVideoRedditPreview(e)
|
||||
If Not tmpUrl.IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, tmpUrl, PostID, PostDate, UserID, False), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, tmpUrl, PostID, PostDate, UserID, False, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
Else
|
||||
added = False
|
||||
End If
|
||||
ElseIf UseM3U8 AndAlso Not If(e({"media", "reddit_video"}, "hls_url")?.Value, String.Empty).IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.m3u8, e.Value({"media", "reddit_video"}, "hls_url"), PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.m3u8, e.Value({"media", "reddit_video"}, "hls_url"), PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
Else
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, tmpUrl, PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, tmpUrl, PostID, PostDate, UserID,, PostText), LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
End If
|
||||
Else
|
||||
@@ -606,20 +667,25 @@ Namespace API.Reddit
|
||||
If Not added Then
|
||||
If AllowReparse Then
|
||||
If If(e.ItemF({"crosspost_parent_list", 0})?.Count, 0) > 0 Then
|
||||
added = ParseContainer(e.ItemF({"crosspost_parent_list", 0}), PostID, PostDate, UserID, True)
|
||||
added = ParseContainer(e.ItemF({"crosspost_parent_list", 0}), PostID, PostDate, UserID, True, PostText)
|
||||
Else
|
||||
Dim tPostId$ = e.Value(Node_CrosspostParent).IfNullOrEmpty(e.Value(Node_CrosspostParentId)).IfNullOrEmpty(e.Value(Node_CrosspostRootId))
|
||||
If Not PostID.IsEmptyString Then
|
||||
Dim r$ = Responser.GetResponse($"https://www.reddit.com/comments/{tPostId.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||
If j.ListExists Then
|
||||
With j.ItemF({0, "data", "children", 0, "data"})
|
||||
If .ListExists Then added = ParseContainer(.Self, PostID, PostDate, UserID, False)
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
For ri% = 0 To 1
|
||||
Wait429()
|
||||
Dim r$ = Responser.GetResponse($"https://www.reddit.com/comments/{tPostId.Split("_").LastOrDefault}/.json",, EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then
|
||||
Err429Reset()
|
||||
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||
If j.ListExists Then
|
||||
With j.ItemF({0, "data", "children", 0, "data"})
|
||||
If .ListExists Then added = ParseContainer(.Self, PostID, PostDate, UserID, False, PostText)
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
@@ -637,7 +703,7 @@ Namespace API.Reddit
|
||||
End Select
|
||||
End With
|
||||
If Not tmpType = UTypes.Undefined Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(tmpType, node.Value, PostID, PostDate, UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(tmpType, node.Value, PostID, PostDate, UserID,, PostText), LNC)
|
||||
added = True
|
||||
End If
|
||||
End If
|
||||
@@ -660,7 +726,7 @@ Namespace API.Reddit
|
||||
If Not tmpUrl.IsEmptyString Then tmpType = UTypes.Picture
|
||||
End If
|
||||
If Not tmpUrl.IsEmptyString And Not tmpType = UTypes.Undefined Then
|
||||
Dim m As UserMedia = MediaFromData(tmpType, tmpUrl, PostID, PostDate, UserID)
|
||||
Dim m As UserMedia = MediaFromData(tmpType, tmpUrl, PostID, PostDate, UserID,, PostText)
|
||||
If tmpType = UTypes.Video Then m.File.Extension = "mp4"
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
_TotalPostsDownloaded += 1
|
||||
@@ -671,6 +737,7 @@ Namespace API.Reddit
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
If Not added And Not PostText.IsEmptyString Then _TempMediaList.ListAddValue(MediaFromData(UTypes.Text, String.Empty, PostID, PostDate, UserID,, PostText))
|
||||
Return added
|
||||
Else
|
||||
Return False
|
||||
@@ -693,28 +760,45 @@ Namespace API.Reddit
|
||||
Return False
|
||||
End Try
|
||||
End Function
|
||||
Private Function GetTextDocument(ByVal e As EContainer) As String
|
||||
Dim t$ = String.Empty
|
||||
Try
|
||||
t = e.Value("title")
|
||||
With e({"rtjson", "document"})
|
||||
If .ListExists Then
|
||||
For Each tt As EContainer In .Self
|
||||
t.StringAppendLine(vbCrLf,, False)
|
||||
t.StringAppendLine(If(tt.ItemF({"c", 0, "t"})?.Value, String.Empty))
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
Catch
|
||||
End Try
|
||||
Return t
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Download Base Functions"
|
||||
Private Function CreateImgurMedia(ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal _UserID As String = "", Optional ByVal IsChannel As Boolean = False) As Boolean
|
||||
Optional ByVal _UserID As String = "", Optional ByVal IsChannel As Boolean = False,
|
||||
Optional ByVal PostText As String = Nothing) As Boolean
|
||||
If Not _URL.IsEmptyString AndAlso _URL.Contains("imgur") Then
|
||||
If _URL.StringContains({".jpg", ".png", ".jpeg"}) Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL, PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL, PostID, PostDate, _UserID,, PostText), LNC)
|
||||
ElseIf _URL.Contains(".gifv") Then
|
||||
If SaveToCache Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL.Replace(".gifv", ".gif"), PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL.Replace(".gifv", ".gif"), PostID, PostDate, _UserID,, PostText), LNC)
|
||||
Else
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL.Replace(".gifv", ".mp4"), PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL.Replace(".gifv", ".mp4"), PostID, PostDate, _UserID,, PostText), LNC)
|
||||
End If
|
||||
ElseIf _URL.Contains(".mp4") Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL, PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Video, _URL, PostID, PostDate, _UserID,, PostText), LNC)
|
||||
ElseIf _URL.Contains(".gif") Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.GIF, _URL, PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.GIF, _URL, PostID, PostDate, _UserID,, PostText), LNC)
|
||||
Else
|
||||
Dim obj As IEnumerable(Of UserMedia) = Imgur.Envir.GetVideoInfo(_URL, EDP.ReturnValue)
|
||||
If Not obj.ListExists Then
|
||||
If Not TryFile(_URL) Then _URL &= ".jpg"
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL, PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, _URL, PostID, PostDate, _UserID,, PostText), LNC)
|
||||
Else
|
||||
Dim ut As UTypes
|
||||
Dim m As UserMedia
|
||||
@@ -729,7 +813,7 @@ Namespace API.Reddit
|
||||
Case "gif" : ut = UTypes.GIF
|
||||
Case Else : ut = UTypes.Picture : .File.Extension = "jpg"
|
||||
End Select
|
||||
m = MediaFromData(ut, _URL, PostID, PostDate, _UserID)
|
||||
m = MediaFromData(ut, _URL, PostID, PostDate, _UserID,, PostText)
|
||||
m.URL = .URL
|
||||
m.File = .File.File
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
@@ -745,7 +829,8 @@ Namespace API.Reddit
|
||||
End If
|
||||
End Function
|
||||
Private Function DownloadGallery(ByVal e As EContainer, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal _UserID As String = Nothing, Optional ByVal FirstOnly As Boolean = False) As Boolean
|
||||
Optional ByVal _UserID As String = Nothing, Optional ByVal FirstOnly As Boolean = False,
|
||||
Optional ByVal PostText As String = Nothing) As Boolean
|
||||
Try
|
||||
Dim added As Boolean = False
|
||||
Dim node As EContainer = Nothing
|
||||
@@ -759,7 +844,7 @@ Namespace API.Reddit
|
||||
For Each n As EContainer In node
|
||||
t = n.ItemF({"s", "u"})
|
||||
If Not t Is Nothing AndAlso Not t.Value.IsEmptyString Then
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, t.Value, PostID, PostDate, _UserID), LNC)
|
||||
_TempMediaList.ListAddValue(MediaFromData(UTypes.Picture, t.Value, PostID, PostDate, _UserID,, PostText), LNC)
|
||||
added = True
|
||||
If FirstOnly Then Exit For
|
||||
End If
|
||||
@@ -866,7 +951,10 @@ Namespace API.Reddit
|
||||
End If
|
||||
Continue For
|
||||
Else
|
||||
Wait429()
|
||||
r = Responser.GetResponse(m.URL,, e)
|
||||
If r.IsEmptyString And Err429TryAgain Then _repeatForRedgifs = True
|
||||
If Not r.IsEmptyString Then Err429Reset()
|
||||
End If
|
||||
Loop While _repeatForRedgifs
|
||||
Else
|
||||
@@ -876,7 +964,7 @@ Namespace API.Reddit
|
||||
If Not r.IsEmptyString Then
|
||||
v = RegexReplace(r, VideoRegEx)
|
||||
If Not v.IsEmptyString Then
|
||||
_TempMediaList(i) = New UserMedia With {.Type = UTypes.Video, .URL = v, .File = v, .Post = m.Post}
|
||||
_TempMediaList(i) = New UserMedia With {.Type = UTypes.Video, .URL = v, .File = v, .Post = m.Post, .PostText = m.PostText, .PostTextFile = m.PostTextFile}
|
||||
Else
|
||||
_TempMediaList.RemoveAt(i)
|
||||
End If
|
||||
@@ -904,11 +992,13 @@ Namespace API.Reddit
|
||||
RedGifsResponser = RedGifsHost.Responser.Copy
|
||||
Dim respNoHeaders As Responser = Responser.Copy
|
||||
Dim m As UserMedia, m2 As UserMedia
|
||||
Dim r$, url$
|
||||
Dim r$ = String.Empty, url$
|
||||
Dim ri As Byte
|
||||
Dim j As EContainer
|
||||
Dim lastCount%, li%
|
||||
Dim rv As New ErrorsDescriber(EDP.ReturnValue)
|
||||
respNoHeaders.Headers.Clear()
|
||||
respNoHeaders.ProcessExceptionDecision = AddressOf Err429Process
|
||||
ProgressPre.ChangeMax(_ContentList.Count)
|
||||
For i% = 0 To _ContentList.Count - 1
|
||||
m = _ContentList(i)
|
||||
@@ -916,15 +1006,20 @@ Namespace API.Reddit
|
||||
If m.State = UStates.Missing AndAlso Not m.Post.ID.IsEmptyString Then
|
||||
ThrowAny(Token)
|
||||
url = $"https://www.reddit.com/comments/{m.Post.ID.Split("_").LastOrDefault}/.json"
|
||||
r = Responser.GetResponse(url,, rv)
|
||||
If r.IsEmptyString Then r = respNoHeaders.GetResponse(url,, rv)
|
||||
For ri = 0 To 1
|
||||
Wait429()
|
||||
r = Responser.GetResponse(url,, rv)
|
||||
If r.IsEmptyString Then Wait429() : r = respNoHeaders.GetResponse(url,, rv)
|
||||
If Not (r.IsEmptyString And Err429TryAgain) Then Exit For
|
||||
Next
|
||||
If Not r.IsEmptyString Then
|
||||
Err429Reset()
|
||||
j = JsonDocument.Parse(r, rv)
|
||||
If Not j Is Nothing Then
|
||||
If j.Count > 0 Then
|
||||
lastCount = _TempMediaList.Count
|
||||
With j.GetNode(SingleJsonNodes)
|
||||
If .ListExists AndAlso ParseContainer(.Self, m.Post.ID, String.Empty) Then
|
||||
If .ListExists AndAlso ParseContainer(.Self, m.Post.ID, String.Empty,,, GetTextDocument(.Self)) Then
|
||||
If lastCount <> _TempMediaList.Count Then
|
||||
For li = IIf(lastCount < 0, 0, lastCount) To _TempMediaList.Count - 1
|
||||
m2 = _TempMediaList(i)
|
||||
@@ -971,13 +1066,15 @@ Namespace API.Reddit
|
||||
#End Region
|
||||
#Region "Structure creator"
|
||||
Private Function MediaFromData(ByVal t As UTypes, ByVal _URL As String, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal _UserID As String = "", Optional ByVal ReplacePreview As Boolean = True) As UserMedia
|
||||
Optional ByVal _UserID As String = "", Optional ByVal ReplacePreview As Boolean = True,
|
||||
Optional ByVal PostText As String = Nothing) As UserMedia
|
||||
If _URL.IsEmptyString And t = UTypes.Picture Then Return Nothing
|
||||
_URL = LinkFormatterSecure(RegexReplace(_URL.Replace("\", String.Empty), LinkPattern))
|
||||
Dim m As New UserMedia(_URL, t) With {.Post = New UserPost With {.ID = PostID, .UserID = _UserID}}
|
||||
If t = UTypes.Picture Or t = UTypes.GIF Then m.File = CreateFileFromUrl(m.URL) Else m.File = Nothing
|
||||
If ReplacePreview And m.URL.Contains("preview") And Not t = UTypes.Picture Then m.URL = $"https://i.redd.it/{m.File.File}"
|
||||
If Not PostDate.IsEmptyString Then m.Post.Date = AConvert(Of Date)(PostDate, DateTrueProvider(IsChannel Or IsSavedPosts), Nothing) Else m.Post.Date = Nothing
|
||||
If Not PostText.IsEmptyString Then m.PostText = PostText
|
||||
Return m
|
||||
End Function
|
||||
Private Function TryFile(ByVal URL As String) As Boolean
|
||||
@@ -1048,25 +1145,37 @@ Namespace API.Reddit
|
||||
ElseIf .StatusCode = HttpStatusCode.Forbidden Then '403
|
||||
UserSuspended = True
|
||||
ElseIf .StatusCode = HttpStatusCode.BadGateway Or .StatusCode = HttpStatusCode.ServiceUnavailable Then '502, 503
|
||||
MyMainLOG = $"{ToStringForLog()}: [{CInt(Responser.StatusCode)}] Reddit is currently unavailable"
|
||||
LogError(Nothing, $"[{CInt(Responser.StatusCode)}] Reddit is currently unavailable")
|
||||
Throw New Plugin.ExitException With {.Silent = True}
|
||||
ElseIf .StatusCode = HttpStatusCode.GatewayTimeout Then '504
|
||||
Return 1
|
||||
ElseIf .StatusCode = HttpStatusCode.Unauthorized Then '401
|
||||
MyMainLOG = $"{ToStringForLog()}: [{CInt(Responser.StatusCode)}] Reddit credentials expired"
|
||||
LogError(Nothing, $"[{CInt(Responser.StatusCode)}] Reddit credentials expired")
|
||||
MySiteSettings.SessionInterrupted = True
|
||||
Throw New Plugin.ExitException With {.Silent = True}
|
||||
ElseIf .StatusCode = HttpStatusCode.InternalServerError Then '500
|
||||
If Not IsNothing(EObj) AndAlso IsNumeric(EObj) AndAlso CInt(EObj) = HttpStatusCode.InternalServerError Then Return 1
|
||||
Return HttpStatusCode.InternalServerError
|
||||
ElseIf .StatusCode = 429 And IsSavedPosts And Err429Count = 0 Then
|
||||
Err429Count += 1
|
||||
Return 429
|
||||
ElseIf .StatusCode = 429 AndAlso
|
||||
((Not IsSavedPosts And CBool(MySiteSettings.UseTokenForTimelines.Value)) Or (IsSavedPosts And CBool(MySiteSettings.UseTokenForSavedPosts.Value))) AndAlso
|
||||
Not MySiteSettings.CredentialsExists Then '429
|
||||
MyMainLOG = $"{ToStringForLog()}: [{CInt(Responser.StatusCode)}] You should use OAuth authorization or disable " &
|
||||
IIf(IsSavedPosts, "token usage for downloading saved posts", "the use of token and cookies for downloading timelines")
|
||||
'ElseIf .StatusCode = 429 And IsSavedPosts And Err429Count = 0 Then '429 (saved)
|
||||
' Err429Count += 1
|
||||
' Return 429
|
||||
ElseIf .StatusCode = 429 Then '429 (all)
|
||||
'If ((Not IsSavedPosts And CBool(MySiteSettings.UseTokenForTimelines.Value)) Or (IsSavedPosts And CBool(MySiteSettings.UseTokenForSavedPosts.Value))) AndAlso
|
||||
' Not MySiteSettings.CredentialsExists Then
|
||||
' LogError(Nothing, "[429] You should use OAuth authorization or disable " &
|
||||
' IIf(IsSavedPosts, "token usage for downloading saved posts", "the use of token and cookies for downloading timelines"))
|
||||
'Else
|
||||
' LogError(Nothing, "Too many requests (429). Try again later!")
|
||||
'End If
|
||||
'MySiteSettings.SessionInterrupted = True
|
||||
'Throw New Plugin.ExitException With {.Silent = True}
|
||||
If ((Not IsSavedPosts And CBool(MySiteSettings.UseTokenForTimelines.Value)) Or (IsSavedPosts And CBool(MySiteSettings.UseTokenForSavedPosts.Value))) AndAlso
|
||||
Not MySiteSettings.CredentialsExists Then
|
||||
LogError(Nothing, "[429] You should use OAuth authorization or disable " &
|
||||
IIf(IsSavedPosts, "token usage for downloading saved posts", "the use of token and cookies for downloading timelines"))
|
||||
Else
|
||||
LogError(Nothing, "Too many requests (429). Try again later!")
|
||||
End If
|
||||
MySiteSettings.SessionInterrupted = True
|
||||
Throw New Plugin.ExitException With {.Silent = True}
|
||||
Else
|
||||
|
||||
@@ -22,6 +22,7 @@ Namespace API.RedGifs
|
||||
Friend ReadOnly Property Token As PropertyValue
|
||||
<PropertyOption, ControlNumber(2), PClonable, HiddenControl>
|
||||
Private ReadOnly Property UserAgent As PropertyValue
|
||||
<PXML> Friend ReadOnly Property UseCookies As PropertyValue
|
||||
<PXML> Friend ReadOnly Property TokenLastDateUpdated As PropertyValue
|
||||
Private Const TokenName As String = "authorization"
|
||||
#Region "TokenUpdateInterval"
|
||||
@@ -31,6 +32,9 @@ Namespace API.RedGifs
|
||||
<Provider(NameOf(TokenUpdateInterval), FieldsChecker:=True)>
|
||||
Private ReadOnly Property TokenUpdateIntervalProvider As IFormatProvider
|
||||
#End Region
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
@@ -44,6 +48,7 @@ Namespace API.RedGifs
|
||||
End With
|
||||
Token = New PropertyValue(t, GetType(String), Sub(v) UpdateResponse(NameOf(Token), v))
|
||||
UserAgent = New PropertyValue(If(Responser.UserAgentExists, Responser.UserAgent, String.Empty), GetType(String), Sub(v) UpdateResponse(NameOf(UserAgent), v))
|
||||
UseCookies = New PropertyValue(False)
|
||||
TokenLastDateUpdated = New PropertyValue(Now.AddYears(-1), GetType(Date))
|
||||
TokenUpdateInterval = New PropertyValue(60 * 12, GetType(Integer))
|
||||
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
|
||||
@@ -59,11 +64,16 @@ Namespace API.RedGifs
|
||||
Case NameOf(Token) : Responser.Headers.Add(TokenName, Value)
|
||||
Case NameOf(UserAgent) : Responser.UserAgent = Value
|
||||
End Select
|
||||
Responser.SaveSettings()
|
||||
Responser.SaveSettings(, New ErrorsDescriber(EDP.ReturnValue + If(_TokenUpdating, EDP.None, EDP.SendToLog)))
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Token updaters"
|
||||
Private _TokenUpdating As Boolean = False
|
||||
Friend Function UpdateTokenIfRequired() As Boolean
|
||||
While _TokenUpdating : Threading.Thread.Sleep(100) : End While
|
||||
Return UpdateTokenIfRequired_Impl()
|
||||
End Function
|
||||
Private Function UpdateTokenIfRequired_Impl() As Boolean
|
||||
Dim d As Date? = AConvert(Of Date)(TokenLastDateUpdated.Value, AModes.Var, Nothing)
|
||||
If Not d.HasValue OrElse d.Value < Now.AddMinutes(-CInt(TokenUpdateInterval.Value)) Then
|
||||
Return UpdateToken()
|
||||
@@ -73,7 +83,12 @@ Namespace API.RedGifs
|
||||
End Function
|
||||
<PropertyUpdater(NameOf(Token))>
|
||||
Friend Function UpdateToken() As Boolean
|
||||
While _TokenUpdating : Threading.Thread.Sleep(100) : End While
|
||||
Return UpdateToken_Impl()
|
||||
End Function
|
||||
Private Function UpdateToken_Impl() As Boolean
|
||||
Try
|
||||
_TokenUpdating = True
|
||||
Dim r$
|
||||
Dim NewToken$ = String.Empty, NewAgent$ = String.Empty
|
||||
Using resp As New Responser : r = resp.GetResponse("https://api.redgifs.com/v2/auth/temporary",, EDP.ThrowException) : End Using
|
||||
@@ -95,6 +110,8 @@ Namespace API.RedGifs
|
||||
End If
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.RedGifs.SiteSettings.UpdateToken]", False)
|
||||
Finally
|
||||
_TokenUpdating = False
|
||||
End Try
|
||||
End Function
|
||||
#End Region
|
||||
|
||||
@@ -36,6 +36,7 @@ Namespace API.RedGifs
|
||||
#End Region
|
||||
#Region "Download functions"
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
If Not MySettings.UseCookies.Value Then Responser.Cookies.Clear()
|
||||
DownloadData(1, Token)
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal Token As CancellationToken)
|
||||
|
||||
@@ -27,6 +27,9 @@ Namespace API.ThisVid
|
||||
"If true, then public videos will be stored in the 'Public' folder, private - in the 'Private' folder." & vbCr &
|
||||
"If false, all videos will be stored in the 'Video' folder."), PClonable>
|
||||
Friend ReadOnly Property DifferentFolders As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
|
||||
@@ -14,7 +14,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Namespace API.ThisVid
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Friend Class UserData : Inherits UserDataBase : Implements IPSite
|
||||
#Region "XML names"
|
||||
Private Const Name_DownloadPublic As String = "DownloadPublic"
|
||||
Private Const Name_DownloadPrivate As String = "DownloadPrivate"
|
||||
@@ -51,7 +51,7 @@ Namespace API.ThisVid
|
||||
Return {SearchRequestLabelName}
|
||||
End Get
|
||||
End Property
|
||||
Friend Property QueryString As String
|
||||
Friend Property QueryString As String Implements IPSite.QueryString
|
||||
Get
|
||||
If SiteMode = SiteModes.User Then
|
||||
Return String.Empty
|
||||
@@ -161,15 +161,7 @@ Namespace API.ThisVid
|
||||
Return New UserExchangeOptions(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
||||
With DirectCast(Obj, UserExchangeOptions)
|
||||
DownloadPublic = .DownloadPublic
|
||||
DownloadPrivate = .DownloadPrivate
|
||||
DownloadFavourite = .DownloadFavourite
|
||||
DifferentFolders = .DifferentFolders
|
||||
QueryString = .QueryString
|
||||
End With
|
||||
End If
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then DirectCast(Obj, UserExchangeOptions).Apply(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.ThisVid
|
||||
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
|
||||
Friend Class UserExchangeOptions : Inherits EditorExchangeOptionsBase_P
|
||||
<PSetting(Caption:="Download public videos")>
|
||||
Friend Property DownloadPublic As Boolean = True
|
||||
<PSetting(Caption:="Download private videos")>
|
||||
@@ -19,6 +20,7 @@ Namespace API.ThisVid
|
||||
Friend Property DifferentFolders As Boolean = True
|
||||
Private ReadOnly Property MySettings As SiteSettings
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
DownloadPublic = s.DownloadPublic.Value
|
||||
DownloadPrivate = s.DownloadPrivate.Value
|
||||
DownloadFavourite = s.DownloadFavourite.Value
|
||||
@@ -26,12 +28,21 @@ Namespace API.ThisVid
|
||||
MySettings = s
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
MyBase.New(u)
|
||||
DownloadPublic = u.DownloadPublic
|
||||
DownloadPrivate = u.DownloadPrivate
|
||||
DownloadFavourite = u.DownloadFavourite
|
||||
DifferentFolders = u.DifferentFolders
|
||||
QueryString = u.QueryString
|
||||
MySettings = u.HOST.Source
|
||||
End Sub
|
||||
Friend Overrides Sub Apply(ByRef u As IPSite)
|
||||
MyBase.Apply(u)
|
||||
With DirectCast(u, UserData)
|
||||
.DownloadPublic = DownloadPublic
|
||||
.DownloadPrivate = DownloadPrivate
|
||||
.DownloadFavourite = DownloadFavourite
|
||||
.DifferentFolders = DifferentFolders
|
||||
End With
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -89,7 +89,7 @@ Namespace API.ThreadsNet
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
Me.New("Threads", "threads.net", AccName, Temp, My.Resources.SiteResources.ThreadsIcon_192, My.Resources.SiteResources.ThreadsIcon_192.ToBitmap)
|
||||
Me.New("Threads", "threads.com", AccName, Temp, My.Resources.SiteResources.ThreadsIcon_192, My.Resources.SiteResources.ThreadsIcon_192.ToBitmap)
|
||||
End Sub
|
||||
Protected Sub New(ByVal SiteName As String, ByVal CookiesDomain As String, ByVal AccName As String, ByVal Temp As Boolean,
|
||||
Optional ByVal __Icon As Icon = Nothing, Optional ByVal __Image As Image = Nothing)
|
||||
@@ -118,8 +118,8 @@ Namespace API.ThreadsNet
|
||||
browserExt = .Value(IG.Header_BrowserExt)
|
||||
platform = .Value(IG.Header_Platform_Verion)
|
||||
End If
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.threads.net"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.threads.net"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.threads.com"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.threads.com"))
|
||||
.Add("Upgrade-Insecure-Requests", 1)
|
||||
.Add("Sec-Ch-Ua-Model", "")
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaMobile, "?0"))
|
||||
@@ -152,9 +152,9 @@ Namespace API.ThreadsNet
|
||||
RequestsWaitTimer_AnyProvider = New IG.TimersChecker(0)
|
||||
DownloadData_Impl = New PropertyValue(True)
|
||||
|
||||
UrlPatternUser = "https://www.threads.net/@{0}"
|
||||
UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "threads.net/@"), 1)
|
||||
ImageVideoContains = "threads.net"
|
||||
UrlPatternUser = "https://www.threads.com/@{0}"
|
||||
UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "threads.(net|com)/@"), 2)
|
||||
ImageVideoContains = "threads.com"
|
||||
UserOptionsType = GetType(EditorExchangeOptionsBase)
|
||||
End Sub
|
||||
#End Region
|
||||
@@ -185,7 +185,7 @@ Namespace API.ThreadsNet
|
||||
Try
|
||||
Dim code$ = DirectCast(User, UserData).GetPostCodeById(Media.Post.ID)
|
||||
Dim name$ = DirectCast(User, UserData).NameTrue
|
||||
If Not code.IsEmptyString Then Return $"https://www.threads.net/@{name}/post/{code}/" Else Return String.Empty
|
||||
If Not code.IsEmptyString Then Return $"https://www.threads.com/@{name}/post/{code}/" Else Return String.Empty
|
||||
Catch ex As Exception
|
||||
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "Can't open user's post", String.Empty)
|
||||
End Try
|
||||
|
||||
@@ -55,7 +55,7 @@ Namespace API.ThreadsNet
|
||||
Return New EditorExchangeOptionsBase(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptionsBase Then NameTrue = DirectCast(Obj, EditorExchangeOptionsBase).UserName
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptionsBase Then DirectCast(Obj, EditorExchangeOptionsBase).ApplyBase(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
@@ -63,7 +63,7 @@ Namespace API.ThreadsNet
|
||||
ObtainMedia_SetReelsFunc()
|
||||
ObtainMedia_AllowAbstract = True
|
||||
DefaultParser_ElemNode = DefaultParser_ElemNode_Default
|
||||
DefaultParser_PostUrlCreator = Function(post) $"https://www.threads.net/@{NameTrue}/post/{post.Code}"
|
||||
DefaultParser_PostUrlCreator = Function(post) $"https://www.threads.com/@{NameTrue}/post/{post.Code}"
|
||||
_ResponserAutoUpdateCookies = True
|
||||
_ResponserAddResponseReceivedHandler = True
|
||||
DefaultParser_Pinned = AddressOf IsPinnedPost
|
||||
@@ -128,10 +128,13 @@ Namespace API.ThreadsNet
|
||||
If IsSavedPosts Then
|
||||
Return False
|
||||
Else
|
||||
If MaxLastDownDate.HasValue Then
|
||||
Dim d As Date? = AConvert(Of Date)(Items(Index).ItemF(DefaultParser_ElemNode_Default).Value("taken_at"), UnixDate32Provider, Nothing)
|
||||
If d.HasValue Then Return d.Value < MaxLastDownDate.Value
|
||||
End If
|
||||
With Items(Index).ItemF(DefaultParser_ElemNode)
|
||||
Return .Value({"text_post_app_info", "pinned_post_info"}, "is_pinned_to_profile").FromXML(Of Boolean)(False)
|
||||
If MaxLastDownDate.HasValue Then
|
||||
Dim d As Date? = AConvert(Of Date)(.Value("taken_at"), UnixDate32Provider, Nothing)
|
||||
If d.HasValue Then Return d.Value <= MaxLastDownDate.Value
|
||||
End If
|
||||
End With
|
||||
Return Not FirstLoadingDone
|
||||
End If
|
||||
Catch ex As Exception
|
||||
@@ -154,8 +157,8 @@ Namespace API.ThreadsNet
|
||||
Responser.Headers.Add(IGS.Header_CSRF_TOKEN, csrf)
|
||||
End If
|
||||
End Sub
|
||||
'Private Const GQL_Q As String = "https://www.threads.net/api/graphql?lsd={0}&fb_dtsg={1}&doc_id={2}&fb_api_req_friendly_name={3}&server_timestamps=true&variables={4}"
|
||||
Private Const GQL_Q2 As String = "https://www.threads.net/graphql/query"
|
||||
'Private Const GQL_Q As String = "https://www.threads.com/api/graphql?lsd={0}&fb_dtsg={1}&doc_id={2}&fb_api_req_friendly_name={3}&server_timestamps=true&variables={4}"
|
||||
Private Const GQL_Q2 As String = "https://www.threads.com/graphql/query"
|
||||
Private Const PayloadData As String = "lsd={0}&fb_dtsg={1}&doc_id={2}&fb_api_req_friendly_name={3}&server_timestamps=true&variables={4}"
|
||||
Private Const GQL_P_DOC_ID As String = "9039187972876777" '"8779269398849532" '"6371597506283707"
|
||||
Private Const GQL_P_NAME As String = "BarcelonaProfileThreadsTabRefetchableDirectQuery" '"BarcelonaProfileThreadsTabRefetchableQuery"
|
||||
@@ -220,7 +223,7 @@ Namespace API.ThreadsNet
|
||||
|
||||
With Responser
|
||||
.Method = "POST"
|
||||
.Referer = $"https://www.threads.net/@{NameTrue}"
|
||||
.Referer = $"https://www.threads.com/@{NameTrue}"
|
||||
.ContentType = "application/x-www-form-urlencoded"
|
||||
With .Headers
|
||||
.Add(GQL_HEADER_FB_LSD, Token_lsd)
|
||||
@@ -283,7 +286,7 @@ Namespace API.ThreadsNet
|
||||
|
||||
With Responser
|
||||
.Method = "POST"
|
||||
.Referer = "https://www.threads.net/"
|
||||
.Referer = "https://www.threads.com/"
|
||||
.ContentType = "application/x-www-form-urlencoded"
|
||||
With .Headers
|
||||
.Add(GQL_HEADER_FB_LSD, Token_lsd)
|
||||
@@ -355,7 +358,7 @@ Namespace API.ThreadsNet
|
||||
End Function
|
||||
Private _IdChanged As Boolean = False
|
||||
Private Function UpdateCredentials(Optional ByVal e As ErrorsDescriber = Nothing) As Boolean
|
||||
Dim URL$ = If(IsSavedPosts, "https://www.threads.net/", $"https://www.threads.net/@{NameTrue}")
|
||||
Dim URL$ = If(IsSavedPosts, "https://www.threads.com/", $"https://www.threads.com/@{NameTrue}")
|
||||
ResetBaseTokens()
|
||||
Dim headers As New HttpHeaderCollection
|
||||
headers.AddRange(Responser.Headers)
|
||||
@@ -366,8 +369,8 @@ Namespace API.ThreadsNet
|
||||
With .Headers
|
||||
.Clear()
|
||||
.Add("dnt", 1)
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.threads.net"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.threads.net"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Authority, "www.threads.com"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.Origin, "https://www.threads.com"))
|
||||
.Add("Sec-Ch-Ua-Model", "")
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaMobile, "?0"))
|
||||
.Add(HttpHeaderCollection.GetSpecialHeader(MyHeaderTypes.SecChUaPlatform, """Windows"""))
|
||||
@@ -429,7 +432,7 @@ Namespace API.ThreadsNet
|
||||
'Const varsPattern$ = """postID"":""{0}"",""userID"":""{1}"",""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsFeedbackHubEnabledrelayprovider"":false"
|
||||
Const varsPattern$ = """postID"":""{0}"",""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaShouldShowFediverseM1Featuresrelayprovider"":true,""__relay_internal__pv__BarcelonaShareableListsrelayprovider"":true,""__relay_internal__pv__BarcelonaIsSearchDiscoveryEnabledrelayprovider"":false,""__relay_internal__pv__BarcelonaOptionalCookiesEnabledrelayprovider"":true,""__relay_internal__pv__BarcelonaQuotedPostUFIEnabledrelayprovider"":false,""__relay_internal__pv__BarcelonaIsCrawlerrelayprovider"":false,""__relay_internal__pv__BarcelonaHasDisplayNamesrelayprovider"":false,""__relay_internal__pv__BarcelonaCanSeeSponsoredContentrelayprovider"":false,""__relay_internal__pv__BarcelonaShouldShowFediverseM075Featuresrelayprovider"":true,""__relay_internal__pv__BarcelonaShouldShowTagRedesignrelayprovider"":false,""__relay_internal__pv__BarcelonaIsInternalUserrelayprovider"":false,""__relay_internal__pv__BarcelonaInlineComposerEnabledrelayprovider"":false"
|
||||
'Const varsPattern$ = "{""postID"":""{0}"",""__relay_internal__pv__BarcelonaIsLoggedInrelayprovider"":true,""__relay_internal__pv__BarcelonaIsFeedbackHubEnabledrelayprovider"":false}"
|
||||
'Const urlPattern$ = "https://www.threads.net/api/graphql?lsd={0}&variables={1}&fb_api_req_friendly_name=BarcelonaPostPageQuery&server_timestamps=true&fb_dtsg={2}&doc_id=25460088156920903"
|
||||
'Const urlPattern$ = "https://www.threads.com/api/graphql?lsd={0}&variables={1}&fb_api_req_friendly_name=BarcelonaPostPageQuery&server_timestamps=true&fb_dtsg={2}&doc_id=25460088156920903"
|
||||
Dim rList As New List(Of Integer)
|
||||
DefaultParser_ElemNode = Nothing
|
||||
DefaultParser_IgnorePass = True
|
||||
@@ -437,7 +440,7 @@ Namespace API.ThreadsNet
|
||||
If ContentMissingExists Then
|
||||
Responser.Method = "POST"
|
||||
Responser.ContentType = "application/x-www-form-urlencoded"
|
||||
Responser.Referer = $"https://www.threads.net/@{NameTrue}"
|
||||
Responser.Referer = $"https://www.threads.com/@{NameTrue}"
|
||||
If Not IsSingleObjectDownload AndAlso Not UpdateCredentials() Then Throw New Exception("Failed to update credentials")
|
||||
Dim m As UserMedia
|
||||
Dim vars$
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Text.RegularExpressions
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.TikTok
|
||||
Friend Module Declarations
|
||||
Friend ReadOnly SimpleDateConverter As New ADateTime("yyyyMMdd")
|
||||
Friend ReadOnly RegexTagsReplacer As RParams = RParams.DM("#\w+\s?", -1, RegexReturn.Replace,
|
||||
CType(Function(input$) String.Empty, Func(Of String, String)), EDP.ReturnValue)
|
||||
Friend ReadOnly RegexPhotoJson As RParams = RParams.DMS("UNIVERSAL_DATA_FOR_REHYDRATION__"" type=""application/json""\>([^\<]+)\<", 1,
|
||||
RegexOptions.IgnoreCase, EDP.ReturnValue)
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -13,6 +13,15 @@ Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Namespace API.TikTok
|
||||
<Manifest("AndyProgram_TikTok"), SpecialForm(False), SeparatedTasks(1)>
|
||||
Friend Class SiteSettings : Inherits SiteSettingsBase
|
||||
#Region "Categories"
|
||||
Private Const CAT_DOWN As String = "Download"
|
||||
#End Region
|
||||
#Region "Download"
|
||||
<PropertyOption(ControlText:="Download videos", Category:=CAT_DOWN), PXML, PClonable>
|
||||
Friend ReadOnly Property DownloadTTVideos As PropertyValue
|
||||
<PropertyOption(ControlText:="Download photos", Category:=CAT_DOWN), PXML, PClonable>
|
||||
Friend ReadOnly Property DownloadTTPhotos As PropertyValue
|
||||
#End Region
|
||||
<PropertyOption(ControlText:="Remove tags from title"), PXML, PClonable>
|
||||
Friend ReadOnly Property RemoveTagsFromTitle As PropertyValue
|
||||
<PropertyOption(ControlText:="Use native title", ControlToolTip:="Use a user-created video title for the filename instead of the video ID."), PXML, PClonable>
|
||||
@@ -34,8 +43,15 @@ Namespace API.TikTok
|
||||
<PropertyOption(ControlText:="Use video date as file date (standalone downloader)",
|
||||
ControlToolTip:="Set the file date to the date the video was added (website) (if available)."), PXML, PClonable>
|
||||
Friend ReadOnly Property UseParsedVideoDateSTD As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
MyBase.New("TikTok", "www.tiktok.com", AccName, Temp, My.Resources.SiteResources.TikTokIcon_32, My.Resources.SiteResources.TikTokPic_192)
|
||||
|
||||
DownloadTTVideos = New PropertyValue(True)
|
||||
DownloadTTPhotos = New PropertyValue(True)
|
||||
|
||||
RemoveTagsFromTitle = New PropertyValue(False)
|
||||
TitleUseNative = New PropertyValue(True)
|
||||
TitleUseNativeSTD = New PropertyValue(True)
|
||||
@@ -45,6 +61,7 @@ Namespace API.TikTok
|
||||
TitleUseRegexForTitle_Value = New PropertyValue(String.Empty, GetType(String))
|
||||
UseParsedVideoDate = New PropertyValue(True)
|
||||
UseParsedVideoDateSTD = New PropertyValue(False)
|
||||
|
||||
UseNetscapeCookies = True
|
||||
UrlPatternUser = "https://www.tiktok.com/@{0}/"
|
||||
UserRegex = RParams.DMS(String.Format(UserRegexDefaultPattern, "tiktok.com/@"), 1)
|
||||
|
||||
@@ -13,6 +13,7 @@ Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.TikTok
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
#Region "XML names"
|
||||
@@ -23,6 +24,7 @@ Namespace API.TikTok
|
||||
Private Const Name_TitleUseRegexForTitle As String = "TitleUseRegexForTitle"
|
||||
Private Const Name_TitleUseRegexForTitle_Value As String = "TitleUseRegexForTitle_Value"
|
||||
Private Const Name_TitleUseGlobalRegexOptions As String = "TitleUseGlobalRegexOptions"
|
||||
Private Const Name_PhotosDownloaded As String = "PhotosDownloaded"
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
Private ReadOnly Property MySettings As SiteSettings
|
||||
@@ -62,6 +64,7 @@ Namespace API.TikTok
|
||||
Friend Property TitleUseRegexForTitle_Value As String = String.Empty
|
||||
Friend Property TitleUseGlobalRegexOptions As Boolean = True
|
||||
Private Property LastDownloadDate As Date? = Nothing
|
||||
Private Property PhotosDownloaded As Boolean = False
|
||||
#End Region
|
||||
#Region "Exchange"
|
||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||
@@ -92,6 +95,7 @@ Namespace API.TikTok
|
||||
TitleUseRegexForTitle = .Value(Name_TitleUseRegexForTitle).FromXML(Of Boolean)(False)
|
||||
TitleUseRegexForTitle_Value = .Value(Name_TitleUseRegexForTitle_Value)
|
||||
TitleUseGlobalRegexOptions = .Value(Name_TitleUseGlobalRegexOptions).FromXML(Of Boolean)(True)
|
||||
PhotosDownloaded = .Value(Name_PhotosDownloaded).FromXML(Of Boolean)(False)
|
||||
Else
|
||||
.Add(Name_RemoveTagsFromTitle, RemoveTagsFromTitle.BoolToInteger)
|
||||
.Add(Name_TitleUseNative, TitleUseNative.BoolToInteger)
|
||||
@@ -100,6 +104,7 @@ Namespace API.TikTok
|
||||
.Add(Name_TitleUseRegexForTitle, TitleUseRegexForTitle.BoolToInteger)
|
||||
.Add(Name_TitleUseRegexForTitle_Value, TitleUseRegexForTitle_Value)
|
||||
.Add(Name_TitleUseGlobalRegexOptions, TitleUseGlobalRegexOptions.BoolToInteger)
|
||||
.Add(Name_PhotosDownloaded, PhotosDownloaded.BoolToInteger)
|
||||
End If
|
||||
End With
|
||||
End Sub
|
||||
@@ -142,7 +147,7 @@ Namespace API.TikTok
|
||||
End Function
|
||||
Private Function GetNewFileName(ByVal Title As String, ByVal Native As Boolean, ByVal RemoveTags As Boolean, ByVal AddVideoID As Boolean,
|
||||
ByVal PostID As String, ByVal TitleRegex As RParams) As String
|
||||
If Not Title.IsEmptyString Then Title = Left(Title, 150).StringTrim
|
||||
If Not Title.IsEmptyString Then Title = TitleHtmlConverter(Left(Title, 150)).StringTrim
|
||||
If Title.IsEmptyString Or Not Native Then
|
||||
Title = PostID
|
||||
Else
|
||||
@@ -157,6 +162,9 @@ Namespace API.TikTok
|
||||
End If
|
||||
Return Title
|
||||
End Function
|
||||
Private Function GetPhotoNode() As Object()
|
||||
Return {"imageURL", "urlList", 0, 0}
|
||||
End Function
|
||||
Friend Overrides Sub DownloadData(ByVal Token As CancellationToken)
|
||||
MyBase.DownloadData(Token)
|
||||
UserCache.DisposeIfReady(False)
|
||||
@@ -166,13 +174,21 @@ Namespace API.TikTok
|
||||
Dim URL$ = $"https://www.tiktok.com/@{NameTrue}"
|
||||
UserCache = CreateCache()
|
||||
Try
|
||||
Dim postID$, title$, postUrl$, newName$
|
||||
Const photoPrefix$ = "photo_"
|
||||
Dim postID$, title$, postUrl$, newName$, t$, postID2$, imgUrl$
|
||||
Dim postDate As Date?
|
||||
Dim dateAfterC As Date? = Nothing
|
||||
Dim dateBefore As Date? = DownloadDateTo
|
||||
Dim dateAfter As Date? = DownloadDateFrom
|
||||
Dim baseDataObtained As Boolean = False
|
||||
Dim titleRegex As RParams = GetTitleRegex()
|
||||
Dim vPath As SFile = Nothing, pPath As SFile = Nothing
|
||||
Dim file As SFile
|
||||
Dim j As EContainer, photo As EContainer
|
||||
Dim photoNode As Object() = GetPhotoNode()
|
||||
Dim c%, cc%, i%
|
||||
Dim errDef As New ErrorsDescriber(EDP.ReturnValue)
|
||||
Dim infoParsed As Boolean = False
|
||||
|
||||
If _ContentList.Count > 0 Then
|
||||
With (From d In _ContentList Where d.Post.Date.HasValue Select d.Post.Date.Value)
|
||||
@@ -198,57 +214,151 @@ Namespace API.TikTok
|
||||
End If
|
||||
End If
|
||||
|
||||
Using b As New YTDLP.YTDLPBatch(Token) With {.TempPostsList = _TempPostsList}
|
||||
b.Commands.Clear()
|
||||
b.ChangeDirectory(UserCache)
|
||||
b.Encoding = BatchExecutor.UnicodeEncoding
|
||||
b.Execute(CreateYTCommand(UserCache.RootDirectory, URL, False, dateBefore, dateAfter))
|
||||
End Using
|
||||
If DownloadVideos And Settings.YtdlpFile.Exists And CBool(MySettings.DownloadTTVideos.Value) Then
|
||||
With UserCache.NewInstance : .Validate() : vPath = .RootDirectory : End With
|
||||
Using b As New YTDLP.YTDLPBatch(Token) With {.TempPostsList = _TempPostsList}
|
||||
b.Commands.Clear()
|
||||
b.ChangeDirectory(vPath)
|
||||
b.Encoding = BatchExecutor.UnicodeEncoding
|
||||
b.Execute(CreateYTCommand(vPath, URL, False, dateBefore, dateAfter))
|
||||
End Using
|
||||
End If
|
||||
|
||||
If DownloadImages And Settings.GalleryDLFile.Exists And CBool(MySettings.DownloadTTPhotos.Value) Then
|
||||
With UserCache.NewInstance : .Validate() : pPath = .RootDirectory : End With
|
||||
Using b As New GDL.GDLBatch(Token)
|
||||
With b
|
||||
If PhotosDownloaded And _TempPostsList.Count > 0 Then
|
||||
.TempPostsList = (From p As String In _TempPostsList
|
||||
Where Not p.IsEmptyString AndAlso p.StartsWith(photoPrefix)
|
||||
Select p.Replace(photoPrefix, String.Empty)).ListIfNothing
|
||||
Else
|
||||
.TempPostsList = New List(Of String)
|
||||
End If
|
||||
.ChangeDirectory(pPath)
|
||||
.Encoding = BatchExecutor.UnicodeEncoding
|
||||
.Execute(CreateGDLCommand(URL))
|
||||
If Not PhotosDownloaded Then _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
|
||||
PhotosDownloaded = True
|
||||
End With
|
||||
End Using
|
||||
End If
|
||||
|
||||
ThrowAny(Token)
|
||||
|
||||
Dim files As List(Of SFile) = SFile.GetFiles(UserCache, "*.json",, EDP.ReturnValue)
|
||||
If files.ListExists Then
|
||||
Dim j As EContainer
|
||||
For Each file As SFile In files
|
||||
j = JsonDocument.Parse(file.GetText, EDP.ReturnValue)
|
||||
If j.ListExists Then
|
||||
If j.Value("_type").StringToLower = "video" Then
|
||||
If Not baseDataObtained Then
|
||||
baseDataObtained = True
|
||||
If ID.IsEmptyString Then
|
||||
ID = j.Value("uploader_id")
|
||||
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
|
||||
Dim files As List(Of SFile)
|
||||
If Not vPath.IsEmptyString AndAlso vPath.Exists(SFO.Path, False) Then
|
||||
files = SFile.GetFiles(vPath, "*.json",, errDef)
|
||||
If files.ListExists Then
|
||||
For Each file In files
|
||||
j = JsonDocument.Parse(file.GetText, errDef)
|
||||
If j.ListExists Then
|
||||
If j.Value("_type").StringToLower = "video" Then
|
||||
If Not baseDataObtained Then
|
||||
baseDataObtained = True
|
||||
If ID.IsEmptyString Then ID = j.Value("uploader_id")
|
||||
newName = j.Value("uploader")
|
||||
If Not newName.IsEmptyString Then NameTrue = newName
|
||||
newName = j.Value("creator")
|
||||
If Not newName.IsEmptyString Then UserSiteName = newName
|
||||
End If
|
||||
newName = j.Value("uploader")
|
||||
If Not newName.IsEmptyString Then NameTrue = newName
|
||||
newName = j.Value("creator")
|
||||
If Not newName.IsEmptyString Then UserSiteName = newName
|
||||
End If
|
||||
postID = j.Value("id")
|
||||
If Not _TempPostsList.Contains(postID) Then
|
||||
_TempPostsList.Add(postID)
|
||||
Else
|
||||
Exit Sub
|
||||
End If
|
||||
title = GetNewFileName(j.Value("title").StringRemoveWinForbiddenSymbols,
|
||||
TitleUseNative, RemoveTagsFromTitle, TitleAddVideoID, postID, titleRegex)
|
||||
postDate = AConvert(Of Date)(j.Value("timestamp"), UnixDate32Provider, Nothing)
|
||||
If Not postDate.HasValue Then postDate = AConvert(Of Date)(j.Value("upload_date"), SimpleDateConverter, Nothing)
|
||||
Select Case CheckDatesLimit(postDate, SimpleDateConverter)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : Exit Sub
|
||||
End Select
|
||||
postID = j.Value("id")
|
||||
If Not _TempPostsList.Contains(postID) Then
|
||||
_TempPostsList.ListAddValue(postID, LNC)
|
||||
Else
|
||||
Exit For 'Exit Sub
|
||||
End If
|
||||
title = GetNewFileName(j.Value("title").StringRemoveWinForbiddenSymbols,
|
||||
TitleUseNative, RemoveTagsFromTitle, TitleAddVideoID, postID, titleRegex)
|
||||
postDate = AConvert(Of Date)(j.Value("timestamp"), UnixDate32Provider, Nothing)
|
||||
If Not postDate.HasValue Then postDate = AConvert(Of Date)(j.Value("upload_date"), SimpleDateConverter, Nothing)
|
||||
Select Case CheckDatesLimit(postDate, SimpleDateConverter)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : Exit For 'Exit Sub
|
||||
End Select
|
||||
|
||||
postUrl = j.Value("webpage_url")
|
||||
If postUrl.IsEmptyString Then postUrl = $"https://www.tiktok.com/@{Name}/video/{postID}"
|
||||
_TempMediaList.Add(New UserMedia(postUrl, UserMedia.Types.Video) With {
|
||||
.File = $"{title}.mp4", .Post = New UserPost(postID, postDate)})
|
||||
postUrl = j.Value("webpage_url")
|
||||
If postUrl.IsEmptyString Then postUrl = $"https://www.tiktok.com/@{Name}/video/{postID}"
|
||||
_TempMediaList.Add(New UserMedia(postUrl, UTypes.Video) With {
|
||||
.File = $"{title}.mp4", .Post = New UserPost(postID, postDate)})
|
||||
End If
|
||||
j.Dispose()
|
||||
End If
|
||||
j.Dispose()
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
|
||||
If Not pPath.IsEmptyString AndAlso pPath.Exists(SFO.Path, False) Then
|
||||
files = SFile.GetFiles(pPath, "*.txt",, errDef)
|
||||
If files.ListExists Then
|
||||
For Each file In files
|
||||
t = file.GetText(errDef)
|
||||
If Not t.IsEmptyString Then t = RegexReplace(t, RegexPhotoJson)
|
||||
If Not t.IsEmptyString Then
|
||||
j = JsonDocument.Parse(t, errDef)
|
||||
If j.ListExists Then
|
||||
With j.ItemF({0, "webapp.video-detail", "itemInfo", "itemStruct"})
|
||||
If .ListExists Then
|
||||
postID = .Value("id")
|
||||
postID2 = $"{photoPrefix}{postID}"
|
||||
If Not _TempPostsList.Contains(postID2) Then _TempPostsList.ListAddValue(postID2, LNC) Else Exit For 'Exit Sub
|
||||
postDate = AConvert(Of Date)(j.Value("createTime"), UnixDate32Provider, Nothing)
|
||||
Select Case CheckDatesLimit(postDate, SimpleDateConverter)
|
||||
Case DateResult.Skip : Continue For
|
||||
Case DateResult.Exit : Exit For 'Exit Sub
|
||||
End Select
|
||||
|
||||
If Not infoParsed Then
|
||||
With .Item("author")
|
||||
If .ListExists Then
|
||||
infoParsed = True
|
||||
SimpleDownloadAvatar(.Value("avatarLarger").IfNullOrEmpty(.Value("avatarMedium")).IfNullOrEmpty(.Value("avatarThumb")),
|
||||
Function(ByVal ____url As String) As SFile
|
||||
Dim ____f As SFile = CreateFileFromUrl(____url)
|
||||
If Not ____f.Name.IsEmptyString Then ____f.Name = ____f.Name.Replace(":", "_").Replace("~", "-")
|
||||
If Not ____f.Extension.IsEmptyString Then
|
||||
If Not (____f.Extension = "jpg" Or ____f.Extension = "jpeg") Then
|
||||
____f.Extension = RegexReplace(____f.Extension, RParams.DMS("(.+)\?", 1, EDP.ReturnValue))
|
||||
If Not ____f.Extension.IsEmptyString AndAlso Not (____f.Extension = "jpg" Or ____f.Extension = "jpeg") Then ____f.Extension = String.Empty
|
||||
End If
|
||||
End If
|
||||
Return ____f
|
||||
End Function)
|
||||
UserSiteNameUpdate(.Value("nickname"))
|
||||
UserDescriptionUpdate(.Value("signature"))
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
|
||||
title = GetNewFileName(j.Value({"imagePost"}, "title").StringRemoveWinForbiddenSymbols,
|
||||
TitleUseNative, RemoveTagsFromTitle, TitleAddVideoID, postID, titleRegex)
|
||||
postUrl = $"https://www.tiktok.com/@{Name}/photo/{postID}"
|
||||
With .Item({"imagePost", "images"})
|
||||
If .ListExists Then
|
||||
i = 0
|
||||
c = .Count
|
||||
cc = Math.Max(c.ToString.Length, 3)
|
||||
For Each photo In .Self
|
||||
i += 1
|
||||
imgUrl = photo.ItemF(photoNode).XmlIfNothingValue
|
||||
If Not imgUrl.IsEmptyString Then _
|
||||
_TempMediaList.Add(New UserMedia(imgUrl, UTypes.Picture) With {
|
||||
.URL_BASE = postUrl,
|
||||
.SpecialFolder = "Photo",
|
||||
.File = $"{title}{IIf(c > 1, $"_{i.NumToString(ANumbers.Formats.NumberGroup, cc)}", String.Empty)}.jpg",
|
||||
.Post = New UserPost(postID, postDate)})
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
End If
|
||||
End With
|
||||
j.Dispose()
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
|
||||
If _TempMediaList.Count > 0 Then LastDownloadDate = Now
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
@@ -259,16 +369,41 @@ Namespace API.TikTok
|
||||
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
||||
If ContentMissingExists Then
|
||||
Dim m As UserMedia
|
||||
Dim d As IYouTubeMediaContainer = Nothing
|
||||
Dim i%
|
||||
Dim rList As New List(Of Integer)
|
||||
Dim picIDs As New List(Of String)
|
||||
Dim defDir As SFile = SFile.GetPath(DownloadContentDefault_GetRootDir())
|
||||
Dim result As Boolean
|
||||
For i = 0 To _ContentList.Count - 1
|
||||
If _ContentList(i).State = UserMedia.States.Missing Then
|
||||
m = _ContentList(i)
|
||||
m.URL = m.URL_BASE
|
||||
_TempMediaList.Add(m)
|
||||
rList.Add(i)
|
||||
result = False
|
||||
Try
|
||||
If m.Type = UTypes.Video Then
|
||||
d = MySettings.GetSingleMediaInstance(m.URL_BASE, defDir)
|
||||
result = False
|
||||
If If(UserCache?.Disposed, True) Then UserCache = CreateCache()
|
||||
DownloadSingleObject_GetPosts(d, Token, UserCache, result)
|
||||
ElseIf m.Type = UTypes.Picture Then
|
||||
If picIDs.Contains(m.Post.ID) Then
|
||||
rList.Add(i)
|
||||
Else
|
||||
d = MySettings.GetSingleMediaInstance(m.URL_BASE, defDir)
|
||||
If If(UserCache?.Disposed, True) Then UserCache = CreateCache()
|
||||
DownloadSingleObject_GetPosts(d, Token, UserCache, result)
|
||||
picIDs.Add(m.Post.ID)
|
||||
End If
|
||||
End If
|
||||
Catch ex As Exception
|
||||
result = False
|
||||
ProcessException(ex, Token, "ReparseMissing")
|
||||
End Try
|
||||
If result Then rList.Add(i)
|
||||
d.DisposeIfReady(False)
|
||||
End If
|
||||
Next
|
||||
picIDs.Clear()
|
||||
If rList.Count > 0 Then
|
||||
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
|
||||
End If
|
||||
@@ -287,7 +422,11 @@ Namespace API.TikTok
|
||||
End If
|
||||
If DateBefore.HasValue Then command &= $"--datebefore {DateBefore.Value.AddDays(1).ToStringDate(SimpleDateConverter)} "
|
||||
If DateAfter.HasValue Then command &= $"--dateafter {DateAfter.Value.AddDays(-1).ToStringDate(SimpleDateConverter)} "
|
||||
If Not CBool(If(IsSingleObjectDownload, MySettings.UseParsedVideoDateSTD, MySettings.UseParsedVideoDate).Value) Then command &= "--no-mtime "
|
||||
If Not CBool(If(IsSingleObjectDownload, MySettings.UseParsedVideoDateSTD, MySettings.UseParsedVideoDate).Value) Then
|
||||
command &= "--no-mtime "
|
||||
Else
|
||||
command &= "--mtime "
|
||||
End If
|
||||
If MySettings.CookiesNetscapeFile.Exists Then command &= $"--no-cookies-from-browser --cookies ""{MySettings.CookiesNetscapeFile}"" "
|
||||
command &= $"{URL} "
|
||||
If SupportOutput Then
|
||||
@@ -303,10 +442,18 @@ Namespace API.TikTok
|
||||
Return command
|
||||
End Function
|
||||
#End Region
|
||||
#Region "GDL Support"
|
||||
Private Function CreateGDLCommand(ByVal URL As String) As String
|
||||
Return $"""{Settings.GalleryDLFile}"" --verbose --no-download --no-skip --write-pages {URL}"
|
||||
End Function
|
||||
#End Region
|
||||
#Region "DownloadContent, DownloadFile"
|
||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||
DownloadContentDefault(Token)
|
||||
End Sub
|
||||
Protected Overrides Function ValidateDownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByRef Interrupt As Boolean) As Boolean
|
||||
Return Not Media.Type = UTypes.Picture
|
||||
End Function
|
||||
Protected Overrides Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
||||
Using b As New TokenBatch(Token) With {.FileExchanger = RootCacheTikTok}
|
||||
b.Encoding = BatchExecutor.UnicodeEncoding
|
||||
@@ -316,33 +463,94 @@ Namespace API.TikTok
|
||||
End Function
|
||||
#End Region
|
||||
#Region "DownloadSingleObject"
|
||||
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||
Protected Overloads Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||
DownloadSingleObject_GetPosts(Data, Token, Nothing, Nothing)
|
||||
End Sub
|
||||
Private Overloads Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken,
|
||||
ByRef Cache As CacheKeeper, ByRef Result As Boolean)
|
||||
Dim f$ = String.Empty
|
||||
If CBool(MySettings.TitleUseNativeSTD.Value) Then
|
||||
Using b As New BatchExecutor(True) With {
|
||||
.Encoding = BatchExecutor.UnicodeEncoding,
|
||||
.CleanAutomaticallyViaRegEx = True,
|
||||
.CleanAutomaticallyViaRegExRemoveAllCommands = True
|
||||
}
|
||||
b.Execute(CreateYTCommand(Nothing, Data.URL, True,,, True, False))
|
||||
b.Clean()
|
||||
With b.OutputData
|
||||
If .Count > 0 Then
|
||||
For Each vData$ In .Self
|
||||
If Not vData.Contains($": {BatchExecutor.UnicodeEncoding}") Then f = vData : Exit For
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
Dim urlsList As New List(Of String)
|
||||
Dim t As UTypes
|
||||
Dim defName$ = New SFile(Data.URL).Name
|
||||
If Data.URL.ToLower.Contains("/video/") Then
|
||||
urlsList.Add(Data.URL)
|
||||
t = UTypes.Video
|
||||
If CBool(MySettings.TitleUseNativeSTD.Value) Then
|
||||
Using b As New BatchExecutor(True) With {
|
||||
.Encoding = BatchExecutor.UnicodeEncoding,
|
||||
.CleanAutomaticallyViaRegEx = True,
|
||||
.CleanAutomaticallyViaRegExRemoveAllCommands = True
|
||||
}
|
||||
b.Execute(CreateYTCommand(Nothing, Data.URL, True,,, True, False))
|
||||
b.Clean()
|
||||
With b.OutputData
|
||||
If .Count > 0 Then
|
||||
For Each vData$ In .Self
|
||||
If Not vData.Contains($": {BatchExecutor.UnicodeEncoding}") Then f = vData : Exit For
|
||||
Next
|
||||
End If
|
||||
End With
|
||||
End Using
|
||||
End If
|
||||
Else
|
||||
t = UTypes.Picture
|
||||
Data.ContentType = Plugin.UserMediaTypes.Picture
|
||||
Data.Title = defName
|
||||
Dim dir As SFile
|
||||
With If(Cache, Settings.Cache).NewInstance() : .Validate() : dir = .RootDirectory : End With
|
||||
Using b As New GDL.GDLBatch(Token)
|
||||
b.ChangeDirectory(dir)
|
||||
b.Encoding = BatchExecutor.UnicodeEncoding
|
||||
b.Execute(CreateGDLCommand(Data.URL))
|
||||
End Using
|
||||
Dim file As SFile = SFile.GetFiles(dir, "*.txt",, EDP.ReturnValue).FirstOrDefault
|
||||
If file.Exists Then
|
||||
Dim r$ = file.GetText(EDP.ReturnValue)
|
||||
If Not r.IsEmptyString Then r = RegexReplace(r, RegexPhotoJson)
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||
If j.ListExists Then
|
||||
With j.ItemF({0, "webapp.video-detail", "itemInfo", "itemStruct"})
|
||||
If CBool(MySettings.TitleUseNativeSTD.Value) Then f = j.Value({"imagePost"}, "title").StringRemoveWinForbiddenSymbols
|
||||
With .Item({"imagePost", "images"})
|
||||
If .ListExists Then
|
||||
For Each photo As EContainer In .Self : urlsList.Add(photo.ItemF(GetPhotoNode()).XmlIfNothingValue) : Next
|
||||
End If
|
||||
End With
|
||||
End With
|
||||
End If
|
||||
End Using
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Dim m As New UserMedia(Data.URL, UserMedia.Types.Video)
|
||||
If Not f.IsEmptyString Then f = TitleHtmlConverter(f)
|
||||
If Not f.IsEmptyString Then
|
||||
f = GetNewFileName(f, MySettings.TitleUseNativeSTD.Value, MySettings.RemoveTagsFromTitle.Value, MySettings.TitleAddVideoIDSTD.Value,
|
||||
m.File.Name, GetTitleRegex)
|
||||
If Not f.IsEmptyString Then m.File.Name = f.StringTrim
|
||||
|
||||
Dim m As UserMedia
|
||||
Dim i% = 0, c%, cc%
|
||||
Dim ff As Boolean = False
|
||||
If urlsList.Count > 0 Then
|
||||
c = urlsList.Count
|
||||
cc = Math.Max(c.ToString.Length, 3)
|
||||
For Each url$ In urlsList
|
||||
i += 1
|
||||
m = New UserMedia(url, t) With {.URL_BASE = Data.URL}
|
||||
If Not f.IsEmptyString Then f = TitleHtmlConverter(f)
|
||||
If Not f.IsEmptyString Or t = UTypes.Picture Then
|
||||
If Not ff Then f = GetNewFileName(f, MySettings.TitleUseNativeSTD.Value, MySettings.RemoveTagsFromTitle.Value, MySettings.TitleAddVideoIDSTD.Value,
|
||||
defName, GetTitleRegex)
|
||||
ff = True
|
||||
If Not f.IsEmptyString Then
|
||||
m.File.Name = $"{f.StringTrim}{IIf(c > 1, $"_{i.NumToString(ANumbers.Formats.NumberGroup, cc)}", String.Empty)}"
|
||||
If t = UTypes.Picture Then m.File.Extension = "jpg"
|
||||
End If
|
||||
End If
|
||||
|
||||
_TempMediaList.Add(m)
|
||||
Result = True
|
||||
Next
|
||||
End If
|
||||
_TempMediaList.Add(m)
|
||||
End Sub
|
||||
Protected Overrides Sub DownloadSingleObject_PostProcessing(ByVal Data As IYouTubeMediaContainer, Optional ByVal ResetTitle As Boolean = True)
|
||||
MyBase.DownloadSingleObject_PostProcessing(Data, Not Data.ContentType = Plugin.UserMediaTypes.Picture)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "EraseData"
|
||||
|
||||
@@ -50,8 +50,13 @@ Namespace API.Twitter
|
||||
Caption:="Force apply",
|
||||
ToolTip:="Force overrides the default parameters for the first download." & vbCr & "Applies to first download only.", LeftOffset:=DefaultOffset)>
|
||||
Friend Overridable Property DownloadModelForceApply As Boolean = False
|
||||
<PSetting(Address:=SettingAddress.User,
|
||||
Caption:="Large profile",
|
||||
ToolTip:="This setting is only used on the first download and is intended to temporarily override the default site settings if they are incompatible with downloading large profiles. After the first download is complete, this option will be disabled and cannot be enabled again.")>
|
||||
Friend Overridable Property LargeProfile As Boolean = False
|
||||
Private ReadOnly Property MySettings As Object
|
||||
Friend Sub New(ByVal s As SiteSettings)
|
||||
MyBase.New(s)
|
||||
GifsDownload = s.GifsDownload.Value
|
||||
GifsSpecialFolder = s.GifsSpecialFolder.Value
|
||||
GifsPrefix = s.GifsPrefix.Value
|
||||
@@ -75,6 +80,7 @@ Namespace API.Twitter
|
||||
UseMD5Comparison = u.UseMD5Comparison
|
||||
RemoveExistingDuplicates = u.RemoveExistingDuplicates
|
||||
MediaModelAllowNonUserTweets = u.MediaModelAllowNonUserTweets
|
||||
LargeProfile = u.LargeProfile
|
||||
If Not TypeOf u Is Mastodon.UserData Then
|
||||
DownloadModelForceApply = u.DownloadModelForceApply
|
||||
DownloadBroadcasts = u.DownloadBroadcasts
|
||||
|
||||
@@ -38,6 +38,7 @@ Namespace API.Twitter
|
||||
Private Const CAT_DOWN As String = "Downloading"
|
||||
#End Region
|
||||
#Region "Auth"
|
||||
Friend Property CookiesUpdateForce As Boolean = False
|
||||
<PropertyOption(ControlText:="Update cookies", ControlToolTip:="Update cookies during requests", IsAuth:=True), PXML, PClonable, HiddenControl>
|
||||
Friend ReadOnly Property CookiesUpdate As PropertyValue
|
||||
<PropertyOption(ControlText:="Use UserAgent", ControlToolTip:="Use UserAgent in requests", IsAuth:=True), PXML, PClonable>
|
||||
@@ -45,9 +46,9 @@ Namespace API.Twitter
|
||||
<PropertyOption(ControlText:="UserAgent", IsAuth:=True, AllowNull:=True, InheritanceName:=SettingsCLS.HEADER_DEF_UserAgent),
|
||||
PXML("UserAgent", OnlyForChecked:=True), PClonable>
|
||||
Private ReadOnly Property UserAgentXML As PropertyValue
|
||||
Friend ReadOnly Property UserAgent As String
|
||||
Friend ReadOnly Property UserAgent(Optional ByVal Force As Boolean = False) As String
|
||||
Get
|
||||
If CBool(UserAgentUse.Value) AndAlso Not CStr(UserAgentXML.Value).IsEmptyString Then
|
||||
If (CBool(UserAgentUse.Value) Or Force) AndAlso Not CStr(UserAgentXML.Value).IsEmptyString Then
|
||||
Return UserAgentXML.Value
|
||||
Else
|
||||
Return String.Empty
|
||||
@@ -73,6 +74,7 @@ Namespace API.Twitter
|
||||
#Region "Limits"
|
||||
Friend Const TimerDisabled As Integer = -1
|
||||
Friend Const TimerFirstUseTheSame As Integer = -2
|
||||
Friend Const TimerDefault As Integer = 20
|
||||
<PropertyOption(ControlText:="Abort on limit", ControlToolTip:="Abort twitter downloading when limit is reached", Category:=CAT_DOWN), PXML, PClonable>
|
||||
Friend Property AbortOnLimit As PropertyValue
|
||||
<PropertyOption(ControlText:="Download already parsed", ControlToolTip:="Download already parsed content on abort", Category:=CAT_DOWN), PXML, PClonable>
|
||||
@@ -143,6 +145,7 @@ Namespace API.Twitter
|
||||
End Property
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Private Const SettingsVersionCurrent As Integer = 1
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
MyBase.New(TwitterSite, "x.com", AccName, Temp, My.Resources.SiteResources.TwitterIcon_32, My.Resources.SiteResources.TwitterIcon_32.ToBitmap)
|
||||
|
||||
@@ -153,7 +156,7 @@ Namespace API.Twitter
|
||||
.Cookies.Changed = False
|
||||
End With
|
||||
|
||||
UseNewIconXML = New PropertyValue(False)
|
||||
UseNewIconXML = New PropertyValue(True)
|
||||
|
||||
CookiesUpdate = New PropertyValue(False)
|
||||
UserAgentUse = New PropertyValue(True)
|
||||
@@ -192,6 +195,10 @@ Namespace API.Twitter
|
||||
UseNetscapeCookies = True
|
||||
End Sub
|
||||
Friend Overrides Sub EndInit()
|
||||
If Not SettingsVersion.Value = SettingsVersionCurrent Then
|
||||
UseNewIconXML.Value = True
|
||||
SettingsVersion.Value = SettingsVersionCurrent
|
||||
End If
|
||||
UpdateIcon()
|
||||
MyBase.EndInit()
|
||||
End Sub
|
||||
@@ -223,7 +230,7 @@ Namespace API.Twitter
|
||||
End Sub
|
||||
Friend Overrides Sub DownloadDone(ByVal What As ISiteSettings.Download)
|
||||
If UserNumber > 0 Then
|
||||
If CBool(CookiesUpdate.Value) Then
|
||||
If CBool(CookiesUpdate.Value) Or CookiesUpdateForce Then
|
||||
With CookieKeeper.ParseNetscapeText(CookiesNetscapeFile.GetText(EDP.ReturnValue), EDP.ReturnValue)
|
||||
If .ListExists Then
|
||||
Responser.Cookies.Clear()
|
||||
@@ -250,6 +257,7 @@ Namespace API.Twitter
|
||||
End With
|
||||
End If
|
||||
LIMIT_ABORT = False
|
||||
CookiesUpdateForce = False
|
||||
MyBase.DownloadDone(What)
|
||||
End Sub
|
||||
#End Region
|
||||
|
||||
@@ -30,6 +30,7 @@ Namespace API.Twitter
|
||||
Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
|
||||
Private Const Name_GifsPrefix As String = "GifsPrefix"
|
||||
Private Const Name_IsCommunity As String = "IsCommunity"
|
||||
Private Const Name_LargeProfile As String = "LargeProfile"
|
||||
Private Const Name_DownloadModelChanged As String = "DownloadModelChanged"
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
@@ -62,6 +63,47 @@ Namespace API.Twitter
|
||||
Friend Property GifsSpecialFolder As String = String.Empty
|
||||
Friend Property GifsPrefix As String = String.Empty
|
||||
Friend Property IsCommunity As Boolean = False
|
||||
#Region "LargeProfile"
|
||||
Friend Property LargeProfile As Boolean = False
|
||||
Private ReadOnly Property LargeProfileOverride As Boolean
|
||||
Get
|
||||
Return LargeProfile And Not FirstDownloadComplete
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property CookiesUpdate As Boolean
|
||||
Get
|
||||
If LargeProfileOverride Then
|
||||
MySettings.CookiesUpdateForce = True
|
||||
Return True
|
||||
Else
|
||||
Return MySettings.CookiesUpdate.Value
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property UserAgent As String
|
||||
Get
|
||||
If LargeProfileOverride Then
|
||||
Return MySettings.UserAgent(True).IfNullOrEmpty(Settings.UserAgent)
|
||||
Else
|
||||
Return MySettings.UserAgent
|
||||
End If
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property SleepTimerBeforeFirst As Integer
|
||||
Get
|
||||
Dim v% = MySettings.SleepTimerBeforeFirst.Value
|
||||
If LargeProfileOverride And v <= 0 And v <> SiteSettings.TimerFirstUseTheSame Then v = SiteSettings.TimerFirstUseTheSame
|
||||
Return v
|
||||
End Get
|
||||
End Property
|
||||
Private ReadOnly Property SleepTimer As Integer
|
||||
Get
|
||||
Dim v% = MySettings.SleepTimer.Value
|
||||
If LargeProfileOverride And v <= 0 Then v = SiteSettings.TimerDefault
|
||||
Return v
|
||||
End Get
|
||||
End Property
|
||||
#End Region
|
||||
Private ReadOnly LikesPosts As List(Of String)
|
||||
Private ReadOnly PostsKV As List(Of PKV)
|
||||
Private ReadOnly _DataNames As List(Of String)
|
||||
@@ -89,6 +131,7 @@ Namespace API.Twitter
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptions Then
|
||||
With DirectCast(Obj, EditorExchangeOptions)
|
||||
.ApplyBase(Me)
|
||||
GifsDownload = .GifsDownload
|
||||
GifsSpecialFolder = .GifsSpecialFolder
|
||||
GifsPrefix = .GifsPrefix
|
||||
@@ -99,13 +142,13 @@ Namespace API.Twitter
|
||||
DownloadModelForceApply = .DownloadModelForceApply
|
||||
MediaModelAllowNonUserTweets = .MediaModelAllowNonUserTweets
|
||||
DownloadBroadcasts = .DownloadBroadcasts
|
||||
LargeProfile = .LargeProfile
|
||||
Dim dModel As DownloadModels = DownloadModel
|
||||
If .DownloadModelMedia Then DownloadModel += DownloadModels.Media
|
||||
If .DownloadModelProfile Or .DownloadBroadcasts Then DownloadModel += DownloadModels.Profile
|
||||
If .DownloadModelSearch Then DownloadModel += DownloadModels.Search
|
||||
If .DownloadModelLikes Then DownloadModel += DownloadModels.Likes
|
||||
If Not dModel = DownloadModel Then DownloadModelChanged = True
|
||||
NameTrue = .UserName
|
||||
End With
|
||||
End If
|
||||
End Sub
|
||||
@@ -155,6 +198,7 @@ Namespace API.Twitter
|
||||
StartMD5Checked = .Value(Name_StartMD5Checked).FromXML(Of Boolean)(False)
|
||||
MediaModelAllowNonUserTweets = .Value(Name_MediaModelAllowNonUserTweets).FromXML(Of Boolean)(False)
|
||||
IsCommunity = .Value(Name_IsCommunity).FromXML(Of Boolean)(False)
|
||||
LargeProfile = .Value(Name_LargeProfile).FromXML(Of Boolean)(False)
|
||||
Else
|
||||
If Name.Contains("@") And Not IsCommunity Then
|
||||
IsCommunity = True
|
||||
@@ -180,6 +224,7 @@ Namespace API.Twitter
|
||||
.Add(Name_StartMD5Checked, StartMD5Checked.BoolToInteger)
|
||||
.Add(Name_MediaModelAllowNonUserTweets, MediaModelAllowNonUserTweets.BoolToInteger)
|
||||
.Add(Name_IsCommunity, IsCommunity.BoolToInteger)
|
||||
.Add(Name_LargeProfile, LargeProfile.BoolToInteger)
|
||||
.Add(Name_TrueName, NameTrue(True))
|
||||
End If
|
||||
End With
|
||||
@@ -257,9 +302,13 @@ Namespace API.Twitter
|
||||
Return result
|
||||
End Function
|
||||
Friend Property GDL_REQUESTS_COUNT As Integer = 0
|
||||
Private Const DEBUG_PROFILE As Boolean = False
|
||||
Private Const DEBUG_LEAVE_CACHE As Boolean = False
|
||||
Private JsonNullErr As Boolean = False
|
||||
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
||||
Try
|
||||
GDL_REQUESTS_COUNT = 0
|
||||
JsonNullErr = False
|
||||
If MySettings.LIMIT_ABORT Then
|
||||
Throw New TwitterLimitException(Me)
|
||||
Else
|
||||
@@ -277,6 +326,7 @@ Namespace API.Twitter
|
||||
LikesPosts.Clear()
|
||||
If _ContentList.Count > 0 Then _DataNames.ListAddList(_ContentList.Select(Function(c) c.File.File), LAP.ClearBeforeAdd, LAP.NotContainsOnly)
|
||||
DownloadData_Timeline(Token)
|
||||
If _TempMediaList.Count = 0 And LikesPosts.Count = 0 And JsonNullErr Then Throw New Plugin.ExitException("No deserialized data found")
|
||||
LoadSavePostsKV(False)
|
||||
If LikesPosts.Count > 0 Then
|
||||
_ReparseLikes = True
|
||||
@@ -289,10 +339,20 @@ Namespace API.Twitter
|
||||
_ReparseLikes = False
|
||||
End Try
|
||||
End Sub
|
||||
Private Class WebDocumentEventArgsT : Inherits WebDocumentEventArgs
|
||||
Public Overloads Overrides Sub Reset()
|
||||
State = States.None
|
||||
End Sub
|
||||
Public Overloads Sub Reset(ByVal Token As CancellationToken)
|
||||
Reset()
|
||||
Me.Token = Token
|
||||
End Sub
|
||||
End Class
|
||||
Private Sub DownloadData_Timeline(ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Dim tCache As CacheKeeper = Nothing
|
||||
Dim likesDetected As Boolean = False
|
||||
Dim jsonArgs As New WebDocumentEventArgsT With {.DeclaredError = New ErrorsDescriber(EDP.ReturnValue)}
|
||||
Try
|
||||
Const entry$ = "entry"
|
||||
Dim PostID$ = String.Empty
|
||||
@@ -340,6 +400,8 @@ Namespace API.Twitter
|
||||
ElseIf dirIndx = 3 Then
|
||||
ElseIf isPins Then
|
||||
Return False
|
||||
ElseIf Not FirstDownloadComplete Then
|
||||
Return True
|
||||
Else
|
||||
ExistsDetected = Not multiMode
|
||||
Return multiMode
|
||||
@@ -379,13 +441,24 @@ Namespace API.Twitter
|
||||
Return True
|
||||
End Function
|
||||
|
||||
tCache = CreateCache()
|
||||
If Not DEBUG_PROFILE Then tCache = CreateCache()
|
||||
|
||||
'0 - media
|
||||
'1 - profile
|
||||
'2 - search
|
||||
'3 - likes
|
||||
Dim dirs As List(Of SFile) = GetTimelineFromGalleryDL(tCache, Token)
|
||||
Dim dirs As List(Of SFile)
|
||||
If Not DEBUG_PROFILE Then
|
||||
dirs = GetTimelineFromGalleryDL(tCache, Token)
|
||||
Else
|
||||
dirs = SFile.GetDirectories($"{DownloadContentDefault_GetRootDir()}\_tCache\".CSFileP)
|
||||
If dirs.ListExists(2) Then
|
||||
dirs = SFile.GetDirectories(dirs(1))
|
||||
Else
|
||||
dirs = New List(Of SFile)
|
||||
End If
|
||||
End If
|
||||
|
||||
If dirs.ListExists Then
|
||||
For Each dir As SFile In dirs
|
||||
dirIndx += 1
|
||||
@@ -408,12 +481,18 @@ Namespace API.Twitter
|
||||
If timelineFiles.ListExists Then
|
||||
ResetFileNameProvider(Math.Max(timelineFiles.Count.ToString.Length, 2))
|
||||
'rename files
|
||||
For i = 0 To timelineFiles.Count - 1 : timelineFiles(i) = RenameGdlFile(timelineFiles(i), i) : Next
|
||||
If Not DEBUG_PROFILE Then
|
||||
For i = 0 To timelineFiles.Count - 1 : timelineFiles(i) = RenameGdlFile(timelineFiles(i), i) : Next
|
||||
End If
|
||||
'parse files
|
||||
For i = 0 To timelineFiles.Count - 1
|
||||
j = JsonDocument.Parse(timelineFiles(i).GetText)
|
||||
j = JsonDocument.Parse(timelineFiles(i).GetText, jsonArgs)
|
||||
If jsonArgs.State = WebDocumentEventArgs.States.Error Then
|
||||
jsonArgs.Reset(Token)
|
||||
Continue For
|
||||
End If
|
||||
If Not j Is Nothing Then
|
||||
If i = 0 And Not indxChanged Then
|
||||
If Not userInfoParsed Or (i = 0 And Not indxChanged) Then
|
||||
If Not userInfoParsed Then
|
||||
userInfoParsed = True
|
||||
Dim resValue$ = j.Value({"data", IIf(IsCommunity, "communityResults", "user"), "result"}, "__typename").StringTrim.StringToLower
|
||||
@@ -453,10 +532,7 @@ Namespace API.Twitter
|
||||
Else
|
||||
With j({"data", "user", "result"})
|
||||
If .ListExists Then
|
||||
If ID.IsEmptyString Then
|
||||
ID = .Value("rest_id")
|
||||
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
|
||||
End If
|
||||
If ID.IsEmptyString Then ID = .Value("rest_id")
|
||||
With .Item({"legacy"})
|
||||
If .ListExists Then
|
||||
If .Value("screen_name").StringToLower = NameTrue.ToLower Then
|
||||
@@ -498,6 +574,8 @@ Namespace API.Twitter
|
||||
Select Case dirIndx
|
||||
Case 0, 1, 3
|
||||
rootNode = j({"data", "user", "result", "timeline_v2", "timeline", "instructions"})
|
||||
If Not rootNode.ListExists Then rootNode = j({"data", "user", "result", "timeline", "timeline", "instructions"})
|
||||
If Not rootNode.ListExists Then rootNode = j({"data", "search_by_raw_query", "search_timeline", "timeline", "instructions"})
|
||||
If rootNode.ListExists Then
|
||||
If dirIndx = 3 Then
|
||||
p = entriesNode
|
||||
@@ -582,6 +660,7 @@ nextpIndx:
|
||||
End If
|
||||
DownloadModelForceApply = False
|
||||
FirstDownloadComplete = True
|
||||
LargeProfile = False
|
||||
Catch jsonNull_ex As JsonDocumentException When jsonNull_ex.State = WebDocumentEventArgs.States.Error
|
||||
Throw New Plugin.ExitException("No deserialized data found")
|
||||
Catch limit_ex As TwitterLimitException
|
||||
@@ -589,8 +668,9 @@ nextpIndx:
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
Finally
|
||||
If Not tCache Is Nothing Then tCache.Dispose()
|
||||
If Not tCache Is Nothing And Not DEBUG_PROFILE And Not DEBUG_LEAVE_CACHE Then tCache.Dispose()
|
||||
If _TempPostsList.Count > 0 And Not likesDetected Then _TempPostsList.Sort()
|
||||
jsonArgs.DisposeIfReady(False)
|
||||
End Try
|
||||
End Sub
|
||||
Private Sub DownloadData_SavedPosts(ByVal Token As CancellationToken)
|
||||
@@ -642,30 +722,42 @@ nextpIndx:
|
||||
Dim s As EContainer = e({"extended_entities", "media"})
|
||||
If If(s?.Count, 0) = 0 Then s = e({"retweeted_status", "extended_entities", "media"})
|
||||
If If(s?.Count, 0) = 0 Then s = e({"retweeted_status_result", "result", "legacy", "extended_entities", "media"})
|
||||
Dim txt$ = If(DownloadText, e.Value("full_text"), String.Empty)
|
||||
|
||||
Dim mUrl$
|
||||
Dim media As UserMedia
|
||||
Dim setMediaDef As Action = Sub()
|
||||
If Not SpecialFolder.IsEmptyString Then media.SpecialFolder = SpecialFolder
|
||||
media.PostText = txt
|
||||
media.PostTextFileSpecialFolder = DownloadTextSpecialFolder
|
||||
End Sub
|
||||
If If(s?.Count, 0) > 0 Then
|
||||
Dim mUrl$
|
||||
Dim media As UserMedia
|
||||
For Each m As EContainer In s
|
||||
If Not CheckVideoNode(m, PostID, PostDate, State, SpecialFolder) Then
|
||||
If Not CheckVideoNode(m, PostID, PostDate, State, SpecialFolder, txt) Then
|
||||
mUrl = m.Value("media_url").IfNullOrEmpty(m.Value("media_url_https"))
|
||||
If Not mUrl.IsEmptyString Then
|
||||
Dim dName$ = UrlFile(mUrl)
|
||||
If Not dName.IsEmptyString AndAlso Not _DataNames.Contains(dName) Then
|
||||
_DataNames.Add(dName)
|
||||
media = MediaFromData(mUrl, PostID, PostDate, GetPictureOption(m), State, UTypes.Picture, Attempts)
|
||||
If Not SpecialFolder.IsEmptyString Then media.SpecialFolder = SpecialFolder
|
||||
setMediaDef()
|
||||
_TempMediaList.ListAddValue(media, LNC)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
ElseIf Not txt.IsEmptyString And DownloadTextPosts Then
|
||||
media = MediaFromData(PostID, PostID, PostDate, String.Empty, State, UTypes.Text, Attempts)
|
||||
setMediaDef()
|
||||
media.PostTextFile = $"{PostID}.txt"
|
||||
_TempMediaList.ListAddValue(media, LNC)
|
||||
End If
|
||||
End Sub
|
||||
Private Function CheckVideoNode(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal SpecialFolder As String = Nothing) As Boolean
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal SpecialFolder As String = Nothing,
|
||||
Optional ByVal PostText As String = Nothing) As Boolean
|
||||
Try
|
||||
If CheckForGif(w, PostID, PostDate, State, SpecialFolder) Then Return True
|
||||
If CheckForGif(w, PostID, PostDate, State, SpecialFolder, PostText) Then Return True
|
||||
Dim URL$ = GetVideoNodeURL(w)
|
||||
If Not URL.IsEmptyString Then
|
||||
Dim f$ = UrlFile(URL)
|
||||
@@ -673,6 +765,7 @@ nextpIndx:
|
||||
_DataNames.Add(f)
|
||||
Dim m As UserMedia = MediaFromData(URL, PostID, PostDate,, State, UTypes.Video)
|
||||
If Not SpecialFolder.IsEmptyString Then m.SpecialFolder = SpecialFolder
|
||||
m.PostText = PostText
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
End If
|
||||
Return True
|
||||
@@ -684,7 +777,8 @@ nextpIndx:
|
||||
End Try
|
||||
End Function
|
||||
Private Function CheckForGif(ByVal w As EContainer, ByVal PostID As String, ByVal PostDate As String,
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal SpecialFolder As String = Nothing) As Boolean
|
||||
Optional ByVal State As UStates = UStates.Unknown, Optional ByVal SpecialFolder As String = Nothing,
|
||||
Optional ByVal PostText As String = Nothing) As Boolean
|
||||
Try
|
||||
Dim gifUrl As Predicate(Of EContainer) = Function(e) Not e.Value("content_type").IsEmptyString AndAlso
|
||||
e.Value("content_type").Contains("mp4") AndAlso
|
||||
@@ -710,6 +804,7 @@ nextpIndx:
|
||||
If Not m.SpecialFolder.IsEmptyString Then m.SpecialFolder &= "\"
|
||||
m.SpecialFolder &= $"{GifsSpecialFolder}*"
|
||||
End If
|
||||
m.PostText = PostText
|
||||
_TempMediaList.ListAddValue(m, LNC)
|
||||
End If
|
||||
Return True
|
||||
@@ -790,8 +885,8 @@ nextpIndx:
|
||||
End Class
|
||||
Private ReadOnly Property SleepTimerValue(ByVal First As Boolean) As Integer
|
||||
Get
|
||||
Dim fTimer% = If(First, MySettings.SleepTimerBeforeFirst, MySettings.SleepTimer).Value
|
||||
If First And fTimer = SiteSettings.TimerFirstUseTheSame Then fTimer = MySettings.SleepTimer.Value
|
||||
Dim fTimer% = If(First, SleepTimerBeforeFirst, SleepTimer)
|
||||
If First And fTimer = SiteSettings.TimerFirstUseTheSame Then fTimer = SleepTimer
|
||||
Return fTimer
|
||||
End Get
|
||||
End Property
|
||||
@@ -1011,10 +1106,10 @@ nextpIndx:
|
||||
Private Function GdlCreateConf(ByVal Path As SFile) As SFile
|
||||
Try
|
||||
Dim conf As SFile = $"{Path.PathWithSeparator}TwitterGdlConfig.conf"
|
||||
Dim __userAgent$ = MySettings.UserAgent
|
||||
Dim __userAgent$ = UserAgent
|
||||
If Not __userAgent.IsEmptyString Then __userAgent = $"""user-agent"": ""{__userAgent}"","
|
||||
Dim confText$ = "{""extractor"":{""cookies"": """ & MySettings.CookiesNetscapeFile.ToString.Replace("\", "/") &
|
||||
$""",""cookies-update"": {IIf(CBool(MySettings.CookiesUpdate.Value), "true", "false")}," & __userAgent &
|
||||
$""",""cookies-update"": {IIf(CookiesUpdate, "true", "false")}," & __userAgent &
|
||||
"""twitter"":{""tweet-endpoint"": ""detail"",""cards"": false,""conversations"": true,""pinned"": false,""quoted"": false,""replies"": true,""retweets"": true,""strategy"": null,""text-tweets"": false,""twitpic"": false,""unique"": true,""users"": ""timeline"",""videos"": true}}}"
|
||||
If conf.Exists(SFO.Path, True, EDP.ThrowException) Then TextSaver.SaveTextToFile(confText, conf)
|
||||
If Not conf.Exists Then Throw New IO.FileNotFoundException("Can't find Twitter GDL config file", conf)
|
||||
|
||||
@@ -35,6 +35,9 @@ Namespace API.XVIDEOS
|
||||
"This playlist must be entered by pattern: https://www.xvideos.com/favorite/01234567/playlistname.",
|
||||
LeftOffset:=130), PXML, PClonable(Clone:=False)>
|
||||
Friend ReadOnly Property SavedVideosPlaylist As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
@@ -47,6 +50,7 @@ Namespace API.XVIDEOS
|
||||
|
||||
_SubscriptionsAllowed = True
|
||||
UrlPatternUser = "https://xvideos.com/{0}"
|
||||
UserOptionsType = GetType(EditorExchangeOptionsBase_P)
|
||||
End Sub
|
||||
Friend Overrides Sub EndInit()
|
||||
Domains.PopulateInitialDomains(SiteDomains.Value)
|
||||
@@ -149,14 +153,6 @@ Namespace API.XVIDEOS
|
||||
Return Nothing
|
||||
End Function
|
||||
#End Region
|
||||
#Region "UserOptions"
|
||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions
|
||||
If OpenForm Then
|
||||
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "IDisposable Support"
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then _Domains.Dispose()
|
||||
|
||||
@@ -15,7 +15,7 @@ Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.XVIDEOS
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Friend Class UserData : Inherits UserDataBase : Implements IPSite
|
||||
#Region "XML names"
|
||||
Private Const Name_PersonType As String = "PersonType"
|
||||
#End Region
|
||||
@@ -62,7 +62,7 @@ Namespace API.XVIDEOS
|
||||
Return {SearchRequestLabelName}
|
||||
End Get
|
||||
End Property
|
||||
Friend Property QueryString As String
|
||||
Friend Property QueryString As String Implements IPSite.QueryString
|
||||
Get
|
||||
If SiteMode = SiteModes.User Then
|
||||
Return String.Empty
|
||||
@@ -82,10 +82,10 @@ Namespace API.XVIDEOS
|
||||
#End Region
|
||||
#Region "Load"
|
||||
Friend Overrides Function ExchangeOptionsGet() As Object
|
||||
Return New UserExchangeOptions(Me)
|
||||
Return New EditorExchangeOptionsBase_P(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then QueryString = DirectCast(Obj, UserExchangeOptions).QueryString
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptionsBase_P Then DirectCast(Obj, EditorExchangeOptionsBase_P).Apply(Me)
|
||||
End Sub
|
||||
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
|
||||
If Not Force OrElse (Not SiteMode = SiteModes.User AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
||||
' This program is free software: you can redistribute it and/or modify
|
||||
' it under the terms of the GNU General Public License as published by
|
||||
' the Free Software Foundation, either version 3 of the License, or
|
||||
' (at your option) any later version.
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Namespace API.XVIDEOS
|
||||
Friend Class UserExchangeOptions : Inherits Xhamster.UserExchangeOptions
|
||||
Friend Sub New()
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
QueryString = u.QueryString
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -33,6 +33,9 @@ Namespace API.Xhamster
|
||||
ControlToolTip:="If enabled and the video is downloaded in a non-native format, the video will be re-encoded." & vbCr &
|
||||
"Attention! Enabling this setting results in maximum CPU usage."), PXML, PClonable>
|
||||
Friend ReadOnly Property ReencodeVideos As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
Friend Sub New(ByVal AccName As String, ByVal Temp As Boolean)
|
||||
@@ -48,6 +51,7 @@ Namespace API.Xhamster
|
||||
UrlPatternUser = "https://xhamster.com/{0}/{1}"
|
||||
UserRegex = RParams.DMS($"/({UserOption}|{ChannelOption}|{P_Creators})/([^/]+)(\Z|.*)", 0, RegexReturn.ListByMatch)
|
||||
ImageVideoContains = "xhamster"
|
||||
UserOptionsType = GetType(UserExchangeOptions)
|
||||
End Sub
|
||||
Friend Overrides Sub EndInit()
|
||||
Domains.PopulateInitialDomains(SiteDomains.Value)
|
||||
@@ -71,6 +75,8 @@ Namespace API.Xhamster
|
||||
Return New UserData
|
||||
End Function
|
||||
Friend Overrides Function Available(ByVal What As ISiteSettings.Download, ByVal Silent As Boolean) As Boolean
|
||||
'TODELETE: xHamster disabled
|
||||
Return False
|
||||
If Settings.UseM3U8 AndAlso MyBase.Available(What, Silent) Then
|
||||
If What = ISiteSettings.Download.SavedPosts Then
|
||||
Return Responser.CookiesExists
|
||||
@@ -160,14 +166,6 @@ Namespace API.Xhamster
|
||||
Return Nothing
|
||||
End Function
|
||||
#End Region
|
||||
#Region "UserOptions"
|
||||
Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
|
||||
If Options Is Nothing OrElse Not TypeOf Options Is UserExchangeOptions Then Options = New UserExchangeOptions
|
||||
If OpenForm Then
|
||||
Using f As New InternalSettingsForm(Options, Me, False) : f.ShowDialog() : End Using
|
||||
End If
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "IDisposable Support"
|
||||
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
||||
If Not disposedValue And disposing Then _Domains.Dispose()
|
||||
|
||||
@@ -6,20 +6,22 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports System.Text
|
||||
Imports System.Threading
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Functions.XML
|
||||
Imports PersonalUtilities.Functions.XML.Base
|
||||
Imports PersonalUtilities.Functions.RegularExpressions
|
||||
Imports PersonalUtilities.Tools.Web.Clients
|
||||
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.API.YouTube.Objects
|
||||
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||
Namespace API.Xhamster
|
||||
Friend Class UserData : Inherits UserDataBase
|
||||
Friend Class UserData : Inherits UserDataBase : Implements IPSite
|
||||
#Region "XML names"
|
||||
Private Const Name_Gender As String = "Gender"
|
||||
Private Const Name_IsCreator As String = "IsCreator"
|
||||
Private Const Name_GetMoments As String = "GetMoments"
|
||||
#End Region
|
||||
#Region "Declarations"
|
||||
Friend Overrides ReadOnly Property FeedIsUser As Boolean
|
||||
@@ -29,6 +31,7 @@ Namespace API.Xhamster
|
||||
End Property
|
||||
Friend Property IsChannel As Boolean = False
|
||||
Friend Property IsCreator As Boolean = False
|
||||
Friend Property GetMoments As Boolean = False
|
||||
Friend Property Gender As String = String.Empty
|
||||
Friend Property SiteMode As SiteModes = SiteModes.User
|
||||
Friend Property Arguments As String = String.Empty
|
||||
@@ -47,7 +50,7 @@ Namespace API.Xhamster
|
||||
Return {SearchRequestLabelName}
|
||||
End Get
|
||||
End Property
|
||||
Friend Property QueryString As String
|
||||
Friend Property QueryString As String Implements IPSite.QueryString
|
||||
Get
|
||||
If SiteMode = SiteModes.User Then
|
||||
Return String.Empty
|
||||
@@ -143,6 +146,7 @@ Namespace API.Xhamster
|
||||
If Loading Then
|
||||
IsChannel = .Value(Name_IsChannel).FromXML(Of Boolean)(False)
|
||||
IsCreator = .Value(Name_IsCreator).FromXML(Of Boolean)(False)
|
||||
GetMoments = .Value(Name_GetMoments).FromXML(Of Boolean)(False)
|
||||
Gender = .Value(Name_Gender)
|
||||
SiteMode = .Value(Name_SiteMode).FromXML(Of Integer)(SiteModes.User)
|
||||
Arguments = .Value(Name_Arguments)
|
||||
@@ -155,6 +159,7 @@ Namespace API.Xhamster
|
||||
End If
|
||||
.Add(Name_IsChannel, IsChannel.BoolToInteger)
|
||||
.Add(Name_IsCreator, IsCreator.BoolToInteger)
|
||||
.Add(Name_GetMoments, GetMoments.BoolToInteger)
|
||||
.Add(Name_TrueName, NameTrue(True))
|
||||
.Add(Name_Gender, Gender)
|
||||
.Add(Name_SiteMode, CInt(SiteMode))
|
||||
@@ -169,7 +174,7 @@ Namespace API.Xhamster
|
||||
Return New UserExchangeOptions(Me)
|
||||
End Function
|
||||
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then QueryString = DirectCast(Obj, UserExchangeOptions).QueryString
|
||||
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then DirectCast(Obj, UserExchangeOptions).Apply(Me)
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "Initializer"
|
||||
@@ -237,21 +242,23 @@ Namespace API.Xhamster
|
||||
_PageVideosRepeat = 0
|
||||
SessionPosts.Clear()
|
||||
Responser.CookiesAsHeader = True
|
||||
If DownloadVideos Then DownloadData(1, True, Token)
|
||||
If DownloadVideos Then DownloadData(1, True, False, Token)
|
||||
If GetMoments Then DownloadData(1, True, True, Token)
|
||||
If Not IsChannel And Not IsCreator And DownloadImages And Not IsSubscription Then
|
||||
DownloadData(1, False, Token)
|
||||
DownloadData(1, False, False, Token)
|
||||
ReparsePhoto(Token)
|
||||
End If
|
||||
Finally
|
||||
Responser.CookiesAsHeader = False
|
||||
End Try
|
||||
End Sub
|
||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal IsVideo As Boolean, ByVal Token As CancellationToken)
|
||||
Private Overloads Sub DownloadData(ByVal Page As Integer, ByVal IsVideo As Boolean, ByVal GetMoments As Boolean, ByVal Token As CancellationToken)
|
||||
Dim URL$ = String.Empty
|
||||
Try
|
||||
Dim MaxPage% = -1
|
||||
Dim Type As UTypes = IIf(IsVideo, UTypes.VideoPre, UTypes.Picture)
|
||||
Dim mPages$ = IIf(IsVideo, "maxVideoPages", "maxPhotoPages")
|
||||
Dim specFolder$ = IIf(GetMoments, "Moments*", String.Empty)
|
||||
Dim listNode$()
|
||||
Dim containerNodes As New List(Of String())
|
||||
Dim skipped As Boolean = False
|
||||
@@ -271,6 +278,7 @@ Namespace API.Xhamster
|
||||
End If
|
||||
ElseIf Not SiteMode = SiteModes.Search Then
|
||||
If IsVideo Then
|
||||
If GetMoments Then containerNodes.Add({"momentListComponent", "videoThumbProps"})
|
||||
containerNodes.Add({"trendingVideoListComponent", "models"})
|
||||
containerNodes.Add({"pagesCategoryComponent", "trendingVideoListProps", "models"})
|
||||
containerNodes.Add({"trendingVideoSectionComponent", "videoModels"})
|
||||
@@ -294,7 +302,7 @@ Namespace API.Xhamster
|
||||
ElseIf IsCreator Or SiteMode = SiteModes.Tags Or SiteMode = SiteModes.Categories Or SiteMode = SiteModes.Pornstars Then
|
||||
URL = GetNonUserUrl(Page)
|
||||
Else
|
||||
URL = $"https://xhamster.com/users/{NameTrue}/{IIf(IsVideo, "videos", "photos")}{IIf(Page = 1, String.Empty, $"/{Page}")}"
|
||||
URL = $"https://xhamster.com/users/{NameTrue}/{If(GetMoments, "moments", IIf(IsVideo, "videos", "photos"))}{IIf(Page = 1, String.Empty, $"/{Page}")}"
|
||||
End If
|
||||
ThrowAny(Token)
|
||||
|
||||
@@ -314,7 +322,7 @@ Namespace API.Xhamster
|
||||
ProgressPre.ChangeMax(.Count)
|
||||
For Each e As EContainer In .Self
|
||||
ProgressPre.Perform()
|
||||
m = ExtractMedia(e, Type)
|
||||
m = ExtractMedia(e, Type,,,, specFolder)
|
||||
If Not m.URL.IsEmptyString Then
|
||||
pids.ListAddValue(m.Post.ID, LNC)
|
||||
If m.File.IsEmptyString Then Continue For
|
||||
@@ -374,7 +382,7 @@ Namespace API.Xhamster
|
||||
(MaxPage = -1 Or Page < MaxPage) And
|
||||
((Not _TempMediaList.Count = cBefore Or skipped) And (IsUser Or Page < 1000))
|
||||
) Or
|
||||
(IsChannel Or (Not IsUser And Page < 1000 And prevPostsFound And Not newPostsFound))) Then DownloadData(Page + 1, IsVideo, Token)
|
||||
(IsChannel Or (Not IsUser And Page < 1000 And prevPostsFound And Not newPostsFound))) Then DownloadData(Page + 1, IsVideo, GetMoments, Token)
|
||||
Catch ex As Exception
|
||||
ProcessException(ex, Token, $"data downloading error [{URL}]")
|
||||
End Try
|
||||
@@ -396,7 +404,7 @@ Namespace API.Xhamster
|
||||
If Not m.URL_BASE.IsEmptyString Then
|
||||
m2 = Nothing
|
||||
ThrowAny(Token)
|
||||
If GetM3U8(m2, m.URL_BASE) Then
|
||||
If GetM3U8(m2, m.URL_BASE, m.SpecialFolder) Then
|
||||
m2.URL_BASE = m.URL_BASE
|
||||
_TempMediaList(i) = m2
|
||||
Else
|
||||
@@ -426,7 +434,7 @@ Namespace API.Xhamster
|
||||
If Not m.URL_BASE.IsEmptyString Then
|
||||
m2 = Nothing
|
||||
ThrowAny(Token)
|
||||
If GetM3U8(m2, m.URL_BASE) Then
|
||||
If GetM3U8(m2, m.URL_BASE, String.Empty) Then
|
||||
m2.URL_BASE = m.URL_BASE
|
||||
_TempMediaList(i) = m2
|
||||
c += 1
|
||||
@@ -507,7 +515,7 @@ Namespace API.Xhamster
|
||||
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
||||
ThrowAny(Token)
|
||||
m2 = Nothing
|
||||
If GetM3U8(m2, m.URL_BASE) Then
|
||||
If GetM3U8(m2, m.URL_BASE, m.SpecialFolder) Then
|
||||
m2.URL_BASE = m.URL_BASE
|
||||
m2.State = UserMedia.States.Missing
|
||||
m2.Attempts = m.Attempts
|
||||
@@ -528,7 +536,7 @@ Namespace API.Xhamster
|
||||
End Sub
|
||||
#End Region
|
||||
#Region "GetM3U8"
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal URL As String) As Boolean
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal URL As String, ByVal SpecFolder As String) As Boolean
|
||||
Try
|
||||
If Not URL.IsEmptyString Then
|
||||
Dim r$ = Responser.GetResponse(URL)
|
||||
@@ -536,7 +544,7 @@ Namespace API.Xhamster
|
||||
If Not r.IsEmptyString Then
|
||||
Using j As EContainer = JsonDocument.Parse(r)
|
||||
If j.ListExists Then
|
||||
m = ExtractMedia(j("videoModel"), UTypes.VideoPre)
|
||||
m = ExtractMedia(j("videoModel"), UTypes.VideoPre,,,, SpecFolder)
|
||||
m.URL_BASE = URL
|
||||
If IsSubscription Then
|
||||
With j("videoModel")
|
||||
@@ -546,7 +554,7 @@ Namespace API.Xhamster
|
||||
End If
|
||||
End With
|
||||
Else
|
||||
Return GetM3U8(m, j)
|
||||
Return GetM3U8(m, j, SpecFolder)
|
||||
End If
|
||||
End If
|
||||
End Using
|
||||
@@ -557,15 +565,85 @@ Namespace API.Xhamster
|
||||
Return ErrorsDescriber.Execute(EDP.ReturnValue, ex, $"[{ToStringForLog()}]: API.Xhamster.GetM3U8({URL})", False)
|
||||
End Try
|
||||
End Function
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal j As EContainer) As Boolean
|
||||
Dim node As EContainer = j({"xplayerSettings", "sources", "hls"})
|
||||
Private Overloads Function GetM3U8(ByRef m As UserMedia, ByVal j As EContainer, ByVal SpecFolder As String, Optional ByVal r As Integer = 0) As Boolean
|
||||
Const urlNode$ = "url"
|
||||
Dim node As EContainer = j({"xplayerSettings", "sources", If(r = 0, "hls", "standard")})
|
||||
If node.ListExists Then
|
||||
Dim url$ = node.GetNode({New NodeParams("url", True, True, True, True, 2)}).XmlIfNothingValue
|
||||
If Not url.IsEmptyString Then m.URL = url : m.Type = UTypes.m3u8 : Return True
|
||||
Dim url$ 'node.GetNode({New NodeParams("url", True, True, True, True, 2)}).XmlIfNothingValue
|
||||
Dim jn As EContainer, jn2 As EContainer
|
||||
Dim __getUrl As Func(Of EContainer, String) = Function(jj) If(jj.Contains(urlNode), Decipher_URL(jj.Value(urlNode)), String.Empty)
|
||||
url = __getUrl(node)
|
||||
If url.IsEmptyString Then
|
||||
For Each jn In node
|
||||
If jn.Contains(urlNode) Then
|
||||
url = __getUrl(jn)
|
||||
ElseIf jn.Count > 0 Then
|
||||
For Each jn2 In jn
|
||||
url = __getUrl(jn2)
|
||||
If Not url.IsEmptyString Then Exit For
|
||||
Next
|
||||
End If
|
||||
If Not url.IsEmptyString Then Exit For
|
||||
Next
|
||||
End If
|
||||
If Not url.IsEmptyString Then
|
||||
m.URL = url
|
||||
m.Type = UTypes.m3u8
|
||||
Return True
|
||||
End If
|
||||
End If
|
||||
If r = 0 Then Return GetM3U8(m, j, SpecFolder, r + 1)
|
||||
Return False
|
||||
End Function
|
||||
#End Region
|
||||
#Region "Decipher"
|
||||
'https://github.com/yt-dlp/yt-dlp/blob/5513036104ed9710f624c537fb3644b07a0680db/yt_dlp/extractor/xhamster.py#L146-L165
|
||||
Private Function Decipher_URL(ByVal Input As String) As String
|
||||
If Input.IsEmptyString Then Return String.Empty
|
||||
|
||||
Dim _XOR_KEY As Byte() = Encoding.ASCII.GetBytes("xh7999")
|
||||
Dim cipher_type$ = String.Empty
|
||||
Dim ciphertext$ = String.Empty
|
||||
|
||||
Try
|
||||
Dim decoded$ = Encoding.ASCII.GetString(Convert.FromBase64String(Input))
|
||||
Dim parts$() = decoded.Split(New Char() {"_"c}, 2)
|
||||
If parts.Length = 2 Then cipher_type = parts(0) : ciphertext = parts(1)
|
||||
Catch
|
||||
End Try
|
||||
|
||||
If cipher_type.IsEmptyString Or ciphertext.IsEmptyString Then Return String.Empty
|
||||
|
||||
If cipher_type = "xor" Then
|
||||
Dim ciphertextBytes() As Byte = Encoding.ASCII.GetBytes(ciphertext)
|
||||
Dim resultBytes(ciphertextBytes.Length - 1) As Byte
|
||||
For i% = 0 To ciphertextBytes.Length - 1
|
||||
resultBytes(i) = ciphertextBytes(i) Xor _XOR_KEY(i Mod _XOR_KEY.Length)
|
||||
Next
|
||||
Return Encoding.ASCII.GetString(resultBytes)
|
||||
End If
|
||||
|
||||
If cipher_type = "rot13" Then Return Decipher_URL_Rot13(ciphertext)
|
||||
|
||||
Return String.Empty
|
||||
End Function
|
||||
Private Function Decipher_URL_Rot13(ByVal Input As String) As String
|
||||
Dim result As New Text.StringBuilder(Input.Length)
|
||||
For Each c As Char In Input
|
||||
Dim offset%
|
||||
If c >= "a"c AndAlso c <= "z"c Then
|
||||
offset = Asc("a"c)
|
||||
result.Append(ChrW((Asc(c) - offset + 13) Mod 26 + offset))
|
||||
ElseIf c >= "A"c AndAlso c <= "Z"c Then
|
||||
offset = Asc("A"c)
|
||||
result.Append(ChrW((Asc(c) - offset + 13) Mod 26 + offset))
|
||||
Else
|
||||
result.Append(c)
|
||||
End If
|
||||
Next
|
||||
Return result.ToString
|
||||
End Function
|
||||
#End Region
|
||||
#Region "DownloadSingleObject"
|
||||
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||
_ContentList.Add(New UserMedia(Data.URL_BASE) With {.State = UserMedia.States.Missing})
|
||||
@@ -583,7 +661,8 @@ Namespace API.Xhamster
|
||||
#End Region
|
||||
#Region "Create media"
|
||||
Private Function ExtractMedia(ByVal j As EContainer, ByVal t As UTypes, Optional ByVal UrlNode As String = "pageURL",
|
||||
Optional ByVal DetectGalery As Boolean = True, Optional ByVal PostDate As Date? = Nothing) As UserMedia
|
||||
Optional ByVal DetectGalery As Boolean = True, Optional ByVal PostDate As Date? = Nothing,
|
||||
Optional ByVal SpecFolder As String = Nothing) As UserMedia
|
||||
If Not j Is Nothing Then
|
||||
Dim m As New UserMedia(j.Value(UrlNode).Replace("\", String.Empty), t) With {
|
||||
.Post = New UserPost With {
|
||||
@@ -615,7 +694,7 @@ Namespace API.Xhamster
|
||||
If m.Post.ID.IsEmptyString Then m.Post.ID = m.URL.Split("/").LastOrDefault
|
||||
If m.PictureOption.IsEmptyString Then m.PictureOption = TitleHtmlConverter(j.Value("titleLocalized"))
|
||||
If m.PictureOption.IsEmptyString Then m.PictureOption = m.Post.ID
|
||||
If setSpecialFolder Then m.SpecialFolder = m.PictureOption
|
||||
If setSpecialFolder Then m.SpecialFolder = IIf(t = UTypes.Picture, "Photo\", String.Empty) & m.PictureOption
|
||||
|
||||
If processFile Then
|
||||
If Not m.PictureOption.IsEmptyString Then
|
||||
@@ -626,6 +705,8 @@ Namespace API.Xhamster
|
||||
End If
|
||||
m.File.Separator = "\"
|
||||
End If
|
||||
If Not SpecFolder.IsEmptyString Then _
|
||||
m.SpecialFolder = $"{m.SpecialFolder.StringTrimEnd("\")}{IIf(m.SpecialFolder.IsEmptyString, String.Empty, "\")}{SpecFolder}"
|
||||
Return m
|
||||
Else
|
||||
Return Nothing
|
||||
|
||||
@@ -6,16 +6,22 @@
|
||||
'
|
||||
' This program is distributed in the hope that it will be useful,
|
||||
' but WITHOUT ANY WARRANTY
|
||||
Imports SCrawler.API.Base
|
||||
Imports SCrawler.Plugin.Attributes
|
||||
Namespace API.Xhamster
|
||||
Friend Class UserExchangeOptions
|
||||
<PSetting(Address:=SettingAddress.User, Caption:="Query",
|
||||
ToolTip:="Query string. Don't change this field when creating a user! Change it only for the same request.")>
|
||||
Friend Property QueryString As String
|
||||
Friend NotInheritable Class UserExchangeOptions : Inherits API.Base.EditorExchangeOptionsBase_P
|
||||
<PSetting(Address:=SettingAddress.User, Caption:="Get moments")>
|
||||
Friend Property GetMoments As Boolean = False
|
||||
Friend Sub New()
|
||||
MyBase.New
|
||||
End Sub
|
||||
Friend Sub New(ByVal u As UserData)
|
||||
QueryString = u.QueryString
|
||||
Friend Sub New(ByVal u As IPSite)
|
||||
MyBase.New(DirectCast(u, UserData))
|
||||
GetMoments = DirectCast(u, UserData).GetMoments
|
||||
End Sub
|
||||
Friend Overrides Sub Apply(ByRef u As IPSite)
|
||||
MyBase.Apply(u)
|
||||
DirectCast(u, UserData).GetMoments = GetMoments
|
||||
End Sub
|
||||
End Class
|
||||
End Namespace
|
||||
@@ -31,6 +31,9 @@ Namespace API.YouTube
|
||||
Friend ReadOnly Property DownloadCommunityImages As PropertyValue
|
||||
<PXML, PropertyOption(ControlText:="Download user community: videos", Category:=DN.CAT_UserDefs), PClonable>
|
||||
Friend ReadOnly Property DownloadCommunityVideos As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadText As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextPosts As PropertyValue
|
||||
<DoNotUse> Friend Overrides Property DownloadTextSpecialFolder As PropertyValue
|
||||
#End Region
|
||||
#Region "Communities"
|
||||
<PXML, PropertyOption(ControlText:="YouTube API host",
|
||||
|
||||
75
SCrawler/Download/Feed/DownloadFeedForm.Designer.vb
generated
75
SCrawler/Download/Feed/DownloadFeedForm.Designer.vb
generated
@@ -36,6 +36,8 @@ Namespace DownloadObjects
|
||||
Dim MENU_LOAD_SEP_0 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim MENU_LOAD_SEP_8 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim MENU_LOAD_SEP_9 As System.Windows.Forms.ToolStripSeparator
|
||||
Dim SEP_FILTER As System.Windows.Forms.ToolStripSeparator
|
||||
Dim SEP_FILTER_1 As System.Windows.Forms.ToolStripSeparator
|
||||
Me.OPT_DEFAULT = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.OPT_SUBSCRIPTIONS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.ToolbarTOP = New System.Windows.Forms.ToolStrip()
|
||||
@@ -47,6 +49,11 @@ Namespace DownloadObjects
|
||||
Me.BTT_MOVE_TO = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_COPY_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_MOVE_SPEC_TO = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FILTER = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FILTER_SIMPLE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FILTER_DISABLE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FILTER_SAVE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FILTER_MANAGE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_LOAD_FAV = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_LOAD_SPEC = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_FEED_ADD_FAV = New System.Windows.Forms.ToolStripMenuItem()
|
||||
@@ -68,6 +75,7 @@ Namespace DownloadObjects
|
||||
Me.BTT_MERGE_FEEDS = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CHECK_ALL = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CHECK_NONE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_CHECK_INVERT = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_VIEW_SAVE = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_VIEW_LOAD = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.SEP_0 = New System.Windows.Forms.ToolStripSeparator()
|
||||
@@ -76,7 +84,6 @@ Namespace DownloadObjects
|
||||
Me.BTT_DOWN_SELECTED = New System.Windows.Forms.ToolStripMenuItem()
|
||||
Me.BTT_REFRESH = New System.Windows.Forms.ToolStripButton()
|
||||
Me.TP_DATA = New System.Windows.Forms.TableLayoutPanel()
|
||||
Me.BTT_CHECK_INVERT = New System.Windows.Forms.ToolStripMenuItem()
|
||||
SEP_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_VIEW = New System.Windows.Forms.ToolStripDropDownButton()
|
||||
@@ -90,6 +97,8 @@ Namespace DownloadObjects
|
||||
MENU_LOAD_SEP_0 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_LOAD_SEP_8 = New System.Windows.Forms.ToolStripSeparator()
|
||||
MENU_LOAD_SEP_9 = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_FILTER = New System.Windows.Forms.ToolStripSeparator()
|
||||
SEP_FILTER_1 = New System.Windows.Forms.ToolStripSeparator()
|
||||
Me.ToolbarTOP.SuspendLayout()
|
||||
Me.SuspendLayout()
|
||||
'
|
||||
@@ -175,6 +184,16 @@ Namespace DownloadObjects
|
||||
MENU_LOAD_SEP_9.Name = "MENU_LOAD_SEP_9"
|
||||
MENU_LOAD_SEP_9.Size = New System.Drawing.Size(349, 6)
|
||||
'
|
||||
'SEP_FILTER
|
||||
'
|
||||
SEP_FILTER.Name = "SEP_FILTER"
|
||||
SEP_FILTER.Size = New System.Drawing.Size(349, 6)
|
||||
'
|
||||
'SEP_FILTER_1
|
||||
'
|
||||
SEP_FILTER_1.Name = "SEP_FILTER_1"
|
||||
SEP_FILTER_1.Size = New System.Drawing.Size(190, 6)
|
||||
'
|
||||
'ToolbarTOP
|
||||
'
|
||||
Me.ToolbarTOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
|
||||
@@ -188,7 +207,7 @@ Namespace DownloadObjects
|
||||
'
|
||||
Me.MENU_LOAD_SESSION.AutoToolTip = False
|
||||
Me.MENU_LOAD_SESSION.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
|
||||
Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_COPY_SPEC_TO, Me.BTT_MOVE_SPEC_TO, MENU_LOAD_SEP_2, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_4, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_5, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_6, Me.BTT_CURR_SESSION_SET, Me.BTT_CURR_SESSION_SET_LAST, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, Me.BTT_RESET_DAILY, MENU_LOAD_SEP_7, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_8, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, Me.BTT_CHECK_INVERT, MENU_LOAD_SEP_9, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD})
|
||||
Me.MENU_LOAD_SESSION.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_LOAD_SESSION_CURRENT, Me.BTT_LOAD_SESSION_LAST, Me.BTT_LOAD_SESSION_CHOOSE, MENU_LOAD_SEP_0, Me.BTT_COPY_TO, Me.BTT_MOVE_TO, MENU_LOAD_SEP_1, Me.BTT_COPY_SPEC_TO, Me.BTT_MOVE_SPEC_TO, MENU_LOAD_SEP_2, Me.BTT_FILTER, SEP_FILTER, Me.BTT_LOAD_FAV, Me.BTT_LOAD_SPEC, MENU_LOAD_SEP_3, Me.BTT_FEED_ADD_FAV, Me.BTT_FEED_ADD_FAV_REMOVE, Me.BTT_FEED_REMOVE_FAV, MENU_LOAD_SEP_4, Me.BTT_FEED_ADD_SPEC, Me.BTT_FEED_ADD_SPEC_REMOVE, Me.BTT_FEED_REMOVE_SPEC, MENU_LOAD_SEP_5, Me.BTT_FEED_CLEAR_FAV, Me.BTT_FEED_CLEAR_SPEC, Me.BTT_FEED_DELETE_SPEC, Me.BTT_FEED_DELETE_DAILY_LIST, Me.BTT_FEED_DELETE_DAILY_DATE, MENU_LOAD_SEP_6, Me.BTT_CURR_SESSION_SET, Me.BTT_CURR_SESSION_SET_LAST, Me.BTT_MERGE_SESSIONS, Me.BTT_CLEAR_DAILY, Me.BTT_RESET_DAILY, MENU_LOAD_SEP_7, Me.BTT_MERGE_FEEDS, MENU_LOAD_SEP_8, Me.BTT_CHECK_ALL, Me.BTT_CHECK_NONE, Me.BTT_CHECK_INVERT, MENU_LOAD_SEP_9, Me.BTT_VIEW_SAVE, Me.BTT_VIEW_LOAD})
|
||||
Me.MENU_LOAD_SESSION.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
|
||||
Me.MENU_LOAD_SESSION.ImageTransparentColor = System.Drawing.Color.Magenta
|
||||
Me.MENU_LOAD_SESSION.Name = "MENU_LOAD_SESSION"
|
||||
@@ -248,6 +267,41 @@ Namespace DownloadObjects
|
||||
Me.BTT_MOVE_SPEC_TO.Text = "Move feed/session files to..."
|
||||
Me.BTT_MOVE_SPEC_TO.ToolTipText = "Move all the files of the loaded feed/session to..."
|
||||
'
|
||||
'BTT_FILTER
|
||||
'
|
||||
Me.BTT_FILTER.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_FILTER_SIMPLE, Me.BTT_FILTER_DISABLE, Me.BTT_FILTER_SAVE, SEP_FILTER_1, Me.BTT_FILTER_MANAGE})
|
||||
Me.BTT_FILTER.Name = "BTT_FILTER"
|
||||
Me.BTT_FILTER.Size = New System.Drawing.Size(352, 22)
|
||||
Me.BTT_FILTER.Text = "Filter"
|
||||
'
|
||||
'BTT_FILTER_SIMPLE
|
||||
'
|
||||
Me.BTT_FILTER_SIMPLE.AutoToolTip = True
|
||||
Me.BTT_FILTER_SIMPLE.Name = "BTT_FILTER_SIMPLE"
|
||||
Me.BTT_FILTER_SIMPLE.Size = New System.Drawing.Size(193, 22)
|
||||
Me.BTT_FILTER_SIMPLE.Text = "Simple filter"
|
||||
Me.BTT_FILTER_SIMPLE.ToolTipText = "Apply filter to current feed/session"
|
||||
'
|
||||
'BTT_FILTER_DISABLE
|
||||
'
|
||||
Me.BTT_FILTER_DISABLE.Image = Global.SCrawler.My.Resources.Resources.DeletePic_24
|
||||
Me.BTT_FILTER_DISABLE.Name = "BTT_FILTER_DISABLE"
|
||||
Me.BTT_FILTER_DISABLE.Size = New System.Drawing.Size(193, 22)
|
||||
Me.BTT_FILTER_DISABLE.Text = "Disable filter"
|
||||
'
|
||||
'BTT_FILTER_SAVE
|
||||
'
|
||||
Me.BTT_FILTER_SAVE.Name = "BTT_FILTER_SAVE"
|
||||
Me.BTT_FILTER_SAVE.Size = New System.Drawing.Size(193, 22)
|
||||
Me.BTT_FILTER_SAVE.Text = "Save current filter"
|
||||
'
|
||||
'BTT_FILTER_MANAGE
|
||||
'
|
||||
Me.BTT_FILTER_MANAGE.Image = Global.SCrawler.My.Resources.Resources.PencilPic_16
|
||||
Me.BTT_FILTER_MANAGE.Name = "BTT_FILTER_MANAGE"
|
||||
Me.BTT_FILTER_MANAGE.Size = New System.Drawing.Size(193, 22)
|
||||
Me.BTT_FILTER_MANAGE.Text = "Managing saved filters"
|
||||
'
|
||||
'BTT_LOAD_FAV
|
||||
'
|
||||
Me.BTT_LOAD_FAV.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
|
||||
@@ -404,6 +458,12 @@ Namespace DownloadObjects
|
||||
Me.BTT_CHECK_NONE.Size = New System.Drawing.Size(352, 22)
|
||||
Me.BTT_CHECK_NONE.Text = "Select none"
|
||||
'
|
||||
'BTT_CHECK_INVERT
|
||||
'
|
||||
Me.BTT_CHECK_INVERT.Name = "BTT_CHECK_INVERT"
|
||||
Me.BTT_CHECK_INVERT.Size = New System.Drawing.Size(352, 22)
|
||||
Me.BTT_CHECK_INVERT.Text = "Invert selection"
|
||||
'
|
||||
'BTT_VIEW_SAVE
|
||||
'
|
||||
Me.BTT_VIEW_SAVE.Name = "BTT_VIEW_SAVE"
|
||||
@@ -484,12 +544,6 @@ Namespace DownloadObjects
|
||||
Me.TP_DATA.Size = New System.Drawing.Size(484, 436)
|
||||
Me.TP_DATA.TabIndex = 1
|
||||
'
|
||||
'BTT_CHECK_INVERT
|
||||
'
|
||||
Me.BTT_CHECK_INVERT.Name = "BTT_CHECK_INVERT"
|
||||
Me.BTT_CHECK_INVERT.Size = New System.Drawing.Size(352, 22)
|
||||
Me.BTT_CHECK_INVERT.Text = "Invert selection"
|
||||
'
|
||||
'DownloadFeedForm
|
||||
'
|
||||
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
|
||||
@@ -551,5 +605,10 @@ Namespace DownloadObjects
|
||||
Private WithEvents BTT_RESET_DAILY As ToolStripMenuItem
|
||||
Private WithEvents BTT_CURR_SESSION_SET_LAST As ToolStripMenuItem
|
||||
Private WithEvents BTT_CHECK_INVERT As ToolStripMenuItem
|
||||
Private WithEvents BTT_FILTER As ToolStripMenuItem
|
||||
Private WithEvents BTT_FILTER_SIMPLE As ToolStripMenuItem
|
||||
Private WithEvents BTT_FILTER_DISABLE As ToolStripMenuItem
|
||||
Private WithEvents BTT_FILTER_SAVE As ToolStripMenuItem
|
||||
Private WithEvents BTT_FILTER_MANAGE As ToolStripMenuItem
|
||||
End Class
|
||||
End Namespace
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user